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

Side by Side Diff: pkg/compiler/lib/src/ssa/builder.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
« no previous file with comments | « pkg/compiler/lib/src/patch_parser.dart ('k') | pkg/compiler/lib/src/ssa/codegen.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) 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 final SsaCodeGeneratorTask generator; 8 final SsaCodeGeneratorTask generator;
9 final SsaBuilderTask builder; 9 final SsaBuilderTask builder;
10 final SsaOptimizerTask optimizer; 10 final SsaOptimizerTask optimizer;
(...skipping 1673 matching lines...) Expand 10 before | Expand all | Expand 10 after
1684 }, 1684 },
1685 visitElse: null, 1685 visitElse: null,
1686 sourceInformation: sourceInformationBuilder.buildIf(function.body)); 1686 sourceInformation: sourceInformationBuilder.buildIf(function.body));
1687 } 1687 }
1688 } 1688 }
1689 if (const bool.fromEnvironment('unreachable-throw') == true) { 1689 if (const bool.fromEnvironment('unreachable-throw') == true) {
1690 var emptyParameters = parameters.values.where((p) => 1690 var emptyParameters = parameters.values.where((p) =>
1691 p.instructionType.isEmpty && !p.instructionType.isNullable); 1691 p.instructionType.isEmpty && !p.instructionType.isNullable);
1692 if (emptyParameters.length > 0) { 1692 if (emptyParameters.length > 0) {
1693 addComment('${emptyParameters} inferred as [empty]'); 1693 addComment('${emptyParameters} inferred as [empty]');
1694 pushInvokeStatic(function.body, backend.assertUnreachableMethod, []); 1694 pushInvokeStatic(function.body, helpers.assertUnreachableMethod, []);
1695 pop(); 1695 pop();
1696 return closeFunction(); 1696 return closeFunction();
1697 } 1697 }
1698 } 1698 }
1699 function.body.accept(this); 1699 function.body.accept(this);
1700 return closeFunction(); 1700 return closeFunction();
1701 } 1701 }
1702 1702
1703 /// Adds a JavaScript comment to the output. The comment will be omitted in 1703 /// Adds a JavaScript comment to the output. The comment will be omitted in
1704 /// minified mode. Each line in [text] is preceded with `//` and indented. 1704 /// minified mode. Each line in [text] is preceded with `//` and indented.
(...skipping 849 matching lines...) Expand 10 before | Expand all | Expand 10 after
2554 original, typeVariable); 2554 original, typeVariable);
2555 } else if (type.isFunctionType) { 2555 } else if (type.isFunctionType) {
2556 String name = kind == HTypeConversion.CAST_TYPE_CHECK 2556 String name = kind == HTypeConversion.CAST_TYPE_CHECK
2557 ? '_asCheck' : '_assertCheck'; 2557 ? '_asCheck' : '_assertCheck';
2558 2558
2559 List<HInstruction> arguments = 2559 List<HInstruction> arguments =
2560 <HInstruction>[buildFunctionType(type), original]; 2560 <HInstruction>[buildFunctionType(type), original];
2561 pushInvokeDynamic( 2561 pushInvokeDynamic(
2562 null, 2562 null,
2563 new Selector.call( 2563 new Selector.call(
2564 new Name(name, backend.jsHelperLibrary), CallStructure.ONE_ARG), 2564 new Name(name, helpers.jsHelperLibrary), CallStructure.ONE_ARG),
2565 null, 2565 null,
2566 arguments); 2566 arguments);
2567 2567
2568 return new HTypeConversion(type, kind, original.instructionType, pop()); 2568 return new HTypeConversion(type, kind, original.instructionType, pop());
2569 } else { 2569 } else {
2570 return original.convertType(compiler, type, kind); 2570 return original.convertType(compiler, type, kind);
2571 } 2571 }
2572 } 2572 }
2573 2573
2574 HInstruction _trustType(HInstruction original, DartType type) { 2574 HInstruction _trustType(HInstruction original, DartType type) {
(...skipping 1293 matching lines...) Expand 10 before | Expand all | Expand 10 after
3868 3868
3869 HInstruction buildIsNode(ast.Node node, 3869 HInstruction buildIsNode(ast.Node node,
3870 DartType type, 3870 DartType type,
3871 HInstruction expression) { 3871 HInstruction expression) {
3872 type = localsHandler.substInContext(type).unaliased; 3872 type = localsHandler.substInContext(type).unaliased;
3873 if (type.isFunctionType) { 3873 if (type.isFunctionType) {
3874 List arguments = [buildFunctionType(type), expression]; 3874 List arguments = [buildFunctionType(type), expression];
3875 pushInvokeDynamic( 3875 pushInvokeDynamic(
3876 node, 3876 node,
3877 new Selector.call( 3877 new Selector.call(
3878 new PrivateName('_isTest', backend.jsHelperLibrary), 3878 new PrivateName('_isTest', helpers.jsHelperLibrary),
3879 CallStructure.ONE_ARG), 3879 CallStructure.ONE_ARG),
3880 null, 3880 null,
3881 arguments); 3881 arguments);
3882 return new HIs.compound(type, expression, pop(), backend.boolType); 3882 return new HIs.compound(type, expression, pop(), backend.boolType);
3883 } else if (type.isTypeVariable) { 3883 } else if (type.isTypeVariable) {
3884 HInstruction runtimeType = addTypeVariableReference(type); 3884 HInstruction runtimeType = addTypeVariableReference(type);
3885 Element helper = helpers.checkSubtypeOfRuntimeType; 3885 Element helper = helpers.checkSubtypeOfRuntimeType;
3886 List<HInstruction> inputs = <HInstruction>[expression, runtimeType]; 3886 List<HInstruction> inputs = <HInstruction>[expression, runtimeType];
3887 pushInvokeStatic(null, helper, inputs, typeMask: backend.boolType); 3887 pushInvokeStatic(null, helper, inputs, typeMask: backend.boolType);
3888 HInstruction call = pop(); 3888 HInstruction call = pop();
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after
4195 // If the isolate library is not used, we just generate code 4195 // If the isolate library is not used, we just generate code
4196 // to fetch the static state. 4196 // to fetch the static state.
4197 String name = backend.namer.staticStateHolder; 4197 String name = backend.namer.staticStateHolder;
4198 push(new HForeignCode(js.js.parseForeignJS(name), 4198 push(new HForeignCode(js.js.parseForeignJS(name),
4199 backend.dynamicType, 4199 backend.dynamicType,
4200 <HInstruction>[])); 4200 <HInstruction>[]));
4201 } else { 4201 } else {
4202 // Call a helper method from the isolate library. The isolate 4202 // Call a helper method from the isolate library. The isolate
4203 // library uses its own isolate structure, that encapsulates 4203 // library uses its own isolate structure, that encapsulates
4204 // Leg's isolate. 4204 // Leg's isolate.
4205 Element element = backend.isolateHelperLibrary.find('_currentIsolate'); 4205 Element element = helpers.currentIsolate;
4206 if (element == null) { 4206 if (element == null) {
4207 reporter.internalError(node, 4207 reporter.internalError(node,
4208 'Isolate library and compiler mismatch.'); 4208 'Isolate library and compiler mismatch.');
4209 } 4209 }
4210 pushInvokeStatic(null, element, [], typeMask: backend.dynamicType); 4210 pushInvokeStatic(null, element, [], typeMask: backend.dynamicType);
4211 } 4211 }
4212 } 4212 }
4213 4213
4214 void handleForeignJsGetFlag(ast.Send node) { 4214 void handleForeignJsGetFlag(ast.Send node) {
4215 List<ast.Node> arguments = node.arguments.toList(); 4215 List<ast.Node> arguments = node.arguments.toList();
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
4270 for (int i = 1; i < arguments.length; i++) { 4270 for (int i = 1; i < arguments.length; i++) {
4271 reporter.reportErrorMessage( 4271 reporter.reportErrorMessage(
4272 arguments[i], MessageKind.GENERIC, 4272 arguments[i], MessageKind.GENERIC,
4273 {'text': 'Error: Extra argument to JS_GET_NAME.'}); 4273 {'text': 'Error: Extra argument to JS_GET_NAME.'});
4274 } 4274 }
4275 return; 4275 return;
4276 } 4276 }
4277 Element element = elements[argument]; 4277 Element element = elements[argument];
4278 if (element == null || 4278 if (element == null ||
4279 element is! FieldElement || 4279 element is! FieldElement ||
4280 element.enclosingClass != backend.jsGetNameEnum) { 4280 element.enclosingClass != helpers.jsGetNameEnum) {
4281 reporter.reportErrorMessage( 4281 reporter.reportErrorMessage(
4282 argument, MessageKind.GENERIC, 4282 argument, MessageKind.GENERIC,
4283 {'text': 'Error: Expected a JsGetName enum value.'}); 4283 {'text': 'Error: Expected a JsGetName enum value.'});
4284 } 4284 }
4285 EnumClassElement enumClass = element.enclosingClass; 4285 EnumClassElement enumClass = element.enclosingClass;
4286 int index = enumClass.enumValues.indexOf(element); 4286 int index = enumClass.enumValues.indexOf(element);
4287 stack.add( 4287 stack.add(
4288 addConstantStringFromName( 4288 addConstantStringFromName(
4289 backend.namer.getNameForJsGetName( 4289 backend.namer.getNameForJsGetName(
4290 argument, JsGetName.values[index]))); 4290 argument, JsGetName.values[index])));
4291 } 4291 }
4292 4292
4293 void handleForeignJsBuiltin(ast.Send node) { 4293 void handleForeignJsBuiltin(ast.Send node) {
4294 List<ast.Node> arguments = node.arguments.toList(); 4294 List<ast.Node> arguments = node.arguments.toList();
4295 ast.Node argument; 4295 ast.Node argument;
4296 if (arguments.length < 2) { 4296 if (arguments.length < 2) {
4297 reporter.reportErrorMessage( 4297 reporter.reportErrorMessage(
4298 node, MessageKind.GENERIC, 4298 node, MessageKind.GENERIC,
4299 {'text': 'Error: Expected at least two arguments to JS_BUILTIN.'}); 4299 {'text': 'Error: Expected at least two arguments to JS_BUILTIN.'});
4300 } 4300 }
4301 4301
4302 Element builtinElement = elements[arguments[1]]; 4302 Element builtinElement = elements[arguments[1]];
4303 if (builtinElement == null || 4303 if (builtinElement == null ||
4304 (builtinElement is! FieldElement) || 4304 (builtinElement is! FieldElement) ||
4305 builtinElement.enclosingClass != backend.jsBuiltinEnum) { 4305 builtinElement.enclosingClass != helpers.jsBuiltinEnum) {
4306 reporter.reportErrorMessage( 4306 reporter.reportErrorMessage(
4307 argument, MessageKind.GENERIC, 4307 argument, MessageKind.GENERIC,
4308 {'text': 'Error: Expected a JsBuiltin enum value.'}); 4308 {'text': 'Error: Expected a JsBuiltin enum value.'});
4309 } 4309 }
4310 EnumClassElement enumClass = builtinElement.enclosingClass; 4310 EnumClassElement enumClass = builtinElement.enclosingClass;
4311 int index = enumClass.enumValues.indexOf(builtinElement); 4311 int index = enumClass.enumValues.indexOf(builtinElement);
4312 4312
4313 js.Template template = 4313 js.Template template =
4314 backend.emitter.builtinTemplateFor(JsBuiltin.values[index]); 4314 backend.emitter.builtinTemplateFor(JsBuiltin.values[index]);
4315 4315
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
4404 Link<ast.Node> link = node.arguments; 4404 Link<ast.Node> link = node.arguments;
4405 if (!compiler.hasIsolateSupport) { 4405 if (!compiler.hasIsolateSupport) {
4406 // If the isolate library is not used, we just invoke the 4406 // If the isolate library is not used, we just invoke the
4407 // closure. 4407 // closure.
4408 visit(link.tail.head); 4408 visit(link.tail.head);
4409 push(new HInvokeClosure(new Selector.callClosure(0), 4409 push(new HInvokeClosure(new Selector.callClosure(0),
4410 <HInstruction>[pop()], 4410 <HInstruction>[pop()],
4411 backend.dynamicType)); 4411 backend.dynamicType));
4412 } else { 4412 } else {
4413 // Call a helper method from the isolate library. 4413 // Call a helper method from the isolate library.
4414 Element element = backend.isolateHelperLibrary.find('_callInIsolate'); 4414 Element element = helpers.callInIsolate;
4415 if (element == null) { 4415 if (element == null) {
4416 reporter.internalError(node, 4416 reporter.internalError(node,
4417 'Isolate library and compiler mismatch.'); 4417 'Isolate library and compiler mismatch.');
4418 } 4418 }
4419 List<HInstruction> inputs = <HInstruction>[]; 4419 List<HInstruction> inputs = <HInstruction>[];
4420 addGenericSendArgumentsToList(link, inputs); 4420 addGenericSendArgumentsToList(link, inputs);
4421 pushInvokeStatic(node, element, inputs, typeMask: backend.dynamicType); 4421 pushInvokeStatic(node, element, inputs, typeMask: backend.dynamicType);
4422 } 4422 }
4423 } 4423 }
4424 4424
(...skipping 656 matching lines...) Expand 10 before | Expand all | Expand 10 after
5081 5081
5082 Element constructor = elements[send]; 5082 Element constructor = elements[send];
5083 CallStructure callStructure = elements.getSelector(send).callStructure; 5083 CallStructure callStructure = elements.getSelector(send).callStructure;
5084 ConstructorElement constructorDeclaration = constructor; 5084 ConstructorElement constructorDeclaration = constructor;
5085 ConstructorElement constructorImplementation = constructor.implementation; 5085 ConstructorElement constructorImplementation = constructor.implementation;
5086 constructor = constructorImplementation.effectiveTarget; 5086 constructor = constructorImplementation.effectiveTarget;
5087 5087
5088 final bool isSymbolConstructor = 5088 final bool isSymbolConstructor =
5089 constructorDeclaration == compiler.symbolConstructor; 5089 constructorDeclaration == compiler.symbolConstructor;
5090 final bool isJSArrayTypedConstructor = 5090 final bool isJSArrayTypedConstructor =
5091 constructorDeclaration == backend.jsArrayTypedConstructor; 5091 constructorDeclaration == helpers.jsArrayTypedConstructor;
5092 5092
5093 if (isSymbolConstructor) { 5093 if (isSymbolConstructor) {
5094 constructor = compiler.symbolValidatedConstructor; 5094 constructor = compiler.symbolValidatedConstructor;
5095 assert(invariant(send, constructor != null, 5095 assert(invariant(send, constructor != null,
5096 message: 'Constructor Symbol.validated is missing')); 5096 message: 'Constructor Symbol.validated is missing'));
5097 callStructure = compiler.symbolValidatedConstructorSelector.callStructure; 5097 callStructure = compiler.symbolValidatedConstructorSelector.callStructure;
5098 assert(invariant(send, callStructure != null, 5098 assert(invariant(send, callStructure != null,
5099 message: 'Constructor Symbol.validated is missing')); 5099 message: 'Constructor Symbol.validated is missing'));
5100 } 5100 }
5101 5101
(...skipping 673 matching lines...) Expand 10 before | Expand all | Expand 10 after
5775 // We prefer to not inline certain operations on indexables, 5775 // We prefer to not inline certain operations on indexables,
5776 // because the constant folder will handle them better and turn 5776 // because the constant folder will handle them better and turn
5777 // them into simpler instructions that allow further 5777 // them into simpler instructions that allow further
5778 // optimizations. 5778 // optimizations.
5779 bool isOptimizableOperationOnIndexable(Selector selector, Element element) { 5779 bool isOptimizableOperationOnIndexable(Selector selector, Element element) {
5780 bool isLength = selector.isGetter 5780 bool isLength = selector.isGetter
5781 && selector.name == "length"; 5781 && selector.name == "length";
5782 if (isLength || selector.isIndex) { 5782 if (isLength || selector.isIndex) {
5783 return compiler.world.isSubtypeOf( 5783 return compiler.world.isSubtypeOf(
5784 element.enclosingClass.declaration, 5784 element.enclosingClass.declaration,
5785 backend.jsIndexableClass); 5785 helpers.jsIndexableClass);
5786 } else if (selector.isIndexSet) { 5786 } else if (selector.isIndexSet) {
5787 return compiler.world.isSubtypeOf( 5787 return compiler.world.isSubtypeOf(
5788 element.enclosingClass.declaration, 5788 element.enclosingClass.declaration,
5789 backend.jsMutableIndexableClass); 5789 helpers.jsMutableIndexableClass);
5790 } else { 5790 } else {
5791 return false; 5791 return false;
5792 } 5792 }
5793 } 5793 }
5794 5794
5795 bool isOptimizableOperation(Selector selector, Element element) { 5795 bool isOptimizableOperation(Selector selector, Element element) {
5796 ClassElement cls = element.enclosingClass; 5796 ClassElement cls = element.enclosingClass;
5797 if (isOptimizableOperationOnIndexable(selector, element)) return true; 5797 if (isOptimizableOperationOnIndexable(selector, element)) return true;
5798 if (!backend.interceptedClasses.contains(cls)) return false; 5798 if (!backend.interceptedClasses.contains(cls)) return false;
5799 if (selector.isOperator) return true; 5799 if (selector.isOperator) return true;
5800 if (selector.isSetter) return true; 5800 if (selector.isSetter) return true;
5801 if (selector.isIndex) return true; 5801 if (selector.isIndex) return true;
5802 if (selector.isIndexSet) return true; 5802 if (selector.isIndexSet) return true;
5803 if (element == backend.jsArrayAdd 5803 if (element == helpers.jsArrayAdd ||
5804 || element == backend.jsArrayRemoveLast 5804 element == helpers.jsArrayRemoveLast ||
5805 || element == backend.jsStringSplit) { 5805 element == helpers.jsStringSplit) {
5806 return true; 5806 return true;
5807 } 5807 }
5808 return false; 5808 return false;
5809 } 5809 }
5810 5810
5811 Element element = compiler.world.locateSingleElement(selector, mask); 5811 Element element = compiler.world.locateSingleElement(selector, mask);
5812 if (element != null && 5812 if (element != null &&
5813 !element.isField && 5813 !element.isField &&
5814 !(element.isGetter && selector.isCall) && 5814 !(element.isGetter && selector.isCall) &&
5815 !(element.isFunction && selector.isGetter) && 5815 !(element.isFunction && selector.isGetter) &&
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
5915 if (element.isConstructor) { 5915 if (element.isConstructor) {
5916 codeTemplate = js.js.parseForeignJS("new #(${argsStub.join(",")})"); 5916 codeTemplate = js.js.parseForeignJS("new #(${argsStub.join(",")})");
5917 } else { 5917 } else {
5918 codeTemplate = js.js.parseForeignJS("#(${argsStub.join(",")})"); 5918 codeTemplate = js.js.parseForeignJS("#(${argsStub.join(",")})");
5919 } 5919 }
5920 } 5920 }
5921 5921
5922 var nativeBehavior = new native.NativeBehavior() 5922 var nativeBehavior = new native.NativeBehavior()
5923 ..codeTemplate = codeTemplate 5923 ..codeTemplate = codeTemplate
5924 ..typesReturned.add( 5924 ..typesReturned.add(
5925 backend.jsJavaScriptObjectClass.thisType) 5925 helpers.jsJavaScriptObjectClass.thisType)
5926 ..typesInstantiated.add( 5926 ..typesInstantiated.add(
5927 backend.jsJavaScriptObjectClass.thisType) 5927 helpers.jsJavaScriptObjectClass.thisType)
5928 ..sideEffects.setAllSideEffects(); 5928 ..sideEffects.setAllSideEffects();
5929 return new HForeignCode( 5929 return new HForeignCode(
5930 codeTemplate, 5930 codeTemplate,
5931 backend.dynamicType, inputs, 5931 backend.dynamicType, inputs,
5932 nativeBehavior: nativeBehavior) 5932 nativeBehavior: nativeBehavior)
5933 ..sourceInformation = sourceInformation; 5933 ..sourceInformation = sourceInformation;
5934 } 5934 }
5935 5935
5936 void pushInvokeStatic(ast.Node location, 5936 void pushInvokeStatic(ast.Node location,
5937 Element element, 5937 Element element,
(...skipping 1496 matching lines...) Expand 10 before | Expand all | Expand 10 after
7434 // This scheme recognizes for-in on direct lists. It does not recognize all 7434 // This scheme recognizes for-in on direct lists. It does not recognize all
7435 // uses of ArrayIterator. They still occur when the receiver is an Iterable 7435 // uses of ArrayIterator. They still occur when the receiver is an Iterable
7436 // with a `get iterator` method that delegate to another Iterable and the 7436 // with a `get iterator` method that delegate to another Iterable and the
7437 // method is inlined. We would require full scalar replacement in that 7437 // method is inlined. We would require full scalar replacement in that
7438 // case. 7438 // case.
7439 7439
7440 Selector selector = elements.getIteratorSelector(node); 7440 Selector selector = elements.getIteratorSelector(node);
7441 TypeMask mask = elements.getIteratorTypeMask(node); 7441 TypeMask mask = elements.getIteratorTypeMask(node);
7442 7442
7443 ClassWorld classWorld = compiler.world; 7443 ClassWorld classWorld = compiler.world;
7444 if (mask != null && mask.satisfies(backend.jsIndexableClass, classWorld)) { 7444 if (mask != null && mask.satisfies(helpers.jsIndexableClass, classWorld)) {
7445 return buildSyncForInIndexable(node, mask); 7445 return buildSyncForInIndexable(node, mask);
7446 } 7446 }
7447 buildSyncForInIterator(node); 7447 buildSyncForInIterator(node);
7448 } 7448 }
7449 7449
7450 buildSyncForInIterator(ast.SyncForIn node) { 7450 buildSyncForInIterator(ast.SyncForIn node) {
7451 // Generate a structure equivalent to: 7451 // Generate a structure equivalent to:
7452 // Iterator<E> $iter = <iterable>.iterator; 7452 // Iterator<E> $iter = <iterable>.iterator;
7453 // while ($iter.moveNext()) { 7453 // while ($iter.moveNext()) {
7454 // <declaredIdentifier> = $iter.current; 7454 // <declaredIdentifier> = $iter.current;
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
7521 Element loopVariable = elements.getForInVariable(node); 7521 Element loopVariable = elements.getForInVariable(node);
7522 SyntheticLocal indexVariable = new SyntheticLocal('_i', loopVariable); 7522 SyntheticLocal indexVariable = new SyntheticLocal('_i', loopVariable);
7523 TypeMask boolType = backend.boolType; 7523 TypeMask boolType = backend.boolType;
7524 7524
7525 // These variables are shared by initializer, condition, body and update. 7525 // These variables are shared by initializer, condition, body and update.
7526 HInstruction array; // Set in buildInitializer. 7526 HInstruction array; // Set in buildInitializer.
7527 bool isFixed; // Set in buildInitializer. 7527 bool isFixed; // Set in buildInitializer.
7528 HInstruction originalLength = null; // Set for growable lists. 7528 HInstruction originalLength = null; // Set for growable lists.
7529 7529
7530 HInstruction buildGetLength() { 7530 HInstruction buildGetLength() {
7531 Element lengthElement = backend.jsIndexableLength; 7531 Element lengthElement = helpers.jsIndexableLength;
7532 HFieldGet result = new HFieldGet( 7532 HFieldGet result = new HFieldGet(
7533 lengthElement, array, backend.positiveIntType, 7533 lengthElement, array, backend.positiveIntType,
7534 isAssignable: !isFixed); 7534 isAssignable: !isFixed);
7535 add(result); 7535 add(result);
7536 return result; 7536 return result;
7537 } 7537 }
7538 7538
7539 void buildConcurrentModificationErrorCheck() { 7539 void buildConcurrentModificationErrorCheck() {
7540 if (originalLength == null) return; 7540 if (originalLength == null) return;
7541 // The static call checkConcurrentModificationError() is expanded in 7541 // The static call checkConcurrentModificationError() is expanded in
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
7667 link = link.tail) { 7667 link = link.tail) {
7668 visit(link.head); 7668 visit(link.head);
7669 listInputs.add(pop()); 7669 listInputs.add(pop());
7670 listInputs.add(pop()); 7670 listInputs.add(pop());
7671 } 7671 }
7672 7672
7673 Element constructor; 7673 Element constructor;
7674 List<HInstruction> inputs = <HInstruction>[]; 7674 List<HInstruction> inputs = <HInstruction>[];
7675 7675
7676 if (listInputs.isEmpty) { 7676 if (listInputs.isEmpty) {
7677 constructor = backend.mapLiteralConstructorEmpty; 7677 constructor = helpers.mapLiteralConstructorEmpty;
7678 } else { 7678 } else {
7679 constructor = backend.mapLiteralConstructor; 7679 constructor = helpers.mapLiteralConstructor;
7680 HLiteralList keyValuePairs = buildLiteralList(listInputs); 7680 HLiteralList keyValuePairs = buildLiteralList(listInputs);
7681 add(keyValuePairs); 7681 add(keyValuePairs);
7682 inputs.add(keyValuePairs); 7682 inputs.add(keyValuePairs);
7683 } 7683 }
7684 7684
7685 assert(constructor.isFactoryConstructor); 7685 assert(constructor.isFactoryConstructor);
7686 7686
7687 ConstructorElement functionElement = constructor; 7687 ConstructorElement functionElement = constructor;
7688 constructor = functionElement.effectiveTarget; 7688 constructor = functionElement.effectiveTarget;
7689 7689
7690 InterfaceType type = elements.getType(node); 7690 InterfaceType type = elements.getType(node);
7691 InterfaceType expectedType = 7691 InterfaceType expectedType =
7692 functionElement.computeEffectiveTargetType(type); 7692 functionElement.computeEffectiveTargetType(type);
7693 expectedType = localsHandler.substInContext(expectedType); 7693 expectedType = localsHandler.substInContext(expectedType);
7694 7694
7695 ClassElement cls = constructor.enclosingClass; 7695 ClassElement cls = constructor.enclosingClass;
7696 7696
7697 if (backend.classNeedsRti(cls)) { 7697 if (backend.classNeedsRti(cls)) {
7698 List<HInstruction> typeInputs = <HInstruction>[]; 7698 List<HInstruction> typeInputs = <HInstruction>[];
7699 expectedType.typeArguments.forEach((DartType argument) { 7699 expectedType.typeArguments.forEach((DartType argument) {
7700 typeInputs.add(analyzeTypeArgument(argument)); 7700 typeInputs.add(analyzeTypeArgument(argument));
7701 }); 7701 });
7702 7702
7703 // We lift this common call pattern into a helper function to save space 7703 // We lift this common call pattern into a helper function to save space
7704 // in the output. 7704 // in the output.
7705 if (typeInputs.every((HInstruction input) => input.isNull())) { 7705 if (typeInputs.every((HInstruction input) => input.isNull())) {
7706 if (listInputs.isEmpty) { 7706 if (listInputs.isEmpty) {
7707 constructor = backend.mapLiteralUntypedEmptyMaker; 7707 constructor = helpers.mapLiteralUntypedEmptyMaker;
7708 } else { 7708 } else {
7709 constructor = backend.mapLiteralUntypedMaker; 7709 constructor = helpers.mapLiteralUntypedMaker;
7710 } 7710 }
7711 } else { 7711 } else {
7712 inputs.addAll(typeInputs); 7712 inputs.addAll(typeInputs);
7713 } 7713 }
7714 } 7714 }
7715 7715
7716 // If rti is needed and the map literal has no type parameters, 7716 // If rti is needed and the map literal has no type parameters,
7717 // 'constructor' is a static function that forwards the call to the factory 7717 // 'constructor' is a static function that forwards the call to the factory
7718 // constructor without type parameters. 7718 // constructor without type parameters.
7719 assert(constructor is ConstructorElement || constructor is FunctionElement); 7719 assert(constructor is ConstructorElement || constructor is FunctionElement);
7720 7720
7721 // The instruction type will always be a subtype of the mapLiteralClass, but 7721 // The instruction type will always be a subtype of the mapLiteralClass, but
7722 // type inference might discover a more specific type, or find nothing (in 7722 // type inference might discover a more specific type, or find nothing (in
7723 // dart2js unit tests). 7723 // dart2js unit tests).
7724 TypeMask mapType = 7724 TypeMask mapType =
7725 new TypeMask.nonNullSubtype(backend.mapLiteralClass, compiler.world); 7725 new TypeMask.nonNullSubtype(helpers.mapLiteralClass, compiler.world);
7726 TypeMask returnTypeMask = TypeMaskFactory.inferredReturnTypeForElement( 7726 TypeMask returnTypeMask = TypeMaskFactory.inferredReturnTypeForElement(
7727 constructor, compiler); 7727 constructor, compiler);
7728 TypeMask instructionType = 7728 TypeMask instructionType =
7729 mapType.intersection(returnTypeMask, compiler.world); 7729 mapType.intersection(returnTypeMask, compiler.world);
7730 7730
7731 addInlinedInstantiation(expectedType); 7731 addInlinedInstantiation(expectedType);
7732 pushInvokeStatic(node, constructor, inputs, 7732 pushInvokeStatic(node, constructor, inputs,
7733 typeMask: instructionType, instanceType: expectedType); 7733 typeMask: instructionType, instanceType: expectedType);
7734 removeInlinedInstantiation(expectedType); 7734 removeInlinedInstantiation(expectedType);
7735 } 7735 }
(...skipping 1321 matching lines...) Expand 10 before | Expand all | Expand 10 after
9057 } 9057 }
9058 9058
9059 class TypeBuilder implements DartTypeVisitor<dynamic, SsaBuilder> { 9059 class TypeBuilder implements DartTypeVisitor<dynamic, SsaBuilder> {
9060 final ClassWorld classWorld; 9060 final ClassWorld classWorld;
9061 9061
9062 TypeBuilder(this.classWorld); 9062 TypeBuilder(this.classWorld);
9063 9063
9064 void visit(DartType type, SsaBuilder builder) => type.accept(this, builder); 9064 void visit(DartType type, SsaBuilder builder) => type.accept(this, builder);
9065 9065
9066 void visitVoidType(VoidType type, SsaBuilder builder) { 9066 void visitVoidType(VoidType type, SsaBuilder builder) {
9067 ClassElement cls = builder.backend.findHelper('VoidRuntimeType'); 9067 ClassElement cls = builder.backend.helpers.VoidRuntimeType;
9068 builder.push(new HVoidType(type, new TypeMask.exact(cls, classWorld))); 9068 builder.push(new HVoidType(type, new TypeMask.exact(cls, classWorld)));
9069 } 9069 }
9070 9070
9071 void visitTypeVariableType(TypeVariableType type, 9071 void visitTypeVariableType(TypeVariableType type,
9072 SsaBuilder builder) { 9072 SsaBuilder builder) {
9073 ClassElement cls = builder.backend.findHelper('RuntimeType'); 9073 ClassElement cls = builder.backend.helpers.RuntimeType;
9074 TypeMask instructionType = new TypeMask.subclass(cls, classWorld); 9074 TypeMask instructionType = new TypeMask.subclass(cls, classWorld);
9075 if (!builder.sourceElement.enclosingElement.isClosure && 9075 if (!builder.sourceElement.enclosingElement.isClosure &&
9076 builder.sourceElement.isInstanceMember) { 9076 builder.sourceElement.isInstanceMember) {
9077 HInstruction receiver = builder.localsHandler.readThis(); 9077 HInstruction receiver = builder.localsHandler.readThis();
9078 builder.push(new HReadTypeVariable(type, receiver, instructionType)); 9078 builder.push(new HReadTypeVariable(type, receiver, instructionType));
9079 } else { 9079 } else {
9080 builder.push( 9080 builder.push(
9081 new HReadTypeVariable.noReceiver( 9081 new HReadTypeVariable.noReceiver(
9082 type, builder.addTypeVariableReference(type), instructionType)); 9082 type, builder.addTypeVariableReference(type), instructionType));
9083 } 9083 }
(...skipping 17 matching lines...) Expand all
9101 List<DartType> namedParameterTypes = type.namedParameterTypes; 9101 List<DartType> namedParameterTypes = type.namedParameterTypes;
9102 List<String> names = type.namedParameters; 9102 List<String> names = type.namedParameters;
9103 for (int index = 0; index < names.length; index++) { 9103 for (int index = 0; index < names.length; index++) {
9104 ast.DartString dartString = new ast.DartString.literal(names[index]); 9104 ast.DartString dartString = new ast.DartString.literal(names[index]);
9105 inputs.add( 9105 inputs.add(
9106 builder.graph.addConstantString(dartString, builder.compiler)); 9106 builder.graph.addConstantString(dartString, builder.compiler));
9107 namedParameterTypes[index].accept(this, builder); 9107 namedParameterTypes[index].accept(this, builder);
9108 inputs.add(builder.pop()); 9108 inputs.add(builder.pop());
9109 } 9109 }
9110 9110
9111 ClassElement cls = builder.backend.findHelper('RuntimeFunctionType'); 9111 ClassElement cls = builder.backend.helpers.RuntimeFunctionType;
9112 builder.push(new HFunctionType(inputs, type, 9112 builder.push(new HFunctionType(inputs, type,
9113 new TypeMask.exact(cls, classWorld))); 9113 new TypeMask.exact(cls, classWorld)));
9114 } 9114 }
9115 9115
9116 void visitMalformedType(MalformedType type, SsaBuilder builder) { 9116 void visitMalformedType(MalformedType type, SsaBuilder builder) {
9117 visitDynamicType(const DynamicType(), builder); 9117 visitDynamicType(const DynamicType(), builder);
9118 } 9118 }
9119 9119
9120 void visitStatementType(StatementType type, SsaBuilder builder) { 9120 void visitStatementType(StatementType type, SsaBuilder builder) {
9121 throw 'not implemented visitStatementType($type)'; 9121 throw 'not implemented visitStatementType($type)';
9122 } 9122 }
9123 9123
9124 void visitInterfaceType(InterfaceType type, SsaBuilder builder) { 9124 void visitInterfaceType(InterfaceType type, SsaBuilder builder) {
9125 List<HInstruction> inputs = <HInstruction>[]; 9125 List<HInstruction> inputs = <HInstruction>[];
9126 for (DartType typeArgument in type.typeArguments) { 9126 for (DartType typeArgument in type.typeArguments) {
9127 typeArgument.accept(this, builder); 9127 typeArgument.accept(this, builder);
9128 inputs.add(builder.pop()); 9128 inputs.add(builder.pop());
9129 } 9129 }
9130 ClassElement cls; 9130 ClassElement cls;
9131 if (type.typeArguments.isEmpty) { 9131 if (type.typeArguments.isEmpty) {
9132 cls = builder.backend.findHelper('RuntimeTypePlain'); 9132 cls = builder.backend.helpers.RuntimeTypePlain;
9133 } else { 9133 } else {
9134 cls = builder.backend.findHelper('RuntimeTypeGeneric'); 9134 cls = builder.backend.helpers.RuntimeTypeGeneric;
9135 } 9135 }
9136 builder.push(new HInterfaceType(inputs, type, 9136 builder.push(new HInterfaceType(inputs, type,
9137 new TypeMask.exact(cls, classWorld))); 9137 new TypeMask.exact(cls, classWorld)));
9138 } 9138 }
9139 9139
9140 void visitTypedefType(TypedefType type, SsaBuilder builder) { 9140 void visitTypedefType(TypedefType type, SsaBuilder builder) {
9141 DartType unaliased = type.unaliased; 9141 DartType unaliased = type.unaliased;
9142 if (unaliased is TypedefType) throw 'unable to unalias $type'; 9142 if (unaliased is TypedefType) throw 'unable to unalias $type';
9143 unaliased.accept(this, builder); 9143 unaliased.accept(this, builder);
9144 } 9144 }
9145 9145
9146 void visitDynamicType(DynamicType type, SsaBuilder builder) { 9146 void visitDynamicType(DynamicType type, SsaBuilder builder) {
9147 JavaScriptBackend backend = builder.compiler.backend; 9147 JavaScriptBackend backend = builder.compiler.backend;
9148 ClassElement cls = backend.findHelper('DynamicRuntimeType'); 9148 ClassElement cls = backend.helpers.DynamicRuntimeType;
9149 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld))); 9149 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld)));
9150 } 9150 }
9151 } 9151 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/patch_parser.dart ('k') | pkg/compiler/lib/src/ssa/codegen.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698