OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 library dart2js.js_emitter.lazy_emitter; | 5 library dart2js.js_emitter.startup_emitter; |
6 | 6 |
7 import 'package:js_runtime/shared/embedded_names.dart' show | 7 import 'package:js_runtime/shared/embedded_names.dart' show |
8 JsBuiltin, | 8 JsBuiltin, |
9 METADATA, | 9 METADATA, |
10 TYPES; | 10 TYPES; |
11 | 11 |
12 import '../program_builder/program_builder.dart' show ProgramBuilder; | 12 import '../program_builder/program_builder.dart' show ProgramBuilder; |
13 import '../model.dart'; | 13 import '../model.dart'; |
14 import 'model_emitter.dart'; | 14 import 'model_emitter.dart'; |
15 import '../../common.dart'; | 15 import '../../common.dart'; |
16 import '../../elements/elements.dart' show FieldElement; | 16 import '../../elements/elements.dart' show FieldElement; |
17 import '../../js/js.dart' as js; | 17 import '../../js/js.dart' as js; |
18 | 18 |
19 import '../../js_backend/js_backend.dart' show | 19 import '../../js_backend/js_backend.dart' show |
20 JavaScriptBackend, | 20 JavaScriptBackend, |
21 Namer; | 21 Namer; |
22 | 22 |
23 import '../js_emitter.dart' show | 23 import '../js_emitter.dart' show |
24 NativeEmitter; | 24 NativeEmitter; |
25 | 25 |
26 import '../js_emitter.dart' as emitterTask show | 26 import '../js_emitter.dart' as emitterTask show |
27 Emitter; | 27 Emitter; |
28 | 28 |
29 import '../../util/util.dart' show | 29 import '../../util/util.dart' show |
30 NO_LOCATION_SPANNABLE; | 30 NO_LOCATION_SPANNABLE; |
31 | 31 |
32 class Emitter implements emitterTask.Emitter { | 32 class Emitter implements emitterTask.Emitter { |
33 final Compiler _compiler; | 33 final Compiler _compiler; |
34 final Namer namer; | 34 final Namer namer; |
35 final ModelEmitter _emitter; | 35 final ModelEmitter _emitter; |
36 | 36 |
37 JavaScriptBackend get _backend => _compiler.backend; | 37 JavaScriptBackend get _backend => _compiler.backend; |
38 | 38 |
39 Emitter(Compiler compiler, Namer namer, NativeEmitter nativeEmitter) | 39 Emitter(Compiler compiler, Namer namer, NativeEmitter nativeEmitter) |
40 : this._compiler = compiler, | 40 : this._compiler = compiler, |
41 this.namer = namer, | 41 this.namer = namer, |
42 _emitter = new ModelEmitter(compiler, namer, nativeEmitter); | 42 _emitter = new ModelEmitter(compiler, namer, nativeEmitter); |
43 | 43 |
44 @override | 44 @override |
45 int emitProgram(ProgramBuilder programBuilder) { | 45 int emitProgram(ProgramBuilder programBuilder) { |
46 Program program = programBuilder.buildProgram(); | 46 Program program = programBuilder.buildProgram(); |
47 return _emitter.emitProgram(program); | 47 return _emitter.emitProgram(program); |
48 } | 48 } |
49 | 49 |
50 // TODO(floitsch): copied from full emitter. Adjust or share. | |
51 @override | 50 @override |
52 bool isConstantInlinedOrAlreadyEmitted(ConstantValue constant) { | 51 bool isConstantInlinedOrAlreadyEmitted(ConstantValue constant) { |
53 return _emitter.isConstantInlinedOrAlreadyEmitted(constant); | 52 return _emitter.isConstantInlinedOrAlreadyEmitted(constant); |
54 } | 53 } |
55 | 54 |
56 // TODO(floitsch): copied from full emitter. Adjust or share. | |
57 @override | 55 @override |
58 int compareConstants(ConstantValue a, ConstantValue b) { | 56 int compareConstants(ConstantValue a, ConstantValue b) { |
59 return _emitter.compareConstants(a, b); | 57 return _emitter.compareConstants(a, b); |
60 } | 58 } |
61 | 59 |
62 @override | 60 @override |
63 js.Expression constantReference(ConstantValue value) { | 61 js.Expression constantReference(ConstantValue value) { |
64 return _emitter.generateConstantReference(value); | 62 return _emitter.generateConstantReference(value); |
65 } | 63 } |
66 | 64 |
(...skipping 11 matching lines...) Expand all Loading... |
78 js.PropertyAccess _globalPropertyAccess(Element element) { | 76 js.PropertyAccess _globalPropertyAccess(Element element) { |
79 js.Name name = namer.globalPropertyName(element); | 77 js.Name name = namer.globalPropertyName(element); |
80 js.PropertyAccess pa = new js.PropertyAccess( | 78 js.PropertyAccess pa = new js.PropertyAccess( |
81 new js.VariableUse(namer.globalObjectFor(element)), name); | 79 new js.VariableUse(namer.globalObjectFor(element)), name); |
82 return pa; | 80 return pa; |
83 } | 81 } |
84 | 82 |
85 @override | 83 @override |
86 js.Expression isolateLazyInitializerAccess(FieldElement element) { | 84 js.Expression isolateLazyInitializerAccess(FieldElement element) { |
87 return js.js('#.#', [namer.globalObjectFor(element), | 85 return js.js('#.#', [namer.globalObjectFor(element), |
88 namer.lazyInitializerName(element)]); | 86 namer.lazyInitializerName(element)]); |
89 } | 87 } |
90 | 88 |
91 @override | 89 @override |
92 js.Expression isolateStaticClosureAccess(FunctionElement element) { | 90 js.Expression isolateStaticClosureAccess(FunctionElement element) { |
93 return _emitter.generateStaticClosureAccess(element); | 91 return _emitter.generateStaticClosureAccess(element); |
94 } | 92 } |
95 | 93 |
96 @override | 94 @override |
97 js.PropertyAccess staticFieldAccess(FieldElement element) { | 95 js.PropertyAccess staticFieldAccess(FieldElement element) { |
98 return _globalPropertyAccess(element); | 96 return _globalPropertyAccess(element); |
(...skipping 12 matching lines...) Expand all Loading... |
111 @override | 109 @override |
112 js.PropertyAccess prototypeAccess(ClassElement element, | 110 js.PropertyAccess prototypeAccess(ClassElement element, |
113 bool hasBeenInstantiated) { | 111 bool hasBeenInstantiated) { |
114 js.Expression constructor = | 112 js.Expression constructor = |
115 hasBeenInstantiated ? constructorAccess(element) : typeAccess(element); | 113 hasBeenInstantiated ? constructorAccess(element) : typeAccess(element); |
116 return js.js('#.prototype', constructor); | 114 return js.js('#.prototype', constructor); |
117 } | 115 } |
118 | 116 |
119 @override | 117 @override |
120 js.Expression interceptorClassAccess(ClassElement element) { | 118 js.Expression interceptorClassAccess(ClassElement element) { |
121 // Some interceptors are eagerly constructed. However, native interceptors | 119 return _globalPropertyAccess(element); |
122 // aren't. | |
123 return js.js('#.ensureResolved()', _globalPropertyAccess(element)); | |
124 } | 120 } |
125 | 121 |
126 @override | 122 @override |
127 js.Expression typeAccess(Element element) { | 123 js.Expression typeAccess(Element element) { |
128 // TODO(floitsch): minify 'ensureResolved'. | 124 return _globalPropertyAccess(element); |
129 // TODO(floitsch): don't emit `ensureResolved` for eager classes. | |
130 return js.js('#.ensureResolved()', _globalPropertyAccess(element)); | |
131 } | 125 } |
132 | 126 |
133 @override | 127 @override |
134 js.Template templateForBuiltin(JsBuiltin builtin) { | 128 js.Template templateForBuiltin(JsBuiltin builtin) { |
135 String typeNameProperty = ModelEmitter.typeNameProperty; | 129 String typeNameProperty = ModelEmitter.typeNameProperty; |
136 | 130 |
137 switch (builtin) { | 131 switch (builtin) { |
138 case JsBuiltin.dartObjectConstructor: | 132 case JsBuiltin.dartObjectConstructor: |
139 return js.js.expressionTemplateYielding( | 133 return js.js.expressionTemplateYielding( |
140 typeAccess(_compiler.objectClass)); | 134 typeAccess(_compiler.objectClass)); |
141 | 135 |
142 case JsBuiltin.isCheckPropertyToJsConstructorName: | 136 case JsBuiltin.isCheckPropertyToJsConstructorName: |
143 int isPrefixLength = namer.operatorIsPrefix.length; | 137 int isPrefixLength = namer.operatorIsPrefix.length; |
144 return js.js.expressionTemplateFor('#.substring($isPrefixLength)'); | 138 return js.js.expressionTemplateFor('#.substring($isPrefixLength)'); |
145 | 139 |
146 case JsBuiltin.isFunctionType: | 140 case JsBuiltin.isFunctionType: |
147 return _backend.rti.representationGenerator.templateForIsFunctionType; | 141 return _backend.rti.representationGenerator.templateForIsFunctionType; |
148 | 142 |
149 case JsBuiltin.rawRtiToJsConstructorName: | 143 case JsBuiltin.rawRtiToJsConstructorName: |
150 return js.js.expressionTemplateFor("#.$typeNameProperty"); | 144 return js.js.expressionTemplateFor("#.$typeNameProperty"); |
151 | 145 |
152 case JsBuiltin.rawRuntimeType: | 146 case JsBuiltin.rawRuntimeType: |
153 return js.js.expressionTemplateFor("#.constructor"); | 147 return js.js.expressionTemplateFor("#.constructor"); |
154 | 148 |
155 case JsBuiltin.createFunctionTypeRti: | 149 case JsBuiltin.createFunctionTypeRti: |
156 return _backend.rti.representationGenerator | 150 return _backend.rti.representationGenerator |
157 .templateForCreateFunctionType; | 151 .templateForCreateFunctionType; |
158 | 152 |
159 case JsBuiltin.isSubtype: | 153 case JsBuiltin.isSubtype: |
160 // TODO(floitsch): move this closer to where is-check properties are | 154 // TODO(floitsch): move this closer to where is-check properties are |
161 // built. | 155 // built. |
162 String isPrefix = namer.operatorIsPrefix; | 156 String isPrefix = namer.operatorIsPrefix; |
163 return js.js.expressionTemplateFor("('$isPrefix' + #) in #.prototype"); | 157 return js.js.expressionTemplateFor("('$isPrefix' + #) in #.prototype"); |
164 | 158 |
165 case JsBuiltin.isGivenTypeRti: | 159 case JsBuiltin.isGivenTypeRti: |
166 return js.js.expressionTemplateFor('#.$typeNameProperty === #'); | 160 return js.js.expressionTemplateFor('#.$typeNameProperty === #'); |
167 | 161 |
168 case JsBuiltin.getMetadata: | 162 case JsBuiltin.getMetadata: |
169 return _emitter.templateForReadMetadata; | 163 String metadataAccess = |
| 164 _emitter.generateEmbeddedGlobalAccessString(METADATA); |
| 165 return js.js.expressionTemplateFor("$metadataAccess[#]"); |
170 | 166 |
171 case JsBuiltin.getType: | 167 case JsBuiltin.getType: |
172 return _emitter.templateForReadType; | 168 String typesAccess = |
| 169 _emitter.generateEmbeddedGlobalAccessString(TYPES); |
| 170 return js.js.expressionTemplateFor("$typesAccess[#]"); |
173 | 171 |
174 default: | 172 default: |
175 _compiler.internalError(NO_LOCATION_SPANNABLE, | 173 _compiler.internalError(NO_LOCATION_SPANNABLE, |
176 "Unhandled Builtin: $builtin"); | 174 "Unhandled Builtin: $builtin"); |
177 return null; | 175 return null; |
178 } | 176 } |
179 } | 177 } |
180 | 178 |
181 @override | 179 @override |
182 void invalidateCaches() { | 180 void invalidateCaches() { |
183 } | 181 } |
184 } | 182 } |
OLD | NEW |