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

Side by Side Diff: pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart

Issue 1144163004: dart2js cps: Always use interceptors and type tags for 'is' checks. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Rebase + status file Created 5 years, 6 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
« no previous file with comments | « no previous file | pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart » ('j') | 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) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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 library dart2js.ir_builder; 5 library dart2js.ir_builder;
6 6
7 import '../constants/constant_system.dart'; 7 import '../constants/constant_system.dart';
8 import '../constants/expressions.dart'; 8 import '../constants/expressions.dart';
9 import '../constants/values.dart' show PrimitiveConstantValue; 9 import '../constants/values.dart' show PrimitiveConstantValue;
10 import '../dart_types.dart'; 10 import '../dart_types.dart';
(...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after
459 459
460 /// Reifies the value of [variable] on the current receiver object. 460 /// Reifies the value of [variable] on the current receiver object.
461 ir.Primitive buildReifyTypeVariable(TypeVariableType variable); 461 ir.Primitive buildReifyTypeVariable(TypeVariableType variable);
462 462
463 /// Creates an access to the receiver from the current (or enclosing) method. 463 /// Creates an access to the receiver from the current (or enclosing) method.
464 /// 464 ///
465 /// If inside a closure class, [buildThis] will redirect access through 465 /// If inside a closure class, [buildThis] will redirect access through
466 /// closure fields in order to access the receiver from the enclosing method. 466 /// closure fields in order to access the receiver from the enclosing method.
467 ir.Primitive buildThis(); 467 ir.Primitive buildThis();
468 468
469 /// In JS-mode, gets an interceptor for [value].
470 /// In Dart-mode, simply returns [value].
471 ir.Primitive buildGetInterceptor(ir.Primitive value);
472
469 // TODO(johnniwinther): Make these field final and remove the default values 473 // TODO(johnniwinther): Make these field final and remove the default values
470 // when [IrBuilder] is a property of [IrBuilderVisitor] instead of a mixin. 474 // when [IrBuilder] is a property of [IrBuilderVisitor] instead of a mixin.
471 475
472 final List<ir.Parameter> _parameters = <ir.Parameter>[]; 476 final List<ir.Parameter> _parameters = <ir.Parameter>[];
473 477
474 IrBuilderSharedState state; 478 IrBuilderSharedState state;
475 479
476 /// A map from variable indexes to their values. 480 /// A map from variable indexes to their values.
477 /// 481 ///
478 /// [BoxLocal]s map to their box. [LocalElement]s that are boxed are not 482 /// [BoxLocal]s map to their box. [LocalElement]s that are boxed are not
(...skipping 1311 matching lines...) Expand 10 before | Expand all | Expand 10 after
1790 catchBuilder.removeMutableVariable(variable); 1794 catchBuilder.removeMutableVariable(variable);
1791 catchBuilder.environment.update(variable, value); 1795 catchBuilder.environment.update(variable, value);
1792 } 1796 }
1793 1797
1794 // Handlers are always translated as having both exception and stack trace 1798 // Handlers are always translated as having both exception and stack trace
1795 // parameters. Multiple clauses do not have to use the same names for 1799 // parameters. Multiple clauses do not have to use the same names for
1796 // them. Choose the first of each as the name hint for the respective 1800 // them. Choose the first of each as the name hint for the respective
1797 // handler parameter. 1801 // handler parameter.
1798 ir.Parameter exceptionParameter = 1802 ir.Parameter exceptionParameter =
1799 new ir.Parameter(catchClauseInfos.first.exceptionVariable); 1803 new ir.Parameter(catchClauseInfos.first.exceptionVariable);
1804 ir.Primitive exceptionInterceptor = new ir.Parameter(null);
1800 LocalVariableElement traceVariable; 1805 LocalVariableElement traceVariable;
1801 CatchClauseInfo catchAll; 1806 CatchClauseInfo catchAll;
1802 for (int i = 0; i < catchClauseInfos.length; ++i) { 1807 for (int i = 0; i < catchClauseInfos.length; ++i) {
1803 CatchClauseInfo info = catchClauseInfos[i]; 1808 CatchClauseInfo info = catchClauseInfos[i];
1804 if (info.type == null) { 1809 if (info.type == null) {
1805 catchAll = info; 1810 catchAll = info;
1806 catchClauseInfos.length = i; 1811 catchClauseInfos.length = i;
1807 break; 1812 break;
1808 } 1813 }
1809 if (traceVariable == null) { 1814 if (traceVariable == null) {
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1845 1850
1846 ir.Parameter typeMatches = new ir.Parameter(null); 1851 ir.Parameter typeMatches = new ir.Parameter(null);
1847 ir.Continuation checkType = new ir.Continuation([typeMatches]); 1852 ir.Continuation checkType = new ir.Continuation([typeMatches]);
1848 checkType.body = 1853 checkType.body =
1849 new ir.LetCont.many([thenContinuation, elseContinuation], 1854 new ir.LetCont.many([thenContinuation, elseContinuation],
1850 new ir.Branch(new ir.IsTrue(typeMatches), 1855 new ir.Branch(new ir.IsTrue(typeMatches),
1851 thenContinuation, 1856 thenContinuation,
1852 elseContinuation)); 1857 elseContinuation));
1853 catchBody = 1858 catchBody =
1854 new ir.LetCont(checkType, 1859 new ir.LetCont(checkType,
1855 new ir.TypeOperator(exceptionParameter, clause.type, checkType, 1860 new ir.TypeOperator(exceptionInterceptor, clause.type, checkType,
1856 isTypeTest: true)); 1861 isTypeTest: true));
1857 } 1862 }
1858 1863
1859 List<ir.Parameter> catchParameters = 1864 List<ir.Parameter> catchParameters =
1860 <ir.Parameter>[exceptionParameter, traceParameter]; 1865 <ir.Parameter>[exceptionParameter, traceParameter];
1861 ir.Continuation catchContinuation = new ir.Continuation(catchParameters); 1866 ir.Continuation catchContinuation = new ir.Continuation(catchParameters);
1867 catchBuilder.buildGetInterceptor(exceptionParameter)
1868 .substituteFor(exceptionInterceptor);
1862 catchBuilder.add(catchBody); 1869 catchBuilder.add(catchBody);
1863 catchContinuation.body = catchBuilder._root; 1870 catchContinuation.body = catchBuilder._root;
1864 1871
1865 tryCatchBuilder.add( 1872 tryCatchBuilder.add(
1866 new ir.LetHandler(catchContinuation, tryBuilder._root)); 1873 new ir.LetHandler(catchContinuation, tryBuilder._root));
1867 add(new ir.LetCont(join.continuation, tryCatchBuilder._root)); 1874 add(new ir.LetCont(join.continuation, tryCatchBuilder._root));
1868 environment = join.environment; 1875 environment = join.environment;
1869 } 1876 }
1870 1877
1871 /// Create a return statement `return value;` or `return;` if [value] is 1878 /// Create a return statement `return value;` or `return;` if [value] is
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
2007 return resultParameter; 2014 return resultParameter;
2008 } 2015 }
2009 2016
2010 /// Creates a type test or type cast of [receiver] against [type]. 2017 /// Creates a type test or type cast of [receiver] against [type].
2011 /// 2018 ///
2012 /// Set [isTypeTest] to `true` to create a type test and furthermore set 2019 /// Set [isTypeTest] to `true` to create a type test and furthermore set
2013 /// [isNotCheck] to `true` to create a negated type test. 2020 /// [isNotCheck] to `true` to create a negated type test.
2014 ir.Primitive buildTypeOperator(ir.Primitive receiver, 2021 ir.Primitive buildTypeOperator(ir.Primitive receiver,
2015 DartType type, 2022 DartType type,
2016 {bool isTypeTest: false, 2023 {bool isTypeTest: false,
2017 bool isNotCheck: false}) { 2024 bool isNotCheck: false});
2018 assert(isOpen);
2019 assert(isTypeTest != null);
2020 assert(!isNotCheck || isTypeTest);
2021 ir.Primitive check = _continueWithExpression(
2022 (k) => new ir.TypeOperator(receiver, type, k, isTypeTest: isTypeTest));
2023 return isNotCheck ? buildNegation(check) : check;
2024 }
2025 2025
2026 /// Create a lazy and/or expression. [leftValue] is the value of the left 2026 /// Create a lazy and/or expression. [leftValue] is the value of the left
2027 /// operand and [buildRightValue] is called to process the value of the right 2027 /// operand and [buildRightValue] is called to process the value of the right
2028 /// operand in the context of its own [IrBuilder]. 2028 /// operand in the context of its own [IrBuilder].
2029 ir.Primitive buildLogicalOperator( 2029 ir.Primitive buildLogicalOperator(
2030 ir.Primitive leftValue, 2030 ir.Primitive leftValue,
2031 ir.Primitive buildRightValue(IrBuilder builder), 2031 ir.Primitive buildRightValue(IrBuilder builder),
2032 {bool isLazyOr: false}) { 2032 {bool isLazyOr: false}) {
2033 // e0 && e1 is translated as if e0 ? (e1 == true) : false. 2033 // e0 && e1 is translated as if e0 ? (e1 == true) : false.
2034 // e0 || e1 is translated as if e0 ? true : (e1 == true). 2034 // e0 || e1 is translated as if e0 ? true : (e1 == true).
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after
2284 value.useElementAsHint(local); 2284 value.useElementAsHint(local);
2285 environment.update(local, value); 2285 environment.update(local, value);
2286 } 2286 }
2287 return value; 2287 return value;
2288 } 2288 }
2289 2289
2290 ir.Primitive buildThis() { 2290 ir.Primitive buildThis() {
2291 return state.enclosingMethodThisParameter; 2291 return state.enclosingMethodThisParameter;
2292 } 2292 }
2293 2293
2294 ir.Primitive buildGetInterceptor(ir.Primitive value) => value;
2295
2294 @override 2296 @override
2295 ir.Primitive buildConstructorInvocation(ConstructorElement element, 2297 ir.Primitive buildConstructorInvocation(ConstructorElement element,
2296 CallStructure callStructure, 2298 CallStructure callStructure,
2297 DartType type, 2299 DartType type,
2298 List<ir.Primitive> arguments) { 2300 List<ir.Primitive> arguments) {
2299 assert(isOpen); 2301 assert(isOpen);
2300 Selector selector = 2302 Selector selector =
2301 new Selector(SelectorKind.CALL, element.memberName, callStructure); 2303 new Selector(SelectorKind.CALL, element.memberName, callStructure);
2302 return _continueWithExpression( 2304 return _continueWithExpression(
2303 (k) => new ir.InvokeConstructor(type, element, selector, 2305 (k) => new ir.InvokeConstructor(type, element, selector,
2304 arguments, k)); 2306 arguments, k));
2305 } 2307 }
2306 2308
2307 @override 2309 @override
2308 ir.Primitive buildReifyTypeVariable(TypeVariableType variable) { 2310 ir.Primitive buildReifyTypeVariable(TypeVariableType variable) {
2309 return addPrimitive(new ir.ReifyTypeVar(variable.element)); 2311 return addPrimitive(new ir.ReifyTypeVar(variable.element));
2310 } 2312 }
2313
2314 @override
2315 ir.Primitive buildTypeOperator(ir.Primitive receiver,
2316 DartType type,
2317 {bool isTypeTest: false,
2318 bool isNotCheck: false}) {
2319 assert(isOpen);
2320 assert(isTypeTest != null);
2321 assert(!isNotCheck || isTypeTest);
2322 ir.Primitive check = _continueWithExpression(
2323 (k) => new ir.TypeOperator(receiver, type, k, isTypeTest: isTypeTest ));
2324 return isNotCheck ? buildNegation(check) : check;
2325 }
2311 } 2326 }
2312 2327
2313 /// State shared between JsIrBuilders within the same function. 2328 /// State shared between JsIrBuilders within the same function.
2314 /// 2329 ///
2315 /// Note that this is not shared between builders of nested functions. 2330 /// Note that this is not shared between builders of nested functions.
2316 class JsIrBuilderSharedState { 2331 class JsIrBuilderSharedState {
2317 /// Maps boxed locals to their location. These locals are not part of 2332 /// Maps boxed locals to their location. These locals are not part of
2318 /// the environment. 2333 /// the environment.
2319 final Map<Local, ClosureLocation> boxedVariables = {}; 2334 final Map<Local, ClosureLocation> boxedVariables = {};
2320 2335
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
2536 } 2551 }
2537 environment.update(scope.box, newBox); 2552 environment.update(scope.box, newBox);
2538 } 2553 }
2539 2554
2540 ir.Primitive buildThis() { 2555 ir.Primitive buildThis() {
2541 if (jsState.receiver != null) return jsState.receiver; 2556 if (jsState.receiver != null) return jsState.receiver;
2542 assert(state.thisParameter != null); 2557 assert(state.thisParameter != null);
2543 return state.thisParameter; 2558 return state.thisParameter;
2544 } 2559 }
2545 2560
2561 ir.Primitive buildGetInterceptor(ir.Primitive value) {
2562 return addPrimitive(new ir.Interceptor(value, program.interceptedClasses));
2563 }
2564
2546 @override 2565 @override
2547 ir.Primitive buildSuperFieldGet(FieldElement target) { 2566 ir.Primitive buildSuperFieldGet(FieldElement target) {
2548 return addPrimitive(new ir.GetField(buildThis(), target)); 2567 return addPrimitive(new ir.GetField(buildThis(), target));
2549 } 2568 }
2550 2569
2551 @override 2570 @override
2552 ir.Primitive buildSuperFieldSet(FieldElement target, ir.Primitive value) { 2571 ir.Primitive buildSuperFieldSet(FieldElement target, ir.Primitive value) {
2553 add(new ir.SetField(buildThis(), target, value)); 2572 add(new ir.SetField(buildThis(), target, value));
2554 return value; 2573 return value;
2555 } 2574 }
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
2652 @override 2671 @override
2653 ir.Primitive buildReifyTypeVariable(TypeVariableType variable) { 2672 ir.Primitive buildReifyTypeVariable(TypeVariableType variable) {
2654 ir.Primitive typeArgument = buildTypeVariableAccess(variable); 2673 ir.Primitive typeArgument = buildTypeVariableAccess(variable);
2655 return addPrimitive(new ir.ReifyRuntimeType(typeArgument)); 2674 return addPrimitive(new ir.ReifyRuntimeType(typeArgument));
2656 } 2675 }
2657 2676
2658 ir.Primitive buildInvocationMirror(Selector selector, 2677 ir.Primitive buildInvocationMirror(Selector selector,
2659 List<ir.Primitive> arguments) { 2678 List<ir.Primitive> arguments) {
2660 return addPrimitive(new ir.CreateInvocationMirror(selector, arguments)); 2679 return addPrimitive(new ir.CreateInvocationMirror(selector, arguments));
2661 } 2680 }
2681
2682 @override
2683 ir.Primitive buildTypeOperator(ir.Primitive receiver,
2684 DartType type,
2685 {bool isTypeTest: false,
2686 bool isNotCheck: false}) {
2687 assert(isOpen);
2688 assert(isTypeTest != null);
2689 assert(!isNotCheck || isTypeTest);
2690 ir.Primitive interceptor =
2691 addPrimitive(new ir.Interceptor(receiver, program.interceptedClasses));
2692 ir.Primitive check = _continueWithExpression(
2693 (k) => new ir.TypeOperator(interceptor, type, k,
2694 isTypeTest: isTypeTest));
2695 return isNotCheck ? buildNegation(check) : check;
2696 }
2697
2662 } 2698 }
2663 2699
2664 2700
2665 /// Location of a variable relative to a given closure. 2701 /// Location of a variable relative to a given closure.
2666 class ClosureLocation { 2702 class ClosureLocation {
2667 /// If not `null`, this location is [box].[field]. 2703 /// If not `null`, this location is [box].[field].
2668 /// The location of [box] can be obtained separately from an 2704 /// The location of [box] can be obtained separately from an
2669 /// enclosing [ClosureEnvironment] or [ClosureScope]. 2705 /// enclosing [ClosureEnvironment] or [ClosureScope].
2670 /// If `null`, then the location is [field] on the enclosing function object. 2706 /// If `null`, then the location is [field] on the enclosing function object.
2671 final BoxLocal box; 2707 final BoxLocal box;
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
2733 } 2769 }
2734 2770
2735 /// Synthetic parameter to a JavaScript factory method that takes the type 2771 /// Synthetic parameter to a JavaScript factory method that takes the type
2736 /// argument given for the type variable [variable]. 2772 /// argument given for the type variable [variable].
2737 class TypeInformationParameter implements Local { 2773 class TypeInformationParameter implements Local {
2738 final TypeVariableElement variable; 2774 final TypeVariableElement variable;
2739 final ExecutableElement executableContext; 2775 final ExecutableElement executableContext;
2740 TypeInformationParameter(this.variable, this.executableContext); 2776 TypeInformationParameter(this.variable, this.executableContext);
2741 String get name => variable.name; 2777 String get name => variable.name;
2742 } 2778 }
OLDNEW
« no previous file with comments | « no previous file | pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698