OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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/interpreter/bytecode-generator.h" | 5 #include "src/interpreter/bytecode-generator.h" |
6 | 6 |
7 #include "src/compiler.h" | 7 #include "src/compiler.h" |
8 #include "src/interpreter/control-flow-builders.h" | 8 #include "src/interpreter/control-flow-builders.h" |
9 #include "src/objects.h" | 9 #include "src/objects.h" |
10 #include "src/parser.h" | 10 #include "src/parser.h" |
(...skipping 1175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1186 execution_result()->SetResultInAccumulator(); | 1186 execution_result()->SetResultInAccumulator(); |
1187 } | 1187 } |
1188 | 1188 |
1189 | 1189 |
1190 void BytecodeGenerator::VisitVariableProxy(VariableProxy* proxy) { | 1190 void BytecodeGenerator::VisitVariableProxy(VariableProxy* proxy) { |
1191 VisitVariableLoad(proxy->var(), proxy->VariableFeedbackSlot()); | 1191 VisitVariableLoad(proxy->var(), proxy->VariableFeedbackSlot()); |
1192 } | 1192 } |
1193 | 1193 |
1194 | 1194 |
1195 void BytecodeGenerator::VisitVariableLoad(Variable* variable, | 1195 void BytecodeGenerator::VisitVariableLoad(Variable* variable, |
1196 FeedbackVectorSlot slot) { | 1196 FeedbackVectorSlot slot, |
| 1197 TypeofMode typeof_mode) { |
1197 switch (variable->location()) { | 1198 switch (variable->location()) { |
1198 case VariableLocation::LOCAL: { | 1199 case VariableLocation::LOCAL: { |
1199 Register source(Register(variable->index())); | 1200 Register source(Register(variable->index())); |
1200 execution_result()->SetResultInRegister(source); | 1201 execution_result()->SetResultInRegister(source); |
1201 break; | 1202 break; |
1202 } | 1203 } |
1203 case VariableLocation::PARAMETER: { | 1204 case VariableLocation::PARAMETER: { |
1204 // The parameter indices are shifted by 1 (receiver is variable | 1205 // The parameter indices are shifted by 1 (receiver is variable |
1205 // index -1 but is parameter index 0 in BytecodeArrayBuilder). | 1206 // index -1 but is parameter index 0 in BytecodeArrayBuilder). |
1206 Register source = builder()->Parameter(variable->index() + 1); | 1207 Register source = builder()->Parameter(variable->index() + 1); |
1207 execution_result()->SetResultInRegister(source); | 1208 execution_result()->SetResultInRegister(source); |
1208 break; | 1209 break; |
1209 } | 1210 } |
1210 case VariableLocation::GLOBAL: | 1211 case VariableLocation::GLOBAL: |
1211 case VariableLocation::UNALLOCATED: { | 1212 case VariableLocation::UNALLOCATED: { |
1212 size_t name_index = builder()->GetConstantPoolEntry(variable->name()); | 1213 size_t name_index = builder()->GetConstantPoolEntry(variable->name()); |
1213 builder()->LoadGlobal(name_index, feedback_index(slot), language_mode()); | 1214 builder()->LoadGlobal(name_index, feedback_index(slot), language_mode(), |
| 1215 typeof_mode); |
1214 execution_result()->SetResultInAccumulator(); | 1216 execution_result()->SetResultInAccumulator(); |
1215 break; | 1217 break; |
1216 } | 1218 } |
1217 case VariableLocation::CONTEXT: { | 1219 case VariableLocation::CONTEXT: { |
1218 int depth = execution_context()->ContextChainDepth(variable->scope()); | 1220 int depth = execution_context()->ContextChainDepth(variable->scope()); |
1219 ContextScope* context = execution_context()->Previous(depth); | 1221 ContextScope* context = execution_context()->Previous(depth); |
1220 Register context_reg; | 1222 Register context_reg; |
1221 if (context) { | 1223 if (context) { |
1222 context_reg = context->reg(); | 1224 context_reg = context->reg(); |
1223 } else { | 1225 } else { |
(...skipping 16 matching lines...) Expand all Loading... |
1240 // let variables. | 1242 // let variables. |
1241 break; | 1243 break; |
1242 } | 1244 } |
1243 case VariableLocation::LOOKUP: | 1245 case VariableLocation::LOOKUP: |
1244 UNIMPLEMENTED(); | 1246 UNIMPLEMENTED(); |
1245 } | 1247 } |
1246 } | 1248 } |
1247 | 1249 |
1248 | 1250 |
1249 void BytecodeGenerator::VisitVariableLoadForAccumulatorValue( | 1251 void BytecodeGenerator::VisitVariableLoadForAccumulatorValue( |
1250 Variable* variable, FeedbackVectorSlot slot) { | 1252 Variable* variable, FeedbackVectorSlot slot, TypeofMode typeof_mode) { |
1251 AccumulatorResultScope accumulator_result(this); | 1253 AccumulatorResultScope accumulator_result(this); |
1252 VisitVariableLoad(variable, slot); | 1254 VisitVariableLoad(variable, slot, typeof_mode); |
1253 } | 1255 } |
1254 | 1256 |
1255 | 1257 |
1256 Register BytecodeGenerator::VisitVariableLoadForRegisterValue( | 1258 Register BytecodeGenerator::VisitVariableLoadForRegisterValue( |
1257 Variable* variable, FeedbackVectorSlot slot) { | 1259 Variable* variable, FeedbackVectorSlot slot, TypeofMode typeof_mode) { |
1258 RegisterResultScope register_scope(this); | 1260 RegisterResultScope register_scope(this); |
1259 VisitVariableLoad(variable, slot); | 1261 VisitVariableLoad(variable, slot, typeof_mode); |
1260 return register_scope.ResultRegister(); | 1262 return register_scope.ResultRegister(); |
1261 } | 1263 } |
1262 | 1264 |
1263 | 1265 |
1264 void BytecodeGenerator::VisitVariableAssignment(Variable* variable, | 1266 void BytecodeGenerator::VisitVariableAssignment(Variable* variable, |
1265 FeedbackVectorSlot slot) { | 1267 FeedbackVectorSlot slot) { |
1266 switch (variable->location()) { | 1268 switch (variable->location()) { |
1267 case VariableLocation::LOCAL: { | 1269 case VariableLocation::LOCAL: { |
1268 // TODO(rmcilroy): support const mode initialization. | 1270 // TODO(rmcilroy): support const mode initialization. |
1269 Register destination(variable->index()); | 1271 Register destination(variable->index()); |
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1609 | 1611 |
1610 | 1612 |
1611 void BytecodeGenerator::VisitVoid(UnaryOperation* expr) { | 1613 void BytecodeGenerator::VisitVoid(UnaryOperation* expr) { |
1612 VisitForEffect(expr->expression()); | 1614 VisitForEffect(expr->expression()); |
1613 builder()->LoadUndefined(); | 1615 builder()->LoadUndefined(); |
1614 execution_result()->SetResultInAccumulator(); | 1616 execution_result()->SetResultInAccumulator(); |
1615 } | 1617 } |
1616 | 1618 |
1617 | 1619 |
1618 void BytecodeGenerator::VisitTypeOf(UnaryOperation* expr) { | 1620 void BytecodeGenerator::VisitTypeOf(UnaryOperation* expr) { |
1619 // TODO(rmcilroy): Set TypeofMode to INSIDE_TYPEOF for any loadICs performed | 1621 if (expr->expression()->IsVariableProxy()) { |
1620 // while visiting the expression. | 1622 // Typeof does not throw a reference error on global variables, hence we |
1621 VisitForAccumulatorValue(expr->expression()); | 1623 // perform a non-contextual load in case the operand is a variable proxy. |
| 1624 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
| 1625 VisitVariableLoadForAccumulatorValue( |
| 1626 proxy->var(), proxy->VariableFeedbackSlot(), INSIDE_TYPEOF); |
| 1627 } else { |
| 1628 VisitForAccumulatorValue(expr->expression()); |
| 1629 } |
1622 builder()->TypeOf(); | 1630 builder()->TypeOf(); |
1623 execution_result()->SetResultInAccumulator(); | 1631 execution_result()->SetResultInAccumulator(); |
1624 } | 1632 } |
1625 | 1633 |
1626 | 1634 |
1627 void BytecodeGenerator::VisitNot(UnaryOperation* expr) { | 1635 void BytecodeGenerator::VisitNot(UnaryOperation* expr) { |
1628 VisitForAccumulatorValue(expr->expression()); | 1636 VisitForAccumulatorValue(expr->expression()); |
1629 builder()->LogicalNot(); | 1637 builder()->LogicalNot(); |
1630 execution_result()->SetResultInAccumulator(); | 1638 execution_result()->SetResultInAccumulator(); |
1631 } | 1639 } |
(...skipping 528 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2160 } | 2168 } |
2161 | 2169 |
2162 | 2170 |
2163 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { | 2171 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { |
2164 return info()->feedback_vector()->GetIndex(slot); | 2172 return info()->feedback_vector()->GetIndex(slot); |
2165 } | 2173 } |
2166 | 2174 |
2167 } // namespace interpreter | 2175 } // namespace interpreter |
2168 } // namespace internal | 2176 } // namespace internal |
2169 } // namespace v8 | 2177 } // namespace v8 |
OLD | NEW |