| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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.h" | 7 #include "vm/assembler.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" |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 140 const Array& args = Array::Handle(Array::New(4)); | 140 const Array& args = Array::Handle(Array::New(4)); |
| 141 args.SetAt(0, length); | 141 args.SetAt(0, length); |
| 142 args.SetAt(1, Integer::Handle(Integer::New(0))); | 142 args.SetAt(1, Integer::Handle(Integer::New(0))); |
| 143 args.SetAt(2, Integer::Handle(Integer::New(Array::kMaxElements))); | 143 args.SetAt(2, Integer::Handle(Integer::New(Array::kMaxElements))); |
| 144 args.SetAt(3, Symbols::Length()); | 144 args.SetAt(3, Symbols::Length()); |
| 145 Exceptions::ThrowByType(Exceptions::kRange, args); | 145 Exceptions::ThrowByType(Exceptions::kRange, args); |
| 146 } | 146 } |
| 147 | 147 |
| 148 | 148 |
| 149 // Helper returning the token position of the Dart caller. | 149 // Helper returning the token position of the Dart caller. |
| 150 static intptr_t GetCallerLocation() { | 150 static TokenDescriptor GetCallerLocation() { |
| 151 DartFrameIterator iterator; | 151 DartFrameIterator iterator; |
| 152 StackFrame* caller_frame = iterator.NextFrame(); | 152 StackFrame* caller_frame = iterator.NextFrame(); |
| 153 ASSERT(caller_frame != NULL); | 153 ASSERT(caller_frame != NULL); |
| 154 return caller_frame->GetTokenPos(); | 154 return caller_frame->GetTokenPos(); |
| 155 } | 155 } |
| 156 | 156 |
| 157 | 157 |
| 158 // Allocate a new object. | 158 // Allocate a new object. |
| 159 // Arg0: class of the object that needs to be allocated. | 159 // Arg0: class of the object that needs to be allocated. |
| 160 // Arg1: type arguments of the object that needs to be allocated. | 160 // Arg1: type arguments of the object that needs to be allocated. |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 200 DEFINE_RUNTIME_ENTRY(InstantiateType, 2) { | 200 DEFINE_RUNTIME_ENTRY(InstantiateType, 2) { |
| 201 AbstractType& type = AbstractType::CheckedHandle(arguments.ArgAt(0)); | 201 AbstractType& type = AbstractType::CheckedHandle(arguments.ArgAt(0)); |
| 202 const TypeArguments& instantiator = | 202 const TypeArguments& instantiator = |
| 203 TypeArguments::CheckedHandle(arguments.ArgAt(1)); | 203 TypeArguments::CheckedHandle(arguments.ArgAt(1)); |
| 204 ASSERT(!type.IsNull() && !type.IsInstantiated()); | 204 ASSERT(!type.IsNull() && !type.IsInstantiated()); |
| 205 ASSERT(instantiator.IsNull() || instantiator.IsInstantiated()); | 205 ASSERT(instantiator.IsNull() || instantiator.IsInstantiated()); |
| 206 Error& bound_error = Error::Handle(); | 206 Error& bound_error = Error::Handle(); |
| 207 type = type.InstantiateFrom(instantiator, &bound_error, NULL, Heap::kOld); | 207 type = type.InstantiateFrom(instantiator, &bound_error, NULL, Heap::kOld); |
| 208 if (!bound_error.IsNull()) { | 208 if (!bound_error.IsNull()) { |
| 209 // Throw a dynamic type error. | 209 // Throw a dynamic type error. |
| 210 const intptr_t location = GetCallerLocation(); | 210 const TokenDescriptor location = GetCallerLocation(); |
| 211 String& bound_error_message = String::Handle( | 211 String& bound_error_message = String::Handle( |
| 212 String::New(bound_error.ToErrorCString())); | 212 String::New(bound_error.ToErrorCString())); |
| 213 Exceptions::CreateAndThrowTypeError( | 213 Exceptions::CreateAndThrowTypeError( |
| 214 location, Symbols::Empty(), Symbols::Empty(), | 214 location, Symbols::Empty(), Symbols::Empty(), |
| 215 Symbols::Empty(), bound_error_message); | 215 Symbols::Empty(), bound_error_message); |
| 216 UNREACHABLE(); | 216 UNREACHABLE(); |
| 217 } | 217 } |
| 218 if (type.IsTypeRef()) { | 218 if (type.IsTypeRef()) { |
| 219 type = TypeRef::Cast(type).type(); | 219 type = TypeRef::Cast(type).type(); |
| 220 ASSERT(!type.IsTypeRef()); | 220 ASSERT(!type.IsTypeRef()); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 239 // Code inlined in the caller should have optimized the case where the | 239 // Code inlined in the caller should have optimized the case where the |
| 240 // instantiator can be reused as type argument vector. | 240 // instantiator can be reused as type argument vector. |
| 241 ASSERT(instantiator.IsNull() || !type_arguments.IsUninstantiatedIdentity()); | 241 ASSERT(instantiator.IsNull() || !type_arguments.IsUninstantiatedIdentity()); |
| 242 if (isolate->flags().type_checks()) { | 242 if (isolate->flags().type_checks()) { |
| 243 Error& bound_error = Error::Handle(); | 243 Error& bound_error = Error::Handle(); |
| 244 type_arguments = | 244 type_arguments = |
| 245 type_arguments.InstantiateAndCanonicalizeFrom(instantiator, | 245 type_arguments.InstantiateAndCanonicalizeFrom(instantiator, |
| 246 &bound_error); | 246 &bound_error); |
| 247 if (!bound_error.IsNull()) { | 247 if (!bound_error.IsNull()) { |
| 248 // Throw a dynamic type error. | 248 // Throw a dynamic type error. |
| 249 const intptr_t location = GetCallerLocation(); | 249 const TokenDescriptor location = GetCallerLocation(); |
| 250 String& bound_error_message = String::Handle( | 250 String& bound_error_message = String::Handle( |
| 251 String::New(bound_error.ToErrorCString())); | 251 String::New(bound_error.ToErrorCString())); |
| 252 Exceptions::CreateAndThrowTypeError( | 252 Exceptions::CreateAndThrowTypeError( |
| 253 location, Symbols::Empty(), Symbols::Empty(), | 253 location, Symbols::Empty(), Symbols::Empty(), |
| 254 Symbols::Empty(), bound_error_message); | 254 Symbols::Empty(), bound_error_message); |
| 255 UNREACHABLE(); | 255 UNREACHABLE(); |
| 256 } | 256 } |
| 257 } else { | 257 } else { |
| 258 type_arguments = | 258 type_arguments = |
| 259 type_arguments.InstantiateAndCanonicalizeFrom(instantiator, NULL); | 259 type_arguments.InstantiateAndCanonicalizeFrom(instantiator, NULL); |
| (...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 468 const Bool& result = | 468 const Bool& result = |
| 469 Bool::Get(instance.IsInstanceOf(type, | 469 Bool::Get(instance.IsInstanceOf(type, |
| 470 instantiator_type_arguments, | 470 instantiator_type_arguments, |
| 471 &bound_error)); | 471 &bound_error)); |
| 472 if (FLAG_trace_type_checks) { | 472 if (FLAG_trace_type_checks) { |
| 473 PrintTypeCheck("InstanceOf", | 473 PrintTypeCheck("InstanceOf", |
| 474 instance, type, instantiator_type_arguments, result); | 474 instance, type, instantiator_type_arguments, result); |
| 475 } | 475 } |
| 476 if (!result.value() && !bound_error.IsNull()) { | 476 if (!result.value() && !bound_error.IsNull()) { |
| 477 // Throw a dynamic type error only if the instanceof test fails. | 477 // Throw a dynamic type error only if the instanceof test fails. |
| 478 const intptr_t location = GetCallerLocation(); | 478 const TokenDescriptor location = GetCallerLocation(); |
| 479 String& bound_error_message = String::Handle( | 479 String& bound_error_message = String::Handle( |
| 480 String::New(bound_error.ToErrorCString())); | 480 String::New(bound_error.ToErrorCString())); |
| 481 Exceptions::CreateAndThrowTypeError( | 481 Exceptions::CreateAndThrowTypeError( |
| 482 location, Symbols::Empty(), Symbols::Empty(), | 482 location, Symbols::Empty(), Symbols::Empty(), |
| 483 Symbols::Empty(), bound_error_message); | 483 Symbols::Empty(), bound_error_message); |
| 484 UNREACHABLE(); | 484 UNREACHABLE(); |
| 485 } | 485 } |
| 486 UpdateTypeTestCache( | 486 UpdateTypeTestCache( |
| 487 instance, type, instantiator_type_arguments, result, cache); | 487 instance, type, instantiator_type_arguments, result, cache); |
| 488 arguments.SetReturn(result); | 488 arguments.SetReturn(result); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 515 const bool is_instance_of = src_instance.IsInstanceOf( | 515 const bool is_instance_of = src_instance.IsInstanceOf( |
| 516 dst_type, instantiator_type_arguments, &bound_error); | 516 dst_type, instantiator_type_arguments, &bound_error); |
| 517 | 517 |
| 518 if (FLAG_trace_type_checks) { | 518 if (FLAG_trace_type_checks) { |
| 519 PrintTypeCheck("TypeCheck", | 519 PrintTypeCheck("TypeCheck", |
| 520 src_instance, dst_type, instantiator_type_arguments, | 520 src_instance, dst_type, instantiator_type_arguments, |
| 521 Bool::Get(is_instance_of)); | 521 Bool::Get(is_instance_of)); |
| 522 } | 522 } |
| 523 if (!is_instance_of) { | 523 if (!is_instance_of) { |
| 524 // Throw a dynamic type error. | 524 // Throw a dynamic type error. |
| 525 const intptr_t location = GetCallerLocation(); | 525 const TokenDescriptor location = GetCallerLocation(); |
| 526 const AbstractType& src_type = AbstractType::Handle(src_instance.GetType()); | 526 const AbstractType& src_type = AbstractType::Handle(src_instance.GetType()); |
| 527 String& src_type_name = String::Handle(src_type.UserVisibleName()); | 527 String& src_type_name = String::Handle(src_type.UserVisibleName()); |
| 528 String& dst_type_name = String::Handle(); | 528 String& dst_type_name = String::Handle(); |
| 529 Library& dst_type_lib = Library::Handle(); | 529 Library& dst_type_lib = Library::Handle(); |
| 530 if (!dst_type.IsInstantiated()) { | 530 if (!dst_type.IsInstantiated()) { |
| 531 // Instantiate dst_type before reporting the error. | 531 // Instantiate dst_type before reporting the error. |
| 532 const AbstractType& instantiated_dst_type = AbstractType::Handle( | 532 const AbstractType& instantiated_dst_type = AbstractType::Handle( |
| 533 dst_type.InstantiateFrom(instantiator_type_arguments, NULL)); | 533 dst_type.InstantiateFrom(instantiator_type_arguments, NULL)); |
| 534 // Note that instantiated_dst_type may be malbounded. | 534 // Note that instantiated_dst_type may be malbounded. |
| 535 dst_type_name = instantiated_dst_type.UserVisibleName(); | 535 dst_type_name = instantiated_dst_type.UserVisibleName(); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 568 arguments.SetReturn(src_instance); | 568 arguments.SetReturn(src_instance); |
| 569 } | 569 } |
| 570 | 570 |
| 571 | 571 |
| 572 // Report that the type of the given object is not bool in conditional context. | 572 // Report that the type of the given object is not bool in conditional context. |
| 573 // Throw assertion error if the object is null. (cf. Boolean Conversion | 573 // Throw assertion error if the object is null. (cf. Boolean Conversion |
| 574 // in language Spec.) | 574 // in language Spec.) |
| 575 // Arg0: bad object. | 575 // Arg0: bad object. |
| 576 // Return value: none, throws TypeError or AssertionError. | 576 // Return value: none, throws TypeError or AssertionError. |
| 577 DEFINE_RUNTIME_ENTRY(NonBoolTypeError, 1) { | 577 DEFINE_RUNTIME_ENTRY(NonBoolTypeError, 1) { |
| 578 const intptr_t location = GetCallerLocation(); | 578 const TokenDescriptor location = GetCallerLocation(); |
| 579 const Instance& src_instance = Instance::CheckedHandle(arguments.ArgAt(0)); | 579 const Instance& src_instance = Instance::CheckedHandle(arguments.ArgAt(0)); |
| 580 | 580 |
| 581 if (src_instance.IsNull()) { | 581 if (src_instance.IsNull()) { |
| 582 const Array& args = Array::Handle(Array::New(4)); | 582 const Array& args = Array::Handle(Array::New(4)); |
| 583 args.SetAt(0, String::Handle( | 583 args.SetAt(0, String::Handle( |
| 584 String::New("Failed assertion: boolean expression must not be null"))); | 584 String::New("Failed assertion: boolean expression must not be null"))); |
| 585 | 585 |
| 586 // No source code for this assertion, set url to null. | 586 // No source code for this assertion, set url to null. |
| 587 args.SetAt(1, String::Handle(String::null())); | 587 args.SetAt(1, String::Handle(String::null())); |
| 588 args.SetAt(2, Smi::Handle(Smi::New(0))); | 588 args.SetAt(2, Smi::Handle(Smi::New(0))); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 605 UNREACHABLE(); | 605 UNREACHABLE(); |
| 606 } | 606 } |
| 607 | 607 |
| 608 | 608 |
| 609 // Report that the type of the type check is malformed or malbounded. | 609 // Report that the type of the type check is malformed or malbounded. |
| 610 // Arg0: src value. | 610 // Arg0: src value. |
| 611 // Arg1: name of destination being assigned to. | 611 // Arg1: name of destination being assigned to. |
| 612 // Arg2: type of destination being assigned to. | 612 // Arg2: type of destination being assigned to. |
| 613 // Return value: none, throws an exception. | 613 // Return value: none, throws an exception. |
| 614 DEFINE_RUNTIME_ENTRY(BadTypeError, 3) { | 614 DEFINE_RUNTIME_ENTRY(BadTypeError, 3) { |
| 615 const intptr_t location = GetCallerLocation(); | 615 const TokenDescriptor location = GetCallerLocation(); |
| 616 const Instance& src_value = Instance::CheckedHandle(arguments.ArgAt(0)); | 616 const Instance& src_value = Instance::CheckedHandle(arguments.ArgAt(0)); |
| 617 const String& dst_name = String::CheckedHandle(arguments.ArgAt(1)); | 617 const String& dst_name = String::CheckedHandle(arguments.ArgAt(1)); |
| 618 const AbstractType& dst_type = | 618 const AbstractType& dst_type = |
| 619 AbstractType::CheckedHandle(arguments.ArgAt(2)); | 619 AbstractType::CheckedHandle(arguments.ArgAt(2)); |
| 620 const AbstractType& src_type = AbstractType::Handle(src_value.GetType()); | 620 const AbstractType& src_type = AbstractType::Handle(src_value.GetType()); |
| 621 const String& src_type_name = String::Handle(src_type.UserVisibleName()); | 621 const String& src_type_name = String::Handle(src_type.UserVisibleName()); |
| 622 | 622 |
| 623 String& dst_type_name = String::Handle(); | 623 String& dst_type_name = String::Handle(); |
| 624 LanguageError& error = LanguageError::Handle(dst_type.error()); | 624 LanguageError& error = LanguageError::Handle(dst_type.error()); |
| 625 ASSERT(!error.IsNull()); | 625 ASSERT(!error.IsNull()); |
| (...skipping 747 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1373 if (do_stacktrace) { | 1373 if (do_stacktrace) { |
| 1374 String& var_name = String::Handle(); | 1374 String& var_name = String::Handle(); |
| 1375 Instance& var_value = Instance::Handle(); | 1375 Instance& var_value = Instance::Handle(); |
| 1376 DebuggerStackTrace* stack = isolate->debugger()->StackTrace(); | 1376 DebuggerStackTrace* stack = isolate->debugger()->StackTrace(); |
| 1377 intptr_t num_frames = stack->Length(); | 1377 intptr_t num_frames = stack->Length(); |
| 1378 for (intptr_t i = 0; i < num_frames; i++) { | 1378 for (intptr_t i = 0; i < num_frames; i++) { |
| 1379 ActivationFrame* frame = stack->FrameAt(i); | 1379 ActivationFrame* frame = stack->FrameAt(i); |
| 1380 // Variable locations and number are unknown when 'always_optimize'. | 1380 // Variable locations and number are unknown when 'always_optimize'. |
| 1381 const int num_vars = | 1381 const int num_vars = |
| 1382 Compiler::always_optimize() ? 0 : frame->NumLocalVariables(); | 1382 Compiler::always_optimize() ? 0 : frame->NumLocalVariables(); |
| 1383 intptr_t unused; | 1383 TokenDescriptor unused = TokenDescriptor::kNoSource; |
| 1384 for (intptr_t v = 0; v < num_vars; v++) { | 1384 for (intptr_t v = 0; v < num_vars; v++) { |
| 1385 frame->VariableAt(v, &var_name, &unused, &unused, &var_value); | 1385 frame->VariableAt(v, &var_name, &unused, &unused, &var_value); |
| 1386 } | 1386 } |
| 1387 } | 1387 } |
| 1388 } | 1388 } |
| 1389 | 1389 |
| 1390 const Error& error = Error::Handle(isolate->HandleInterrupts()); | 1390 const Error& error = Error::Handle(isolate->HandleInterrupts()); |
| 1391 if (!error.IsNull()) { | 1391 if (!error.IsNull()) { |
| 1392 Exceptions::PropagateError(error); | 1392 Exceptions::PropagateError(error); |
| 1393 UNREACHABLE(); | 1393 UNREACHABLE(); |
| (...skipping 493 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1887 const intptr_t elm_size = old_data.ElementSizeInBytes(); | 1887 const intptr_t elm_size = old_data.ElementSizeInBytes(); |
| 1888 const TypedData& new_data = | 1888 const TypedData& new_data = |
| 1889 TypedData::Handle(TypedData::New(cid, new_size, Heap::kOld)); | 1889 TypedData::Handle(TypedData::New(cid, new_size, Heap::kOld)); |
| 1890 TypedData::Copy(new_data, 0, old_data, 0, old_size * elm_size); | 1890 TypedData::Copy(new_data, 0, old_data, 0, old_size * elm_size); |
| 1891 typed_data_cell.SetAt(0, new_data); | 1891 typed_data_cell.SetAt(0, new_data); |
| 1892 arguments.SetReturn(new_data); | 1892 arguments.SetReturn(new_data); |
| 1893 } | 1893 } |
| 1894 | 1894 |
| 1895 | 1895 |
| 1896 } // namespace dart | 1896 } // namespace dart |
| OLD | NEW |