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