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

Side by Side Diff: pkg/compiler/lib/src/ssa/builder.dart

Issue 1030103004: Implement ResolvedVisitor using SemanticSendVisitor. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Cleanups. Created 5 years, 9 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
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 part of ssa; 5 part of ssa;
6 6
7 class SsaFunctionCompiler implements FunctionCompiler { 7 class SsaFunctionCompiler implements FunctionCompiler {
8 SsaCodeGeneratorTask generator; 8 SsaCodeGeneratorTask generator;
9 SsaBuilderTask builder; 9 SsaBuilderTask builder;
10 SsaOptimizerTask optimizer; 10 SsaOptimizerTask optimizer;
(...skipping 959 matching lines...) Expand 10 before | Expand all | Expand 10 after
970 for (JumpTarget target in targetIndexMap.keys) { 970 for (JumpTarget target in targetIndexMap.keys) {
971 builder.jumpTargets.remove(target); 971 builder.jumpTargets.remove(target);
972 } 972 }
973 super.close(); 973 super.close();
974 } 974 }
975 } 975 }
976 976
977 /** 977 /**
978 * This class builds SSA nodes for functions represented in AST. 978 * This class builds SSA nodes for functions represented in AST.
979 */ 979 */
980 class SsaBuilder extends ResolvedVisitor { 980 class SsaBuilder extends NewResolvedVisitor {
981 final Compiler compiler; 981 final Compiler compiler;
982 final JavaScriptBackend backend; 982 final JavaScriptBackend backend;
983 final ConstantSystem constantSystem; 983 final ConstantSystem constantSystem;
984 final CodegenWorkItem work; 984 final CodegenWorkItem work;
985 final RuntimeTypes rti; 985 final RuntimeTypes rti;
986 final bool generateSourceMap; 986 final bool generateSourceMap;
987 bool inLazyInitializerExpression = false; 987 bool inLazyInitializerExpression = false;
988 988
989 /* This field is used by the native handler. */ 989 /* This field is used by the native handler. */
990 final NativeEmitter nativeEmitter; 990 final NativeEmitter nativeEmitter;
(...skipping 2132 matching lines...) Expand 10 before | Expand all | Expand 10 after
3123 isAnd: ("&&" == op.source)); 3123 isAnd: ("&&" == op.source));
3124 } 3124 }
3125 3125
3126 void visitLogicalNot(ast.Send node) { 3126 void visitLogicalNot(ast.Send node) {
3127 assert(node.argumentsNode is ast.Prefix); 3127 assert(node.argumentsNode is ast.Prefix);
3128 visit(node.receiver); 3128 visit(node.receiver);
3129 HNot not = new HNot(popBoolified(), backend.boolType); 3129 HNot not = new HNot(popBoolified(), backend.boolType);
3130 pushWithPosition(not, node); 3130 pushWithPosition(not, node);
3131 } 3131 }
3132 3132
3133 void visitUnary(ast.Send node, ast.Operator op) { 3133 void visitUnarySend(ast.Send node, ast.Operator op) {
3134 assert(node.argumentsNode is ast.Prefix); 3134 assert(node.argumentsNode is ast.Prefix);
3135 visit(node.receiver); 3135 visit(node.receiver);
3136 assert(!identical(op.token.kind, PLUS_TOKEN)); 3136 assert(!identical(op.token.kind, PLUS_TOKEN));
3137 HInstruction operand = pop(); 3137 HInstruction operand = pop();
3138 3138
3139 // See if we can constant-fold right away. This avoids rewrites later on. 3139 // See if we can constant-fold right away. This avoids rewrites later on.
3140 if (operand is HConstant) { 3140 if (operand is HConstant) {
3141 UnaryOperation operation = constantSystem.lookupUnary(op.source); 3141 UnaryOperation operation = constantSystem.lookupUnary(op.source);
3142 HConstant constant = operand; 3142 HConstant constant = operand;
3143 ConstantValue folded = operation.fold(constant.constant); 3143 ConstantValue folded = operation.fold(constant.constant);
3144 if (folded != null) { 3144 if (folded != null) {
3145 stack.add(graph.addConstant(folded, compiler)); 3145 stack.add(graph.addConstant(folded, compiler));
3146 return; 3146 return;
3147 } 3147 }
3148 } 3148 }
3149 3149
3150 pushInvokeDynamic(node, elements.getSelector(node), [operand]); 3150 pushInvokeDynamic(node, elements.getSelector(node), [operand]);
3151 } 3151 }
3152 3152
3153 void visitBinary(HInstruction left, 3153 void visitBinarySend(HInstruction left,
3154 ast.Operator op, 3154 ast.Operator op,
3155 HInstruction right, 3155 HInstruction right,
3156 Selector selector, 3156 Selector selector,
3157 ast.Send send) { 3157 ast.Send send) {
3158 switch (op.source) { 3158 switch (op.source) {
3159 case "===": 3159 case "===":
3160 pushWithPosition( 3160 pushWithPosition(
3161 new HIdentity(left, right, null, backend.boolType), op); 3161 new HIdentity(left, right, null, backend.boolType), op);
3162 return; 3162 return;
3163 case "!==": 3163 case "!==":
3164 HIdentity eq = new HIdentity(left, right, null, backend.boolType); 3164 HIdentity eq = new HIdentity(left, right, null, backend.boolType);
3165 add(eq); 3165 add(eq);
3166 pushWithPosition(new HNot(eq, backend.boolType), op); 3166 pushWithPosition(new HNot(eq, backend.boolType), op);
3167 return; 3167 return;
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
3415 visitOperatorSend(ast.Send node) { 3415 visitOperatorSend(ast.Send node) {
3416 ast.Operator op = node.selector; 3416 ast.Operator op = node.selector;
3417 if ("[]" == op.source) { 3417 if ("[]" == op.source) {
3418 visitDynamicSend(node); 3418 visitDynamicSend(node);
3419 } else if ("&&" == op.source || 3419 } else if ("&&" == op.source ||
3420 "||" == op.source) { 3420 "||" == op.source) {
3421 visitLogicalAndOr(node, op); 3421 visitLogicalAndOr(node, op);
3422 } else if ("!" == op.source) { 3422 } else if ("!" == op.source) {
3423 visitLogicalNot(node); 3423 visitLogicalNot(node);
3424 } else if (node.argumentsNode is ast.Prefix) { 3424 } else if (node.argumentsNode is ast.Prefix) {
3425 visitUnary(node, op); 3425 visitUnarySend(node, op);
3426 } else if ("is" == op.source) { 3426 } else if ("is" == op.source) {
3427 visitIsSend(node); 3427 visitIsSend(node);
3428 } else if ("as" == op.source) { 3428 } else if ("as" == op.source) {
3429 visit(node.receiver); 3429 visit(node.receiver);
3430 HInstruction expression = pop(); 3430 HInstruction expression = pop();
3431 DartType type = elements.getType(node.typeAnnotationFromIsCheckOrCast); 3431 DartType type = elements.getType(node.typeAnnotationFromIsCheckOrCast);
3432 if (type.isMalformed) { 3432 if (type.isMalformed) {
3433 ErroneousElement element = type.element; 3433 ErroneousElement element = type.element;
3434 generateTypeError(node, element.message); 3434 generateTypeError(node, element.message);
3435 } else { 3435 } else {
3436 HInstruction converted = buildTypeConversion( 3436 HInstruction converted = buildTypeConversion(
3437 expression, 3437 expression,
3438 localsHandler.substInContext(type), 3438 localsHandler.substInContext(type),
3439 HTypeConversion.CAST_TYPE_CHECK); 3439 HTypeConversion.CAST_TYPE_CHECK);
3440 if (converted != expression) add(converted); 3440 if (converted != expression) add(converted);
3441 stack.add(converted); 3441 stack.add(converted);
3442 } 3442 }
3443 } else { 3443 } else {
3444 visit(node.receiver); 3444 visit(node.receiver);
3445 visit(node.argumentsNode); 3445 visit(node.argumentsNode);
3446 var right = pop(); 3446 var right = pop();
3447 var left = pop(); 3447 var left = pop();
3448 visitBinary(left, op, right, elements.getSelector(node), node); 3448 visitBinarySend(left, op, right, elements.getSelector(node), node);
3449 } 3449 }
3450 } 3450 }
3451 3451
3452 void visitIsSend(ast.Send node) { 3452 void visitIsSend(ast.Send node) {
3453 visit(node.receiver); 3453 visit(node.receiver);
3454 HInstruction expression = pop(); 3454 HInstruction expression = pop();
3455 bool isNot = node.isIsNotCheck; 3455 bool isNot = node.isIsNotCheck;
3456 DartType type = elements.getType(node.typeAnnotationFromIsCheckOrCast); 3456 DartType type = elements.getType(node.typeAnnotationFromIsCheckOrCast);
3457 HInstruction instruction = buildIsNode(node, type, expression); 3457 HInstruction instruction = buildIsNode(node, type, expression);
3458 if (isNot) { 3458 if (isNot) {
(...skipping 1068 matching lines...) Expand 10 before | Expand all | Expand 10 after
4527 DartType instance = type.asInstanceOf(supertype.element); 4527 DartType instance = type.asInstanceOf(supertype.element);
4528 compiler.types.checkTypeVariableBounds(instance, 4528 compiler.types.checkTypeVariableBounds(instance,
4529 addTypeVariableBoundCheck); 4529 addTypeVariableBoundCheck);
4530 if (definitelyFails) { 4530 if (definitelyFails) {
4531 return true; 4531 return true;
4532 } 4532 }
4533 } 4533 }
4534 return false; 4534 return false;
4535 } 4535 }
4536 4536
4537 visitAssert(node) { 4537 visitAssertSend(node) {
4538 if (!compiler.enableUserAssertions) { 4538 if (!compiler.enableUserAssertions) {
4539 stack.add(graph.addConstantNull(compiler)); 4539 stack.add(graph.addConstantNull(compiler));
4540 return; 4540 return;
4541 } 4541 }
4542 // TODO(johnniwinther): Don't handle assert like a regular static call. 4542 // TODO(johnniwinther): Don't handle assert like a regular static call.
4543 // It breaks the selector name check since the assert helper method cannot 4543 // It breaks the selector name check since the assert helper method cannot
4544 // be called `assert` and therefore does not match the selector like a 4544 // be called `assert` and therefore does not match the selector like a
4545 // regular method. 4545 // regular method.
4546 visitStaticSend(node); 4546 visitStaticSend(node);
4547 } 4547 }
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
4627 type = localsHandler.substInContext(type); 4627 type = localsHandler.substInContext(type);
4628 HInstruction value = analyzeTypeArgument(type); 4628 HInstruction value = analyzeTypeArgument(type);
4629 pushInvokeStatic(node, 4629 pushInvokeStatic(node,
4630 backend.getRuntimeTypeToString(), 4630 backend.getRuntimeTypeToString(),
4631 [value], 4631 [value],
4632 backend.stringType); 4632 backend.stringType);
4633 pushInvokeStatic(node, 4633 pushInvokeStatic(node,
4634 backend.getCreateRuntimeType(), 4634 backend.getCreateRuntimeType(),
4635 [pop()]); 4635 [pop()]);
4636 } else { 4636 } else {
4637 internalError('unexpected type kind ${type.kind}', node: node); 4637 internalError(node, 'unexpected type kind ${type.kind}');
4638 } 4638 }
4639 if (node.isCall) { 4639 if (node.isCall) {
4640 // This send is of the form 'e(...)', where e is resolved to a type 4640 // This send is of the form 'e(...)', where e is resolved to a type
4641 // reference. We create a regular closure call on the result of the type 4641 // reference. We create a regular closure call on the result of the type
4642 // reference instead of creating a NoSuchMethodError to avoid pulling it 4642 // reference instead of creating a NoSuchMethodError to avoid pulling it
4643 // in if it is not used (e.g., in a try/catch). 4643 // in if it is not used (e.g., in a try/catch).
4644 HInstruction target = pop(); 4644 HInstruction target = pop();
4645 Selector selector = elements.getSelector(node); 4645 Selector selector = elements.getSelector(node);
4646 List<HInstruction> inputs = <HInstruction>[target]; 4646 List<HInstruction> inputs = <HInstruction>[target];
4647 addDynamicSendArgumentsToList(node, inputs); 4647 addDynamicSendArgumentsToList(node, inputs);
4648 Selector closureSelector = new Selector.callClosureFrom(selector); 4648 Selector closureSelector = new Selector.callClosureFrom(selector);
4649 push(new HInvokeClosure(closureSelector, inputs, backend.dynamicType)); 4649 push(new HInvokeClosure(closureSelector, inputs, backend.dynamicType));
4650 } 4650 }
4651 } 4651 }
4652 4652
4653 visitGetterSend(ast.Send node) { 4653 visitGetterSend(ast.Send node) {
4654 generateIsDeferredLoadedCheckIfNeeded(node); 4654 generateIsDeferredLoadedCheckIfNeeded(node);
4655 generateGetter(node, elements[node]); 4655 generateGetter(node, elements[node]);
4656 } 4656 }
4657 4657
4658 // TODO(antonm): migrate rest of SsaFromAstMixin to internalError. 4658 // TODO(antonm): migrate rest of SsaFromAstMixin to internalError.
4659 internalError(String reason, {ast.Node node}) { 4659 internalError(Spannable node, String reason) {
4660 compiler.internalError(node, reason); 4660 compiler.internalError(node, reason);
4661 } 4661 }
4662 4662
4663 void generateError(ast.Node node, String message, Element helper) { 4663 void generateError(ast.Node node, String message, Element helper) {
4664 HInstruction errorMessage = addConstantString(message); 4664 HInstruction errorMessage = addConstantString(message);
4665 pushInvokeStatic(node, helper, [errorMessage]); 4665 pushInvokeStatic(node, helper, [errorMessage]);
4666 } 4666 }
4667 4667
4668 void generateRuntimeError(ast.Node node, String message) { 4668 void generateRuntimeError(ast.Node node, String message) {
4669 generateError(node, message, backend.getThrowRuntimeError()); 4669 generateError(node, message, backend.getThrowRuntimeError());
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after
4914 HInstruction receiver, 4914 HInstruction receiver,
4915 Link<ast.Node> arguments) { 4915 Link<ast.Node> arguments) {
4916 HInstruction rhs; 4916 HInstruction rhs;
4917 if (node.isPrefix || node.isPostfix) { 4917 if (node.isPrefix || node.isPostfix) {
4918 rhs = graph.addConstantInt(1, compiler); 4918 rhs = graph.addConstantInt(1, compiler);
4919 } else { 4919 } else {
4920 visit(arguments.head); 4920 visit(arguments.head);
4921 assert(arguments.tail.isEmpty); 4921 assert(arguments.tail.isEmpty);
4922 rhs = pop(); 4922 rhs = pop();
4923 } 4923 }
4924 visitBinary(receiver, node.assignmentOperator, rhs, 4924 visitBinarySend(receiver, node.assignmentOperator, rhs,
4925 elements.getOperatorSelectorInComplexSendSet(node), node); 4925 elements.getOperatorSelectorInComplexSendSet(node), node);
4926 } 4926 }
4927 4927
4928 visitSendSet(ast.SendSet node) { 4928 visitSendSet(ast.SendSet node) {
4929 generateIsDeferredLoadedCheckIfNeeded(node); 4929 generateIsDeferredLoadedCheckIfNeeded(node);
4930 Element element = elements[node]; 4930 Element element = elements[node];
4931 if (!Elements.isUnresolved(element) && element.impliesType) { 4931 if (!Elements.isUnresolved(element) && element.impliesType) {
4932 ast.Identifier selector = node.selector; 4932 ast.Identifier selector = node.selector;
4933 generateThrowNoSuchMethod(node, selector.source, 4933 generateThrowNoSuchMethod(node, selector.source,
4934 argumentNodes: node.arguments); 4934 argumentNodes: node.arguments);
4935 return; 4935 return;
(...skipping 2008 matching lines...) Expand 10 before | Expand all | Expand 10 after
6944 if (unaliased is TypedefType) throw 'unable to unalias $type'; 6944 if (unaliased is TypedefType) throw 'unable to unalias $type';
6945 unaliased.accept(this, builder); 6945 unaliased.accept(this, builder);
6946 } 6946 }
6947 6947
6948 void visitDynamicType(DynamicType type, SsaBuilder builder) { 6948 void visitDynamicType(DynamicType type, SsaBuilder builder) {
6949 JavaScriptBackend backend = builder.compiler.backend; 6949 JavaScriptBackend backend = builder.compiler.backend;
6950 ClassElement cls = backend.findHelper('DynamicRuntimeType'); 6950 ClassElement cls = backend.findHelper('DynamicRuntimeType');
6951 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld))); 6951 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld)));
6952 } 6952 }
6953 } 6953 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698