OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_IA32 | 7 #if V8_TARGET_ARCH_IA32 |
8 | 8 |
9 #include "src/code-factory.h" | 9 #include "src/code-factory.h" |
10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
(...skipping 1914 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1925 case VARIABLE: | 1925 case VARIABLE: |
1926 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), | 1926 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), |
1927 expr->op()); | 1927 expr->op()); |
1928 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 1928 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
1929 context()->Plug(eax); | 1929 context()->Plug(eax); |
1930 break; | 1930 break; |
1931 case NAMED_PROPERTY: | 1931 case NAMED_PROPERTY: |
1932 EmitNamedPropertyAssignment(expr); | 1932 EmitNamedPropertyAssignment(expr); |
1933 break; | 1933 break; |
1934 case NAMED_SUPER_PROPERTY: | 1934 case NAMED_SUPER_PROPERTY: |
1935 EmitNamedSuperPropertyAssignment(expr); | 1935 EmitNamedSuperPropertyStore(property); |
| 1936 context()->Plug(eax); |
1936 break; | 1937 break; |
1937 case KEYED_PROPERTY: | 1938 case KEYED_PROPERTY: |
1938 EmitKeyedPropertyAssignment(expr); | 1939 EmitKeyedPropertyAssignment(expr); |
1939 break; | 1940 break; |
1940 } | 1941 } |
1941 } | 1942 } |
1942 | 1943 |
1943 | 1944 |
1944 void FullCodeGenerator::VisitYield(Yield* expr) { | 1945 void FullCodeGenerator::VisitYield(Yield* expr) { |
1945 Comment cmnt(masm_, "[ Yield"); | 1946 Comment cmnt(masm_, "[ Yield"); |
(...skipping 598 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2544 // Record source code position before IC call. | 2545 // Record source code position before IC call. |
2545 SetSourcePosition(expr->position()); | 2546 SetSourcePosition(expr->position()); |
2546 __ mov(StoreDescriptor::NameRegister(), prop->key()->AsLiteral()->value()); | 2547 __ mov(StoreDescriptor::NameRegister(), prop->key()->AsLiteral()->value()); |
2547 __ pop(StoreDescriptor::ReceiverRegister()); | 2548 __ pop(StoreDescriptor::ReceiverRegister()); |
2548 CallStoreIC(expr->AssignmentFeedbackId()); | 2549 CallStoreIC(expr->AssignmentFeedbackId()); |
2549 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2550 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
2550 context()->Plug(eax); | 2551 context()->Plug(eax); |
2551 } | 2552 } |
2552 | 2553 |
2553 | 2554 |
2554 void FullCodeGenerator::EmitNamedSuperPropertyAssignment(Assignment* expr) { | 2555 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { |
2555 // Assignment to named property of super. | 2556 // Assignment to named property of super. |
2556 // eax : value | 2557 // eax : value |
2557 // stack : receiver ('this'), home_object | 2558 // stack : receiver ('this'), home_object |
2558 Property* prop = expr->target()->AsProperty(); | |
2559 DCHECK(prop != NULL); | 2559 DCHECK(prop != NULL); |
2560 Literal* key = prop->key()->AsLiteral(); | 2560 Literal* key = prop->key()->AsLiteral(); |
2561 DCHECK(key != NULL); | 2561 DCHECK(key != NULL); |
2562 | 2562 |
2563 __ push(eax); | 2563 __ push(eax); |
2564 __ push(Immediate(key->value())); | 2564 __ push(Immediate(key->value())); |
2565 __ CallRuntime((strict_mode() == STRICT ? Runtime::kStoreToSuper_Strict | 2565 __ CallRuntime((strict_mode() == STRICT ? Runtime::kStoreToSuper_Strict |
2566 : Runtime::kStoreToSuper_Sloppy), | 2566 : Runtime::kStoreToSuper_Sloppy), |
2567 4); | 2567 4); |
2568 context()->Plug(eax); | |
2569 } | 2568 } |
2570 | 2569 |
2571 | 2570 |
2572 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { | 2571 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { |
2573 // Assignment to a property, using a keyed store IC. | 2572 // Assignment to a property, using a keyed store IC. |
2574 // eax : value | 2573 // eax : value |
2575 // esp[0] : key | 2574 // esp[0] : key |
2576 // esp[kPointerSize] : receiver | 2575 // esp[kPointerSize] : receiver |
2577 | 2576 |
2578 __ pop(StoreDescriptor::NameRegister()); // Key. | 2577 __ pop(StoreDescriptor::NameRegister()); // Key. |
(...skipping 1746 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4325 | 4324 |
4326 | 4325 |
4327 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { | 4326 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { |
4328 DCHECK(expr->expression()->IsValidReferenceExpression()); | 4327 DCHECK(expr->expression()->IsValidReferenceExpression()); |
4329 | 4328 |
4330 Comment cmnt(masm_, "[ CountOperation"); | 4329 Comment cmnt(masm_, "[ CountOperation"); |
4331 SetSourcePosition(expr->position()); | 4330 SetSourcePosition(expr->position()); |
4332 | 4331 |
4333 // Expression can only be a property, a global or a (parameter or local) | 4332 // Expression can only be a property, a global or a (parameter or local) |
4334 // slot. | 4333 // slot. |
4335 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; | 4334 enum LhsKind { |
| 4335 VARIABLE, |
| 4336 NAMED_PROPERTY, |
| 4337 KEYED_PROPERTY, |
| 4338 NAMED_SUPER_PROPERTY |
| 4339 }; |
4336 LhsKind assign_type = VARIABLE; | 4340 LhsKind assign_type = VARIABLE; |
4337 Property* prop = expr->expression()->AsProperty(); | 4341 Property* prop = expr->expression()->AsProperty(); |
4338 // In case of a property we use the uninitialized expression context | 4342 // In case of a property we use the uninitialized expression context |
4339 // of the key to detect a named property. | 4343 // of the key to detect a named property. |
4340 if (prop != NULL) { | 4344 if (prop != NULL) { |
4341 assign_type = | 4345 assign_type = |
4342 (prop->key()->IsPropertyName()) ? NAMED_PROPERTY : KEYED_PROPERTY; | 4346 (prop->key()->IsPropertyName()) |
4343 if (prop->IsSuperAccess()) { | 4347 ? (prop->IsSuperAccess() ? NAMED_SUPER_PROPERTY : NAMED_PROPERTY) |
4344 // throw exception. | 4348 : KEYED_PROPERTY; |
4345 VisitSuperReference(prop->obj()->AsSuperReference()); | |
4346 return; | |
4347 } | |
4348 } | 4349 } |
4349 | 4350 |
4350 // Evaluate expression and get value. | 4351 // Evaluate expression and get value. |
4351 if (assign_type == VARIABLE) { | 4352 if (assign_type == VARIABLE) { |
4352 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); | 4353 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); |
4353 AccumulatorValueContext context(this); | 4354 AccumulatorValueContext context(this); |
4354 EmitVariableLoad(expr->expression()->AsVariableProxy()); | 4355 EmitVariableLoad(expr->expression()->AsVariableProxy()); |
4355 } else { | 4356 } else { |
4356 // Reserve space for result of postfix operation. | 4357 // Reserve space for result of postfix operation. |
4357 if (expr->is_postfix() && !context()->IsEffect()) { | 4358 if (expr->is_postfix() && !context()->IsEffect()) { |
4358 __ push(Immediate(Smi::FromInt(0))); | 4359 __ push(Immediate(Smi::FromInt(0))); |
4359 } | 4360 } |
4360 if (assign_type == NAMED_PROPERTY) { | 4361 if (assign_type == NAMED_PROPERTY) { |
4361 // Put the object both on the stack and in the register. | 4362 // Put the object both on the stack and in the register. |
4362 VisitForStackValue(prop->obj()); | 4363 VisitForStackValue(prop->obj()); |
4363 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); | 4364 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); |
4364 EmitNamedPropertyLoad(prop); | 4365 EmitNamedPropertyLoad(prop); |
| 4366 } else if (assign_type == NAMED_SUPER_PROPERTY) { |
| 4367 VisitForStackValue(prop->obj()->AsSuperReference()->this_var()); |
| 4368 EmitLoadHomeObject(prop->obj()->AsSuperReference()); |
| 4369 __ push(result_register()); |
| 4370 __ push(MemOperand(esp, kPointerSize)); |
| 4371 __ push(result_register()); |
| 4372 EmitNamedSuperPropertyLoad(prop); |
4365 } else { | 4373 } else { |
4366 VisitForStackValue(prop->obj()); | 4374 VisitForStackValue(prop->obj()); |
4367 VisitForStackValue(prop->key()); | 4375 VisitForStackValue(prop->key()); |
4368 __ mov(LoadDescriptor::ReceiverRegister(), | 4376 __ mov(LoadDescriptor::ReceiverRegister(), |
4369 Operand(esp, kPointerSize)); // Object. | 4377 Operand(esp, kPointerSize)); // Object. |
4370 __ mov(LoadDescriptor::NameRegister(), Operand(esp, 0)); // Key. | 4378 __ mov(LoadDescriptor::NameRegister(), Operand(esp, 0)); // Key. |
4371 EmitKeyedPropertyLoad(prop); | 4379 EmitKeyedPropertyLoad(prop); |
4372 } | 4380 } |
4373 } | 4381 } |
4374 | 4382 |
(...skipping 18 matching lines...) Expand all Loading... |
4393 // Save the result on the stack. If we have a named or keyed property | 4401 // Save the result on the stack. If we have a named or keyed property |
4394 // we store the result under the receiver that is currently on top | 4402 // we store the result under the receiver that is currently on top |
4395 // of the stack. | 4403 // of the stack. |
4396 switch (assign_type) { | 4404 switch (assign_type) { |
4397 case VARIABLE: | 4405 case VARIABLE: |
4398 __ push(eax); | 4406 __ push(eax); |
4399 break; | 4407 break; |
4400 case NAMED_PROPERTY: | 4408 case NAMED_PROPERTY: |
4401 __ mov(Operand(esp, kPointerSize), eax); | 4409 __ mov(Operand(esp, kPointerSize), eax); |
4402 break; | 4410 break; |
| 4411 case NAMED_SUPER_PROPERTY: |
| 4412 __ mov(Operand(esp, 2 * kPointerSize), eax); |
| 4413 break; |
4403 case KEYED_PROPERTY: | 4414 case KEYED_PROPERTY: |
4404 __ mov(Operand(esp, 2 * kPointerSize), eax); | 4415 __ mov(Operand(esp, 2 * kPointerSize), eax); |
4405 break; | 4416 break; |
4406 } | 4417 } |
4407 } | 4418 } |
4408 } | 4419 } |
4409 | 4420 |
4410 if (expr->op() == Token::INC) { | 4421 if (expr->op() == Token::INC) { |
4411 __ add(eax, Immediate(Smi::FromInt(1))); | 4422 __ add(eax, Immediate(Smi::FromInt(1))); |
4412 } else { | 4423 } else { |
(...skipping 18 matching lines...) Expand all Loading... |
4431 // Save the result on the stack. If we have a named or keyed property | 4442 // Save the result on the stack. If we have a named or keyed property |
4432 // we store the result under the receiver that is currently on top | 4443 // we store the result under the receiver that is currently on top |
4433 // of the stack. | 4444 // of the stack. |
4434 switch (assign_type) { | 4445 switch (assign_type) { |
4435 case VARIABLE: | 4446 case VARIABLE: |
4436 __ push(eax); | 4447 __ push(eax); |
4437 break; | 4448 break; |
4438 case NAMED_PROPERTY: | 4449 case NAMED_PROPERTY: |
4439 __ mov(Operand(esp, kPointerSize), eax); | 4450 __ mov(Operand(esp, kPointerSize), eax); |
4440 break; | 4451 break; |
| 4452 case NAMED_SUPER_PROPERTY: |
| 4453 __ mov(Operand(esp, 2 * kPointerSize), eax); |
| 4454 break; |
4441 case KEYED_PROPERTY: | 4455 case KEYED_PROPERTY: |
4442 __ mov(Operand(esp, 2 * kPointerSize), eax); | 4456 __ mov(Operand(esp, 2 * kPointerSize), eax); |
4443 break; | 4457 break; |
4444 } | 4458 } |
4445 } | 4459 } |
4446 } | 4460 } |
4447 | 4461 |
4448 // Record position before stub call. | 4462 // Record position before stub call. |
4449 SetSourcePosition(expr->position()); | 4463 SetSourcePosition(expr->position()); |
4450 | 4464 |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4490 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4504 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
4491 if (expr->is_postfix()) { | 4505 if (expr->is_postfix()) { |
4492 if (!context()->IsEffect()) { | 4506 if (!context()->IsEffect()) { |
4493 context()->PlugTOS(); | 4507 context()->PlugTOS(); |
4494 } | 4508 } |
4495 } else { | 4509 } else { |
4496 context()->Plug(eax); | 4510 context()->Plug(eax); |
4497 } | 4511 } |
4498 break; | 4512 break; |
4499 } | 4513 } |
| 4514 case NAMED_SUPER_PROPERTY: { |
| 4515 EmitNamedSuperPropertyStore(prop); |
| 4516 if (expr->is_postfix()) { |
| 4517 if (!context()->IsEffect()) { |
| 4518 context()->PlugTOS(); |
| 4519 } |
| 4520 } else { |
| 4521 context()->Plug(eax); |
| 4522 } |
| 4523 break; |
| 4524 } |
4500 case KEYED_PROPERTY: { | 4525 case KEYED_PROPERTY: { |
4501 __ pop(StoreDescriptor::NameRegister()); | 4526 __ pop(StoreDescriptor::NameRegister()); |
4502 __ pop(StoreDescriptor::ReceiverRegister()); | 4527 __ pop(StoreDescriptor::ReceiverRegister()); |
4503 Handle<Code> ic = | 4528 Handle<Code> ic = |
4504 CodeFactory::KeyedStoreIC(isolate(), strict_mode()).code(); | 4529 CodeFactory::KeyedStoreIC(isolate(), strict_mode()).code(); |
4505 CallIC(ic, expr->CountStoreFeedbackId()); | 4530 CallIC(ic, expr->CountStoreFeedbackId()); |
4506 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4531 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
4507 if (expr->is_postfix()) { | 4532 if (expr->is_postfix()) { |
4508 // Result is on the stack | 4533 // Result is on the stack |
4509 if (!context()->IsEffect()) { | 4534 if (!context()->IsEffect()) { |
(...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4951 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), | 4976 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), |
4952 Assembler::target_address_at(call_target_address, | 4977 Assembler::target_address_at(call_target_address, |
4953 unoptimized_code)); | 4978 unoptimized_code)); |
4954 return OSR_AFTER_STACK_CHECK; | 4979 return OSR_AFTER_STACK_CHECK; |
4955 } | 4980 } |
4956 | 4981 |
4957 | 4982 |
4958 } } // namespace v8::internal | 4983 } } // namespace v8::internal |
4959 | 4984 |
4960 #endif // V8_TARGET_ARCH_IA32 | 4985 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |