OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 part of dart2js.js_emitter; | 5 part of dart2js.js_emitter; |
6 | 6 |
7 class InterceptorEmitter extends CodeEmitterHelper { | 7 class InterceptorEmitter extends CodeEmitterHelper { |
8 final Set<String> interceptorInvocationNames = new Set<String>(); | 8 final Set<String> interceptorInvocationNames = new Set<String>(); |
9 | 9 |
10 void recordMangledNameOfMemberMethod(FunctionElement member, String name) { | 10 void recordMangledNameOfMemberMethod(FunctionElement member, String name) { |
11 if (backend.isInterceptedMethod(member)) { | 11 if (backend.isInterceptedMethod(member)) { |
12 interceptorInvocationNames.add(name); | 12 interceptorInvocationNames.add(name); |
13 } | 13 } |
14 } | 14 } |
15 | 15 |
16 void emitGetInterceptorMethod(CodeBuffer buffer, | 16 void emitGetInterceptorMethod(CodeOutput output, |
17 String key, | 17 String key, |
18 Set<ClassElement> classes) { | 18 Set<ClassElement> classes) { |
19 InterceptorStubGenerator stubGenerator = | 19 InterceptorStubGenerator stubGenerator = |
20 new InterceptorStubGenerator(compiler, namer, backend); | 20 new InterceptorStubGenerator(compiler, namer, backend); |
21 jsAst.Expression function = | 21 jsAst.Expression function = |
22 stubGenerator.generateGetInterceptorMethod(classes); | 22 stubGenerator.generateGetInterceptorMethod(classes); |
23 | 23 |
24 buffer.write(jsAst.prettyPrint( | 24 output.addBuffer(jsAst.prettyPrint( |
25 js('${namer.globalObjectFor(backend.interceptorsLibrary)}.# = #', | 25 js('${namer.globalObjectFor(backend.interceptorsLibrary)}.# = #', |
26 [key, function]), | 26 [key, function]), |
27 compiler)); | 27 compiler)); |
28 buffer.write(N); | 28 output.add(N); |
29 } | 29 } |
30 | 30 |
31 /** | 31 /** |
32 * Emit all versions of the [:getInterceptor:] method. | 32 * Emit all versions of the [:getInterceptor:] method. |
33 */ | 33 */ |
34 void emitGetInterceptorMethods(CodeBuffer buffer) { | 34 void emitGetInterceptorMethods(CodeOutput output) { |
35 emitter.addComment('getInterceptor methods', buffer); | 35 emitter.addComment('getInterceptor methods', output); |
36 Map<String, Set<ClassElement>> specializedGetInterceptors = | 36 Map<String, Set<ClassElement>> specializedGetInterceptors = |
37 backend.specializedGetInterceptors; | 37 backend.specializedGetInterceptors; |
38 for (String name in specializedGetInterceptors.keys.toList()..sort()) { | 38 for (String name in specializedGetInterceptors.keys.toList()..sort()) { |
39 Set<ClassElement> classes = specializedGetInterceptors[name]; | 39 Set<ClassElement> classes = specializedGetInterceptors[name]; |
40 emitGetInterceptorMethod(buffer, name, classes); | 40 emitGetInterceptorMethod(output, name, classes); |
41 } | 41 } |
42 } | 42 } |
43 | 43 |
44 void emitOneShotInterceptors(CodeBuffer buffer) { | 44 void emitOneShotInterceptors(CodeOutput output) { |
45 List<String> names = backend.oneShotInterceptors.keys.toList(); | 45 List<String> names = backend.oneShotInterceptors.keys.toList(); |
46 names.sort(); | 46 names.sort(); |
47 | 47 |
48 InterceptorStubGenerator stubGenerator = | 48 InterceptorStubGenerator stubGenerator = |
49 new InterceptorStubGenerator(compiler, namer, backend); | 49 new InterceptorStubGenerator(compiler, namer, backend); |
50 String globalObject = namer.globalObjectFor(backend.interceptorsLibrary); | 50 String globalObject = namer.globalObjectFor(backend.interceptorsLibrary); |
51 for (String name in names) { | 51 for (String name in names) { |
52 jsAst.Expression function = | 52 jsAst.Expression function = |
53 stubGenerator.generateOneShotInterceptor(name); | 53 stubGenerator.generateOneShotInterceptor(name); |
54 jsAst.Expression assignment = | 54 jsAst.Expression assignment = |
55 js('${globalObject}.# = #', [name, function]); | 55 js('${globalObject}.# = #', [name, function]); |
56 | 56 |
57 buffer.write(jsAst.prettyPrint(assignment, compiler)); | 57 output.addBuffer(jsAst.prettyPrint(assignment, compiler)); |
58 buffer.write(N); | 58 output.add(N); |
59 } | 59 } |
60 } | 60 } |
61 | 61 |
62 /** | 62 /** |
63 * If [JSInvocationMirror._invokeOn] has been compiled, emit all the | 63 * If [JSInvocationMirror._invokeOn] has been compiled, emit all the |
64 * possible selector names that are intercepted into the | 64 * possible selector names that are intercepted into the |
65 * [interceptedNames] top-level variable. The implementation of | 65 * [interceptedNames] top-level variable. The implementation of |
66 * [_invokeOn] will use it to determine whether it should call the | 66 * [_invokeOn] will use it to determine whether it should call the |
67 * method with an extra parameter. | 67 * method with an extra parameter. |
68 */ | 68 */ |
69 void emitInterceptedNames(CodeBuffer buffer) { | 69 void emitInterceptedNames(CodeOutput output) { |
70 // TODO(ahe): We should not generate the list of intercepted names at | 70 // TODO(ahe): We should not generate the list of intercepted names at |
71 // compile time, it can be generated automatically at runtime given | 71 // compile time, it can be generated automatically at runtime given |
72 // subclasses of Interceptor (which can easily be identified). | 72 // subclasses of Interceptor (which can easily be identified). |
73 if (!compiler.enabledInvokeOn) return; | 73 if (!compiler.enabledInvokeOn) return; |
74 | 74 |
75 // TODO(ahe): We should roll this into | 75 // TODO(ahe): We should roll this into |
76 // [emitStaticNonFinalFieldInitializations]. | 76 // [emitStaticNonFinalFieldInitializations]. |
77 String name = backend.namer.getNameOfGlobalField(backend.interceptedNames); | 77 String name = backend.namer.getNameOfGlobalField(backend.interceptedNames); |
78 | 78 |
79 int index = 0; | 79 int index = 0; |
80 var invocationNames = interceptorInvocationNames.toList()..sort(); | 80 var invocationNames = interceptorInvocationNames.toList()..sort(); |
81 List<jsAst.Expression> elements = invocationNames.map(js.string).toList(); | 81 List<jsAst.Expression> elements = invocationNames.map(js.string).toList(); |
82 jsAst.ArrayInitializer array = | 82 jsAst.ArrayInitializer array = |
83 new jsAst.ArrayInitializer(elements); | 83 new jsAst.ArrayInitializer(elements); |
84 | 84 |
85 jsAst.Expression assignment = | 85 jsAst.Expression assignment = |
86 js('${emitter.isolateProperties}.# = #', [name, array]); | 86 js('${emitter.isolateProperties}.# = #', [name, array]); |
87 | 87 |
88 buffer.write(jsAst.prettyPrint(assignment, compiler)); | 88 output.addBuffer(jsAst.prettyPrint(assignment, compiler)); |
89 buffer.write(N); | 89 output.add(N); |
90 } | 90 } |
91 | 91 |
92 /** | 92 /** |
93 * Emit initializer for [mapTypeToInterceptor] data structure used by | 93 * Emit initializer for [mapTypeToInterceptor] data structure used by |
94 * [findInterceptorForType]. See declaration of [mapTypeToInterceptor] in | 94 * [findInterceptorForType]. See declaration of [mapTypeToInterceptor] in |
95 * `interceptors.dart`. | 95 * `interceptors.dart`. |
96 */ | 96 */ |
97 void emitMapTypeToInterceptor(CodeBuffer buffer) { | 97 void emitMapTypeToInterceptor(CodeOutput output) { |
98 // TODO(sra): Perhaps inject a constant instead? | 98 // TODO(sra): Perhaps inject a constant instead? |
99 CustomElementsAnalysis analysis = backend.customElementsAnalysis; | 99 CustomElementsAnalysis analysis = backend.customElementsAnalysis; |
100 if (!analysis.needsTable) return; | 100 if (!analysis.needsTable) return; |
101 | 101 |
102 List<jsAst.Expression> elements = <jsAst.Expression>[]; | 102 List<jsAst.Expression> elements = <jsAst.Expression>[]; |
103 JavaScriptConstantCompiler handler = backend.constants; | 103 JavaScriptConstantCompiler handler = backend.constants; |
104 List<ConstantValue> constants = | 104 List<ConstantValue> constants = |
105 handler.getConstantsForEmission(emitter.compareConstants); | 105 handler.getConstantsForEmission(emitter.compareConstants); |
106 for (ConstantValue constant in constants) { | 106 for (ConstantValue constant in constants) { |
107 if (constant is TypeConstantValue) { | 107 if (constant is TypeConstantValue) { |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
142 } | 142 } |
143 } | 143 } |
144 } | 144 } |
145 | 145 |
146 jsAst.ArrayInitializer array = new jsAst.ArrayInitializer(elements); | 146 jsAst.ArrayInitializer array = new jsAst.ArrayInitializer(elements); |
147 String name = | 147 String name = |
148 backend.namer.getNameOfGlobalField(backend.mapTypeToInterceptor); | 148 backend.namer.getNameOfGlobalField(backend.mapTypeToInterceptor); |
149 jsAst.Expression assignment = | 149 jsAst.Expression assignment = |
150 js('${emitter.isolateProperties}.# = #', [name, array]); | 150 js('${emitter.isolateProperties}.# = #', [name, array]); |
151 | 151 |
152 buffer.write(jsAst.prettyPrint(assignment, compiler)); | 152 output.addBuffer(jsAst.prettyPrint(assignment, compiler)); |
153 buffer.write(N); | 153 output.add(N); |
154 } | 154 } |
155 } | 155 } |
OLD | NEW |