Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 class Constant implements Hashable { | 5 class Constant implements Hashable { |
| 6 const Constant(); | 6 const Constant(); |
| 7 | 7 |
| 8 bool isNull() => false; | 8 bool isNull() => false; |
| 9 bool isBool() => false; | 9 bool isBool() => false; |
| 10 bool isTrue() => false; | 10 bool isTrue() => false; |
| 11 bool isFalse() => false; | 11 bool isFalse() => false; |
| 12 bool isInt() => false; | 12 bool isInt() => false; |
| 13 bool isDouble() => false; | 13 bool isDouble() => false; |
| 14 bool isNum() => false; | 14 bool isNum() => false; |
| 15 bool isString() => false; | 15 bool isString() => false; |
| 16 bool isList() => false; | 16 bool isList() => false; |
| 17 bool isMap() => false; | 17 bool isMap() => false; |
| 18 bool isConstructedObject() => false; | 18 bool isConstructedObject() => false; |
| 19 bool isFunction() => false; | 19 bool isFunction() => false; |
| 20 /** Returns true if the constant is null, a bool, a number or a string. */ | 20 /** Returns true if the constant is null, a bool, a number or a string. */ |
| 21 bool isPrimitive() => false; | 21 bool isPrimitive() => false; |
| 22 /** Returns true if the constant is a list, a map or a constructed object. */ | 22 /** Returns true if the constant is a list, a map or a constructed object. */ |
| 23 bool isObject() => false; | 23 bool isObject() => false; |
| 24 | 24 |
| 25 bool isNaN() => false; | 25 bool isNaN() => false; |
| 26 | 26 |
| 27 abstract bool isSameType(Constant constant); | |
|
ngeoffray
2012/08/30 07:29:13
I'd prefer having something consistant with what w
Lasse Reichstein Nielsen
2012/08/30 10:54:25
Seems reasonable if there is a simple way to get a
ngeoffray
2012/08/30 11:07:13
The Dart "primitive" types? compiler.boolClass.com
Lasse Reichstein Nielsen
2012/09/03 09:12:56
Done.
| |
| 28 | |
| 27 abstract void _writeJsCode(CodeBuffer buffer, ConstantHandler handler); | 29 abstract void _writeJsCode(CodeBuffer buffer, ConstantHandler handler); |
| 28 /** | 30 /** |
| 29 * Unless the constant can be emitted multiple times (as for numbers and | 31 * Unless the constant can be emitted multiple times (as for numbers and |
| 30 * strings) adds its canonical name to the buffer. | 32 * strings) adds its canonical name to the buffer. |
| 31 */ | 33 */ |
| 32 abstract void _writeCanonicalizedJsCode(CodeBuffer buffer, | 34 abstract void _writeCanonicalizedJsCode(CodeBuffer buffer, |
| 33 ConstantHandler handler); | 35 ConstantHandler handler); |
| 34 abstract List<Constant> getDependencies(); | 36 abstract List<Constant> getDependencies(); |
| 35 } | 37 } |
| 36 | 38 |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 87 } | 89 } |
| 88 | 90 |
| 89 class NullConstant extends PrimitiveConstant { | 91 class NullConstant extends PrimitiveConstant { |
| 90 /** The value a Dart null is compiled to in JavaScript. */ | 92 /** The value a Dart null is compiled to in JavaScript. */ |
| 91 static const String JsNull = "null"; | 93 static const String JsNull = "null"; |
| 92 | 94 |
| 93 factory NullConstant() => const NullConstant._internal(); | 95 factory NullConstant() => const NullConstant._internal(); |
| 94 const NullConstant._internal(); | 96 const NullConstant._internal(); |
| 95 bool isNull() => true; | 97 bool isNull() => true; |
| 96 get value => null; | 98 get value => null; |
| 99 bool isSameType(Constant constant) => constant.isNull(); | |
| 97 | 100 |
| 98 void _writeJsCode(CodeBuffer buffer, ConstantHandler handler) { | 101 void _writeJsCode(CodeBuffer buffer, ConstantHandler handler) { |
| 99 buffer.add(JsNull); | 102 buffer.add(JsNull); |
| 100 } | 103 } |
| 101 | 104 |
| 102 // The magic constant has no meaning. It is just a random value. | 105 // The magic constant has no meaning. It is just a random value. |
| 103 int hashCode() => 785965825; | 106 int hashCode() => 785965825; |
| 104 DartString toDartString() => const LiteralDartString("null"); | 107 DartString toDartString() => const LiteralDartString("null"); |
| 105 } | 108 } |
| 106 | 109 |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 125 case 8: return const IntConstant._internal(8); | 128 case 8: return const IntConstant._internal(8); |
| 126 case 9: return const IntConstant._internal(9); | 129 case 9: return const IntConstant._internal(9); |
| 127 case 10: return const IntConstant._internal(10); | 130 case 10: return const IntConstant._internal(10); |
| 128 case -1: return const IntConstant._internal(-1); | 131 case -1: return const IntConstant._internal(-1); |
| 129 case -2: return const IntConstant._internal(-2); | 132 case -2: return const IntConstant._internal(-2); |
| 130 default: return new IntConstant._internal(value); | 133 default: return new IntConstant._internal(value); |
| 131 } | 134 } |
| 132 } | 135 } |
| 133 const IntConstant._internal(this.value); | 136 const IntConstant._internal(this.value); |
| 134 bool isInt() => true; | 137 bool isInt() => true; |
| 138 bool isSameType(Constant constant) => constant.isInt(); | |
| 135 | 139 |
| 136 void _writeJsCode(CodeBuffer buffer, ConstantHandler handler) { | 140 void _writeJsCode(CodeBuffer buffer, ConstantHandler handler) { |
| 137 buffer.add("$value"); | 141 buffer.add("$value"); |
| 138 } | 142 } |
| 139 | 143 |
| 140 // We have to override the equality operator so that ints and doubles are | 144 // We have to override the equality operator so that ints and doubles are |
| 141 // treated as separate constants. | 145 // treated as separate constants. |
| 142 // The is [:!IntConstant:] check at the beginning of the function makes sure | 146 // The is [:!IntConstant:] check at the beginning of the function makes sure |
| 143 // that we compare only equal to integer constants. | 147 // that we compare only equal to integer constants. |
| 144 bool operator ==(var other) { | 148 bool operator ==(var other) { |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 164 return const DoubleConstant._internal(0.0); | 168 return const DoubleConstant._internal(0.0); |
| 165 } else if (value == 1.0) { | 169 } else if (value == 1.0) { |
| 166 return const DoubleConstant._internal(1.0); | 170 return const DoubleConstant._internal(1.0); |
| 167 } else { | 171 } else { |
| 168 return new DoubleConstant._internal(value); | 172 return new DoubleConstant._internal(value); |
| 169 } | 173 } |
| 170 } | 174 } |
| 171 const DoubleConstant._internal(this.value); | 175 const DoubleConstant._internal(this.value); |
| 172 bool isDouble() => true; | 176 bool isDouble() => true; |
| 173 bool isNaN() => value.isNaN(); | 177 bool isNaN() => value.isNaN(); |
| 178 bool isSameType(Constant constant) => constant.isDouble(); | |
| 174 | 179 |
| 175 void _writeJsCode(CodeBuffer buffer, ConstantHandler handler) { | 180 void _writeJsCode(CodeBuffer buffer, ConstantHandler handler) { |
| 176 if (value.isNaN()) { | 181 if (value.isNaN()) { |
| 177 buffer.add("(0/0)"); | 182 buffer.add("(0/0)"); |
| 178 } else if (value == double.INFINITY) { | 183 } else if (value == double.INFINITY) { |
| 179 buffer.add("(1/0)"); | 184 buffer.add("(1/0)"); |
| 180 } else if (value == -double.INFINITY) { | 185 } else if (value == -double.INFINITY) { |
| 181 buffer.add("(-1/0)"); | 186 buffer.add("(-1/0)"); |
| 182 } else { | 187 } else { |
| 183 buffer.add("$value"); | 188 buffer.add("$value"); |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 200 int hashCode() => value.hashCode(); | 205 int hashCode() => value.hashCode(); |
| 201 DartString toDartString() => new DartString.literal(value.toString()); | 206 DartString toDartString() => new DartString.literal(value.toString()); |
| 202 } | 207 } |
| 203 | 208 |
| 204 class BoolConstant extends PrimitiveConstant { | 209 class BoolConstant extends PrimitiveConstant { |
| 205 factory BoolConstant(value) { | 210 factory BoolConstant(value) { |
| 206 return value ? new TrueConstant() : new FalseConstant(); | 211 return value ? new TrueConstant() : new FalseConstant(); |
| 207 } | 212 } |
| 208 const BoolConstant._internal(); | 213 const BoolConstant._internal(); |
| 209 bool isBool() => true; | 214 bool isBool() => true; |
| 215 bool isSameType(Constant constant) => constant.isBool(); | |
| 210 | 216 |
| 211 BoolConstant unaryFold(String op) { | 217 BoolConstant unaryFold(String op) { |
| 212 if (op == "!") return new BoolConstant(!value); | 218 if (op == "!") return new BoolConstant(!value); |
| 213 return null; | 219 return null; |
| 214 } | 220 } |
| 215 | 221 |
| 216 abstract BoolConstant negate(); | 222 abstract BoolConstant negate(); |
| 217 } | 223 } |
| 218 | 224 |
| 219 class TrueConstant extends BoolConstant { | 225 class TrueConstant extends BoolConstant { |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 261 int _hashCode; | 267 int _hashCode; |
| 262 final Node node; | 268 final Node node; |
| 263 | 269 |
| 264 StringConstant(this.value, this.node) { | 270 StringConstant(this.value, this.node) { |
| 265 // TODO(floitsch): cache StringConstants. | 271 // TODO(floitsch): cache StringConstants. |
| 266 // TODO(floitsch): compute hashcode without calling toString() on the | 272 // TODO(floitsch): compute hashcode without calling toString() on the |
| 267 // DartString. | 273 // DartString. |
| 268 _hashCode = value.slowToString().hashCode(); | 274 _hashCode = value.slowToString().hashCode(); |
| 269 } | 275 } |
| 270 bool isString() => true; | 276 bool isString() => true; |
| 277 bool isSameType(Constant constant) => constant.isString(); | |
| 271 | 278 |
| 272 void _writeJsCode(CodeBuffer buffer, ConstantHandler handler) { | 279 void _writeJsCode(CodeBuffer buffer, ConstantHandler handler) { |
| 273 buffer.add("'"); | 280 buffer.add("'"); |
| 274 ConstantHandler.writeEscapedString(value, buffer, (reason) { | 281 ConstantHandler.writeEscapedString(value, buffer, (reason) { |
| 275 handler.compiler.reportError(node, reason); | 282 handler.compiler.reportError(node, reason); |
| 276 }); | 283 }); |
| 277 buffer.add("'"); | 284 buffer.add("'"); |
| 278 } | 285 } |
| 279 | 286 |
| 280 bool operator ==(var other) { | 287 bool operator ==(var other) { |
| 281 if (other is !StringConstant) return false; | 288 if (other is !StringConstant) return false; |
| 282 StringConstant otherString = other; | 289 StringConstant otherString = other; |
| 283 return (_hashCode == otherString._hashCode) && (value == otherString.value); | 290 return (_hashCode == otherString._hashCode) && (value == otherString.value); |
| 284 } | 291 } |
| 285 | 292 |
| 286 int hashCode() => _hashCode; | 293 int hashCode() => _hashCode; |
| 287 DartString toDartString() => value; | 294 DartString toDartString() => value; |
| 288 int get length => value.length; | 295 int get length => value.length; |
| 289 } | 296 } |
| 290 | 297 |
| 291 class ObjectConstant extends Constant { | 298 abstract class ObjectConstant extends Constant { |
| 292 final Type type; | 299 final Type type; |
| 293 | 300 |
| 294 ObjectConstant(this.type); | 301 ObjectConstant(this.type); |
| 295 bool isObject() => true; | 302 bool isObject() => true; |
| 296 | 303 |
| 297 // TODO(1603): The class should be marked as abstract, but the VM doesn't | |
| 298 // currently allow this. | |
| 299 abstract int hashCode(); | 304 abstract int hashCode(); |
| 300 | 305 |
| 301 void _writeCanonicalizedJsCode(CodeBuffer buffer, ConstantHandler handler) { | 306 void _writeCanonicalizedJsCode(CodeBuffer buffer, ConstantHandler handler) { |
| 302 String name = handler.getNameForConstant(this); | 307 String name = handler.getNameForConstant(this); |
| 303 buffer.add(handler.compiler.namer.isolatePropertiesAccessForConstant(name)); | 308 buffer.add(handler.compiler.namer.isolatePropertiesAccessForConstant(name)); |
| 304 } | 309 } |
| 305 } | 310 } |
| 306 | 311 |
| 307 class ListConstant extends ObjectConstant { | 312 class ListConstant extends ObjectConstant { |
| 308 final List<Constant> entries; | 313 final List<Constant> entries; |
| 309 int _hashCode; | 314 int _hashCode; |
| 310 | 315 |
| 311 ListConstant(Type type, this.entries) : super(type) { | 316 ListConstant(Type type, this.entries) : super(type) { |
| 312 // TODO(floitsch): create a better hash. | 317 // TODO(floitsch): create a better hash. |
| 313 int hash = 0; | 318 int hash = 0; |
| 314 for (Constant input in entries) hash ^= input.hashCode(); | 319 for (Constant input in entries) hash ^= input.hashCode(); |
| 315 _hashCode = hash; | 320 _hashCode = hash; |
| 316 } | 321 } |
| 317 bool isList() => true; | 322 bool isList() => true; |
| 323 bool isSameType(Constant constant) { | |
| 324 if (!constant.isList()) return false; | |
| 325 ListConstant listConstant = constant; | |
| 326 // TODO(lrn): Does this work at all? | |
| 327 return type == listConstant.type; | |
|
floitsch
2012/08/30 14:08:18
I would expect this to be always true. Maybe chang
Lasse Reichstein Nielsen
2012/09/03 09:12:56
It's gone now. Switched everything to having a com
| |
| 328 } | |
| 318 | 329 |
| 319 void _writeJsCode(CodeBuffer buffer, ConstantHandler handler) { | 330 void _writeJsCode(CodeBuffer buffer, ConstantHandler handler) { |
| 320 // TODO(floitsch): we should not need to go through the compiler to make | 331 // TODO(floitsch): we should not need to go through the compiler to make |
| 321 // the list constant. | 332 // the list constant. |
| 322 buffer.add("${handler.compiler.namer.ISOLATE}.makeConstantList"); | 333 buffer.add("${handler.compiler.namer.ISOLATE}.makeConstantList"); |
| 323 buffer.add("(["); | 334 buffer.add("(["); |
| 324 for (int i = 0; i < entries.length; i++) { | 335 for (int i = 0; i < entries.length; i++) { |
| 325 if (i != 0) buffer.add(", "); | 336 if (i != 0) buffer.add(", "); |
| 326 Constant entry = entries[i]; | 337 Constant entry = entries[i]; |
| 327 handler.writeConstant(buffer, entry); | 338 handler.writeConstant(buffer, entry); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 371 | 382 |
| 372 MapConstant(Type type, this.keys, this.values, this.protoValue) | 383 MapConstant(Type type, this.keys, this.values, this.protoValue) |
| 373 : super(type) { | 384 : super(type) { |
| 374 // TODO(floitsch): create a better hash. | 385 // TODO(floitsch): create a better hash. |
| 375 int hash = 0; | 386 int hash = 0; |
| 376 for (Constant value in values) hash ^= value.hashCode(); | 387 for (Constant value in values) hash ^= value.hashCode(); |
| 377 _hashCode = hash; | 388 _hashCode = hash; |
| 378 } | 389 } |
| 379 bool isMap() => true; | 390 bool isMap() => true; |
| 380 | 391 |
| 392 bool isSameType(Constant constant) { | |
| 393 if (!constant.isMap()) return false; | |
| 394 MapConstant mapConstant = constant; | |
|
floitsch
2012/08/30 14:08:18
ditto, but no assert, since maps containing __prot
Lasse Reichstein Nielsen
2012/09/03 09:12:56
Gone too.
| |
| 395 return type == mapConstant.type; | |
| 396 } | |
| 397 | |
| 381 void _writeJsCode(CodeBuffer buffer, ConstantHandler handler) { | 398 void _writeJsCode(CodeBuffer buffer, ConstantHandler handler) { |
| 382 | 399 |
| 383 void writeJsMap() { | 400 void writeJsMap() { |
| 384 buffer.add("{"); | 401 buffer.add("{"); |
| 385 int valueIndex = 0; | 402 int valueIndex = 0; |
| 386 for (int i = 0; i < keys.entries.length; i++) { | 403 for (int i = 0; i < keys.entries.length; i++) { |
| 387 StringConstant key = keys.entries[i]; | 404 StringConstant key = keys.entries[i]; |
| 388 if (key.value == const LiteralDartString(PROTO_PROPERTY)) continue; | 405 if (key.value == const LiteralDartString(PROTO_PROPERTY)) continue; |
| 389 | 406 |
| 390 if (valueIndex != 0) buffer.add(", "); | 407 if (valueIndex != 0) buffer.add(", "); |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 469 assert(type !== null); | 486 assert(type !== null); |
| 470 // TODO(floitsch): create a better hash. | 487 // TODO(floitsch): create a better hash. |
| 471 int hash = 0; | 488 int hash = 0; |
| 472 for (Constant field in fields) { | 489 for (Constant field in fields) { |
| 473 hash ^= field.hashCode(); | 490 hash ^= field.hashCode(); |
| 474 } | 491 } |
| 475 hash ^= type.element.hashCode(); | 492 hash ^= type.element.hashCode(); |
| 476 _hashCode = hash; | 493 _hashCode = hash; |
| 477 } | 494 } |
| 478 bool isConstructedObject() => true; | 495 bool isConstructedObject() => true; |
| 496 bool isSameType(Constant constant) { | |
| 497 if (!constant.isConstructedObject()) return false; | |
| 498 ConstructredConstant constructedConstant = constant; | |
| 499 // TODO(lrn): Is this the entire type, including type parameters? | |
| 500 return type == constructedConstant.type; | |
| 501 } | |
| 479 | 502 |
| 480 void _writeJsCode(CodeBuffer buffer, ConstantHandler handler) { | 503 void _writeJsCode(CodeBuffer buffer, ConstantHandler handler) { |
| 481 buffer.add("new "); | 504 buffer.add("new "); |
| 482 buffer.add(handler.getJsConstructor(type.element)); | 505 buffer.add(handler.getJsConstructor(type.element)); |
| 483 buffer.add("("); | 506 buffer.add("("); |
| 484 for (int i = 0; i < fields.length; i++) { | 507 for (int i = 0; i < fields.length; i++) { |
| 485 if (i != 0) buffer.add(", "); | 508 if (i != 0) buffer.add(", "); |
| 486 Constant field = fields[i]; | 509 Constant field = fields[i]; |
| 487 handler.writeConstant(buffer, field); | 510 handler.writeConstant(buffer, field); |
| 488 } | 511 } |
| (...skipping 721 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1210 Constant fieldValue = fieldValues[field]; | 1233 Constant fieldValue = fieldValues[field]; |
| 1211 if (fieldValue === null) { | 1234 if (fieldValue === null) { |
| 1212 // Use the default value. | 1235 // Use the default value. |
| 1213 fieldValue = compiler.compileVariable(field); | 1236 fieldValue = compiler.compileVariable(field); |
| 1214 } | 1237 } |
| 1215 jsNewArguments.add(fieldValue); | 1238 jsNewArguments.add(fieldValue); |
| 1216 }); | 1239 }); |
| 1217 return jsNewArguments; | 1240 return jsNewArguments; |
| 1218 } | 1241 } |
| 1219 } | 1242 } |
| OLD | NEW |