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

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

Issue 1095113002: Refactor visitOperatorSend to used SemanticSendVisitor methods. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 5 years, 8 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 | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 2562 matching lines...) Expand 10 before | Expand all | Expand 10 after
2573 SourceLocation location = 2573 SourceLocation location =
2574 new TokenSourceLocation(sourceFile, token, sourceElement.name); 2574 new TokenSourceLocation(sourceFile, token, sourceElement.name);
2575 checkValidSourceFileLocation(location, sourceFile, token.charOffset); 2575 checkValidSourceFileLocation(location, sourceFile, token.charOffset);
2576 return location; 2576 return location;
2577 } 2577 }
2578 2578
2579 void visit(ast.Node node) { 2579 void visit(ast.Node node) {
2580 if (node != null) node.accept(this); 2580 if (node != null) node.accept(this);
2581 } 2581 }
2582 2582
2583 /// Visit [node] and pop the resulting [HInstruction].
2584 HInstruction visitAndPop(ast.Node node) {
2585 node.accept(this);
2586 return pop();
2587 }
2588
2583 visitBlock(ast.Block node) { 2589 visitBlock(ast.Block node) {
2584 assert(!isAborted()); 2590 assert(!isAborted());
2585 if (!isReachable) return; // This can only happen when inlining. 2591 if (!isReachable) return; // This can only happen when inlining.
2586 for (Link<ast.Node> link = node.statements.nodes; 2592 for (Link<ast.Node> link = node.statements.nodes;
2587 !link.isEmpty; 2593 !link.isEmpty;
2588 link = link.tail) { 2594 link = link.tail) {
2589 visit(link.head); 2595 visit(link.head);
2590 if (!isReachable) { 2596 if (!isReachable) {
2591 // The block has been aborted by a return or a throw. 2597 // The block has been aborted by a return or a throw.
2592 if (!stack.isEmpty) { 2598 if (!stack.isEmpty) {
(...skipping 559 matching lines...) Expand 10 before | Expand all | Expand 10 after
3152 () => visit(node.thenPart), 3158 () => visit(node.thenPart),
3153 node.elsePart != null ? () => visit(node.elsePart) : null); 3159 node.elsePart != null ? () => visit(node.elsePart) : null);
3154 } 3160 }
3155 3161
3156 void handleIf(ast.Node diagnosticNode, 3162 void handleIf(ast.Node diagnosticNode,
3157 void visitCondition(), void visitThen(), void visitElse()) { 3163 void visitCondition(), void visitThen(), void visitElse()) {
3158 SsaBranchBuilder branchBuilder = new SsaBranchBuilder(this, diagnosticNode); 3164 SsaBranchBuilder branchBuilder = new SsaBranchBuilder(this, diagnosticNode);
3159 branchBuilder.handleIf(visitCondition, visitThen, visitElse); 3165 branchBuilder.handleIf(visitCondition, visitThen, visitElse);
3160 } 3166 }
3161 3167
3162 void visitLogicalAndOr(ast.Send node, ast.Operator op) { 3168 @override
3169 void visitLogicalAnd(ast.Send node, ast.Node left, ast.Node right, _) {
3163 SsaBranchBuilder branchBuilder = new SsaBranchBuilder(this, node); 3170 SsaBranchBuilder branchBuilder = new SsaBranchBuilder(this, node);
3164 branchBuilder.handleLogicalAndOrWithLeftNode( 3171 branchBuilder.handleLogicalAndOrWithLeftNode(
3165 node.receiver, 3172 left,
3166 () { visit(node.argumentsNode); }, 3173 () { visit(right); },
3167 isAnd: ("&&" == op.source)); 3174 isAnd: true);
3168 } 3175 }
3169 3176
3170 void visitLogicalNot(ast.Send node) { 3177 @override
3178 void visitLogicalOr(ast.Send node, ast.Node left, ast.Node right, _) {
3179 SsaBranchBuilder branchBuilder = new SsaBranchBuilder(this, node);
3180 branchBuilder.handleLogicalAndOrWithLeftNode(
3181 left,
3182 () { visit(right); },
3183 isAnd: false);
3184 }
3185
3186 @override
3187 void visitNot(ast.Send node, ast.Node expression, _) {
3171 assert(node.argumentsNode is ast.Prefix); 3188 assert(node.argumentsNode is ast.Prefix);
3172 visit(node.receiver); 3189 visit(expression);
3173 HNot not = new HNot(popBoolified(), backend.boolType); 3190 HNot not = new HNot(popBoolified(), backend.boolType);
3174 pushWithPosition(not, node); 3191 pushWithPosition(not, node);
3175 } 3192 }
3176 3193
3177 void visitUnarySend(ast.Send node, ast.Operator op) { 3194 @override
3195 void visitUnary(ast.Send node,
3196 UnaryOperator operator,
3197 ast.Node expression,_) {
3178 assert(node.argumentsNode is ast.Prefix); 3198 assert(node.argumentsNode is ast.Prefix);
3179 visit(node.receiver); 3199 HInstruction operand = visitAndPop(expression);
3180 assert(!identical(op.token.kind, PLUS_TOKEN));
3181 HInstruction operand = pop();
3182 3200
3183 // See if we can constant-fold right away. This avoids rewrites later on. 3201 // See if we can constant-fold right away. This avoids rewrites later on.
3184 if (operand is HConstant) { 3202 if (operand is HConstant) {
3185 UnaryOperation operation = constantSystem.lookupUnary( 3203 UnaryOperation operation = constantSystem.lookupUnary(operator);
3186 UnaryOperator.parse(op.source));
3187 HConstant constant = operand; 3204 HConstant constant = operand;
3188 ConstantValue folded = operation.fold(constant.constant); 3205 ConstantValue folded = operation.fold(constant.constant);
3189 if (folded != null) { 3206 if (folded != null) {
3190 stack.add(graph.addConstant(folded, compiler)); 3207 stack.add(graph.addConstant(folded, compiler));
3191 return; 3208 return;
3192 } 3209 }
3193 } 3210 }
3194 3211
3195 pushInvokeDynamic(node, elements.getSelector(node), [operand]); 3212 pushInvokeDynamic(node, elements.getSelector(node), [operand]);
3196 } 3213 }
3197 3214
3215 @override
3216 void visitBinary(ast.Send node,
3217 ast.Node left,
3218 BinaryOperator operator,
3219 ast.Node right, _) {
3220 handleBinary(node, left, right);
3221 }
3222
3223 @override
3224 void visitIndex(ast.Send node, ast.Node receiver, ast.Node index, _) {
3225 // TODO(johnniwinther): Add a new helper to join the paths used by
3226 // [visitIndex], [visitDynamicSend] and [handleSendSet].
3227 visitDynamicSend(node);
3228 }
3229
3230 @override
3231 void visitEquals(ast.Send node, ast.Node left, ast.Node right, _) {
3232 handleBinary(node, left, right);
3233 }
3234
3235 @override
3236 void visitNotEquals(ast.Send node, ast.Node left, ast.Node right, _) {
3237 handleBinary(node, left, right);
3238 pushWithPosition(new HNot(popBoolified(), backend.boolType), node.selector);
3239 }
3240
3241 void handleBinary(ast.Send node, ast.Node left, ast.Node right) {
3242 visitBinarySend(
3243 visitAndPop(left),
3244 visitAndPop(right),
3245 elements.getSelector(node),
3246 node,
3247 location: node.selector);
3248 }
3249
3250 /// TODO(johnniwinther): Merge [visitBinarySend] with [handleBinary] and
3251 /// remove use of [location] for source information.
3198 void visitBinarySend(HInstruction left, 3252 void visitBinarySend(HInstruction left,
3199 ast.Operator op,
3200 HInstruction right, 3253 HInstruction right,
3201 Selector selector, 3254 Selector selector,
3202 ast.Send send) { 3255 ast.Send send,
3203 switch (op.source) { 3256 {ast.Node location}) {
3204 case "===": 3257 pushInvokeDynamic(send, selector, [left, right], location: location);
3205 pushWithPosition(
3206 new HIdentity(left, right, null, backend.boolType), op);
3207 return;
3208 case "!==":
3209 HIdentity eq = new HIdentity(left, right, null, backend.boolType);
3210 add(eq);
3211 pushWithPosition(new HNot(eq, backend.boolType), op);
3212 return;
3213 }
3214
3215 pushInvokeDynamic(send, selector, [left, right], location: op);
3216 if (op.source == '!=') {
3217 pushWithPosition(new HNot(popBoolified(), backend.boolType), op);
3218 }
3219 } 3258 }
3220 3259
3221 HInstruction generateInstanceSendReceiver(ast.Send send) { 3260 HInstruction generateInstanceSendReceiver(ast.Send send) {
3222 assert(Elements.isInstanceSend(send, elements)); 3261 assert(Elements.isInstanceSend(send, elements));
3223 if (send.receiver == null) { 3262 if (send.receiver == null) {
3224 return localsHandler.readThis(); 3263 return localsHandler.readThis();
3225 } 3264 }
3226 visit(send.receiver); 3265 visit(send.receiver);
3227 return pop(); 3266 return pop();
3228 } 3267 }
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after
3470 // template manager build them. 3509 // template manager build them.
3471 js.Template code = js.js.uncachedExpressionTemplate(template); 3510 js.Template code = js.js.uncachedExpressionTemplate(template);
3472 HInstruction representation = 3511 HInstruction representation =
3473 new HForeignCode(code, backend.readableArrayType, inputs, 3512 new HForeignCode(code, backend.readableArrayType, inputs,
3474 nativeBehavior: native.NativeBehavior.PURE_ALLOCATION); 3513 nativeBehavior: native.NativeBehavior.PURE_ALLOCATION);
3475 return representation; 3514 return representation;
3476 } 3515 }
3477 } 3516 }
3478 3517
3479 visitOperatorSend(ast.Send node) { 3518 visitOperatorSend(ast.Send node) {
3480 ast.Operator op = node.selector; 3519 internalError(node, 'Unexpected operator send: ${node}');
3481 if ("[]" == op.source) { 3520 }
3482 visitDynamicSend(node); 3521
3483 } else if ("&&" == op.source || 3522 @override
3484 "||" == op.source) { 3523 void visitAs(ast.Send node, ast.Node expression, DartType type, _) {
3485 visitLogicalAndOr(node, op); 3524 HInstruction expressionInstruction = visitAndPop(expression);
3486 } else if ("!" == op.source) { 3525 if (type.isMalformed) {
3487 visitLogicalNot(node); 3526 ErroneousElement element = type.element;
3488 } else if (node.argumentsNode is ast.Prefix) { 3527 generateTypeError(node, element.message);
3489 visitUnarySend(node, op);
3490 } else if ("is" == op.source) {
3491 visitIsSend(node);
3492 } else if ("as" == op.source) {
3493 visit(node.receiver);
3494 HInstruction expression = pop();
3495 DartType type = elements.getType(node.typeAnnotationFromIsCheckOrCast);
3496 if (type.isMalformed) {
3497 ErroneousElement element = type.element;
3498 generateTypeError(node, element.message);
3499 } else {
3500 HInstruction converted = buildTypeConversion(
3501 expression,
3502 localsHandler.substInContext(type),
3503 HTypeConversion.CAST_TYPE_CHECK);
3504 if (converted != expression) add(converted);
3505 stack.add(converted);
3506 }
3507 } else { 3528 } else {
3508 visit(node.receiver); 3529 HInstruction converted = buildTypeConversion(
3509 visit(node.argumentsNode); 3530 expressionInstruction,
3510 var right = pop(); 3531 localsHandler.substInContext(type),
3511 var left = pop(); 3532 HTypeConversion.CAST_TYPE_CHECK);
3512 visitBinarySend(left, op, right, elements.getSelector(node), node); 3533 if (converted != expressionInstruction) add(converted);
3534 stack.add(converted);
3513 } 3535 }
3514 } 3536 }
3515 3537
3516 void visitIsSend(ast.Send node) { 3538 @override
3517 visit(node.receiver); 3539 void visitIs(ast.Send node, ast.Node expression, DartType type, _) {
3518 HInstruction expression = pop(); 3540 HInstruction expressionInstruction = visitAndPop(expression);
3519 bool isNot = node.isIsNotCheck; 3541 push(buildIsNode(node, type, expressionInstruction));
3520 DartType type = elements.getType(node.typeAnnotationFromIsCheckOrCast); 3542 }
3521 HInstruction instruction = buildIsNode(node, type, expression); 3543
3522 if (isNot) { 3544 @override
3523 add(instruction); 3545 void visitIsNot(ast.Send node, ast.Node expression, DartType type, _) {
3524 instruction = new HNot(instruction, backend.boolType); 3546 HInstruction expressionInstruction = visitAndPop(expression);
3525 } 3547 HInstruction instruction = buildIsNode(node, type, expressionInstruction);
3526 push(instruction); 3548 add(instruction);
3549 push(new HNot(instruction, backend.boolType));
3527 } 3550 }
3528 3551
3529 HInstruction buildIsNode(ast.Node node, 3552 HInstruction buildIsNode(ast.Node node,
3530 DartType type, 3553 DartType type,
3531 HInstruction expression) { 3554 HInstruction expression) {
3532 type = localsHandler.substInContext(type).unalias(compiler); 3555 type = localsHandler.substInContext(type).unalias(compiler);
3533 if (type.isFunctionType) { 3556 if (type.isFunctionType) {
3534 List arguments = [buildFunctionType(type), expression]; 3557 List arguments = [buildFunctionType(type), expression];
3535 pushInvokeDynamic( 3558 pushInvokeDynamic(
3536 node, new Selector.call('_isTest', backend.jsHelperLibrary, 1), 3559 node, new Selector.call('_isTest', backend.jsHelperLibrary, 1),
(...skipping 1454 matching lines...) Expand 10 before | Expand all | Expand 10 after
4991 HInstruction receiver, 5014 HInstruction receiver,
4992 Link<ast.Node> arguments) { 5015 Link<ast.Node> arguments) {
4993 HInstruction rhs; 5016 HInstruction rhs;
4994 if (node.isPrefix || node.isPostfix) { 5017 if (node.isPrefix || node.isPostfix) {
4995 rhs = graph.addConstantInt(1, compiler); 5018 rhs = graph.addConstantInt(1, compiler);
4996 } else { 5019 } else {
4997 visit(arguments.head); 5020 visit(arguments.head);
4998 assert(arguments.tail.isEmpty); 5021 assert(arguments.tail.isEmpty);
4999 rhs = pop(); 5022 rhs = pop();
5000 } 5023 }
5001 visitBinarySend(receiver, node.assignmentOperator, rhs, 5024 visitBinarySend(receiver, rhs,
5002 elements.getOperatorSelectorInComplexSendSet(node), node); 5025 elements.getOperatorSelectorInComplexSendSet(node),
5026 node,
5027 location: node.assignmentOperator);
5003 } 5028 }
5004 5029
5005 @override 5030 @override
5006 handleSendSet(ast.SendSet node) { 5031 handleSendSet(ast.SendSet node) {
5007 generateIsDeferredLoadedCheckIfNeeded(node); 5032 generateIsDeferredLoadedCheckIfNeeded(node);
5008 Element element = elements[node]; 5033 Element element = elements[node];
5009 if (!Elements.isUnresolved(element) && element.impliesType) { 5034 if (!Elements.isUnresolved(element) && element.impliesType) {
5010 ast.Identifier selector = node.selector; 5035 ast.Identifier selector = node.selector;
5011 generateThrowNoSuchMethod(node, selector.source, 5036 generateThrowNoSuchMethod(node, selector.source,
5012 argumentNodes: node.arguments); 5037 argumentNodes: node.arguments);
(...skipping 2024 matching lines...) Expand 10 before | Expand all | Expand 10 after
7037 if (unaliased is TypedefType) throw 'unable to unalias $type'; 7062 if (unaliased is TypedefType) throw 'unable to unalias $type';
7038 unaliased.accept(this, builder); 7063 unaliased.accept(this, builder);
7039 } 7064 }
7040 7065
7041 void visitDynamicType(DynamicType type, SsaBuilder builder) { 7066 void visitDynamicType(DynamicType type, SsaBuilder builder) {
7042 JavaScriptBackend backend = builder.compiler.backend; 7067 JavaScriptBackend backend = builder.compiler.backend;
7043 ClassElement cls = backend.findHelper('DynamicRuntimeType'); 7068 ClassElement cls = backend.findHelper('DynamicRuntimeType');
7044 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld))); 7069 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld)));
7045 } 7070 }
7046 } 7071 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698