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

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

Issue 1413213004: Move remaining helpers to BackendHelpers (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 5 years, 1 month 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
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 final SourceInformationStrategy sourceInformationFactory; 10 final SourceInformationStrategy sourceInformationFactory;
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 controlFlowOperators = new Set<HInstruction>(), 150 controlFlowOperators = new Set<HInstruction>(),
151 breakAction = new Map<Entity, EntityAction>(), 151 breakAction = new Map<Entity, EntityAction>(),
152 continueAction = new Map<Entity, EntityAction>(); 152 continueAction = new Map<Entity, EntityAction>();
153 153
154 Compiler get compiler => backend.compiler; 154 Compiler get compiler => backend.compiler;
155 155
156 NativeEmitter get nativeEmitter => backend.emitter.nativeEmitter; 156 NativeEmitter get nativeEmitter => backend.emitter.nativeEmitter;
157 157
158 CodegenRegistry get registry => work.registry; 158 CodegenRegistry get registry => work.registry;
159 159
160 BackendHelpers get helpers => backend.helpers;
161
160 native.NativeEnqueuer get nativeEnqueuer { 162 native.NativeEnqueuer get nativeEnqueuer {
161 return compiler.enqueuer.codegen.nativeEnqueuer; 163 return compiler.enqueuer.codegen.nativeEnqueuer;
162 } 164 }
163 165
164 DiagnosticReporter get reporter => compiler.reporter; 166 DiagnosticReporter get reporter => compiler.reporter;
165 167
166 CoreClasses get coreClasses => compiler.coreClasses; 168 CoreClasses get coreClasses => compiler.coreClasses;
167 169
168 bool isGenerateAtUseSite(HInstruction instruction) { 170 bool isGenerateAtUseSite(HInstruction instruction) {
169 return generateAtUseSite.contains(instruction); 171 return generateAtUseSite.contains(instruction);
(...skipping 529 matching lines...) Expand 10 before | Expand all | Expand 10 after
699 bool visitTryInfo(HTryBlockInformation info) { 701 bool visitTryInfo(HTryBlockInformation info) {
700 js.Block body = generateStatementsInNewBlock(info.body); 702 js.Block body = generateStatementsInNewBlock(info.body);
701 js.Catch catchPart = null; 703 js.Catch catchPart = null;
702 js.Block finallyPart = null; 704 js.Block finallyPart = null;
703 if (info.catchBlock != null) { 705 if (info.catchBlock != null) {
704 void register(ClassElement classElement) { 706 void register(ClassElement classElement) {
705 if (classElement != null) { 707 if (classElement != null) {
706 registry.registerInstantiatedClass(classElement); 708 registry.registerInstantiatedClass(classElement);
707 } 709 }
708 } 710 }
709 register(backend.jsPlainJavaScriptObjectClass); 711 register(helpers.jsPlainJavaScriptObjectClass);
710 register(backend.jsUnknownJavaScriptObjectClass); 712 register(helpers.jsUnknownJavaScriptObjectClass);
711 713
712 HLocalValue exception = info.catchVariable; 714 HLocalValue exception = info.catchVariable;
713 String name = variableNames.getName(exception); 715 String name = variableNames.getName(exception);
714 js.VariableDeclaration decl = new js.VariableDeclaration(name); 716 js.VariableDeclaration decl = new js.VariableDeclaration(name);
715 js.Block catchBlock = generateStatementsInNewBlock(info.catchBlock); 717 js.Block catchBlock = generateStatementsInNewBlock(info.catchBlock);
716 catchPart = new js.Catch(decl, catchBlock); 718 catchPart = new js.Catch(decl, catchBlock);
717 } 719 }
718 if (info.finallyBlock != null) { 720 if (info.finallyBlock != null) {
719 finallyPart = generateStatementsInNewBlock(info.finallyBlock); 721 finallyPart = generateStatementsInNewBlock(info.finallyBlock);
720 } 722 }
(...skipping 795 matching lines...) Expand 10 before | Expand all | Expand 10 after
1516 js.Expression receiverExpression = pop(); 1518 js.Expression receiverExpression = pop();
1517 use(node.conditionalConstantInterceptor); 1519 use(node.conditionalConstantInterceptor);
1518 js.Expression constant = pop(); 1520 js.Expression constant = pop();
1519 push(js.js('# && #', [receiverExpression, constant])); 1521 push(js.js('# && #', [receiverExpression, constant]));
1520 } else { 1522 } else {
1521 assert(node.inputs.length == 1); 1523 assert(node.inputs.length == 1);
1522 registry.registerSpecializedGetInterceptor(node.interceptedClasses); 1524 registry.registerSpecializedGetInterceptor(node.interceptedClasses);
1523 js.Name name = 1525 js.Name name =
1524 backend.namer.nameForGetInterceptor(node.interceptedClasses); 1526 backend.namer.nameForGetInterceptor(node.interceptedClasses);
1525 var isolate = new js.VariableUse( 1527 var isolate = new js.VariableUse(
1526 backend.namer.globalObjectFor(backend.interceptorsLibrary)); 1528 backend.namer.globalObjectFor(helpers.interceptorsLibrary));
1527 use(node.receiver); 1529 use(node.receiver);
1528 List<js.Expression> arguments = <js.Expression>[pop()]; 1530 List<js.Expression> arguments = <js.Expression>[pop()];
1529 push(js.propertyCall(isolate, name, arguments) 1531 push(js.propertyCall(isolate, name, arguments)
1530 .withSourceInformation(node.sourceInformation)); 1532 .withSourceInformation(node.sourceInformation));
1531 registry.registerUseInterceptor(); 1533 registry.registerUseInterceptor();
1532 } 1534 }
1533 } 1535 }
1534 1536
1535 visitInvokeDynamicMethod(HInvokeDynamicMethod node) { 1537 visitInvokeDynamicMethod(HInvokeDynamicMethod node) {
1536 use(node.receiver); 1538 use(node.receiver);
1537 js.Expression object = pop(); 1539 js.Expression object = pop();
1538 String methodName; 1540 String methodName;
1539 List<js.Expression> arguments = visitArguments(node.inputs); 1541 List<js.Expression> arguments = visitArguments(node.inputs);
1540 Element target = node.element; 1542 Element target = node.element;
1541 1543
1542 // TODO(herhut): The namer should return the appropriate backendname here. 1544 // TODO(herhut): The namer should return the appropriate backendname here.
1543 if (target != null && !node.isInterceptedCall) { 1545 if (target != null && !node.isInterceptedCall) {
1544 if (target == backend.jsArrayAdd) { 1546 if (target == helpers.jsArrayAdd) {
1545 methodName = 'push'; 1547 methodName = 'push';
1546 } else if (target == backend.jsArrayRemoveLast) { 1548 } else if (target == helpers.jsArrayRemoveLast) {
1547 methodName = 'pop'; 1549 methodName = 'pop';
1548 } else if (target == backend.jsStringSplit) { 1550 } else if (target == helpers.jsStringSplit) {
1549 methodName = 'split'; 1551 methodName = 'split';
1550 // Split returns a List, so we make sure the backend knows the 1552 // Split returns a List, so we make sure the backend knows the
1551 // list class is instantiated. 1553 // list class is instantiated.
1552 registry.registerInstantiatedClass(coreClasses.listClass); 1554 registry.registerInstantiatedClass(coreClasses.listClass);
1553 } else if (backend.isNative(target) && target.isFunction 1555 } else if (backend.isNative(target) && target.isFunction
1554 && !node.isInterceptedCall) { 1556 && !node.isInterceptedCall) {
1555 // A direct (i.e. non-interceptor) native call is the result of 1557 // A direct (i.e. non-interceptor) native call is the result of
1556 // optimization. The optimization ensures any type checks or 1558 // optimization. The optimization ensures any type checks or
1557 // conversions have been satisified. 1559 // conversions have been satisified.
1558 methodName = backend.getFixedBackendName(target); 1560 methodName = backend.getFixedBackendName(target);
(...skipping 17 matching lines...) Expand all
1576 js.Name methodName = backend.namer.instanceMethodName(node.element); 1578 js.Name methodName = backend.namer.instanceMethodName(node.element);
1577 List<js.Expression> arguments = visitArguments(node.inputs); 1579 List<js.Expression> arguments = visitArguments(node.inputs);
1578 push(js.propertyCall(object, methodName, arguments) 1580 push(js.propertyCall(object, methodName, arguments)
1579 .withSourceInformation(node.sourceInformation)); 1581 .withSourceInformation(node.sourceInformation));
1580 registry.registerStaticUse(node.element); 1582 registry.registerStaticUse(node.element);
1581 } 1583 }
1582 1584
1583 void visitOneShotInterceptor(HOneShotInterceptor node) { 1585 void visitOneShotInterceptor(HOneShotInterceptor node) {
1584 List<js.Expression> arguments = visitArguments(node.inputs); 1586 List<js.Expression> arguments = visitArguments(node.inputs);
1585 var isolate = new js.VariableUse( 1587 var isolate = new js.VariableUse(
1586 backend.namer.globalObjectFor(backend.interceptorsLibrary)); 1588 backend.namer.globalObjectFor(helpers.interceptorsLibrary));
1587 Selector selector = node.selector; 1589 Selector selector = node.selector;
1588 TypeMask mask = getOptimizedSelectorFor(node, selector, node.mask); 1590 TypeMask mask = getOptimizedSelectorFor(node, selector, node.mask);
1589 js.Name methodName = backend.registerOneShotInterceptor(selector); 1591 js.Name methodName = backend.registerOneShotInterceptor(selector);
1590 push(js.propertyCall(isolate, methodName, arguments) 1592 push(js.propertyCall(isolate, methodName, arguments)
1591 .withSourceInformation(node.sourceInformation)); 1593 .withSourceInformation(node.sourceInformation));
1592 if (selector.isGetter) { 1594 if (selector.isGetter) {
1593 registerGetter(node); 1595 registerGetter(node);
1594 } else if (selector.isSetter) { 1596 } else if (selector.isSetter) {
1595 registerSetter(node); 1597 registerSetter(node);
1596 } else { 1598 } else {
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
1790 1792
1791 visitFieldGet(HFieldGet node) { 1793 visitFieldGet(HFieldGet node) {
1792 use(node.receiver); 1794 use(node.receiver);
1793 Element element = node.element; 1795 Element element = node.element;
1794 if (node.isNullCheck) { 1796 if (node.isNullCheck) {
1795 // We access a JavaScript member we know all objects besides 1797 // We access a JavaScript member we know all objects besides
1796 // null and undefined have: V8 does not like accessing a member 1798 // null and undefined have: V8 does not like accessing a member
1797 // that does not exist. 1799 // that does not exist.
1798 push(new js.PropertyAccess.field(pop(), 'toString') 1800 push(new js.PropertyAccess.field(pop(), 'toString')
1799 .withSourceInformation(node.sourceInformation)); 1801 .withSourceInformation(node.sourceInformation));
1800 } else if (element == backend.jsIndexableLength) { 1802 } else if (element == helpers.jsIndexableLength) {
1801 // We're accessing a native JavaScript property called 'length' 1803 // We're accessing a native JavaScript property called 'length'
1802 // on a JS String or a JS array. Therefore, the name of that 1804 // on a JS String or a JS array. Therefore, the name of that
1803 // property should not be mangled. 1805 // property should not be mangled.
1804 push(new js.PropertyAccess.field(pop(), 'length') 1806 push(new js.PropertyAccess.field(pop(), 'length')
1805 .withSourceInformation(node.sourceInformation)); 1807 .withSourceInformation(node.sourceInformation));
1806 } else { 1808 } else {
1807 js.Name name = backend.namer.instanceFieldPropertyName(element); 1809 js.Name name = backend.namer.instanceFieldPropertyName(element);
1808 push(new js.PropertyAccess(pop(), name) 1810 push(new js.PropertyAccess(pop(), name)
1809 .withSourceInformation(node.sourceInformation)); 1811 .withSourceInformation(node.sourceInformation));
1810 registry.registerFieldGetter(element); 1812 registry.registerFieldGetter(element);
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after
2073 visitThis(HThis node) { 2075 visitThis(HThis node) {
2074 push(new js.This()); 2076 push(new js.This());
2075 } 2077 }
2076 2078
2077 visitThrow(HThrow node) { 2079 visitThrow(HThrow node) {
2078 if (node.isRethrow) { 2080 if (node.isRethrow) {
2079 use(node.inputs[0]); 2081 use(node.inputs[0]);
2080 pushStatement(new js.Throw(pop()) 2082 pushStatement(new js.Throw(pop())
2081 .withSourceInformation(node.sourceInformation)); 2083 .withSourceInformation(node.sourceInformation));
2082 } else { 2084 } else {
2083 generateThrowWithHelper('wrapException', node.inputs[0], 2085 generateThrowWithHelper(helpers.wrapExceptionHelper, node.inputs[0],
2084 sourceInformation: node.sourceInformation); 2086 sourceInformation: node.sourceInformation);
2085 } 2087 }
2086 } 2088 }
2087 2089
2088 visitAwait(HAwait node) { 2090 visitAwait(HAwait node) {
2089 use(node.inputs[0]); 2091 use(node.inputs[0]);
2090 push(new js.Await(pop()) 2092 push(new js.Await(pop())
2091 .withSourceInformation(node.sourceInformation)); 2093 .withSourceInformation(node.sourceInformation));
2092 } 2094 }
2093 2095
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
2134 } 2136 }
2135 assert(over != null || under != null); 2137 assert(over != null || under != null);
2136 js.Expression underOver = under == null 2138 js.Expression underOver = under == null
2137 ? over 2139 ? over
2138 : over == null 2140 : over == null
2139 ? under 2141 ? under
2140 : new js.Binary("||", under, over); 2142 : new js.Binary("||", under, over);
2141 js.Statement thenBody = new js.Block.empty(); 2143 js.Statement thenBody = new js.Block.empty();
2142 js.Block oldContainer = currentContainer; 2144 js.Block oldContainer = currentContainer;
2143 currentContainer = thenBody; 2145 currentContainer = thenBody;
2144 generateThrowWithHelper('ioore', [node.array, node.reportedIndex]); 2146 generateThrowWithHelper(helpers.throwIndexOutOfRangeException,
2147 [node.array, node.reportedIndex]);
2145 currentContainer = oldContainer; 2148 currentContainer = oldContainer;
2146 thenBody = unwrapStatement(thenBody); 2149 thenBody = unwrapStatement(thenBody);
2147 pushStatement(new js.If.noElse(underOver, thenBody) 2150 pushStatement(new js.If.noElse(underOver, thenBody)
2148 .withSourceInformation(node.sourceInformation)); 2151 .withSourceInformation(node.sourceInformation));
2149 } else { 2152 } else {
2150 generateThrowWithHelper('ioore', [node.array, node.index]); 2153 generateThrowWithHelper(helpers.throwIndexOutOfRangeException,
2154 [node.array, node.index]);
2151 } 2155 }
2152 } 2156 }
2153 2157
2154 void generateThrowWithHelper(String helperName, argument, 2158 void generateThrowWithHelper(Element helper, argument,
2155 {SourceInformation sourceInformation}) { 2159 {SourceInformation sourceInformation}) {
2156 Element helper = backend.findHelper(helperName);
2157 registry.registerStaticUse(helper); 2160 registry.registerStaticUse(helper);
2158 js.Expression jsHelper = backend.emitter.staticFunctionAccess(helper); 2161 js.Expression jsHelper = backend.emitter.staticFunctionAccess(helper);
2159 List arguments = []; 2162 List arguments = [];
2160 var location; 2163 var location;
2161 if (argument is List) { 2164 if (argument is List) {
2162 location = argument[0]; 2165 location = argument[0];
2163 argument.forEach((instruction) { 2166 argument.forEach((instruction) {
2164 use(instruction); 2167 use(instruction);
2165 arguments.add(pop()); 2168 arguments.add(pop());
2166 }); 2169 });
2167 } else { 2170 } else {
2168 location = argument; 2171 location = argument;
2169 use(argument); 2172 use(argument);
2170 arguments.add(pop()); 2173 arguments.add(pop());
2171 } 2174 }
2172 js.Call value = new js.Call(jsHelper, arguments.toList(growable: false), 2175 js.Call value = new js.Call(jsHelper, arguments.toList(growable: false),
2173 sourceInformation: sourceInformation); 2176 sourceInformation: sourceInformation);
2174 // BUG(4906): Using throw/return here adds to the size of the generated code 2177 // BUG(4906): Using throw/return here adds to the size of the generated code
2175 // but it has the advantage of explicitly telling the JS engine that 2178 // but it has the advantage of explicitly telling the JS engine that
2176 // this code path will terminate abruptly. Needs more work. 2179 // this code path will terminate abruptly. Needs more work.
2177 if (helperName == 'wrapException') { 2180 if (helper == helpers.wrapExceptionHelper) {
2178 pushStatement(new js.Throw(value) 2181 pushStatement(new js.Throw(value)
2179 .withSourceInformation(sourceInformation)); 2182 .withSourceInformation(sourceInformation));
2180 } else { 2183 } else {
2181 Element element = work.element; 2184 Element element = work.element;
2182 if (element is FunctionElement && element.asyncMarker.isYielding) { 2185 if (element is FunctionElement && element.asyncMarker.isYielding) {
2183 // `return <expr>;` is illegal in a sync* or async* function. 2186 // `return <expr>;` is illegal in a sync* or async* function.
2184 // To have the the async-translator working, we avoid introducing 2187 // To have the the async-translator working, we avoid introducing
2185 // `return` nodes. 2188 // `return` nodes.
2186 pushStatement(new js.ExpressionStatement(value) 2189 pushStatement(new js.ExpressionStatement(value)
2187 .withSourceInformation(sourceInformation)); 2190 .withSourceInformation(sourceInformation));
2188 } else { 2191 } else {
2189 pushStatement(new js.Return(value) 2192 pushStatement(new js.Return(value)
2190 .withSourceInformation(sourceInformation)); 2193 .withSourceInformation(sourceInformation));
2191 } 2194 }
2192 } 2195 }
2193 } 2196 }
2194 2197
2195 visitThrowExpression(HThrowExpression node) { 2198 visitThrowExpression(HThrowExpression node) {
2196 HInstruction argument = node.inputs[0]; 2199 HInstruction argument = node.inputs[0];
2197 use(argument); 2200 use(argument);
2198 2201
2199 Element helper = backend.findHelper("throwExpression"); 2202 Element helper = helpers.throwExpressionHelper;
2200 registry.registerStaticUse(helper); 2203 registry.registerStaticUse(helper);
2201 2204
2202 js.Expression jsHelper = backend.emitter.staticFunctionAccess(helper); 2205 js.Expression jsHelper = backend.emitter.staticFunctionAccess(helper);
2203 js.Call value = new js.Call(jsHelper, [pop()]) 2206 js.Call value = new js.Call(jsHelper, [pop()])
2204 .withSourceInformation(node.sourceInformation); 2207 .withSourceInformation(node.sourceInformation);
2205 push(value); 2208 push(value);
2206 } 2209 }
2207 2210
2208 void visitSwitch(HSwitch node) { 2211 void visitSwitch(HSwitch node) {
2209 // Switches are handled using [visitSwitchInfo]. 2212 // Switches are handled using [visitSwitchInfo].
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
2420 void checkNonNull(HInstruction input) { 2423 void checkNonNull(HInstruction input) {
2421 use(input); 2424 use(input);
2422 push(new js.Binary('!=', pop(), new js.LiteralNull())); 2425 push(new js.Binary('!=', pop(), new js.LiteralNull()));
2423 } 2426 }
2424 2427
2425 void checkType(HInstruction input, HInstruction interceptor, 2428 void checkType(HInstruction input, HInstruction interceptor,
2426 DartType type, 2429 DartType type,
2427 SourceInformation sourceInformation, 2430 SourceInformation sourceInformation,
2428 {bool negative: false}) { 2431 {bool negative: false}) {
2429 Element element = type.element; 2432 Element element = type.element;
2430 if (element == backend.jsArrayClass) { 2433 if (element == helpers.jsArrayClass) {
2431 checkArray(input, negative ? '!==': '==='); 2434 checkArray(input, negative ? '!==': '===');
2432 return; 2435 return;
2433 } else if (element == backend.jsMutableArrayClass) { 2436 } else if (element == helpers.jsMutableArrayClass) {
2434 if (negative) { 2437 if (negative) {
2435 checkImmutableArray(input); 2438 checkImmutableArray(input);
2436 } else { 2439 } else {
2437 checkMutableArray(input); 2440 checkMutableArray(input);
2438 } 2441 }
2439 return; 2442 return;
2440 } else if (element == backend.jsExtendableArrayClass) { 2443 } else if (element == helpers.jsExtendableArrayClass) {
2441 if (negative) { 2444 if (negative) {
2442 checkFixedArray(input); 2445 checkFixedArray(input);
2443 } else { 2446 } else {
2444 checkExtendableArray(input); 2447 checkExtendableArray(input);
2445 } 2448 }
2446 return; 2449 return;
2447 } else if (element == backend.jsFixedArrayClass) { 2450 } else if (element == helpers.jsFixedArrayClass) {
2448 if (negative) { 2451 if (negative) {
2449 checkExtendableArray(input); 2452 checkExtendableArray(input);
2450 } else { 2453 } else {
2451 checkFixedArray(input); 2454 checkFixedArray(input);
2452 } 2455 }
2453 return; 2456 return;
2454 } else if (element == backend.jsUnmodifiableArrayClass) { 2457 } else if (element == helpers.jsUnmodifiableArrayClass) {
2455 if (negative) { 2458 if (negative) {
2456 checkMutableArray(input); 2459 checkMutableArray(input);
2457 } else { 2460 } else {
2458 checkImmutableArray(input); 2461 checkImmutableArray(input);
2459 } 2462 }
2460 return; 2463 return;
2461 } 2464 }
2462 if (interceptor != null) { 2465 if (interceptor != null) {
2463 checkTypeViaProperty(interceptor, type, sourceInformation, 2466 checkTypeViaProperty(interceptor, type, sourceInformation,
2464 negative: negative); 2467 negative: negative);
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
2683 TypeMask inputType = input.instructionType; 2686 TypeMask inputType = input.instructionType;
2684 // Figure out if it is beneficial to turn this into a null check. 2687 // Figure out if it is beneficial to turn this into a null check.
2685 // V8 generally prefers 'typeof' checks, but for integers and 2688 // V8 generally prefers 'typeof' checks, but for integers and
2686 // indexable primitives we cannot compile this test into a single 2689 // indexable primitives we cannot compile this test into a single
2687 // typeof check so the null check is cheaper. 2690 // typeof check so the null check is cheaper.
2688 bool isIntCheck = checkedType.containsOnlyInt(classWorld); 2691 bool isIntCheck = checkedType.containsOnlyInt(classWorld);
2689 bool turnIntoNumCheck = isIntCheck && input.isIntegerOrNull(compiler); 2692 bool turnIntoNumCheck = isIntCheck && input.isIntegerOrNull(compiler);
2690 bool turnIntoNullCheck = !turnIntoNumCheck 2693 bool turnIntoNullCheck = !turnIntoNumCheck
2691 && (checkedType.nullable() == inputType) 2694 && (checkedType.nullable() == inputType)
2692 && (isIntCheck 2695 && (isIntCheck
2693 || checkedType.satisfies(backend.jsIndexableClass, classWorld)); 2696 || checkedType.satisfies(helpers.jsIndexableClass, classWorld));
2694 2697
2695 if (turnIntoNullCheck) { 2698 if (turnIntoNullCheck) {
2696 use(input); 2699 use(input);
2697 return new js.Binary("==", pop(), new js.LiteralNull()) 2700 return new js.Binary("==", pop(), new js.LiteralNull())
2698 .withSourceInformation(input.sourceInformation); 2701 .withSourceInformation(input.sourceInformation);
2699 } else if (isIntCheck && !turnIntoNumCheck) { 2702 } else if (isIntCheck && !turnIntoNumCheck) {
2700 // input is !int 2703 // input is !int
2701 checkBigInt(input, '!==', input.sourceInformation); 2704 checkBigInt(input, '!==', input.sourceInformation);
2702 return pop(); 2705 return pop();
2703 } else if (turnIntoNumCheck || checkedType.containsOnlyNum(classWorld)) { 2706 } else if (turnIntoNumCheck || checkedType.containsOnlyNum(classWorld)) {
(...skipping 20 matching lines...) Expand all
2724 // sufficient for doing an argument or receiver check. 2727 // sufficient for doing an argument or receiver check.
2725 assert(compiler.trustTypeAnnotations || 2728 assert(compiler.trustTypeAnnotations ||
2726 !node.checkedType.containsOnlyInt(classWorld) || 2729 !node.checkedType.containsOnlyInt(classWorld) ||
2727 node.checkedInput.isIntegerOrNull(compiler)); 2730 node.checkedInput.isIntegerOrNull(compiler));
2728 js.Expression test = generateReceiverOrArgumentTypeTest( 2731 js.Expression test = generateReceiverOrArgumentTypeTest(
2729 node.checkedInput, node.checkedType); 2732 node.checkedInput, node.checkedType);
2730 js.Block oldContainer = currentContainer; 2733 js.Block oldContainer = currentContainer;
2731 js.Statement body = new js.Block.empty(); 2734 js.Statement body = new js.Block.empty();
2732 currentContainer = body; 2735 currentContainer = body;
2733 if (node.isArgumentTypeCheck) { 2736 if (node.isArgumentTypeCheck) {
2734 generateThrowWithHelper('iae', 2737 generateThrowWithHelper(
2738 helpers.throwIllegalArgumentException,
2735 node.checkedInput, 2739 node.checkedInput,
2736 sourceInformation: node.sourceInformation); 2740 sourceInformation: node.sourceInformation);
2737 } else if (node.isReceiverTypeCheck) { 2741 } else if (node.isReceiverTypeCheck) {
2738 use(node.checkedInput); 2742 use(node.checkedInput);
2739 js.Name methodName = 2743 js.Name methodName =
2740 backend.namer.invocationName(node.receiverTypeCheckSelector); 2744 backend.namer.invocationName(node.receiverTypeCheckSelector);
2741 js.Expression call = js.propertyCall(pop(), methodName, []); 2745 js.Expression call = js.propertyCall(pop(), methodName, []);
2742 pushStatement(new js.Return(call)); 2746 pushStatement(new js.Return(call));
2743 } 2747 }
2744 currentContainer = oldContainer; 2748 currentContainer = oldContainer;
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
2819 var arguments = [ 2823 var arguments = [
2820 returnType, 2824 returnType,
2821 new js.ArrayInitializer(parameterTypes), 2825 new js.ArrayInitializer(parameterTypes),
2822 new js.ObjectInitializer(namedParameters)]; 2826 new js.ObjectInitializer(namedParameters)];
2823 push(js.js('#(#)', [accessHelper('buildNamedFunctionType'), arguments])); 2827 push(js.js('#(#)', [accessHelper('buildNamedFunctionType'), arguments]));
2824 } 2828 }
2825 } 2829 }
2826 2830
2827 void visitReadTypeVariable(HReadTypeVariable node) { 2831 void visitReadTypeVariable(HReadTypeVariable node) {
2828 TypeVariableElement element = node.dartType.element; 2832 TypeVariableElement element = node.dartType.element;
2829 Element helperElement = backend.findHelper('convertRtiToRuntimeType'); 2833 Element helperElement = helpers.convertRtiToRuntimeType;
2830 registry.registerStaticUse(helperElement); 2834 registry.registerStaticUse(helperElement);
2831 2835
2832 use(node.inputs[0]); 2836 use(node.inputs[0]);
2833 if (node.hasReceiver) { 2837 if (node.hasReceiver) {
2834 if (backend.isInterceptorClass(element.enclosingClass)) { 2838 if (backend.isInterceptorClass(element.enclosingClass)) {
2835 int index = element.index; 2839 int index = element.index;
2836 js.Expression receiver = pop(); 2840 js.Expression receiver = pop();
2837 js.Expression helper = backend.emitter 2841 js.Expression helper = backend.emitter
2838 .staticFunctionAccess(helperElement); 2842 .staticFunctionAccess(helperElement);
2839 push(js.js(r'#(#.$builtinTypeInfo && #.$builtinTypeInfo[#])', 2843 push(js.js(r'#(#.$builtinTypeInfo && #.$builtinTypeInfo[#])',
2840 [helper, receiver, receiver, js.js.number(index)])); 2844 [helper, receiver, receiver, js.js.number(index)]));
2841 } else { 2845 } else {
2842 backend.emitter.registerReadTypeVariable(element); 2846 backend.emitter.registerReadTypeVariable(element);
2843 push(js.js('#.#()', 2847 push(js.js('#.#()',
2844 [pop(), backend.namer.nameForReadTypeVariable(element)])); 2848 [pop(), backend.namer.nameForReadTypeVariable(element)]));
2845 } 2849 }
2846 } else { 2850 } else {
2847 push(js.js('#(#)', [ 2851 push(js.js('#(#)', [
2848 backend.emitter.staticFunctionAccess( 2852 backend.emitter.staticFunctionAccess(helperElement),
2849 backend.findHelper('convertRtiToRuntimeType')),
2850 pop()])); 2853 pop()]));
2851 } 2854 }
2852 } 2855 }
2853 2856
2854 void visitInterfaceType(HInterfaceType node) { 2857 void visitInterfaceType(HInterfaceType node) {
2855 List<js.Expression> typeArguments = <js.Expression>[]; 2858 List<js.Expression> typeArguments = <js.Expression>[];
2856 for (HInstruction type in node.inputs) { 2859 for (HInstruction type in node.inputs) {
2857 use(type); 2860 use(type);
2858 typeArguments.add(pop()); 2861 typeArguments.add(pop());
2859 } 2862 }
2860 2863
2861 ClassElement cls = node.dartType.element; 2864 ClassElement cls = node.dartType.element;
2862 var arguments = [backend.emitter.typeAccess(cls)]; 2865 var arguments = [backend.emitter.typeAccess(cls)];
2863 if (!typeArguments.isEmpty) { 2866 if (!typeArguments.isEmpty) {
2864 arguments.add(new js.ArrayInitializer(typeArguments)); 2867 arguments.add(new js.ArrayInitializer(typeArguments));
2865 } 2868 }
2866 push(js.js('#(#)', [accessHelper('buildInterfaceType'), arguments])); 2869 push(js.js('#(#)', [accessHelper('buildInterfaceType'), arguments]));
2867 } 2870 }
2868 2871
2869 void visitVoidType(HVoidType node) { 2872 void visitVoidType(HVoidType node) {
2870 push(js.js('#()', accessHelper('getVoidRuntimeType'))); 2873 push(js.js('#()', accessHelper('getVoidRuntimeType')));
2871 } 2874 }
2872 2875
2873 void visitDynamicType(HDynamicType node) { 2876 void visitDynamicType(HDynamicType node) {
2874 push(js.js('#()', accessHelper('getDynamicRuntimeType'))); 2877 push(js.js('#()', accessHelper('getDynamicRuntimeType')));
2875 } 2878 }
2876 2879
2877 js.PropertyAccess accessHelper(String name) { 2880 js.PropertyAccess accessHelper(String name) {
2878 Element helper = backend.findHelper(name); 2881 Element helper = helpers.findHelper(name);
2879 if (helper == null) { 2882 if (helper == null) {
2880 // For mocked-up tests. 2883 // For mocked-up tests.
2881 return js.js('(void 0).$name'); 2884 return js.js('(void 0).$name');
2882 } 2885 }
2883 registry.registerStaticUse(helper); 2886 registry.registerStaticUse(helper);
2884 return backend.emitter.staticFunctionAccess(helper); 2887 return backend.emitter.staticFunctionAccess(helper);
2885 } 2888 }
2886 2889
2887 @override 2890 @override
2888 void visitRef(HRef node) { 2891 void visitRef(HRef node) {
2889 visit(node.value); 2892 visit(node.value);
2890 } 2893 }
2891 } 2894 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/ssa/builder.dart ('k') | pkg/compiler/lib/src/ssa/interceptor_simplifier.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698