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 |
591 // For error reporting, simplify type name, e.g, all integer types (Smi, Mint, | 592 // For error reporting, simplify type name, e.g, all integer types (Smi, Mint, |
592 // Bigint) are reported as 'int' and all String types are mapped to 'String'. | 593 // Bigint) are reported as 'int' and all String types are mapped to 'String'. |
593 static RawString* GetSimpleTypeName(const Instance& value) { | 594 static RawString* GetSimpleTypeName(const Instance& value) { |
594 if (value.IsInteger()) { | 595 if (value.IsInteger()) { |
595 return String::NewSymbol("int"); | 596 return Symbols::New("int"); |
596 } else if (value.IsString()) { | 597 } else if (value.IsString()) { |
597 return String::NewSymbol("String"); | 598 return Symbols::New("String"); |
598 } else { | 599 } else { |
599 return Type::Handle(value.GetType()).Name(); | 600 return Type::Handle(value.GetType()).Name(); |
600 } | 601 } |
601 } | 602 } |
602 | 603 |
603 | 604 |
604 // Check that the type of the given instance is a subtype of the given type and | 605 // Check that the type of the given instance is a subtype of the given type and |
605 // can therefore be assigned. | 606 // can therefore be assigned. |
606 // Arg0: node-id of the assignment. | 607 // Arg0: node-id of the assignment. |
607 // Arg1: instance being assigned. | 608 // Arg1: instance being assigned. |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
669 // Return value: none, throws a TypeError. | 670 // Return value: none, throws a TypeError. |
670 DEFINE_RUNTIME_ENTRY(ConditionTypeError, 1) { | 671 DEFINE_RUNTIME_ENTRY(ConditionTypeError, 1) { |
671 ASSERT(arguments.Count() == | 672 ASSERT(arguments.Count() == |
672 kConditionTypeErrorRuntimeEntry.argument_count()); | 673 kConditionTypeErrorRuntimeEntry.argument_count()); |
673 const intptr_t location = GetCallerLocation(); | 674 const intptr_t location = GetCallerLocation(); |
674 const Instance& src_instance = Instance::CheckedHandle(arguments.At(0)); | 675 const Instance& src_instance = Instance::CheckedHandle(arguments.At(0)); |
675 ASSERT(src_instance.IsNull() || !src_instance.IsBool()); | 676 ASSERT(src_instance.IsNull() || !src_instance.IsBool()); |
676 const Type& bool_interface = Type::Handle(Type::BoolInterface()); | 677 const Type& bool_interface = Type::Handle(Type::BoolInterface()); |
677 const String& src_type_name = String::Handle(GetSimpleTypeName(src_instance)); | 678 const String& src_type_name = String::Handle(GetSimpleTypeName(src_instance)); |
678 const String& bool_type_name = String::Handle(bool_interface.Name()); | 679 const String& bool_type_name = String::Handle(bool_interface.Name()); |
679 const String& expr = String::Handle(String::NewSymbol("boolean expression")); | 680 const String& expr = String::Handle(Symbols::New("boolean expression")); |
680 const String& no_malformed_type_error = String::Handle(); | 681 const String& no_malformed_type_error = String::Handle(); |
681 Exceptions::CreateAndThrowTypeError(location, src_type_name, bool_type_name, | 682 Exceptions::CreateAndThrowTypeError(location, src_type_name, bool_type_name, |
682 expr, no_malformed_type_error); | 683 expr, no_malformed_type_error); |
683 UNREACHABLE(); | 684 UNREACHABLE(); |
684 } | 685 } |
685 | 686 |
686 | 687 |
687 // Report that the type of the type check is malformed. | 688 // Report that the type of the type check is malformed. |
688 // Arg0: src value. | 689 // Arg0: src value. |
689 // Arg1: name of instance being assigned to. | 690 // Arg1: name of instance being assigned to. |
690 // Arg2: malformed type error message. | 691 // Arg2: malformed type error message. |
691 // Return value: none, throws an exception. | 692 // Return value: none, throws an exception. |
692 DEFINE_RUNTIME_ENTRY(MalformedTypeError, 3) { | 693 DEFINE_RUNTIME_ENTRY(MalformedTypeError, 3) { |
693 ASSERT(arguments.Count() == | 694 ASSERT(arguments.Count() == |
694 kMalformedTypeErrorRuntimeEntry.argument_count()); | 695 kMalformedTypeErrorRuntimeEntry.argument_count()); |
695 const intptr_t location = GetCallerLocation(); | 696 const intptr_t location = GetCallerLocation(); |
696 const Instance& src_value = Instance::CheckedHandle(arguments.At(0)); | 697 const Instance& src_value = Instance::CheckedHandle(arguments.At(0)); |
697 const String& dst_name = String::CheckedHandle(arguments.At(1)); | 698 const String& dst_name = String::CheckedHandle(arguments.At(1)); |
698 const String& malformed_error = String::CheckedHandle(arguments.At(2)); | 699 const String& malformed_error = String::CheckedHandle(arguments.At(2)); |
699 const String& dst_type_name = String::Handle(String::NewSymbol("malformed")); | 700 const String& dst_type_name = String::Handle(Symbols::New("malformed")); |
700 const String& src_type_name = String::Handle(GetSimpleTypeName(src_value)); | 701 const String& src_type_name = String::Handle(GetSimpleTypeName(src_value)); |
701 Exceptions::CreateAndThrowTypeError(location, src_type_name, | 702 Exceptions::CreateAndThrowTypeError(location, src_type_name, |
702 dst_type_name, dst_name, malformed_error); | 703 dst_type_name, dst_name, malformed_error); |
703 UNREACHABLE(); | 704 UNREACHABLE(); |
704 } | 705 } |
705 | 706 |
706 | 707 |
707 DEFINE_RUNTIME_ENTRY(Throw, 1) { | 708 DEFINE_RUNTIME_ENTRY(Throw, 1) { |
708 ASSERT(arguments.Count() == kThrowRuntimeEntry.argument_count()); | 709 ASSERT(arguments.Count() == kThrowRuntimeEntry.argument_count()); |
709 const Instance& exception = Instance::CheckedHandle(arguments.At(0)); | 710 const Instance& exception = Instance::CheckedHandle(arguments.At(0)); |
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1017 if (!original_function_name.StartsWith(getter_prefix)) { | 1018 if (!original_function_name.StartsWith(getter_prefix)) { |
1018 // This is not a getter so can't be the case where we are trying to | 1019 // This is not a getter so can't be the case where we are trying to |
1019 // create an implicit closure of an instance function. | 1020 // create an implicit closure of an instance function. |
1020 arguments.SetReturn(closure); | 1021 arguments.SetReturn(closure); |
1021 return; | 1022 return; |
1022 } | 1023 } |
1023 const Class& receiver_class = Class::Handle(receiver.clazz()); | 1024 const Class& receiver_class = Class::Handle(receiver.clazz()); |
1024 ASSERT(!receiver_class.IsNull()); | 1025 ASSERT(!receiver_class.IsNull()); |
1025 String& func_name = String::Handle(); | 1026 String& func_name = String::Handle(); |
1026 func_name = String::SubString(original_function_name, getter_prefix.Length()); | 1027 func_name = String::SubString(original_function_name, getter_prefix.Length()); |
1027 func_name = String::NewSymbol(func_name); | 1028 func_name = Symbols::New(func_name); |
1028 const Function& function = Function::Handle( | 1029 const Function& function = Function::Handle( |
1029 LookupDynamicFunction(isolate, receiver_class, func_name)); | 1030 LookupDynamicFunction(isolate, receiver_class, func_name)); |
1030 if (function.IsNull()) { | 1031 if (function.IsNull()) { |
1031 // There is no function of the same name so can't be the case where | 1032 // There is no function of the same name so can't be the case where |
1032 // we are trying to create an implicit closure of an instance function. | 1033 // we are trying to create an implicit closure of an instance function. |
1033 arguments.SetReturn(closure); | 1034 arguments.SetReturn(closure); |
1034 return; | 1035 return; |
1035 } | 1036 } |
1036 Function& implicit_closure_function = | 1037 Function& implicit_closure_function = |
1037 Function::Handle(function.ImplicitClosureFunction()); | 1038 Function::Handle(function.ImplicitClosureFunction()); |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1192 const String& original_function_name = String::Handle(ic_data.target_name()); | 1193 const String& original_function_name = String::Handle(ic_data.target_name()); |
1193 ASSERT(!Array::CheckedHandle(arguments.At(2)).IsNull()); | 1194 ASSERT(!Array::CheckedHandle(arguments.At(2)).IsNull()); |
1194 const Array& orig_arguments = Array::CheckedHandle(arguments.At(3)); | 1195 const Array& orig_arguments = Array::CheckedHandle(arguments.At(3)); |
1195 // TODO(regis): The signature of the "noSuchMethod" method has to change from | 1196 // TODO(regis): The signature of the "noSuchMethod" method has to change from |
1196 // noSuchMethod(String name, Array arguments) to something like | 1197 // noSuchMethod(String name, Array arguments) to something like |
1197 // noSuchMethod(InvocationMirror call). | 1198 // noSuchMethod(InvocationMirror call). |
1198 const int kNumArguments = 3; | 1199 const int kNumArguments = 3; |
1199 const int kNumNamedArguments = 0; | 1200 const int kNumNamedArguments = 0; |
1200 const Array& kNoArgumentNames = Array::Handle(); | 1201 const Array& kNoArgumentNames = Array::Handle(); |
1201 const String& function_name = | 1202 const String& function_name = |
1202 String::Handle(String::NewSymbol("noSuchMethod")); | 1203 String::Handle(Symbols::New("noSuchMethod")); |
1203 const Function& function = Function::ZoneHandle( | 1204 const Function& function = Function::ZoneHandle( |
1204 Resolver::ResolveDynamic(receiver, | 1205 Resolver::ResolveDynamic(receiver, |
1205 function_name, | 1206 function_name, |
1206 kNumArguments, | 1207 kNumArguments, |
1207 kNumNamedArguments)); | 1208 kNumNamedArguments)); |
1208 ASSERT(!function.IsNull()); | 1209 ASSERT(!function.IsNull()); |
1209 GrowableArray<const Object*> invoke_arguments(2); | 1210 GrowableArray<const Object*> invoke_arguments(2); |
1210 invoke_arguments.Add(&original_function_name); | 1211 invoke_arguments.Add(&original_function_name); |
1211 invoke_arguments.Add(&orig_arguments); | 1212 invoke_arguments.Add(&orig_arguments); |
1212 const Object& result = Object::Handle( | 1213 const Object& result = Object::Handle( |
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1571 } | 1572 } |
1572 } | 1573 } |
1573 } | 1574 } |
1574 // The cache is null terminated, therefore the loop above should never | 1575 // The cache is null terminated, therefore the loop above should never |
1575 // terminate by itself. | 1576 // terminate by itself. |
1576 UNREACHABLE(); | 1577 UNREACHABLE(); |
1577 return Code::null(); | 1578 return Code::null(); |
1578 } | 1579 } |
1579 | 1580 |
1580 } // namespace dart | 1581 } // namespace dart |
OLD | NEW |