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 |