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

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

Issue 798873006: First simple implementation of class literals in TurboFan. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebased. Created 5 years, 11 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
« no previous file with comments | « src/compiler/ast-graph-builder.h ('k') | src/compiler/pipeline.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/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
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
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 347 matching lines...) Expand 10 before | Expand all | Expand 10 after
835 // Create node to instantiate a new closure. 840 // Create node to instantiate a new closure.
836 Node* info = jsgraph()->Constant(shared_info); 841 Node* info = jsgraph()->Constant(shared_info);
837 Node* pretenure = jsgraph()->BooleanConstant(expr->pretenure()); 842 Node* pretenure = jsgraph()->BooleanConstant(expr->pretenure());
838 const Operator* op = javascript()->CallRuntime(Runtime::kNewClosure, 3); 843 const Operator* op = javascript()->CallRuntime(Runtime::kNewClosure, 3);
839 Node* value = NewNode(op, context, info, pretenure); 844 Node* value = NewNode(op, context, info, pretenure);
840 ast_context()->ProduceValue(value); 845 ast_context()->ProduceValue(value);
841 } 846 }
842 847
843 848
844 void AstGraphBuilder::VisitClassLiteral(ClassLiteral* expr) { 849 void AstGraphBuilder::VisitClassLiteral(ClassLiteral* expr) {
845 UNREACHABLE(); 850 if (expr->scope() == NULL) {
851 // Visit class literal in the same scope, no declarations.
852 VisitClassLiteralContents(expr);
853 } else {
854 // Visit declarations and class literal in a block scope.
855 Node* context = BuildLocalBlockContext(expr->scope());
856 ContextScope scope(this, expr->scope(), context);
857 VisitDeclarations(expr->scope()->declarations());
858 VisitClassLiteralContents(expr);
859 }
846 } 860 }
847 861
848 862
863 void AstGraphBuilder::VisitClassLiteralContents(ClassLiteral* expr) {
864 Node* class_name = expr->raw_name() ? jsgraph()->Constant(expr->name())
865 : jsgraph()->UndefinedConstant();
866
867 // The class name is expected on the operand stack.
868 environment()->Push(class_name);
869 VisitForValueOrTheHole(expr->extends());
870 VisitForValue(expr->constructor());
871
872 // Create node to instantiate a new class.
873 Node* constructor = environment()->Pop();
874 Node* extends = environment()->Pop();
875 Node* name = environment()->Pop();
876 Node* script = jsgraph()->Constant(info()->script());
877 Node* start = jsgraph()->Constant(expr->start_position());
878 Node* end = jsgraph()->Constant(expr->end_position());
879 const Operator* opc = javascript()->CallRuntime(Runtime::kDefineClass, 6);
880 Node* literal = NewNode(opc, name, extends, constructor, script, start, end);
881
882 // The prototype is ensured to exist by Runtime_DefineClass. No access check
883 // is needed here since the constructor is created by the class literal.
884 Node* proto =
885 BuildLoadObjectField(literal, JSFunction::kPrototypeOrInitialMapOffset);
886
887 // The class literal and the prototype are both expected on the operand stack
888 // during evaluation of the method values.
889 environment()->Push(literal);
890 environment()->Push(proto);
891
892 // Create nodes to store method values into the literal.
893 for (int i = 0; i < expr->properties()->length(); i++) {
894 ObjectLiteral::Property* property = expr->properties()->at(i);
895 environment()->Push(property->is_static() ? literal : proto);
896
897 VisitForValue(property->key());
898 VisitForValue(property->value());
899 Node* value = environment()->Pop();
900 Node* key = environment()->Pop();
901 Node* receiver = environment()->Pop();
902 switch (property->kind()) {
903 case ObjectLiteral::Property::CONSTANT:
904 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
905 UNREACHABLE();
906 case ObjectLiteral::Property::COMPUTED:
907 case ObjectLiteral::Property::PROTOTYPE: {
908 const Operator* op =
909 javascript()->CallRuntime(Runtime::kDefineClassMethod, 3);
910 NewNode(op, receiver, key, value);
911 break;
912 }
913 case ObjectLiteral::Property::GETTER: {
914 const Operator* op = javascript()->CallRuntime(
915 Runtime::kDefineGetterPropertyUnchecked, 3);
916 NewNode(op, receiver, key, value);
917 break;
918 }
919 case ObjectLiteral::Property::SETTER: {
920 const Operator* op = javascript()->CallRuntime(
921 Runtime::kDefineSetterPropertyUnchecked, 3);
922 NewNode(op, receiver, key, value);
923 break;
924 }
925 }
926
927 // TODO(mstarzinger): This is temporary to make "super" work and replicates
928 // the existing FullCodeGenerator::NeedsHomeObject predicate.
929 if (FunctionLiteral::NeedsHomeObject(property->value())) {
930 Unique<Name> name =
931 MakeUnique(isolate()->factory()->home_object_symbol());
932 NewNode(javascript()->StoreNamed(strict_mode(), name), value, receiver);
933 }
934 }
935
936 // Transform both the class literal and the prototype to fast properties.
937 const Operator* op = javascript()->CallRuntime(Runtime::kToFastProperties, 1);
938 NewNode(op, environment()->Pop()); // prototype
939 NewNode(op, environment()->Pop()); // literal
940
941 // Assign to class variable.
942 if (expr->scope() != NULL) {
943 DCHECK_NOT_NULL(expr->class_variable_proxy());
944 Variable* var = expr->class_variable_proxy()->var();
945 BuildVariableAssignment(var, literal, Token::INIT_CONST, BailoutId::None());
946 }
947
948 ast_context()->ProduceValue(literal);
949 }
950
951
849 void AstGraphBuilder::VisitNativeFunctionLiteral(NativeFunctionLiteral* expr) { 952 void AstGraphBuilder::VisitNativeFunctionLiteral(NativeFunctionLiteral* expr) {
850 UNREACHABLE(); 953 UNREACHABLE();
851 } 954 }
852 955
853 956
854 void AstGraphBuilder::VisitConditional(Conditional* expr) { 957 void AstGraphBuilder::VisitConditional(Conditional* expr) {
855 IfBuilder compare_if(this); 958 IfBuilder compare_if(this);
856 VisitForTest(expr->condition()); 959 VisitForTest(expr->condition());
857 Node* condition = environment()->Pop(); 960 Node* condition = environment()->Pop();
858 compare_if.If(condition); 961 compare_if.If(condition);
(...skipping 963 matching lines...) Expand 10 before | Expand all | Expand 10 after
1822 // Context variable (at bottom of the context chain). 1925 // Context variable (at bottom of the context chain).
1823 DCHECK_EQ(0, info()->scope()->ContextChainLength(variable->scope())); 1926 DCHECK_EQ(0, info()->scope()->ContextChainLength(variable->scope()));
1824 const Operator* op = javascript()->StoreContext(0, variable->index()); 1927 const Operator* op = javascript()->StoreContext(0, variable->index());
1825 NewNode(op, local_context, parameter); 1928 NewNode(op, local_context, parameter);
1826 } 1929 }
1827 1930
1828 return local_context; 1931 return local_context;
1829 } 1932 }
1830 1933
1831 1934
1935 Node* AstGraphBuilder::BuildLocalBlockContext(Scope* scope) {
1936 Node* closure = GetFunctionClosure();
1937
1938 // Allocate a new local context.
1939 const Operator* op = javascript()->CreateBlockContext();
1940 Node* scope_info = jsgraph()->Constant(scope->GetScopeInfo());
1941 Node* local_context = NewNode(op, scope_info, closure);
1942
1943 return local_context;
1944 }
1945
1946
1832 Node* AstGraphBuilder::BuildArgumentsObject(Variable* arguments) { 1947 Node* AstGraphBuilder::BuildArgumentsObject(Variable* arguments) {
1833 if (arguments == NULL) return NULL; 1948 if (arguments == NULL) return NULL;
1834 1949
1835 // Allocate and initialize a new arguments object. 1950 // Allocate and initialize a new arguments object.
1836 Node* callee = GetFunctionClosure(); 1951 Node* callee = GetFunctionClosure();
1837 const Operator* op = javascript()->CallRuntime(Runtime::kNewArguments, 1); 1952 const Operator* op = javascript()->CallRuntime(Runtime::kNewArguments, 1);
1838 Node* object = NewNode(op, callee); 1953 Node* object = NewNode(op, callee);
1839 1954
1840 // Assign the object to the arguments variable. 1955 // Assign the object to the arguments variable.
1841 DCHECK(arguments->IsContextSlot() || arguments->IsStackAllocated()); 1956 DCHECK(arguments->IsContextSlot() || arguments->IsStackAllocated());
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after
2242 2357
2243 BitVector* AstGraphBuilder::GetVariablesAssignedInLoop( 2358 BitVector* AstGraphBuilder::GetVariablesAssignedInLoop(
2244 IterationStatement* stmt) { 2359 IterationStatement* stmt) {
2245 if (loop_assignment_analysis_ == NULL) return NULL; 2360 if (loop_assignment_analysis_ == NULL) return NULL;
2246 return loop_assignment_analysis_->GetVariablesAssignedInLoop(stmt); 2361 return loop_assignment_analysis_->GetVariablesAssignedInLoop(stmt);
2247 } 2362 }
2248 2363
2249 } // namespace compiler 2364 } // namespace compiler
2250 } // namespace internal 2365 } // namespace internal
2251 } // namespace v8 2366 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/ast-graph-builder.h ('k') | src/compiler/pipeline.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698