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

Side by Side Diff: dart/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart

Issue 50313007: Implement dynamic function checks. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Merged with r30787 Created 7 years 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 SsaCodeGeneratorTask extends CompilerTask { 7 class SsaCodeGeneratorTask extends CompilerTask {
8 8
9 final JavaScriptBackend backend; 9 final JavaScriptBackend backend;
10 10
(...skipping 2515 matching lines...) Expand 10 before | Expand all | Expand 10 after
2526 assert(type.kind != TypeKind.TYPEDEF); 2526 assert(type.kind != TypeKind.TYPEDEF);
2527 if (type.kind == TypeKind.FUNCTION) { 2527 if (type.kind == TypeKind.FUNCTION) {
2528 // TODO(5022): We currently generate $isFunction checks for 2528 // TODO(5022): We currently generate $isFunction checks for
2529 // function types. 2529 // function types.
2530 world.registerIsCheck( 2530 world.registerIsCheck(
2531 compiler.functionClass.computeType(compiler), work.resolutionTree); 2531 compiler.functionClass.computeType(compiler), work.resolutionTree);
2532 } 2532 }
2533 world.registerIsCheck(type, work.resolutionTree); 2533 world.registerIsCheck(type, work.resolutionTree);
2534 2534
2535 CheckedModeHelper helper; 2535 CheckedModeHelper helper;
2536 FunctionElement helperElement;
2537 if (node.isBooleanConversionCheck) { 2536 if (node.isBooleanConversionCheck) {
2538 helper = 2537 helper =
2539 const CheckedModeHelper('boolConversionCheck'); 2538 const CheckedModeHelper('boolConversionCheck');
2540 } else { 2539 } else {
2541 helper = 2540 helper =
2542 backend.getCheckedModeHelper(type, typeCast: node.isCastTypeCheck); 2541 backend.getCheckedModeHelper(type, typeCast: node.isCastTypeCheck);
2543 } 2542 }
2544 2543
2545 push(helper.generateCall(this, node)); 2544 if (helper == null) {
2545 assert(type.kind == TypeKind.FUNCTION);
2546 use(node.inputs[0]);
2547 } else {
2548 push(helper.generateCall(this, node));
2549 }
2546 } 2550 }
2547 2551
2548 void visitTypeKnown(HTypeKnown node) { 2552 void visitTypeKnown(HTypeKnown node) {
2549 // [HTypeKnown] instructions are removed before generating code. 2553 // [HTypeKnown] instructions are removed before generating code.
2550 assert(false); 2554 assert(false);
2551 } 2555 }
2556
2557 void visitFunctionType(HFunctionType node) {
2558 FunctionType type = node.dartType;
2559 int inputCount = 0;
2560 use(node.inputs[inputCount++]);
2561 js.Expression returnType = pop();
2562
2563 List<js.Expression> parameterTypes = <js.Expression>[];
2564 for (var _ in type.parameterTypes) {
2565 use(node.inputs[inputCount++]);
2566 parameterTypes.add(pop());
2567 }
2568
2569 List<js.Expression> optionalParameterTypes = <js.Expression>[];
2570 for (var _ in type.optionalParameterTypes) {
2571 use(node.inputs[inputCount++]);
2572 optionalParameterTypes.add(pop());
2573 }
2574
2575 List<js.Property> namedParameters = <js.Property>[];
2576 for (var _ in type.namedParameters) {
2577 use(node.inputs[inputCount++]);
2578 js.Expression name = pop();
2579 use(node.inputs[inputCount++]);
2580 namedParameters.add(new js.Property(name, pop()));
2581 }
2582
2583 if (namedParameters.isEmpty) {
2584 var arguments = [returnType];
2585 if (!parameterTypes.isEmpty || !optionalParameterTypes.isEmpty) {
2586 arguments.add(new js.ArrayInitializer.from(parameterTypes));
2587 }
2588 if (!optionalParameterTypes.isEmpty) {
2589 arguments.add(new js.ArrayInitializer.from(optionalParameterTypes));
2590 }
2591 push(accessHelper('buildFunctionType')(arguments));
2592 } else {
2593 var arguments = [
2594 returnType,
2595 new js.ArrayInitializer.from(parameterTypes),
2596 new js.ObjectInitializer(namedParameters)];
2597 push(accessHelper('buildNamedFunctionType')(arguments));
2598 }
2599 }
2600
2601 void visitReadTypeVariable(HReadTypeVariable node) {
2602 TypeVariableElement element = node.dartType.element;
2603 Element helperElement = compiler.findHelper('convertRtiToRuntimeType');
2604 world.registerStaticUse(helperElement);
2605
2606 use(node.inputs[0]);
2607 if (node.hasReceiver) {
2608 if (backend.isInterceptorClass(element.getEnclosingClass())) {
2609 int index = RuntimeTypes.getTypeVariableIndex(element);
2610 js.Expression receiver = pop();
2611 js.Expression helper = backend.namer.elementAccess(helperElement);
2612 push(helper(js.js(r'#.$builtinTypeInfo && #.$builtinTypeInfo[#]',
2613 [receiver, receiver, js.js.toExpression(index)])));
2614 } else {
2615 backend.emitter.registerReadTypeVariable(element);
2616 push(
2617 js.js('#.${backend.namer.readTypeVariableName(element)}()', pop()));
2618 }
2619 } else {
2620 push(
2621 backend.namer.elementAccess(
2622 compiler.findHelper('convertRtiToRuntimeType'))(pop()));
2623 }
2624 }
2625
2626 void visitInterfaceType(HInterfaceType node) {
2627 List<js.Expression> typeArguments = <js.Expression>[];
2628 for (HInstruction type in node.inputs) {
2629 use(type);
2630 typeArguments.add(pop());
2631 }
2632
2633 ClassElement cls = node.dartType.element;
2634 var arguments = [
2635 backend.namer.elementAccess(backend.getImplementationClass(cls))];
2636 if (!typeArguments.isEmpty) {
2637 arguments.add(new js.ArrayInitializer.from(typeArguments));
2638 }
2639 push(accessHelper('buildInterfaceType')(arguments));
2640 }
2641
2642 void visitVoidType(HVoidType node) {
2643 push(accessHelper('getVoidRuntimeType')());
2644 }
2645
2646 void visitDynamicType(HDynamicType node) {
2647 push(accessHelper('getDynamicRuntimeType')());
2648 }
2649
2650 js.PropertyAccess accessHelper(String name) {
2651 Element helper = compiler.findHelper(name);
2652 world.registerStaticUse(helper);
2653 return backend.namer.elementAccess(helper);
2654 }
2552 } 2655 }
2553 2656
2554 String singleIdentityComparison(HInstruction left, 2657 String singleIdentityComparison(HInstruction left,
2555 HInstruction right, 2658 HInstruction right,
2556 Compiler compiler) { 2659 Compiler compiler) {
2557 // Returns the single identity comparison (== or ===) or null if a more 2660 // Returns the single identity comparison (== or ===) or null if a more
2558 // complex expression is required. 2661 // complex expression is required.
2559 if ((left.isConstant() && left.isConstantSentinel()) || 2662 if ((left.isConstant() && left.isConstantSentinel()) ||
2560 (right.isConstant() && right.isConstantSentinel())) return '==='; 2663 (right.isConstant() && right.isConstantSentinel())) return '===';
2561 if (left.canBeNull() && right.canBeNull()) { 2664 if (left.canBeNull() && right.canBeNull()) {
2562 if (left.isConstantNull() || right.isConstantNull() || 2665 if (left.isConstantNull() || right.isConstantNull() ||
2563 (left.isPrimitive(compiler) && 2666 (left.isPrimitive(compiler) &&
2564 left.instructionType == right.instructionType)) { 2667 left.instructionType == right.instructionType)) {
2565 return '=='; 2668 return '==';
2566 } 2669 }
2567 return null; 2670 return null;
2568 } else { 2671 } else {
2569 return '==='; 2672 return '===';
2570 } 2673 }
2571 } 2674 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698