OLD | NEW |
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 3218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3229 ClosureClassMap nestedClosureData = | 3229 ClosureClassMap nestedClosureData = |
3230 compiler.closureToClassMapper.getMappingForNestedFunction(node); | 3230 compiler.closureToClassMapper.getMappingForNestedFunction(node); |
3231 assert(nestedClosureData != null); | 3231 assert(nestedClosureData != null); |
3232 assert(nestedClosureData.closureClassElement != null); | 3232 assert(nestedClosureData.closureClassElement != null); |
3233 ClosureClassElement closureClassElement = | 3233 ClosureClassElement closureClassElement = |
3234 nestedClosureData.closureClassElement; | 3234 nestedClosureData.closureClassElement; |
3235 FunctionElement callElement = nestedClosureData.callElement; | 3235 FunctionElement callElement = nestedClosureData.callElement; |
3236 // TODO(ahe): This should be registered in codegen, not here. | 3236 // TODO(ahe): This should be registered in codegen, not here. |
3237 // TODO(johnniwinther): Is [registerStaticUse] equivalent to | 3237 // TODO(johnniwinther): Is [registerStaticUse] equivalent to |
3238 // [addToWorkList]? | 3238 // [addToWorkList]? |
3239 registry?.registerStaticUse(callElement); | 3239 registry?.registerStaticUse(new StaticUse.foreignUse(callElement)); |
3240 | 3240 |
3241 List<HInstruction> capturedVariables = <HInstruction>[]; | 3241 List<HInstruction> capturedVariables = <HInstruction>[]; |
3242 closureClassElement.closureFields.forEach((ClosureFieldElement field) { | 3242 closureClassElement.closureFields.forEach((ClosureFieldElement field) { |
3243 Local capturedLocal = | 3243 Local capturedLocal = |
3244 nestedClosureData.getLocalVariableForClosureField(field); | 3244 nestedClosureData.getLocalVariableForClosureField(field); |
3245 assert(capturedLocal != null); | 3245 assert(capturedLocal != null); |
3246 capturedVariables.add(localsHandler.readLocal(capturedLocal)); | 3246 capturedVariables.add(localsHandler.readLocal(capturedLocal)); |
3247 }); | 3247 }); |
3248 | 3248 |
3249 TypeMask type = | 3249 TypeMask type = |
(...skipping 1187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4437 // TODO(johnniwinther): Try to eliminate the need to distinguish declaration | 4437 // TODO(johnniwinther): Try to eliminate the need to distinguish declaration |
4438 // and implementation signatures. Currently it is need because the | 4438 // and implementation signatures. Currently it is need because the |
4439 // signatures have different elements for parameters. | 4439 // signatures have different elements for parameters. |
4440 FunctionElement implementation = function.implementation; | 4440 FunctionElement implementation = function.implementation; |
4441 FunctionSignature params = implementation.functionSignature; | 4441 FunctionSignature params = implementation.functionSignature; |
4442 if (params.optionalParameterCount != 0) { | 4442 if (params.optionalParameterCount != 0) { |
4443 reporter.internalError(closure, | 4443 reporter.internalError(closure, |
4444 '"$name" does not handle closure with optional parameters.'); | 4444 '"$name" does not handle closure with optional parameters.'); |
4445 } | 4445 } |
4446 | 4446 |
4447 registry?.registerStaticUse(element); | 4447 registry?.registerStaticUse( |
| 4448 new StaticUse.foreignUse(function)); |
4448 push(new HForeignCode( | 4449 push(new HForeignCode( |
4449 js.js.expressionTemplateYielding( | 4450 js.js.expressionTemplateYielding( |
4450 backend.emitter.staticFunctionAccess(element)), | 4451 backend.emitter.staticFunctionAccess(function)), |
4451 backend.dynamicType, | 4452 backend.dynamicType, |
4452 <HInstruction>[], | 4453 <HInstruction>[], |
4453 nativeBehavior: native.NativeBehavior.PURE)); | 4454 nativeBehavior: native.NativeBehavior.PURE)); |
4454 return params; | 4455 return params; |
4455 } | 4456 } |
4456 | 4457 |
4457 void handleForeignDartClosureToJs(ast.Send node, String name) { | 4458 void handleForeignDartClosureToJs(ast.Send node, String name) { |
4458 // TODO(ahe): This implements DART_CLOSURE_TO_JS and should probably take | 4459 // TODO(ahe): This implements DART_CLOSURE_TO_JS and should probably take |
4459 // care to wrap the closure in another closure that saves the current | 4460 // care to wrap the closure in another closure that saves the current |
4460 // isolate. | 4461 // isolate. |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4543 List<HInstruction> arguments) { | 4544 List<HInstruction> arguments) { |
4544 String name = selector.name; | 4545 String name = selector.name; |
4545 | 4546 |
4546 ClassElement cls = currentNonClosureClass; | 4547 ClassElement cls = currentNonClosureClass; |
4547 Element element = cls.lookupSuperMember(Identifiers.noSuchMethod_); | 4548 Element element = cls.lookupSuperMember(Identifiers.noSuchMethod_); |
4548 if (compiler.enabledInvokeOn && !element.enclosingClass.isObject) { | 4549 if (compiler.enabledInvokeOn && !element.enclosingClass.isObject) { |
4549 // Register the call as dynamic if [noSuchMethod] on the super | 4550 // Register the call as dynamic if [noSuchMethod] on the super |
4550 // class is _not_ the default implementation from [Object], in | 4551 // class is _not_ the default implementation from [Object], in |
4551 // case the [noSuchMethod] implementation calls | 4552 // case the [noSuchMethod] implementation calls |
4552 // [JSInvocationMirror._invokeOn]. | 4553 // [JSInvocationMirror._invokeOn]. |
4553 registry?.registerSelectorUse(selector); | 4554 // TODO(johnniwinther): Register this more precisely. |
| 4555 registry?.registerDynamicUse(new UniverseSelector(selector, null)); |
4554 } | 4556 } |
4555 String publicName = name; | 4557 String publicName = name; |
4556 if (selector.isSetter) publicName += '='; | 4558 if (selector.isSetter) publicName += '='; |
4557 | 4559 |
4558 ConstantValue nameConstant = constantSystem.createString( | 4560 ConstantValue nameConstant = constantSystem.createString( |
4559 new ast.DartString.literal(publicName)); | 4561 new ast.DartString.literal(publicName)); |
4560 | 4562 |
4561 js.Name internalName = backend.namer.invocationName(selector); | 4563 js.Name internalName = backend.namer.invocationName(selector); |
4562 | 4564 |
4563 Element createInvocationMirror = helpers.createInvocationMirror; | 4565 Element createInvocationMirror = helpers.createInvocationMirror; |
(...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4982 HInstruction newObject) { | 4984 HInstruction newObject) { |
4983 if (!backend.classNeedsRti(type.element) || type.treatAsRaw) { | 4985 if (!backend.classNeedsRti(type.element) || type.treatAsRaw) { |
4984 return newObject; | 4986 return newObject; |
4985 } | 4987 } |
4986 List<HInstruction> inputs = <HInstruction>[]; | 4988 List<HInstruction> inputs = <HInstruction>[]; |
4987 type = localsHandler.substInContext(type); | 4989 type = localsHandler.substInContext(type); |
4988 type.typeArguments.forEach((DartType argument) { | 4990 type.typeArguments.forEach((DartType argument) { |
4989 inputs.add(analyzeTypeArgument(argument)); | 4991 inputs.add(analyzeTypeArgument(argument)); |
4990 }); | 4992 }); |
4991 // TODO(15489): Register at codegen. | 4993 // TODO(15489): Register at codegen. |
4992 registry?.registerInstantiatedType(type); | 4994 registry?.registerInstantiation(type); |
4993 return callSetRuntimeTypeInfo(type.element, inputs, newObject); | 4995 return callSetRuntimeTypeInfo(type.element, inputs, newObject); |
4994 } | 4996 } |
4995 | 4997 |
4996 void copyRuntimeTypeInfo(HInstruction source, HInstruction target) { | 4998 void copyRuntimeTypeInfo(HInstruction source, HInstruction target) { |
4997 Element copyHelper = helpers.copyTypeArguments; | 4999 Element copyHelper = helpers.copyTypeArguments; |
4998 pushInvokeStatic(null, copyHelper, [source, target], | 5000 pushInvokeStatic(null, copyHelper, [source, target], |
4999 sourceInformation: target.sourceInformation); | 5001 sourceInformation: target.sourceInformation); |
5000 pop(); | 5002 pop(); |
5001 } | 5003 } |
5002 | 5004 |
(...skipping 2236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7239 HInstruction setRtiIfNeeded(HInstruction object, ast.Node node) { | 7241 HInstruction setRtiIfNeeded(HInstruction object, ast.Node node) { |
7240 InterfaceType type = localsHandler.substInContext(elements.getType(node)); | 7242 InterfaceType type = localsHandler.substInContext(elements.getType(node)); |
7241 if (!backend.classNeedsRti(type.element) || type.treatAsRaw) { | 7243 if (!backend.classNeedsRti(type.element) || type.treatAsRaw) { |
7242 return object; | 7244 return object; |
7243 } | 7245 } |
7244 List<HInstruction> arguments = <HInstruction>[]; | 7246 List<HInstruction> arguments = <HInstruction>[]; |
7245 for (DartType argument in type.typeArguments) { | 7247 for (DartType argument in type.typeArguments) { |
7246 arguments.add(analyzeTypeArgument(argument)); | 7248 arguments.add(analyzeTypeArgument(argument)); |
7247 } | 7249 } |
7248 // TODO(15489): Register at codegen. | 7250 // TODO(15489): Register at codegen. |
7249 registry?.registerInstantiatedType(type); | 7251 registry?.registerInstantiation(type); |
7250 return callSetRuntimeTypeInfo(type.element, arguments, object); | 7252 return callSetRuntimeTypeInfo(type.element, arguments, object); |
7251 } | 7253 } |
7252 | 7254 |
7253 visitLiteralList(ast.LiteralList node) { | 7255 visitLiteralList(ast.LiteralList node) { |
7254 HInstruction instruction; | 7256 HInstruction instruction; |
7255 | 7257 |
7256 if (node.isConst) { | 7258 if (node.isConst) { |
7257 instruction = addConstant(node); | 7259 instruction = addConstant(node); |
7258 } else { | 7260 } else { |
7259 List<HInstruction> inputs = <HInstruction>[]; | 7261 List<HInstruction> inputs = <HInstruction>[]; |
(...skipping 1882 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9142 if (unaliased is TypedefType) throw 'unable to unalias $type'; | 9144 if (unaliased is TypedefType) throw 'unable to unalias $type'; |
9143 unaliased.accept(this, builder); | 9145 unaliased.accept(this, builder); |
9144 } | 9146 } |
9145 | 9147 |
9146 void visitDynamicType(DynamicType type, SsaBuilder builder) { | 9148 void visitDynamicType(DynamicType type, SsaBuilder builder) { |
9147 JavaScriptBackend backend = builder.compiler.backend; | 9149 JavaScriptBackend backend = builder.compiler.backend; |
9148 ClassElement cls = backend.helpers.DynamicRuntimeType; | 9150 ClassElement cls = backend.helpers.DynamicRuntimeType; |
9149 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld))); | 9151 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld))); |
9150 } | 9152 } |
9151 } | 9153 } |
OLD | NEW |