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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/js_backend/constant_emitter.dart

Issue 614993002: Rename Constant to ConstantValue and ConstExp to ConstantExpression. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Updated cf. comments. Created 6 years, 2 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 | Annotate | Revision Log
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 js_backend; 5 part of js_backend;
6 6
7 class ConstantEmitter { 7 class ConstantEmitter {
8 ConstantReferenceEmitter _referenceEmitter; 8 ConstantReferenceEmitter _referenceEmitter;
9 ConstantLiteralEmitter _literalEmitter; 9 ConstantLiteralEmitter _literalEmitter;
10 10
11 ConstantEmitter(Compiler compiler, Namer namer) { 11 ConstantEmitter(Compiler compiler, Namer namer) {
12 _literalEmitter = new ConstantLiteralEmitter(compiler, namer, this); 12 _literalEmitter = new ConstantLiteralEmitter(compiler, namer, this);
13 _referenceEmitter = new ConstantReferenceEmitter(compiler, namer, this); 13 _referenceEmitter = new ConstantReferenceEmitter(compiler, namer, this);
14 } 14 }
15 15
16 /** 16 /**
17 * Constructs an expression that is a reference to the constant. Uses a 17 * Constructs an expression that is a reference to the constant. Uses a
18 * canonical name unless the constant can be emitted multiple times (as for 18 * canonical name unless the constant can be emitted multiple times (as for
19 * numbers and strings). 19 * numbers and strings).
20 */ 20 */
21 jsAst.Expression reference(Constant constant) { 21 jsAst.Expression reference(ConstantValue constant) {
22 return _referenceEmitter.generate(constant); 22 return _referenceEmitter.generate(constant);
23 } 23 }
24 24
25 /** 25 /**
26 * Constructs a literal expression that evaluates to the constant. Uses a 26 * Constructs a literal expression that evaluates to the constant. Uses a
27 * canonical name unless the constant can be emitted multiple times (as for 27 * canonical name unless the constant can be emitted multiple times (as for
28 * numbers and strings). 28 * numbers and strings).
29 */ 29 */
30 jsAst.Expression literal(Constant constant) { 30 jsAst.Expression literal(ConstantValue constant) {
31 return _literalEmitter.generate(constant); 31 return _literalEmitter.generate(constant);
32 } 32 }
33 33
34 /** 34 /**
35 * Constructs an expression like [reference], but the expression is valid 35 * Constructs an expression like [reference], but the expression is valid
36 * during isolate initialization. 36 * during isolate initialization.
37 */ 37 */
38 jsAst.Expression referenceInInitializationContext(Constant constant) { 38 jsAst.Expression referenceInInitializationContext(ConstantValue constant) {
39 return _referenceEmitter.generate(constant); 39 return _referenceEmitter.generate(constant);
40 } 40 }
41 41
42 /** 42 /**
43 * Constructs an expression used to initialize a canonicalized constant. 43 * Constructs an expression used to initialize a canonicalized constant.
44 */ 44 */
45 jsAst.Expression initializationExpression(Constant constant) { 45 jsAst.Expression initializationExpression(ConstantValue constant) {
46 return _literalEmitter.generate(constant); 46 return _literalEmitter.generate(constant);
47 } 47 }
48 } 48 }
49 49
50 /** 50 /**
51 * Visitor for generating JavaScript expressions to refer to [Constant]s. 51 * Visitor for generating JavaScript expressions to refer to [ConstantValue]s.
52 * Do not use directly, use methods from [ConstantEmitter]. 52 * Do not use directly, use methods from [ConstantEmitter].
53 */ 53 */
54 class ConstantReferenceEmitter implements ConstantVisitor<jsAst.Expression> { 54 class ConstantReferenceEmitter
55 implements ConstantValueVisitor<jsAst.Expression> {
55 final Compiler compiler; 56 final Compiler compiler;
56 final Namer namer; 57 final Namer namer;
57 58
58 final ConstantEmitter constantEmitter; 59 final ConstantEmitter constantEmitter;
59 60
60 ConstantReferenceEmitter(this.compiler, this.namer, this.constantEmitter); 61 ConstantReferenceEmitter(this.compiler, this.namer, this.constantEmitter);
61 62
62 jsAst.Expression generate(Constant constant) { 63 jsAst.Expression generate(ConstantValue constant) {
63 return _visit(constant); 64 return _visit(constant);
64 } 65 }
65 66
66 jsAst.Expression _visit(Constant constant) { 67 jsAst.Expression _visit(ConstantValue constant) {
67 return constant.accept(this); 68 return constant.accept(this);
68 } 69 }
69 70
70 jsAst.Expression emitCanonicalVersion(Constant constant) { 71 jsAst.Expression emitCanonicalVersion(ConstantValue constant) {
71 String name = namer.constantName(constant); 72 String name = namer.constantName(constant);
72 return new jsAst.PropertyAccess.field( 73 return new jsAst.PropertyAccess.field(
73 new jsAst.VariableUse(namer.globalObjectForConstant(constant)), name); 74 new jsAst.VariableUse(namer.globalObjectForConstant(constant)), name);
74 } 75 }
75 76
76 jsAst.Expression literal(Constant constant) { 77 jsAst.Expression literal(ConstantValue constant) {
77 return constantEmitter.literal(constant); 78 return constantEmitter.literal(constant);
78 } 79 }
79 80
80 jsAst.Expression visitFunction(FunctionConstant constant) { 81 jsAst.Expression visitFunction(FunctionConstantValue constant) {
81 return namer.isolateStaticClosureAccess(constant.element); 82 return namer.isolateStaticClosureAccess(constant.element);
82 } 83 }
83 84
84 jsAst.Expression visitNull(NullConstant constant) { 85 jsAst.Expression visitNull(NullConstantValue constant) {
85 return literal(constant); 86 return literal(constant);
86 } 87 }
87 88
88 jsAst.Expression visitInt(IntConstant constant) { 89 jsAst.Expression visitInt(IntConstantValue constant) {
89 return literal(constant); 90 return literal(constant);
90 } 91 }
91 92
92 jsAst.Expression visitDouble(DoubleConstant constant) { 93 jsAst.Expression visitDouble(DoubleConstantValue constant) {
93 return literal(constant); 94 return literal(constant);
94 } 95 }
95 96
96 jsAst.Expression visitTrue(TrueConstant constant) { 97 jsAst.Expression visitTrue(TrueConstantValue constant) {
97 return literal(constant); 98 return literal(constant);
98 } 99 }
99 100
100 jsAst.Expression visitFalse(FalseConstant constant) { 101 jsAst.Expression visitFalse(FalseConstantValue constant) {
101 return literal(constant); 102 return literal(constant);
102 } 103 }
103 104
104 /** 105 /**
105 * Write the contents of the quoted string to a [CodeBuffer] in 106 * Write the contents of the quoted string to a [CodeBuffer] in
106 * a form that is valid as JavaScript string literal content. 107 * a form that is valid as JavaScript string literal content.
107 * The string is assumed quoted by double quote characters. 108 * The string is assumed quoted by double quote characters.
108 */ 109 */
109 jsAst.Expression visitString(StringConstant constant) { 110 jsAst.Expression visitString(StringConstantValue constant) {
110 // TODO(sra): If the string is long *and repeated* (and not on a hot path) 111 // TODO(sra): If the string is long *and repeated* (and not on a hot path)
111 // then it should be assigned to a name. We don't have reference counts (or 112 // then it should be assigned to a name. We don't have reference counts (or
112 // profile information) here, so this is the wrong place. 113 // profile information) here, so this is the wrong place.
113 return literal(constant); 114 return literal(constant);
114 } 115 }
115 116
116 jsAst.Expression visitList(ListConstant constant) { 117 jsAst.Expression visitList(ListConstantValue constant) {
117 return emitCanonicalVersion(constant); 118 return emitCanonicalVersion(constant);
118 } 119 }
119 120
120 jsAst.Expression visitMap(MapConstant constant) { 121 jsAst.Expression visitMap(MapConstantValue constant) {
121 return emitCanonicalVersion(constant); 122 return emitCanonicalVersion(constant);
122 } 123 }
123 124
124 jsAst.Expression visitType(TypeConstant constant) { 125 jsAst.Expression visitType(TypeConstantValue constant) {
125 return emitCanonicalVersion(constant); 126 return emitCanonicalVersion(constant);
126 } 127 }
127 128
128 jsAst.Expression visitConstructed(ConstructedConstant constant) { 129 jsAst.Expression visitConstructed(ConstructedConstantValue constant) {
129 return emitCanonicalVersion(constant); 130 return emitCanonicalVersion(constant);
130 } 131 }
131 132
132 jsAst.Expression visitInterceptor(InterceptorConstant constant) { 133 jsAst.Expression visitInterceptor(InterceptorConstantValue constant) {
133 return emitCanonicalVersion(constant); 134 return emitCanonicalVersion(constant);
134 } 135 }
135 136
136 jsAst.Expression visitDummy(DummyConstant constant) { 137 jsAst.Expression visitDummy(DummyConstantValue constant) {
137 return literal(constant); 138 return literal(constant);
138 } 139 }
139 140
140 jsAst.Expression visitDeferred(DeferredConstant constant) { 141 jsAst.Expression visitDeferred(DeferredConstantValue constant) {
141 return emitCanonicalVersion(constant); 142 return emitCanonicalVersion(constant);
142 } 143 }
143 } 144 }
144 145
145 /** 146 /**
146 * Visitor for generating JavaScript expressions that litterally represent 147 * Visitor for generating JavaScript expressions that litterally represent
147 * [Constant]s. These can be used for inlining constants or in initializers. 148 * [ConstantValue]s. These can be used for inlining constants or in
148 * Do not use directly, use methods from [ConstantEmitter]. 149 * initializers. Do not use directly, use methods from [ConstantEmitter].
149 */ 150 */
150 class ConstantLiteralEmitter implements ConstantVisitor<jsAst.Expression> { 151 class ConstantLiteralEmitter implements ConstantValueVisitor<jsAst.Expression> {
151 152
152 // Matches blank lines, comment lines and trailing comments that can't be part 153 // Matches blank lines, comment lines and trailing comments that can't be part
153 // of a string. 154 // of a string.
154 static final RegExp COMMENT_RE = 155 static final RegExp COMMENT_RE =
155 new RegExp(r'''^ *(//.*)?\n| *//[^''"\n]*$''' , multiLine: true); 156 new RegExp(r'''^ *(//.*)?\n| *//[^''"\n]*$''' , multiLine: true);
156 157
157 final Compiler compiler; 158 final Compiler compiler;
158 final Namer namer; 159 final Namer namer;
159 final ConstantEmitter constantEmitter; 160 final ConstantEmitter constantEmitter;
160 161
161 ConstantLiteralEmitter(this.compiler, this.namer, this.constantEmitter); 162 ConstantLiteralEmitter(this.compiler, this.namer, this.constantEmitter);
162 163
163 jsAst.Expression generate(Constant constant) { 164 jsAst.Expression generate(ConstantValue constant) {
164 return _visit(constant); 165 return _visit(constant);
165 } 166 }
166 167
167 jsAst.Expression _visit(Constant constant) { 168 jsAst.Expression _visit(ConstantValue constant) {
168 return constant.accept(this); 169 return constant.accept(this);
169 } 170 }
170 171
171 jsAst.Expression visitFunction(FunctionConstant constant) { 172 jsAst.Expression visitFunction(FunctionConstantValue constant) {
172 compiler.internalError(NO_LOCATION_SPANNABLE, 173 compiler.internalError(NO_LOCATION_SPANNABLE,
173 "The function constant does not need specific JS code."); 174 "The function constant does not need specific JS code.");
174 return null; 175 return null;
175 } 176 }
176 177
177 jsAst.Expression visitNull(NullConstant constant) { 178 jsAst.Expression visitNull(NullConstantValue constant) {
178 return new jsAst.LiteralNull(); 179 return new jsAst.LiteralNull();
179 } 180 }
180 181
181 jsAst.Expression visitInt(IntConstant constant) { 182 jsAst.Expression visitInt(IntConstantValue constant) {
182 return new jsAst.LiteralNumber('${constant.value}'); 183 return new jsAst.LiteralNumber('${constant.primitiveValue}');
183 } 184 }
184 185
185 jsAst.Expression visitDouble(DoubleConstant constant) { 186 jsAst.Expression visitDouble(DoubleConstantValue constant) {
186 double value = constant.value; 187 double value = constant.primitiveValue;
187 if (value.isNaN) { 188 if (value.isNaN) {
188 return js("0/0"); 189 return js("0/0");
189 } else if (value == double.INFINITY) { 190 } else if (value == double.INFINITY) {
190 return js("1/0"); 191 return js("1/0");
191 } else if (value == -double.INFINITY) { 192 } else if (value == -double.INFINITY) {
192 return js("-1/0"); 193 return js("-1/0");
193 } else { 194 } else {
194 return new jsAst.LiteralNumber("$value"); 195 return new jsAst.LiteralNumber("$value");
195 } 196 }
196 } 197 }
197 198
198 jsAst.Expression visitTrue(TrueConstant constant) { 199 jsAst.Expression visitTrue(TrueConstantValue constant) {
199 if (compiler.enableMinification) { 200 if (compiler.enableMinification) {
200 // Use !0 for true. 201 // Use !0 for true.
201 return js("!0"); 202 return js("!0");
202 } else { 203 } else {
203 return js('true'); 204 return js('true');
204 } 205 }
205 } 206 }
206 207
207 jsAst.Expression visitFalse(FalseConstant constant) { 208 jsAst.Expression visitFalse(FalseConstantValue constant) {
208 if (compiler.enableMinification) { 209 if (compiler.enableMinification) {
209 // Use !1 for false. 210 // Use !1 for false.
210 return js("!1"); 211 return js("!1");
211 } else { 212 } else {
212 return js('false'); 213 return js('false');
213 } 214 }
214 } 215 }
215 216
216 /** 217 /**
217 * Write the contents of the quoted string to a [CodeBuffer] in 218 * Write the contents of the quoted string to a [CodeBuffer] in
218 * a form that is valid as JavaScript string literal content. 219 * a form that is valid as JavaScript string literal content.
219 * The string is assumed quoted by double quote characters. 220 * The string is assumed quoted by double quote characters.
220 */ 221 */
221 jsAst.Expression visitString(StringConstant constant) { 222 jsAst.Expression visitString(StringConstantValue constant) {
222 StringBuffer sb = new StringBuffer(); 223 StringBuffer sb = new StringBuffer();
223 writeJsonEscapedCharsOn(constant.value.slowToString(), sb); 224 writeJsonEscapedCharsOn(constant.primitiveValue.slowToString(), sb);
224 return new jsAst.LiteralString('"$sb"'); 225 return new jsAst.LiteralString('"$sb"');
225 } 226 }
226 227
227 jsAst.Expression visitList(ListConstant constant) { 228 jsAst.Expression visitList(ListConstantValue constant) {
228 jsAst.Expression value = new jsAst.Call( 229 jsAst.Expression value = new jsAst.Call(
229 new jsAst.PropertyAccess.field( 230 new jsAst.PropertyAccess.field(
230 new jsAst.VariableUse(namer.isolateName), 231 new jsAst.VariableUse(namer.isolateName),
231 namer.getMappedInstanceName('makeConstantList')), 232 namer.getMappedInstanceName('makeConstantList')),
232 [new jsAst.ArrayInitializer.from(_array(constant.entries))]); 233 [new jsAst.ArrayInitializer.from(_array(constant.entries))]);
233 return maybeAddTypeArguments(constant.type, value); 234 return maybeAddTypeArguments(constant.type, value);
234 } 235 }
235 236
236 jsAst.Expression getJsConstructor(ClassElement element) { 237 jsAst.Expression getJsConstructor(ClassElement element) {
237 return namer.elementAccess(element); 238 return namer.elementAccess(element);
238 } 239 }
239 240
240 jsAst.Expression visitMap(JavaScriptMapConstant constant) { 241 jsAst.Expression visitMap(JavaScriptMapConstant constant) {
241 jsAst.Expression jsMap() { 242 jsAst.Expression jsMap() {
242 List<jsAst.Property> properties = <jsAst.Property>[]; 243 List<jsAst.Property> properties = <jsAst.Property>[];
243 for (int i = 0; i < constant.length; i++) { 244 for (int i = 0; i < constant.length; i++) {
244 StringConstant key = constant.keys[i]; 245 StringConstantValue key = constant.keys[i];
245 if (key.value == JavaScriptMapConstant.PROTO_PROPERTY) continue; 246 if (key.primitiveValue == JavaScriptMapConstant.PROTO_PROPERTY) {
247 continue;
248 }
246 249
247 // Keys in literal maps must be emitted in place. 250 // Keys in literal maps must be emitted in place.
248 jsAst.Literal keyExpression = _visit(key); 251 jsAst.Literal keyExpression = _visit(key);
249 jsAst.Expression valueExpression = 252 jsAst.Expression valueExpression =
250 constantEmitter.reference(constant.values[i]); 253 constantEmitter.reference(constant.values[i]);
251 properties.add(new jsAst.Property(keyExpression, valueExpression)); 254 properties.add(new jsAst.Property(keyExpression, valueExpression));
252 } 255 }
253 return new jsAst.ObjectInitializer(properties); 256 return new jsAst.ObjectInitializer(properties);
254 } 257 }
255 258
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
310 new jsAst.New(getJsConstructor(classElement), arguments); 313 new jsAst.New(getJsConstructor(classElement), arguments);
311 return maybeAddTypeArguments(constant.type, value); 314 return maybeAddTypeArguments(constant.type, value);
312 } 315 }
313 316
314 JavaScriptBackend get backend => compiler.backend; 317 JavaScriptBackend get backend => compiler.backend;
315 318
316 jsAst.PropertyAccess getHelperProperty(Element helper) { 319 jsAst.PropertyAccess getHelperProperty(Element helper) {
317 return backend.namer.elementAccess(helper); 320 return backend.namer.elementAccess(helper);
318 } 321 }
319 322
320 jsAst.Expression visitType(TypeConstant constant) { 323 jsAst.Expression visitType(TypeConstantValue constant) {
321 DartType type = constant.representedType; 324 DartType type = constant.representedType;
322 String name = namer.getRuntimeTypeName(type.element); 325 String name = namer.getRuntimeTypeName(type.element);
323 jsAst.Expression typeName = new jsAst.LiteralString("'$name'"); 326 jsAst.Expression typeName = new jsAst.LiteralString("'$name'");
324 return new jsAst.Call(getHelperProperty(backend.getCreateRuntimeType()), 327 return new jsAst.Call(getHelperProperty(backend.getCreateRuntimeType()),
325 [typeName]); 328 [typeName]);
326 } 329 }
327 330
328 jsAst.Expression visitInterceptor(InterceptorConstant constant) { 331 jsAst.Expression visitInterceptor(InterceptorConstantValue constant) {
329 return new jsAst.PropertyAccess.field( 332 return new jsAst.PropertyAccess.field(
330 getJsConstructor(constant.dispatchedType.element), 333 getJsConstructor(constant.dispatchedType.element),
331 'prototype'); 334 'prototype');
332 } 335 }
333 336
334 jsAst.Expression visitDummy(DummyConstant constant) { 337 jsAst.Expression visitDummy(DummyConstantValue constant) {
335 return new jsAst.LiteralNumber('0'); 338 return new jsAst.LiteralNumber('0');
336 } 339 }
337 340
338 jsAst.Expression visitConstructed(ConstructedConstant constant) { 341 jsAst.Expression visitConstructed(ConstructedConstantValue constant) {
339 Element element = constant.type.element; 342 Element element = constant.type.element;
340 if (element.isForeign(backend) 343 if (element.isForeign(backend)
341 && element.name == 'JS_CONST') { 344 && element.name == 'JS_CONST') {
342 StringConstant str = constant.fields[0]; 345 StringConstantValue str = constant.fields[0];
343 String value = str.value.slowToString(); 346 String value = str.primitiveValue.slowToString();
344 return new jsAst.LiteralExpression(stripComments(value)); 347 return new jsAst.LiteralExpression(stripComments(value));
345 } 348 }
346 jsAst.New instantiation = new jsAst.New( 349 jsAst.New instantiation = new jsAst.New(
347 getJsConstructor(constant.type.element), 350 getJsConstructor(constant.type.element),
348 _array(constant.fields)); 351 _array(constant.fields));
349 return maybeAddTypeArguments(constant.type, instantiation); 352 return maybeAddTypeArguments(constant.type, instantiation);
350 } 353 }
351 354
352 String stripComments(String rawJavaScript) { 355 String stripComments(String rawJavaScript) {
353 return rawJavaScript.replaceAll(COMMENT_RE, ''); 356 return rawJavaScript.replaceAll(COMMENT_RE, '');
354 } 357 }
355 358
356 List<jsAst.Expression> _array(List<Constant> values) { 359 List<jsAst.Expression> _array(List<ConstantValue> values) {
357 List<jsAst.Expression> valueList = <jsAst.Expression>[]; 360 List<jsAst.Expression> valueList = <jsAst.Expression>[];
358 for (int i = 0; i < values.length; i++) { 361 for (int i = 0; i < values.length; i++) {
359 valueList.add(constantEmitter.reference(values[i])); 362 valueList.add(constantEmitter.reference(values[i]));
360 } 363 }
361 return valueList; 364 return valueList;
362 } 365 }
363 366
364 jsAst.Expression maybeAddTypeArguments(InterfaceType type, 367 jsAst.Expression maybeAddTypeArguments(InterfaceType type,
365 jsAst.Expression value) { 368 jsAst.Expression value) {
366 if (type is InterfaceType && 369 if (type is InterfaceType &&
367 !type.treatAsRaw && 370 !type.treatAsRaw &&
368 backend.classNeedsRti(type.element)) { 371 backend.classNeedsRti(type.element)) {
369 InterfaceType interface = type; 372 InterfaceType interface = type;
370 RuntimeTypes rti = backend.rti; 373 RuntimeTypes rti = backend.rti;
371 Iterable<String> arguments = interface.typeArguments 374 Iterable<String> arguments = interface.typeArguments
372 .map((DartType type) => 375 .map((DartType type) =>
373 rti.getTypeRepresentationWithHashes(type, (_){})); 376 rti.getTypeRepresentationWithHashes(type, (_){}));
374 jsAst.Expression argumentList = 377 jsAst.Expression argumentList =
375 new jsAst.LiteralString('[${arguments.join(', ')}]'); 378 new jsAst.LiteralString('[${arguments.join(', ')}]');
376 return new jsAst.Call(getHelperProperty(backend.getSetRuntimeTypeInfo()), 379 return new jsAst.Call(getHelperProperty(backend.getSetRuntimeTypeInfo()),
377 [value, argumentList]); 380 [value, argumentList]);
378 } 381 }
379 return value; 382 return value;
380 } 383 }
381 384
382 jsAst.Expression visitDeferred(DeferredConstant constant) { 385 jsAst.Expression visitDeferred(DeferredConstantValue constant) {
383 return constantEmitter.reference(constant.referenced); 386 return constantEmitter.reference(constant.referenced);
384 } 387 }
385 } 388 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698