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/compiler.h" | 7 #include "src/compiler.h" |
8 #include "src/compiler/control-builders.h" | 8 #include "src/compiler/control-builders.h" |
9 #include "src/compiler/node-properties.h" | 9 #include "src/compiler/node-properties.h" |
10 #include "src/compiler/node-properties-inl.h" | 10 #include "src/compiler/node-properties-inl.h" |
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
231 stack_dirty_ = false; | 231 stack_dirty_ = false; |
232 } | 232 } |
233 | 233 |
234 Operator* op = common()->FrameState(ast_id); | 234 Operator* op = common()->FrameState(ast_id); |
235 | 235 |
236 return graph()->NewNode(op, parameters_node_, locals_node_, stack_node_); | 236 return graph()->NewNode(op, parameters_node_, locals_node_, stack_node_); |
237 } | 237 } |
238 | 238 |
239 | 239 |
240 AstGraphBuilder::AstContext::AstContext(AstGraphBuilder* own, | 240 AstGraphBuilder::AstContext::AstContext(AstGraphBuilder* own, |
241 Expression::Context kind, | 241 Expression::Context kind) |
242 BailoutId bailout_id) | 242 : kind_(kind), owner_(own), outer_(own->ast_context()) { |
243 : bailout_id_(bailout_id), | |
244 kind_(kind), | |
245 owner_(own), | |
246 outer_(own->ast_context()) { | |
247 owner()->set_ast_context(this); // Push. | 243 owner()->set_ast_context(this); // Push. |
248 #ifdef DEBUG | 244 #ifdef DEBUG |
249 original_height_ = environment()->stack_height(); | 245 original_height_ = environment()->stack_height(); |
250 #endif | 246 #endif |
251 } | 247 } |
252 | 248 |
253 | 249 |
254 AstGraphBuilder::AstContext::~AstContext() { | 250 AstGraphBuilder::AstContext::~AstContext() { |
255 owner()->set_ast_context(outer_); // Pop. | 251 owner()->set_ast_context(outer_); // Pop. |
256 } | 252 } |
257 | 253 |
258 | 254 |
259 AstGraphBuilder::AstEffectContext::~AstEffectContext() { | 255 AstGraphBuilder::AstEffectContext::~AstEffectContext() { |
260 DCHECK(environment()->stack_height() == original_height_); | 256 DCHECK(environment()->stack_height() == original_height_); |
261 } | 257 } |
262 | 258 |
263 | 259 |
264 AstGraphBuilder::AstValueContext::~AstValueContext() { | 260 AstGraphBuilder::AstValueContext::~AstValueContext() { |
265 DCHECK(environment()->stack_height() == original_height_ + 1); | 261 DCHECK(environment()->stack_height() == original_height_ + 1); |
266 } | 262 } |
267 | 263 |
268 | 264 |
269 AstGraphBuilder::AstTestContext::~AstTestContext() { | 265 AstGraphBuilder::AstTestContext::~AstTestContext() { |
270 DCHECK(environment()->stack_height() == original_height_ + 1); | 266 DCHECK(environment()->stack_height() == original_height_ + 1); |
271 } | 267 } |
272 | 268 |
273 | 269 |
274 void AstGraphBuilder::AstEffectContext::ProduceValueWithLazyBailout( | |
275 Node* value) { | |
276 ProduceValue(value); | |
277 owner()->BuildLazyBailout(value, bailout_id_); | |
278 } | |
279 | |
280 | |
281 void AstGraphBuilder::AstValueContext::ProduceValueWithLazyBailout( | |
282 Node* value) { | |
283 ProduceValue(value); | |
284 owner()->BuildLazyBailout(value, bailout_id_); | |
285 } | |
286 | |
287 | |
288 void AstGraphBuilder::AstTestContext::ProduceValueWithLazyBailout(Node* value) { | |
289 environment()->Push(value); | |
290 owner()->BuildLazyBailout(value, bailout_id_); | |
291 environment()->Pop(); | |
292 ProduceValue(value); | |
293 } | |
294 | |
295 | |
296 void AstGraphBuilder::AstEffectContext::ProduceValue(Node* value) { | 270 void AstGraphBuilder::AstEffectContext::ProduceValue(Node* value) { |
297 // The value is ignored. | 271 // The value is ignored. |
298 } | 272 } |
299 | 273 |
300 | 274 |
301 void AstGraphBuilder::AstValueContext::ProduceValue(Node* value) { | 275 void AstGraphBuilder::AstValueContext::ProduceValue(Node* value) { |
302 environment()->Push(value); | 276 environment()->Push(value); |
303 } | 277 } |
304 | 278 |
305 | 279 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
352 | 326 |
353 | 327 |
354 void AstGraphBuilder::VisitForValues(ZoneList<Expression*>* exprs) { | 328 void AstGraphBuilder::VisitForValues(ZoneList<Expression*>* exprs) { |
355 for (int i = 0; i < exprs->length(); ++i) { | 329 for (int i = 0; i < exprs->length(); ++i) { |
356 VisitForValue(exprs->at(i)); | 330 VisitForValue(exprs->at(i)); |
357 } | 331 } |
358 } | 332 } |
359 | 333 |
360 | 334 |
361 void AstGraphBuilder::VisitForValue(Expression* expr) { | 335 void AstGraphBuilder::VisitForValue(Expression* expr) { |
362 AstValueContext for_value(this, expr->id()); | 336 AstValueContext for_value(this); |
363 if (!HasStackOverflow()) { | 337 if (!HasStackOverflow()) { |
364 expr->Accept(this); | 338 expr->Accept(this); |
365 } | 339 } |
366 } | 340 } |
367 | 341 |
368 | 342 |
369 void AstGraphBuilder::VisitForEffect(Expression* expr) { | 343 void AstGraphBuilder::VisitForEffect(Expression* expr) { |
370 AstEffectContext for_effect(this, expr->id()); | 344 AstEffectContext for_effect(this); |
371 if (!HasStackOverflow()) { | 345 if (!HasStackOverflow()) { |
372 expr->Accept(this); | 346 expr->Accept(this); |
373 } | 347 } |
374 } | 348 } |
375 | 349 |
376 | 350 |
377 void AstGraphBuilder::VisitForTest(Expression* expr) { | 351 void AstGraphBuilder::VisitForTest(Expression* expr) { |
378 AstTestContext for_condition(this, expr->id()); | 352 AstTestContext for_condition(this); |
379 if (!HasStackOverflow()) { | 353 if (!HasStackOverflow()) { |
380 expr->Accept(this); | 354 expr->Accept(this); |
381 } | 355 } |
382 } | 356 } |
383 | 357 |
384 | 358 |
385 void AstGraphBuilder::VisitVariableDeclaration(VariableDeclaration* decl) { | 359 void AstGraphBuilder::VisitVariableDeclaration(VariableDeclaration* decl) { |
386 Variable* variable = decl->proxy()->var(); | 360 Variable* variable = decl->proxy()->var(); |
387 VariableMode mode = decl->mode(); | 361 VariableMode mode = decl->mode(); |
388 bool hole_init = mode == CONST || mode == CONST_LEGACY || mode == LET; | 362 bool hole_init = mode == CONST || mode == CONST_LEGACY || mode == LET; |
(...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
705 environment()->Push(cache_array); | 679 environment()->Push(cache_array); |
706 environment()->Push(cache_length); | 680 environment()->Push(cache_length); |
707 environment()->Push(jsgraph()->ZeroConstant()); | 681 environment()->Push(jsgraph()->ZeroConstant()); |
708 // PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); | 682 // PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); |
709 LoopBuilder for_loop(this); | 683 LoopBuilder for_loop(this); |
710 for_loop.BeginLoop(); | 684 for_loop.BeginLoop(); |
711 // Check loop termination condition. | 685 // Check loop termination condition. |
712 Node* index = environment()->Peek(0); | 686 Node* index = environment()->Peek(0); |
713 Node* exit_cond = | 687 Node* exit_cond = |
714 NewNode(javascript()->LessThan(), index, cache_length); | 688 NewNode(javascript()->LessThan(), index, cache_length); |
715 // TODO(jarin): provide real bailout id. | |
716 BuildLazyBailout(exit_cond, BailoutId::None()); | |
717 for_loop.BreakUnless(exit_cond); | 689 for_loop.BreakUnless(exit_cond); |
718 // TODO(dcarney): this runtime call should be a handful of | 690 // TODO(dcarney): this runtime call should be a handful of |
719 // simplified instructions that | 691 // simplified instructions that |
720 // basically produce | 692 // basically produce |
721 // value = array[index] | 693 // value = array[index] |
722 environment()->Push(obj); | 694 environment()->Push(obj); |
723 environment()->Push(cache_array); | 695 environment()->Push(cache_array); |
724 environment()->Push(cache_type); | 696 environment()->Push(cache_type); |
725 environment()->Push(index); | 697 environment()->Push(index); |
726 Node* pair = | 698 Node* pair = |
(...skipping 18 matching lines...) Expand all Loading... |
745 // Callee. | 717 // Callee. |
746 environment()->Push(jsgraph()->HeapConstant(function)); | 718 environment()->Push(jsgraph()->HeapConstant(function)); |
747 // Receiver. | 719 // Receiver. |
748 environment()->Push(obj); | 720 environment()->Push(obj); |
749 // Args. | 721 // Args. |
750 environment()->Push(value); | 722 environment()->Push(value); |
751 // result is either the string key or Smi(0) indicating the property | 723 // result is either the string key or Smi(0) indicating the property |
752 // is gone. | 724 // is gone. |
753 Node* res = ProcessArguments( | 725 Node* res = ProcessArguments( |
754 javascript()->Call(3, NO_CALL_FUNCTION_FLAGS), 3); | 726 javascript()->Call(3, NO_CALL_FUNCTION_FLAGS), 3); |
755 // TODO(jarin): provide real bailout id. | |
756 BuildLazyBailout(res, BailoutId::None()); | |
757 Node* property_missing = NewNode(javascript()->StrictEqual(), res, | 727 Node* property_missing = NewNode(javascript()->StrictEqual(), res, |
758 jsgraph()->ZeroConstant()); | 728 jsgraph()->ZeroConstant()); |
759 { | 729 { |
760 IfBuilder is_property_missing(this); | 730 IfBuilder is_property_missing(this); |
761 is_property_missing.If(property_missing); | 731 is_property_missing.If(property_missing); |
762 is_property_missing.Then(); | 732 is_property_missing.Then(); |
763 // Inc counter and continue. | 733 // Inc counter and continue. |
764 Node* index_inc = | 734 Node* index_inc = |
765 NewNode(javascript()->Add(), index, jsgraph()->OneConstant()); | 735 NewNode(javascript()->Add(), index, jsgraph()->OneConstant()); |
766 environment()->Poke(0, index_inc); | 736 environment()->Poke(0, index_inc); |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
852 compare_if.Then(); | 822 compare_if.Then(); |
853 Visit(expr->then_expression()); | 823 Visit(expr->then_expression()); |
854 compare_if.Else(); | 824 compare_if.Else(); |
855 Visit(expr->else_expression()); | 825 Visit(expr->else_expression()); |
856 compare_if.End(); | 826 compare_if.End(); |
857 ast_context()->ReplaceValue(); | 827 ast_context()->ReplaceValue(); |
858 } | 828 } |
859 | 829 |
860 | 830 |
861 void AstGraphBuilder::VisitVariableProxy(VariableProxy* expr) { | 831 void AstGraphBuilder::VisitVariableProxy(VariableProxy* expr) { |
862 Node* value = BuildVariableLoad(expr->var(), expr->id()); | 832 Node* value = BuildVariableLoad(expr->var()); |
863 ast_context()->ProduceValue(value); | 833 ast_context()->ProduceValue(value); |
864 } | 834 } |
865 | 835 |
866 | 836 |
867 void AstGraphBuilder::VisitLiteral(Literal* expr) { | 837 void AstGraphBuilder::VisitLiteral(Literal* expr) { |
868 Node* value = jsgraph()->Constant(expr->value()); | 838 Node* value = jsgraph()->Constant(expr->value()); |
869 ast_context()->ProduceValue(value); | 839 ast_context()->ProduceValue(value); |
870 } | 840 } |
871 | 841 |
872 | 842 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
919 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value())); | 889 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value())); |
920 // Fall through. | 890 // Fall through. |
921 case ObjectLiteral::Property::COMPUTED: { | 891 case ObjectLiteral::Property::COMPUTED: { |
922 // It is safe to use [[Put]] here because the boilerplate already | 892 // It is safe to use [[Put]] here because the boilerplate already |
923 // contains computed properties with an uninitialized value. | 893 // contains computed properties with an uninitialized value. |
924 if (key->value()->IsInternalizedString()) { | 894 if (key->value()->IsInternalizedString()) { |
925 if (property->emit_store()) { | 895 if (property->emit_store()) { |
926 VisitForValue(property->value()); | 896 VisitForValue(property->value()); |
927 Node* value = environment()->Pop(); | 897 Node* value = environment()->Pop(); |
928 PrintableUnique<Name> name = MakeUnique(key->AsPropertyName()); | 898 PrintableUnique<Name> name = MakeUnique(key->AsPropertyName()); |
929 Node* store = | 899 NewNode(javascript()->StoreNamed(name), literal, value); |
930 NewNode(javascript()->StoreNamed(name), literal, value); | |
931 BuildLazyBailout(store, key->id()); | |
932 } else { | 900 } else { |
933 VisitForEffect(property->value()); | 901 VisitForEffect(property->value()); |
934 } | 902 } |
935 break; | 903 break; |
936 } | 904 } |
937 environment()->Push(literal); // Duplicate receiver. | 905 environment()->Push(literal); // Duplicate receiver. |
938 VisitForValue(property->key()); | 906 VisitForValue(property->key()); |
939 VisitForValue(property->value()); | 907 VisitForValue(property->value()); |
940 Node* value = environment()->Pop(); | 908 Node* value = environment()->Pop(); |
941 Node* key = environment()->Pop(); | 909 Node* key = environment()->Pop(); |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1012 | 980 |
1013 // Create nodes to evaluate all the non-constant subexpressions and to store | 981 // Create nodes to evaluate all the non-constant subexpressions and to store |
1014 // them into the newly cloned array. | 982 // them into the newly cloned array. |
1015 for (int i = 0; i < expr->values()->length(); i++) { | 983 for (int i = 0; i < expr->values()->length(); i++) { |
1016 Expression* subexpr = expr->values()->at(i); | 984 Expression* subexpr = expr->values()->at(i); |
1017 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; | 985 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; |
1018 | 986 |
1019 VisitForValue(subexpr); | 987 VisitForValue(subexpr); |
1020 Node* value = environment()->Pop(); | 988 Node* value = environment()->Pop(); |
1021 Node* index = jsgraph()->Constant(i); | 989 Node* index = jsgraph()->Constant(i); |
1022 Node* store = NewNode(javascript()->StoreProperty(), literal, index, value); | 990 NewNode(javascript()->StoreProperty(), literal, index, value); |
1023 BuildLazyBailout(store, expr->GetIdForElement(i)); | |
1024 } | 991 } |
1025 | 992 |
1026 environment()->Pop(); // Array literal index. | 993 environment()->Pop(); // Array literal index. |
1027 ast_context()->ProduceValue(environment()->Pop()); | 994 ast_context()->ProduceValue(environment()->Pop()); |
1028 } | 995 } |
1029 | 996 |
1030 | 997 |
1031 void AstGraphBuilder::VisitForInAssignment(Expression* expr, Node* value) { | 998 void AstGraphBuilder::VisitForInAssignment(Expression* expr, Node* value) { |
1032 DCHECK(expr->IsValidReferenceExpression()); | 999 DCHECK(expr->IsValidReferenceExpression()); |
1033 | 1000 |
1034 // Left-hand side can only be a property, a global or a variable slot. | 1001 // Left-hand side can only be a property, a global or a variable slot. |
1035 Property* property = expr->AsProperty(); | 1002 Property* property = expr->AsProperty(); |
1036 LhsKind assign_type = DetermineLhsKind(expr); | 1003 LhsKind assign_type = DetermineLhsKind(expr); |
1037 | 1004 |
1038 // Evaluate LHS expression and store the value. | 1005 // Evaluate LHS expression and store the value. |
1039 switch (assign_type) { | 1006 switch (assign_type) { |
1040 case VARIABLE: { | 1007 case VARIABLE: { |
1041 Variable* var = expr->AsVariableProxy()->var(); | 1008 Variable* var = expr->AsVariableProxy()->var(); |
1042 // TODO(jarin) Fill in the correct bailout id. | 1009 BuildVariableAssignment(var, value, Token::ASSIGN); |
1043 BuildVariableAssignment(var, value, Token::ASSIGN, BailoutId::None()); | |
1044 break; | 1010 break; |
1045 } | 1011 } |
1046 case NAMED_PROPERTY: { | 1012 case NAMED_PROPERTY: { |
1047 environment()->Push(value); | 1013 environment()->Push(value); |
1048 VisitForValue(property->obj()); | 1014 VisitForValue(property->obj()); |
1049 Node* object = environment()->Pop(); | 1015 Node* object = environment()->Pop(); |
1050 value = environment()->Pop(); | 1016 value = environment()->Pop(); |
1051 PrintableUnique<Name> name = | 1017 PrintableUnique<Name> name = |
1052 MakeUnique(property->key()->AsLiteral()->AsPropertyName()); | 1018 MakeUnique(property->key()->AsLiteral()->AsPropertyName()); |
1053 Node* store = NewNode(javascript()->StoreNamed(name), object, value); | 1019 NewNode(javascript()->StoreNamed(name), object, value); |
1054 // TODO(jarin) Fill in the correct bailout id. | |
1055 BuildLazyBailout(store, BailoutId::None()); | |
1056 break; | 1020 break; |
1057 } | 1021 } |
1058 case KEYED_PROPERTY: { | 1022 case KEYED_PROPERTY: { |
1059 environment()->Push(value); | 1023 environment()->Push(value); |
1060 VisitForValue(property->obj()); | 1024 VisitForValue(property->obj()); |
1061 VisitForValue(property->key()); | 1025 VisitForValue(property->key()); |
1062 Node* key = environment()->Pop(); | 1026 Node* key = environment()->Pop(); |
1063 Node* object = environment()->Pop(); | 1027 Node* object = environment()->Pop(); |
1064 value = environment()->Pop(); | 1028 value = environment()->Pop(); |
1065 Node* store = NewNode(javascript()->StoreProperty(), object, key, value); | 1029 NewNode(javascript()->StoreProperty(), object, key, value); |
1066 // TODO(jarin) Fill in the correct bailout id. | |
1067 BuildLazyBailout(store, BailoutId::None()); | |
1068 break; | 1030 break; |
1069 } | 1031 } |
1070 } | 1032 } |
1071 } | 1033 } |
1072 | 1034 |
1073 | 1035 |
1074 void AstGraphBuilder::VisitAssignment(Assignment* expr) { | 1036 void AstGraphBuilder::VisitAssignment(Assignment* expr) { |
1075 DCHECK(expr->target()->IsValidReferenceExpression()); | 1037 DCHECK(expr->target()->IsValidReferenceExpression()); |
1076 | 1038 |
1077 // Left-hand side can only be a property, a global or a variable slot. | 1039 // Left-hand side can only be a property, a global or a variable slot. |
(...skipping 15 matching lines...) Expand all Loading... |
1093 } | 1055 } |
1094 } | 1056 } |
1095 | 1057 |
1096 // Evaluate the value and potentially handle compound assignments by loading | 1058 // Evaluate the value and potentially handle compound assignments by loading |
1097 // the left-hand side value and performing a binary operation. | 1059 // the left-hand side value and performing a binary operation. |
1098 if (expr->is_compound()) { | 1060 if (expr->is_compound()) { |
1099 Node* old_value = NULL; | 1061 Node* old_value = NULL; |
1100 switch (assign_type) { | 1062 switch (assign_type) { |
1101 case VARIABLE: { | 1063 case VARIABLE: { |
1102 Variable* variable = expr->target()->AsVariableProxy()->var(); | 1064 Variable* variable = expr->target()->AsVariableProxy()->var(); |
1103 old_value = BuildVariableLoad(variable, expr->target()->id()); | 1065 old_value = BuildVariableLoad(variable); |
1104 break; | 1066 break; |
1105 } | 1067 } |
1106 case NAMED_PROPERTY: { | 1068 case NAMED_PROPERTY: { |
1107 Node* object = environment()->Top(); | 1069 Node* object = environment()->Top(); |
1108 PrintableUnique<Name> name = | 1070 PrintableUnique<Name> name = |
1109 MakeUnique(property->key()->AsLiteral()->AsPropertyName()); | 1071 MakeUnique(property->key()->AsLiteral()->AsPropertyName()); |
1110 old_value = NewNode(javascript()->LoadNamed(name), object); | 1072 old_value = NewNode(javascript()->LoadNamed(name), object); |
1111 BuildLazyBailoutWithPushedNode(old_value, property->LoadId()); | |
1112 break; | 1073 break; |
1113 } | 1074 } |
1114 case KEYED_PROPERTY: { | 1075 case KEYED_PROPERTY: { |
1115 Node* key = environment()->Top(); | 1076 Node* key = environment()->Top(); |
1116 Node* object = environment()->Peek(1); | 1077 Node* object = environment()->Peek(1); |
1117 old_value = NewNode(javascript()->LoadProperty(), object, key); | 1078 old_value = NewNode(javascript()->LoadProperty(), object, key); |
1118 BuildLazyBailoutWithPushedNode(old_value, property->LoadId()); | |
1119 break; | 1079 break; |
1120 } | 1080 } |
1121 } | 1081 } |
1122 environment()->Push(old_value); | 1082 environment()->Push(old_value); |
1123 VisitForValue(expr->value()); | 1083 VisitForValue(expr->value()); |
1124 Node* right = environment()->Pop(); | 1084 Node* right = environment()->Pop(); |
1125 Node* left = environment()->Pop(); | 1085 Node* left = environment()->Pop(); |
1126 Node* value = BuildBinaryOp(left, right, expr->binary_op()); | 1086 Node* value = BuildBinaryOp(left, right, expr->binary_op()); |
1127 environment()->Push(value); | 1087 environment()->Push(value); |
1128 BuildLazyBailout(value, expr->binary_operation()->id()); | |
1129 } else { | 1088 } else { |
1130 VisitForValue(expr->value()); | 1089 VisitForValue(expr->value()); |
1131 } | 1090 } |
1132 | 1091 |
1133 // Store the value. | 1092 // Store the value. |
1134 Node* value = environment()->Pop(); | 1093 Node* value = environment()->Pop(); |
1135 switch (assign_type) { | 1094 switch (assign_type) { |
1136 case VARIABLE: { | 1095 case VARIABLE: { |
1137 Variable* variable = expr->target()->AsVariableProxy()->var(); | 1096 Variable* variable = expr->target()->AsVariableProxy()->var(); |
1138 BuildVariableAssignment(variable, value, expr->op(), | 1097 BuildVariableAssignment(variable, value, expr->op()); |
1139 expr->AssignmentId()); | |
1140 break; | 1098 break; |
1141 } | 1099 } |
1142 case NAMED_PROPERTY: { | 1100 case NAMED_PROPERTY: { |
1143 Node* object = environment()->Pop(); | 1101 Node* object = environment()->Pop(); |
1144 PrintableUnique<Name> name = | 1102 PrintableUnique<Name> name = |
1145 MakeUnique(property->key()->AsLiteral()->AsPropertyName()); | 1103 MakeUnique(property->key()->AsLiteral()->AsPropertyName()); |
1146 Node* store = NewNode(javascript()->StoreNamed(name), object, value); | 1104 NewNode(javascript()->StoreNamed(name), object, value); |
1147 BuildLazyBailout(store, expr->AssignmentId()); | |
1148 break; | 1105 break; |
1149 } | 1106 } |
1150 case KEYED_PROPERTY: { | 1107 case KEYED_PROPERTY: { |
1151 Node* key = environment()->Pop(); | 1108 Node* key = environment()->Pop(); |
1152 Node* object = environment()->Pop(); | 1109 Node* object = environment()->Pop(); |
1153 Node* store = NewNode(javascript()->StoreProperty(), object, key, value); | 1110 NewNode(javascript()->StoreProperty(), object, key, value); |
1154 BuildLazyBailout(store, expr->AssignmentId()); | |
1155 break; | 1111 break; |
1156 } | 1112 } |
1157 } | 1113 } |
1158 | 1114 |
1159 ast_context()->ProduceValue(value); | 1115 ast_context()->ProduceValue(value); |
1160 } | 1116 } |
1161 | 1117 |
1162 | 1118 |
1163 void AstGraphBuilder::VisitYield(Yield* expr) { | 1119 void AstGraphBuilder::VisitYield(Yield* expr) { |
1164 VisitForValue(expr->generator_object()); | 1120 VisitForValue(expr->generator_object()); |
(...skipping 22 matching lines...) Expand all Loading... |
1187 PrintableUnique<Name> name = | 1143 PrintableUnique<Name> name = |
1188 MakeUnique(expr->key()->AsLiteral()->AsPropertyName()); | 1144 MakeUnique(expr->key()->AsLiteral()->AsPropertyName()); |
1189 value = NewNode(javascript()->LoadNamed(name), object); | 1145 value = NewNode(javascript()->LoadNamed(name), object); |
1190 } else { | 1146 } else { |
1191 VisitForValue(expr->obj()); | 1147 VisitForValue(expr->obj()); |
1192 VisitForValue(expr->key()); | 1148 VisitForValue(expr->key()); |
1193 Node* key = environment()->Pop(); | 1149 Node* key = environment()->Pop(); |
1194 Node* object = environment()->Pop(); | 1150 Node* object = environment()->Pop(); |
1195 value = NewNode(javascript()->LoadProperty(), object, key); | 1151 value = NewNode(javascript()->LoadProperty(), object, key); |
1196 } | 1152 } |
1197 ast_context()->ProduceValueWithLazyBailout(value); | 1153 ast_context()->ProduceValue(value); |
1198 } | 1154 } |
1199 | 1155 |
1200 | 1156 |
1201 void AstGraphBuilder::VisitCall(Call* expr) { | 1157 void AstGraphBuilder::VisitCall(Call* expr) { |
1202 Expression* callee = expr->expression(); | 1158 Expression* callee = expr->expression(); |
1203 Call::CallType call_type = expr->GetCallType(isolate()); | 1159 Call::CallType call_type = expr->GetCallType(isolate()); |
1204 | 1160 |
1205 // Prepare the callee and the receiver to the function call. This depends on | 1161 // Prepare the callee and the receiver to the function call. This depends on |
1206 // the semantics of the underlying call type. | 1162 // the semantics of the underlying call type. |
1207 CallFunctionFlags flags = NO_CALL_FUNCTION_FLAGS; | 1163 CallFunctionFlags flags = NO_CALL_FUNCTION_FLAGS; |
1208 Node* receiver_value = NULL; | 1164 Node* receiver_value = NULL; |
1209 Node* callee_value = NULL; | 1165 Node* callee_value = NULL; |
1210 bool possibly_eval = false; | 1166 bool possibly_eval = false; |
1211 switch (call_type) { | 1167 switch (call_type) { |
1212 case Call::GLOBAL_CALL: { | 1168 case Call::GLOBAL_CALL: { |
1213 Variable* variable = callee->AsVariableProxy()->var(); | 1169 Variable* variable = callee->AsVariableProxy()->var(); |
1214 callee_value = BuildVariableLoad(variable, expr->expression()->id()); | 1170 callee_value = BuildVariableLoad(variable); |
1215 receiver_value = jsgraph()->UndefinedConstant(); | 1171 receiver_value = jsgraph()->UndefinedConstant(); |
1216 break; | 1172 break; |
1217 } | 1173 } |
1218 case Call::LOOKUP_SLOT_CALL: { | 1174 case Call::LOOKUP_SLOT_CALL: { |
1219 Variable* variable = callee->AsVariableProxy()->var(); | 1175 Variable* variable = callee->AsVariableProxy()->var(); |
1220 DCHECK(variable->location() == Variable::LOOKUP); | 1176 DCHECK(variable->location() == Variable::LOOKUP); |
1221 Node* name = jsgraph()->Constant(variable->name()); | 1177 Node* name = jsgraph()->Constant(variable->name()); |
1222 Operator* op = javascript()->Runtime(Runtime::kLoadLookupSlot, 2); | 1178 Operator* op = javascript()->Runtime(Runtime::kLoadLookupSlot, 2); |
1223 Node* pair = NewNode(op, current_context(), name); | 1179 Node* pair = NewNode(op, current_context(), name); |
1224 callee_value = NewNode(common()->Projection(0), pair); | 1180 callee_value = NewNode(common()->Projection(0), pair); |
1225 receiver_value = NewNode(common()->Projection(1), pair); | 1181 receiver_value = NewNode(common()->Projection(1), pair); |
1226 break; | 1182 break; |
1227 } | 1183 } |
1228 case Call::PROPERTY_CALL: { | 1184 case Call::PROPERTY_CALL: { |
1229 Property* property = callee->AsProperty(); | 1185 Property* property = callee->AsProperty(); |
1230 VisitForValue(property->obj()); | 1186 VisitForValue(property->obj()); |
1231 Node* object = environment()->Top(); | 1187 Node* object = environment()->Top(); |
1232 if (property->key()->IsPropertyName()) { | 1188 if (property->key()->IsPropertyName()) { |
1233 PrintableUnique<Name> name = | 1189 PrintableUnique<Name> name = |
1234 MakeUnique(property->key()->AsLiteral()->AsPropertyName()); | 1190 MakeUnique(property->key()->AsLiteral()->AsPropertyName()); |
1235 callee_value = NewNode(javascript()->LoadNamed(name), object); | 1191 callee_value = NewNode(javascript()->LoadNamed(name), object); |
1236 } else { | 1192 } else { |
1237 VisitForValue(property->key()); | 1193 VisitForValue(property->key()); |
1238 Node* key = environment()->Pop(); | 1194 Node* key = environment()->Pop(); |
1239 callee_value = NewNode(javascript()->LoadProperty(), object, key); | 1195 callee_value = NewNode(javascript()->LoadProperty(), object, key); |
1240 } | 1196 } |
1241 BuildLazyBailoutWithPushedNode(callee_value, property->LoadId()); | |
1242 receiver_value = environment()->Pop(); | 1197 receiver_value = environment()->Pop(); |
1243 // Note that a PROPERTY_CALL requires the receiver to be wrapped into an | 1198 // Note that a PROPERTY_CALL requires the receiver to be wrapped into an |
1244 // object for sloppy callees. This could also be modeled explicitly here, | 1199 // object for sloppy callees. This could also be modeled explicitly here, |
1245 // thereby obsoleting the need for a flag to the call operator. | 1200 // thereby obsoleting the need for a flag to the call operator. |
1246 flags = CALL_AS_METHOD; | 1201 flags = CALL_AS_METHOD; |
1247 break; | 1202 break; |
1248 } | 1203 } |
1249 case Call::POSSIBLY_EVAL_CALL: | 1204 case Call::POSSIBLY_EVAL_CALL: |
1250 possibly_eval = true; | 1205 possibly_eval = true; |
1251 // Fall through. | 1206 // Fall through. |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1286 Node* new_receiver = NewNode(common()->Projection(1), pair); | 1241 Node* new_receiver = NewNode(common()->Projection(1), pair); |
1287 | 1242 |
1288 // Patch callee and receiver on the environment. | 1243 // Patch callee and receiver on the environment. |
1289 environment()->Poke(arg_count + 1, new_callee); | 1244 environment()->Poke(arg_count + 1, new_callee); |
1290 environment()->Poke(arg_count + 0, new_receiver); | 1245 environment()->Poke(arg_count + 0, new_receiver); |
1291 } | 1246 } |
1292 | 1247 |
1293 // Create node to perform the function call. | 1248 // Create node to perform the function call. |
1294 Operator* call = javascript()->Call(args->length() + 2, flags); | 1249 Operator* call = javascript()->Call(args->length() + 2, flags); |
1295 Node* value = ProcessArguments(call, args->length() + 2); | 1250 Node* value = ProcessArguments(call, args->length() + 2); |
1296 ast_context()->ProduceValueWithLazyBailout(value); | 1251 ast_context()->ProduceValue(value); |
1297 } | 1252 } |
1298 | 1253 |
1299 | 1254 |
1300 void AstGraphBuilder::VisitCallNew(CallNew* expr) { | 1255 void AstGraphBuilder::VisitCallNew(CallNew* expr) { |
1301 VisitForValue(expr->expression()); | 1256 VisitForValue(expr->expression()); |
1302 | 1257 |
1303 // Evaluate all arguments to the construct call. | 1258 // Evaluate all arguments to the construct call. |
1304 ZoneList<Expression*>* args = expr->arguments(); | 1259 ZoneList<Expression*>* args = expr->arguments(); |
1305 VisitForValues(args); | 1260 VisitForValues(args); |
1306 | 1261 |
1307 // Create node to perform the construct call. | 1262 // Create node to perform the construct call. |
1308 Operator* call = javascript()->CallNew(args->length() + 1); | 1263 Operator* call = javascript()->CallNew(args->length() + 1); |
1309 Node* value = ProcessArguments(call, args->length() + 1); | 1264 Node* value = ProcessArguments(call, args->length() + 1); |
1310 ast_context()->ProduceValueWithLazyBailout(value); | 1265 ast_context()->ProduceValue(value); |
1311 } | 1266 } |
1312 | 1267 |
1313 | 1268 |
1314 void AstGraphBuilder::VisitCallJSRuntime(CallRuntime* expr) { | 1269 void AstGraphBuilder::VisitCallJSRuntime(CallRuntime* expr) { |
1315 Handle<String> name = expr->name(); | 1270 Handle<String> name = expr->name(); |
1316 | 1271 |
1317 // The callee and the receiver both have to be pushed onto the operand stack | 1272 // The callee and the receiver both have to be pushed onto the operand stack |
1318 // before arguments are being evaluated. | 1273 // before arguments are being evaluated. |
1319 CallFunctionFlags flags = NO_CALL_FUNCTION_FLAGS; | 1274 CallFunctionFlags flags = NO_CALL_FUNCTION_FLAGS; |
1320 Node* receiver_value = BuildLoadBuiltinsObject(); | 1275 Node* receiver_value = BuildLoadBuiltinsObject(); |
1321 PrintableUnique<String> unique = MakeUnique(name); | 1276 PrintableUnique<String> unique = MakeUnique(name); |
1322 Node* callee_value = NewNode(javascript()->LoadNamed(unique), receiver_value); | 1277 Node* callee_value = NewNode(javascript()->LoadNamed(unique), receiver_value); |
1323 environment()->Push(callee_value); | 1278 environment()->Push(callee_value); |
1324 // TODO(jarin): Find/create a bailout id to deoptimize to (crankshaft | |
1325 // refuses to optimize functions with jsruntime calls). | |
1326 BuildLazyBailout(callee_value, BailoutId::None()); | |
1327 environment()->Push(receiver_value); | 1279 environment()->Push(receiver_value); |
1328 | 1280 |
1329 // Evaluate all arguments to the JS runtime call. | 1281 // Evaluate all arguments to the JS runtime call. |
1330 ZoneList<Expression*>* args = expr->arguments(); | 1282 ZoneList<Expression*>* args = expr->arguments(); |
1331 VisitForValues(args); | 1283 VisitForValues(args); |
1332 | 1284 |
1333 // Create node to perform the JS runtime call. | 1285 // Create node to perform the JS runtime call. |
1334 Operator* call = javascript()->Call(args->length() + 2, flags); | 1286 Operator* call = javascript()->Call(args->length() + 2, flags); |
1335 Node* value = ProcessArguments(call, args->length() + 2); | 1287 Node* value = ProcessArguments(call, args->length() + 2); |
1336 ast_context()->ProduceValueWithLazyBailout(value); | 1288 ast_context()->ProduceValue(value); |
1337 } | 1289 } |
1338 | 1290 |
1339 | 1291 |
1340 void AstGraphBuilder::VisitCallRuntime(CallRuntime* expr) { | 1292 void AstGraphBuilder::VisitCallRuntime(CallRuntime* expr) { |
1341 const Runtime::Function* function = expr->function(); | 1293 const Runtime::Function* function = expr->function(); |
1342 | 1294 |
1343 // Handle calls to runtime functions implemented in JavaScript separately as | 1295 // Handle calls to runtime functions implemented in JavaScript separately as |
1344 // the call follows JavaScript ABI and the callee is statically unknown. | 1296 // the call follows JavaScript ABI and the callee is statically unknown. |
1345 if (expr->is_jsruntime()) { | 1297 if (expr->is_jsruntime()) { |
1346 DCHECK(function == NULL && expr->name()->length() > 0); | 1298 DCHECK(function == NULL && expr->name()->length() > 0); |
1347 return VisitCallJSRuntime(expr); | 1299 return VisitCallJSRuntime(expr); |
1348 } | 1300 } |
1349 | 1301 |
1350 // Evaluate all arguments to the runtime call. | 1302 // Evaluate all arguments to the runtime call. |
1351 ZoneList<Expression*>* args = expr->arguments(); | 1303 ZoneList<Expression*>* args = expr->arguments(); |
1352 VisitForValues(args); | 1304 VisitForValues(args); |
1353 | 1305 |
1354 // Create node to perform the runtime call. | 1306 // Create node to perform the runtime call. |
1355 Runtime::FunctionId functionId = function->function_id; | 1307 Runtime::FunctionId functionId = function->function_id; |
1356 Operator* call = javascript()->Runtime(functionId, args->length()); | 1308 Operator* call = javascript()->Runtime(functionId, args->length()); |
1357 Node* value = ProcessArguments(call, args->length()); | 1309 Node* value = ProcessArguments(call, args->length()); |
1358 ast_context()->ProduceValueWithLazyBailout(value); | 1310 ast_context()->ProduceValue(value); |
| 1311 |
| 1312 BuildLazyBailout(value, expr->id()); |
1359 } | 1313 } |
1360 | 1314 |
1361 | 1315 |
1362 void AstGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) { | 1316 void AstGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) { |
1363 switch (expr->op()) { | 1317 switch (expr->op()) { |
1364 case Token::DELETE: | 1318 case Token::DELETE: |
1365 return VisitDelete(expr); | 1319 return VisitDelete(expr); |
1366 case Token::VOID: | 1320 case Token::VOID: |
1367 return VisitVoid(expr); | 1321 return VisitVoid(expr); |
1368 case Token::TYPEOF: | 1322 case Token::TYPEOF: |
(...skipping 16 matching lines...) Expand all Loading... |
1385 // Reserve space for result of postfix operation. | 1339 // Reserve space for result of postfix operation. |
1386 bool is_postfix = expr->is_postfix() && !ast_context()->IsEffect(); | 1340 bool is_postfix = expr->is_postfix() && !ast_context()->IsEffect(); |
1387 if (is_postfix) environment()->Push(jsgraph()->UndefinedConstant()); | 1341 if (is_postfix) environment()->Push(jsgraph()->UndefinedConstant()); |
1388 | 1342 |
1389 // Evaluate LHS expression and get old value. | 1343 // Evaluate LHS expression and get old value. |
1390 Node* old_value = NULL; | 1344 Node* old_value = NULL; |
1391 int stack_depth = -1; | 1345 int stack_depth = -1; |
1392 switch (assign_type) { | 1346 switch (assign_type) { |
1393 case VARIABLE: { | 1347 case VARIABLE: { |
1394 Variable* variable = expr->expression()->AsVariableProxy()->var(); | 1348 Variable* variable = expr->expression()->AsVariableProxy()->var(); |
1395 old_value = BuildVariableLoad(variable, expr->expression()->id()); | 1349 old_value = BuildVariableLoad(variable); |
1396 stack_depth = 0; | 1350 stack_depth = 0; |
1397 break; | 1351 break; |
1398 } | 1352 } |
1399 case NAMED_PROPERTY: { | 1353 case NAMED_PROPERTY: { |
1400 VisitForValue(property->obj()); | 1354 VisitForValue(property->obj()); |
1401 Node* object = environment()->Top(); | 1355 Node* object = environment()->Top(); |
1402 PrintableUnique<Name> name = | 1356 PrintableUnique<Name> name = |
1403 MakeUnique(property->key()->AsLiteral()->AsPropertyName()); | 1357 MakeUnique(property->key()->AsLiteral()->AsPropertyName()); |
1404 old_value = NewNode(javascript()->LoadNamed(name), object); | 1358 old_value = NewNode(javascript()->LoadNamed(name), object); |
1405 BuildLazyBailoutWithPushedNode(old_value, property->LoadId()); | |
1406 stack_depth = 1; | 1359 stack_depth = 1; |
1407 break; | 1360 break; |
1408 } | 1361 } |
1409 case KEYED_PROPERTY: { | 1362 case KEYED_PROPERTY: { |
1410 VisitForValue(property->obj()); | 1363 VisitForValue(property->obj()); |
1411 VisitForValue(property->key()); | 1364 VisitForValue(property->key()); |
1412 Node* key = environment()->Top(); | 1365 Node* key = environment()->Top(); |
1413 Node* object = environment()->Peek(1); | 1366 Node* object = environment()->Peek(1); |
1414 old_value = NewNode(javascript()->LoadProperty(), object, key); | 1367 old_value = NewNode(javascript()->LoadProperty(), object, key); |
1415 BuildLazyBailoutWithPushedNode(old_value, property->LoadId()); | |
1416 stack_depth = 2; | 1368 stack_depth = 2; |
1417 break; | 1369 break; |
1418 } | 1370 } |
1419 } | 1371 } |
1420 | 1372 |
1421 // Convert old value into a number. | 1373 // Convert old value into a number. |
1422 old_value = NewNode(javascript()->ToNumber(), old_value); | 1374 old_value = NewNode(javascript()->ToNumber(), old_value); |
1423 | 1375 |
1424 // Save result for postfix expressions at correct stack depth. | 1376 // Save result for postfix expressions at correct stack depth. |
1425 if (is_postfix) environment()->Poke(stack_depth, old_value); | 1377 if (is_postfix) environment()->Poke(stack_depth, old_value); |
1426 | 1378 |
1427 // Create node to perform +1/-1 operation. | 1379 // Create node to perform +1/-1 operation. |
1428 Node* value = | 1380 Node* value = |
1429 BuildBinaryOp(old_value, jsgraph()->OneConstant(), expr->binary_op()); | 1381 BuildBinaryOp(old_value, jsgraph()->OneConstant(), expr->binary_op()); |
1430 // TODO(jarin) Insert proper bailout id here (will need to change | |
1431 // full code generator). | |
1432 BuildLazyBailout(value, BailoutId::None()); | |
1433 | 1382 |
1434 // Store the value. | 1383 // Store the value. |
1435 switch (assign_type) { | 1384 switch (assign_type) { |
1436 case VARIABLE: { | 1385 case VARIABLE: { |
1437 Variable* variable = expr->expression()->AsVariableProxy()->var(); | 1386 Variable* variable = expr->expression()->AsVariableProxy()->var(); |
1438 BuildVariableAssignment(variable, value, expr->op(), | 1387 BuildVariableAssignment(variable, value, expr->op()); |
1439 expr->AssignmentId()); | |
1440 break; | 1388 break; |
1441 } | 1389 } |
1442 case NAMED_PROPERTY: { | 1390 case NAMED_PROPERTY: { |
1443 Node* object = environment()->Pop(); | 1391 Node* object = environment()->Pop(); |
1444 PrintableUnique<Name> name = | 1392 PrintableUnique<Name> name = |
1445 MakeUnique(property->key()->AsLiteral()->AsPropertyName()); | 1393 MakeUnique(property->key()->AsLiteral()->AsPropertyName()); |
1446 Node* store = NewNode(javascript()->StoreNamed(name), object, value); | 1394 NewNode(javascript()->StoreNamed(name), object, value); |
1447 BuildLazyBailout(store, expr->AssignmentId()); | |
1448 break; | 1395 break; |
1449 } | 1396 } |
1450 case KEYED_PROPERTY: { | 1397 case KEYED_PROPERTY: { |
1451 Node* key = environment()->Pop(); | 1398 Node* key = environment()->Pop(); |
1452 Node* object = environment()->Pop(); | 1399 Node* object = environment()->Pop(); |
1453 Node* store = NewNode(javascript()->StoreProperty(), object, key, value); | 1400 NewNode(javascript()->StoreProperty(), object, key, value); |
1454 BuildLazyBailout(store, expr->AssignmentId()); | |
1455 break; | 1401 break; |
1456 } | 1402 } |
1457 } | 1403 } |
1458 | 1404 |
1459 // Restore old value for postfix expressions. | 1405 // Restore old value for postfix expressions. |
1460 if (is_postfix) value = environment()->Pop(); | 1406 if (is_postfix) value = environment()->Pop(); |
1461 | 1407 |
1462 ast_context()->ProduceValue(value); | 1408 ast_context()->ProduceValue(value); |
1463 } | 1409 } |
1464 | 1410 |
1465 | 1411 |
1466 void AstGraphBuilder::VisitBinaryOperation(BinaryOperation* expr) { | 1412 void AstGraphBuilder::VisitBinaryOperation(BinaryOperation* expr) { |
1467 switch (expr->op()) { | 1413 switch (expr->op()) { |
1468 case Token::COMMA: | 1414 case Token::COMMA: |
1469 return VisitComma(expr); | 1415 return VisitComma(expr); |
1470 case Token::OR: | 1416 case Token::OR: |
1471 case Token::AND: | 1417 case Token::AND: |
1472 return VisitLogicalExpression(expr); | 1418 return VisitLogicalExpression(expr); |
1473 default: { | 1419 default: { |
1474 VisitForValue(expr->left()); | 1420 VisitForValue(expr->left()); |
1475 VisitForValue(expr->right()); | 1421 VisitForValue(expr->right()); |
1476 Node* right = environment()->Pop(); | 1422 Node* right = environment()->Pop(); |
1477 Node* left = environment()->Pop(); | 1423 Node* left = environment()->Pop(); |
1478 Node* value = BuildBinaryOp(left, right, expr->op()); | 1424 Node* value = BuildBinaryOp(left, right, expr->op()); |
1479 ast_context()->ProduceValueWithLazyBailout(value); | 1425 ast_context()->ProduceValue(value); |
1480 } | 1426 } |
1481 } | 1427 } |
1482 } | 1428 } |
1483 | 1429 |
1484 | 1430 |
1485 void AstGraphBuilder::VisitCompareOperation(CompareOperation* expr) { | 1431 void AstGraphBuilder::VisitCompareOperation(CompareOperation* expr) { |
1486 Operator* op; | 1432 Operator* op; |
1487 switch (expr->op()) { | 1433 switch (expr->op()) { |
1488 case Token::EQ: | 1434 case Token::EQ: |
1489 op = javascript()->Equal(); | 1435 op = javascript()->Equal(); |
(...skipping 28 matching lines...) Expand all Loading... |
1518 default: | 1464 default: |
1519 op = NULL; | 1465 op = NULL; |
1520 UNREACHABLE(); | 1466 UNREACHABLE(); |
1521 } | 1467 } |
1522 VisitForValue(expr->left()); | 1468 VisitForValue(expr->left()); |
1523 VisitForValue(expr->right()); | 1469 VisitForValue(expr->right()); |
1524 Node* right = environment()->Pop(); | 1470 Node* right = environment()->Pop(); |
1525 Node* left = environment()->Pop(); | 1471 Node* left = environment()->Pop(); |
1526 Node* value = NewNode(op, left, right); | 1472 Node* value = NewNode(op, left, right); |
1527 ast_context()->ProduceValue(value); | 1473 ast_context()->ProduceValue(value); |
1528 | |
1529 BuildLazyBailout(value, expr->id()); | |
1530 } | 1474 } |
1531 | 1475 |
1532 | 1476 |
1533 void AstGraphBuilder::VisitThisFunction(ThisFunction* expr) { | 1477 void AstGraphBuilder::VisitThisFunction(ThisFunction* expr) { |
1534 Node* value = GetFunctionClosure(); | 1478 Node* value = GetFunctionClosure(); |
1535 ast_context()->ProduceValue(value); | 1479 ast_context()->ProduceValue(value); |
1536 } | 1480 } |
1537 | 1481 |
1538 | 1482 |
1539 void AstGraphBuilder::VisitCaseClause(CaseClause* expr) { UNREACHABLE(); } | 1483 void AstGraphBuilder::VisitCaseClause(CaseClause* expr) { UNREACHABLE(); } |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1599 ast_context()->ProduceValue(value); | 1543 ast_context()->ProduceValue(value); |
1600 } | 1544 } |
1601 | 1545 |
1602 | 1546 |
1603 void AstGraphBuilder::VisitTypeof(UnaryOperation* expr) { | 1547 void AstGraphBuilder::VisitTypeof(UnaryOperation* expr) { |
1604 Node* operand; | 1548 Node* operand; |
1605 if (expr->expression()->IsVariableProxy()) { | 1549 if (expr->expression()->IsVariableProxy()) { |
1606 // Typeof does not throw a reference error on global variables, hence we | 1550 // Typeof does not throw a reference error on global variables, hence we |
1607 // perform a non-contextual load in case the operand is a variable proxy. | 1551 // perform a non-contextual load in case the operand is a variable proxy. |
1608 Variable* variable = expr->expression()->AsVariableProxy()->var(); | 1552 Variable* variable = expr->expression()->AsVariableProxy()->var(); |
1609 operand = | 1553 operand = BuildVariableLoad(variable, NOT_CONTEXTUAL); |
1610 BuildVariableLoad(variable, expr->expression()->id(), NOT_CONTEXTUAL); | |
1611 } else { | 1554 } else { |
1612 VisitForValue(expr->expression()); | 1555 VisitForValue(expr->expression()); |
1613 operand = environment()->Pop(); | 1556 operand = environment()->Pop(); |
1614 } | 1557 } |
1615 Node* value = NewNode(javascript()->TypeOf(), operand); | 1558 Node* value = NewNode(javascript()->TypeOf(), operand); |
1616 ast_context()->ProduceValue(value); | 1559 ast_context()->ProduceValue(value); |
1617 } | 1560 } |
1618 | 1561 |
1619 | 1562 |
1620 void AstGraphBuilder::VisitNot(UnaryOperation* expr) { | 1563 void AstGraphBuilder::VisitNot(UnaryOperation* expr) { |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1700 Node* AstGraphBuilder::BuildArgumentsObject(Variable* arguments) { | 1643 Node* AstGraphBuilder::BuildArgumentsObject(Variable* arguments) { |
1701 if (arguments == NULL) return NULL; | 1644 if (arguments == NULL) return NULL; |
1702 | 1645 |
1703 // Allocate and initialize a new arguments object. | 1646 // Allocate and initialize a new arguments object. |
1704 Node* callee = GetFunctionClosure(); | 1647 Node* callee = GetFunctionClosure(); |
1705 Operator* op = javascript()->Runtime(Runtime::kNewArguments, 1); | 1648 Operator* op = javascript()->Runtime(Runtime::kNewArguments, 1); |
1706 Node* object = NewNode(op, callee); | 1649 Node* object = NewNode(op, callee); |
1707 | 1650 |
1708 // Assign the object to the arguments variable. | 1651 // Assign the object to the arguments variable. |
1709 DCHECK(arguments->IsContextSlot() || arguments->IsStackAllocated()); | 1652 DCHECK(arguments->IsContextSlot() || arguments->IsStackAllocated()); |
1710 // This should never lazy deopt, so it is fine to send invalid bailout id. | 1653 BuildVariableAssignment(arguments, object, Token::ASSIGN); |
1711 BuildVariableAssignment(arguments, object, Token::ASSIGN, BailoutId::None()); | |
1712 | 1654 |
1713 return object; | 1655 return object; |
1714 } | 1656 } |
1715 | 1657 |
1716 | 1658 |
1717 Node* AstGraphBuilder::BuildHoleCheckSilent(Node* value, Node* for_hole, | 1659 Node* AstGraphBuilder::BuildHoleCheckSilent(Node* value, Node* for_hole, |
1718 Node* not_hole) { | 1660 Node* not_hole) { |
1719 IfBuilder hole_check(this); | 1661 IfBuilder hole_check(this); |
1720 Node* the_hole = jsgraph()->TheHoleConstant(); | 1662 Node* the_hole = jsgraph()->TheHoleConstant(); |
1721 Node* check = NewNode(javascript()->StrictEqual(), value, the_hole); | 1663 Node* check = NewNode(javascript()->StrictEqual(), value, the_hole); |
(...skipping 16 matching lines...) Expand all Loading... |
1738 hole_check.Then(); | 1680 hole_check.Then(); |
1739 environment()->Push(BuildThrowReferenceError(variable)); | 1681 environment()->Push(BuildThrowReferenceError(variable)); |
1740 hole_check.Else(); | 1682 hole_check.Else(); |
1741 environment()->Push(not_hole); | 1683 environment()->Push(not_hole); |
1742 hole_check.End(); | 1684 hole_check.End(); |
1743 return environment()->Pop(); | 1685 return environment()->Pop(); |
1744 } | 1686 } |
1745 | 1687 |
1746 | 1688 |
1747 Node* AstGraphBuilder::BuildVariableLoad(Variable* variable, | 1689 Node* AstGraphBuilder::BuildVariableLoad(Variable* variable, |
1748 BailoutId bailout_id, | |
1749 ContextualMode contextual_mode) { | 1690 ContextualMode contextual_mode) { |
1750 Node* the_hole = jsgraph()->TheHoleConstant(); | 1691 Node* the_hole = jsgraph()->TheHoleConstant(); |
1751 VariableMode mode = variable->mode(); | 1692 VariableMode mode = variable->mode(); |
1752 switch (variable->location()) { | 1693 switch (variable->location()) { |
1753 case Variable::UNALLOCATED: { | 1694 case Variable::UNALLOCATED: { |
1754 // Global var, const, or let variable. | 1695 // Global var, const, or let variable. |
1755 Node* global = BuildLoadGlobalObject(); | 1696 Node* global = BuildLoadGlobalObject(); |
1756 PrintableUnique<Name> name = MakeUnique(variable->name()); | 1697 PrintableUnique<Name> name = MakeUnique(variable->name()); |
1757 Operator* op = javascript()->LoadNamed(name, contextual_mode); | 1698 Operator* op = javascript()->LoadNamed(name, contextual_mode); |
1758 Node* node = NewNode(op, global); | 1699 return NewNode(op, global); |
1759 BuildLazyBailoutWithPushedNode(node, bailout_id); | |
1760 return node; | |
1761 } | 1700 } |
1762 case Variable::PARAMETER: | 1701 case Variable::PARAMETER: |
1763 case Variable::LOCAL: { | 1702 case Variable::LOCAL: { |
1764 // Local var, const, or let variable. | 1703 // Local var, const, or let variable. |
1765 Node* value = environment()->Lookup(variable); | 1704 Node* value = environment()->Lookup(variable); |
1766 if (mode == CONST_LEGACY) { | 1705 if (mode == CONST_LEGACY) { |
1767 // Perform check for uninitialized legacy const variables. | 1706 // Perform check for uninitialized legacy const variables. |
1768 if (value->op() == the_hole->op()) { | 1707 if (value->op() == the_hole->op()) { |
1769 value = jsgraph()->UndefinedConstant(); | 1708 value = jsgraph()->UndefinedConstant(); |
1770 } else if (value->opcode() == IrOpcode::kPhi) { | 1709 } else if (value->opcode() == IrOpcode::kPhi) { |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1839 Operator* op = javascript()->Runtime(Runtime::kDeleteLookupSlot, 2); | 1778 Operator* op = javascript()->Runtime(Runtime::kDeleteLookupSlot, 2); |
1840 return NewNode(op, current_context(), name); | 1779 return NewNode(op, current_context(), name); |
1841 } | 1780 } |
1842 } | 1781 } |
1843 UNREACHABLE(); | 1782 UNREACHABLE(); |
1844 return NULL; | 1783 return NULL; |
1845 } | 1784 } |
1846 | 1785 |
1847 | 1786 |
1848 Node* AstGraphBuilder::BuildVariableAssignment(Variable* variable, Node* value, | 1787 Node* AstGraphBuilder::BuildVariableAssignment(Variable* variable, Node* value, |
1849 Token::Value op, | 1788 Token::Value op) { |
1850 BailoutId bailout_id) { | |
1851 Node* the_hole = jsgraph()->TheHoleConstant(); | 1789 Node* the_hole = jsgraph()->TheHoleConstant(); |
1852 VariableMode mode = variable->mode(); | 1790 VariableMode mode = variable->mode(); |
1853 switch (variable->location()) { | 1791 switch (variable->location()) { |
1854 case Variable::UNALLOCATED: { | 1792 case Variable::UNALLOCATED: { |
1855 // Global var, const, or let variable. | 1793 // Global var, const, or let variable. |
1856 Node* global = BuildLoadGlobalObject(); | 1794 Node* global = BuildLoadGlobalObject(); |
1857 PrintableUnique<Name> name = MakeUnique(variable->name()); | 1795 PrintableUnique<Name> name = MakeUnique(variable->name()); |
1858 Operator* op = javascript()->StoreNamed(name); | 1796 Operator* op = javascript()->StoreNamed(name); |
1859 Node* store = NewNode(op, global, value); | 1797 return NewNode(op, global, value); |
1860 BuildLazyBailout(store, bailout_id); | |
1861 return store; | |
1862 } | 1798 } |
1863 case Variable::PARAMETER: | 1799 case Variable::PARAMETER: |
1864 case Variable::LOCAL: | 1800 case Variable::LOCAL: |
1865 // Local var, const, or let variable. | 1801 // Local var, const, or let variable. |
1866 if (mode == CONST_LEGACY && op == Token::INIT_CONST_LEGACY) { | 1802 if (mode == CONST_LEGACY && op == Token::INIT_CONST_LEGACY) { |
1867 // Perform an initialization check for legacy const variables. | 1803 // Perform an initialization check for legacy const variables. |
1868 Node* current = environment()->Lookup(variable); | 1804 Node* current = environment()->Lookup(variable); |
1869 if (current->op() != the_hole->op()) { | 1805 if (current->op() != the_hole->op()) { |
1870 value = BuildHoleCheckSilent(current, value, current); | 1806 value = BuildHoleCheckSilent(current, value, current); |
1871 } | 1807 } |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2015 DCHECK(environment()->GetControlDependency() == node); | 1951 DCHECK(environment()->GetControlDependency() == node); |
2016 | 1952 |
2017 StructuredGraphBuilder::Environment* continuation_env = environment(); | 1953 StructuredGraphBuilder::Environment* continuation_env = environment(); |
2018 // Create environment for the deoptimization block, and build the block. | 1954 // Create environment for the deoptimization block, and build the block. |
2019 StructuredGraphBuilder::Environment* deopt_env = | 1955 StructuredGraphBuilder::Environment* deopt_env = |
2020 CopyEnvironment(continuation_env); | 1956 CopyEnvironment(continuation_env); |
2021 set_environment(deopt_env); | 1957 set_environment(deopt_env); |
2022 | 1958 |
2023 NewNode(common()->LazyDeoptimization()); | 1959 NewNode(common()->LazyDeoptimization()); |
2024 | 1960 |
2025 // TODO(jarin) If ast_id.IsNone(), perhaps we should generate an empty | |
2026 // deopt block and make sure there is no patch entry for this (so | |
2027 // that the deoptimizer dies when trying to deoptimize here). | |
2028 | |
2029 Node* state_node = environment()->Checkpoint(ast_id); | 1961 Node* state_node = environment()->Checkpoint(ast_id); |
2030 | 1962 |
2031 Node* deoptimize_node = NewNode(common()->Deoptimize(), state_node); | 1963 Node* deoptimize_node = NewNode(common()->Deoptimize(), state_node); |
2032 | 1964 |
2033 UpdateControlDependencyToLeaveFunction(deoptimize_node); | 1965 UpdateControlDependencyToLeaveFunction(deoptimize_node); |
2034 | 1966 |
2035 // Continue with the original environment. | 1967 // Continue with the original environment. |
2036 set_environment(continuation_env); | 1968 set_environment(continuation_env); |
2037 | 1969 |
2038 NewNode(common()->Continuation()); | 1970 NewNode(common()->Continuation()); |
2039 } | 1971 } |
2040 } | 1972 } |
2041 | |
2042 | |
2043 void AstGraphBuilder::BuildLazyBailoutWithPushedNode(Node* node, | |
2044 BailoutId ast_id) { | |
2045 environment()->Push(node); | |
2046 BuildLazyBailout(node, ast_id); | |
2047 environment()->Pop(); | |
2048 } | |
2049 } | 1973 } |
2050 } | 1974 } |
2051 } // namespace v8::internal::compiler | 1975 } // namespace v8::internal::compiler |
OLD | NEW |