Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(238)

Side by Side Diff: runtime/vm/code_generator.cc

Issue 10191020: Revert change 6946. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | runtime/vm/code_generator_ia32.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/code_patcher.h" 7 #include "vm/code_patcher.h"
8 #include "vm/compiler.h" 8 #include "vm/compiler.h"
9 #include "vm/dart_api_impl.h" 9 #include "vm/dart_api_impl.h"
10 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after
296 const Context& ctx = Context::CheckedHandle(arguments.At(0)); 296 const Context& ctx = Context::CheckedHandle(arguments.At(0));
297 Context& cloned_ctx = Context::Handle(Context::New(ctx.num_variables())); 297 Context& cloned_ctx = Context::Handle(Context::New(ctx.num_variables()));
298 cloned_ctx.set_parent(Context::Handle(ctx.parent())); 298 cloned_ctx.set_parent(Context::Handle(ctx.parent()));
299 for (int i = 0; i < ctx.num_variables(); i++) { 299 for (int i = 0; i < ctx.num_variables(); i++) {
300 cloned_ctx.SetAt(i, Instance::Handle(ctx.At(i))); 300 cloned_ctx.SetAt(i, Instance::Handle(ctx.At(i)));
301 } 301 }
302 arguments.SetReturn(cloned_ctx); 302 arguments.SetReturn(cloned_ctx);
303 } 303 }
304 304
305 305
306 // Helper routine for tracing a type check.
307 static void PrintTypeCheck(const char* message,
308 const Instance& instance,
309 const AbstractType&type,
310 const AbstractTypeArguments& type_instantiator,
311 const Bool& result) {
312 const Type& instance_type = Type::Handle(instance.GetType());
313 ASSERT(instance_type.IsInstantiated());
314 if (type.IsInstantiated()) {
315 OS::Print("%s: '%s' %s '%s'.\n",
316 message,
317 String::Handle(instance_type.Name()).ToCString(),
318 (result.raw() == Bool::True()) ? "is" : "is !",
319 String::Handle(type.Name()).ToCString());
320 } else {
321 // Instantiate type before printing.
322 const AbstractType& instantiated_type =
323 AbstractType::Handle(type.InstantiateFrom(type_instantiator));
324 OS::Print("%s: '%s' %s '%s' instantiated from '%s'.\n",
325 message,
326 String::Handle(instance_type.Name()).ToCString(),
327 (result.raw() == Bool::True()) ? "is" : "is !",
328 String::Handle(instantiated_type.Name()).ToCString(),
329 String::Handle(type.Name()).ToCString());
330 }
331 DartFrameIterator iterator;
332 StackFrame* caller_frame = iterator.NextFrame();
333 ASSERT(caller_frame != NULL);
334 const Function& function = Function::Handle(
335 caller_frame->LookupDartFunction());
336 OS::Print(" -> Function %s\n", function.ToFullyQualifiedCString());
337 }
338
339
340 // Converts InstantiatedTypeArguments to TypeArguments and stores it
341 // into the instance. The assembly code can handle only type arguments of
342 // class TypeArguments. Because of the overhead, do it only when needed.
343 static void OptimizeTypeArguments(const Instance& instance) {
344 const Type& instance_type = Type::Handle(instance.GetType());
345 const Class& type_class = Class::ZoneHandle(instance_type.type_class());
346 if (type_class.HasTypeArguments()) {
347 const AbstractTypeArguments& type_arguments =
348 AbstractTypeArguments::Handle(instance_type.arguments());
349 if (!type_arguments.IsNull() &&
350 type_arguments.IsInstantiatedTypeArguments()) {
351 TypeArguments& new_type_arguments =
352 TypeArguments::Handle(TypeArguments::New(type_arguments.Length()));
353 for (int i = 0; i < type_arguments.Length(); i++) {
354 const AbstractType& type_at =
355 AbstractType::Handle(type_arguments.TypeAt(i));
356 // TODO(srdjan): Implement also for other classes of AbstractType.
357 if (!type_at.IsType() && !type_at.IsInstantiatedType()) {
358 UNIMPLEMENTED();
359 return;
360 }
361 new_type_arguments.SetTypeAt(i, type_at);
362 }
363 instance.SetTypeArguments(new_type_arguments);
364 }
365 }
366 }
367
368
369 // This updates the type test cache, an array containing tuples (instance class,
370 // test result_. It can be applied to classes with type arguments in which
371 // case it contains just the result of the class subtype test, not including
372 // the evaluation of type arguments.
373 // Note that the 'result' contains the whole type test (inlcluding type
374 // arguments), but the type test cache contains only the result of the
375 // class test. Therefore we may need to recompute the 'result'.
376 // This operation is currently very slow (lookup of code is not efficient yet).
377 static void UpdateTypeTestCache(intptr_t node_id,
378 const Instance& instance,
379 const AbstractType& type,
380 const AbstractTypeArguments& type_instantiator,
381 const Bool& result) {
382 // Since the test is expensive, don't do it unless necessary.
383 // The list of disallowed cases will decrease as they are implemented in
384 // inlined assembly.
385 if (!type.IsInstantiated()) return;
386 // TODO(srdjan): Implement assembly code for checking type arguments then
387 // remove this check.
388 if (Class::Handle(type.type_class()).HasTypeArguments()) {
389 const AbstractTypeArguments& type_arguments =
390 AbstractTypeArguments::Handle(type.arguments());
391 const bool is_raw_type = type_arguments.IsNull() ||
392 type_arguments.IsRaw(type_arguments.Length());
393 if (!is_raw_type) {
394 return;
395 }
396 }
397 DartFrameIterator iterator;
398 StackFrame* caller_frame = iterator.NextFrame();
399 ASSERT(caller_frame != NULL);
400 const Code& code = Code::Handle(caller_frame->LookupDartCode());
401 ASSERT(!code.IsNull());
402 uword loc = code.GetTypeTestAtNodeId(node_id);
403 if (loc != 0) {
404 // Found type test cache.
405 Array& value = Array::Handle(CodePatcher::GetTypeTestArray(loc));
406 // TODO(srdjan): Prevent type test cache from growing too much, it has been
407 // observed to grow to 100 elements.
408 const Class& instance_class = Class::Handle(instance.clazz());
409 // Don't enter duplicate entries.
410 Class& last_checked = Class::Handle();
411 for (intptr_t i = 0; i < value.Length(); i += 2) {
412 last_checked ^= value.At(i);
413 if (last_checked.raw() == instance_class.raw()) {
414 if (FLAG_trace_type_checks) {
415 PrintTypeCheck("WARING duplicate cache entry", instance, type,
416 type_instantiator, result);
417 }
418 return;
419 }
420 }
421
422 // Array must be null terminated.
423 ASSERT(last_checked.IsNull());
424
425 // Check if the result for cache needs to be recomputed.
426 const Class& cls = Class::Handle(type.type_class());
427 Bool& class_test_result = Bool::Handle(result.raw());
428 if (!result.value() && cls.HasTypeArguments()) {
429 Error& malformed_error = Error::Handle();
430 if (instance_class.IsSubtypeOf(TypeArguments::Handle(),
431 cls,
432 TypeArguments::Handle(),
433 &malformed_error)) {
434 class_test_result = Bool::True();
435 }
436 }
437 ASSERT(!value.IsNull());
438 intptr_t old_len = value.Length();
439 value = value.Grow(value, old_len + 2);
440 value.SetAt(old_len - 2, instance_class);
441 value.SetAt(old_len - 1, class_test_result);
442 CodePatcher::SetTypeTestArray(loc, value);
443 OptimizeTypeArguments(instance);
444 }
445 }
446
447
448 // Check that the given instance is an instance of the given type. 306 // Check that the given instance is an instance of the given type.
449 // Tested instance may not be null, because the null test is inlined. 307 // Tested instance may not be null, because the null test is inlined.
450 // Arg0: index of the token of the instanceof test (source location). 308 // Arg0: index of the token of the instanceof test (source location).
451 // Arg1: node id of the instanceof node. 309 // Arg1: node id of the instanceof node.
452 // Arg2: instance being checked. 310 // Arg2: instance being checked.
453 // Arg3: type. 311 // Arg3: type.
454 // Arg4: type arguments of the instantiator of the type. 312 // Arg4: type arguments of the instantiator of the type.
455 // Return value: true or false, or may throw a type error in checked mode. 313 // Return value: true or false, or may throw a type error in checked mode.
456 DEFINE_RUNTIME_ENTRY(Instanceof, 5) { 314 DEFINE_RUNTIME_ENTRY(Instanceof, 5) {
457 ASSERT(arguments.Count() == kInstanceofRuntimeEntry.argument_count()); 315 ASSERT(arguments.Count() == kInstanceofRuntimeEntry.argument_count());
458 // TODO(regis): Get the token index from the PcDesc (via StackFrame). 316 // TODO(regis): Get the token index from the PcDesc (via DartFrame).
459 intptr_t location = Smi::CheckedHandle(arguments.At(0)).Value(); 317 intptr_t location = Smi::CheckedHandle(arguments.At(0)).Value();
460 intptr_t node_id = Smi::CheckedHandle(arguments.At(1)).Value(); 318 intptr_t node_id = Smi::CheckedHandle(arguments.At(1)).Value();
461 const Instance& instance = Instance::CheckedHandle(arguments.At(2)); 319 const Instance& instance = Instance::CheckedHandle(arguments.At(2));
462 const AbstractType& type = AbstractType::CheckedHandle(arguments.At(3)); 320 const AbstractType& type = AbstractType::CheckedHandle(arguments.At(3));
463 const AbstractTypeArguments& type_instantiator = 321 const AbstractTypeArguments& type_instantiator =
464 AbstractTypeArguments::CheckedHandle(arguments.At(4)); 322 AbstractTypeArguments::CheckedHandle(arguments.At(4));
465 ASSERT(type.IsFinalized()); 323 ASSERT(type.IsFinalized());
466 Error& malformed_error = Error::Handle(); 324 Error& malformed_error = Error::Handle();
467 const Bool& result = Bool::Handle( 325 const Bool& result = Bool::Handle(
468 instance.IsInstanceOf(type, type_instantiator, &malformed_error) ? 326 instance.IsInstanceOf(type, type_instantiator, &malformed_error) ?
469 Bool::True() : Bool::False()); 327 Bool::True() : Bool::False());
470 if (FLAG_trace_type_checks) { 328 if (FLAG_trace_type_checks) {
471 PrintTypeCheck("InstanceOf", instance, type, type_instantiator, result); 329 const Type& instance_type = Type::Handle(instance.GetType());
330 ASSERT(instance_type.IsInstantiated());
331 if (type.IsInstantiated()) {
332 OS::Print("InstanceOf: '%s' %s '%s'.\n",
333 String::Handle(instance_type.Name()).ToCString(),
334 (result.raw() == Bool::True()) ? "is" : "is !",
335 String::Handle(type.Name()).ToCString());
336 } else {
337 // Instantiate type before printing.
338 const AbstractType& instantiated_type =
339 AbstractType::Handle(type.InstantiateFrom(type_instantiator));
340 OS::Print("InstanceOf: '%s' %s '%s' instantiated from '%s'.\n",
341 String::Handle(instance_type.Name()).ToCString(),
342 (result.raw() == Bool::True()) ? "is" : "is !",
343 String::Handle(instantiated_type.Name()).ToCString(),
344 String::Handle(type.Name()).ToCString());
345 }
346 DartFrameIterator iterator;
347 StackFrame* caller_frame = iterator.NextFrame();
348 ASSERT(caller_frame != NULL && caller_frame->IsDartFrame());
349 const Function& function = Function::Handle(
350 caller_frame->LookupDartFunction());
351 OS::Print(" -> Function %s\n", function.ToFullyQualifiedCString());
472 } 352 }
473 if (!result.value() && !malformed_error.IsNull()) { 353 if (!result.value() && !malformed_error.IsNull()) {
474 // Throw a dynamic type error only if the instanceof test fails. 354 // Throw a dynamic type error only if the instanceof test fails.
475 String& malformed_error_message = String::Handle( 355 String& malformed_error_message = String::Handle(
476 String::New(malformed_error.ToErrorCString())); 356 String::New(malformed_error.ToErrorCString()));
477 const String& no_name = String::Handle(String::NewSymbol("")); 357 const String& no_name = String::Handle(String::NewSymbol(""));
478 Exceptions::CreateAndThrowTypeError( 358 Exceptions::CreateAndThrowTypeError(
479 location, no_name, no_name, no_name, malformed_error_message); 359 location, no_name, no_name, no_name, malformed_error_message);
480 UNREACHABLE(); 360 UNREACHABLE();
481 } 361 }
482 UpdateTypeTestCache(node_id, instance, type, type_instantiator, result); 362 // Update cache: add class of instance and result.
363 if (type.IsInstantiated() &&
364 !Class::Handle(type.type_class()).HasTypeArguments()) {
365 DartFrameIterator iterator;
366 StackFrame* caller_frame = iterator.NextFrame();
367 ASSERT(caller_frame != NULL && caller_frame->IsDartFrame());
368 const Code& code = Code::Handle(caller_frame->LookupDartCode());
369 ASSERT(!code.IsNull());
370 uword loc = code.GetTypeTestAtNodeId(node_id);
371 // TODO(srdjan): Check when 'loc' can be 0, once implemented everywhere.
372 if (loc != 0) {
373 // Found type test cache.
374 Array& value = Array::Handle(CodePatcher::GetTypeTestArray(loc));
375 const Class& instance_class = Class::Handle(instance.clazz());
376
377 #if defined(DEBUG)
378 // Check for duplicate entries.
379 Class& last_checked = Class::Handle();
380 for (intptr_t i = 0; i < value.Length(); i += 2) {
381 last_checked ^= value.At(i);
382 ASSERT(last_checked.raw() != instance_class.raw());
383 }
384 // Array must be null terminated.
385 ASSERT(last_checked.IsNull());
386 #endif
387
388 ASSERT(!value.IsNull());
389 intptr_t old_len = value.Length();
390 value = value.Grow(value, old_len + 2);
391 value.SetAt(old_len - 2, instance_class);
392 value.SetAt(old_len - 1, result);
393 CodePatcher::SetTypeTestArray(loc, value);
394 }
395 }
483 arguments.SetReturn(result); 396 arguments.SetReturn(result);
484 } 397 }
485 398
486 399
487 // For error reporting simplify type name, e.g, all integer types (Smi, Mint, 400 // For error reporting simplify type name, e.g, all integer types (Smi, Mint,
488 // Bigint) a re reported as 'int'. 401 // Bigint) a re reported as 'int'.
489 static RawString* GetSimpleTypeName(const Instance& value) { 402 static RawString* GetSimpleTypeName(const Instance& value) {
490 if (value.IsInteger()) { 403 if (value.IsInteger()) {
491 return String::NewSymbol("int"); 404 return String::NewSymbol("int");
492 } else { 405 } else {
493 return Type::Handle(value.GetType()).Name(); 406 return Type::Handle(value.GetType()).Name();
494 } 407 }
495 } 408 }
496 409
497 410
498 // Check that the type of the given instance is a subtype of the given type and 411 // Check that the type of the given instance is a subtype of the given type and
499 // can therefore be assigned. 412 // can therefore be assigned.
500 // Arg0: index of the token of the assignment (source location). 413 // Arg0: index of the token of the assignment (source location).
501 // Arg1: node-id of the assignemnt. 414 // Arg1: node-id of the assignemnt.
502 // Arg1: instance being assigned. 415 // Arg1: instance being assigned.
503 // Arg2: type being assigned to. 416 // Arg2: type being assigned to.
504 // Arg3: type arguments of the instantiator of the type being assigned to. 417 // Arg3: type arguments of the instantiator of the type being assigned to.
505 // Arg4: name of variable being assigned to. 418 // Arg4: name of variable being assigned to.
506 // Return value: instance if a subtype, otherwise throw a TypeError. 419 // Return value: instance if a subtype, otherwise throw a TypeError.
507 DEFINE_RUNTIME_ENTRY(TypeCheck, 6) { 420 DEFINE_RUNTIME_ENTRY(TypeCheck, 6) {
508 ASSERT(arguments.Count() == kTypeCheckRuntimeEntry.argument_count()); 421 ASSERT(arguments.Count() == kTypeCheckRuntimeEntry.argument_count());
509 // TODO(regis): Get the token index from the PcDesc (via StackFrame). 422 // TODO(regis): Get the token index from the PcDesc (via DartFrame).
510 intptr_t location = Smi::CheckedHandle(arguments.At(0)).Value(); 423 intptr_t location = Smi::CheckedHandle(arguments.At(0)).Value();
511 intptr_t node_id = Smi::CheckedHandle(arguments.At(1)).Value(); 424 intptr_t node_id = Smi::CheckedHandle(arguments.At(1)).Value();
512 const Instance& src_instance = Instance::CheckedHandle(arguments.At(2)); 425 const Instance& src_instance = Instance::CheckedHandle(arguments.At(2));
513 const AbstractType& dst_type = AbstractType::CheckedHandle(arguments.At(3)); 426 const AbstractType& dst_type = AbstractType::CheckedHandle(arguments.At(3));
514 const AbstractTypeArguments& dst_type_instantiator = 427 const AbstractTypeArguments& dst_type_instantiator =
515 AbstractTypeArguments::CheckedHandle(arguments.At(4)); 428 AbstractTypeArguments::CheckedHandle(arguments.At(4));
516 const String& dst_name = String::CheckedHandle(arguments.At(5)); 429 const String& dst_name = String::CheckedHandle(arguments.At(5));
517 ASSERT(!dst_type.IsDynamicType()); // No need to check assignment. 430 ASSERT(!dst_type.IsDynamicType()); // No need to check assignment.
518 ASSERT(!dst_type.IsMalformed()); // Already checked in code generator. 431 ASSERT(!dst_type.IsMalformed()); // Already checked in code generator.
519 ASSERT(!src_instance.IsNull()); // Already checked in inlined code. 432 ASSERT(!src_instance.IsNull()); // Already checked in inlined code.
520 433
521 Error& malformed_error = Error::Handle(); 434 Error& malformed_error = Error::Handle();
522 const bool is_instance_of = src_instance.IsInstanceOf( 435 const bool is_instance_of = src_instance.IsInstanceOf(
523 dst_type, dst_type_instantiator, &malformed_error); 436 dst_type, dst_type_instantiator, &malformed_error);
524 437
525 if (FLAG_trace_type_checks) { 438 if (FLAG_trace_type_checks) {
526 PrintTypeCheck("TypeCheck", src_instance, dst_type, dst_type_instantiator, 439 const Type& src_type = Type::Handle(src_instance.GetType());
527 Bool::Handle(is_instance_of ? Bool::True() : Bool::False())); 440 ASSERT(src_type.IsInstantiated());
441 if (dst_type.IsInstantiated()) {
442 OS::Print("TypeCheck: type '%s' %s a subtype of type '%s' of '%s'.\n",
443 String::Handle(src_type.Name()).ToCString(),
444 is_instance_of ? "is" : "is not",
445 String::Handle(dst_type.Name()).ToCString(),
446 dst_name.ToCString());
447 } else {
448 // Instantiate dst_type before printing.
449 const AbstractType& instantiated_dst_type = AbstractType::Handle(
450 dst_type.InstantiateFrom(dst_type_instantiator));
451 OS::Print("TypeCheck: type '%s' %s a subtype of type '%s' of '%s' "
452 "instantiated from '%s'.\n",
453 String::Handle(src_type.Name()).ToCString(),
454 is_instance_of ? "is" : "is not",
455 String::Handle(instantiated_dst_type.Name()).ToCString(),
456 dst_name.ToCString(),
457 String::Handle(dst_type.Name()).ToCString());
458 }
459 DartFrameIterator iterator;
460 StackFrame* caller_frame = iterator.NextFrame();
461 ASSERT(caller_frame != NULL && caller_frame->IsDartFrame());
462 const Function& function = Function::Handle(
463 caller_frame->LookupDartFunction());
464 OS::Print(" -> Function %s\n", function.ToFullyQualifiedCString());
528 } 465 }
529 if (!is_instance_of) { 466 if (!is_instance_of) {
530 String& src_type_name = String::Handle(GetSimpleTypeName(src_instance)); 467 String& src_type_name = String::Handle(GetSimpleTypeName(src_instance));
531 String& dst_type_name = String::Handle(); 468 String& dst_type_name = String::Handle();
532 if (!dst_type.IsInstantiated()) { 469 if (!dst_type.IsInstantiated()) {
533 // Instantiate dst_type before reporting the error. 470 // Instantiate dst_type before reporting the error.
534 const AbstractType& instantiated_dst_type = AbstractType::Handle( 471 const AbstractType& instantiated_dst_type = AbstractType::Handle(
535 dst_type.InstantiateFrom(dst_type_instantiator)); 472 dst_type.InstantiateFrom(dst_type_instantiator));
536 dst_type_name = instantiated_dst_type.Name(); 473 dst_type_name = instantiated_dst_type.Name();
537 } else { 474 } else {
538 dst_type_name = dst_type.Name(); 475 dst_type_name = dst_type.Name();
539 } 476 }
540 String& malformed_error_message = String::Handle(); 477 String& malformed_error_message = String::Handle();
541 if (!malformed_error.IsNull()) { 478 if (!malformed_error.IsNull()) {
542 ASSERT(FLAG_enable_type_checks); 479 ASSERT(FLAG_enable_type_checks);
543 malformed_error_message = String::New(malformed_error.ToErrorCString()); 480 malformed_error_message = String::New(malformed_error.ToErrorCString());
544 } 481 }
545 Exceptions::CreateAndThrowTypeError(location, src_type_name, dst_type_name, 482 Exceptions::CreateAndThrowTypeError(location, src_type_name, dst_type_name,
546 dst_name, malformed_error_message); 483 dst_name, malformed_error_message);
547 UNREACHABLE(); 484 UNREACHABLE();
548 } 485 }
549 UpdateTypeTestCache(node_id, src_instance, dst_type, dst_type_instantiator, 486 // Update cache: add class of instance and result.
550 Bool::ZoneHandle(Bool::True())); 487 if (dst_type.IsInstantiated() &&
488 !Class::Handle(dst_type.type_class()).HasTypeArguments()) {
489 DartFrameIterator iterator;
490 StackFrame* caller_frame = iterator.NextFrame();
491 ASSERT(caller_frame != NULL && caller_frame->IsDartFrame());
492 const Code& code = Code::Handle(caller_frame->LookupDartCode());
493 ASSERT(!code.IsNull());
494 uword loc = code.GetTypeTestAtNodeId(node_id);
495 if (loc != 0) {
496 // Found type test cache.
497 Array& value = Array::Handle(CodePatcher::GetTypeTestArray(loc));
498 const Class& src_instance_class = Class::Handle(src_instance.clazz());
499
500 #if defined(DEBUG)
501 // Check for duplicate entries.
502 Class& last_checked = Class::Handle();
503 for (intptr_t i = 0; i < value.Length(); i += 2) {
504 last_checked ^= value.At(i);
505 ASSERT(last_checked.raw() != src_instance_class.raw());
506 }
507 // Array must be null terminated.
508 ASSERT(last_checked.IsNull());
509 #endif
510
511 ASSERT(!value.IsNull());
512 intptr_t old_len = value.Length();
513 value = value.Grow(value, old_len + 2);
514 value.SetAt(old_len - 2, src_instance_class);
515 value.SetAt(old_len - 1, Bool::ZoneHandle(Bool::True()));
516 CodePatcher::SetTypeTestArray(loc, value);
517 }
518 }
551 arguments.SetReturn(src_instance); 519 arguments.SetReturn(src_instance);
552 } 520 }
553 521
554 522
555 // Report that the type of the given object is not bool in conditional context. 523 // Report that the type of the given object is not bool in conditional context.
556 // Arg0: index of the token of the assignment (source location). 524 // Arg0: index of the token of the assignment (source location).
557 // Arg1: bad object. 525 // Arg1: bad object.
558 // Return value: none, throws a TypeError. 526 // Return value: none, throws a TypeError.
559 DEFINE_RUNTIME_ENTRY(ConditionTypeError, 2) { 527 DEFINE_RUNTIME_ENTRY(ConditionTypeError, 2) {
560 ASSERT(arguments.Count() == 528 ASSERT(arguments.Count() ==
561 kConditionTypeErrorRuntimeEntry.argument_count()); 529 kConditionTypeErrorRuntimeEntry.argument_count());
562 // TODO(regis): Get the token index from the PcDesc (via StackFrame). 530 // TODO(regis): Get the token index from the PcDesc (via DartFrame).
563 intptr_t location = Smi::CheckedHandle(arguments.At(0)).Value(); 531 intptr_t location = Smi::CheckedHandle(arguments.At(0)).Value();
564 const Instance& src_instance = Instance::CheckedHandle(arguments.At(1)); 532 const Instance& src_instance = Instance::CheckedHandle(arguments.At(1));
565 ASSERT(src_instance.IsNull() || !src_instance.IsBool()); 533 ASSERT(src_instance.IsNull() || !src_instance.IsBool());
566 const Type& bool_interface = Type::Handle(Type::BoolInterface()); 534 const Type& bool_interface = Type::Handle(Type::BoolInterface());
567 const String& src_type_name = String::Handle(GetSimpleTypeName(src_instance)); 535 const String& src_type_name = String::Handle(GetSimpleTypeName(src_instance));
568 const String& bool_type_name = String::Handle(bool_interface.Name()); 536 const String& bool_type_name = String::Handle(bool_interface.Name());
569 const String& expr = String::Handle(String::NewSymbol("boolean expression")); 537 const String& expr = String::Handle(String::NewSymbol("boolean expression"));
570 const String& no_malformed_type_error = String::Handle(); 538 const String& no_malformed_type_error = String::Handle();
571 Exceptions::CreateAndThrowTypeError(location, src_type_name, bool_type_name, 539 Exceptions::CreateAndThrowTypeError(location, src_type_name, bool_type_name,
572 expr, no_malformed_type_error); 540 expr, no_malformed_type_error);
573 UNREACHABLE(); 541 UNREACHABLE();
574 } 542 }
575 543
576 544
577 // Report that the type of the type check is malformed. 545 // Report that the type of the type check is malformed.
578 // Arg0: index of the token of the failed type check. 546 // Arg0: index of the token of the failed type check.
579 // Arg1: src value. 547 // Arg1: src value.
580 // Arg2: name of instance being assigned to. 548 // Arg2: name of instance being assigned to.
581 // Arg3: malformed type error message. 549 // Arg3: malformed type error message.
582 // Return value: none, throws an exception. 550 // Return value: none, throws an exception.
583 DEFINE_RUNTIME_ENTRY(MalformedTypeError, 4) { 551 DEFINE_RUNTIME_ENTRY(MalformedTypeError, 4) {
584 ASSERT(arguments.Count() == 552 ASSERT(arguments.Count() ==
585 kMalformedTypeErrorRuntimeEntry.argument_count()); 553 kMalformedTypeErrorRuntimeEntry.argument_count());
586 // TODO(regis): Get the token index from the PcDesc (via StackFrame). 554 // TODO(regis): Get the token index from the PcDesc (via DartFrame).
587 intptr_t location = Smi::CheckedHandle(arguments.At(0)).Value(); 555 intptr_t location = Smi::CheckedHandle(arguments.At(0)).Value();
588 const Instance& src_value = Instance::CheckedHandle(arguments.At(1)); 556 const Instance& src_value = Instance::CheckedHandle(arguments.At(1));
589 const String& dst_name = String::CheckedHandle(arguments.At(2)); 557 const String& dst_name = String::CheckedHandle(arguments.At(2));
590 const String& malformed_error = String::CheckedHandle(arguments.At(3)); 558 const String& malformed_error = String::CheckedHandle(arguments.At(3));
591 const String& dst_type_name = String::Handle(String::NewSymbol("malformed")); 559 const String& dst_type_name = String::Handle(String::NewSymbol("malformed"));
592 const String& src_type_name = String::Handle(GetSimpleTypeName(src_value)); 560 const String& src_type_name = String::Handle(GetSimpleTypeName(src_value));
593 Exceptions::CreateAndThrowTypeError(location, src_type_name, 561 Exceptions::CreateAndThrowTypeError(location, src_type_name,
594 dst_type_name, dst_name, malformed_error); 562 dst_type_name, dst_name, malformed_error);
595 UNREACHABLE(); 563 UNREACHABLE();
596 } 564 }
597 565
598 566
599 // TODO(regis): Function rest arguments are not supported anymore, but they may 567 // TODO(regis): Function rest arguments are not supported anymore, but they may
600 // come back. 568 // come back.
601 // Check that the type of each element of the given array is assignable to the 569 // Check that the type of each element of the given array is assignable to the
602 // given type. 570 // given type.
603 // Arg0: index of the token of the rest argument declaration (source location). 571 // Arg0: index of the token of the rest argument declaration (source location).
604 // Arg1: rest argument array. 572 // Arg1: rest argument array.
605 // Arg2: element declaration type. 573 // Arg2: element declaration type.
606 // Arg3: type arguments of the instantiator of the element declaration type. 574 // Arg3: type arguments of the instantiator of the element declaration type.
607 // Arg4: name of object being assigned to, i.e. name of rest argument. 575 // Arg4: name of object being assigned to, i.e. name of rest argument.
608 // Return value: null if assignable, otherwise allocate and throw a TypeError. 576 // Return value: null if assignable, otherwise allocate and throw a TypeError.
609 DEFINE_RUNTIME_ENTRY(RestArgumentTypeCheck, 5) { 577 DEFINE_RUNTIME_ENTRY(RestArgumentTypeCheck, 5) {
610 ASSERT(arguments.Count() == 578 ASSERT(arguments.Count() ==
611 kRestArgumentTypeCheckRuntimeEntry.argument_count()); 579 kRestArgumentTypeCheckRuntimeEntry.argument_count());
612 // TODO(regis): Get the token index from the PcDesc (via StackFrame). 580 // TODO(regis): Get the token index from the PcDesc (via DartFrame).
613 intptr_t location = Smi::CheckedHandle(arguments.At(0)).Value(); 581 intptr_t location = Smi::CheckedHandle(arguments.At(0)).Value();
614 const Array& rest_array = Array::CheckedHandle(arguments.At(1)); 582 const Array& rest_array = Array::CheckedHandle(arguments.At(1));
615 const AbstractType& element_type = 583 const AbstractType& element_type =
616 AbstractType::CheckedHandle(arguments.At(2)); 584 AbstractType::CheckedHandle(arguments.At(2));
617 const AbstractTypeArguments& element_type_instantiator = 585 const AbstractTypeArguments& element_type_instantiator =
618 AbstractTypeArguments::CheckedHandle(arguments.At(3)); 586 AbstractTypeArguments::CheckedHandle(arguments.At(3));
619 const String& rest_name = String::CheckedHandle(arguments.At(4)); 587 const String& rest_name = String::CheckedHandle(arguments.At(4));
620 ASSERT(!element_type.IsDynamicType()); // No need to check assignment. 588 ASSERT(!element_type.IsDynamicType()); // No need to check assignment.
621 ASSERT(!element_type.IsMalformed()); // Already checked in code generator. 589 ASSERT(!element_type.IsMalformed()); // Already checked in code generator.
622 ASSERT(!rest_array.IsNull()); 590 ASSERT(!rest_array.IsNull());
(...skipping 839 matching lines...) Expand 10 before | Expand all | Expand 10 after
1462 } 1430 }
1463 } 1431 }
1464 } 1432 }
1465 // The cache is null terminated, therefore the loop above should never 1433 // The cache is null terminated, therefore the loop above should never
1466 // terminate by itself. 1434 // terminate by itself.
1467 UNREACHABLE(); 1435 UNREACHABLE();
1468 return Code::null(); 1436 return Code::null();
1469 } 1437 }
1470 1438
1471 } // namespace dart 1439 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/code_generator_ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698