| 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 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 296 // Declare a function called "generateAccessor". This is used in | 296 // Declare a function called "generateAccessor". This is used in |
| 297 // defineClassFunction (it's a local declaration in init()). | 297 // defineClassFunction (it's a local declaration in init()). |
| 298 return [ | 298 return [ |
| 299 generateAccessorFunction, | 299 generateAccessorFunction, |
| 300 js('$generateAccessorHolder = generateAccessor'), | 300 js('$generateAccessorHolder = generateAccessor'), |
| 301 new jsAst.FunctionDeclaration( | 301 new jsAst.FunctionDeclaration( |
| 302 new jsAst.VariableDeclaration('defineClass'), defineClass) ]; | 302 new jsAst.VariableDeclaration('defineClass'), defineClass) ]; |
| 303 } | 303 } |
| 304 | 304 |
| 305 /** Needs defineClass to be defined. */ | 305 /** Needs defineClass to be defined. */ |
| 306 List buildInheritFrom() { | 306 jsAst.Expression buildInheritFrom() { |
| 307 return [js(r''' | 307 return js(r''' |
| 308 var inheritFrom = function() { | 308 var inheritFrom = function() { |
| 309 function tmp() {} | 309 function tmp() {} |
| 310 var hasOwnProperty = Object.prototype.hasOwnProperty; | 310 var hasOwnProperty = Object.prototype.hasOwnProperty; |
| 311 return function (constructor, superConstructor) { | 311 return function (constructor, superConstructor) { |
| 312 tmp.prototype = superConstructor.prototype; | 312 tmp.prototype = superConstructor.prototype; |
| 313 var object = new tmp(); | 313 var object = new tmp(); |
| 314 var properties = constructor.prototype; | 314 var properties = constructor.prototype; |
| 315 for (var member in properties) { | 315 for (var member in properties) { |
| 316 if (hasOwnProperty.call(properties, member)) { | 316 if (hasOwnProperty.call(properties, member)) { |
| 317 object[member] = properties[member]; | 317 object[member] = properties[member]; |
| 318 } | 318 } |
| 319 } | 319 } |
| 320 object.constructor = constructor; | 320 object.constructor = constructor; |
| 321 constructor.prototype = object; | 321 constructor.prototype = object; |
| 322 return object; | 322 return object; |
| 323 }; | 323 }; |
| 324 }() | 324 }() |
| 325 ''')]; | 325 '''); |
| 326 } |
| 327 |
| 328 /// Code that needs to be run before first invocation of |
| 329 /// [finishClassesFunction], but should only be run once. |
| 330 jsAst.Expression get initFinishClasses { |
| 331 jsAst.Expression allClassesAccess = |
| 332 generateEmbeddedGlobalAccess(embeddedNames.ALL_CLASSES); |
| 333 jsAst.Expression interceptorsByTagAccess = |
| 334 generateEmbeddedGlobalAccess(embeddedNames.INTERCEPTORS_BY_TAG); |
| 335 jsAst.Expression leafTagsAccess = |
| 336 generateEmbeddedGlobalAccess(embeddedNames.LEAF_TAGS); |
| 337 jsAst.Expression finishedClassesAccess = |
| 338 generateEmbeddedGlobalAccess(embeddedNames.FINISHED_CLASSES); |
| 339 |
| 340 return js(''' |
| 341 (function(){ |
| 342 # = Object.create(null); // embedded allClasses. |
| 343 # = Object.create(null); // embedded interceptorsByTag. |
| 344 # = Object.create(null); // embedded leafTags. |
| 345 # = Object.create(null); // embedded finishedClasses |
| 346 })() |
| 347 ''', [allClassesAccess, |
| 348 interceptorsByTagAccess, |
| 349 leafTagsAccess, |
| 350 finishedClassesAccess]); |
| 326 } | 351 } |
| 327 | 352 |
| 328 List buildSplitOffAliases() { | 353 List buildSplitOffAliases() { |
| 329 return [js(r''' | 354 return [js(r''' |
| 330 var splitOffAliases = function(constructor) { | 355 var splitOffAliases = function(constructor) { |
| 331 var hasOwnProperty = Object.prototype.hasOwnProperty; | 356 var hasOwnProperty = Object.prototype.hasOwnProperty; |
| 332 var properties = constructor.prototype; | 357 var properties = constructor.prototype; |
| 333 for (var member in properties) { | 358 for (var member in properties) { |
| 334 if (hasOwnProperty.call(properties, member)) { | 359 if (hasOwnProperty.call(properties, member)) { |
| 335 var s = member.split(':'); | 360 var s = member.split(':'); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 355 // constructor. | 380 // constructor. |
| 356 // For engines where we have access to the '__proto__' we can manipulate | 381 // For engines where we have access to the '__proto__' we can manipulate |
| 357 // the object literal directly. For other engines we have to create a new | 382 // the object literal directly. For other engines we have to create a new |
| 358 // object and copy over the members. | 383 // object and copy over the members. |
| 359 | 384 |
| 360 String reflectableField = namer.reflectableField; | 385 String reflectableField = namer.reflectableField; |
| 361 jsAst.Expression allClassesAccess = | 386 jsAst.Expression allClassesAccess = |
| 362 generateEmbeddedGlobalAccess(embeddedNames.ALL_CLASSES); | 387 generateEmbeddedGlobalAccess(embeddedNames.ALL_CLASSES); |
| 363 jsAst.Expression metadataAccess = | 388 jsAst.Expression metadataAccess = |
| 364 generateEmbeddedGlobalAccess(embeddedNames.METADATA); | 389 generateEmbeddedGlobalAccess(embeddedNames.METADATA); |
| 365 jsAst.Expression interceptorsByTagAccess = | 390 jsAst.Expression finishedClassesAccess = |
| 366 generateEmbeddedGlobalAccess(embeddedNames.INTERCEPTORS_BY_TAG); | 391 generateEmbeddedGlobalAccess(embeddedNames.FINISHED_CLASSES); |
| 367 jsAst.Expression leafTagsAccess = | |
| 368 generateEmbeddedGlobalAccess(embeddedNames.LEAF_TAGS); | |
| 369 | 392 |
| 370 return js(''' | 393 return js(''' |
| 371 function(collectedClasses, isolateProperties, existingIsolateProperties) { | 394 function(collectedClasses, isolateProperties, existingIsolateProperties) { |
| 372 var pendingClasses = Object.create(null); | 395 var pendingClasses = Object.create(null); |
| 373 if (!#) # = Object.create(null); // embedded allClasses. | |
| 374 var allClasses = #; // embedded allClasses; | 396 var allClasses = #; // embedded allClasses; |
| 397 var constructors; |
| 375 | 398 |
| 376 if (#) // DEBUG_FAST_OBJECTS | 399 if (#) // DEBUG_FAST_OBJECTS |
| 377 print("Number of classes: " + | 400 print("Number of classes: " + |
| 378 Object.getOwnPropertyNames(\$\$).length); | 401 Object.getOwnPropertyNames(\$\$).length); |
| 379 | 402 |
| 380 var hasOwnProperty = Object.prototype.hasOwnProperty; | 403 var hasOwnProperty = Object.prototype.hasOwnProperty; |
| 381 | 404 |
| 382 if (typeof dart_precompiled == "function") { | 405 if (typeof dart_precompiled == "function") { |
| 383 var constructors = dart_precompiled(collectedClasses); | 406 constructors = dart_precompiled(collectedClasses); |
| 384 } else { | 407 } else { |
| 385 var combinedConstructorFunction = | 408 var combinedConstructorFunction = |
| 386 "function \$reflectable(fn){fn.$reflectableField=1;return fn};\\n"+ | 409 "function \$reflectable(fn){fn.$reflectableField=1;return fn};\\n"+ |
| 387 "var \$desc;\\n"; | 410 "var \$desc;\\n"; |
| 388 var constructorsList = []; | 411 var constructorsList = []; |
| 389 } | 412 } |
| 390 | 413 |
| 391 for (var cls in collectedClasses) { | 414 for (var cls in collectedClasses) { |
| 392 var desc = collectedClasses[cls]; | 415 var desc = collectedClasses[cls]; |
| 393 if (desc instanceof Array) desc = desc[1]; | 416 if (desc instanceof Array) desc = desc[1]; |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 468 desc = desc[1]; | 491 desc = desc[1]; |
| 469 } | 492 } |
| 470 if (#) //backend.isTreeShakingDisabled, | 493 if (#) //backend.isTreeShakingDisabled, |
| 471 constructor["${namer.metadataField}"] = desc; | 494 constructor["${namer.metadataField}"] = desc; |
| 472 allClasses[cls] = constructor; | 495 allClasses[cls] = constructor; |
| 473 globalObject[cls] = constructor; | 496 globalObject[cls] = constructor; |
| 474 } | 497 } |
| 475 | 498 |
| 476 constructors = null; | 499 constructors = null; |
| 477 | 500 |
| 478 var finishedClasses = Object.create(null); | 501 var finishedClasses = #; // embedded finishedClasses |
| 479 # = Object.create(null); // embedded interceptorsByTag. | |
| 480 # = Object.create(null); // embedded leafTags. | |
| 481 | 502 |
| 482 #; // buildFinishClass(), | 503 #; // buildFinishClass(), |
| 483 | 504 |
| 484 #; // buildTrivialNsmHandlers() | 505 #; // buildTrivialNsmHandlers() |
| 485 | 506 |
| 486 for (var cls in pendingClasses) finishClass(cls); | 507 for (var cls in pendingClasses) finishClass(cls); |
| 487 }''', [ | 508 }''', [ |
| 488 allClassesAccess, allClassesAccess, | |
| 489 allClassesAccess, | 509 allClassesAccess, |
| 490 DEBUG_FAST_OBJECTS, | 510 DEBUG_FAST_OBJECTS, |
| 491 backend.hasRetainedMetadata, | 511 backend.hasRetainedMetadata, |
| 492 metadataAccess, | 512 metadataAccess, |
| 493 needsMixinSupport, | 513 needsMixinSupport, |
| 494 backend.isTreeShakingDisabled, | 514 backend.isTreeShakingDisabled, |
| 495 interceptorsByTagAccess, | 515 finishedClassesAccess, |
| 496 leafTagsAccess, | |
| 497 buildFinishClass(), | 516 buildFinishClass(), |
| 498 nsmEmitter.buildTrivialNsmHandlers()]); | 517 nsmEmitter.buildTrivialNsmHandlers()]); |
| 499 } | 518 } |
| 500 | 519 |
| 501 jsAst.Node optional(bool condition, jsAst.Node node) { | 520 jsAst.Node optional(bool condition, jsAst.Node node) { |
| 502 return condition ? node : new jsAst.EmptyStatement(); | 521 return condition ? node : new jsAst.EmptyStatement(); |
| 503 } | 522 } |
| 504 | 523 |
| 505 jsAst.FunctionDeclaration buildFinishClass() { | 524 jsAst.FunctionDeclaration buildFinishClass() { |
| 506 String specProperty = '"${namer.nativeSpecProperty}"'; // "%" | 525 String specProperty = '"${namer.nativeSpecProperty}"'; // "%" |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 688 } | 707 } |
| 689 } | 708 } |
| 690 ''', [laziesAccess, laziesAccess, | 709 ''', [laziesAccess, laziesAccess, |
| 691 laziesAccess, | 710 laziesAccess, |
| 692 cyclicThrow]); | 711 cyclicThrow]); |
| 693 } | 712 } |
| 694 | 713 |
| 695 List buildDefineClassAndFinishClassFunctionsIfNecessary() { | 714 List buildDefineClassAndFinishClassFunctionsIfNecessary() { |
| 696 if (!needsDefineClass) return []; | 715 if (!needsDefineClass) return []; |
| 697 return defineClassFunction | 716 return defineClassFunction |
| 698 ..addAll(buildInheritFrom()) | 717 ..add(buildInheritFrom()) |
| 699 ..addAll(buildSplitOffAliases()) | 718 ..addAll(buildSplitOffAliases()) |
| 700 ..addAll([ | 719 ..add(js('$finishClassesName = #', finishClassesFunction)) |
| 701 js('$finishClassesName = #', finishClassesFunction) | 720 ..add(initFinishClasses); |
| 702 ]); | |
| 703 } | 721 } |
| 704 | 722 |
| 705 List buildLazyInitializerFunctionIfNecessary() { | 723 List buildLazyInitializerFunctionIfNecessary() { |
| 706 if (!needsLazyInitializer) return []; | 724 if (!needsLazyInitializer) return []; |
| 707 | 725 |
| 708 return [js('# = #', [js(lazyInitializerName), lazyInitializerFunction])]; | 726 return [js('# = #', [js(lazyInitializerName), lazyInitializerFunction])]; |
| 709 } | 727 } |
| 710 | 728 |
| 711 List buildFinishIsolateConstructor() { | 729 List buildFinishIsolateConstructor() { |
| 712 return [ | 730 return [ |
| (...skipping 1301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2014 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) { | 2032 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) { |
| 2015 if (element.isInstanceMember) { | 2033 if (element.isInstanceMember) { |
| 2016 cachedClassBuilders.remove(element.enclosingClass); | 2034 cachedClassBuilders.remove(element.enclosingClass); |
| 2017 | 2035 |
| 2018 nativeEmitter.cachedBuilders.remove(element.enclosingClass); | 2036 nativeEmitter.cachedBuilders.remove(element.enclosingClass); |
| 2019 | 2037 |
| 2020 } | 2038 } |
| 2021 } | 2039 } |
| 2022 } | 2040 } |
| 2023 } | 2041 } |
| OLD | NEW |