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/ast-loop-assignment-analyzer.h" | 8 #include "src/compiler/ast-loop-assignment-analyzer.h" |
9 #include "src/compiler/control-builders.h" | 9 #include "src/compiler/control-builders.h" |
10 #include "src/compiler/machine-operator.h" | 10 #include "src/compiler/machine-operator.h" |
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
313 | 313 |
314 | 314 |
315 void AstGraphBuilder::VisitForValueOrNull(Expression* expr) { | 315 void AstGraphBuilder::VisitForValueOrNull(Expression* expr) { |
316 if (expr == NULL) { | 316 if (expr == NULL) { |
317 return environment()->Push(jsgraph()->NullConstant()); | 317 return environment()->Push(jsgraph()->NullConstant()); |
318 } | 318 } |
319 VisitForValue(expr); | 319 VisitForValue(expr); |
320 } | 320 } |
321 | 321 |
322 | 322 |
323 void AstGraphBuilder::VisitForValueOrTheHole(Expression* expr) { | |
324 if (expr == NULL) { | |
325 return environment()->Push(jsgraph()->TheHoleConstant()); | |
326 } | |
327 VisitForValue(expr); | |
328 } | |
329 | |
330 | |
323 void AstGraphBuilder::VisitForValues(ZoneList<Expression*>* exprs) { | 331 void AstGraphBuilder::VisitForValues(ZoneList<Expression*>* exprs) { |
324 for (int i = 0; i < exprs->length(); ++i) { | 332 for (int i = 0; i < exprs->length(); ++i) { |
325 VisitForValue(exprs->at(i)); | 333 VisitForValue(exprs->at(i)); |
326 } | 334 } |
327 } | 335 } |
328 | 336 |
329 | 337 |
330 void AstGraphBuilder::VisitForValue(Expression* expr) { | 338 void AstGraphBuilder::VisitForValue(Expression* expr) { |
331 AstValueContext for_value(this); | 339 AstValueContext for_value(this); |
332 if (!CheckStackOverflow()) { | 340 if (!CheckStackOverflow()) { |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
462 | 470 |
463 | 471 |
464 void AstGraphBuilder::VisitBlock(Block* stmt) { | 472 void AstGraphBuilder::VisitBlock(Block* stmt) { |
465 BlockBuilder block(this); | 473 BlockBuilder block(this); |
466 BreakableScope scope(this, stmt, &block, 0); | 474 BreakableScope scope(this, stmt, &block, 0); |
467 if (stmt->labels() != NULL) block.BeginBlock(); | 475 if (stmt->labels() != NULL) block.BeginBlock(); |
468 if (stmt->scope() == NULL) { | 476 if (stmt->scope() == NULL) { |
469 // Visit statements in the same scope, no declarations. | 477 // Visit statements in the same scope, no declarations. |
470 VisitStatements(stmt->statements()); | 478 VisitStatements(stmt->statements()); |
471 } else { | 479 } else { |
472 const Operator* op = javascript()->CreateBlockContext(); | 480 // Visit declarations and statements in a block scope. |
473 Node* scope_info = jsgraph()->Constant(stmt->scope()->GetScopeInfo()); | 481 Node* context = BuildLocalBlockContext(stmt->scope()); |
474 Node* context = NewNode(op, scope_info, GetFunctionClosure()); | |
475 ContextScope scope(this, stmt->scope(), context); | 482 ContextScope scope(this, stmt->scope(), context); |
476 | |
477 // Visit declarations and statements in a block scope. | |
478 VisitDeclarations(stmt->scope()->declarations()); | 483 VisitDeclarations(stmt->scope()->declarations()); |
479 VisitStatements(stmt->statements()); | 484 VisitStatements(stmt->statements()); |
480 } | 485 } |
481 if (stmt->labels() != NULL) block.EndBlock(); | 486 if (stmt->labels() != NULL) block.EndBlock(); |
482 } | 487 } |
483 | 488 |
484 | 489 |
485 void AstGraphBuilder::VisitModuleStatement(ModuleStatement* stmt) { | 490 void AstGraphBuilder::VisitModuleStatement(ModuleStatement* stmt) { |
486 UNREACHABLE(); | 491 UNREACHABLE(); |
487 } | 492 } |
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
827 // Create node to instantiate a new closure. | 832 // Create node to instantiate a new closure. |
828 Node* info = jsgraph()->Constant(shared_info); | 833 Node* info = jsgraph()->Constant(shared_info); |
829 Node* pretenure = jsgraph()->BooleanConstant(expr->pretenure()); | 834 Node* pretenure = jsgraph()->BooleanConstant(expr->pretenure()); |
830 const Operator* op = javascript()->CallRuntime(Runtime::kNewClosure, 3); | 835 const Operator* op = javascript()->CallRuntime(Runtime::kNewClosure, 3); |
831 Node* value = NewNode(op, context, info, pretenure); | 836 Node* value = NewNode(op, context, info, pretenure); |
832 ast_context()->ProduceValue(value); | 837 ast_context()->ProduceValue(value); |
833 } | 838 } |
834 | 839 |
835 | 840 |
836 void AstGraphBuilder::VisitClassLiteral(ClassLiteral* expr) { | 841 void AstGraphBuilder::VisitClassLiteral(ClassLiteral* expr) { |
837 UNREACHABLE(); | 842 if (expr->scope() == NULL) { |
843 // Visit class literal in the same scope, no declarations. | |
844 VisitClassLiteralContents(expr); | |
845 } else { | |
846 // Visit declarations and class literal in a block scope. | |
847 Node* context = BuildLocalBlockContext(expr->scope()); | |
848 ContextScope scope(this, expr->scope(), context); | |
849 VisitDeclarations(expr->scope()->declarations()); | |
850 VisitClassLiteralContents(expr); | |
851 } | |
838 } | 852 } |
839 | 853 |
840 | 854 |
855 void AstGraphBuilder::VisitClassLiteralContents(ClassLiteral* expr) { | |
856 Node* class_name = expr->raw_name() ? jsgraph()->Constant(expr->name()) | |
857 : jsgraph()->UndefinedConstant(); | |
858 | |
859 // The class name is expected on the operand stack. | |
860 environment()->Push(class_name); | |
861 VisitForValueOrTheHole(expr->extends()); | |
862 VisitForValue(expr->constructor()); | |
863 | |
864 // Create node to instantiate a new class. | |
865 Node* constructor = environment()->Pop(); | |
866 Node* extends = environment()->Pop(); | |
867 Node* name = environment()->Pop(); | |
868 Node* script = jsgraph()->Constant(info()->script()); | |
869 Node* start = jsgraph()->Constant(expr->start_position()); | |
870 Node* end = jsgraph()->Constant(expr->end_position()); | |
871 const Operator* opc = javascript()->CallRuntime(Runtime::kDefineClass, 6); | |
872 Node* literal = NewNode(opc, name, extends, constructor, script, start, end); | |
873 | |
874 // The prototype is ensured to exist by Runtime_DefineClass. No access check | |
875 // is needed here since the constructor is created by the class literal. | |
876 Node* proto = | |
877 BuildLoadObjectField(literal, JSFunction::kPrototypeOrInitialMapOffset); | |
878 | |
879 // The class literal and the prototype are both expected on the operand stack | |
880 // during evaluation of the method values. | |
881 environment()->Push(literal); | |
882 environment()->Push(proto); | |
883 | |
884 // Create nodes to store method values into the literal. | |
885 for (int i = 0; i < expr->properties()->length(); i++) { | |
886 ObjectLiteral::Property* property = expr->properties()->at(i); | |
887 environment()->Push(property->is_static() ? literal : proto); | |
888 | |
889 VisitForValue(property->key()); | |
890 VisitForValue(property->value()); | |
891 Node* value = environment()->Pop(); | |
892 Node* key = environment()->Pop(); | |
893 Node* receiver = environment()->Pop(); | |
894 switch (property->kind()) { | |
895 case ObjectLiteral::Property::CONSTANT: | |
896 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | |
897 case ObjectLiteral::Property::COMPUTED: | |
898 case ObjectLiteral::Property::PROTOTYPE: { | |
rossberg
2015/01/15 15:31:19
It seems to me that none but MATERIALIZED_LITERAL
arv (Not doing code reviews)
2015/01/15 16:12:24
I believe PROTOTYPE can happen too
class C {
__
rossberg
2015/01/15 16:35:11
That is just considered a regular method definitio
arv (Not doing code reviews)
2015/01/15 16:51:02
The AST only checks the value of the property name
Michael Starzinger
2015/01/16 09:43:54
Done. Made CONSTANT and MATERIALIZED_LITERAL unrea
arv (Not doing code reviews)
2015/01/16 14:42:07
I'll take care of this in a follow up CL
| |
899 const Operator* op = | |
900 javascript()->CallRuntime(Runtime::kDefineClassMethod, 3); | |
901 NewNode(op, receiver, key, value); | |
902 break; | |
903 } | |
904 case ObjectLiteral::Property::GETTER: { | |
905 const Operator* op = | |
906 javascript()->CallRuntime(Runtime::kDefineClassGetter, 3); | |
907 NewNode(op, receiver, key, value); | |
908 break; | |
909 } | |
910 case ObjectLiteral::Property::SETTER: { | |
911 const Operator* op = | |
912 javascript()->CallRuntime(Runtime::kDefineClassSetter, 3); | |
913 NewNode(op, receiver, key, value); | |
914 break; | |
915 } | |
916 } | |
917 | |
918 // TODO(mstarzinger): This is temporary to make "super" work and replicates | |
919 // the existing FullCodeGenerator::NeedsHomeObject predicate. | |
920 if (FunctionLiteral::NeedsHomeObject(property->value())) { | |
921 Unique<Name> name = | |
922 MakeUnique(isolate()->factory()->home_object_symbol()); | |
923 NewNode(javascript()->StoreNamed(strict_mode(), name), value, receiver); | |
924 } | |
925 } | |
926 | |
927 // Transform both the class literal and the prototype to fast properties. | |
928 const Operator* op = javascript()->CallRuntime(Runtime::kToFastProperties, 1); | |
929 NewNode(op, environment()->Pop()); // prototype | |
930 NewNode(op, environment()->Pop()); // literal | |
931 | |
932 // Assign to class variable. | |
933 if (expr->scope() != NULL) { | |
934 DCHECK_NOT_NULL(expr->class_variable_proxy()); | |
935 Variable* var = expr->class_variable_proxy()->var(); | |
936 BuildVariableAssignment(var, literal, Token::INIT_CONST, BailoutId::None()); | |
937 } | |
938 | |
939 ast_context()->ProduceValue(literal); | |
940 } | |
941 | |
942 | |
841 void AstGraphBuilder::VisitNativeFunctionLiteral(NativeFunctionLiteral* expr) { | 943 void AstGraphBuilder::VisitNativeFunctionLiteral(NativeFunctionLiteral* expr) { |
842 UNREACHABLE(); | 944 UNREACHABLE(); |
843 } | 945 } |
844 | 946 |
845 | 947 |
846 void AstGraphBuilder::VisitConditional(Conditional* expr) { | 948 void AstGraphBuilder::VisitConditional(Conditional* expr) { |
847 IfBuilder compare_if(this); | 949 IfBuilder compare_if(this); |
848 VisitForTest(expr->condition()); | 950 VisitForTest(expr->condition()); |
849 Node* condition = environment()->Pop(); | 951 Node* condition = environment()->Pop(); |
850 compare_if.If(condition); | 952 compare_if.If(condition); |
(...skipping 963 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1814 // Context variable (at bottom of the context chain). | 1916 // Context variable (at bottom of the context chain). |
1815 DCHECK_EQ(0, info()->scope()->ContextChainLength(variable->scope())); | 1917 DCHECK_EQ(0, info()->scope()->ContextChainLength(variable->scope())); |
1816 const Operator* op = javascript()->StoreContext(0, variable->index()); | 1918 const Operator* op = javascript()->StoreContext(0, variable->index()); |
1817 NewNode(op, local_context, parameter); | 1919 NewNode(op, local_context, parameter); |
1818 } | 1920 } |
1819 | 1921 |
1820 return local_context; | 1922 return local_context; |
1821 } | 1923 } |
1822 | 1924 |
1823 | 1925 |
1926 Node* AstGraphBuilder::BuildLocalBlockContext(Scope* scope) { | |
1927 Node* closure = GetFunctionClosure(); | |
1928 | |
1929 // Allocate a new local context. | |
1930 const Operator* op = javascript()->CreateBlockContext(); | |
1931 Node* scope_info = jsgraph()->Constant(scope->GetScopeInfo()); | |
1932 Node* local_context = NewNode(op, scope_info, closure); | |
1933 | |
1934 return local_context; | |
1935 } | |
1936 | |
1937 | |
1824 Node* AstGraphBuilder::BuildArgumentsObject(Variable* arguments) { | 1938 Node* AstGraphBuilder::BuildArgumentsObject(Variable* arguments) { |
1825 if (arguments == NULL) return NULL; | 1939 if (arguments == NULL) return NULL; |
1826 | 1940 |
1827 // Allocate and initialize a new arguments object. | 1941 // Allocate and initialize a new arguments object. |
1828 Node* callee = GetFunctionClosure(); | 1942 Node* callee = GetFunctionClosure(); |
1829 const Operator* op = javascript()->CallRuntime(Runtime::kNewArguments, 1); | 1943 const Operator* op = javascript()->CallRuntime(Runtime::kNewArguments, 1); |
1830 Node* object = NewNode(op, callee); | 1944 Node* object = NewNode(op, callee); |
1831 | 1945 |
1832 // Assign the object to the arguments variable. | 1946 // Assign the object to the arguments variable. |
1833 DCHECK(arguments->IsContextSlot() || arguments->IsStackAllocated()); | 1947 DCHECK(arguments->IsContextSlot() || arguments->IsStackAllocated()); |
(...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2237 | 2351 |
2238 BitVector* AstGraphBuilder::GetVariablesAssignedInLoop( | 2352 BitVector* AstGraphBuilder::GetVariablesAssignedInLoop( |
2239 IterationStatement* stmt) { | 2353 IterationStatement* stmt) { |
2240 if (loop_assignment_analysis_ == NULL) return NULL; | 2354 if (loop_assignment_analysis_ == NULL) return NULL; |
2241 return loop_assignment_analysis_->GetVariablesAssignedInLoop(stmt); | 2355 return loop_assignment_analysis_->GetVariablesAssignedInLoop(stmt); |
2242 } | 2356 } |
2243 | 2357 |
2244 } // namespace compiler | 2358 } // namespace compiler |
2245 } // namespace internal | 2359 } // namespace internal |
2246 } // namespace v8 | 2360 } // namespace v8 |
OLD | NEW |