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_X87 | 7 #if V8_TARGET_ARCH_X87 |
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 1901 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1912 case VARIABLE: | 1912 case VARIABLE: |
1913 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), | 1913 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), |
1914 expr->op()); | 1914 expr->op()); |
1915 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 1915 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
1916 context()->Plug(eax); | 1916 context()->Plug(eax); |
1917 break; | 1917 break; |
1918 case NAMED_PROPERTY: | 1918 case NAMED_PROPERTY: |
1919 EmitNamedPropertyAssignment(expr); | 1919 EmitNamedPropertyAssignment(expr); |
1920 break; | 1920 break; |
1921 case NAMED_SUPER_PROPERTY: | 1921 case NAMED_SUPER_PROPERTY: |
1922 EmitNamedSuperPropertyAssignment(expr); | 1922 EmitNamedSuperPropertyStore(property); |
| 1923 context()->Plug(eax); |
1923 break; | 1924 break; |
1924 case KEYED_PROPERTY: | 1925 case KEYED_PROPERTY: |
1925 EmitKeyedPropertyAssignment(expr); | 1926 EmitKeyedPropertyAssignment(expr); |
1926 break; | 1927 break; |
1927 } | 1928 } |
1928 } | 1929 } |
1929 | 1930 |
1930 | 1931 |
1931 void FullCodeGenerator::VisitYield(Yield* expr) { | 1932 void FullCodeGenerator::VisitYield(Yield* expr) { |
1932 Comment cmnt(masm_, "[ Yield"); | 1933 Comment cmnt(masm_, "[ Yield"); |
(...skipping 598 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2531 // Record source code position before IC call. | 2532 // Record source code position before IC call. |
2532 SetSourcePosition(expr->position()); | 2533 SetSourcePosition(expr->position()); |
2533 __ mov(StoreDescriptor::NameRegister(), prop->key()->AsLiteral()->value()); | 2534 __ mov(StoreDescriptor::NameRegister(), prop->key()->AsLiteral()->value()); |
2534 __ pop(StoreDescriptor::ReceiverRegister()); | 2535 __ pop(StoreDescriptor::ReceiverRegister()); |
2535 CallStoreIC(expr->AssignmentFeedbackId()); | 2536 CallStoreIC(expr->AssignmentFeedbackId()); |
2536 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2537 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
2537 context()->Plug(eax); | 2538 context()->Plug(eax); |
2538 } | 2539 } |
2539 | 2540 |
2540 | 2541 |
2541 void FullCodeGenerator::EmitNamedSuperPropertyAssignment(Assignment* expr) { | 2542 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { |
2542 // Assignment to named property of super. | 2543 // Assignment to named property of super. |
2543 // eax : value | 2544 // eax : value |
2544 // stack : receiver ('this'), home_object | 2545 // stack : receiver ('this'), home_object |
2545 Property* prop = expr->target()->AsProperty(); | |
2546 DCHECK(prop != NULL); | 2546 DCHECK(prop != NULL); |
2547 Literal* key = prop->key()->AsLiteral(); | 2547 Literal* key = prop->key()->AsLiteral(); |
2548 DCHECK(key != NULL); | 2548 DCHECK(key != NULL); |
2549 | 2549 |
2550 __ push(eax); | 2550 __ push(eax); |
2551 __ push(Immediate(key->value())); | 2551 __ push(Immediate(key->value())); |
2552 __ CallRuntime((strict_mode() == STRICT ? Runtime::kStoreToSuper_Strict | 2552 __ CallRuntime((strict_mode() == STRICT ? Runtime::kStoreToSuper_Strict |
2553 : Runtime::kStoreToSuper_Sloppy), | 2553 : Runtime::kStoreToSuper_Sloppy), |
2554 4); | 2554 4); |
2555 context()->Plug(eax); | |
2556 } | 2555 } |
2557 | 2556 |
2558 | 2557 |
2559 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { | 2558 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { |
2560 // Assignment to a property, using a keyed store IC. | 2559 // Assignment to a property, using a keyed store IC. |
2561 // eax : value | 2560 // eax : value |
2562 // esp[0] : key | 2561 // esp[0] : key |
2563 // esp[kPointerSize] : receiver | 2562 // esp[kPointerSize] : receiver |
2564 | 2563 |
2565 __ pop(StoreDescriptor::NameRegister()); // Key. | 2564 __ pop(StoreDescriptor::NameRegister()); // Key. |
(...skipping 1748 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4314 | 4313 |
4315 | 4314 |
4316 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { | 4315 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { |
4317 DCHECK(expr->expression()->IsValidReferenceExpression()); | 4316 DCHECK(expr->expression()->IsValidReferenceExpression()); |
4318 | 4317 |
4319 Comment cmnt(masm_, "[ CountOperation"); | 4318 Comment cmnt(masm_, "[ CountOperation"); |
4320 SetSourcePosition(expr->position()); | 4319 SetSourcePosition(expr->position()); |
4321 | 4320 |
4322 // Expression can only be a property, a global or a (parameter or local) | 4321 // Expression can only be a property, a global or a (parameter or local) |
4323 // slot. | 4322 // slot. |
4324 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; | 4323 enum LhsKind { |
| 4324 VARIABLE, |
| 4325 NAMED_PROPERTY, |
| 4326 KEYED_PROPERTY, |
| 4327 NAMED_SUPER_PROPERTY |
| 4328 }; |
4325 LhsKind assign_type = VARIABLE; | 4329 LhsKind assign_type = VARIABLE; |
4326 Property* prop = expr->expression()->AsProperty(); | 4330 Property* prop = expr->expression()->AsProperty(); |
4327 // In case of a property we use the uninitialized expression context | 4331 // In case of a property we use the uninitialized expression context |
4328 // of the key to detect a named property. | 4332 // of the key to detect a named property. |
4329 if (prop != NULL) { | 4333 if (prop != NULL) { |
4330 assign_type = | 4334 assign_type = |
4331 (prop->key()->IsPropertyName()) ? NAMED_PROPERTY : KEYED_PROPERTY; | 4335 (prop->key()->IsPropertyName()) |
4332 if (prop->IsSuperAccess()) { | 4336 ? (prop->IsSuperAccess() ? NAMED_SUPER_PROPERTY : NAMED_PROPERTY) |
4333 // throw exception. | 4337 : KEYED_PROPERTY; |
4334 VisitSuperReference(prop->obj()->AsSuperReference()); | |
4335 return; | |
4336 } | |
4337 } | 4338 } |
4338 | 4339 |
4339 // Evaluate expression and get value. | 4340 // Evaluate expression and get value. |
4340 if (assign_type == VARIABLE) { | 4341 if (assign_type == VARIABLE) { |
4341 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); | 4342 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); |
4342 AccumulatorValueContext context(this); | 4343 AccumulatorValueContext context(this); |
4343 EmitVariableLoad(expr->expression()->AsVariableProxy()); | 4344 EmitVariableLoad(expr->expression()->AsVariableProxy()); |
4344 } else { | 4345 } else { |
4345 // Reserve space for result of postfix operation. | 4346 // Reserve space for result of postfix operation. |
4346 if (expr->is_postfix() && !context()->IsEffect()) { | 4347 if (expr->is_postfix() && !context()->IsEffect()) { |
4347 __ push(Immediate(Smi::FromInt(0))); | 4348 __ push(Immediate(Smi::FromInt(0))); |
4348 } | 4349 } |
4349 if (assign_type == NAMED_PROPERTY) { | 4350 if (assign_type == NAMED_PROPERTY) { |
4350 // Put the object both on the stack and in the register. | 4351 // Put the object both on the stack and in the register. |
4351 VisitForStackValue(prop->obj()); | 4352 VisitForStackValue(prop->obj()); |
4352 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); | 4353 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); |
4353 EmitNamedPropertyLoad(prop); | 4354 EmitNamedPropertyLoad(prop); |
| 4355 } else if (assign_type == NAMED_SUPER_PROPERTY) { |
| 4356 VisitForStackValue(prop->obj()->AsSuperReference()->this_var()); |
| 4357 EmitLoadHomeObject(prop->obj()->AsSuperReference()); |
| 4358 __ push(result_register()); |
| 4359 __ push(MemOperand(esp, kPointerSize)); |
| 4360 __ push(result_register()); |
| 4361 EmitNamedSuperPropertyLoad(prop); |
4354 } else { | 4362 } else { |
4355 VisitForStackValue(prop->obj()); | 4363 VisitForStackValue(prop->obj()); |
4356 VisitForStackValue(prop->key()); | 4364 VisitForStackValue(prop->key()); |
4357 __ mov(LoadDescriptor::ReceiverRegister(), | 4365 __ mov(LoadDescriptor::ReceiverRegister(), |
4358 Operand(esp, kPointerSize)); // Object. | 4366 Operand(esp, kPointerSize)); // Object. |
4359 __ mov(LoadDescriptor::NameRegister(), Operand(esp, 0)); // Key. | 4367 __ mov(LoadDescriptor::NameRegister(), Operand(esp, 0)); // Key. |
4360 EmitKeyedPropertyLoad(prop); | 4368 EmitKeyedPropertyLoad(prop); |
4361 } | 4369 } |
4362 } | 4370 } |
4363 | 4371 |
(...skipping 18 matching lines...) Expand all Loading... |
4382 // Save the result on the stack. If we have a named or keyed property | 4390 // Save the result on the stack. If we have a named or keyed property |
4383 // we store the result under the receiver that is currently on top | 4391 // we store the result under the receiver that is currently on top |
4384 // of the stack. | 4392 // of the stack. |
4385 switch (assign_type) { | 4393 switch (assign_type) { |
4386 case VARIABLE: | 4394 case VARIABLE: |
4387 __ push(eax); | 4395 __ push(eax); |
4388 break; | 4396 break; |
4389 case NAMED_PROPERTY: | 4397 case NAMED_PROPERTY: |
4390 __ mov(Operand(esp, kPointerSize), eax); | 4398 __ mov(Operand(esp, kPointerSize), eax); |
4391 break; | 4399 break; |
| 4400 case NAMED_SUPER_PROPERTY: |
| 4401 __ mov(Operand(esp, 2 * kPointerSize), eax); |
| 4402 break; |
4392 case KEYED_PROPERTY: | 4403 case KEYED_PROPERTY: |
4393 __ mov(Operand(esp, 2 * kPointerSize), eax); | 4404 __ mov(Operand(esp, 2 * kPointerSize), eax); |
4394 break; | 4405 break; |
4395 } | 4406 } |
4396 } | 4407 } |
4397 } | 4408 } |
4398 | 4409 |
4399 if (expr->op() == Token::INC) { | 4410 if (expr->op() == Token::INC) { |
4400 __ add(eax, Immediate(Smi::FromInt(1))); | 4411 __ add(eax, Immediate(Smi::FromInt(1))); |
4401 } else { | 4412 } else { |
(...skipping 18 matching lines...) Expand all Loading... |
4420 // Save the result on the stack. If we have a named or keyed property | 4431 // Save the result on the stack. If we have a named or keyed property |
4421 // we store the result under the receiver that is currently on top | 4432 // we store the result under the receiver that is currently on top |
4422 // of the stack. | 4433 // of the stack. |
4423 switch (assign_type) { | 4434 switch (assign_type) { |
4424 case VARIABLE: | 4435 case VARIABLE: |
4425 __ push(eax); | 4436 __ push(eax); |
4426 break; | 4437 break; |
4427 case NAMED_PROPERTY: | 4438 case NAMED_PROPERTY: |
4428 __ mov(Operand(esp, kPointerSize), eax); | 4439 __ mov(Operand(esp, kPointerSize), eax); |
4429 break; | 4440 break; |
| 4441 case NAMED_SUPER_PROPERTY: |
| 4442 __ mov(Operand(esp, 2 * kPointerSize), eax); |
| 4443 break; |
4430 case KEYED_PROPERTY: | 4444 case KEYED_PROPERTY: |
4431 __ mov(Operand(esp, 2 * kPointerSize), eax); | 4445 __ mov(Operand(esp, 2 * kPointerSize), eax); |
4432 break; | 4446 break; |
4433 } | 4447 } |
4434 } | 4448 } |
4435 } | 4449 } |
4436 | 4450 |
4437 // Record position before stub call. | 4451 // Record position before stub call. |
4438 SetSourcePosition(expr->position()); | 4452 SetSourcePosition(expr->position()); |
4439 | 4453 |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4479 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4493 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
4480 if (expr->is_postfix()) { | 4494 if (expr->is_postfix()) { |
4481 if (!context()->IsEffect()) { | 4495 if (!context()->IsEffect()) { |
4482 context()->PlugTOS(); | 4496 context()->PlugTOS(); |
4483 } | 4497 } |
4484 } else { | 4498 } else { |
4485 context()->Plug(eax); | 4499 context()->Plug(eax); |
4486 } | 4500 } |
4487 break; | 4501 break; |
4488 } | 4502 } |
| 4503 case NAMED_SUPER_PROPERTY: { |
| 4504 EmitNamedSuperPropertyStore(prop); |
| 4505 if (expr->is_postfix()) { |
| 4506 if (!context()->IsEffect()) { |
| 4507 context()->PlugTOS(); |
| 4508 } |
| 4509 } else { |
| 4510 context()->Plug(eax); |
| 4511 } |
| 4512 break; |
| 4513 } |
4489 case KEYED_PROPERTY: { | 4514 case KEYED_PROPERTY: { |
4490 __ pop(StoreDescriptor::NameRegister()); | 4515 __ pop(StoreDescriptor::NameRegister()); |
4491 __ pop(StoreDescriptor::ReceiverRegister()); | 4516 __ pop(StoreDescriptor::ReceiverRegister()); |
4492 Handle<Code> ic = | 4517 Handle<Code> ic = |
4493 CodeFactory::KeyedStoreIC(isolate(), strict_mode()).code(); | 4518 CodeFactory::KeyedStoreIC(isolate(), strict_mode()).code(); |
4494 CallIC(ic, expr->CountStoreFeedbackId()); | 4519 CallIC(ic, expr->CountStoreFeedbackId()); |
4495 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4520 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
4496 if (expr->is_postfix()) { | 4521 if (expr->is_postfix()) { |
4497 // Result is on the stack | 4522 // Result is on the stack |
4498 if (!context()->IsEffect()) { | 4523 if (!context()->IsEffect()) { |
(...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4940 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), | 4965 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), |
4941 Assembler::target_address_at(call_target_address, | 4966 Assembler::target_address_at(call_target_address, |
4942 unoptimized_code)); | 4967 unoptimized_code)); |
4943 return OSR_AFTER_STACK_CHECK; | 4968 return OSR_AFTER_STACK_CHECK; |
4944 } | 4969 } |
4945 | 4970 |
4946 | 4971 |
4947 } } // namespace v8::internal | 4972 } } // namespace v8::internal |
4948 | 4973 |
4949 #endif // V8_TARGET_ARCH_X87 | 4974 #endif // V8_TARGET_ARCH_X87 |
OLD | NEW |