OLD | NEW |
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 5004 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5015 // ArgumentsAccessStub takes the parameter count as an input argument | 5015 // ArgumentsAccessStub takes the parameter count as an input argument |
5016 // in register eax. Create a constant result for it. | 5016 // in register eax. Create a constant result for it. |
5017 Result count(Handle<Smi>(Smi::FromInt(scope_->num_parameters()))); | 5017 Result count(Handle<Smi>(Smi::FromInt(scope_->num_parameters()))); |
5018 // Call the shared stub to get to the arguments.length. | 5018 // Call the shared stub to get to the arguments.length. |
5019 ArgumentsAccessStub stub(ArgumentsAccessStub::READ_LENGTH); | 5019 ArgumentsAccessStub stub(ArgumentsAccessStub::READ_LENGTH); |
5020 Result result = frame_->CallStub(&stub, &count); | 5020 Result result = frame_->CallStub(&stub, &count); |
5021 frame_->Push(&result); | 5021 frame_->Push(&result); |
5022 } | 5022 } |
5023 | 5023 |
5024 | 5024 |
| 5025 void CodeGenerator::GenerateClassOf(ZoneList<Expression*>* args) { |
| 5026 ASSERT(args->length() == 1); |
| 5027 JumpTarget leave, null, function, non_function_constructor; |
| 5028 Load(args->at(0)); // Load the object. |
| 5029 Result obj = frame_->Pop(); |
| 5030 obj.ToRegister(); |
| 5031 frame_->Spill(obj.reg()); |
| 5032 |
| 5033 // If the object is a smi, we return null. |
| 5034 __ test(obj.reg(), Immediate(kSmiTagMask)); |
| 5035 null.Branch(zero); |
| 5036 |
| 5037 // Check that the object is a JS object but take special care of JS |
| 5038 // functions to make sure they have 'Function' as their class. |
| 5039 { Result tmp = allocator()->Allocate(); |
| 5040 __ mov(obj.reg(), FieldOperand(obj.reg(), HeapObject::kMapOffset)); |
| 5041 __ movzx_b(tmp.reg(), FieldOperand(obj.reg(), Map::kInstanceTypeOffset)); |
| 5042 __ cmp(tmp.reg(), FIRST_JS_OBJECT_TYPE); |
| 5043 null.Branch(less); |
| 5044 |
| 5045 // As long as JS_FUNCTION_TYPE is the last instance type and it is |
| 5046 // right after LAST_JS_OBJECT_TYPE, we can avoid checking for |
| 5047 // LAST_JS_OBJECT_TYPE. |
| 5048 ASSERT(LAST_TYPE == JS_FUNCTION_TYPE); |
| 5049 ASSERT(JS_FUNCTION_TYPE == LAST_JS_OBJECT_TYPE + 1); |
| 5050 __ cmp(tmp.reg(), JS_FUNCTION_TYPE); |
| 5051 function.Branch(equal); |
| 5052 } |
| 5053 |
| 5054 // Check if the constructor in the map is a function. |
| 5055 { Result tmp = allocator()->Allocate(); |
| 5056 __ mov(obj.reg(), FieldOperand(obj.reg(), Map::kConstructorOffset)); |
| 5057 __ CmpObjectType(obj.reg(), JS_FUNCTION_TYPE, tmp.reg()); |
| 5058 non_function_constructor.Branch(not_equal); |
| 5059 } |
| 5060 |
| 5061 // The map register now contains the constructor function. Grab the |
| 5062 // instance class name from there. |
| 5063 __ mov(obj.reg(), |
| 5064 FieldOperand(obj.reg(), JSFunction::kSharedFunctionInfoOffset)); |
| 5065 __ mov(obj.reg(), |
| 5066 FieldOperand(obj.reg(), SharedFunctionInfo::kInstanceClassNameOffset)); |
| 5067 frame_->Push(&obj); |
| 5068 leave.Jump(); |
| 5069 |
| 5070 // Functions have class 'Function'. |
| 5071 function.Bind(); |
| 5072 frame_->Push(Factory::function_class_symbol()); |
| 5073 leave.Jump(); |
| 5074 |
| 5075 // Objects with a non-function constructor have class 'Object'. |
| 5076 non_function_constructor.Bind(); |
| 5077 frame_->Push(Factory::Object_symbol()); |
| 5078 leave.Jump(); |
| 5079 |
| 5080 // Non-JS objects have class null. |
| 5081 null.Bind(); |
| 5082 frame_->Push(Factory::null_value()); |
| 5083 |
| 5084 // All done. |
| 5085 leave.Bind(); |
| 5086 } |
| 5087 |
| 5088 |
5025 void CodeGenerator::GenerateValueOf(ZoneList<Expression*>* args) { | 5089 void CodeGenerator::GenerateValueOf(ZoneList<Expression*>* args) { |
5026 ASSERT(args->length() == 1); | 5090 ASSERT(args->length() == 1); |
5027 JumpTarget leave; | 5091 JumpTarget leave; |
5028 Load(args->at(0)); // Load the object. | 5092 Load(args->at(0)); // Load the object. |
5029 frame_->Dup(); | 5093 frame_->Dup(); |
5030 Result object = frame_->Pop(); | 5094 Result object = frame_->Pop(); |
5031 object.ToRegister(); | 5095 object.ToRegister(); |
5032 ASSERT(object.is_valid()); | 5096 ASSERT(object.is_valid()); |
5033 // if (object->IsSmi()) return object. | 5097 // if (object->IsSmi()) return object. |
5034 __ test(object.reg(), Immediate(kSmiTagMask)); | 5098 __ test(object.reg(), Immediate(kSmiTagMask)); |
(...skipping 2840 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7875 | 7939 |
7876 // Slow-case: Go through the JavaScript implementation. | 7940 // Slow-case: Go through the JavaScript implementation. |
7877 __ bind(&slow); | 7941 __ bind(&slow); |
7878 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); | 7942 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); |
7879 } | 7943 } |
7880 | 7944 |
7881 | 7945 |
7882 #undef __ | 7946 #undef __ |
7883 | 7947 |
7884 } } // namespace v8::internal | 7948 } } // namespace v8::internal |
OLD | NEW |