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 |