Inline condition type check.

Review URL: https://chromereviews.googleplex.com/3534018

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@166 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
regis@google.com 2011-10-06 22:35:01 +00:00
parent 2af03fc05b
commit b618447392
4 changed files with 33 additions and 3 deletions

View file

@ -224,8 +224,7 @@ DEFINE_RUNTIME_ENTRY(ConditionTypeCheck, 2) {
const char* msg = "boolean expression";
if (src_instance.IsNull() || !src_instance.IsBool()) {
const Type& bool_interface =
Type::ZoneHandle(Isolate::Current()->object_store()->bool_interface());
const Type& bool_interface = Type::Handle(Type::BoolInterface());
const Type& src_type = Type::Handle(src_instance.GetType());
const String& src_type_name = String::Handle(src_type.Name());
const String& bool_type_name = String::Handle(bool_interface.Name());

View file

@ -1605,16 +1605,39 @@ void CodeGenerator::GenerateConditionTypeCheck(intptr_t token_index) {
return;
}
// Check that the type of the object on the stack is allowed in conditional
// context.
// Call the runtime if the object is null or not of type bool.
const Immediate raw_null =
Immediate(reinterpret_cast<intptr_t>(Object::null()));
Label runtime_call, done;
__ movl(EAX, Address(ESP, 0));
__ cmpl(EAX, raw_null);
__ j(EQUAL, &runtime_call, Assembler::kNearJump);
__ testl(EAX, Immediate(kSmiTagMask));
__ j(ZERO, &runtime_call, Assembler::kNearJump); // Call runtime for Smi.
const Type& bool_interface = Type::Handle(Type::BoolInterface());
const Class& bool_class = Class::ZoneHandle(bool_interface.type_class());
__ movl(ECX, FieldAddress(EAX, Object::class_offset()));
__ CompareObject(ECX, bool_class);
__ j(EQUAL, &done, Assembler::kNearJump);
__ Bind(&runtime_call);
const Object& result = Object::ZoneHandle();
__ PushObject(result); // Make room for the result of the runtime call.
const Immediate location =
Immediate(reinterpret_cast<int32_t>(Smi::New(token_index)));
__ pushl(location); // Push the source location.
__ pushl(Address(ESP, 2 * kWordSize)); // Push the source object.
__ pushl(EAX); // Push the source object.
// TODO(regis): Once we enforce the rule prohibiting subtyping of bool, we
// should rename the runtime call 'ConditionTypeCheck' to
// 'ConditionTypeError'.
GenerateCallRuntime(token_index, kConditionTypeCheckRuntimeEntry);
// Pop the parameters supplied to the runtime entry. The result of the
// type check runtime call is the checked value.
__ addl(ESP, Immediate(3 * kWordSize));
__ Bind(&done);
}

View file

@ -1674,6 +1674,11 @@ RawType* Type::ObjectType() {
}
RawType* Type::BoolInterface() {
return Isolate::Current()->object_store()->bool_interface();
}
RawType* Type::FunctionInterface() {
return Isolate::Current()->object_store()->function_interface();
}

View file

@ -709,6 +709,9 @@ class Type : public Object {
// The 'Object' type.
static RawType* ObjectType();
// The 'bool' interface type.
static RawType* BoolInterface();
// The 'Function' interface type.
static RawType* FunctionInterface();