Chromium Code Reviews| 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/compiler/ast-graph-builder.h" | 5 #include "src/compiler/ast-graph-builder.h" |
| 6 | 6 |
| 7 #include "src/ast/compile-time-value.h" | 7 #include "src/ast/compile-time-value.h" |
| 8 #include "src/ast/scopes.h" | 8 #include "src/ast/scopes.h" |
| 9 #include "src/compilation-info.h" | 9 #include "src/compilation-info.h" |
| 10 #include "src/compiler.h" | 10 #include "src/compiler.h" |
| (...skipping 1155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1166 for_loop.BreakUnless(jsgraph()->TrueConstant()); | 1166 for_loop.BreakUnless(jsgraph()->TrueConstant()); |
| 1167 } | 1167 } |
| 1168 VisitIterationBody(stmt, &for_loop, stmt->StackCheckId()); | 1168 VisitIterationBody(stmt, &for_loop, stmt->StackCheckId()); |
| 1169 for_loop.EndBody(); | 1169 for_loop.EndBody(); |
| 1170 VisitIfNotNull(stmt->next()); | 1170 VisitIfNotNull(stmt->next()); |
| 1171 for_loop.EndLoop(); | 1171 for_loop.EndLoop(); |
| 1172 } | 1172 } |
| 1173 | 1173 |
| 1174 | 1174 |
| 1175 void AstGraphBuilder::VisitForInStatement(ForInStatement* stmt) { | 1175 void AstGraphBuilder::VisitForInStatement(ForInStatement* stmt) { |
| 1176 VisitForValue(stmt->subject()); | 1176 // Only the BytecodeGraphBuilder supports for-in. |
| 1177 Node* object = environment()->Pop(); | 1177 return SetStackOverflow(); |
|
Yang
2017/02/08 06:24:58
In other places we simply have a UNREACHABLE(). Se
Benedikt Meurer
2017/02/08 06:26:08
We still need to handle for..in inside asm.js, and
| |
| 1178 BlockBuilder for_block(this); | |
| 1179 for_block.BeginBlock(); | |
| 1180 // Check for null or undefined before entering loop. | |
| 1181 Node* is_null_cond = | |
| 1182 NewNode(javascript()->StrictEqual(CompareOperationHint::kAny), object, | |
| 1183 jsgraph()->NullConstant()); | |
| 1184 for_block.BreakWhen(is_null_cond, BranchHint::kFalse); | |
| 1185 Node* is_undefined_cond = | |
| 1186 NewNode(javascript()->StrictEqual(CompareOperationHint::kAny), object, | |
| 1187 jsgraph()->UndefinedConstant()); | |
| 1188 for_block.BreakWhen(is_undefined_cond, BranchHint::kFalse); | |
| 1189 { | |
| 1190 // Convert object to jsobject. | |
| 1191 object = BuildToObject(object, stmt->ToObjectId()); | |
| 1192 environment()->Push(object); | |
| 1193 | |
| 1194 // Prepare for-in cache. | |
| 1195 Node* prepare = NewNode(javascript()->ForInPrepare(), object); | |
| 1196 PrepareFrameState(prepare, stmt->PrepareId(), | |
| 1197 OutputFrameStateCombine::Push(3)); | |
| 1198 Node* cache_type = NewNode(common()->Projection(0), prepare); | |
| 1199 Node* cache_array = NewNode(common()->Projection(1), prepare); | |
| 1200 Node* cache_length = NewNode(common()->Projection(2), prepare); | |
| 1201 | |
| 1202 // Construct the rest of the environment. | |
| 1203 environment()->Push(cache_type); | |
| 1204 environment()->Push(cache_array); | |
| 1205 environment()->Push(cache_length); | |
| 1206 environment()->Push(jsgraph()->ZeroConstant()); | |
| 1207 | |
| 1208 // Build the actual loop body. | |
| 1209 LoopBuilder for_loop(this); | |
| 1210 for_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), CheckOsrEntry(stmt)); | |
| 1211 { | |
| 1212 // These stack values are renamed in the case of OSR, so reload them | |
| 1213 // from the environment. | |
| 1214 Node* index = environment()->Peek(0); | |
| 1215 Node* cache_length = environment()->Peek(1); | |
| 1216 Node* cache_array = environment()->Peek(2); | |
| 1217 Node* cache_type = environment()->Peek(3); | |
| 1218 Node* object = environment()->Peek(4); | |
| 1219 | |
| 1220 // Check loop termination condition (we know that the {index} is always | |
| 1221 // in Smi range, so we can just set the hint on the comparison below). | |
| 1222 PrepareEagerCheckpoint(stmt->EntryId()); | |
| 1223 Node* exit_cond = | |
| 1224 NewNode(javascript()->LessThan(CompareOperationHint::kSignedSmall), | |
| 1225 index, cache_length); | |
| 1226 PrepareFrameState(exit_cond, BailoutId::None()); | |
| 1227 for_loop.BreakUnless(exit_cond); | |
| 1228 | |
| 1229 // Compute the next enumerated value. | |
| 1230 Node* value = NewNode(javascript()->ForInNext(), object, cache_array, | |
| 1231 cache_type, index); | |
| 1232 PrepareFrameState(value, stmt->FilterId(), | |
| 1233 OutputFrameStateCombine::Push()); | |
| 1234 IfBuilder test_value(this); | |
| 1235 Node* test_value_cond = | |
| 1236 NewNode(javascript()->StrictEqual(CompareOperationHint::kAny), value, | |
| 1237 jsgraph()->UndefinedConstant()); | |
| 1238 test_value.If(test_value_cond, BranchHint::kFalse); | |
| 1239 test_value.Then(); | |
| 1240 test_value.Else(); | |
| 1241 { | |
| 1242 environment()->Push(value); | |
| 1243 PrepareEagerCheckpoint(stmt->FilterId()); | |
| 1244 value = environment()->Pop(); | |
| 1245 // Bind value and do loop body. | |
| 1246 VectorSlotPair feedback = | |
| 1247 CreateVectorSlotPair(stmt->EachFeedbackSlot()); | |
| 1248 VisitForInAssignment(stmt->each(), value, feedback, | |
| 1249 stmt->AssignmentId()); | |
| 1250 VisitIterationBody(stmt, &for_loop, stmt->StackCheckId()); | |
| 1251 } | |
| 1252 test_value.End(); | |
| 1253 for_loop.EndBody(); | |
| 1254 | |
| 1255 // Increment counter and continue (we know that the {index} is always | |
| 1256 // in Smi range, so we can just set the hint on the increment below). | |
| 1257 index = environment()->Peek(0); | |
| 1258 PrepareEagerCheckpoint(stmt->IncrementId()); | |
| 1259 index = NewNode(javascript()->Add(BinaryOperationHint::kSignedSmall), | |
| 1260 index, jsgraph()->OneConstant()); | |
| 1261 PrepareFrameState(index, BailoutId::None()); | |
| 1262 environment()->Poke(0, index); | |
| 1263 } | |
| 1264 for_loop.EndLoop(); | |
| 1265 environment()->Drop(5); | |
| 1266 } | |
| 1267 for_block.EndBlock(); | |
| 1268 } | 1178 } |
| 1269 | 1179 |
| 1270 | 1180 |
| 1271 void AstGraphBuilder::VisitForOfStatement(ForOfStatement* stmt) { | 1181 void AstGraphBuilder::VisitForOfStatement(ForOfStatement* stmt) { |
| 1272 // Iterator looping is supported only by going through Ignition first. | 1182 // Iterator looping is supported only by going through Ignition first. |
| 1273 UNREACHABLE(); | 1183 UNREACHABLE(); |
| 1274 } | 1184 } |
| 1275 | 1185 |
| 1276 | 1186 |
| 1277 void AstGraphBuilder::VisitTryCatchStatement(TryCatchStatement* stmt) { | 1187 void AstGraphBuilder::VisitTryCatchStatement(TryCatchStatement* stmt) { |
| (...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1526 Node* index = jsgraph()->Constant(array_index); | 1436 Node* index = jsgraph()->Constant(array_index); |
| 1527 Node* literal = environment()->Top(); | 1437 Node* literal = environment()->Top(); |
| 1528 Node* store = BuildKeyedStore(literal, index, value, pair); | 1438 Node* store = BuildKeyedStore(literal, index, value, pair); |
| 1529 PrepareFrameState(store, expr->GetIdForElement(array_index), | 1439 PrepareFrameState(store, expr->GetIdForElement(array_index), |
| 1530 OutputFrameStateCombine::Ignore()); | 1440 OutputFrameStateCombine::Ignore()); |
| 1531 } | 1441 } |
| 1532 | 1442 |
| 1533 ast_context()->ProduceValue(expr, environment()->Pop()); | 1443 ast_context()->ProduceValue(expr, environment()->Pop()); |
| 1534 } | 1444 } |
| 1535 | 1445 |
| 1536 void AstGraphBuilder::VisitForInAssignment(Expression* expr, Node* value, | |
| 1537 const VectorSlotPair& feedback, | |
| 1538 BailoutId bailout_id) { | |
| 1539 DCHECK(expr->IsValidReferenceExpressionOrThis()); | |
| 1540 | |
| 1541 // Left-hand side can only be a property, a global or a variable slot. | |
| 1542 Property* property = expr->AsProperty(); | |
| 1543 LhsKind assign_type = Property::GetAssignType(property); | |
| 1544 | |
| 1545 // Evaluate LHS expression and store the value. | |
| 1546 switch (assign_type) { | |
| 1547 case VARIABLE: { | |
| 1548 Variable* var = expr->AsVariableProxy()->var(); | |
| 1549 BuildVariableAssignment(var, value, Token::ASSIGN, feedback, bailout_id); | |
| 1550 break; | |
| 1551 } | |
| 1552 case NAMED_PROPERTY: { | |
| 1553 environment()->Push(value); | |
| 1554 VisitForValue(property->obj()); | |
| 1555 Node* object = environment()->Pop(); | |
| 1556 value = environment()->Pop(); | |
| 1557 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); | |
| 1558 Node* store = BuildNamedStore(object, name, value, feedback); | |
| 1559 PrepareFrameState(store, bailout_id, OutputFrameStateCombine::Ignore()); | |
| 1560 break; | |
| 1561 } | |
| 1562 case KEYED_PROPERTY: { | |
| 1563 environment()->Push(value); | |
| 1564 VisitForValue(property->obj()); | |
| 1565 VisitForValue(property->key()); | |
| 1566 Node* key = environment()->Pop(); | |
| 1567 Node* object = environment()->Pop(); | |
| 1568 value = environment()->Pop(); | |
| 1569 Node* store = BuildKeyedStore(object, key, value, feedback); | |
| 1570 PrepareFrameState(store, bailout_id, OutputFrameStateCombine::Ignore()); | |
| 1571 break; | |
| 1572 } | |
| 1573 case NAMED_SUPER_PROPERTY: | |
| 1574 case KEYED_SUPER_PROPERTY: | |
| 1575 UNREACHABLE(); | |
| 1576 break; | |
| 1577 } | |
| 1578 } | |
| 1579 | |
| 1580 | |
| 1581 void AstGraphBuilder::VisitAssignment(Assignment* expr) { | 1446 void AstGraphBuilder::VisitAssignment(Assignment* expr) { |
| 1582 DCHECK(expr->target()->IsValidReferenceExpressionOrThis()); | 1447 DCHECK(expr->target()->IsValidReferenceExpressionOrThis()); |
| 1583 | 1448 |
| 1584 // Left-hand side can only be a property, a global or a variable slot. | 1449 // Left-hand side can only be a property, a global or a variable slot. |
| 1585 Property* property = expr->target()->AsProperty(); | 1450 Property* property = expr->target()->AsProperty(); |
| 1586 LhsKind assign_type = Property::GetAssignType(property); | 1451 LhsKind assign_type = Property::GetAssignType(property); |
| 1587 bool needs_frame_state_before = true; | 1452 bool needs_frame_state_before = true; |
| 1588 | 1453 |
| 1589 // Evaluate LHS expression. | 1454 // Evaluate LHS expression. |
| 1590 switch (assign_type) { | 1455 switch (assign_type) { |
| (...skipping 1720 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3311 float invocation_frequency, LoopAssignmentAnalysis* loop_assignment, | 3176 float invocation_frequency, LoopAssignmentAnalysis* loop_assignment, |
| 3312 SourcePositionTable* source_positions, int inlining_id) | 3177 SourcePositionTable* source_positions, int inlining_id) |
| 3313 : AstGraphBuilder(local_zone, info, jsgraph, invocation_frequency, | 3178 : AstGraphBuilder(local_zone, info, jsgraph, invocation_frequency, |
| 3314 loop_assignment), | 3179 loop_assignment), |
| 3315 source_positions_(source_positions), | 3180 source_positions_(source_positions), |
| 3316 start_position_(info->shared_info()->start_position(), inlining_id) {} | 3181 start_position_(info->shared_info()->start_position(), inlining_id) {} |
| 3317 | 3182 |
| 3318 } // namespace compiler | 3183 } // namespace compiler |
| 3319 } // namespace internal | 3184 } // namespace internal |
| 3320 } // namespace v8 | 3185 } // namespace v8 |
| OLD | NEW |