| 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 |