| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/code_generator.h" | 5 #include "vm/code_generator.h" |
| 6 | 6 |
| 7 #include "vm/assembler_macros.h" | 7 #include "vm/assembler_macros.h" |
| 8 #include "vm/ast.h" | 8 #include "vm/ast.h" |
| 9 #include "vm/code_patcher.h" | 9 #include "vm/code_patcher.h" |
| 10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
| 11 #include "vm/dart_api_impl.h" | 11 #include "vm/dart_api_impl.h" |
| 12 #include "vm/dart_entry.h" | 12 #include "vm/dart_entry.h" |
| 13 #include "vm/debugger.h" | 13 #include "vm/debugger.h" |
| 14 #include "vm/exceptions.h" | 14 #include "vm/exceptions.h" |
| 15 #include "vm/object_store.h" | 15 #include "vm/object_store.h" |
| 16 #include "vm/message.h" | 16 #include "vm/message.h" |
| 17 #include "vm/message_handler.h" | 17 #include "vm/message_handler.h" |
| 18 #include "vm/resolver.h" | 18 #include "vm/resolver.h" |
| 19 #include "vm/runtime_entry.h" | 19 #include "vm/runtime_entry.h" |
| 20 #include "vm/stack_frame.h" | 20 #include "vm/stack_frame.h" |
| 21 #include "vm/symbols.h" |
| 21 #include "vm/verifier.h" | 22 #include "vm/verifier.h" |
| 22 | 23 |
| 23 namespace dart { | 24 namespace dart { |
| 24 | 25 |
| 25 DEFINE_FLAG(bool, inline_cache, true, "Enable inline caches"); | 26 DEFINE_FLAG(bool, inline_cache, true, "Enable inline caches"); |
| 26 DEFINE_FLAG(bool, trace_deopt, false, "Trace deoptimization"); | 27 DEFINE_FLAG(bool, trace_deopt, false, "Trace deoptimization"); |
| 27 DEFINE_FLAG(bool, trace_ic, false, "Trace IC handling"); | 28 DEFINE_FLAG(bool, trace_ic, false, "Trace IC handling"); |
| 28 DEFINE_FLAG(bool, trace_patching, false, "Trace patching of code."); | 29 DEFINE_FLAG(bool, trace_patching, false, "Trace patching of code."); |
| 29 DEFINE_FLAG(bool, trace_runtime_calls, false, "Trace runtime calls"); | 30 DEFINE_FLAG(bool, trace_runtime_calls, false, "Trace runtime calls"); |
| 30 DEFINE_FLAG(int, optimization_counter_threshold, 2000, | 31 DEFINE_FLAG(int, optimization_counter_threshold, 2000, |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 207 ASSERT(type_arguments.IsInstantiated()); | 208 ASSERT(type_arguments.IsInstantiated()); |
| 208 Error& malformed_error = Error::Handle(); | 209 Error& malformed_error = Error::Handle(); |
| 209 if (!type_arguments.IsWithinBoundsOf(cls, | 210 if (!type_arguments.IsWithinBoundsOf(cls, |
| 210 bounds_instantiator, | 211 bounds_instantiator, |
| 211 &malformed_error)) { | 212 &malformed_error)) { |
| 212 ASSERT(!malformed_error.IsNull()); | 213 ASSERT(!malformed_error.IsNull()); |
| 213 // Throw a dynamic type error. | 214 // Throw a dynamic type error. |
| 214 const intptr_t location = GetCallerLocation(); | 215 const intptr_t location = GetCallerLocation(); |
| 215 String& malformed_error_message = String::Handle( | 216 String& malformed_error_message = String::Handle( |
| 216 String::New(malformed_error.ToErrorCString())); | 217 String::New(malformed_error.ToErrorCString())); |
| 217 const String& no_name = String::Handle(String::NewSymbol("")); | 218 const String& no_name = String::Handle(Symbols::New("")); |
| 218 Exceptions::CreateAndThrowTypeError( | 219 Exceptions::CreateAndThrowTypeError( |
| 219 location, no_name, no_name, no_name, malformed_error_message); | 220 location, no_name, no_name, no_name, malformed_error_message); |
| 220 UNREACHABLE(); | 221 UNREACHABLE(); |
| 221 } | 222 } |
| 222 } | 223 } |
| 223 instance.SetTypeArguments(type_arguments); | 224 instance.SetTypeArguments(type_arguments); |
| 224 } | 225 } |
| 225 | 226 |
| 226 | 227 |
| 227 // Instantiate type arguments. | 228 // Instantiate type arguments. |
| (...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 570 Bool::True() : Bool::False()); | 571 Bool::True() : Bool::False()); |
| 571 if (FLAG_trace_type_checks) { | 572 if (FLAG_trace_type_checks) { |
| 572 PrintTypeCheck("InstanceOf", | 573 PrintTypeCheck("InstanceOf", |
| 573 instance, type, instantiator_type_arguments, result); | 574 instance, type, instantiator_type_arguments, result); |
| 574 } | 575 } |
| 575 if (!result.value() && !malformed_error.IsNull()) { | 576 if (!result.value() && !malformed_error.IsNull()) { |
| 576 // Throw a dynamic type error only if the instanceof test fails. | 577 // Throw a dynamic type error only if the instanceof test fails. |
| 577 const intptr_t location = GetCallerLocation(); | 578 const intptr_t location = GetCallerLocation(); |
| 578 String& malformed_error_message = String::Handle( | 579 String& malformed_error_message = String::Handle( |
| 579 String::New(malformed_error.ToErrorCString())); | 580 String::New(malformed_error.ToErrorCString())); |
| 580 const String& no_name = String::Handle(String::NewSymbol("")); | 581 const String& no_name = String::Handle(Symbols::New("")); |
| 581 Exceptions::CreateAndThrowTypeError( | 582 Exceptions::CreateAndThrowTypeError( |
| 582 location, no_name, no_name, no_name, malformed_error_message); | 583 location, no_name, no_name, no_name, malformed_error_message); |
| 583 UNREACHABLE(); | 584 UNREACHABLE(); |
| 584 } | 585 } |
| 585 UpdateTypeTestCache(node_id, instance, type, instantiator, | 586 UpdateTypeTestCache(node_id, instance, type, instantiator, |
| 586 instantiator_type_arguments, result, cache); | 587 instantiator_type_arguments, result, cache); |
| 587 arguments.SetReturn(result); | 588 arguments.SetReturn(result); |
| 588 } | 589 } |
| 589 | 590 |
| 590 | 591 |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 659 ASSERT(arguments.Count() == | 660 ASSERT(arguments.Count() == |
| 660 kConditionTypeErrorRuntimeEntry.argument_count()); | 661 kConditionTypeErrorRuntimeEntry.argument_count()); |
| 661 const intptr_t location = GetCallerLocation(); | 662 const intptr_t location = GetCallerLocation(); |
| 662 const Instance& src_instance = Instance::CheckedHandle(arguments.At(0)); | 663 const Instance& src_instance = Instance::CheckedHandle(arguments.At(0)); |
| 663 ASSERT(src_instance.IsNull() || !src_instance.IsBool()); | 664 ASSERT(src_instance.IsNull() || !src_instance.IsBool()); |
| 664 const Type& bool_interface = Type::Handle(Type::BoolInterface()); | 665 const Type& bool_interface = Type::Handle(Type::BoolInterface()); |
| 665 const AbstractType& src_type = AbstractType::Handle(src_instance.GetType()); | 666 const AbstractType& src_type = AbstractType::Handle(src_instance.GetType()); |
| 666 const String& src_type_name = String::Handle(src_type.UserVisibleName()); | 667 const String& src_type_name = String::Handle(src_type.UserVisibleName()); |
| 667 const String& bool_type_name = | 668 const String& bool_type_name = |
| 668 String::Handle(bool_interface.UserVisibleName()); | 669 String::Handle(bool_interface.UserVisibleName()); |
| 669 const String& expr = String::Handle(String::NewSymbol("boolean expression")); | 670 const String& expr = String::Handle(Symbols::New("boolean expression")); |
| 670 const String& no_malformed_type_error = String::Handle(); | 671 const String& no_malformed_type_error = String::Handle(); |
| 671 Exceptions::CreateAndThrowTypeError(location, src_type_name, bool_type_name, | 672 Exceptions::CreateAndThrowTypeError(location, src_type_name, bool_type_name, |
| 672 expr, no_malformed_type_error); | 673 expr, no_malformed_type_error); |
| 673 UNREACHABLE(); | 674 UNREACHABLE(); |
| 674 } | 675 } |
| 675 | 676 |
| 676 | 677 |
| 677 // Report that the type of the type check is malformed. | 678 // Report that the type of the type check is malformed. |
| 678 // Arg0: src value. | 679 // Arg0: src value. |
| 679 // Arg1: name of instance being assigned to. | 680 // Arg1: name of instance being assigned to. |
| 680 // Arg2: malformed type error message. | 681 // Arg2: malformed type error message. |
| 681 // Return value: none, throws an exception. | 682 // Return value: none, throws an exception. |
| 682 DEFINE_RUNTIME_ENTRY(MalformedTypeError, 3) { | 683 DEFINE_RUNTIME_ENTRY(MalformedTypeError, 3) { |
| 683 ASSERT(arguments.Count() == | 684 ASSERT(arguments.Count() == |
| 684 kMalformedTypeErrorRuntimeEntry.argument_count()); | 685 kMalformedTypeErrorRuntimeEntry.argument_count()); |
| 685 const intptr_t location = GetCallerLocation(); | 686 const intptr_t location = GetCallerLocation(); |
| 686 const Instance& src_value = Instance::CheckedHandle(arguments.At(0)); | 687 const Instance& src_value = Instance::CheckedHandle(arguments.At(0)); |
| 687 const String& dst_name = String::CheckedHandle(arguments.At(1)); | 688 const String& dst_name = String::CheckedHandle(arguments.At(1)); |
| 688 const String& malformed_error = String::CheckedHandle(arguments.At(2)); | 689 const String& malformed_error = String::CheckedHandle(arguments.At(2)); |
| 689 const String& dst_type_name = String::Handle(String::NewSymbol("malformed")); | 690 const String& dst_type_name = String::Handle(Symbols::New("malformed")); |
| 690 const AbstractType& src_type = AbstractType::Handle(src_value.GetType()); | 691 const AbstractType& src_type = AbstractType::Handle(src_value.GetType()); |
| 691 const String& src_type_name = String::Handle(src_type.UserVisibleName()); | 692 const String& src_type_name = String::Handle(src_type.UserVisibleName()); |
| 692 Exceptions::CreateAndThrowTypeError(location, src_type_name, | 693 Exceptions::CreateAndThrowTypeError(location, src_type_name, |
| 693 dst_type_name, dst_name, malformed_error); | 694 dst_type_name, dst_name, malformed_error); |
| 694 UNREACHABLE(); | 695 UNREACHABLE(); |
| 695 } | 696 } |
| 696 | 697 |
| 697 | 698 |
| 698 DEFINE_RUNTIME_ENTRY(Throw, 1) { | 699 DEFINE_RUNTIME_ENTRY(Throw, 1) { |
| 699 ASSERT(arguments.Count() == kThrowRuntimeEntry.argument_count()); | 700 ASSERT(arguments.Count() == kThrowRuntimeEntry.argument_count()); |
| (...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1008 if (!original_function_name.StartsWith(getter_prefix)) { | 1009 if (!original_function_name.StartsWith(getter_prefix)) { |
| 1009 // This is not a getter so can't be the case where we are trying to | 1010 // This is not a getter so can't be the case where we are trying to |
| 1010 // create an implicit closure of an instance function. | 1011 // create an implicit closure of an instance function. |
| 1011 arguments.SetReturn(closure); | 1012 arguments.SetReturn(closure); |
| 1012 return; | 1013 return; |
| 1013 } | 1014 } |
| 1014 const Class& receiver_class = Class::Handle(receiver.clazz()); | 1015 const Class& receiver_class = Class::Handle(receiver.clazz()); |
| 1015 ASSERT(!receiver_class.IsNull()); | 1016 ASSERT(!receiver_class.IsNull()); |
| 1016 String& func_name = String::Handle(); | 1017 String& func_name = String::Handle(); |
| 1017 func_name = String::SubString(original_function_name, getter_prefix.Length()); | 1018 func_name = String::SubString(original_function_name, getter_prefix.Length()); |
| 1018 func_name = String::NewSymbol(func_name); | 1019 func_name = Symbols::New(func_name); |
| 1019 const Function& function = Function::Handle( | 1020 const Function& function = Function::Handle( |
| 1020 LookupDynamicFunction(isolate, receiver_class, func_name)); | 1021 LookupDynamicFunction(isolate, receiver_class, func_name)); |
| 1021 if (function.IsNull()) { | 1022 if (function.IsNull()) { |
| 1022 // There is no function of the same name so can't be the case where | 1023 // There is no function of the same name so can't be the case where |
| 1023 // we are trying to create an implicit closure of an instance function. | 1024 // we are trying to create an implicit closure of an instance function. |
| 1024 arguments.SetReturn(closure); | 1025 arguments.SetReturn(closure); |
| 1025 return; | 1026 return; |
| 1026 } | 1027 } |
| 1027 Function& implicit_closure_function = | 1028 Function& implicit_closure_function = |
| 1028 Function::Handle(function.ImplicitClosureFunction()); | 1029 Function::Handle(function.ImplicitClosureFunction()); |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1183 const String& original_function_name = String::Handle(ic_data.target_name()); | 1184 const String& original_function_name = String::Handle(ic_data.target_name()); |
| 1184 ASSERT(!Array::CheckedHandle(arguments.At(2)).IsNull()); | 1185 ASSERT(!Array::CheckedHandle(arguments.At(2)).IsNull()); |
| 1185 const Array& orig_arguments = Array::CheckedHandle(arguments.At(3)); | 1186 const Array& orig_arguments = Array::CheckedHandle(arguments.At(3)); |
| 1186 // TODO(regis): The signature of the "noSuchMethod" method has to change from | 1187 // TODO(regis): The signature of the "noSuchMethod" method has to change from |
| 1187 // noSuchMethod(String name, Array arguments) to something like | 1188 // noSuchMethod(String name, Array arguments) to something like |
| 1188 // noSuchMethod(InvocationMirror call). | 1189 // noSuchMethod(InvocationMirror call). |
| 1189 const int kNumArguments = 3; | 1190 const int kNumArguments = 3; |
| 1190 const int kNumNamedArguments = 0; | 1191 const int kNumNamedArguments = 0; |
| 1191 const Array& kNoArgumentNames = Array::Handle(); | 1192 const Array& kNoArgumentNames = Array::Handle(); |
| 1192 const String& function_name = | 1193 const String& function_name = |
| 1193 String::Handle(String::NewSymbol("noSuchMethod")); | 1194 String::Handle(Symbols::New("noSuchMethod")); |
| 1194 const Function& function = Function::ZoneHandle( | 1195 const Function& function = Function::ZoneHandle( |
| 1195 Resolver::ResolveDynamic(receiver, | 1196 Resolver::ResolveDynamic(receiver, |
| 1196 function_name, | 1197 function_name, |
| 1197 kNumArguments, | 1198 kNumArguments, |
| 1198 kNumNamedArguments)); | 1199 kNumNamedArguments)); |
| 1199 ASSERT(!function.IsNull()); | 1200 ASSERT(!function.IsNull()); |
| 1200 GrowableArray<const Object*> invoke_arguments(2); | 1201 GrowableArray<const Object*> invoke_arguments(2); |
| 1201 invoke_arguments.Add(&original_function_name); | 1202 invoke_arguments.Add(&original_function_name); |
| 1202 invoke_arguments.Add(&orig_arguments); | 1203 invoke_arguments.Add(&orig_arguments); |
| 1203 const Object& result = Object::Handle( | 1204 const Object& result = Object::Handle( |
| (...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1568 } | 1569 } |
| 1569 } | 1570 } |
| 1570 } | 1571 } |
| 1571 // The cache is null terminated, therefore the loop above should never | 1572 // The cache is null terminated, therefore the loop above should never |
| 1572 // terminate by itself. | 1573 // terminate by itself. |
| 1573 UNREACHABLE(); | 1574 UNREACHABLE(); |
| 1574 return Code::null(); | 1575 return Code::null(); |
| 1575 } | 1576 } |
| 1576 | 1577 |
| 1577 } // namespace dart | 1578 } // namespace dart |
| OLD | NEW |