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

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

Powered by Google App Engine
This is Rietveld 408576698