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

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

Powered by Google App Engine
This is Rietveld 408576698