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_MIPS | 7 #if V8_TARGET_ARCH_MIPS |
8 | 8 |
9 // Note on Mips implementation: | 9 // Note on Mips implementation: |
10 // | 10 // |
(...skipping 1390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1401 __ Branch(&fast, eq, temp, Operand(t0)); | 1401 __ Branch(&fast, eq, temp, Operand(t0)); |
1402 // Check that extension is NULL. | 1402 // Check that extension is NULL. |
1403 __ lw(temp, ContextOperand(next, Context::EXTENSION_INDEX)); | 1403 __ lw(temp, ContextOperand(next, Context::EXTENSION_INDEX)); |
1404 __ Branch(slow, ne, temp, Operand(zero_reg)); | 1404 __ Branch(slow, ne, temp, Operand(zero_reg)); |
1405 // Load next context in chain. | 1405 // Load next context in chain. |
1406 __ lw(next, ContextOperand(next, Context::PREVIOUS_INDEX)); | 1406 __ lw(next, ContextOperand(next, Context::PREVIOUS_INDEX)); |
1407 __ Branch(&loop); | 1407 __ Branch(&loop); |
1408 __ bind(&fast); | 1408 __ bind(&fast); |
1409 } | 1409 } |
1410 | 1410 |
1411 __ lw(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); | 1411 // All extension objects were empty and it is safe to use a normal global |
1412 __ li(LoadDescriptor::NameRegister(), Operand(proxy->var()->name())); | 1412 // load machinery. |
1413 __ li(LoadDescriptor::SlotRegister(), | 1413 EmitGlobalVariableLoad(proxy, typeof_state); |
1414 Operand(SmiFromSlot(proxy->VariableFeedbackSlot()))); | |
1415 | |
1416 ContextualMode mode = (typeof_state == INSIDE_TYPEOF) | |
1417 ? NOT_CONTEXTUAL | |
1418 : CONTEXTUAL; | |
1419 CallLoadIC(mode); | |
1420 } | 1414 } |
1421 | 1415 |
1422 | 1416 |
1423 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, | 1417 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, |
1424 Label* slow) { | 1418 Label* slow) { |
1425 DCHECK(var->IsContextSlot()); | 1419 DCHECK(var->IsContextSlot()); |
1426 Register context = cp; | 1420 Register context = cp; |
1427 Register next = a3; | 1421 Register next = a3; |
1428 Register temp = t0; | 1422 Register temp = t0; |
1429 | 1423 |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1478 __ li(a0, Operand(var->name())); | 1472 __ li(a0, Operand(var->name())); |
1479 __ push(a0); | 1473 __ push(a0); |
1480 __ CallRuntime(Runtime::kThrowReferenceError, 1); | 1474 __ CallRuntime(Runtime::kThrowReferenceError, 1); |
1481 } | 1475 } |
1482 } | 1476 } |
1483 __ Branch(done); | 1477 __ Branch(done); |
1484 } | 1478 } |
1485 } | 1479 } |
1486 | 1480 |
1487 | 1481 |
1488 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { | 1482 void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy, |
| 1483 TypeofState typeof_state) { |
| 1484 Variable* var = proxy->var(); |
| 1485 DCHECK(var->IsUnallocatedOrGlobalSlot() || |
| 1486 (var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL)); |
| 1487 __ lw(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); |
| 1488 __ li(LoadDescriptor::NameRegister(), Operand(var->name())); |
| 1489 __ li(LoadDescriptor::SlotRegister(), |
| 1490 Operand(SmiFromSlot(proxy->VariableFeedbackSlot()))); |
| 1491 // Inside typeof use a regular load, not a contextual load, to avoid |
| 1492 // a reference error. |
| 1493 CallLoadIC(typeof_state == NOT_INSIDE_TYPEOF ? CONTEXTUAL : NOT_CONTEXTUAL); |
| 1494 } |
| 1495 |
| 1496 |
| 1497 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy, |
| 1498 TypeofState typeof_state) { |
1489 // Record position before possible IC call. | 1499 // Record position before possible IC call. |
1490 SetExpressionPosition(proxy); | 1500 SetExpressionPosition(proxy); |
1491 PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS); | 1501 PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS); |
1492 Variable* var = proxy->var(); | 1502 Variable* var = proxy->var(); |
1493 | 1503 |
1494 // Three cases: global variables, lookup variables, and all other types of | 1504 // Three cases: global variables, lookup variables, and all other types of |
1495 // variables. | 1505 // variables. |
1496 switch (var->location()) { | 1506 switch (var->location()) { |
1497 case VariableLocation::GLOBAL: | 1507 case VariableLocation::GLOBAL: |
1498 case VariableLocation::UNALLOCATED: { | 1508 case VariableLocation::UNALLOCATED: { |
1499 Comment cmnt(masm_, "[ Global variable"); | 1509 Comment cmnt(masm_, "[ Global variable"); |
1500 __ lw(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); | 1510 EmitGlobalVariableLoad(proxy, typeof_state); |
1501 __ li(LoadDescriptor::NameRegister(), Operand(var->name())); | |
1502 __ li(LoadDescriptor::SlotRegister(), | |
1503 Operand(SmiFromSlot(proxy->VariableFeedbackSlot()))); | |
1504 CallGlobalLoadIC(var->name()); | |
1505 context()->Plug(v0); | 1511 context()->Plug(v0); |
1506 break; | 1512 break; |
1507 } | 1513 } |
1508 | 1514 |
1509 case VariableLocation::PARAMETER: | 1515 case VariableLocation::PARAMETER: |
1510 case VariableLocation::LOCAL: | 1516 case VariableLocation::LOCAL: |
1511 case VariableLocation::CONTEXT: { | 1517 case VariableLocation::CONTEXT: { |
| 1518 DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_state); |
1512 Comment cmnt(masm_, var->IsContextSlot() ? "[ Context variable" | 1519 Comment cmnt(masm_, var->IsContextSlot() ? "[ Context variable" |
1513 : "[ Stack variable"); | 1520 : "[ Stack variable"); |
1514 if (var->binding_needs_init()) { | 1521 if (var->binding_needs_init()) { |
1515 // var->scope() may be NULL when the proxy is located in eval code and | 1522 // var->scope() may be NULL when the proxy is located in eval code and |
1516 // refers to a potential outside binding. Currently those bindings are | 1523 // refers to a potential outside binding. Currently those bindings are |
1517 // always looked up dynamically, i.e. in that case | 1524 // always looked up dynamically, i.e. in that case |
1518 // var->location() == LOOKUP. | 1525 // var->location() == LOOKUP. |
1519 // always holds. | 1526 // always holds. |
1520 DCHECK(var->scope() != NULL); | 1527 DCHECK(var->scope() != NULL); |
1521 | 1528 |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1577 } | 1584 } |
1578 context()->Plug(var); | 1585 context()->Plug(var); |
1579 break; | 1586 break; |
1580 } | 1587 } |
1581 | 1588 |
1582 case VariableLocation::LOOKUP: { | 1589 case VariableLocation::LOOKUP: { |
1583 Comment cmnt(masm_, "[ Lookup variable"); | 1590 Comment cmnt(masm_, "[ Lookup variable"); |
1584 Label done, slow; | 1591 Label done, slow; |
1585 // Generate code for loading from variables potentially shadowed | 1592 // Generate code for loading from variables potentially shadowed |
1586 // by eval-introduced variables. | 1593 // by eval-introduced variables. |
1587 EmitDynamicLookupFastCase(proxy, NOT_INSIDE_TYPEOF, &slow, &done); | 1594 EmitDynamicLookupFastCase(proxy, typeof_state, &slow, &done); |
1588 __ bind(&slow); | 1595 __ bind(&slow); |
1589 __ li(a1, Operand(var->name())); | 1596 __ li(a1, Operand(var->name())); |
1590 __ Push(cp, a1); // Context and name. | 1597 __ Push(cp, a1); // Context and name. |
1591 __ CallRuntime(Runtime::kLoadLookupSlot, 2); | 1598 Runtime::FunctionId function_id = |
| 1599 typeof_state == NOT_INSIDE_TYPEOF |
| 1600 ? Runtime::kLoadLookupSlot |
| 1601 : Runtime::kLoadLookupSlotNoReferenceError; |
| 1602 __ CallRuntime(function_id, 2); |
1592 __ bind(&done); | 1603 __ bind(&done); |
1593 context()->Plug(v0); | 1604 context()->Plug(v0); |
1594 } | 1605 } |
1595 } | 1606 } |
1596 } | 1607 } |
1597 | 1608 |
1598 | 1609 |
1599 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { | 1610 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { |
1600 Comment cmnt(masm_, "[ RegExpLiteral"); | 1611 Comment cmnt(masm_, "[ RegExpLiteral"); |
1601 Label materialized; | 1612 Label materialized; |
(...skipping 3568 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5170 } | 5181 } |
5171 } else { | 5182 } else { |
5172 context()->Plug(v0); | 5183 context()->Plug(v0); |
5173 } | 5184 } |
5174 break; | 5185 break; |
5175 } | 5186 } |
5176 } | 5187 } |
5177 } | 5188 } |
5178 | 5189 |
5179 | 5190 |
5180 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { | |
5181 DCHECK(!context()->IsEffect()); | |
5182 DCHECK(!context()->IsTest()); | |
5183 VariableProxy* proxy = expr->AsVariableProxy(); | |
5184 if (proxy != NULL && proxy->var()->IsUnallocatedOrGlobalSlot()) { | |
5185 Comment cmnt(masm_, "[ Global variable"); | |
5186 __ lw(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); | |
5187 __ li(LoadDescriptor::NameRegister(), Operand(proxy->name())); | |
5188 __ li(LoadDescriptor::SlotRegister(), | |
5189 Operand(SmiFromSlot(proxy->VariableFeedbackSlot()))); | |
5190 // Use a regular load, not a contextual load, to avoid a reference | |
5191 // error. | |
5192 CallLoadIC(NOT_CONTEXTUAL); | |
5193 PrepareForBailout(expr, TOS_REG); | |
5194 context()->Plug(v0); | |
5195 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { | |
5196 Comment cmnt(masm_, "[ Lookup slot"); | |
5197 Label done, slow; | |
5198 | |
5199 // Generate code for loading from variables potentially shadowed | |
5200 // by eval-introduced variables. | |
5201 EmitDynamicLookupFastCase(proxy, INSIDE_TYPEOF, &slow, &done); | |
5202 | |
5203 __ bind(&slow); | |
5204 __ li(a0, Operand(proxy->name())); | |
5205 __ Push(cp, a0); | |
5206 __ CallRuntime(Runtime::kLoadLookupSlotNoReferenceError, 2); | |
5207 PrepareForBailout(expr, TOS_REG); | |
5208 __ bind(&done); | |
5209 | |
5210 context()->Plug(v0); | |
5211 } else { | |
5212 // This expression cannot throw a reference error at the top level. | |
5213 VisitInDuplicateContext(expr); | |
5214 } | |
5215 } | |
5216 | |
5217 void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr, | 5191 void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr, |
5218 Expression* sub_expr, | 5192 Expression* sub_expr, |
5219 Handle<String> check) { | 5193 Handle<String> check) { |
5220 Label materialize_true, materialize_false; | 5194 Label materialize_true, materialize_false; |
5221 Label* if_true = NULL; | 5195 Label* if_true = NULL; |
5222 Label* if_false = NULL; | 5196 Label* if_false = NULL; |
5223 Label* fall_through = NULL; | 5197 Label* fall_through = NULL; |
5224 context()->PrepareTest(&materialize_true, &materialize_false, | 5198 context()->PrepareTest(&materialize_true, &materialize_false, |
5225 &if_true, &if_false, &fall_through); | 5199 &if_true, &if_false, &fall_through); |
5226 | 5200 |
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5576 reinterpret_cast<uint32_t>( | 5550 reinterpret_cast<uint32_t>( |
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 | 5554 |
5581 | 5555 |
5582 } // namespace internal | 5556 } // namespace internal |
5583 } // namespace v8 | 5557 } // namespace v8 |
5584 | 5558 |
5585 #endif // V8_TARGET_ARCH_MIPS | 5559 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |