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

Side by Side Diff: pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart

Issue 974803002: Defer addStubs to class instantiation time. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 5 years, 9 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) 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 317 matching lines...) Expand 10 before | Expand all | Expand 10 after
328 328
329 for (var i = 0; i < fields.length; i++) { 329 for (var i = 0; i < fields.length; i++) {
330 if(i != 0) str += ", "; 330 if(i != 0) str += ", ";
331 331
332 var field = generateAccessor(fields[i], accessors, name); 332 var field = generateAccessor(fields[i], accessors, name);
333 if (#hasIsolateSupport) { fieldNames += "'" + field + "',"; } 333 if (#hasIsolateSupport) { fieldNames += "'" + field + "',"; }
334 var parameter = "p_" + field; 334 var parameter = "p_" + field;
335 str += parameter; 335 str += parameter;
336 body += ("this." + field + " = " + parameter + ";\n"); 336 body += ("this." + field + " = " + parameter + ";\n");
337 } 337 }
338 if (supportsDirectProtoAccess)
339 body += "if (this." + #deferredAction + ") this." + #deferredAction
340 + "();";
338 str += ") {\n" + body + "}\n"; 341 str += ") {\n" + body + "}\n";
339 str += name + ".builtin$cls=\"" + name + "\";\n"; 342 str += name + ".builtin$cls=\"" + name + "\";\n";
340 str += "$desc=$collectedClasses." + name + "[1];\n"; 343 str += "$desc=$collectedClasses." + name + "[1];\n";
341 str += name + ".prototype = $desc;\n"; 344 str += name + ".prototype = $desc;\n";
342 if (typeof defineClass.name != "string") { 345 if (typeof defineClass.name != "string") {
343 str += name + ".name=\"" + name + "\";\n"; 346 str += name + ".name=\"" + name + "\";\n";
344 } 347 }
345 if (#hasIsolateSupport) { 348 if (#hasIsolateSupport) {
346 str += name + "." + #fieldNamesProperty + "=[" + fieldNames 349 str += name + "." + #fieldNamesProperty + "=[" + fieldNames
347 + "];\n"; 350 + "];\n";
348 } 351 }
349 str += accessors.join(""); 352 str += accessors.join("");
350 353
351 return str; 354 return str;
352 }''', { 'hasIsolateSupport': hasIsolateSupport, 355 }''', { 'deferredAction': js.string(namer.deferredAction),
356 'hasIsolateSupport': hasIsolateSupport,
353 'fieldNamesProperty': js.string(fieldNamesProperty)}); 357 'fieldNamesProperty': js.string(fieldNamesProperty)});
354 358
355 // Declare a function called "generateAccessor". This is used in 359 // Declare a function called "generateAccessor". This is used in
356 // defineClassFunction. 360 // defineClassFunction.
357 List result = <jsAst.Node>[ 361 List result = <jsAst.Node>[
358 generateAccessorFunction, 362 generateAccessorFunction,
359 new jsAst.FunctionDeclaration( 363 new jsAst.FunctionDeclaration(
360 new jsAst.VariableDeclaration('defineClass'), defineClass) ]; 364 new jsAst.VariableDeclaration('defineClass'), defineClass) ];
361 365
362 if (compiler.hasIncrementalSupport) { 366 if (compiler.hasIncrementalSupport) {
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
416 420
417 return result; 421 return result;
418 } 422 }
419 423
420 /** Needs defineClass to be defined. */ 424 /** Needs defineClass to be defined. */
421 jsAst.Expression buildInheritFrom() { 425 jsAst.Expression buildInheritFrom() {
422 jsAst.Expression result = js(r""" 426 jsAst.Expression result = js(r"""
423 // If the browser supports changing the prototype via __proto__, we make 427 // If the browser supports changing the prototype via __proto__, we make
424 // use of that feature. Otherwise, we copy the properties into a new 428 // use of that feature. Otherwise, we copy the properties into a new
425 // constructor. 429 // constructor.
426 (function () { 430 supportsDirectProtoAccess ?
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) { 431 function(constructor, superConstructor) {
434 var prototype = constructor.prototype; 432 var prototype = constructor.prototype;
435 prototype.__proto__ = superConstructor.prototype; 433 prototype.__proto__ = superConstructor.prototype;
436 // Use a function for `true` here, as functions are stored in the 434 // Use a function for `true` here, as functions are stored in the
437 // hidden class and not as properties in the object. 435 // hidden class and not as properties in the object.
438 prototype.constructor = constructor; 436 prototype.constructor = constructor;
439 prototype[#operatorIsPrefix + constructor.name] = constructor; 437 prototype[#operatorIsPrefix + constructor.name] = constructor;
440 return convertToFastObject(prototype); 438 return convertToFastObject(prototype);
441 } : 439 } :
442 function() { 440 function() {
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
522 // class. The minifier together with noSuchMethod can put methods on 520 // class. The minifier together with noSuchMethod can put methods on
523 // the Object.prototype object, and they show through here, so we check 521 // the Object.prototype object, and they show through here, so we check
524 // that we have a string. 522 // that we have a string.
525 if (!superclass || typeof superclass != "string") { 523 if (!superclass || typeof superclass != "string") {
526 // Inlined special case of InheritFrom here for performance reasons. 524 // Inlined special case of InheritFrom here for performance reasons.
527 // Fix up the the Dart Object class' prototype. 525 // Fix up the the Dart Object class' prototype.
528 var constructor = allClasses[cls]; 526 var constructor = allClasses[cls];
529 var prototype = constructor.prototype; 527 var prototype = constructor.prototype;
530 prototype.constructor = constructor; 528 prototype.constructor = constructor;
531 prototype.#isObject = constructor; 529 prototype.#isObject = constructor;
530 // Ensure that all stubs have been generated.
531 if (constructor.prototype.#deferredAction)
532 constructor.prototype.#deferredAction();
532 return; 533 return;
533 } 534 }
534 finishClass(superclass); 535 finishClass(superclass);
535 var superConstructor = allClasses[superclass]; 536 var superConstructor = allClasses[superclass];
536 537
537 if (!superConstructor) 538 if (!superConstructor)
538 superConstructor = existingIsolateProperties[superclass]; 539 superConstructor = existingIsolateProperties[superclass];
539 540
540 var constructor = allClasses[cls]; 541 var constructor = allClasses[cls];
541 var prototype = inheritFrom(constructor, superConstructor); 542 var prototype = inheritFrom(constructor, superConstructor);
542 543
543 if (#hasNativeClasses) 544 if (#hasNativeClasses)
544 if (Object.prototype.hasOwnProperty.call(prototype, $specProperty)) 545 if (Object.prototype.hasOwnProperty.call(prototype, $specProperty)) {
545 #nativeInfoHandler 546 #nativeInfoHandler;
547 // As native classes can come into existence without a constructor
548 // call, we have to ensure that the class has been fully
549 // initialized.
550 if (constructor.prototype.#deferredAction)
551 constructor.prototype.#deferredAction();
552 }
553 // Interceptors (or rather their prototypes) are also used without
554 // first instantiating them first.
floitsch 2015/03/06 14:54:09 delete first "first".
555 if (superclass === #interceptorClassName &&
556 constructor.prototype.#deferredAction) {
557 constructor.prototype.#deferredAction();
558 }
546 } 559 }
547 }''', {'finishedClassesAccess': finishedClassesAccess, 560 }''', {'deferredAction': namer.deferredAction,
561 'finishedClassesAccess': finishedClassesAccess,
548 'needsMixinSupport': needsMixinSupport, 562 'needsMixinSupport': needsMixinSupport,
549 'hasNativeClasses': hasNativeClasses, 563 'hasNativeClasses': hasNativeClasses,
550 'nativeInfoHandler': nativeInfoHandler, 564 'nativeInfoHandler': nativeInfoHandler,
565 'interceptorClassName':
566 js.string(namer.getNameOfClass(backend.jsInterceptorClass)),
551 'isObject' : namer.operatorIs(compiler.objectClass) }); 567 'isObject' : namer.operatorIs(compiler.objectClass) });
552 } 568 }
553 569
554 void emitFinishIsolateConstructorInvocation(CodeOutput output) { 570 void emitFinishIsolateConstructorInvocation(CodeOutput output) {
555 String isolate = namer.isolateName; 571 String isolate = namer.isolateName;
556 output.add("$isolate = $finishIsolateConstructorName($isolate)$N"); 572 output.add("$isolate = $finishIsolateConstructorName($isolate)$N");
557 } 573 }
558 574
559 /// In minified mode we want to keep the name for the most common core types. 575 /// In minified mode we want to keep the name for the most common core types.
560 bool _isNativeTypeNeedingReflectionName(Element element) { 576 bool _isNativeTypeNeedingReflectionName(Element element) {
(...skipping 573 matching lines...) Expand 10 before | Expand all | Expand 10 after
1134 // mode. 1150 // mode.
1135 properties.__MAGIC_SLOW_PROPERTY = 1; 1151 properties.__MAGIC_SLOW_PROPERTY = 1;
1136 delete properties.__MAGIC_SLOW_PROPERTY; 1152 delete properties.__MAGIC_SLOW_PROPERTY;
1137 return properties; 1153 return properties;
1138 }'''); 1154 }''');
1139 1155
1140 output.addBuffer(jsAst.prettyPrint(convertToSlowObject, compiler)); 1156 output.addBuffer(jsAst.prettyPrint(convertToSlowObject, compiler));
1141 output.add(N); 1157 output.add(N);
1142 } 1158 }
1143 1159
1160 void emitSupportsDirectProtoAccess(CodeOutput output) {
1161 jsAst.Statement supportsDirectProtoAccess = js.statement(r'''
1162 var supportsDirectProtoAccess = (function () {
1163 var cls = function () {};
1164 cls.prototype = {'p': {}};
1165 var object = new cls();
1166 return object.__proto__ &&
1167 object.__proto__.p === cls.prototype.p;
1168 })();
1169 ''');
1170
1171 output.addBuffer(jsAst.prettyPrint(supportsDirectProtoAccess, compiler));
1172 output.add(N);
1173 }
1174
1144 void writeLibraryDescriptors(CodeOutput output, LibraryElement library) { 1175 void writeLibraryDescriptors(CodeOutput output, LibraryElement library) {
1145 var uri = ""; 1176 var uri = "";
1146 if (!compiler.enableMinification || backend.mustPreserveUris) { 1177 if (!compiler.enableMinification || backend.mustPreserveUris) {
1147 uri = library.canonicalUri; 1178 uri = library.canonicalUri;
1148 if (uri.scheme == 'file' && compiler.outputUri != null) { 1179 if (uri.scheme == 'file' && compiler.outputUri != null) {
1149 uri = relativize(compiler.outputUri, library.canonicalUri, false); 1180 uri = relativize(compiler.outputUri, library.canonicalUri, false);
1150 } 1181 }
1151 } 1182 }
1152 ClassBuilder descriptor = elementDescriptors[library]; 1183 ClassBuilder descriptor = elementDescriptors[library];
1153 if (descriptor == null) { 1184 if (descriptor == null) {
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
1363 /// The semicolon is important in minified mode, without it the 1394 /// The semicolon is important in minified mode, without it the
1364 /// following parenthesis looks like a call to the object literal. 1395 /// following parenthesis looks like a call to the object literal.
1365 mainOutput.add( 1396 mainOutput.add(
1366 'self.${deferredInitializers} = self.${deferredInitializers} || ' 1397 'self.${deferredInitializers} = self.${deferredInitializers} || '
1367 'Object.create(null);$n'); 1398 'Object.create(null);$n');
1368 } 1399 }
1369 1400
1370 // Using a named function here produces easier to read stack traces in 1401 // Using a named function here produces easier to read stack traces in
1371 // Chrome/V8. 1402 // Chrome/V8.
1372 mainOutput.add('(function(${namer.currentIsolate})$_{\n'); 1403 mainOutput.add('(function(${namer.currentIsolate})$_{\n');
1404 emitSupportsDirectProtoAccess(mainOutput);
1373 if (compiler.hasIncrementalSupport) { 1405 if (compiler.hasIncrementalSupport) {
1374 mainOutput.addBuffer(jsAst.prettyPrint(js.statement( 1406 mainOutput.addBuffer(jsAst.prettyPrint(js.statement(
1375 """ 1407 """
1376 { 1408 {
1377 #helper = #helper || Object.create(null); 1409 #helper = #helper || Object.create(null);
1378 #helper.patch = function(a) { eval(a)}; 1410 #helper.patch = function(a) { eval(a)};
1379 #helper.schemaChange = #schemaChange; 1411 #helper.schemaChange = #schemaChange;
1380 #helper.addMethod = #addMethod; 1412 #helper.addMethod = #addMethod;
1381 #helper.extractStubs = function(array, name, isStatic, originalDescriptor) { 1413 #helper.extractStubs = function(array, name, isStatic, originalDescriptor) {
1382 var descriptor = Object.create(null); 1414 var descriptor = Object.create(null);
(...skipping 651 matching lines...) Expand 10 before | Expand all | Expand 10 after
2034 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) { 2066 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) {
2035 if (element.isInstanceMember) { 2067 if (element.isInstanceMember) {
2036 cachedClassBuilders.remove(element.enclosingClass); 2068 cachedClassBuilders.remove(element.enclosingClass);
2037 2069
2038 nativeEmitter.cachedBuilders.remove(element.enclosingClass); 2070 nativeEmitter.cachedBuilders.remove(element.enclosingClass);
2039 2071
2040 } 2072 }
2041 } 2073 }
2042 } 2074 }
2043 } 2075 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/js_backend/namer.dart ('k') | pkg/compiler/lib/src/js_emitter/old_emitter/reflection_data_parser.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698