| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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_PPC | 7 #if V8_TARGET_ARCH_PPC |
| 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 1369 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1380 // Check that extension is NULL. | 1380 // Check that extension is NULL. |
| 1381 __ LoadP(temp, ContextOperand(next, Context::EXTENSION_INDEX)); | 1381 __ LoadP(temp, ContextOperand(next, Context::EXTENSION_INDEX)); |
| 1382 __ cmpi(temp, Operand::Zero()); | 1382 __ cmpi(temp, Operand::Zero()); |
| 1383 __ bne(slow); | 1383 __ bne(slow); |
| 1384 // Load next context in chain. | 1384 // Load next context in chain. |
| 1385 __ LoadP(next, ContextOperand(next, Context::PREVIOUS_INDEX)); | 1385 __ LoadP(next, ContextOperand(next, Context::PREVIOUS_INDEX)); |
| 1386 __ b(&loop); | 1386 __ b(&loop); |
| 1387 __ bind(&fast); | 1387 __ bind(&fast); |
| 1388 } | 1388 } |
| 1389 | 1389 |
| 1390 __ LoadP(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); | 1390 // All extension objects were empty and it is safe to use a normal global |
| 1391 __ mov(LoadDescriptor::NameRegister(), Operand(proxy->var()->name())); | 1391 // load machinery. |
| 1392 __ mov(LoadDescriptor::SlotRegister(), | 1392 EmitGlobalVariableLoad(proxy, typeof_state); |
| 1393 Operand(SmiFromSlot(proxy->VariableFeedbackSlot()))); | |
| 1394 | |
| 1395 ContextualMode mode = | |
| 1396 (typeof_state == INSIDE_TYPEOF) ? NOT_CONTEXTUAL : CONTEXTUAL; | |
| 1397 CallLoadIC(mode); | |
| 1398 } | 1393 } |
| 1399 | 1394 |
| 1400 | 1395 |
| 1401 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, | 1396 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, |
| 1402 Label* slow) { | 1397 Label* slow) { |
| 1403 DCHECK(var->IsContextSlot()); | 1398 DCHECK(var->IsContextSlot()); |
| 1404 Register context = cp; | 1399 Register context = cp; |
| 1405 Register next = r6; | 1400 Register next = r6; |
| 1406 Register temp = r7; | 1401 Register temp = r7; |
| 1407 | 1402 |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1455 __ mov(r3, Operand(var->name())); | 1450 __ mov(r3, Operand(var->name())); |
| 1456 __ push(r3); | 1451 __ push(r3); |
| 1457 __ CallRuntime(Runtime::kThrowReferenceError, 1); | 1452 __ CallRuntime(Runtime::kThrowReferenceError, 1); |
| 1458 } | 1453 } |
| 1459 } | 1454 } |
| 1460 __ b(done); | 1455 __ b(done); |
| 1461 } | 1456 } |
| 1462 } | 1457 } |
| 1463 | 1458 |
| 1464 | 1459 |
| 1465 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { | 1460 void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy, |
| 1461 TypeofState typeof_state) { |
| 1462 Variable* var = proxy->var(); |
| 1463 DCHECK(var->IsUnallocatedOrGlobalSlot() || |
| 1464 (var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL)); |
| 1465 __ LoadP(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); |
| 1466 __ mov(LoadDescriptor::NameRegister(), Operand(var->name())); |
| 1467 __ mov(LoadDescriptor::SlotRegister(), |
| 1468 Operand(SmiFromSlot(proxy->VariableFeedbackSlot()))); |
| 1469 // Inside typeof use a regular load, not a contextual load, to avoid |
| 1470 // a reference error. |
| 1471 CallLoadIC(typeof_state == NOT_INSIDE_TYPEOF ? CONTEXTUAL : NOT_CONTEXTUAL); |
| 1472 } |
| 1473 |
| 1474 |
| 1475 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy, |
| 1476 TypeofState typeof_state) { |
| 1466 // Record position before possible IC call. | 1477 // Record position before possible IC call. |
| 1467 SetExpressionPosition(proxy); | 1478 SetExpressionPosition(proxy); |
| 1468 PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS); | 1479 PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS); |
| 1469 Variable* var = proxy->var(); | 1480 Variable* var = proxy->var(); |
| 1470 | 1481 |
| 1471 // Three cases: global variables, lookup variables, and all other types of | 1482 // Three cases: global variables, lookup variables, and all other types of |
| 1472 // variables. | 1483 // variables. |
| 1473 switch (var->location()) { | 1484 switch (var->location()) { |
| 1474 case VariableLocation::GLOBAL: | 1485 case VariableLocation::GLOBAL: |
| 1475 case VariableLocation::UNALLOCATED: { | 1486 case VariableLocation::UNALLOCATED: { |
| 1476 Comment cmnt(masm_, "[ Global variable"); | 1487 Comment cmnt(masm_, "[ Global variable"); |
| 1477 __ LoadP(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); | 1488 EmitGlobalVariableLoad(proxy, typeof_state); |
| 1478 __ mov(LoadDescriptor::NameRegister(), Operand(var->name())); | |
| 1479 __ mov(LoadDescriptor::SlotRegister(), | |
| 1480 Operand(SmiFromSlot(proxy->VariableFeedbackSlot()))); | |
| 1481 CallGlobalLoadIC(var->name()); | |
| 1482 context()->Plug(r3); | 1489 context()->Plug(r3); |
| 1483 break; | 1490 break; |
| 1484 } | 1491 } |
| 1485 | 1492 |
| 1486 case VariableLocation::PARAMETER: | 1493 case VariableLocation::PARAMETER: |
| 1487 case VariableLocation::LOCAL: | 1494 case VariableLocation::LOCAL: |
| 1488 case VariableLocation::CONTEXT: { | 1495 case VariableLocation::CONTEXT: { |
| 1496 DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_state); |
| 1489 Comment cmnt(masm_, var->IsContextSlot() ? "[ Context variable" | 1497 Comment cmnt(masm_, var->IsContextSlot() ? "[ Context variable" |
| 1490 : "[ Stack variable"); | 1498 : "[ Stack variable"); |
| 1491 if (var->binding_needs_init()) { | 1499 if (var->binding_needs_init()) { |
| 1492 // var->scope() may be NULL when the proxy is located in eval code and | 1500 // var->scope() may be NULL when the proxy is located in eval code and |
| 1493 // refers to a potential outside binding. Currently those bindings are | 1501 // refers to a potential outside binding. Currently those bindings are |
| 1494 // always looked up dynamically, i.e. in that case | 1502 // always looked up dynamically, i.e. in that case |
| 1495 // var->location() == LOOKUP. | 1503 // var->location() == LOOKUP. |
| 1496 // always holds. | 1504 // always holds. |
| 1497 DCHECK(var->scope() != NULL); | 1505 DCHECK(var->scope() != NULL); |
| 1498 | 1506 |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1552 } | 1560 } |
| 1553 context()->Plug(var); | 1561 context()->Plug(var); |
| 1554 break; | 1562 break; |
| 1555 } | 1563 } |
| 1556 | 1564 |
| 1557 case VariableLocation::LOOKUP: { | 1565 case VariableLocation::LOOKUP: { |
| 1558 Comment cmnt(masm_, "[ Lookup variable"); | 1566 Comment cmnt(masm_, "[ Lookup variable"); |
| 1559 Label done, slow; | 1567 Label done, slow; |
| 1560 // Generate code for loading from variables potentially shadowed | 1568 // Generate code for loading from variables potentially shadowed |
| 1561 // by eval-introduced variables. | 1569 // by eval-introduced variables. |
| 1562 EmitDynamicLookupFastCase(proxy, NOT_INSIDE_TYPEOF, &slow, &done); | 1570 EmitDynamicLookupFastCase(proxy, typeof_state, &slow, &done); |
| 1563 __ bind(&slow); | 1571 __ bind(&slow); |
| 1564 __ mov(r4, Operand(var->name())); | 1572 __ mov(r4, Operand(var->name())); |
| 1565 __ Push(cp, r4); // Context and name. | 1573 __ Push(cp, r4); // Context and name. |
| 1566 __ CallRuntime(Runtime::kLoadLookupSlot, 2); | 1574 Runtime::FunctionId function_id = |
| 1575 typeof_state == NOT_INSIDE_TYPEOF |
| 1576 ? Runtime::kLoadLookupSlot |
| 1577 : Runtime::kLoadLookupSlotNoReferenceError; |
| 1578 __ CallRuntime(function_id, 2); |
| 1567 __ bind(&done); | 1579 __ bind(&done); |
| 1568 context()->Plug(r3); | 1580 context()->Plug(r3); |
| 1569 } | 1581 } |
| 1570 } | 1582 } |
| 1571 } | 1583 } |
| 1572 | 1584 |
| 1573 | 1585 |
| 1574 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { | 1586 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { |
| 1575 Comment cmnt(masm_, "[ RegExpLiteral"); | 1587 Comment cmnt(masm_, "[ RegExpLiteral"); |
| 1576 Label materialized; | 1588 Label materialized; |
| (...skipping 3594 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5171 } | 5183 } |
| 5172 } else { | 5184 } else { |
| 5173 context()->Plug(r3); | 5185 context()->Plug(r3); |
| 5174 } | 5186 } |
| 5175 break; | 5187 break; |
| 5176 } | 5188 } |
| 5177 } | 5189 } |
| 5178 } | 5190 } |
| 5179 | 5191 |
| 5180 | 5192 |
| 5181 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { | |
| 5182 DCHECK(!context()->IsEffect()); | |
| 5183 DCHECK(!context()->IsTest()); | |
| 5184 VariableProxy* proxy = expr->AsVariableProxy(); | |
| 5185 if (proxy != NULL && proxy->var()->IsUnallocatedOrGlobalSlot()) { | |
| 5186 Comment cmnt(masm_, "[ Global variable"); | |
| 5187 __ LoadP(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); | |
| 5188 __ mov(LoadDescriptor::NameRegister(), Operand(proxy->name())); | |
| 5189 __ mov(LoadDescriptor::SlotRegister(), | |
| 5190 Operand(SmiFromSlot(proxy->VariableFeedbackSlot()))); | |
| 5191 // Use a regular load, not a contextual load, to avoid a reference | |
| 5192 // error. | |
| 5193 CallLoadIC(NOT_CONTEXTUAL); | |
| 5194 PrepareForBailout(expr, TOS_REG); | |
| 5195 context()->Plug(r3); | |
| 5196 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { | |
| 5197 Comment cmnt(masm_, "[ Lookup slot"); | |
| 5198 Label done, slow; | |
| 5199 | |
| 5200 // Generate code for loading from variables potentially shadowed | |
| 5201 // by eval-introduced variables. | |
| 5202 EmitDynamicLookupFastCase(proxy, INSIDE_TYPEOF, &slow, &done); | |
| 5203 | |
| 5204 __ bind(&slow); | |
| 5205 __ mov(r3, Operand(proxy->name())); | |
| 5206 __ Push(cp, r3); | |
| 5207 __ CallRuntime(Runtime::kLoadLookupSlotNoReferenceError, 2); | |
| 5208 PrepareForBailout(expr, TOS_REG); | |
| 5209 __ bind(&done); | |
| 5210 | |
| 5211 context()->Plug(r3); | |
| 5212 } else { | |
| 5213 // This expression cannot throw a reference error at the top level. | |
| 5214 VisitInDuplicateContext(expr); | |
| 5215 } | |
| 5216 } | |
| 5217 | |
| 5218 | |
| 5219 void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr, | 5193 void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr, |
| 5220 Expression* sub_expr, | 5194 Expression* sub_expr, |
| 5221 Handle<String> check) { | 5195 Handle<String> check) { |
| 5222 Label materialize_true, materialize_false; | 5196 Label materialize_true, materialize_false; |
| 5223 Label* if_true = NULL; | 5197 Label* if_true = NULL; |
| 5224 Label* if_false = NULL; | 5198 Label* if_false = NULL; |
| 5225 Label* fall_through = NULL; | 5199 Label* fall_through = NULL; |
| 5226 context()->PrepareTest(&materialize_true, &materialize_false, &if_true, | 5200 context()->PrepareTest(&materialize_true, &materialize_false, &if_true, |
| 5227 &if_false, &fall_through); | 5201 &if_false, &fall_through); |
| 5228 | 5202 |
| (...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5573 return ON_STACK_REPLACEMENT; | 5547 return ON_STACK_REPLACEMENT; |
| 5574 } | 5548 } |
| 5575 | 5549 |
| 5576 DCHECK(interrupt_address == | 5550 DCHECK(interrupt_address == |
| 5577 isolate->builtins()->OsrAfterStackCheck()->entry()); | 5551 isolate->builtins()->OsrAfterStackCheck()->entry()); |
| 5578 return OSR_AFTER_STACK_CHECK; | 5552 return OSR_AFTER_STACK_CHECK; |
| 5579 } | 5553 } |
| 5580 } // namespace internal | 5554 } // namespace internal |
| 5581 } // namespace v8 | 5555 } // namespace v8 |
| 5582 #endif // V8_TARGET_ARCH_PPC | 5556 #endif // V8_TARGET_ARCH_PPC |
| OLD | NEW |