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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/js_emitter/code_emitter_task.dart

Issue 238633007: Redo "Add more MiniJsParser functionality." (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 8 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 dart2js.js_emitter; 5 part of dart2js.js_emitter;
6 6
7 /** 7 /**
8 * Generates the code for all used classes in the program. Static fields (even 8 * Generates the code for all used classes in the program. Static fields (even
9 * in classes) are ignored, since they can be treated as non-class elements. 9 * in classes) are ignored, since they can be treated as non-class elements.
10 * 10 *
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after
263 // defineClassFunction (it's a local declaration in init()). 263 // defineClassFunction (it's a local declaration in init()).
264 return [ 264 return [
265 generateAccessorFunction, 265 generateAccessorFunction,
266 js('$generateAccessorHolder = generateAccessor'), 266 js('$generateAccessorHolder = generateAccessor'),
267 new jsAst.FunctionDeclaration( 267 new jsAst.FunctionDeclaration(
268 new jsAst.VariableDeclaration('defineClass'), defineClass) ]; 268 new jsAst.VariableDeclaration('defineClass'), defineClass) ];
269 } 269 }
270 270
271 /** Needs defineClass to be defined. */ 271 /** Needs defineClass to be defined. */
272 List buildInheritFrom() { 272 List buildInheritFrom() {
273 return [ 273 return [js(r'''
274 js('var inheritFrom = #', 274 var inheritFrom = function() {
275 js.fun([], [ 275 function tmp() {}
276 new jsAst.FunctionDeclaration( 276 var hasOwnProperty = Object.prototype.hasOwnProperty;
277 new jsAst.VariableDeclaration('tmp'), js.fun([], [])), 277 return function (constructor, superConstructor) {
278 js('var hasOwnProperty = Object.prototype.hasOwnProperty'), 278 tmp.prototype = superConstructor.prototype;
279 js.return_(js.fun(['constructor', 'superConstructor'], [ 279 var object = new tmp();
280 js('tmp.prototype = superConstructor.prototype'), 280 var properties = constructor.prototype;
281 js('var object = new tmp()'), 281 for (var member in properties)
282 js('var properties = constructor.prototype'), 282 if (hasOwnProperty.call(properties, member))
283 js.forIn('member', 'properties', 283 object[member] = properties[member];
284 js.if_('hasOwnProperty.call(properties, member)', 284 object.constructor = constructor;
285 js('object[member] = properties[member]'))), 285 constructor.prototype = object;
286 js('object.constructor = constructor'), 286 return object;
287 js('constructor.prototype = object'), 287 };
288 js.return_('object') 288 }()
289 ]))])())]; 289 ''')];
290 } 290 }
291 291
292 jsAst.Fun get finishClassesFunction { 292 jsAst.Fun get finishClassesFunction {
293 // Class descriptions are collected in a JS object. 293 // Class descriptions are collected in a JS object.
294 // 'finishClasses' takes all collected descriptions and sets up 294 // 'finishClasses' takes all collected descriptions and sets up
295 // the prototype. 295 // the prototype.
296 // Once set up, the constructors prototype field satisfy: 296 // Once set up, the constructors prototype field satisfy:
297 // - it contains all (local) members. 297 // - it contains all (local) members.
298 // - its internal prototype (__proto__) points to the superclass' 298 // - its internal prototype (__proto__) points to the superclass'
299 // prototype field. 299 // prototype field.
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
378 ]), 378 ]),
379 ])), 379 ])),
380 380
381 js.if_('typeof dart_precompiled != "function"', 381 js.if_('typeof dart_precompiled != "function"',
382 [js('combinedConstructorFunction +=' 382 [js('combinedConstructorFunction +='
383 ' defineClass(name, cls, fields)'), 383 ' defineClass(name, cls, fields)'),
384 js('constructorsList.push(cls)')]), 384 js('constructorsList.push(cls)')]),
385 js.if_('supr', js('pendingClasses[cls] = supr')) 385 js.if_('supr', js('pendingClasses[cls] = supr'))
386 ]) 386 ])
387 ]), 387 ]),
388 js.if_('typeof dart_precompiled != "function"', 388 js.statement('''
389 [js('combinedConstructorFunction +=' 389 if (typeof dart_precompiled != "function") {
390 ' "return [\\n " + constructorsList.join(",\\n ") + "\\n]"'), 390 combinedConstructorFunction +=
391 js('var constructors =' 391 "return [\\n " + constructorsList.join(",\\n ") + "\\n]";
392 ' new Function("\$collectedClasses", combinedConstructorFunction)' 392 var constructors =
393 '(collectedClasses)'), 393 new Function("\$collectedClasses", combinedConstructorFunction)
394 js('combinedConstructorFunction = null')]), 394 (collectedClasses);
395 combinedConstructorFunction = null;
396 }'''),
395 js.for_('var i = 0', 'i < constructors.length', 'i++', [ 397 js.for_('var i = 0', 'i < constructors.length', 'i++', [
396 js('var constructor = constructors[i]'), 398 js('var constructor = constructors[i]'),
397 js('var cls = constructor.name'), 399 js('var cls = constructor.name'),
398 js('var desc = collectedClasses[cls]'), 400 js('var desc = collectedClasses[cls]'),
399 js('var globalObject = isolateProperties'), 401 js('var globalObject = isolateProperties'),
400 js.if_('desc instanceof Array', [ 402 js.if_('desc instanceof Array', [
401 js('globalObject = desc[0] || isolateProperties'), 403 js('globalObject = desc[0] || isolateProperties'),
402 js('desc = desc[1]') 404 js('desc = desc[1]')
403 ]), 405 ]),
404 optional(backend.isTreeShakingDisabled, 406 optional(backend.isTreeShakingDisabled,
405 js('constructor["${namer.metadataField}"] = desc')), 407 js('constructor["${namer.metadataField}"] = desc')),
406 js('allClasses[cls] = constructor'), 408 js('allClasses[cls] = constructor'),
407 js('globalObject[cls] = constructor'), 409 js('globalObject[cls] = constructor'),
408 ]), 410 ]),
409 js('constructors = null'), 411 js('constructors = null'),
410 412
411 js('var finishedClasses = {}'), 413 js('var finishedClasses = {}'),
412 js('init.interceptorsByTag = Object.create(null)'), 414 js('init.interceptorsByTag = Object.create(null)'),
413 js('init.leafTags = {}'), 415 js('init.leafTags = {}'),
414 416
415 buildFinishClass(), 417 buildFinishClass(),
416 ]; 418 ];
417 419
418 nsmEmitter.addTrivialNsmHandlers(statements); 420 nsmEmitter.addTrivialNsmHandlers(statements);
419 421
420 statements.add( 422 statements.add(
421 js.forIn('cls', 'pendingClasses', js('finishClass(cls)')) 423 js.statement('for (var cls in pendingClasses) finishClass(cls);')
422 ); 424 );
425
423 // function(collectedClasses, 426 // function(collectedClasses,
424 // isolateProperties, 427 // isolateProperties,
425 // existingIsolateProperties) 428 // existingIsolateProperties)
426 return js.fun(['collectedClasses', 'isolateProperties', 429 return js.fun(['collectedClasses', 'isolateProperties',
427 'existingIsolateProperties'], statements); 430 'existingIsolateProperties'], statements);
428 } 431 }
429 432
430 jsAst.Node optional(bool condition, jsAst.Node node) { 433 jsAst.Node optional(bool condition, jsAst.Node node) {
431 return condition ? node : new jsAst.EmptyStatement(); 434 return condition ? node : new jsAst.EmptyStatement();
432 } 435 }
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
512 new jsAst.VariableDeclaration('finishClass'), 515 new jsAst.VariableDeclaration('finishClass'),
513 fun); 516 fun);
514 } 517 }
515 518
516 jsAst.Fun get finishIsolateConstructorFunction { 519 jsAst.Fun get finishIsolateConstructorFunction {
517 // We replace the old Isolate function with a new one that initializes 520 // We replace the old Isolate function with a new one that initializes
518 // all its fields with the initial (and often final) value of all globals. 521 // all its fields with the initial (and often final) value of all globals.
519 // 522 //
520 // We also copy over old values like the prototype, and the 523 // We also copy over old values like the prototype, and the
521 // isolateProperties themselves. 524 // isolateProperties themselves.
522 return js.fun('oldIsolate', [ 525 return js('''
523 js('var isolateProperties = oldIsolate.${namer.isolatePropertiesName}'), 526 function (oldIsolate) {
524 new jsAst.FunctionDeclaration( 527 var isolateProperties = oldIsolate.${namer.isolatePropertiesName};
525 new jsAst.VariableDeclaration('Isolate'), 528 function Isolate() {
526 js.fun([], [ 529 var hasOwnProperty = Object.prototype.hasOwnProperty;
527 js('var hasOwnProperty = Object.prototype.hasOwnProperty'), 530 for (var staticName in isolateProperties)
528 js.forIn('staticName', 'isolateProperties', 531 if (hasOwnProperty.call(isolateProperties, staticName))
529 js.if_('hasOwnProperty.call(isolateProperties, staticName)', 532 this[staticName] = isolateProperties[staticName];
530 js('this[staticName] = isolateProperties[staticName]'))), 533 // Use the newly created object as prototype. In Chrome,
531 // Use the newly created object as prototype. In Chrome, 534 // this creates a hidden class for the object and makes
532 // this creates a hidden class for the object and makes 535 // sure it is fast to access.
533 // sure it is fast to access. 536 function ForceEfficientMap() {}
534 new jsAst.FunctionDeclaration( 537 ForceEfficientMap.prototype = this;
535 new jsAst.VariableDeclaration('ForceEfficientMap'), 538 new ForceEfficientMap();
536 js.fun([], [])), 539 }
537 js('ForceEfficientMap.prototype = this'), 540 Isolate.prototype = oldIsolate.prototype;
538 js('new ForceEfficientMap()')])), 541 Isolate.prototype.constructor = Isolate;
539 js('Isolate.prototype = oldIsolate.prototype'), 542 Isolate.${namer.isolatePropertiesName} = isolateProperties;
540 js('Isolate.prototype.constructor = Isolate'), 543 #
541 js('Isolate.${namer.isolatePropertiesName} = isolateProperties'), 544 #
542 optional(needsDefineClass, 545 return Isolate;
543 js('Isolate.$finishClassesProperty =' 546 }''',
544 ' oldIsolate.$finishClassesProperty')), 547 [ optional(needsDefineClass,
545 optional(hasMakeConstantList, 548 js('Isolate.$finishClassesProperty ='
546 js('Isolate.makeConstantList = oldIsolate.makeConstantList')), 549 ' oldIsolate.$finishClassesProperty')),
547 js.return_('Isolate')]); 550 optional(hasMakeConstantList,
551 js('Isolate.makeConstantList = oldIsolate.makeConstantList'))
552 ]);
548 } 553 }
549 554
550 jsAst.Fun get lazyInitializerFunction { 555 jsAst.Fun get lazyInitializerFunction {
551 // function(prototype, staticName, fieldName, getterName, lazyValue) { 556 // function(prototype, staticName, fieldName, getterName, lazyValue) {
552 var parameters = <String>['prototype', 'staticName', 'fieldName', 557 var parameters = <String>['prototype', 'staticName', 'fieldName',
553 'getterName', 'lazyValue']; 558 'getterName', 'lazyValue'];
554 return js.fun(parameters, addLazyInitializerLogic()); 559 return js.fun(parameters, addLazyInitializerLogic());
555 } 560 }
556 561
557 List addLazyInitializerLogic() { 562 List addLazyInitializerLogic() {
(...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after
985 String mainAccess = "${namer.isolateStaticClosureAccess(appMain)}"; 990 String mainAccess = "${namer.isolateStaticClosureAccess(appMain)}";
986 // Since we pass the closurized version of the main method to 991 // Since we pass the closurized version of the main method to
987 // the isolate method, we must make sure that it exists. 992 // the isolate method, we must make sure that it exists.
988 return "(function(a){${namer.isolateAccess(isolateMain)}($mainAccess,a)})"; 993 return "(function(a){${namer.isolateAccess(isolateMain)}($mainAccess,a)})";
989 } 994 }
990 995
991 /** 996 /**
992 * Emits code that sets `init.isolateTag` to a unique string. 997 * Emits code that sets `init.isolateTag` to a unique string.
993 */ 998 */
994 jsAst.Expression generateIsolateAffinityTagInitialization() { 999 jsAst.Expression generateIsolateAffinityTagInitialization() {
995 return js('!#', js.fun([], [ 1000 return js('''
996 1001 !function() {
997 // On V8, the 'intern' function converts a string to a symbol, which 1002 // On V8, the 'intern' function converts a string to a symbol, which
998 // makes property access much faster. 1003 // makes property access much faster.
999 new jsAst.FunctionDeclaration(new jsAst.VariableDeclaration('intern'), 1004 function intern(s) {
1000 js.fun(['s'], [ 1005 var o = {};
1001 js('var o = {}'), 1006 o[s] = 1;
1002 js('o[s] = 1'), 1007 return Object.keys(convertToFastObject(o))[0];
1003 js.return_(js('Object.keys(convertToFastObject(o))[0]'))])), 1008 }
1004 1009
1005 1010 init.getIsolateTag = function(name) {
1006 js('init.getIsolateTag = #', 1011 return intern("___dart_" + name + init.isolateTag);
1007 js.fun(['name'], 1012 };
1008 js.return_('intern("___dart_" + name + init.isolateTag)'))),
1009 1013
1010 // To ensure that different programs loaded into the same context (page) 1014 // To ensure that different programs loaded into the same context (page)
1011 // use distinct dispatch properies, we place an object on `Object` to 1015 // use distinct dispatch properies, we place an object on `Object` to
1012 // contain the names already in use. 1016 // contain the names already in use.
1013 js('var tableProperty = "___dart_isolate_tags_"'), 1017 var tableProperty = "___dart_isolate_tags_";
1014 js('var usedProperties = Object[tableProperty] ||' 1018 var usedProperties = Object[tableProperty] ||
1015 '(Object[tableProperty] = Object.create(null))'), 1019 (Object[tableProperty] = Object.create(null));
1016 1020
1017 js('var rootProperty = "_${generateIsolateTagRoot()}"'), 1021 var rootProperty = "_${generateIsolateTagRoot()}";
1018 js.for_('var i = 0', null, 'i++', [ 1022 for (var i = 0; ; i++) {
1019 js('var property = intern(rootProperty + "_" + i + "_")'), 1023 var property = intern(rootProperty + "_" + i + "_");
1020 js.if_('!(property in usedProperties)', [ 1024 if (!(property in usedProperties)) {
1021 js('usedProperties[property] = 1'), 1025 usedProperties[property] = 1;
1022 js('init.isolateTag = property'), 1026 init.isolateTag = property;
1023 new jsAst.Break(null)])])]) 1027 break;
1024 ()); 1028 }
1025 1029 }
1030 }()
1031 ''');
1026 } 1032 }
1027 1033
1028 jsAst.Expression generateDispatchPropertyNameInitialization() { 1034 jsAst.Expression generateDispatchPropertyNameInitialization() {
1029 return js( 1035 return js(
1030 'init.dispatchPropertyName = init.getIsolateTag("dispatch_record")'); 1036 'init.dispatchPropertyName = init.getIsolateTag("dispatch_record")');
1031 } 1037 }
1032 1038
1033 String generateIsolateTagRoot() { 1039 String generateIsolateTagRoot() {
1034 // TODO(sra): MD5 of contributing source code or URIs? 1040 // TODO(sra): MD5 of contributing source code or URIs?
1035 return 'ZxYxX'; 1041 return 'ZxYxX';
(...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after
1399 var map = new jsAst.ObjectInitializer(properties); 1405 var map = new jsAst.ObjectInitializer(properties);
1400 mainBuffer.write( 1406 mainBuffer.write(
1401 jsAst.prettyPrint( 1407 jsAst.prettyPrint(
1402 js('init.mangledGlobalNames = #', map).toStatement(), 1408 js('init.mangledGlobalNames = #', map).toStatement(),
1403 compiler)); 1409 compiler));
1404 if (compiler.enableMinification) { 1410 if (compiler.enableMinification) {
1405 mainBuffer.write(';'); 1411 mainBuffer.write(';');
1406 } 1412 }
1407 } 1413 }
1408 mainBuffer 1414 mainBuffer
1409 ..write(getReflectionDataParser(classesCollector, backend)) 1415 ..write('(')
1416 ..write(
1417 jsAst.prettyPrint(
1418 getReflectionDataParser(classesCollector, backend),
1419 compiler))
1420 ..write(')')
1410 ..write('([$n'); 1421 ..write('([$n');
1411 1422
1412 List<Element> sortedElements = 1423 List<Element> sortedElements =
1413 Elements.sortedByPosition(elementDescriptors.keys); 1424 Elements.sortedByPosition(elementDescriptors.keys);
1414 1425
1415 Iterable<Element> pendingStatics = sortedElements.where((element) { 1426 Iterable<Element> pendingStatics = sortedElements.where((element) {
1416 return !element.isLibrary() && 1427 return !element.isLibrary() &&
1417 elementDescriptors[element].values.any((descriptor) => 1428 elementDescriptors[element].values.any((descriptor) =>
1418 descriptor != null); 1429 descriptor != null);
1419 }); 1430 });
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after
1657 ..write('var old${namer.currentIsolate}$_=' 1668 ..write('var old${namer.currentIsolate}$_='
1658 '$_${namer.currentIsolate}$N' 1669 '$_${namer.currentIsolate}$N'
1659 // TODO(ahe): This defines a lot of properties on the 1670 // TODO(ahe): This defines a lot of properties on the
1660 // Isolate.prototype object. We know this will turn it into a 1671 // Isolate.prototype object. We know this will turn it into a
1661 // slow object in V8, so instead we should do something similar 1672 // slow object in V8, so instead we should do something similar
1662 // to Isolate.$finishIsolateConstructor. 1673 // to Isolate.$finishIsolateConstructor.
1663 '${namer.currentIsolate}$_=' 1674 '${namer.currentIsolate}$_='
1664 '$_${namer.isolateName}.prototype$N$n' 1675 '$_${namer.isolateName}.prototype$N$n'
1665 // The classesCollector object ($$). 1676 // The classesCollector object ($$).
1666 '$classesCollector$_=$_{};$n') 1677 '$classesCollector$_=$_{};$n')
1667 ..write(getReflectionDataParser(classesCollector, backend)) 1678 ..write('(')
1679 ..write(
1680 jsAst.prettyPrint(
1681 getReflectionDataParser(classesCollector, backend),
1682 compiler))
1683 ..write(')')
1668 ..write('([$n') 1684 ..write('([$n')
1669 ..addBuffer(outputBuffer) 1685 ..addBuffer(outputBuffer)
1670 ..write('])$N'); 1686 ..write('])$N');
1671 1687
1672 if (outputClassLists.containsKey(outputUnit)) { 1688 if (outputClassLists.containsKey(outputUnit)) {
1673 buffer.write( 1689 buffer.write(
1674 '$finishClassesName($classesCollector,$_${namer.currentIsolate},' 1690 '$finishClassesName($classesCollector,$_${namer.currentIsolate},'
1675 '$_$isolatePropertiesName)$N'); 1691 '$_$isolatePropertiesName)$N');
1676 } 1692 }
1677 1693
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1713 String sourceMap = sourceMapBuilder.build(); 1729 String sourceMap = sourceMapBuilder.build();
1714 compiler.outputProvider(name, 'js.map') 1730 compiler.outputProvider(name, 'js.map')
1715 ..add(sourceMap) 1731 ..add(sourceMap)
1716 ..close(); 1732 ..close();
1717 } 1733 }
1718 1734
1719 void registerReadTypeVariable(TypeVariableElement element) { 1735 void registerReadTypeVariable(TypeVariableElement element) {
1720 readTypeVariables.add(element); 1736 readTypeVariables.add(element);
1721 } 1737 }
1722 } 1738 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698