OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 4158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4169 Handle<Code> ic(Builtins::builtin(Builtins::JSConstructCall)); | 4169 Handle<Code> ic(Builtins::builtin(Builtins::JSConstructCall)); |
4170 frame_->CallCodeObject(ic, RelocInfo::CONSTRUCT_CALL, arg_count + 1); | 4170 frame_->CallCodeObject(ic, RelocInfo::CONSTRUCT_CALL, arg_count + 1); |
4171 | 4171 |
4172 // Discard old TOS value and push r0 on the stack (same as Pop(), push(r0)). | 4172 // Discard old TOS value and push r0 on the stack (same as Pop(), push(r0)). |
4173 __ str(r0, frame_->Top()); | 4173 __ str(r0, frame_->Top()); |
4174 ASSERT_EQ(original_height + 1, frame_->height()); | 4174 ASSERT_EQ(original_height + 1, frame_->height()); |
4175 } | 4175 } |
4176 | 4176 |
4177 | 4177 |
4178 void CodeGenerator::GenerateClassOf(ZoneList<Expression*>* args) { | 4178 void CodeGenerator::GenerateClassOf(ZoneList<Expression*>* args) { |
4179 VirtualFrame::SpilledScope spilled_scope(frame_); | 4179 JumpTarget leave, null, function, non_function_constructor; |
| 4180 Register scratch = VirtualFrame::scratch0(); |
| 4181 |
| 4182 // Load the object into register. |
4180 ASSERT(args->length() == 1); | 4183 ASSERT(args->length() == 1); |
4181 JumpTarget leave, null, function, non_function_constructor; | |
4182 | |
4183 // Load the object into r0. | |
4184 Load(args->at(0)); | 4184 Load(args->at(0)); |
4185 frame_->EmitPop(r0); | 4185 Register tos = frame_->PopToRegister(); |
4186 | 4186 |
4187 // If the object is a smi, we return null. | 4187 // If the object is a smi, we return null. |
4188 __ tst(r0, Operand(kSmiTagMask)); | 4188 __ tst(tos, Operand(kSmiTagMask)); |
4189 null.Branch(eq); | 4189 null.Branch(eq); |
4190 | 4190 |
4191 // Check that the object is a JS object but take special care of JS | 4191 // Check that the object is a JS object but take special care of JS |
4192 // functions to make sure they have 'Function' as their class. | 4192 // functions to make sure they have 'Function' as their class. |
4193 __ CompareObjectType(r0, r0, r1, FIRST_JS_OBJECT_TYPE); | 4193 __ CompareObjectType(tos, tos, scratch, FIRST_JS_OBJECT_TYPE); |
4194 null.Branch(lt); | 4194 null.Branch(lt); |
4195 | 4195 |
4196 // As long as JS_FUNCTION_TYPE is the last instance type and it is | 4196 // As long as JS_FUNCTION_TYPE is the last instance type and it is |
4197 // right after LAST_JS_OBJECT_TYPE, we can avoid checking for | 4197 // right after LAST_JS_OBJECT_TYPE, we can avoid checking for |
4198 // LAST_JS_OBJECT_TYPE. | 4198 // LAST_JS_OBJECT_TYPE. |
4199 STATIC_ASSERT(LAST_TYPE == JS_FUNCTION_TYPE); | 4199 STATIC_ASSERT(LAST_TYPE == JS_FUNCTION_TYPE); |
4200 STATIC_ASSERT(JS_FUNCTION_TYPE == LAST_JS_OBJECT_TYPE + 1); | 4200 STATIC_ASSERT(JS_FUNCTION_TYPE == LAST_JS_OBJECT_TYPE + 1); |
4201 __ cmp(r1, Operand(JS_FUNCTION_TYPE)); | 4201 __ cmp(scratch, Operand(JS_FUNCTION_TYPE)); |
4202 function.Branch(eq); | 4202 function.Branch(eq); |
4203 | 4203 |
4204 // Check if the constructor in the map is a function. | 4204 // Check if the constructor in the map is a function. |
4205 __ ldr(r0, FieldMemOperand(r0, Map::kConstructorOffset)); | 4205 __ ldr(tos, FieldMemOperand(tos, Map::kConstructorOffset)); |
4206 __ CompareObjectType(r0, r1, r1, JS_FUNCTION_TYPE); | 4206 __ CompareObjectType(tos, scratch, scratch, JS_FUNCTION_TYPE); |
4207 non_function_constructor.Branch(ne); | 4207 non_function_constructor.Branch(ne); |
4208 | 4208 |
4209 // The r0 register now contains the constructor function. Grab the | 4209 // The tos register now contains the constructor function. Grab the |
4210 // instance class name from there. | 4210 // instance class name from there. |
4211 __ ldr(r0, FieldMemOperand(r0, JSFunction::kSharedFunctionInfoOffset)); | 4211 __ ldr(tos, FieldMemOperand(tos, JSFunction::kSharedFunctionInfoOffset)); |
4212 __ ldr(r0, FieldMemOperand(r0, SharedFunctionInfo::kInstanceClassNameOffset)); | 4212 __ ldr(tos, |
4213 frame_->EmitPush(r0); | 4213 FieldMemOperand(tos, SharedFunctionInfo::kInstanceClassNameOffset)); |
| 4214 frame_->EmitPush(tos); |
4214 leave.Jump(); | 4215 leave.Jump(); |
4215 | 4216 |
4216 // Functions have class 'Function'. | 4217 // Functions have class 'Function'. |
4217 function.Bind(); | 4218 function.Bind(); |
4218 __ mov(r0, Operand(Factory::function_class_symbol())); | 4219 __ mov(tos, Operand(Factory::function_class_symbol())); |
4219 frame_->EmitPush(r0); | 4220 frame_->EmitPush(tos); |
4220 leave.Jump(); | 4221 leave.Jump(); |
4221 | 4222 |
4222 // Objects with a non-function constructor have class 'Object'. | 4223 // Objects with a non-function constructor have class 'Object'. |
4223 non_function_constructor.Bind(); | 4224 non_function_constructor.Bind(); |
4224 __ mov(r0, Operand(Factory::Object_symbol())); | 4225 __ mov(tos, Operand(Factory::Object_symbol())); |
4225 frame_->EmitPush(r0); | 4226 frame_->EmitPush(tos); |
4226 leave.Jump(); | 4227 leave.Jump(); |
4227 | 4228 |
4228 // Non-JS objects have class null. | 4229 // Non-JS objects have class null. |
4229 null.Bind(); | 4230 null.Bind(); |
4230 __ LoadRoot(r0, Heap::kNullValueRootIndex); | 4231 __ LoadRoot(tos, Heap::kNullValueRootIndex); |
4231 frame_->EmitPush(r0); | 4232 frame_->EmitPush(tos); |
4232 | 4233 |
4233 // All done. | 4234 // All done. |
4234 leave.Bind(); | 4235 leave.Bind(); |
4235 } | 4236 } |
4236 | 4237 |
4237 | 4238 |
4238 void CodeGenerator::GenerateValueOf(ZoneList<Expression*>* args) { | 4239 void CodeGenerator::GenerateValueOf(ZoneList<Expression*>* args) { |
4239 VirtualFrame::SpilledScope spilled_scope(frame_); | 4240 Register scratch = VirtualFrame::scratch0(); |
| 4241 JumpTarget leave; |
| 4242 |
4240 ASSERT(args->length() == 1); | 4243 ASSERT(args->length() == 1); |
4241 JumpTarget leave; | |
4242 Load(args->at(0)); | 4244 Load(args->at(0)); |
4243 frame_->EmitPop(r0); // r0 contains object. | 4245 Register tos = frame_->PopToRegister(); // tos contains object. |
4244 // if (object->IsSmi()) return the object. | 4246 // if (object->IsSmi()) return the object. |
4245 __ tst(r0, Operand(kSmiTagMask)); | 4247 __ tst(tos, Operand(kSmiTagMask)); |
4246 leave.Branch(eq); | 4248 leave.Branch(eq); |
4247 // It is a heap object - get map. If (!object->IsJSValue()) return the object. | 4249 // It is a heap object - get map. If (!object->IsJSValue()) return the object. |
4248 __ CompareObjectType(r0, r1, r1, JS_VALUE_TYPE); | 4250 __ CompareObjectType(tos, scratch, scratch, JS_VALUE_TYPE); |
4249 leave.Branch(ne); | 4251 leave.Branch(ne); |
4250 // Load the value. | 4252 // Load the value. |
4251 __ ldr(r0, FieldMemOperand(r0, JSValue::kValueOffset)); | 4253 __ ldr(tos, FieldMemOperand(tos, JSValue::kValueOffset)); |
4252 leave.Bind(); | 4254 leave.Bind(); |
4253 frame_->EmitPush(r0); | 4255 frame_->EmitPush(tos); |
4254 } | 4256 } |
4255 | 4257 |
4256 | 4258 |
4257 void CodeGenerator::GenerateSetValueOf(ZoneList<Expression*>* args) { | 4259 void CodeGenerator::GenerateSetValueOf(ZoneList<Expression*>* args) { |
4258 VirtualFrame::SpilledScope spilled_scope(frame_); | 4260 Register scratch1 = VirtualFrame::scratch0(); |
| 4261 Register scratch2 = VirtualFrame::scratch1(); |
| 4262 JumpTarget leave; |
| 4263 |
4259 ASSERT(args->length() == 2); | 4264 ASSERT(args->length() == 2); |
4260 JumpTarget leave; | |
4261 Load(args->at(0)); // Load the object. | 4265 Load(args->at(0)); // Load the object. |
4262 Load(args->at(1)); // Load the value. | 4266 Load(args->at(1)); // Load the value. |
4263 frame_->EmitPop(r0); // r0 contains value | 4267 Register value = frame_->PopToRegister(); |
4264 frame_->EmitPop(r1); // r1 contains object | 4268 Register object = frame_->PopToRegister(value); |
4265 // if (object->IsSmi()) return object. | 4269 // if (object->IsSmi()) return object. |
4266 __ tst(r1, Operand(kSmiTagMask)); | 4270 __ tst(object, Operand(kSmiTagMask)); |
4267 leave.Branch(eq); | 4271 leave.Branch(eq); |
4268 // It is a heap object - get map. If (!object->IsJSValue()) return the object. | 4272 // It is a heap object - get map. If (!object->IsJSValue()) return the object. |
4269 __ CompareObjectType(r1, r2, r2, JS_VALUE_TYPE); | 4273 __ CompareObjectType(object, scratch1, scratch1, JS_VALUE_TYPE); |
4270 leave.Branch(ne); | 4274 leave.Branch(ne); |
4271 // Store the value. | 4275 // Store the value. |
4272 __ str(r0, FieldMemOperand(r1, JSValue::kValueOffset)); | 4276 __ str(value, FieldMemOperand(object, JSValue::kValueOffset)); |
4273 // Update the write barrier. | 4277 // Update the write barrier. |
4274 __ RecordWrite(r1, Operand(JSValue::kValueOffset - kHeapObjectTag), r2, r3); | 4278 __ RecordWrite(object, |
| 4279 Operand(JSValue::kValueOffset - kHeapObjectTag), |
| 4280 scratch1, |
| 4281 scratch2); |
4275 // Leave. | 4282 // Leave. |
4276 leave.Bind(); | 4283 leave.Bind(); |
4277 frame_->EmitPush(r0); | 4284 frame_->EmitPush(value); |
4278 } | 4285 } |
4279 | 4286 |
4280 | 4287 |
4281 void CodeGenerator::GenerateIsSmi(ZoneList<Expression*>* args) { | 4288 void CodeGenerator::GenerateIsSmi(ZoneList<Expression*>* args) { |
4282 ASSERT(args->length() == 1); | 4289 ASSERT(args->length() == 1); |
4283 Load(args->at(0)); | 4290 Load(args->at(0)); |
4284 Register reg = frame_->PopToRegister(); | 4291 Register reg = frame_->PopToRegister(); |
4285 __ tst(reg, Operand(kSmiTagMask)); | 4292 __ tst(reg, Operand(kSmiTagMask)); |
4286 cc_reg_ = eq; | 4293 cc_reg_ = eq; |
4287 } | 4294 } |
(...skipping 7146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11434 __ bind(&string_add_runtime); | 11441 __ bind(&string_add_runtime); |
11435 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); | 11442 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); |
11436 } | 11443 } |
11437 | 11444 |
11438 | 11445 |
11439 #undef __ | 11446 #undef __ |
11440 | 11447 |
11441 } } // namespace v8::internal | 11448 } } // namespace v8::internal |
11442 | 11449 |
11443 #endif // V8_TARGET_ARCH_ARM | 11450 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |