diff --git a/runtime/vm/ast.h b/runtime/vm/ast.h index c3b6ac1f6f8..14934fd3cef 100644 --- a/runtime/vm/ast.h +++ b/runtime/vm/ast.h @@ -1814,19 +1814,14 @@ class NativeBodyNode : public AstNode { NativeBodyNode(intptr_t token_pos, const Function& function, const String& native_c_function_name, - NativeFunction native_c_function, LocalScope* scope, - bool is_bootstrap_native, bool link_lazily = false) : AstNode(token_pos), function_(function), native_c_function_name_(native_c_function_name), - native_c_function_(native_c_function), scope_(scope), - is_bootstrap_native_(is_bootstrap_native), link_lazily_(link_lazily) { ASSERT(function_.IsZoneHandle()); - ASSERT(native_c_function_ != NULL); ASSERT(native_c_function_name_.IsZoneHandle()); ASSERT(native_c_function_name_.IsSymbol()); } @@ -1835,9 +1830,7 @@ class NativeBodyNode : public AstNode { const String& native_c_function_name() const { return native_c_function_name_; } - NativeFunction native_c_function() const { return native_c_function_; } LocalScope* scope() const { return scope_; } - bool is_bootstrap_native() const { return is_bootstrap_native_; } bool link_lazily() const { return link_lazily_; } @@ -1848,9 +1841,7 @@ class NativeBodyNode : public AstNode { private: const Function& function_; // Native Dart function. const String& native_c_function_name_; - NativeFunction native_c_function_; // Actual non-Dart implementation. LocalScope* scope_; - const bool is_bootstrap_native_; // Is a bootstrap native method. const bool link_lazily_; DISALLOW_IMPLICIT_CONSTRUCTORS(NativeBodyNode); diff --git a/runtime/vm/code_generator_test.cc b/runtime/vm/code_generator_test.cc index aac931182ef..2cdc6fbcc24 100644 --- a/runtime/vm/code_generator_test.cc +++ b/runtime/vm/code_generator_test.cc @@ -192,58 +192,6 @@ CODEGEN_TEST_GENERATE(BinaryOpCodegen, test) { CODEGEN_TEST_RUN(BinaryOpCodegen, Double::New(2.5)); -// Tested Dart code: -// int dec(int a, [int b = 1]) native: "TestSmiSub"; -// The native entry TestSmiSub implements dec natively. -CODEGEN_TEST_GENERATE(NativeDecCodegen, test) { - // A NativeBodyNode, preceded by an EnterNode and followed by a ReturnNode, - // implements the body of a native Dart function. Let's take this native - // function as an example: int dec(int a, int b = 1) native; - // Since this function has an optional parameter, its prologue will copy - // incoming parameters to locals. - SequenceNode* node_seq = test->node_sequence(); - const int num_fixed_params = 1; - const int num_opt_params = 1; - const int num_params = num_fixed_params + num_opt_params; - LocalScope* local_scope = node_seq->scope(); - local_scope->InsertParameterAt(0, NewTestLocalVariable("a")); - local_scope->InsertParameterAt(1, NewTestLocalVariable("b")); - ASSERT(local_scope->num_variables() == num_params); - ZoneGrowableArray* default_values = - new ZoneGrowableArray(num_opt_params); - default_values->Add(&Smi::ZoneHandle(Smi::New(1))); // b = 1. - test->set_default_parameter_values(default_values); - const Function& function = test->function(); - function.set_is_native(true); - function.set_num_fixed_parameters(num_fixed_params); - function.SetNumOptionalParameters(num_opt_params, true); - const String& native_name = - String::ZoneHandle(Symbols::New("TestSmiSub")); - NativeFunction native_function = - reinterpret_cast(TestSmiSub); - node_seq->Add( - new ReturnNode(kPos, - new NativeBodyNode(kPos, - function, - native_name, - native_function, - local_scope, - false /* not bootstrap native */))); -} - - -// Tested Dart code: -// return dec(5); -CODEGEN_TEST2_GENERATE(StaticDecCallCodegen, function, test) { - SequenceNode* node_seq = test->node_sequence(); - ArgumentListNode* arguments = new ArgumentListNode(kPos); - arguments->Add(new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(5)))); - node_seq->Add(new ReturnNode(kPos, - new StaticCallNode(kPos, function, arguments))); -} -CODEGEN_TEST2_RUN(StaticDecCallCodegen, NativeDecCodegen, Smi::New(4)) - - CODEGEN_TEST_GENERATE(SmiUnaryOpCodegen, test) { SequenceNode* node_seq = test->node_sequence(); LiteralNode* a = new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(12))); @@ -368,159 +316,6 @@ CODEGEN_TEST_GENERATE(InstanceCallCodegen, test) { CODEGEN_TEST_RUN(InstanceCallCodegen, Smi::New(42)) -// Tested Dart code: -// int sum(int a, int b, -// [int c = 10, int d = 21, int e = -32]) native: "TestSmiSum"; -// The native entry TestSmiSum implements sum natively. -CODEGEN_TEST_GENERATE(NativeSumCodegen, test) { - SequenceNode* node_seq = test->node_sequence(); - const int num_fixed_params = 2; - const int num_opt_params = 3; - const int num_params = num_fixed_params + num_opt_params; - LocalScope* local_scope = node_seq->scope(); - local_scope->InsertParameterAt(0, NewTestLocalVariable("a")); - local_scope->InsertParameterAt(1, NewTestLocalVariable("b")); - local_scope->InsertParameterAt(2, NewTestLocalVariable("c")); - local_scope->InsertParameterAt(3, NewTestLocalVariable("d")); - local_scope->InsertParameterAt(4, NewTestLocalVariable("e")); - ASSERT(local_scope->num_variables() == num_params); - ZoneGrowableArray* default_values = - new ZoneGrowableArray(num_opt_params); - default_values->Add(&Smi::ZoneHandle(Smi::New(10))); - default_values->Add(&Smi::ZoneHandle(Smi::New(21))); - default_values->Add(&Smi::ZoneHandle(Smi::New(-32))); - test->set_default_parameter_values(default_values); - const Function& function = test->function(); - function.set_is_native(true); - function.set_num_fixed_parameters(num_fixed_params); - function.SetNumOptionalParameters(num_opt_params, true); - function.set_parameter_types(Array::Handle(Array::New(num_params))); - function.set_parameter_names(Array::Handle(Array::New(num_params))); - const Type& param_type = Type::Handle(Type::DynamicType()); - for (int i = 0; i < num_params; i++) { - function.SetParameterTypeAt(i, param_type); - } - const String& native_name = - String::ZoneHandle(Symbols::New("TestSmiSum")); - NativeFunction native_function = - reinterpret_cast(TestSmiSum); - node_seq->Add( - new ReturnNode(kPos, - new NativeBodyNode(kPos, - function, - native_name, - native_function, - local_scope, - false /* Not bootstrap native */))); -} - - -// Tested Dart code, calling function sum declared above: -// return sum(1, 3); -// Optional arguments are not passed and hence are set to their default values. -CODEGEN_TEST2_GENERATE(StaticSumCallNoOptCodegen, function, test) { - SequenceNode* node_seq = test->node_sequence(); - ArgumentListNode* arguments = new ArgumentListNode(kPos); - arguments->Add(new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(1)))); - arguments->Add(new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(3)))); - node_seq->Add(new ReturnNode(kPos, - new StaticCallNode(kPos, function, arguments))); -} -CODEGEN_TEST2_RUN(StaticSumCallNoOptCodegen, - NativeSumCodegen, - Smi::New(1 + 3 + 10 + 21 - 32)) - - -// Tested Dart code, calling function sum declared above: -// return sum(1, 3, 5); -// Only one out of three optional arguments is passed in; the second and third -// arguments are hence set to their default values. -CODEGEN_TEST2_GENERATE(StaticSumCallOneOptCodegen, function, test) { - SequenceNode* node_seq = test->node_sequence(); - ArgumentListNode* arguments = new ArgumentListNode(kPos); - arguments->Add(new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(1)))); - arguments->Add(new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(3)))); - arguments->Add(new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(5)))); - node_seq->Add(new ReturnNode(kPos, - new StaticCallNode(kPos, function, arguments))); -} -CODEGEN_TEST2_RUN(StaticSumCallOneOptCodegen, - NativeSumCodegen, - Smi::New(1 + 3 + 5 + 21 - 32)) - - -// Tested Dart code, calling function sum declared above: -// return sum(0, 1, 1, 2, 3); -// Optional arguments are passed in. -CODEGEN_TEST2_GENERATE(StaticSumCallTenFiboCodegen, function, test) { - SequenceNode* node_seq = test->node_sequence(); - ArgumentListNode* arguments = new ArgumentListNode(kPos); - arguments->Add(new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(0)))); - arguments->Add(new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(1)))); - arguments->Add(new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(1)))); - arguments->Add(new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(2)))); - arguments->Add(new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(3)))); - node_seq->Add(new ReturnNode(kPos, - new StaticCallNode(kPos, function, arguments))); -} -CODEGEN_TEST2_RUN( - StaticSumCallTenFiboCodegen, - NativeSumCodegen, - Smi::New(0 + 1 + 1 + 2 + 3)) - - -// Tested Dart code: -// int sum(a, b, c) native: "TestNonNullSmiSum"; -// The native entry TestNonNullSmiSum implements sum natively. -CODEGEN_TEST_GENERATE(NativeNonNullSumCodegen, test) { - SequenceNode* node_seq = test->node_sequence(); - const int num_params = 3; - LocalScope* local_scope = node_seq->scope(); - local_scope->InsertParameterAt(0, NewTestLocalVariable("a")); - local_scope->InsertParameterAt(1, NewTestLocalVariable("b")); - local_scope->InsertParameterAt(2, NewTestLocalVariable("c")); - ASSERT(local_scope->num_variables() == num_params); - const Function& function = test->function(); - function.set_is_native(true); - function.set_num_fixed_parameters(num_params); - ASSERT(!function.HasOptionalParameters()); - function.set_parameter_types(Array::Handle(Array::New(num_params))); - function.set_parameter_names(Array::Handle(Array::New(num_params))); - const Type& param_type = Type::Handle(Type::DynamicType()); - for (int i = 0; i < num_params; i++) { - function.SetParameterTypeAt(i, param_type); - } - const String& native_name = - String::ZoneHandle(Symbols::New("TestNonNullSmiSum")); - NativeFunction native_function = - reinterpret_cast(TestNonNullSmiSum); - node_seq->Add( - new ReturnNode(kPos, - new NativeBodyNode(kPos, - function, - native_name, - native_function, - local_scope, - false /* Not bootstrap native */))); -} - - -// Tested Dart code, calling function sum declared above: -// return sum(1, null, 3); -CODEGEN_TEST2_GENERATE(StaticNonNullSumCallCodegen, function, test) { - SequenceNode* node_seq = test->node_sequence(); - ArgumentListNode* arguments = new ArgumentListNode(kPos); - arguments->Add(new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(1)))); - arguments->Add(new LiteralNode(kPos, Instance::ZoneHandle())); - arguments->Add(new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(3)))); - node_seq->Add(new ReturnNode(kPos, - new StaticCallNode(kPos, function, arguments))); -} -CODEGEN_TEST2_RUN(StaticNonNullSumCallCodegen, - NativeNonNullSumCodegen, - Smi::New(1 + 3)) - - // Test allocation of dart objects. CODEGEN_TEST_GENERATE(AllocateNewObjectCodegen, test) { const char* kScriptChars = diff --git a/runtime/vm/compiler.cc b/runtime/vm/compiler.cc index 0422cf30622..43bbcbafdf6 100644 --- a/runtime/vm/compiler.cc +++ b/runtime/vm/compiler.cc @@ -852,7 +852,6 @@ static bool CompileParsedFunctionHelper(CompilationPipeline* pipeline, THR_Print("%s\n", error.ToErrorCString()); } done = true; - ASSERT(optimized); } // Clear the error if it was not a real error, but just a bailout. @@ -1091,8 +1090,14 @@ static RawError* CompileFunctionHelper(CompilationPipeline* pipeline, } function.SetIsOptimizable(false); return Error::null(); + } else { + // Encountered error. + Error& error = Error::Handle(); + // We got an error during compilation. + error = isolate->object_store()->sticky_error(); + isolate->object_store()->clear_sticky_error(); + return error.raw(); } - UNREACHABLE(); } per_compile_timer.Stop(); diff --git a/runtime/vm/intermediate_language.cc b/runtime/vm/intermediate_language.cc index f063e7dae66..2293d9c179f 100644 --- a/runtime/vm/intermediate_language.cc +++ b/runtime/vm/intermediate_language.cc @@ -5,6 +5,7 @@ #include "vm/intermediate_language.h" #include "vm/bit_vector.h" +#include "vm/bootstrap.h" #include "vm/compiler.h" #include "vm/constant_propagator.h" #include "vm/cpu.h" @@ -3656,6 +3657,30 @@ intptr_t MergedMathInstr::OutputIndexOf(Token::Kind token) { } +void NativeCallInstr::SetupNative() { + Zone* Z = Thread::Current()->zone(); + const Class& cls = Class::Handle(Z, function().Owner()); + const Library& library = Library::Handle(Z, cls.library()); + const int num_params = + NativeArguments::ParameterCountForResolution(function()); + bool auto_setup_scope = true; + NativeFunction native_function = NativeEntry::ResolveNative( + library, native_name(), num_params, &auto_setup_scope); + if (native_function == NULL) { + Report::MessageF(Report::kError, + Script::Handle(function().script()), + function().token_pos(), + "native function '%s' (%" Pd " arguments) cannot be found", + native_name().ToCString(), + function().NumParameters()); + } + set_native_c_function(native_function); + function().SetIsNativeAutoSetupScope(auto_setup_scope); + Dart_NativeEntryResolver resolver = library.native_entry_resolver(); + bool is_bootstrap_native = Bootstrap::IsBootstapResolver(resolver); + set_is_bootstrap_native(is_bootstrap_native); +} + #undef __ } // namespace dart diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h index fbd405122c9..2b9b7625266 100644 --- a/runtime/vm/intermediate_language.h +++ b/runtime/vm/intermediate_language.h @@ -3393,7 +3393,9 @@ class StoreLocalInstr : public TemplateDefinition<1, NoThrow> { class NativeCallInstr : public TemplateDefinition<0, Throws> { public: explicit NativeCallInstr(NativeBodyNode* node) - : ast_node_(*node) {} + : ast_node_(*node), + native_c_function_(NULL), + is_bootstrap_native_(false) { } DECLARE_INSTRUCTION(NativeCall) @@ -3406,11 +3408,11 @@ class NativeCallInstr : public TemplateDefinition<0, Throws> { } NativeFunction native_c_function() const { - return ast_node_.native_c_function(); + return native_c_function_; } bool is_bootstrap_native() const { - return ast_node_.is_bootstrap_native(); + return is_bootstrap_native_; } bool link_lazily() const { @@ -3423,8 +3425,18 @@ class NativeCallInstr : public TemplateDefinition<0, Throws> { virtual EffectSet Effects() const { return EffectSet::All(); } + void SetupNative(); + private: + void set_native_c_function(NativeFunction value) { + native_c_function_ = value; + } + + void set_is_bootstrap_native(bool value) { is_bootstrap_native_ = value; } + const NativeBodyNode& ast_node_; + NativeFunction native_c_function_; + bool is_bootstrap_native_; DISALLOW_COPY_AND_ASSIGN(NativeCallInstr); }; diff --git a/runtime/vm/intermediate_language_arm.cc b/runtime/vm/intermediate_language_arm.cc index a82b455e6fb..1f547339a0f 100644 --- a/runtime/vm/intermediate_language_arm.cc +++ b/runtime/vm/intermediate_language_arm.cc @@ -925,6 +925,7 @@ LocationSummary* NativeCallInstr::MakeLocationSummary(Zone* zone, void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { + SetupNative(); const Register result = locs()->out(0).reg(); // Push the result place holder initialized to NULL. @@ -942,7 +943,7 @@ void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { uword entry; const intptr_t argc_tag = NativeArguments::ComputeArgcTag(function()); const bool is_leaf_call = - (argc_tag & NativeArguments::AutoSetupScopeMask()) == 0; + (argc_tag & NativeArguments::AutoSetupScopeMask()) == 0; const StubEntry* stub_entry; if (link_lazily()) { stub_entry = StubCode::CallBootstrapCFunction_entry(); diff --git a/runtime/vm/intermediate_language_arm64.cc b/runtime/vm/intermediate_language_arm64.cc index 892a2967853..7707e0b3d4c 100644 --- a/runtime/vm/intermediate_language_arm64.cc +++ b/runtime/vm/intermediate_language_arm64.cc @@ -779,6 +779,7 @@ LocationSummary* NativeCallInstr::MakeLocationSummary(Zone* zone, void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { + SetupNative(); const Register result = locs()->out(0).reg(); // Push the result place holder initialized to NULL. @@ -796,7 +797,7 @@ void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { uword entry; const intptr_t argc_tag = NativeArguments::ComputeArgcTag(function()); const bool is_leaf_call = - (argc_tag & NativeArguments::AutoSetupScopeMask()) == 0; + (argc_tag & NativeArguments::AutoSetupScopeMask()) == 0; const StubEntry* stub_entry; if (link_lazily()) { stub_entry = StubCode::CallBootstrapCFunction_entry(); diff --git a/runtime/vm/intermediate_language_ia32.cc b/runtime/vm/intermediate_language_ia32.cc index eab55fb8d0e..b5a851faf9f 100644 --- a/runtime/vm/intermediate_language_ia32.cc +++ b/runtime/vm/intermediate_language_ia32.cc @@ -818,6 +818,7 @@ LocationSummary* NativeCallInstr::MakeLocationSummary(Zone* zone, void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { + SetupNative(); Register result = locs()->out(0).reg(); const intptr_t argc_tag = NativeArguments::ComputeArgcTag(function()); const bool is_leaf_call = diff --git a/runtime/vm/intermediate_language_mips.cc b/runtime/vm/intermediate_language_mips.cc index 04713cd2f0f..c005041504d 100644 --- a/runtime/vm/intermediate_language_mips.cc +++ b/runtime/vm/intermediate_language_mips.cc @@ -975,6 +975,7 @@ LocationSummary* NativeCallInstr::MakeLocationSummary(Zone* zone, void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { + SetupNative(); __ Comment("NativeCallInstr"); Register result = locs()->out(0).reg(); @@ -993,7 +994,7 @@ void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { uword entry; const intptr_t argc_tag = NativeArguments::ComputeArgcTag(function()); const bool is_leaf_call = - (argc_tag & NativeArguments::AutoSetupScopeMask()) == 0; + (argc_tag & NativeArguments::AutoSetupScopeMask()) == 0; const StubEntry* stub_entry; if (link_lazily()) { stub_entry = StubCode::CallBootstrapCFunction_entry(); diff --git a/runtime/vm/intermediate_language_x64.cc b/runtime/vm/intermediate_language_x64.cc index cc1967501c1..3d30dc0a2e6 100644 --- a/runtime/vm/intermediate_language_x64.cc +++ b/runtime/vm/intermediate_language_x64.cc @@ -772,10 +772,11 @@ LocationSummary* NativeCallInstr::MakeLocationSummary(Zone* zone, void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { + SetupNative(); Register result = locs()->out(0).reg(); const intptr_t argc_tag = NativeArguments::ComputeArgcTag(function()); const bool is_leaf_call = - (argc_tag & NativeArguments::AutoSetupScopeMask()) == 0; + (argc_tag & NativeArguments::AutoSetupScopeMask()) == 0; // Push the result place holder initialized to NULL. __ PushObject(Object::null_object()); diff --git a/runtime/vm/native_entry.cc b/runtime/vm/native_entry.cc index 5d5a59685cd..63c9a61a185 100644 --- a/runtime/vm/native_entry.cc +++ b/runtime/vm/native_entry.cc @@ -234,7 +234,7 @@ void NativeEntry::LinkNativeCall(Dart_NativeArguments args) { const intptr_t argc_tag = NativeArguments::ComputeArgcTag(func); const bool is_leaf_call = - (argc_tag & NativeArguments::AutoSetupScopeMask()) == 0; + (argc_tag & NativeArguments::AutoSetupScopeMask()) == 0; call_through_wrapper = !is_bootstrap_native && !is_leaf_call; diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc index 748c38d53e8..8271d481700 100644 --- a/runtime/vm/parser.cc +++ b/runtime/vm/parser.cc @@ -7339,39 +7339,20 @@ void Parser::AddFormalParamsToScope(const ParamList* params, void Parser::ParseNativeFunctionBlock(const ParamList* params, const Function& func) { ASSERT(func.is_native()); - TRACE_PARSER("ParseNativeFunctionBlock"); - const Class& cls = Class::Handle(Z, func.Owner()); - const Library& library = Library::Handle(Z, cls.library()); ASSERT(func.NumParameters() == params->parameters->length()); + TRACE_PARSER("ParseNativeFunctionBlock"); // Parse the function name out. - const intptr_t native_pos = TokenPos(); const String& native_name = ParseNativeDeclaration(); - // Now resolve the native function to the corresponding native entrypoint. - const int num_params = NativeArguments::ParameterCountForResolution(func); - bool auto_setup_scope = true; - NativeFunction native_function = NativeEntry::ResolveNative( - library, native_name, num_params, &auto_setup_scope); - if (native_function == NULL) { - ReportError(native_pos, - "native function '%s' (%" Pd " arguments) cannot be found", - native_name.ToCString(), func.NumParameters()); - } - func.SetIsNativeAutoSetupScope(auto_setup_scope); - // Now add the NativeBodyNode and return statement. - Dart_NativeEntryResolver resolver = library.native_entry_resolver(); - bool is_bootstrap_native = Bootstrap::IsBootstapResolver(resolver); current_block_->statements->Add(new(Z) ReturnNode( TokenPos(), new(Z) NativeBodyNode( TokenPos(), Function::ZoneHandle(Z, func.raw()), native_name, - native_function, current_block_->scope, - is_bootstrap_native, FLAG_link_natives_lazily))); }