Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(187)

Side by Side Diff: src/compiler/ast-graph-builder.cc

Issue 555283004: [turbofan] Next step towards shared operators. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/compiler/ast-graph-builder.h ('k') | src/compiler/change-lowering.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/machine-operator.h" 9 #include "src/compiler/machine-operator.h"
10 #include "src/compiler/node-properties.h" 10 #include "src/compiler/node-properties.h"
(...skipping 13 matching lines...) Expand all
24 globals_(0, info->zone()), 24 globals_(0, info->zone()),
25 breakable_(NULL), 25 breakable_(NULL),
26 execution_context_(NULL) { 26 execution_context_(NULL) {
27 InitializeAstVisitor(info->zone()); 27 InitializeAstVisitor(info->zone());
28 } 28 }
29 29
30 30
31 Node* AstGraphBuilder::GetFunctionClosure() { 31 Node* AstGraphBuilder::GetFunctionClosure() {
32 if (!function_closure_.is_set()) { 32 if (!function_closure_.is_set()) {
33 // Parameter -1 is special for the function closure 33 // Parameter -1 is special for the function closure
34 Operator* op = common()->Parameter(-1); 34 const Operator* op = common()->Parameter(-1);
35 Node* node = NewNode(op, graph()->start()); 35 Node* node = NewNode(op, graph()->start());
36 function_closure_.set(node); 36 function_closure_.set(node);
37 } 37 }
38 return function_closure_.get(); 38 return function_closure_.get();
39 } 39 }
40 40
41 41
42 Node* AstGraphBuilder::GetFunctionContext() { 42 Node* AstGraphBuilder::GetFunctionContext() {
43 if (!function_context_.is_set()) { 43 if (!function_context_.is_set()) {
44 // Parameter (arity + 1) is special for the outer context of the function 44 // Parameter (arity + 1) is special for the outer context of the function
45 Operator* op = common()->Parameter(info()->num_parameters() + 1); 45 const Operator* op = common()->Parameter(info()->num_parameters() + 1);
46 Node* node = NewNode(op, graph()->start()); 46 Node* node = NewNode(op, graph()->start());
47 function_context_.set(node); 47 function_context_.set(node);
48 } 48 }
49 return function_context_.get(); 49 return function_context_.get();
50 } 50 }
51 51
52 52
53 bool AstGraphBuilder::CreateGraph() { 53 bool AstGraphBuilder::CreateGraph() {
54 Scope* scope = info()->scope(); 54 Scope* scope = info()->scope();
55 DCHECK(graph() != NULL); 55 DCHECK(graph() != NULL);
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
204 } else { 204 } else {
205 DCHECK(static_cast<size_t>(offset + count) <= values()->size()); 205 DCHECK(static_cast<size_t>(offset + count) <= values()->size());
206 for (int i = 0; i < count; i++) { 206 for (int i = 0; i < count; i++) {
207 if ((*state_values)->InputAt(i) != env_values[i]) { 207 if ((*state_values)->InputAt(i) != env_values[i]) {
208 should_update = true; 208 should_update = true;
209 break; 209 break;
210 } 210 }
211 } 211 }
212 } 212 }
213 if (should_update) { 213 if (should_update) {
214 Operator* op = common()->StateValues(count); 214 const Operator* op = common()->StateValues(count);
215 (*state_values) = graph()->NewNode(op, count, env_values); 215 (*state_values) = graph()->NewNode(op, count, env_values);
216 } 216 }
217 } 217 }
218 218
219 219
220 Node* AstGraphBuilder::Environment::Checkpoint( 220 Node* AstGraphBuilder::Environment::Checkpoint(
221 BailoutId ast_id, OutputFrameStateCombine combine) { 221 BailoutId ast_id, OutputFrameStateCombine combine) {
222 UpdateStateValues(&parameters_node_, 0, parameters_count()); 222 UpdateStateValues(&parameters_node_, 0, parameters_count());
223 UpdateStateValues(&locals_node_, parameters_count(), locals_count()); 223 UpdateStateValues(&locals_node_, parameters_count(), locals_count());
224 UpdateStateValues(&stack_node_, parameters_count() + locals_count(), 224 UpdateStateValues(&stack_node_, parameters_count() + locals_count(),
225 stack_height()); 225 stack_height());
226 226
227 Operator* op = common()->FrameState(ast_id, combine); 227 const Operator* op = common()->FrameState(ast_id, combine);
228 228
229 return graph()->NewNode(op, parameters_node_, locals_node_, stack_node_, 229 return graph()->NewNode(op, parameters_node_, locals_node_, stack_node_,
230 GetContext(), 230 GetContext(),
231 builder()->jsgraph()->UndefinedConstant()); 231 builder()->jsgraph()->UndefinedConstant());
232 } 232 }
233 233
234 234
235 AstGraphBuilder::AstContext::AstContext(AstGraphBuilder* own, 235 AstGraphBuilder::AstContext::AstContext(AstGraphBuilder* own,
236 Expression::Context kind) 236 Expression::Context kind)
237 : kind_(kind), owner_(own), outer_(own->ast_context()) { 237 : kind_(kind), owner_(own), outer_(own->ast_context()) {
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
367 case Variable::PARAMETER: 367 case Variable::PARAMETER:
368 case Variable::LOCAL: 368 case Variable::LOCAL:
369 if (hole_init) { 369 if (hole_init) {
370 Node* value = jsgraph()->TheHoleConstant(); 370 Node* value = jsgraph()->TheHoleConstant();
371 environment()->Bind(variable, value); 371 environment()->Bind(variable, value);
372 } 372 }
373 break; 373 break;
374 case Variable::CONTEXT: 374 case Variable::CONTEXT:
375 if (hole_init) { 375 if (hole_init) {
376 Node* value = jsgraph()->TheHoleConstant(); 376 Node* value = jsgraph()->TheHoleConstant();
377 Operator* op = javascript()->StoreContext(0, variable->index()); 377 const Operator* op = javascript()->StoreContext(0, variable->index());
378 NewNode(op, current_context(), value); 378 NewNode(op, current_context(), value);
379 } 379 }
380 break; 380 break;
381 case Variable::LOOKUP: 381 case Variable::LOOKUP:
382 UNIMPLEMENTED(); 382 UNIMPLEMENTED();
383 } 383 }
384 } 384 }
385 385
386 386
387 void AstGraphBuilder::VisitFunctionDeclaration(FunctionDeclaration* decl) { 387 void AstGraphBuilder::VisitFunctionDeclaration(FunctionDeclaration* decl) {
(...skipping 11 matching lines...) Expand all
399 case Variable::PARAMETER: 399 case Variable::PARAMETER:
400 case Variable::LOCAL: { 400 case Variable::LOCAL: {
401 VisitForValue(decl->fun()); 401 VisitForValue(decl->fun());
402 Node* value = environment()->Pop(); 402 Node* value = environment()->Pop();
403 environment()->Bind(variable, value); 403 environment()->Bind(variable, value);
404 break; 404 break;
405 } 405 }
406 case Variable::CONTEXT: { 406 case Variable::CONTEXT: {
407 VisitForValue(decl->fun()); 407 VisitForValue(decl->fun());
408 Node* value = environment()->Pop(); 408 Node* value = environment()->Pop();
409 Operator* op = javascript()->StoreContext(0, variable->index()); 409 const Operator* op = javascript()->StoreContext(0, variable->index());
410 NewNode(op, current_context(), value); 410 NewNode(op, current_context(), value);
411 break; 411 break;
412 } 412 }
413 case Variable::LOOKUP: 413 case Variable::LOOKUP:
414 UNIMPLEMENTED(); 414 UNIMPLEMENTED();
415 } 415 }
416 } 416 }
417 417
418 418
419 void AstGraphBuilder::VisitModuleDeclaration(ModuleDeclaration* decl) { 419 void AstGraphBuilder::VisitModuleDeclaration(ModuleDeclaration* decl) {
(...skipping 26 matching lines...) Expand all
446 446
447 447
448 void AstGraphBuilder::VisitBlock(Block* stmt) { 448 void AstGraphBuilder::VisitBlock(Block* stmt) {
449 BlockBuilder block(this); 449 BlockBuilder block(this);
450 BreakableScope scope(this, stmt, &block, 0); 450 BreakableScope scope(this, stmt, &block, 0);
451 if (stmt->labels() != NULL) block.BeginBlock(); 451 if (stmt->labels() != NULL) block.BeginBlock();
452 if (stmt->scope() == NULL) { 452 if (stmt->scope() == NULL) {
453 // Visit statements in the same scope, no declarations. 453 // Visit statements in the same scope, no declarations.
454 VisitStatements(stmt->statements()); 454 VisitStatements(stmt->statements());
455 } else { 455 } else {
456 Operator* op = javascript()->CreateBlockContext(); 456 const Operator* op = javascript()->CreateBlockContext();
457 Node* scope_info = jsgraph()->Constant(stmt->scope()->GetScopeInfo()); 457 Node* scope_info = jsgraph()->Constant(stmt->scope()->GetScopeInfo());
458 Node* context = NewNode(op, scope_info, GetFunctionClosure()); 458 Node* context = NewNode(op, scope_info, GetFunctionClosure());
459 ContextScope scope(this, stmt->scope(), context); 459 ContextScope scope(this, stmt->scope(), context);
460 460
461 // Visit declarations and statements in a block scope. 461 // Visit declarations and statements in a block scope.
462 VisitDeclarations(stmt->scope()->declarations()); 462 VisitDeclarations(stmt->scope()->declarations());
463 VisitStatements(stmt->statements()); 463 VisitStatements(stmt->statements());
464 } 464 }
465 if (stmt->labels() != NULL) block.EndBlock(); 465 if (stmt->labels() != NULL) block.EndBlock();
466 } 466 }
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
512 VisitForValue(stmt->expression()); 512 VisitForValue(stmt->expression());
513 Node* result = environment()->Pop(); 513 Node* result = environment()->Pop();
514 Node* control = NewNode(common()->Return(), result); 514 Node* control = NewNode(common()->Return(), result);
515 UpdateControlDependencyToLeaveFunction(control); 515 UpdateControlDependencyToLeaveFunction(control);
516 } 516 }
517 517
518 518
519 void AstGraphBuilder::VisitWithStatement(WithStatement* stmt) { 519 void AstGraphBuilder::VisitWithStatement(WithStatement* stmt) {
520 VisitForValue(stmt->expression()); 520 VisitForValue(stmt->expression());
521 Node* value = environment()->Pop(); 521 Node* value = environment()->Pop();
522 Operator* op = javascript()->CreateWithContext(); 522 const Operator* op = javascript()->CreateWithContext();
523 Node* context = NewNode(op, value, GetFunctionClosure()); 523 Node* context = NewNode(op, value, GetFunctionClosure());
524 ContextScope scope(this, stmt->scope(), context); 524 ContextScope scope(this, stmt->scope(), context);
525 Visit(stmt->statement()); 525 Visit(stmt->statement());
526 } 526 }
527 527
528 528
529 void AstGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) { 529 void AstGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) {
530 ZoneList<CaseClause*>* clauses = stmt->cases(); 530 ZoneList<CaseClause*>* clauses = stmt->cases();
531 SwitchBuilder compare_switch(this, clauses->length()); 531 SwitchBuilder compare_switch(this, clauses->length());
532 BreakableScope scope(this, stmt, &compare_switch, 0); 532 BreakableScope scope(this, stmt, &compare_switch, 0);
(...skipping 11 matching lines...) Expand all
544 // The default is not a test, remember index. 544 // The default is not a test, remember index.
545 if (clause->is_default()) { 545 if (clause->is_default()) {
546 default_index = i; 546 default_index = i;
547 continue; 547 continue;
548 } 548 }
549 549
550 // Create nodes to perform label comparison as if via '==='. The switch 550 // Create nodes to perform label comparison as if via '==='. The switch
551 // value is still on the operand stack while the label is evaluated. 551 // value is still on the operand stack while the label is evaluated.
552 VisitForValue(clause->label()); 552 VisitForValue(clause->label());
553 Node* label = environment()->Pop(); 553 Node* label = environment()->Pop();
554 Operator* op = javascript()->StrictEqual(); 554 const Operator* op = javascript()->StrictEqual();
555 Node* condition = NewNode(op, tag, label); 555 Node* condition = NewNode(op, tag, label);
556 compare_switch.BeginLabel(i, condition); 556 compare_switch.BeginLabel(i, condition);
557 557
558 // Discard the switch value at label match. 558 // Discard the switch value at label match.
559 environment()->Pop(); 559 environment()->Pop();
560 compare_switch.EndLabel(); 560 compare_switch.EndLabel();
561 } 561 }
562 562
563 // Discard the switch value and mark the default case. 563 // Discard the switch value and mark the default case.
564 environment()->Pop(); 564 environment()->Pop();
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after
799 SearchSharedFunctionInfo(info()->shared_info()->code(), expr); 799 SearchSharedFunctionInfo(info()->shared_info()->code(), expr);
800 if (shared_info.is_null()) { 800 if (shared_info.is_null()) {
801 shared_info = Compiler::BuildFunctionInfo(expr, info()->script(), info()); 801 shared_info = Compiler::BuildFunctionInfo(expr, info()->script(), info());
802 CHECK(!shared_info.is_null()); // TODO(mstarzinger): Set stack overflow? 802 CHECK(!shared_info.is_null()); // TODO(mstarzinger): Set stack overflow?
803 } 803 }
804 804
805 // Create node to instantiate a new closure. 805 // Create node to instantiate a new closure.
806 Node* info = jsgraph()->Constant(shared_info); 806 Node* info = jsgraph()->Constant(shared_info);
807 Node* pretenure = expr->pretenure() ? jsgraph()->TrueConstant() 807 Node* pretenure = expr->pretenure() ? jsgraph()->TrueConstant()
808 : jsgraph()->FalseConstant(); 808 : jsgraph()->FalseConstant();
809 Operator* op = javascript()->Runtime(Runtime::kNewClosure, 3); 809 const Operator* op = javascript()->Runtime(Runtime::kNewClosure, 3);
810 Node* value = NewNode(op, context, info, pretenure); 810 Node* value = NewNode(op, context, info, pretenure);
811 ast_context()->ProduceValue(value); 811 ast_context()->ProduceValue(value);
812 } 812 }
813 813
814 814
815 void AstGraphBuilder::VisitNativeFunctionLiteral(NativeFunctionLiteral* expr) { 815 void AstGraphBuilder::VisitNativeFunctionLiteral(NativeFunctionLiteral* expr) {
816 UNREACHABLE(); 816 UNREACHABLE();
817 } 817 }
818 818
819 819
(...skipping 25 matching lines...) Expand all
845 845
846 void AstGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) { 846 void AstGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) {
847 Node* closure = GetFunctionClosure(); 847 Node* closure = GetFunctionClosure();
848 848
849 // Create node to materialize a regular expression literal. 849 // Create node to materialize a regular expression literal.
850 Node* literals_array = 850 Node* literals_array =
851 BuildLoadObjectField(closure, JSFunction::kLiteralsOffset); 851 BuildLoadObjectField(closure, JSFunction::kLiteralsOffset);
852 Node* literal_index = jsgraph()->Constant(expr->literal_index()); 852 Node* literal_index = jsgraph()->Constant(expr->literal_index());
853 Node* pattern = jsgraph()->Constant(expr->pattern()); 853 Node* pattern = jsgraph()->Constant(expr->pattern());
854 Node* flags = jsgraph()->Constant(expr->flags()); 854 Node* flags = jsgraph()->Constant(expr->flags());
855 Operator* op = javascript()->Runtime(Runtime::kMaterializeRegExpLiteral, 4); 855 const Operator* op =
856 javascript()->Runtime(Runtime::kMaterializeRegExpLiteral, 4);
856 Node* literal = NewNode(op, literals_array, literal_index, pattern, flags); 857 Node* literal = NewNode(op, literals_array, literal_index, pattern, flags);
857 ast_context()->ProduceValue(literal); 858 ast_context()->ProduceValue(literal);
858 } 859 }
859 860
860 861
861 void AstGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { 862 void AstGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
862 Node* closure = GetFunctionClosure(); 863 Node* closure = GetFunctionClosure();
863 864
864 // Create node to deep-copy the literal boilerplate. 865 // Create node to deep-copy the literal boilerplate.
865 expr->BuildConstantProperties(isolate()); 866 expr->BuildConstantProperties(isolate());
866 Node* literals_array = 867 Node* literals_array =
867 BuildLoadObjectField(closure, JSFunction::kLiteralsOffset); 868 BuildLoadObjectField(closure, JSFunction::kLiteralsOffset);
868 Node* literal_index = jsgraph()->Constant(expr->literal_index()); 869 Node* literal_index = jsgraph()->Constant(expr->literal_index());
869 Node* constants = jsgraph()->Constant(expr->constant_properties()); 870 Node* constants = jsgraph()->Constant(expr->constant_properties());
870 Node* flags = jsgraph()->Constant(expr->ComputeFlags()); 871 Node* flags = jsgraph()->Constant(expr->ComputeFlags());
871 Operator* op = javascript()->Runtime(Runtime::kCreateObjectLiteral, 4); 872 const Operator* op = javascript()->Runtime(Runtime::kCreateObjectLiteral, 4);
872 Node* literal = NewNode(op, literals_array, literal_index, constants, flags); 873 Node* literal = NewNode(op, literals_array, literal_index, constants, flags);
873 874
874 // The object is expected on the operand stack during computation of the 875 // The object is expected on the operand stack during computation of the
875 // property values and is the value of the entire expression. 876 // property values and is the value of the entire expression.
876 environment()->Push(literal); 877 environment()->Push(literal);
877 878
878 // Mark all computed expressions that are bound to a key that is shadowed by 879 // Mark all computed expressions that are bound to a key that is shadowed by
879 // a later occurrence of the same key. For the marked expressions, no store 880 // a later occurrence of the same key. For the marked expressions, no store
880 // code is emitted. 881 // code is emitted.
881 expr->CalculateEmitStore(zone()); 882 expr->CalculateEmitStore(zone());
(...skipping 28 matching lines...) Expand all
910 break; 911 break;
911 } 912 }
912 environment()->Push(literal); // Duplicate receiver. 913 environment()->Push(literal); // Duplicate receiver.
913 VisitForValue(property->key()); 914 VisitForValue(property->key());
914 VisitForValue(property->value()); 915 VisitForValue(property->value());
915 Node* value = environment()->Pop(); 916 Node* value = environment()->Pop();
916 Node* key = environment()->Pop(); 917 Node* key = environment()->Pop();
917 Node* receiver = environment()->Pop(); 918 Node* receiver = environment()->Pop();
918 if (property->emit_store()) { 919 if (property->emit_store()) {
919 Node* strict = jsgraph()->Constant(SLOPPY); 920 Node* strict = jsgraph()->Constant(SLOPPY);
920 Operator* op = javascript()->Runtime(Runtime::kSetProperty, 4); 921 const Operator* op = javascript()->Runtime(Runtime::kSetProperty, 4);
921 NewNode(op, receiver, key, value, strict); 922 NewNode(op, receiver, key, value, strict);
922 } 923 }
923 break; 924 break;
924 } 925 }
925 case ObjectLiteral::Property::PROTOTYPE: { 926 case ObjectLiteral::Property::PROTOTYPE: {
926 environment()->Push(literal); // Duplicate receiver. 927 environment()->Push(literal); // Duplicate receiver.
927 VisitForValue(property->value()); 928 VisitForValue(property->value());
928 Node* value = environment()->Pop(); 929 Node* value = environment()->Pop();
929 Node* receiver = environment()->Pop(); 930 Node* receiver = environment()->Pop();
930 if (property->emit_store()) { 931 if (property->emit_store()) {
931 Operator* op = javascript()->Runtime(Runtime::kSetPrototype, 2); 932 const Operator* op = javascript()->Runtime(Runtime::kSetPrototype, 2);
932 NewNode(op, receiver, value); 933 NewNode(op, receiver, value);
933 } 934 }
934 break; 935 break;
935 } 936 }
936 case ObjectLiteral::Property::GETTER: 937 case ObjectLiteral::Property::GETTER:
937 accessor_table.lookup(key)->second->getter = property->value(); 938 accessor_table.lookup(key)->second->getter = property->value();
938 break; 939 break;
939 case ObjectLiteral::Property::SETTER: 940 case ObjectLiteral::Property::SETTER:
940 accessor_table.lookup(key)->second->setter = property->value(); 941 accessor_table.lookup(key)->second->setter = property->value();
941 break; 942 break;
942 } 943 }
943 } 944 }
944 945
945 // Create nodes to define accessors, using only a single call to the runtime 946 // Create nodes to define accessors, using only a single call to the runtime
946 // for each pair of corresponding getters and setters. 947 // for each pair of corresponding getters and setters.
947 for (AccessorTable::Iterator it = accessor_table.begin(); 948 for (AccessorTable::Iterator it = accessor_table.begin();
948 it != accessor_table.end(); ++it) { 949 it != accessor_table.end(); ++it) {
949 VisitForValue(it->first); 950 VisitForValue(it->first);
950 VisitForValueOrNull(it->second->getter); 951 VisitForValueOrNull(it->second->getter);
951 VisitForValueOrNull(it->second->setter); 952 VisitForValueOrNull(it->second->setter);
952 Node* setter = environment()->Pop(); 953 Node* setter = environment()->Pop();
953 Node* getter = environment()->Pop(); 954 Node* getter = environment()->Pop();
954 Node* name = environment()->Pop(); 955 Node* name = environment()->Pop();
955 Node* attr = jsgraph()->Constant(NONE); 956 Node* attr = jsgraph()->Constant(NONE);
956 Operator* op = 957 const Operator* op =
957 javascript()->Runtime(Runtime::kDefineAccessorPropertyUnchecked, 5); 958 javascript()->Runtime(Runtime::kDefineAccessorPropertyUnchecked, 5);
958 NewNode(op, literal, name, getter, setter, attr); 959 NewNode(op, literal, name, getter, setter, attr);
959 } 960 }
960 961
961 // Transform literals that contain functions to fast properties. 962 // Transform literals that contain functions to fast properties.
962 if (expr->has_function()) { 963 if (expr->has_function()) {
963 Operator* op = javascript()->Runtime(Runtime::kToFastProperties, 1); 964 const Operator* op = javascript()->Runtime(Runtime::kToFastProperties, 1);
964 NewNode(op, literal); 965 NewNode(op, literal);
965 } 966 }
966 967
967 ast_context()->ProduceValue(environment()->Pop()); 968 ast_context()->ProduceValue(environment()->Pop());
968 } 969 }
969 970
970 971
971 void AstGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) { 972 void AstGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
972 Node* closure = GetFunctionClosure(); 973 Node* closure = GetFunctionClosure();
973 974
974 // Create node to deep-copy the literal boilerplate. 975 // Create node to deep-copy the literal boilerplate.
975 expr->BuildConstantElements(isolate()); 976 expr->BuildConstantElements(isolate());
976 Node* literals_array = 977 Node* literals_array =
977 BuildLoadObjectField(closure, JSFunction::kLiteralsOffset); 978 BuildLoadObjectField(closure, JSFunction::kLiteralsOffset);
978 Node* literal_index = jsgraph()->Constant(expr->literal_index()); 979 Node* literal_index = jsgraph()->Constant(expr->literal_index());
979 Node* constants = jsgraph()->Constant(expr->constant_elements()); 980 Node* constants = jsgraph()->Constant(expr->constant_elements());
980 Node* flags = jsgraph()->Constant(expr->ComputeFlags()); 981 Node* flags = jsgraph()->Constant(expr->ComputeFlags());
981 Operator* op = javascript()->Runtime(Runtime::kCreateArrayLiteral, 4); 982 const Operator* op = javascript()->Runtime(Runtime::kCreateArrayLiteral, 4);
982 Node* literal = NewNode(op, literals_array, literal_index, constants, flags); 983 Node* literal = NewNode(op, literals_array, literal_index, constants, flags);
983 984
984 // The array and the literal index are both expected on the operand stack 985 // The array and the literal index are both expected on the operand stack
985 // during computation of the element values. 986 // during computation of the element values.
986 environment()->Push(literal); 987 environment()->Push(literal);
987 environment()->Push(literal_index); 988 environment()->Push(literal_index);
988 989
989 // Create nodes to evaluate all the non-constant subexpressions and to store 990 // Create nodes to evaluate all the non-constant subexpressions and to store
990 // them into the newly cloned array. 991 // them into the newly cloned array.
991 for (int i = 0; i < expr->values()->length(); i++) { 992 for (int i = 0; i < expr->values()->length(); i++) {
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
1147 environment()->Pop(); 1148 environment()->Pop();
1148 environment()->Pop(); 1149 environment()->Pop();
1149 // TODO(turbofan): VisitYield 1150 // TODO(turbofan): VisitYield
1150 ast_context()->ProduceValue(jsgraph()->UndefinedConstant()); 1151 ast_context()->ProduceValue(jsgraph()->UndefinedConstant());
1151 } 1152 }
1152 1153
1153 1154
1154 void AstGraphBuilder::VisitThrow(Throw* expr) { 1155 void AstGraphBuilder::VisitThrow(Throw* expr) {
1155 VisitForValue(expr->exception()); 1156 VisitForValue(expr->exception());
1156 Node* exception = environment()->Pop(); 1157 Node* exception = environment()->Pop();
1157 Operator* op = javascript()->Runtime(Runtime::kThrow, 1); 1158 const Operator* op = javascript()->Runtime(Runtime::kThrow, 1);
1158 Node* value = NewNode(op, exception); 1159 Node* value = NewNode(op, exception);
1159 ast_context()->ProduceValue(value); 1160 ast_context()->ProduceValue(value);
1160 } 1161 }
1161 1162
1162 1163
1163 void AstGraphBuilder::VisitProperty(Property* expr) { 1164 void AstGraphBuilder::VisitProperty(Property* expr) {
1164 Node* value; 1165 Node* value;
1165 if (expr->key()->IsPropertyName()) { 1166 if (expr->key()->IsPropertyName()) {
1166 VisitForValue(expr->obj()); 1167 VisitForValue(expr->obj());
1167 Node* object = environment()->Pop(); 1168 Node* object = environment()->Pop();
(...skipping 25 matching lines...) Expand all
1193 case Call::GLOBAL_CALL: { 1194 case Call::GLOBAL_CALL: {
1194 Variable* variable = callee->AsVariableProxy()->var(); 1195 Variable* variable = callee->AsVariableProxy()->var();
1195 callee_value = BuildVariableLoad(variable, expr->expression()->id()); 1196 callee_value = BuildVariableLoad(variable, expr->expression()->id());
1196 receiver_value = jsgraph()->UndefinedConstant(); 1197 receiver_value = jsgraph()->UndefinedConstant();
1197 break; 1198 break;
1198 } 1199 }
1199 case Call::LOOKUP_SLOT_CALL: { 1200 case Call::LOOKUP_SLOT_CALL: {
1200 Variable* variable = callee->AsVariableProxy()->var(); 1201 Variable* variable = callee->AsVariableProxy()->var();
1201 DCHECK(variable->location() == Variable::LOOKUP); 1202 DCHECK(variable->location() == Variable::LOOKUP);
1202 Node* name = jsgraph()->Constant(variable->name()); 1203 Node* name = jsgraph()->Constant(variable->name());
1203 Operator* op = javascript()->Runtime(Runtime::kLoadLookupSlot, 2); 1204 const Operator* op = javascript()->Runtime(Runtime::kLoadLookupSlot, 2);
1204 Node* pair = NewNode(op, current_context(), name); 1205 Node* pair = NewNode(op, current_context(), name);
1205 callee_value = NewNode(common()->Projection(0), pair); 1206 callee_value = NewNode(common()->Projection(0), pair);
1206 receiver_value = NewNode(common()->Projection(1), pair); 1207 receiver_value = NewNode(common()->Projection(1), pair);
1207 break; 1208 break;
1208 } 1209 }
1209 case Call::PROPERTY_CALL: { 1210 case Call::PROPERTY_CALL: {
1210 Property* property = callee->AsProperty(); 1211 Property* property = callee->AsProperty();
1211 VisitForValue(property->obj()); 1212 VisitForValue(property->obj());
1212 Node* object = environment()->Top(); 1213 Node* object = environment()->Top();
1213 if (property->key()->IsPropertyName()) { 1214 if (property->key()->IsPropertyName()) {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1253 1254
1254 // Extract callee and source string from the environment. 1255 // Extract callee and source string from the environment.
1255 Node* callee = environment()->Peek(arg_count + 1); 1256 Node* callee = environment()->Peek(arg_count + 1);
1256 Node* source = environment()->Peek(arg_count - 1); 1257 Node* source = environment()->Peek(arg_count - 1);
1257 1258
1258 // Create node to ask for help resolving potential eval call. This will 1259 // Create node to ask for help resolving potential eval call. This will
1259 // provide a fully resolved callee and the corresponding receiver. 1260 // provide a fully resolved callee and the corresponding receiver.
1260 Node* receiver = environment()->Lookup(info()->scope()->receiver()); 1261 Node* receiver = environment()->Lookup(info()->scope()->receiver());
1261 Node* strict = jsgraph()->Constant(strict_mode()); 1262 Node* strict = jsgraph()->Constant(strict_mode());
1262 Node* position = jsgraph()->Constant(info()->scope()->start_position()); 1263 Node* position = jsgraph()->Constant(info()->scope()->start_position());
1263 Operator* op = 1264 const Operator* op =
1264 javascript()->Runtime(Runtime::kResolvePossiblyDirectEval, 5); 1265 javascript()->Runtime(Runtime::kResolvePossiblyDirectEval, 5);
1265 Node* pair = NewNode(op, callee, source, receiver, strict, position); 1266 Node* pair = NewNode(op, callee, source, receiver, strict, position);
1266 Node* new_callee = NewNode(common()->Projection(0), pair); 1267 Node* new_callee = NewNode(common()->Projection(0), pair);
1267 Node* new_receiver = NewNode(common()->Projection(1), pair); 1268 Node* new_receiver = NewNode(common()->Projection(1), pair);
1268 1269
1269 // Patch callee and receiver on the environment. 1270 // Patch callee and receiver on the environment.
1270 environment()->Poke(arg_count + 1, new_callee); 1271 environment()->Poke(arg_count + 1, new_callee);
1271 environment()->Poke(arg_count + 0, new_receiver); 1272 environment()->Poke(arg_count + 0, new_receiver);
1272 } 1273 }
1273 1274
1274 // Create node to perform the function call. 1275 // Create node to perform the function call.
1275 Operator* call = javascript()->Call(args->length() + 2, flags); 1276 const Operator* call = javascript()->Call(args->length() + 2, flags);
1276 Node* value = ProcessArguments(call, args->length() + 2); 1277 Node* value = ProcessArguments(call, args->length() + 2);
1277 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); 1278 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
1278 ast_context()->ProduceValue(value); 1279 ast_context()->ProduceValue(value);
1279 } 1280 }
1280 1281
1281 1282
1282 void AstGraphBuilder::VisitCallNew(CallNew* expr) { 1283 void AstGraphBuilder::VisitCallNew(CallNew* expr) {
1283 VisitForValue(expr->expression()); 1284 VisitForValue(expr->expression());
1284 1285
1285 // Evaluate all arguments to the construct call. 1286 // Evaluate all arguments to the construct call.
1286 ZoneList<Expression*>* args = expr->arguments(); 1287 ZoneList<Expression*>* args = expr->arguments();
1287 VisitForValues(args); 1288 VisitForValues(args);
1288 1289
1289 // Create node to perform the construct call. 1290 // Create node to perform the construct call.
1290 Operator* call = javascript()->CallNew(args->length() + 1); 1291 const Operator* call = javascript()->CallNew(args->length() + 1);
1291 Node* value = ProcessArguments(call, args->length() + 1); 1292 Node* value = ProcessArguments(call, args->length() + 1);
1292 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); 1293 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
1293 ast_context()->ProduceValue(value); 1294 ast_context()->ProduceValue(value);
1294 } 1295 }
1295 1296
1296 1297
1297 void AstGraphBuilder::VisitCallJSRuntime(CallRuntime* expr) { 1298 void AstGraphBuilder::VisitCallJSRuntime(CallRuntime* expr) {
1298 Handle<String> name = expr->name(); 1299 Handle<String> name = expr->name();
1299 1300
1300 // The callee and the receiver both have to be pushed onto the operand stack 1301 // The callee and the receiver both have to be pushed onto the operand stack
1301 // before arguments are being evaluated. 1302 // before arguments are being evaluated.
1302 CallFunctionFlags flags = NO_CALL_FUNCTION_FLAGS; 1303 CallFunctionFlags flags = NO_CALL_FUNCTION_FLAGS;
1303 Node* receiver_value = BuildLoadBuiltinsObject(); 1304 Node* receiver_value = BuildLoadBuiltinsObject();
1304 Unique<String> unique = MakeUnique(name); 1305 Unique<String> unique = MakeUnique(name);
1305 Node* callee_value = NewNode(javascript()->LoadNamed(unique), receiver_value); 1306 Node* callee_value = NewNode(javascript()->LoadNamed(unique), receiver_value);
1306 // TODO(jarin): Find/create a bailout id to deoptimize to (crankshaft 1307 // TODO(jarin): Find/create a bailout id to deoptimize to (crankshaft
1307 // refuses to optimize functions with jsruntime calls). 1308 // refuses to optimize functions with jsruntime calls).
1308 PrepareFrameState(callee_value, BailoutId::None(), kPushOutput); 1309 PrepareFrameState(callee_value, BailoutId::None(), kPushOutput);
1309 environment()->Push(callee_value); 1310 environment()->Push(callee_value);
1310 environment()->Push(receiver_value); 1311 environment()->Push(receiver_value);
1311 1312
1312 // Evaluate all arguments to the JS runtime call. 1313 // Evaluate all arguments to the JS runtime call.
1313 ZoneList<Expression*>* args = expr->arguments(); 1314 ZoneList<Expression*>* args = expr->arguments();
1314 VisitForValues(args); 1315 VisitForValues(args);
1315 1316
1316 // Create node to perform the JS runtime call. 1317 // Create node to perform the JS runtime call.
1317 Operator* call = javascript()->Call(args->length() + 2, flags); 1318 const Operator* call = javascript()->Call(args->length() + 2, flags);
1318 Node* value = ProcessArguments(call, args->length() + 2); 1319 Node* value = ProcessArguments(call, args->length() + 2);
1319 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); 1320 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
1320 ast_context()->ProduceValue(value); 1321 ast_context()->ProduceValue(value);
1321 } 1322 }
1322 1323
1323 1324
1324 void AstGraphBuilder::VisitCallRuntime(CallRuntime* expr) { 1325 void AstGraphBuilder::VisitCallRuntime(CallRuntime* expr) {
1325 const Runtime::Function* function = expr->function(); 1326 const Runtime::Function* function = expr->function();
1326 1327
1327 // Handle calls to runtime functions implemented in JavaScript separately as 1328 // Handle calls to runtime functions implemented in JavaScript separately as
1328 // the call follows JavaScript ABI and the callee is statically unknown. 1329 // the call follows JavaScript ABI and the callee is statically unknown.
1329 if (expr->is_jsruntime()) { 1330 if (expr->is_jsruntime()) {
1330 DCHECK(function == NULL && expr->name()->length() > 0); 1331 DCHECK(function == NULL && expr->name()->length() > 0);
1331 return VisitCallJSRuntime(expr); 1332 return VisitCallJSRuntime(expr);
1332 } 1333 }
1333 1334
1334 // Evaluate all arguments to the runtime call. 1335 // Evaluate all arguments to the runtime call.
1335 ZoneList<Expression*>* args = expr->arguments(); 1336 ZoneList<Expression*>* args = expr->arguments();
1336 VisitForValues(args); 1337 VisitForValues(args);
1337 1338
1338 // Create node to perform the runtime call. 1339 // Create node to perform the runtime call.
1339 Runtime::FunctionId functionId = function->function_id; 1340 Runtime::FunctionId functionId = function->function_id;
1340 Operator* call = javascript()->Runtime(functionId, args->length()); 1341 const Operator* call = javascript()->Runtime(functionId, args->length());
1341 Node* value = ProcessArguments(call, args->length()); 1342 Node* value = ProcessArguments(call, args->length());
1342 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); 1343 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
1343 ast_context()->ProduceValue(value); 1344 ast_context()->ProduceValue(value);
1344 } 1345 }
1345 1346
1346 1347
1347 void AstGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) { 1348 void AstGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) {
1348 switch (expr->op()) { 1349 switch (expr->op()) {
1349 case Token::DELETE: 1350 case Token::DELETE:
1350 return VisitDelete(expr); 1351 return VisitDelete(expr);
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
1464 Node* left = environment()->Pop(); 1465 Node* left = environment()->Pop();
1465 Node* value = BuildBinaryOp(left, right, expr->op()); 1466 Node* value = BuildBinaryOp(left, right, expr->op());
1466 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); 1467 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
1467 ast_context()->ProduceValue(value); 1468 ast_context()->ProduceValue(value);
1468 } 1469 }
1469 } 1470 }
1470 } 1471 }
1471 1472
1472 1473
1473 void AstGraphBuilder::VisitCompareOperation(CompareOperation* expr) { 1474 void AstGraphBuilder::VisitCompareOperation(CompareOperation* expr) {
1474 Operator* op; 1475 const Operator* op;
1475 switch (expr->op()) { 1476 switch (expr->op()) {
1476 case Token::EQ: 1477 case Token::EQ:
1477 op = javascript()->Equal(); 1478 op = javascript()->Equal();
1478 break; 1479 break;
1479 case Token::NE: 1480 case Token::NE:
1480 op = javascript()->NotEqual(); 1481 op = javascript()->NotEqual();
1481 break; 1482 break;
1482 case Token::EQ_STRICT: 1483 case Token::EQ_STRICT:
1483 op = javascript()->StrictEqual(); 1484 op = javascript()->StrictEqual();
1484 break; 1485 break;
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1536 AstVisitor::VisitDeclarations(declarations); 1537 AstVisitor::VisitDeclarations(declarations);
1537 if (globals()->is_empty()) return; 1538 if (globals()->is_empty()) return;
1538 Handle<FixedArray> data = 1539 Handle<FixedArray> data =
1539 isolate()->factory()->NewFixedArray(globals()->length(), TENURED); 1540 isolate()->factory()->NewFixedArray(globals()->length(), TENURED);
1540 for (int i = 0; i < globals()->length(); ++i) data->set(i, *globals()->at(i)); 1541 for (int i = 0; i < globals()->length(); ++i) data->set(i, *globals()->at(i));
1541 int encoded_flags = DeclareGlobalsEvalFlag::encode(info()->is_eval()) | 1542 int encoded_flags = DeclareGlobalsEvalFlag::encode(info()->is_eval()) |
1542 DeclareGlobalsNativeFlag::encode(info()->is_native()) | 1543 DeclareGlobalsNativeFlag::encode(info()->is_native()) |
1543 DeclareGlobalsStrictMode::encode(strict_mode()); 1544 DeclareGlobalsStrictMode::encode(strict_mode());
1544 Node* flags = jsgraph()->Constant(encoded_flags); 1545 Node* flags = jsgraph()->Constant(encoded_flags);
1545 Node* pairs = jsgraph()->Constant(data); 1546 Node* pairs = jsgraph()->Constant(data);
1546 Operator* op = javascript()->Runtime(Runtime::kDeclareGlobals, 3); 1547 const Operator* op = javascript()->Runtime(Runtime::kDeclareGlobals, 3);
1547 NewNode(op, current_context(), pairs, flags); 1548 NewNode(op, current_context(), pairs, flags);
1548 globals()->Rewind(0); 1549 globals()->Rewind(0);
1549 } 1550 }
1550 1551
1551 1552
1552 void AstGraphBuilder::VisitIfNotNull(Statement* stmt) { 1553 void AstGraphBuilder::VisitIfNotNull(Statement* stmt) {
1553 if (stmt == NULL) return; 1554 if (stmt == NULL) return;
1554 Visit(stmt); 1555 Visit(stmt);
1555 } 1556 }
1556 1557
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
1643 environment()->Pop(); 1644 environment()->Pop();
1644 Visit(expr->right()); 1645 Visit(expr->right());
1645 } else if (ast_context()->IsEffect()) { 1646 } else if (ast_context()->IsEffect()) {
1646 environment()->Pop(); 1647 environment()->Pop();
1647 } 1648 }
1648 compare_if.End(); 1649 compare_if.End();
1649 ast_context()->ReplaceValue(); 1650 ast_context()->ReplaceValue();
1650 } 1651 }
1651 1652
1652 1653
1653 Node* AstGraphBuilder::ProcessArguments(Operator* op, int arity) { 1654 Node* AstGraphBuilder::ProcessArguments(const Operator* op, int arity) {
1654 DCHECK(environment()->stack_height() >= arity); 1655 DCHECK(environment()->stack_height() >= arity);
1655 Node** all = info()->zone()->NewArray<Node*>(arity); 1656 Node** all = info()->zone()->NewArray<Node*>(arity);
1656 for (int i = arity - 1; i >= 0; --i) { 1657 for (int i = arity - 1; i >= 0; --i) {
1657 all[i] = environment()->Pop(); 1658 all[i] = environment()->Pop();
1658 } 1659 }
1659 Node* value = NewNode(op, arity, all); 1660 Node* value = NewNode(op, arity, all);
1660 return value; 1661 return value;
1661 } 1662 }
1662 1663
1663 1664
1664 Node* AstGraphBuilder::BuildLocalFunctionContext(Node* context, Node* closure) { 1665 Node* AstGraphBuilder::BuildLocalFunctionContext(Node* context, Node* closure) {
1665 int heap_slots = info()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; 1666 int heap_slots = info()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
1666 if (heap_slots <= 0) return context; 1667 if (heap_slots <= 0) return context;
1667 set_current_context(context); 1668 set_current_context(context);
1668 1669
1669 // Allocate a new local context. 1670 // Allocate a new local context.
1670 Operator* op = javascript()->CreateFunctionContext(); 1671 const Operator* op = javascript()->CreateFunctionContext();
1671 Node* local_context = NewNode(op, closure); 1672 Node* local_context = NewNode(op, closure);
1672 set_current_context(local_context); 1673 set_current_context(local_context);
1673 1674
1674 // Copy parameters into context if necessary. 1675 // Copy parameters into context if necessary.
1675 int num_parameters = info()->scope()->num_parameters(); 1676 int num_parameters = info()->scope()->num_parameters();
1676 for (int i = 0; i < num_parameters; i++) { 1677 for (int i = 0; i < num_parameters; i++) {
1677 Variable* variable = info()->scope()->parameter(i); 1678 Variable* variable = info()->scope()->parameter(i);
1678 if (!variable->IsContextSlot()) continue; 1679 if (!variable->IsContextSlot()) continue;
1679 // Temporary parameter node. The parameter indices are shifted by 1 1680 // Temporary parameter node. The parameter indices are shifted by 1
1680 // (receiver is parameter index -1 but environment index 0). 1681 // (receiver is parameter index -1 but environment index 0).
1681 Node* parameter = NewNode(common()->Parameter(i + 1), graph()->start()); 1682 Node* parameter = NewNode(common()->Parameter(i + 1), graph()->start());
1682 // Context variable (at bottom of the context chain). 1683 // Context variable (at bottom of the context chain).
1683 DCHECK_EQ(0, info()->scope()->ContextChainLength(variable->scope())); 1684 DCHECK_EQ(0, info()->scope()->ContextChainLength(variable->scope()));
1684 Operator* op = javascript()->StoreContext(0, variable->index()); 1685 const Operator* op = javascript()->StoreContext(0, variable->index());
1685 NewNode(op, local_context, parameter); 1686 NewNode(op, local_context, parameter);
1686 } 1687 }
1687 1688
1688 return local_context; 1689 return local_context;
1689 } 1690 }
1690 1691
1691 1692
1692 Node* AstGraphBuilder::BuildArgumentsObject(Variable* arguments) { 1693 Node* AstGraphBuilder::BuildArgumentsObject(Variable* arguments) {
1693 if (arguments == NULL) return NULL; 1694 if (arguments == NULL) return NULL;
1694 1695
1695 // Allocate and initialize a new arguments object. 1696 // Allocate and initialize a new arguments object.
1696 Node* callee = GetFunctionClosure(); 1697 Node* callee = GetFunctionClosure();
1697 Operator* op = javascript()->Runtime(Runtime::kNewArguments, 1); 1698 const Operator* op = javascript()->Runtime(Runtime::kNewArguments, 1);
1698 Node* object = NewNode(op, callee); 1699 Node* object = NewNode(op, callee);
1699 1700
1700 // Assign the object to the arguments variable. 1701 // Assign the object to the arguments variable.
1701 DCHECK(arguments->IsContextSlot() || arguments->IsStackAllocated()); 1702 DCHECK(arguments->IsContextSlot() || arguments->IsStackAllocated());
1702 // This should never lazy deopt, so it is fine to send invalid bailout id. 1703 // This should never lazy deopt, so it is fine to send invalid bailout id.
1703 BuildVariableAssignment(arguments, object, Token::ASSIGN, BailoutId::None()); 1704 BuildVariableAssignment(arguments, object, Token::ASSIGN, BailoutId::None());
1704 1705
1705 return object; 1706 return object;
1706 } 1707 }
1707 1708
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1739 Node* AstGraphBuilder::BuildVariableLoad(Variable* variable, 1740 Node* AstGraphBuilder::BuildVariableLoad(Variable* variable,
1740 BailoutId bailout_id, 1741 BailoutId bailout_id,
1741 ContextualMode contextual_mode) { 1742 ContextualMode contextual_mode) {
1742 Node* the_hole = jsgraph()->TheHoleConstant(); 1743 Node* the_hole = jsgraph()->TheHoleConstant();
1743 VariableMode mode = variable->mode(); 1744 VariableMode mode = variable->mode();
1744 switch (variable->location()) { 1745 switch (variable->location()) {
1745 case Variable::UNALLOCATED: { 1746 case Variable::UNALLOCATED: {
1746 // Global var, const, or let variable. 1747 // Global var, const, or let variable.
1747 Node* global = BuildLoadGlobalObject(); 1748 Node* global = BuildLoadGlobalObject();
1748 Unique<Name> name = MakeUnique(variable->name()); 1749 Unique<Name> name = MakeUnique(variable->name());
1749 Operator* op = javascript()->LoadNamed(name, contextual_mode); 1750 const Operator* op = javascript()->LoadNamed(name, contextual_mode);
1750 Node* node = NewNode(op, global); 1751 Node* node = NewNode(op, global);
1751 PrepareFrameState(node, bailout_id, kPushOutput); 1752 PrepareFrameState(node, bailout_id, kPushOutput);
1752 return node; 1753 return node;
1753 } 1754 }
1754 case Variable::PARAMETER: 1755 case Variable::PARAMETER:
1755 case Variable::LOCAL: { 1756 case Variable::LOCAL: {
1756 // Local var, const, or let variable. 1757 // Local var, const, or let variable.
1757 Node* value = environment()->Lookup(variable); 1758 Node* value = environment()->Lookup(variable);
1758 if (mode == CONST_LEGACY) { 1759 if (mode == CONST_LEGACY) {
1759 // Perform check for uninitialized legacy const variables. 1760 // Perform check for uninitialized legacy const variables.
(...skipping 10 matching lines...) Expand all
1770 } else if (value->opcode() == IrOpcode::kPhi) { 1771 } else if (value->opcode() == IrOpcode::kPhi) {
1771 value = BuildHoleCheckThrow(value, variable, value); 1772 value = BuildHoleCheckThrow(value, variable, value);
1772 } 1773 }
1773 } 1774 }
1774 return value; 1775 return value;
1775 } 1776 }
1776 case Variable::CONTEXT: { 1777 case Variable::CONTEXT: {
1777 // Context variable (potentially up the context chain). 1778 // Context variable (potentially up the context chain).
1778 int depth = current_scope()->ContextChainLength(variable->scope()); 1779 int depth = current_scope()->ContextChainLength(variable->scope());
1779 bool immutable = variable->maybe_assigned() == kNotAssigned; 1780 bool immutable = variable->maybe_assigned() == kNotAssigned;
1780 Operator* op = 1781 const Operator* op =
1781 javascript()->LoadContext(depth, variable->index(), immutable); 1782 javascript()->LoadContext(depth, variable->index(), immutable);
1782 Node* value = NewNode(op, current_context()); 1783 Node* value = NewNode(op, current_context());
1783 // TODO(titzer): initialization checks are redundant for already 1784 // TODO(titzer): initialization checks are redundant for already
1784 // initialized immutable context loads, but only specialization knows. 1785 // initialized immutable context loads, but only specialization knows.
1785 // Maybe specializer should be a parameter to the graph builder? 1786 // Maybe specializer should be a parameter to the graph builder?
1786 if (mode == CONST_LEGACY) { 1787 if (mode == CONST_LEGACY) {
1787 // Perform check for uninitialized legacy const variables. 1788 // Perform check for uninitialized legacy const variables.
1788 Node* undefined = jsgraph()->UndefinedConstant(); 1789 Node* undefined = jsgraph()->UndefinedConstant();
1789 value = BuildHoleCheckSilent(value, undefined, value); 1790 value = BuildHoleCheckSilent(value, undefined, value);
1790 } else if (mode == LET || mode == CONST) { 1791 } else if (mode == LET || mode == CONST) {
1791 // Perform check for uninitialized let/const variables. 1792 // Perform check for uninitialized let/const variables.
1792 value = BuildHoleCheckThrow(value, variable, value); 1793 value = BuildHoleCheckThrow(value, variable, value);
1793 } 1794 }
1794 return value; 1795 return value;
1795 } 1796 }
1796 case Variable::LOOKUP: { 1797 case Variable::LOOKUP: {
1797 // Dynamic lookup of context variable (anywhere in the chain). 1798 // Dynamic lookup of context variable (anywhere in the chain).
1798 Node* name = jsgraph()->Constant(variable->name()); 1799 Node* name = jsgraph()->Constant(variable->name());
1799 Runtime::FunctionId function_id = 1800 Runtime::FunctionId function_id =
1800 (contextual_mode == CONTEXTUAL) 1801 (contextual_mode == CONTEXTUAL)
1801 ? Runtime::kLoadLookupSlot 1802 ? Runtime::kLoadLookupSlot
1802 : Runtime::kLoadLookupSlotNoReferenceError; 1803 : Runtime::kLoadLookupSlotNoReferenceError;
1803 Operator* op = javascript()->Runtime(function_id, 2); 1804 const Operator* op = javascript()->Runtime(function_id, 2);
1804 Node* pair = NewNode(op, current_context(), name); 1805 Node* pair = NewNode(op, current_context(), name);
1805 return NewNode(common()->Projection(0), pair); 1806 return NewNode(common()->Projection(0), pair);
1806 } 1807 }
1807 } 1808 }
1808 UNREACHABLE(); 1809 UNREACHABLE();
1809 return NULL; 1810 return NULL;
1810 } 1811 }
1811 1812
1812 1813
1813 Node* AstGraphBuilder::BuildVariableDelete(Variable* variable) { 1814 Node* AstGraphBuilder::BuildVariableDelete(Variable* variable) {
1814 switch (variable->location()) { 1815 switch (variable->location()) {
1815 case Variable::UNALLOCATED: { 1816 case Variable::UNALLOCATED: {
1816 // Global var, const, or let variable. 1817 // Global var, const, or let variable.
1817 Node* global = BuildLoadGlobalObject(); 1818 Node* global = BuildLoadGlobalObject();
1818 Node* name = jsgraph()->Constant(variable->name()); 1819 Node* name = jsgraph()->Constant(variable->name());
1819 Operator* op = javascript()->DeleteProperty(strict_mode()); 1820 const Operator* op = javascript()->DeleteProperty(strict_mode());
1820 return NewNode(op, global, name); 1821 return NewNode(op, global, name);
1821 } 1822 }
1822 case Variable::PARAMETER: 1823 case Variable::PARAMETER:
1823 case Variable::LOCAL: 1824 case Variable::LOCAL:
1824 case Variable::CONTEXT: 1825 case Variable::CONTEXT:
1825 // Local var, const, or let variable or context variable. 1826 // Local var, const, or let variable or context variable.
1826 return variable->is_this() ? jsgraph()->TrueConstant() 1827 return variable->is_this() ? jsgraph()->TrueConstant()
1827 : jsgraph()->FalseConstant(); 1828 : jsgraph()->FalseConstant();
1828 case Variable::LOOKUP: { 1829 case Variable::LOOKUP: {
1829 // Dynamic lookup of context variable (anywhere in the chain). 1830 // Dynamic lookup of context variable (anywhere in the chain).
1830 Node* name = jsgraph()->Constant(variable->name()); 1831 Node* name = jsgraph()->Constant(variable->name());
1831 Operator* op = javascript()->Runtime(Runtime::kDeleteLookupSlot, 2); 1832 const Operator* op = javascript()->Runtime(Runtime::kDeleteLookupSlot, 2);
1832 return NewNode(op, current_context(), name); 1833 return NewNode(op, current_context(), name);
1833 } 1834 }
1834 } 1835 }
1835 UNREACHABLE(); 1836 UNREACHABLE();
1836 return NULL; 1837 return NULL;
1837 } 1838 }
1838 1839
1839 1840
1840 Node* AstGraphBuilder::BuildVariableAssignment(Variable* variable, Node* value, 1841 Node* AstGraphBuilder::BuildVariableAssignment(Variable* variable, Node* value,
1841 Token::Value op, 1842 Token::Value op,
1842 BailoutId bailout_id) { 1843 BailoutId bailout_id) {
1843 Node* the_hole = jsgraph()->TheHoleConstant(); 1844 Node* the_hole = jsgraph()->TheHoleConstant();
1844 VariableMode mode = variable->mode(); 1845 VariableMode mode = variable->mode();
1845 switch (variable->location()) { 1846 switch (variable->location()) {
1846 case Variable::UNALLOCATED: { 1847 case Variable::UNALLOCATED: {
1847 // Global var, const, or let variable. 1848 // Global var, const, or let variable.
1848 Node* global = BuildLoadGlobalObject(); 1849 Node* global = BuildLoadGlobalObject();
1849 Unique<Name> name = MakeUnique(variable->name()); 1850 Unique<Name> name = MakeUnique(variable->name());
1850 Operator* op = javascript()->StoreNamed(strict_mode(), name); 1851 const Operator* op = javascript()->StoreNamed(strict_mode(), name);
1851 Node* store = NewNode(op, global, value); 1852 Node* store = NewNode(op, global, value);
1852 PrepareFrameState(store, bailout_id); 1853 PrepareFrameState(store, bailout_id);
1853 return store; 1854 return store;
1854 } 1855 }
1855 case Variable::PARAMETER: 1856 case Variable::PARAMETER:
1856 case Variable::LOCAL: 1857 case Variable::LOCAL:
1857 // Local var, const, or let variable. 1858 // Local var, const, or let variable.
1858 if (mode == CONST_LEGACY && op == Token::INIT_CONST_LEGACY) { 1859 if (mode == CONST_LEGACY && op == Token::INIT_CONST_LEGACY) {
1859 // Perform an initialization check for legacy const variables. 1860 // Perform an initialization check for legacy const variables.
1860 Node* current = environment()->Lookup(variable); 1861 Node* current = environment()->Lookup(variable);
(...skipping 18 matching lines...) Expand all
1879 // All assignments to const variables are early errors. 1880 // All assignments to const variables are early errors.
1880 UNREACHABLE(); 1881 UNREACHABLE();
1881 } 1882 }
1882 environment()->Bind(variable, value); 1883 environment()->Bind(variable, value);
1883 return value; 1884 return value;
1884 case Variable::CONTEXT: { 1885 case Variable::CONTEXT: {
1885 // Context variable (potentially up the context chain). 1886 // Context variable (potentially up the context chain).
1886 int depth = current_scope()->ContextChainLength(variable->scope()); 1887 int depth = current_scope()->ContextChainLength(variable->scope());
1887 if (mode == CONST_LEGACY && op == Token::INIT_CONST_LEGACY) { 1888 if (mode == CONST_LEGACY && op == Token::INIT_CONST_LEGACY) {
1888 // Perform an initialization check for legacy const variables. 1889 // Perform an initialization check for legacy const variables.
1889 Operator* op = 1890 const Operator* op =
1890 javascript()->LoadContext(depth, variable->index(), false); 1891 javascript()->LoadContext(depth, variable->index(), false);
1891 Node* current = NewNode(op, current_context()); 1892 Node* current = NewNode(op, current_context());
1892 value = BuildHoleCheckSilent(current, value, current); 1893 value = BuildHoleCheckSilent(current, value, current);
1893 } else if (mode == CONST_LEGACY && op != Token::INIT_CONST_LEGACY) { 1894 } else if (mode == CONST_LEGACY && op != Token::INIT_CONST_LEGACY) {
1894 // Non-initializing assignments to legacy const is ignored. 1895 // Non-initializing assignments to legacy const is ignored.
1895 return value; 1896 return value;
1896 } else if (mode == LET && op != Token::INIT_LET) { 1897 } else if (mode == LET && op != Token::INIT_LET) {
1897 // Perform an initialization check for let declared variables. 1898 // Perform an initialization check for let declared variables.
1898 Operator* op = 1899 const Operator* op =
1899 javascript()->LoadContext(depth, variable->index(), false); 1900 javascript()->LoadContext(depth, variable->index(), false);
1900 Node* current = NewNode(op, current_context()); 1901 Node* current = NewNode(op, current_context());
1901 value = BuildHoleCheckThrow(current, variable, value); 1902 value = BuildHoleCheckThrow(current, variable, value);
1902 } else if (mode == CONST && op != Token::INIT_CONST) { 1903 } else if (mode == CONST && op != Token::INIT_CONST) {
1903 // All assignments to const variables are early errors. 1904 // All assignments to const variables are early errors.
1904 UNREACHABLE(); 1905 UNREACHABLE();
1905 } 1906 }
1906 Operator* op = javascript()->StoreContext(depth, variable->index()); 1907 const Operator* op = javascript()->StoreContext(depth, variable->index());
1907 return NewNode(op, current_context(), value); 1908 return NewNode(op, current_context(), value);
1908 } 1909 }
1909 case Variable::LOOKUP: { 1910 case Variable::LOOKUP: {
1910 // Dynamic lookup of context variable (anywhere in the chain). 1911 // Dynamic lookup of context variable (anywhere in the chain).
1911 Node* name = jsgraph()->Constant(variable->name()); 1912 Node* name = jsgraph()->Constant(variable->name());
1912 Node* strict = jsgraph()->Constant(strict_mode()); 1913 Node* strict = jsgraph()->Constant(strict_mode());
1913 // TODO(mstarzinger): Use Runtime::kInitializeLegacyConstLookupSlot for 1914 // TODO(mstarzinger): Use Runtime::kInitializeLegacyConstLookupSlot for
1914 // initializations of const declarations. 1915 // initializations of const declarations.
1915 Operator* op = javascript()->Runtime(Runtime::kStoreLookupSlot, 4); 1916 const Operator* op = javascript()->Runtime(Runtime::kStoreLookupSlot, 4);
1916 return NewNode(op, value, current_context(), name, strict); 1917 return NewNode(op, value, current_context(), name, strict);
1917 } 1918 }
1918 } 1919 }
1919 UNREACHABLE(); 1920 UNREACHABLE();
1920 return NULL; 1921 return NULL;
1921 } 1922 }
1922 1923
1923 1924
1924 Node* AstGraphBuilder::BuildLoadObjectField(Node* object, int offset) { 1925 Node* AstGraphBuilder::BuildLoadObjectField(Node* object, int offset) {
1925 // TODO(sigurds) Use simplified load here once it is ready. 1926 // TODO(sigurds) Use simplified load here once it is ready.
1926 MachineOperatorBuilder machine(zone()); 1927 MachineOperatorBuilder machine(zone());
1927 Node* field_load = NewNode(machine.Load(kMachAnyTagged), object, 1928 Node* field_load = NewNode(machine.Load(kMachAnyTagged), object,
1928 jsgraph_->Int32Constant(offset - kHeapObjectTag)); 1929 jsgraph_->Int32Constant(offset - kHeapObjectTag));
1929 return field_load; 1930 return field_load;
1930 } 1931 }
1931 1932
1932 1933
1933 Node* AstGraphBuilder::BuildLoadBuiltinsObject() { 1934 Node* AstGraphBuilder::BuildLoadBuiltinsObject() {
1934 Node* global = BuildLoadGlobalObject(); 1935 Node* global = BuildLoadGlobalObject();
1935 Node* builtins = 1936 Node* builtins =
1936 BuildLoadObjectField(global, JSGlobalObject::kBuiltinsOffset); 1937 BuildLoadObjectField(global, JSGlobalObject::kBuiltinsOffset);
1937 return builtins; 1938 return builtins;
1938 } 1939 }
1939 1940
1940 1941
1941 Node* AstGraphBuilder::BuildLoadGlobalObject() { 1942 Node* AstGraphBuilder::BuildLoadGlobalObject() {
1942 Node* context = GetFunctionContext(); 1943 Node* context = GetFunctionContext();
1943 Operator* load_op = 1944 const Operator* load_op =
1944 javascript()->LoadContext(0, Context::GLOBAL_OBJECT_INDEX, true); 1945 javascript()->LoadContext(0, Context::GLOBAL_OBJECT_INDEX, true);
1945 return NewNode(load_op, context); 1946 return NewNode(load_op, context);
1946 } 1947 }
1947 1948
1948 1949
1949 Node* AstGraphBuilder::BuildToBoolean(Node* value) { 1950 Node* AstGraphBuilder::BuildToBoolean(Node* value) {
1950 // TODO(mstarzinger): Possible optimization is to NOP for boolean values. 1951 // TODO(mstarzinger): Possible optimization is to NOP for boolean values.
1951 return NewNode(javascript()->ToBoolean(), value); 1952 return NewNode(javascript()->ToBoolean(), value);
1952 } 1953 }
1953 1954
1954 1955
1955 Node* AstGraphBuilder::BuildThrowReferenceError(Variable* variable) { 1956 Node* AstGraphBuilder::BuildThrowReferenceError(Variable* variable) {
1956 // TODO(mstarzinger): Should be unified with the VisitThrow implementation. 1957 // TODO(mstarzinger): Should be unified with the VisitThrow implementation.
1957 Node* variable_name = jsgraph()->Constant(variable->name()); 1958 Node* variable_name = jsgraph()->Constant(variable->name());
1958 Operator* op = javascript()->Runtime(Runtime::kThrowReferenceError, 1); 1959 const Operator* op = javascript()->Runtime(Runtime::kThrowReferenceError, 1);
1959 return NewNode(op, variable_name); 1960 return NewNode(op, variable_name);
1960 } 1961 }
1961 1962
1962 1963
1963 Node* AstGraphBuilder::BuildBinaryOp(Node* left, Node* right, Token::Value op) { 1964 Node* AstGraphBuilder::BuildBinaryOp(Node* left, Node* right, Token::Value op) {
1964 Operator* js_op; 1965 const Operator* js_op;
1965 switch (op) { 1966 switch (op) {
1966 case Token::BIT_OR: 1967 case Token::BIT_OR:
1967 js_op = javascript()->BitwiseOr(); 1968 js_op = javascript()->BitwiseOr();
1968 break; 1969 break;
1969 case Token::BIT_AND: 1970 case Token::BIT_AND:
1970 js_op = javascript()->BitwiseAnd(); 1971 js_op = javascript()->BitwiseAnd();
1971 break; 1972 break;
1972 case Token::BIT_XOR: 1973 case Token::BIT_XOR:
1973 js_op = javascript()->BitwiseXor(); 1974 js_op = javascript()->BitwiseXor();
1974 break; 1975 break;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
2012 DCHECK(node->InputAt(frame_state_index)->op()->opcode() == IrOpcode::kDead); 2013 DCHECK(node->InputAt(frame_state_index)->op()->opcode() == IrOpcode::kDead);
2013 2014
2014 Node* frame_state_node = environment()->Checkpoint(ast_id, combine); 2015 Node* frame_state_node = environment()->Checkpoint(ast_id, combine);
2015 node->ReplaceInput(frame_state_index, frame_state_node); 2016 node->ReplaceInput(frame_state_index, frame_state_node);
2016 } 2017 }
2017 } 2018 }
2018 2019
2019 } 2020 }
2020 } 2021 }
2021 } // namespace v8::internal::compiler 2022 } // namespace v8::internal::compiler
OLDNEW
« no previous file with comments | « src/compiler/ast-graph-builder.h ('k') | src/compiler/change-lowering.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698