| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 | 7 |
| 8 class OldEmitter implements Emitter { | 8 class OldEmitter implements Emitter { |
| 9 final Compiler compiler; | 9 final Compiler compiler; |
| 10 final CodeEmitterTask task; | 10 final CodeEmitterTask task; |
| (...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 413 instanceFromClassIdAssignment, | 413 instanceFromClassIdAssignment, |
| 414 initializeEmptyInstanceAssignment]); | 414 initializeEmptyInstanceAssignment]); |
| 415 } | 415 } |
| 416 | 416 |
| 417 return result; | 417 return result; |
| 418 } | 418 } |
| 419 | 419 |
| 420 /** Needs defineClass to be defined. */ | 420 /** Needs defineClass to be defined. */ |
| 421 jsAst.Expression buildInheritFrom() { | 421 jsAst.Expression buildInheritFrom() { |
| 422 jsAst.Expression result = js(r""" | 422 jsAst.Expression result = js(r""" |
| 423 // If the browser supports changing the prototype via __proto__, we make |
| 424 // use of that feature. Otherwise, we copy the properties into a new |
| 425 // constructor. |
| 426 (function () { |
| 427 var cls = function () {}; |
| 428 cls.prototype = {'p': {}}; |
| 429 var object = new cls(); |
| 430 return object.__proto__ && |
| 431 object.__proto__.p === cls.prototype.p; |
| 432 })() ? |
| 433 function(constructor, superConstructor) { |
| 434 var prototype = constructor.prototype; |
| 435 prototype.__proto__ = superConstructor.prototype; |
| 436 // Use a function for `true` here, as functions are stored in the |
| 437 // hidden class and not as properties in the object. |
| 438 prototype.constructor = constructor; |
| 439 prototype[#operatorIsPrefix + constructor.name] = constructor; |
| 440 return convertToFastObject(prototype); |
| 441 } : |
| 423 function() { | 442 function() { |
| 424 function tmp() {} | 443 function tmp() {} |
| 425 return function (constructor, superConstructor) { | 444 return function (constructor, superConstructor) { |
| 426 tmp.prototype = superConstructor.prototype; | 445 tmp.prototype = superConstructor.prototype; |
| 427 var object = new tmp(); | 446 var object = new tmp(); |
| 428 object.x = 0; delete object.x; // Make object slow. | 447 convertToSlowObject(object); |
| 429 var properties = constructor.prototype; | 448 var properties = constructor.prototype; |
| 430 var members = Object.keys(properties); | 449 var members = Object.keys(properties); |
| 431 for (var i = 0; i < members.length; i++) { | 450 for (var i = 0; i < members.length; i++) { |
| 432 var member = members[i]; | 451 var member = members[i]; |
| 433 object[member] = properties[member]; | 452 object[member] = properties[member]; |
| 434 } | 453 } |
| 435 // Use a function for `true` here, as functions are stored in the | 454 // Use a function for `true` here, as functions are stored in the |
| 436 // hidden class and not as properties in the object. | 455 // hidden class and not as properties in the object. |
| 437 object[#operatorIsPrefix + constructor.name] = constructor; | 456 object[#operatorIsPrefix + constructor.name] = constructor; |
| 438 object.constructor = constructor; | 457 object.constructor = constructor; |
| (...skipping 662 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1101 MyClass.prototype = properties; | 1120 MyClass.prototype = properties; |
| 1102 new MyClass(); | 1121 new MyClass(); |
| 1103 #; | 1122 #; |
| 1104 return properties; | 1123 return properties; |
| 1105 }''', [debugCode]); | 1124 }''', [debugCode]); |
| 1106 | 1125 |
| 1107 output.addBuffer(jsAst.prettyPrint(convertToFastObject, compiler)); | 1126 output.addBuffer(jsAst.prettyPrint(convertToFastObject, compiler)); |
| 1108 output.add(N); | 1127 output.add(N); |
| 1109 } | 1128 } |
| 1110 | 1129 |
| 1130 void emitConvertToSlowObjectFunction(CodeOutput output) { |
| 1131 jsAst.Statement convertToSlowObject = js.statement(r''' |
| 1132 function convertToSlowObject(properties) { |
| 1133 // Add and remove a property to make the object transition into hashmap |
| 1134 // mode. |
| 1135 properties.__MAGIC_SLOW_PROPERTY = 1; |
| 1136 delete properties.__MAGIC_SLOW_PROPERTY; |
| 1137 return properties; |
| 1138 }'''); |
| 1139 |
| 1140 output.addBuffer(jsAst.prettyPrint(convertToSlowObject, compiler)); |
| 1141 output.add(N); |
| 1142 } |
| 1143 |
| 1111 void writeLibraryDescriptors(CodeOutput output, LibraryElement library) { | 1144 void writeLibraryDescriptors(CodeOutput output, LibraryElement library) { |
| 1112 var uri = ""; | 1145 var uri = ""; |
| 1113 if (!compiler.enableMinification || backend.mustPreserveUris) { | 1146 if (!compiler.enableMinification || backend.mustPreserveUris) { |
| 1114 uri = library.canonicalUri; | 1147 uri = library.canonicalUri; |
| 1115 if (uri.scheme == 'file' && compiler.outputUri != null) { | 1148 if (uri.scheme == 'file' && compiler.outputUri != null) { |
| 1116 uri = relativize(compiler.outputUri, library.canonicalUri, false); | 1149 uri = relativize(compiler.outputUri, library.canonicalUri, false); |
| 1117 } | 1150 } |
| 1118 } | 1151 } |
| 1119 ClassBuilder descriptor = elementDescriptors[library]; | 1152 ClassBuilder descriptor = elementDescriptors[library]; |
| 1120 if (descriptor == null) { | 1153 if (descriptor == null) { |
| (...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1465 isolateProperties = isolatePropertiesName; | 1498 isolateProperties = isolatePropertiesName; |
| 1466 // The following code should not use the short-hand for the | 1499 // The following code should not use the short-hand for the |
| 1467 // initialStatics. | 1500 // initialStatics. |
| 1468 mainOutput.add('${namer.currentIsolate}$_=${_}null$N'); | 1501 mainOutput.add('${namer.currentIsolate}$_=${_}null$N'); |
| 1469 | 1502 |
| 1470 emitFinishIsolateConstructorInvocation(mainOutput); | 1503 emitFinishIsolateConstructorInvocation(mainOutput); |
| 1471 mainOutput.add( | 1504 mainOutput.add( |
| 1472 '${namer.currentIsolate}$_=${_}new ${namer.isolateName}()$N'); | 1505 '${namer.currentIsolate}$_=${_}new ${namer.isolateName}()$N'); |
| 1473 | 1506 |
| 1474 emitConvertToFastObjectFunction(mainOutput); | 1507 emitConvertToFastObjectFunction(mainOutput); |
| 1508 emitConvertToSlowObjectFunction(mainOutput); |
| 1509 |
| 1475 for (String globalObject in Namer.reservedGlobalObjectNames) { | 1510 for (String globalObject in Namer.reservedGlobalObjectNames) { |
| 1476 mainOutput.add('$globalObject = convertToFastObject($globalObject)$N'); | 1511 mainOutput.add('$globalObject = convertToFastObject($globalObject)$N'); |
| 1477 } | 1512 } |
| 1478 if (DEBUG_FAST_OBJECTS) { | 1513 if (DEBUG_FAST_OBJECTS) { |
| 1479 mainOutput.add(r''' | 1514 mainOutput.add(r''' |
| 1480 // The following only works on V8 when run with option | 1515 // The following only works on V8 when run with option |
| 1481 // "--allow-natives-syntax". We use'new Function' because the | 1516 // "--allow-natives-syntax". We use'new Function' because the |
| 1482 // miniparser does not understand V8 native syntax. | 1517 // miniparser does not understand V8 native syntax. |
| 1483 if (typeof print === "function") { | 1518 if (typeof print === "function") { |
| 1484 var HasFastProperties = | 1519 var HasFastProperties = |
| (...skipping 514 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1999 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) { | 2034 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) { |
| 2000 if (element.isInstanceMember) { | 2035 if (element.isInstanceMember) { |
| 2001 cachedClassBuilders.remove(element.enclosingClass); | 2036 cachedClassBuilders.remove(element.enclosingClass); |
| 2002 | 2037 |
| 2003 nativeEmitter.cachedBuilders.remove(element.enclosingClass); | 2038 nativeEmitter.cachedBuilders.remove(element.enclosingClass); |
| 2004 | 2039 |
| 2005 } | 2040 } |
| 2006 } | 2041 } |
| 2007 } | 2042 } |
| 2008 } | 2043 } |
| OLD | NEW |