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

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: Split cleanup into separate CL. 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
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 339 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698