Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Correctly export the main fn in the json abi #5707

Merged
merged 2 commits into from
Mar 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 2 additions & 8 deletions sway-core/src/abi_generation/fuel_abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,8 @@ pub fn generate_program_abi(
configurables: Some(configurables),
}
}
TyProgramKind::Script {
entry_function: main_function,
..
}
| TyProgramKind::Predicate {
entry_function: main_function,
..
} => {
TyProgramKind::Script { main_function, .. }
| TyProgramKind::Predicate { main_function, .. } => {
let main_function = decl_engine.get_function(main_function);
let functions =
vec![main_function.generate_abi_function(ctx, type_engine, decl_engine, types)];
Expand Down
93 changes: 90 additions & 3 deletions sway-core/src/control_flow_analysis/dead_code_analysis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ use crate::{
decl_engine::*,
language::{
parsed::TreeType,
ty::{self, TyAstNodeContent, TyImplItem},
ty::{
self, ConstantDecl, FunctionDecl, StructDecl, TraitDecl, TyAstNode, TyAstNodeContent,
TyDecl, TyImplItem, TypeAliasDecl,
},
CallPath, Visibility,
},
transform::{self, AttributesMap},
Expand All @@ -24,6 +27,88 @@ use sway_types::{
Ident, Named, Spanned,
};

// Defines if this node starts the dca graph or not
fn is_entry_point(node: &TyAstNode, decl_engine: &DeclEngine, tree_type: &TreeType) -> bool {
match tree_type {
TreeType::Predicate | TreeType::Script => {
// Predicates and scripts have main and test functions as entry points.
match node {
TyAstNode {
span: _,
content:
TyAstNodeContent::Declaration(TyDecl::FunctionDecl(FunctionDecl {
decl_id,
..
})),
..
} => {
let decl = decl_engine.get_function(decl_id);
decl.is_entry() || decl.is_main() || decl.is_test()
}
_ => false,
}
}
TreeType::Contract | TreeType::Library { .. } => match node {
TyAstNode {
content:
TyAstNodeContent::Declaration(TyDecl::FunctionDecl(FunctionDecl {
decl_id,
decl_span: _,
..
})),
..
} => {
let decl = decl_engine.get_function(decl_id);
decl.visibility == Visibility::Public || decl.is_test()
}
TyAstNode {
content:
TyAstNodeContent::Declaration(TyDecl::TraitDecl(TraitDecl {
decl_id,
decl_span: _,
..
})),
..
} => decl_engine.get_trait(decl_id).visibility.is_public(),
TyAstNode {
content:
TyAstNodeContent::Declaration(TyDecl::StructDecl(StructDecl { decl_id, .. })),
..
} => {
let struct_decl = decl_engine.get_struct(decl_id);
struct_decl.visibility == Visibility::Public
}
TyAstNode {
content: TyAstNodeContent::Declaration(TyDecl::ImplTrait { .. }),
..
} => true,
TyAstNode {
content:
TyAstNodeContent::Declaration(TyDecl::ConstantDecl(ConstantDecl {
decl_id,
decl_span: _,
..
})),
..
} => {
let decl = decl_engine.get_constant(decl_id);
decl.visibility.is_public()
}
TyAstNode {
content:
TyAstNodeContent::Declaration(TyDecl::TypeAliasDecl(TypeAliasDecl {
decl_id, ..
})),
..
} => {
let decl = decl_engine.get_type_alias(decl_id);
decl.visibility.is_public()
}
_ => false,
},
}
}

impl<'cfg> ControlFlowGraph<'cfg> {
pub(crate) fn find_dead_code(&self, decl_engine: &DeclEngine) -> Vec<CompileWarning> {
// Dead code is code that has no path from the entry point.
Expand Down Expand Up @@ -287,13 +372,15 @@ impl<'cfg> ControlFlowGraph<'cfg> {

let mut entry_points = vec![];
let mut non_entry_points = vec![];

for ast_node in module_nodes {
if ast_node.is_entry_point(decl_engine, tree_type) {
if is_entry_point(ast_node, decl_engine, tree_type) {
entry_points.push(ast_node);
} else {
non_entry_points.push(ast_node);
}
}

for ast_entrypoint in non_entry_points.into_iter().chain(entry_points) {
let (_l_leaves, _new_exit_node) = connect_node(
engines,
Expand All @@ -320,7 +407,7 @@ fn collect_entry_points(
for i in graph.node_indices() {
let is_entry = match &graph[i] {
ControlFlowGraphNode::ProgramNode { node, .. } => {
node.is_entry_point(decl_engine, tree_type)
is_entry_point(node, decl_engine, tree_type)
}
_ => false,
};
Expand Down
4 changes: 2 additions & 2 deletions sway-core/src/ir_generation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ pub fn compile_program<'eng>(
match kind {
// predicates and scripts have the same codegen, their only difference is static
// type-check time checks.
ty::TyProgramKind::Script { entry_function } => compile::compile_script(
ty::TyProgramKind::Script { entry_function, .. } => compile::compile_script(
engines,
&mut ctx,
entry_function,
Expand All @@ -73,7 +73,7 @@ pub fn compile_program<'eng>(
&messages_types,
&test_fns,
),
ty::TyProgramKind::Predicate { entry_function } => compile::compile_predicate(
ty::TyProgramKind::Predicate { entry_function, .. } => compile::compile_predicate(
engines,
&mut ctx,
entry_function,
Expand Down
12 changes: 6 additions & 6 deletions sway-core/src/ir_generation/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use std::{collections::HashMap, sync::Arc};
pub(super) fn compile_script(
engines: &Engines,
context: &mut Context,
main_function: &DeclId<ty::TyFunctionDecl>,
entry_function: &DeclId<ty::TyFunctionDecl>,
namespace: &namespace::Module,
declarations: &[ty::TyDecl],
logged_types_map: &HashMap<TypeId, LogId>,
Expand All @@ -49,7 +49,7 @@ pub(super) fn compile_script(
context,
&mut md_mgr,
module,
main_function,
entry_function,
logged_types_map,
messages_types_map,
None,
Expand All @@ -71,7 +71,7 @@ pub(super) fn compile_script(
pub(super) fn compile_predicate(
engines: &Engines,
context: &mut Context,
main_function: &DeclId<ty::TyFunctionDecl>,
entry_function: &DeclId<ty::TyFunctionDecl>,
namespace: &namespace::Module,
declarations: &[ty::TyDecl],
logged_types: &HashMap<TypeId, LogId>,
Expand All @@ -96,7 +96,7 @@ pub(super) fn compile_predicate(
context,
&mut md_mgr,
module,
main_function,
entry_function,
&HashMap::new(),
&HashMap::new(),
None,
Expand All @@ -117,7 +117,7 @@ pub(super) fn compile_predicate(
#[allow(clippy::too_many_arguments)]
pub(super) fn compile_contract(
context: &mut Context,
main_function: Option<&DeclId<ty::TyFunctionDecl>>,
entry_function: Option<&DeclId<ty::TyFunctionDecl>>,
abi_entries: &[DeclId<ty::TyFunctionDecl>],
namespace: &namespace::Module,
declarations: &[ty::TyDecl],
Expand All @@ -140,7 +140,7 @@ pub(super) fn compile_contract(
)
.map_err(|err| vec![err])?;

if let Some(main_function) = main_function {
if let Some(main_function) = entry_function {
compile_entry_function(
engines,
context,
Expand Down
1 change: 1 addition & 0 deletions sway-core/src/language/parsed/declaration/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use sway_types::{ident::Ident, span::Span};
pub enum FunctionDeclarationKind {
Default,
Entry,
Main,
Test,
}

Expand Down
86 changes: 1 addition & 85 deletions sway-core/src/language/ty/ast_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use sway_types::{Ident, Span};
use crate::{
decl_engine::*,
engine_threading::*,
language::{parsed::TreeType, ty::*, Visibility},
language::ty::*,
semantic_analysis::{
TypeCheckAnalysis, TypeCheckAnalysisContext, TypeCheckContext, TypeCheckFinalization,
TypeCheckFinalizationContext,
Expand Down Expand Up @@ -192,90 +192,6 @@ impl TyAstNode {
}
}

pub(crate) fn is_entry_point(&self, decl_engine: &DeclEngine, tree_type: &TreeType) -> bool {
match tree_type {
TreeType::Predicate | TreeType::Script => {
// Predicates and scripts have main and test functions as entry points.
match self {
TyAstNode {
span: _,
content:
TyAstNodeContent::Declaration(TyDecl::FunctionDecl(FunctionDecl {
decl_id,
..
})),
..
} => {
let decl = decl_engine.get_function(decl_id);
decl.is_entry_or_test()
}
_ => false,
}
}
TreeType::Contract | TreeType::Library { .. } => match self {
TyAstNode {
content:
TyAstNodeContent::Declaration(TyDecl::FunctionDecl(FunctionDecl {
decl_id,
decl_span: _,
..
})),
..
} => {
let decl = decl_engine.get_function(decl_id);
decl.visibility == Visibility::Public || decl.is_test()
}
TyAstNode {
content:
TyAstNodeContent::Declaration(TyDecl::TraitDecl(TraitDecl {
decl_id,
decl_span: _,
..
})),
..
} => decl_engine.get_trait(decl_id).visibility.is_public(),
TyAstNode {
content:
TyAstNodeContent::Declaration(TyDecl::StructDecl(StructDecl {
decl_id, ..
})),
..
} => {
let struct_decl = decl_engine.get_struct(decl_id);
struct_decl.visibility == Visibility::Public
}
TyAstNode {
content: TyAstNodeContent::Declaration(TyDecl::ImplTrait { .. }),
..
} => true,
TyAstNode {
content:
TyAstNodeContent::Declaration(TyDecl::ConstantDecl(ConstantDecl {
decl_id,
decl_span: _,
..
})),
..
} => {
let decl = decl_engine.get_constant(decl_id);
decl.visibility.is_public()
}
TyAstNode {
content:
TyAstNodeContent::Declaration(TyDecl::TypeAliasDecl(TypeAliasDecl {
decl_id,
..
})),
..
} => {
let decl = decl_engine.get_type_alias(decl_id);
decl.visibility.is_public()
}
_ => false,
},
}
}

pub(crate) fn type_info(&self, type_engine: &TypeEngine) -> TypeInfo {
// return statement should be ()
match &self.content {
Expand Down
11 changes: 6 additions & 5 deletions sway-core/src/language/ty/declaration/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ use sway_types::{
pub enum TyFunctionDeclKind {
Default,
Entry,
Main,
Test,
}

Expand Down Expand Up @@ -336,6 +337,7 @@ impl TyFunctionDecl {
FunctionDeclarationKind::Default => TyFunctionDeclKind::Default,
FunctionDeclarationKind::Entry => TyFunctionDeclKind::Entry,
FunctionDeclarationKind::Test => TyFunctionDeclKind::Test,
FunctionDeclarationKind::Main => TyFunctionDeclKind::Main,
},
}
}
Expand Down Expand Up @@ -412,6 +414,10 @@ impl TyFunctionDecl {
matches!(self.kind, TyFunctionDeclKind::Entry)
}

pub fn is_main(&self) -> bool {
matches!(self.kind, TyFunctionDeclKind::Main)
}

/// Whether or not this function is a unit test, i.e. decorated with `#[test]`.
pub fn is_test(&self) -> bool {
//TODO match kind to Test
Expand All @@ -435,11 +441,6 @@ impl TyFunctionDecl {
}
}

/// Whether or not this function describes a program entry point.
pub fn is_entry_or_test(&self) -> bool {
self.is_entry() || self.is_test()
}

/// Whether or not this function is a constructor for the type given by `type_id`.
///
/// Returns `Some(true)` if the function is surely the constructor and `Some(false)` if
Expand Down
Loading
Loading