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 |