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

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

Issue 1198293002: dart2js: Use an abstract Name class for names in the generated JavaScript ast. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: fix tests 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
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 SsaCodeGeneratorTask generator; 8 SsaCodeGeneratorTask generator;
9 SsaBuilderTask builder; 9 SsaBuilderTask builder;
10 SsaOptimizerTask optimizer; 10 SsaOptimizerTask optimizer;
11 11
12 SsaFunctionCompiler(JavaScriptBackend backend, 12 SsaFunctionCompiler(JavaScriptBackend backend,
13 SourceInformationFactory sourceInformationFactory) 13 SourceInformationFactory sourceInformationFactory)
14 : generator = new SsaCodeGeneratorTask(backend, sourceInformationFactory), 14 : generator = new SsaCodeGeneratorTask(backend, sourceInformationFactory),
15 builder = new SsaBuilderTask(backend, sourceInformationFactory), 15 builder = new SsaBuilderTask(backend, sourceInformationFactory),
16 optimizer = new SsaOptimizerTask(backend); 16 optimizer = new SsaOptimizerTask(backend);
17 17
18 /// Generates JavaScript code for `work.element`. 18 /// Generates JavaScript code for `work.element`.
19 /// Using the ssa builder, optimizer and codegenerator. 19 /// Using the ssa builder, optimizer and codegenerator.
20 js.Fun compile(CodegenWorkItem work) { 20 js.Fun compile(CodegenWorkItem work) {
21 HGraph graph = builder.build(work); 21 HGraph graph = builder.build(work);
22 optimizer.optimize(work, graph); 22 optimizer.optimize(work, graph);
23 Element element = work.element; 23 Element element = work.element;
24 js.Expression result = generator.generateCode(work, graph); 24 js.Expression result = generator.generateCode(work, graph);
25 if (element is FunctionElement) { 25 if (element is FunctionElement) {
26 JavaScriptBackend backend = builder.backend; 26 JavaScriptBackend backend = builder.backend;
27 27
28 AsyncRewriterBase rewriter = null; 28 AsyncRewriterBase rewriter = null;
29 String name = backend.namer.methodPropertyName(element); 29 js.Name name = backend.namer.methodPropertyName(element);
30 if (element.asyncMarker == AsyncMarker.ASYNC) { 30 if (element.asyncMarker == AsyncMarker.ASYNC) {
31 rewriter = new AsyncRewriter( 31 rewriter = new AsyncRewriter(
32 backend.compiler, 32 backend.compiler,
33 backend.compiler.currentElement, 33 backend.compiler.currentElement,
34 asyncHelper: 34 asyncHelper:
35 backend.emitter.staticFunctionAccess(backend.getAsyncHelper()), 35 backend.emitter.staticFunctionAccess(backend.getAsyncHelper()),
36 newCompleter: backend.emitter.staticFunctionAccess( 36 newCompleter: backend.emitter.staticFunctionAccess(
37 backend.getCompleterConstructor()), 37 backend.getCompleterConstructor()),
38 safeVariableName: backend.namer.safeVariableName, 38 safeVariableName: backend.namer.safeVariablePrefixForAsyncRewrite,
39 bodyName: name); 39 bodyName: backend.namer.deriveAsyncBodyName(name));
40 } else if (element.asyncMarker == AsyncMarker.SYNC_STAR) { 40 } else if (element.asyncMarker == AsyncMarker.SYNC_STAR) {
41 rewriter = new SyncStarRewriter( 41 rewriter = new SyncStarRewriter(
42 backend.compiler, 42 backend.compiler,
43 backend.compiler.currentElement, 43 backend.compiler.currentElement,
44 endOfIteration: backend.emitter.staticFunctionAccess( 44 endOfIteration: backend.emitter.staticFunctionAccess(
45 backend.getEndOfIteration()), 45 backend.getEndOfIteration()),
46 newIterable: backend.emitter.staticFunctionAccess( 46 newIterable: backend.emitter.staticFunctionAccess(
47 backend.getSyncStarIterableConstructor()), 47 backend.getSyncStarIterableConstructor()),
48 yieldStarExpression: backend.emitter.staticFunctionAccess( 48 yieldStarExpression: backend.emitter.staticFunctionAccess(
49 backend.getYieldStar()), 49 backend.getYieldStar()),
50 uncaughtErrorExpression: backend.emitter.staticFunctionAccess( 50 uncaughtErrorExpression: backend.emitter.staticFunctionAccess(
51 backend.getSyncStarUncaughtError()), 51 backend.getSyncStarUncaughtError()),
52 safeVariableName: backend.namer.safeVariableName, 52 safeVariableName: backend.namer.safeVariablePrefixForAsyncRewrite,
53 bodyName: name); 53 bodyName: backend.namer.deriveAsyncBodyName(name));
54 } 54 }
55 else if (element.asyncMarker == AsyncMarker.ASYNC_STAR) { 55 else if (element.asyncMarker == AsyncMarker.ASYNC_STAR) {
56 rewriter = new AsyncStarRewriter( 56 rewriter = new AsyncStarRewriter(
57 backend.compiler, 57 backend.compiler,
58 backend.compiler.currentElement, 58 backend.compiler.currentElement,
59 asyncStarHelper: backend.emitter.staticFunctionAccess( 59 asyncStarHelper: backend.emitter.staticFunctionAccess(
60 backend.getAsyncStarHelper()), 60 backend.getAsyncStarHelper()),
61 streamOfController: backend.emitter.staticFunctionAccess( 61 streamOfController: backend.emitter.staticFunctionAccess(
62 backend.getStreamOfController()), 62 backend.getStreamOfController()),
63 newController: backend.emitter.staticFunctionAccess( 63 newController: backend.emitter.staticFunctionAccess(
64 backend.getASyncStarControllerConstructor()), 64 backend.getASyncStarControllerConstructor()),
65 safeVariableName: backend.namer.safeVariableName, 65 safeVariableName: backend.namer.safeVariablePrefixForAsyncRewrite,
66 yieldExpression: backend.emitter.staticFunctionAccess( 66 yieldExpression: backend.emitter.staticFunctionAccess(
67 backend.getYieldSingle()), 67 backend.getYieldSingle()),
68 yieldStarExpression: backend.emitter.staticFunctionAccess( 68 yieldStarExpression: backend.emitter.staticFunctionAccess(
69 backend.getYieldStar()), 69 backend.getYieldStar()),
70 bodyName: name); 70 bodyName: backend.namer.deriveAsyncBodyName(name));
71 } 71 }
72 if (rewriter != null) { 72 if (rewriter != null) {
73 result = rewriter.rewrite(result); 73 result = rewriter.rewrite(result);
74 } 74 }
75 } 75 }
76 return result; 76 return result;
77 } 77 }
78 78
79 Iterable<CompilerTask> get tasks { 79 Iterable<CompilerTask> get tasks {
80 return <CompilerTask>[builder, optimizer, generator]; 80 return <CompilerTask>[builder, optimizer, generator];
(...skipping 3585 matching lines...) Expand 10 before | Expand all | Expand 10 after
3666 List<HInstruction> inputs = <HInstruction>[expression, runtimeType]; 3666 List<HInstruction> inputs = <HInstruction>[expression, runtimeType];
3667 pushInvokeStatic(null, helper, inputs, typeMask: backend.boolType); 3667 pushInvokeStatic(null, helper, inputs, typeMask: backend.boolType);
3668 HInstruction call = pop(); 3668 HInstruction call = pop();
3669 return new HIs.variable(type, expression, call, backend.boolType); 3669 return new HIs.variable(type, expression, call, backend.boolType);
3670 } else if (RuntimeTypes.hasTypeArguments(type)) { 3670 } else if (RuntimeTypes.hasTypeArguments(type)) {
3671 ClassElement element = type.element; 3671 ClassElement element = type.element;
3672 Element helper = backend.getCheckSubtype(); 3672 Element helper = backend.getCheckSubtype();
3673 HInstruction representations = 3673 HInstruction representations =
3674 buildTypeArgumentRepresentations(type); 3674 buildTypeArgumentRepresentations(type);
3675 add(representations); 3675 add(representations);
3676 String operator = backend.namer.operatorIs(element); 3676 js.Name operator = backend.namer.operatorIs(element);
3677 HInstruction isFieldName = addConstantString(operator); 3677 HInstruction isFieldName = addConstantStringFromName(operator);
3678 HInstruction asFieldName = compiler.world.hasAnyStrictSubtype(element) 3678 HInstruction asFieldName = compiler.world.hasAnyStrictSubtype(element)
3679 ? addConstantString(backend.namer.substitutionName(element)) 3679 ? addConstantStringFromName(backend.namer.substitutionName(element))
3680 : graph.addConstantNull(compiler); 3680 : graph.addConstantNull(compiler);
3681 List<HInstruction> inputs = <HInstruction>[expression, 3681 List<HInstruction> inputs = <HInstruction>[expression,
3682 isFieldName, 3682 isFieldName,
3683 representations, 3683 representations,
3684 asFieldName]; 3684 asFieldName];
3685 pushInvokeStatic(node, helper, inputs, typeMask: backend.boolType); 3685 pushInvokeStatic(node, helper, inputs, typeMask: backend.boolType);
3686 HInstruction call = pop(); 3686 HInstruction call = pop();
3687 return new HIs.compound(type, expression, call, backend.boolType); 3687 return new HIs.compound(type, expression, call, backend.boolType);
3688 } else if (type.isMalformed) { 3688 } else if (type.isMalformed) {
3689 ErroneousElement element = type.element; 3689 ErroneousElement element = type.element;
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after
4021 if (element == null || 4021 if (element == null ||
4022 element is! FieldElement || 4022 element is! FieldElement ||
4023 element.enclosingClass != backend.jsGetNameEnum) { 4023 element.enclosingClass != backend.jsGetNameEnum) {
4024 compiler.reportError( 4024 compiler.reportError(
4025 argument, MessageKind.GENERIC, 4025 argument, MessageKind.GENERIC,
4026 {'text': 'Error: Expected a JsGetName enum value.'}); 4026 {'text': 'Error: Expected a JsGetName enum value.'});
4027 } 4027 }
4028 EnumClassElement enumClass = element.enclosingClass; 4028 EnumClassElement enumClass = element.enclosingClass;
4029 int index = enumClass.enumValues.indexOf(element); 4029 int index = enumClass.enumValues.indexOf(element);
4030 stack.add( 4030 stack.add(
4031 addConstantString( 4031 addConstantStringFromName(
4032 backend.namer.getNameForJsGetName( 4032 backend.namer.getNameForJsGetName(
4033 argument, JsGetName.values[index]))); 4033 argument, JsGetName.values[index])));
4034 } 4034 }
4035 4035
4036 void handleForeignJsBuiltin(ast.Send node) { 4036 void handleForeignJsBuiltin(ast.Send node) {
4037 List<ast.Node> arguments = node.arguments.toList(); 4037 List<ast.Node> arguments = node.arguments.toList();
4038 ast.Node argument; 4038 ast.Node argument;
4039 if (arguments.length < 2) { 4039 if (arguments.length < 2) {
4040 compiler.reportError( 4040 compiler.reportError(
4041 node, MessageKind.GENERIC, 4041 node, MessageKind.GENERIC,
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after
4292 // case the [noSuchMethod] implementation calls 4292 // case the [noSuchMethod] implementation calls
4293 // [JSInvocationMirror._invokeOn]. 4293 // [JSInvocationMirror._invokeOn].
4294 registry.registerSelectorUse(selector.asUntyped); 4294 registry.registerSelectorUse(selector.asUntyped);
4295 } 4295 }
4296 String publicName = name; 4296 String publicName = name;
4297 if (selector.isSetter) publicName += '='; 4297 if (selector.isSetter) publicName += '=';
4298 4298
4299 ConstantValue nameConstant = constantSystem.createString( 4299 ConstantValue nameConstant = constantSystem.createString(
4300 new ast.DartString.literal(publicName)); 4300 new ast.DartString.literal(publicName));
4301 4301
4302 String internalName = backend.namer.invocationName(selector); 4302 js.Name internalName = backend.namer.invocationName(selector);
4303 ConstantValue internalNameConstant =
4304 constantSystem.createString(new ast.DartString.literal(internalName));
4305 4303
4306 Element createInvocationMirror = backend.getCreateInvocationMirror(); 4304 Element createInvocationMirror = backend.getCreateInvocationMirror();
4307 var argumentsInstruction = buildLiteralList(arguments); 4305 var argumentsInstruction = buildLiteralList(arguments);
4308 add(argumentsInstruction); 4306 add(argumentsInstruction);
4309 4307
4310 var argumentNames = new List<HInstruction>(); 4308 var argumentNames = new List<HInstruction>();
4311 for (String argumentName in selector.namedArguments) { 4309 for (String argumentName in selector.namedArguments) {
4312 ConstantValue argumentNameConstant = 4310 ConstantValue argumentNameConstant =
4313 constantSystem.createString(new ast.DartString.literal(argumentName)); 4311 constantSystem.createString(new ast.DartString.literal(argumentName));
4314 argumentNames.add(graph.addConstant(argumentNameConstant, compiler)); 4312 argumentNames.add(graph.addConstant(argumentNameConstant, compiler));
4315 } 4313 }
4316 var argumentNamesInstruction = buildLiteralList(argumentNames); 4314 var argumentNamesInstruction = buildLiteralList(argumentNames);
4317 add(argumentNamesInstruction); 4315 add(argumentNamesInstruction);
4318 4316
4319 ConstantValue kindConstant = 4317 ConstantValue kindConstant =
4320 constantSystem.createInt(selector.invocationMirrorKind); 4318 constantSystem.createInt(selector.invocationMirrorKind);
4321 4319
4322 pushInvokeStatic(null, 4320 pushInvokeStatic(null,
4323 createInvocationMirror, 4321 createInvocationMirror,
4324 [graph.addConstant(nameConstant, compiler), 4322 [graph.addConstant(nameConstant, compiler),
4325 graph.addConstant(internalNameConstant, compiler), 4323 graph.addConstantStringFromName(internalName, compiler),
4326 graph.addConstant(kindConstant, compiler), 4324 graph.addConstant(kindConstant, compiler),
4327 argumentsInstruction, 4325 argumentsInstruction,
4328 argumentNamesInstruction], 4326 argumentNamesInstruction],
4329 typeMask: backend.dynamicType); 4327 typeMask: backend.dynamicType);
4330 4328
4331 var inputs = <HInstruction>[pop()]; 4329 var inputs = <HInstruction>[pop()];
4332 push(buildInvokeSuper(compiler.noSuchMethodSelector, element, inputs)); 4330 push(buildInvokeSuper(compiler.noSuchMethodSelector, element, inputs));
4333 } 4331 }
4334 4332
4335 /// Generate a call to a super method or constructor. 4333 /// Generate a call to a super method or constructor.
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
4581 4579
4582 HInstruction target = localsHandler.readThis(); 4580 HInstruction target = localsHandler.readThis();
4583 HConstant index = graph.addConstantInt( 4581 HConstant index = graph.addConstantInt(
4584 RuntimeTypes.getTypeVariableIndex(variable), 4582 RuntimeTypes.getTypeVariableIndex(variable),
4585 compiler); 4583 compiler);
4586 4584
4587 if (needsSubstitutionForTypeVariableAccess(cls)) { 4585 if (needsSubstitutionForTypeVariableAccess(cls)) {
4588 // TODO(ahe): Creating a string here is unfortunate. It is slow (due to 4586 // TODO(ahe): Creating a string here is unfortunate. It is slow (due to
4589 // string concatenation in the implementation), and may prevent 4587 // string concatenation in the implementation), and may prevent
4590 // segmentation of '$'. 4588 // segmentation of '$'.
4591 String substitutionNameString = backend.namer.runtimeTypeName(cls); 4589 js.Name substitutionName = backend.namer.runtimeTypeName(cls);
4592 HInstruction substitutionName = graph.addConstantString( 4590 HInstruction substitutionNameInstr = graph.addConstantStringFromName(
4593 new ast.LiteralDartString(substitutionNameString), compiler); 4591 substitutionName, compiler);
4594 pushInvokeStatic(null, 4592 pushInvokeStatic(null,
4595 backend.getGetRuntimeTypeArgument(), 4593 backend.getGetRuntimeTypeArgument(),
4596 [target, substitutionName, index], 4594 [target, substitutionNameInstr, index],
4597 typeMask: backend.dynamicType); 4595 typeMask: backend.dynamicType);
4598 } else { 4596 } else {
4599 pushInvokeStatic(null, backend.getGetTypeArgumentByIndex(), 4597 pushInvokeStatic(null, backend.getGetTypeArgumentByIndex(),
4600 [target, index], 4598 [target, index],
4601 typeMask: backend.dynamicType); 4599 typeMask: backend.dynamicType);
4602 } 4600 }
4603 return pop(); 4601 return pop();
4604 } 4602 }
4605 4603
4606 // TODO(karlklose): this is needed to avoid a bug where the resolved type is 4604 // TODO(karlklose): this is needed to avoid a bug where the resolved type is
(...skipping 579 matching lines...) Expand 10 before | Expand all | Expand 10 after
5186 handleInvalidStaticInvoke(node, element); 5184 handleInvalidStaticInvoke(node, element);
5187 } else { 5185 } else {
5188 // TODO(ahe): Do something like [generateWrongArgumentCountError]. 5186 // TODO(ahe): Do something like [generateWrongArgumentCountError].
5189 stack.add(graph.addConstantNull(compiler)); 5187 stack.add(graph.addConstantNull(compiler));
5190 } 5188 }
5191 return; 5189 return;
5192 } 5190 }
5193 5191
5194 HConstant addConstantString(String string) { 5192 HConstant addConstantString(String string) {
5195 ast.DartString dartString = new ast.DartString.literal(string); 5193 ast.DartString dartString = new ast.DartString.literal(string);
5196 ConstantValue constant = constantSystem.createString(dartString); 5194 return graph.addConstantString(dartString, compiler);
5197 return graph.addConstant(constant, compiler); 5195 }
5196
5197 HConstant addConstantStringFromName(js.Name name) {
5198 return graph.addConstantStringFromName(name, compiler);
5198 } 5199 }
5199 5200
5200 visitClassTypeLiteralGet( 5201 visitClassTypeLiteralGet(
5201 ast.Send node, 5202 ast.Send node,
5202 ConstantExpression constant, 5203 ConstantExpression constant,
5203 _) { 5204 _) {
5204 generateConstantTypeLiteral(node); 5205 generateConstantTypeLiteral(node);
5205 } 5206 }
5206 5207
5207 visitClassTypeLiteralInvoke( 5208 visitClassTypeLiteralInvoke(
(...skipping 2901 matching lines...) Expand 10 before | Expand all | Expand 10 after
8109 if (unaliased is TypedefType) throw 'unable to unalias $type'; 8110 if (unaliased is TypedefType) throw 'unable to unalias $type';
8110 unaliased.accept(this, builder); 8111 unaliased.accept(this, builder);
8111 } 8112 }
8112 8113
8113 void visitDynamicType(DynamicType type, SsaBuilder builder) { 8114 void visitDynamicType(DynamicType type, SsaBuilder builder) {
8114 JavaScriptBackend backend = builder.compiler.backend; 8115 JavaScriptBackend backend = builder.compiler.backend;
8115 ClassElement cls = backend.findHelper('DynamicRuntimeType'); 8116 ClassElement cls = backend.findHelper('DynamicRuntimeType');
8116 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld))); 8117 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld)));
8117 } 8118 }
8118 } 8119 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698