Chromium Code Reviews| Index: src/arm/codegen-arm.cc |
| =================================================================== |
| --- src/arm/codegen-arm.cc (revision 2324) |
| +++ src/arm/codegen-arm.cc (working copy) |
| @@ -3176,9 +3176,62 @@ |
| void CodeGenerator::GenerateClassOf(ZoneList<Expression*>* args) { |
| VirtualFrame::SpilledScope spilled_scope; |
| ASSERT(args->length() == 1); |
| - LoadAndSpill(args->at(0)); // Load the object. |
| - frame_->CallRuntime(Runtime::kClassOf, 1); |
| + JumpTarget leave, null, function, non_function_constructor; |
| + |
| + // Load the object into r0. |
| + LoadAndSpill(args->at(0)); |
| + frame_->EmitPop(r0); |
| + |
| + // If the object is a smi, we return null. |
| + __ tst(r0, Operand(kSmiTagMask)); |
| + null.Branch(eq); |
|
Erik Corry
2009/07/02 13:48:31
Ideally I'd like to do this as a conditional move
|
| + |
| + // Check that the object is a JS object but take special care of JS |
| + // functions to make sure they have 'Function' as their class. |
| + __ ldr(r0, FieldMemOperand(r0, HeapObject::kMapOffset)); |
| + __ ldrb(r1, FieldMemOperand(r0, Map::kInstanceTypeOffset)); |
| + __ cmp(r1, Operand(FIRST_JS_OBJECT_TYPE)); |
|
Erik Corry
2009/07/02 13:48:31
You can do these 3 in one with __ CompareObjectTyp
Mads Ager (chromium)
2009/07/02 14:14:08
Ah, yes, there is one more register parameter to C
|
| + null.Branch(lt); |
| + |
| + // As long as JS_FUNCTION_TYPE is the last instance type and it is |
| + // right after LAST_JS_OBJECT_TYPE, we can avoid checking for |
| + // LAST_JS_OBJECT_TYPE. |
| + ASSERT(LAST_TYPE == JS_FUNCTION_TYPE); |
| + ASSERT(JS_FUNCTION_TYPE == LAST_JS_OBJECT_TYPE + 1); |
| + __ cmp(r1, Operand(JS_FUNCTION_TYPE)); |
| + function.Branch(eq); |
| + |
| + // Check if the constructor in the map is a function. |
| + __ ldr(r0, FieldMemOperand(r0, Map::kConstructorOffset)); |
| + __ CompareObjectType(r0, r1, r1, JS_FUNCTION_TYPE); |
|
Erik Corry
2009/07/02 13:48:31
r0 = Object.
r1 = Map.
r1 = type (overwrites map)
Mads Ager (chromium)
2009/07/02 14:14:08
Yes, that is fine. All I need is for the construc
|
| + non_function_constructor.Branch(ne); |
| + |
| + // The map register now contains the constructor function. Grab the |
|
Erik Corry
2009/07/02 13:48:31
Map register is r0? I think r0 is the constructor
Mads Ager (chromium)
2009/07/02 14:14:08
Yeah, strange comment. Changed it to 'The r0 regi
|
| + // instance class name from there. |
| + __ ldr(r0, FieldMemOperand(r0, JSFunction::kSharedFunctionInfoOffset)); |
| + __ ldr(r0, FieldMemOperand(r0, SharedFunctionInfo::kInstanceClassNameOffset)); |
| frame_->EmitPush(r0); |
| + leave.Jump(); |
| + |
| + // Functions have class 'Function'. |
| + function.Bind(); |
| + __ mov(r0, Operand(Factory::function_class_symbol())); |
| + frame_->EmitPush(r0); |
| + leave.Jump(); |
| + |
| + // Objects with a non-function constructor have class 'Object'. |
| + non_function_constructor.Bind(); |
| + __ mov(r0, Operand(Factory::Object_symbol())); |
| + frame_->EmitPush(r0); |
| + leave.Jump(); |
| + |
| + // Non-JS objects have class null. |
| + null.Bind(); |
| + __ mov(r0, Operand(Factory::null_value())); |
| + frame_->EmitPush(r0); |
| + |
| + // All done. |
| + leave.Bind(); |
| } |