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 /** | 5 /** |
| 6 * A function element that represents a closure call. The signature is copied | 6 * A function element that represents a closure call. The signature is copied |
| 7 * from the given element. | 7 * from the given element. |
| 8 */ | 8 */ |
| 9 class ClosureInvocationElement extends FunctionElement { | 9 class ClosureInvocationElement extends FunctionElement { |
| 10 ClosureInvocationElement(SourceString name, | 10 ClosureInvocationElement(SourceString name, |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 21 * The code for the containing (used) methods must exist in the [:universe:]. | 21 * The code for the containing (used) methods must exist in the [:universe:]. |
| 22 */ | 22 */ |
| 23 class CodeEmitterTask extends CompilerTask { | 23 class CodeEmitterTask extends CompilerTask { |
| 24 bool needsInheritFunction = false; | 24 bool needsInheritFunction = false; |
| 25 bool needsDefineClass = false; | 25 bool needsDefineClass = false; |
| 26 bool needsClosureClass = false; | 26 bool needsClosureClass = false; |
| 27 final Namer namer; | 27 final Namer namer; |
| 28 final NativeEmitter nativeEmitter; | 28 final NativeEmitter nativeEmitter; |
| 29 StringBuffer boundClosureBuffer; | 29 StringBuffer boundClosureBuffer; |
| 30 StringBuffer mainBuffer; | 30 StringBuffer mainBuffer; |
| 31 String isolatePrototype; | 31 /** Shorter access to [isolatePropertiesName]. Both here in the code, as |
| 32 well as in the generated code. */ | |
| 33 String isolateProperties; | |
| 32 | 34 |
| 33 CodeEmitterTask(Compiler compiler) | 35 CodeEmitterTask(Compiler compiler) |
| 34 : namer = compiler.namer, | 36 : namer = compiler.namer, |
| 35 nativeEmitter = new NativeEmitter(compiler), | 37 nativeEmitter = new NativeEmitter(compiler), |
| 36 boundClosureBuffer = new StringBuffer(), | 38 boundClosureBuffer = new StringBuffer(), |
| 37 mainBuffer = new StringBuffer(), | 39 mainBuffer = new StringBuffer(), |
| 38 super(compiler); | 40 super(compiler); |
| 39 | 41 |
| 40 String get name() => 'CodeEmitter'; | 42 String get name() => 'CodeEmitter'; |
| 41 | 43 |
| 42 String get defineClassName() => '${namer.ISOLATE}.\$defineClass'; | 44 String get defineClassName() |
| 43 String get finishClassesName() => '${namer.ISOLATE}.\$finishClasses'; | 45 => '${namer.ISOLATE}.\$defineClass'; |
| 46 String get finishClassesName() | |
| 47 => '${namer.ISOLATE}.\$finishClasses'; | |
| 48 String get finishIsolateConstructorName() | |
| 49 => '${namer.ISOLATE}.\$finishIsolateConstructor'; | |
| 50 String get pendingClassesName() | |
| 51 => '${namer.ISOLATE}.\$pendingClasses'; | |
| 52 String get isolatePropertiesName() | |
| 53 => '${namer.ISOLATE}.${namer.ISOLATE_PROPERTIES}'; | |
| 44 | 54 |
| 45 String buildDefineClassFunction(String isolate) { | 55 String get defineClassFunction() { |
| 46 // Example: | 56 // Example: |
| 47 // defineClass("A", "B", | 57 // defineClass("A", "B", |
| 48 // function(x) { /* The JavaScript constructor. */ | 58 // function(x) { /* The JavaScript constructor. */ |
| 49 // this.x = x; | 59 // this.x = x; |
| 50 // }, { /* The members inside an Object literal. */ | 60 // }, { /* The members inside an Object literal. */ |
| 51 // foo$1: function(y) { | 61 // foo$1: function(y) { |
| 52 // print(this.x + y); | 62 // print(this.x + y); |
| 53 // }, | 63 // }, |
| 54 // bar$2: function(t, v) { | 64 // bar$2: function(t, v) { |
| 55 // this.x = t - v; | 65 // this.x = t - v; |
| 56 // }, | 66 // }, |
| 57 // }); | 67 // }); |
| 58 return """ | 68 return """ |
| 59 function(cls, superclass, constructor, prototype) { | 69 function(cls, superclass, constructor, prototype) { |
| 60 $isolate.prototype[cls] = constructor; | 70 $isolatePropertiesName[cls] = constructor; |
| 61 constructor.prototype = prototype; | 71 constructor.prototype = prototype; |
| 62 if (superclass !== "") { | 72 if (superclass !== "") { |
| 63 $isolate.pendingClasses[cls] = superclass; | 73 $pendingClassesName[cls] = superclass; |
| 64 } | 74 } |
| 65 }"""; | 75 }"""; |
| 66 } | 76 } |
| 67 | 77 |
| 68 String buildFinishClassesFunction(String isolate) { | 78 String get finishClassesFunction() { |
| 69 // 'defineClass' does not require the classes to be constructed in order. | 79 // 'defineClass' does not require the classes to be constructed in order. |
| 70 // Classes are initially just stored in the 'pendingClasses' field. | 80 // Classes are initially just stored in the 'pendingClasses' field. |
| 71 // 'finishClasses' takes all pending classes and sets up the prototype. | 81 // 'finishClasses' takes all pending classes and sets up the prototype. |
| 72 // Once set up, the constructors prototype field satisfy: | 82 // Once set up, the constructors prototype field satisfy: |
| 73 // - it contains all (local) members. | 83 // - it contains all (local) members. |
| 74 // - its internal prototype (__proto__) points to the superclass' | 84 // - its internal prototype (__proto__) points to the superclass' |
| 75 // prototype field. | 85 // prototype field. |
| 76 // - the prototype's constructor field points to the JavaScript | 86 // - the prototype's constructor field points to the JavaScript |
| 77 // constructor. | 87 // constructor. |
| 78 // For engines where we have access to the '__proto__' we can manipulate | 88 // For engines where we have access to the '__proto__' we can manipulate |
| 79 // the object literal directly. For other engines we have to create a new | 89 // the object literal directly. For other engines we have to create a new |
| 80 // object and copy over the members. | 90 // object and copy over the members. |
| 81 return ''' | 91 return ''' |
| 82 function() { | 92 function() { |
| 83 var pendingClasses = $isolate.pendingClasses; | 93 var pendingClasses = $pendingClassesName; |
| 84 '''/* FinishClasses can be called multiple times. This means that we need to | 94 '''/* FinishClasses can be called multiple times. This means that we need to |
| 85 clear the pendingClasses property. */''' | 95 clear the pendingClasses property. */''' |
| 86 $isolate.pendingClasses = {}; | 96 $pendingClassesName = {}; |
| 87 var finishedClasses = {}; | 97 var finishedClasses = {}; |
| 88 function finishClass(cls) { | 98 function finishClass(cls) { |
| 89 if (finishedClasses[cls]) return; | 99 if (finishedClasses[cls]) return; |
| 90 finishedClasses[cls] = true; | 100 finishedClasses[cls] = true; |
| 91 var superclass = pendingClasses[cls]; | 101 var superclass = pendingClasses[cls]; |
| 92 '''/* The superclass is only false (empty string) for Dart's Object class. */''' | 102 '''/* The superclass is only false (empty string) for Dart's Object class. */''' |
| 93 if (!superclass) return; | 103 if (!superclass) return; |
| 94 finishClass(superclass); | 104 finishClass(superclass); |
| 95 var constructor = $isolate.prototype[cls]; | 105 var constructor = $isolatePropertiesName[cls]; |
| 96 var superConstructor = $isolate.prototype[superclass]; | 106 var superConstructor = $isolatePropertiesName[superclass]; |
| 97 var prototype = constructor.prototype; | 107 var prototype = constructor.prototype; |
| 98 if (prototype.__proto__) { | 108 if (prototype.__proto__) { |
| 99 '''/* On Firefox and Webkit browsers we can manipulate the __proto__ | 109 '''/* On Firefox and Webkit browsers we can manipulate the __proto__ |
| 100 directly. */''' | 110 directly. */''' |
| 101 prototype.__proto__ = superConstructor.prototype; | 111 prototype.__proto__ = superConstructor.prototype; |
| 102 prototype.constructor = constructor; | 112 prototype.constructor = constructor; |
| 103 } else { | 113 } else { |
| 104 '''/* On the remaining browsers we need to instantiate an object with the | 114 '''/* On the remaining browsers we need to instantiate an object with the |
| 105 correct (internal) prototype set up correctly, and then copy the | 115 correct (internal) prototype set up correctly, and then copy the |
| 106 members. */''' | 116 members. */''' |
| 107 function tmp() {}; | 117 function tmp() {}; |
| 108 tmp.prototype = superConstructor.prototype; | 118 tmp.prototype = superConstructor.prototype; |
| 109 var newPrototype = new tmp(); | 119 var newPrototype = new tmp(); |
| 110 constructor.prototype = newPrototype; | 120 constructor.prototype = newPrototype; |
| 111 newPrototype.constructor = constructor; | 121 newPrototype.constructor = constructor; |
| 112 '''/* Opera does not support 'getOwnPropertyNames'. Therefore we use | 122 '''/* Opera does not support 'getOwnPropertyNames'. Therefore we use |
| 113 hosOwnProperty instead. */''' | 123 hosOwnProperty instead. */''' |
| 114 var hasOwnProperty = Object.prototype.hasOwnProperty; | 124 var hasOwnProperty = Object.prototype.hasOwnProperty; |
| 115 for (var member in prototype) { | 125 for (var member in prototype) { |
| 116 if (hasOwnProperty.call(prototype, member)) { | 126 if (hasOwnProperty.call(prototype, member)) { |
| 117 newPrototype[member] = prototype[member]; | 127 newPrototype[member] = prototype[member]; |
| 118 } | 128 } |
| 119 } | 129 } |
| 120 } | 130 } |
| 121 } | 131 } |
| 122 for (var cls in pendingClasses) finishClass(cls); | 132 for (var cls in pendingClasses) finishClass(cls); |
| 123 }; | 133 }'''; |
| 124 '''; | 134 } |
| 135 | |
| 136 String get finishIsolateConstructorFunction() { | |
| 137 String isolate = namer.ISOLATE; | |
| 138 // We replace the old Isolate function with a new one that initializes | |
| 139 // all its field with the initial (and often final) value of all globals. | |
| 140 // This has two advantages: | |
| 141 // 1. the properties are in the object itself (thus avoiding to go through | |
| 142 // the prototype when looking up globals. | |
| 143 // 2. a new isolate goes through a (usually well optimized) constructor | |
| 144 // function of the form: "function() { this.x = ...; this.y = ...; }". | |
| 145 // | |
| 146 // Example: If [isolateProperties] is an object containing: x = 3 and | |
| 147 // A = function A() { /* constructor of class A. */ }, then we generate: | |
| 148 // str = "{ | |
| 149 // var isolateProperties = Isolate.$isolateProperties; | |
| 150 // this.x = isolateProperties.x; | |
| 151 // this.A = isolateProperties.A; | |
| 152 // }"; | |
| 153 // which is then dynamically evaluated: | |
| 154 // var newIsolate = new Function(str); | |
| 155 // | |
| 156 // We also copy over old values like the prototype, and the | |
| 157 // isolateProperties themselves. | |
| 158 return """function(oldIsolate) { | |
| 159 var isolateProperties = oldIsolate.${namer.ISOLATE_PROPERTIES}; | |
| 160 var isolatePrototype = oldIsolate.prototype; | |
| 161 var str = "{\\n"; | |
| 162 str += "var isolateProperties = $isolate.${namer.ISOLATE_PROPERTIES};\\n"; | |
| 163 for (var staticName in isolateProperties) { | |
| 164 if (Object.prototype.hasOwnProperty.call(isolateProperties, staticName)) { | |
| 165 str += "this." + staticName + "= isolateProperties." + staticName + ";\\n" ; | |
|
ngeoffray
2012/05/07 09:48:45
line too long
floitsch
2012/05/07 14:09:11
done in CL 10388006.
| |
| 166 } | |
| 167 } | |
| 168 str += "}\\n"; | |
| 169 var newIsolate = new Function(str); | |
| 170 newIsolate.prototype = isolatePrototype; | |
| 171 isolatePrototype.constructor = newIsolate; | |
| 172 newIsolate.${namer.ISOLATE_PROPERTIES} = isolateProperties; | |
| 173 return newIsolate; | |
| 174 }"""; | |
| 125 } | 175 } |
| 126 | 176 |
| 127 void addDefineClassAndFinishClassFunctionsIfNecessary(StringBuffer buffer) { | 177 void addDefineClassAndFinishClassFunctionsIfNecessary(StringBuffer buffer) { |
| 128 String isolate = namer.ISOLATE; | 178 String isolate = namer.ISOLATE; |
| 129 buffer.add("$defineClassName = ${buildDefineClassFunction(isolate)};\n"); | 179 buffer.add("$defineClassName = $defineClassFunction;\n"); |
| 130 buffer.add("$isolate.pendingClasses = {};\n"); | 180 buffer.add("$pendingClassesName = {};\n"); |
| 131 buffer.add("$finishClassesName = ${buildFinishClassesFunction(isolate)};"); | 181 buffer.add("$finishClassesName = $finishClassesFunction;\n"); |
| 132 buffer.add("\n"); | 182 } |
| 183 | |
| 184 void emitFinishIsolateConstructor(StringBuffer buffer) { | |
| 185 String name = finishIsolateConstructorName; | |
| 186 String value = finishIsolateConstructorFunction; | |
| 187 buffer.add("$name = $value;\n"); | |
| 188 } | |
| 189 | |
| 190 void emitFinishIsolateConstructorInvocation(StringBuffer buffer) { | |
| 191 String isolate = namer.ISOLATE; | |
| 192 buffer.add("$isolate = $finishIsolateConstructorName($isolate);\n"); | |
| 133 } | 193 } |
| 134 | 194 |
| 135 void addParameterStub(FunctionElement member, | 195 void addParameterStub(FunctionElement member, |
| 136 Selector selector, | 196 Selector selector, |
| 137 void defineInstanceMember(String invocationName, | 197 void defineInstanceMember(String invocationName, |
| 138 String definition)) { | 198 String definition)) { |
| 139 FunctionParameters parameters = member.computeParameters(compiler); | 199 FunctionParameters parameters = member.computeParameters(compiler); |
| 140 int positionalArgumentCount = selector.positionalArgumentCount; | 200 int positionalArgumentCount = selector.positionalArgumentCount; |
| 141 if (positionalArgumentCount == parameters.parameterCount) { | 201 if (positionalArgumentCount == parameters.parameterCount) { |
| 142 assert(selector.namedArgumentCount == 0); | 202 assert(selector.namedArgumentCount == 0); |
| (...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 436 | 496 |
| 437 void emitFinishClassesInvocationIfNecessary(StringBuffer buffer) { | 497 void emitFinishClassesInvocationIfNecessary(StringBuffer buffer) { |
| 438 if (needsDefineClass) buffer.add("$finishClassesName();\n"); | 498 if (needsDefineClass) buffer.add("$finishClassesName();\n"); |
| 439 } | 499 } |
| 440 | 500 |
| 441 void emitStaticFunctionsWithNamer(StringBuffer buffer, | 501 void emitStaticFunctionsWithNamer(StringBuffer buffer, |
| 442 Map<Element, String> generatedCode, | 502 Map<Element, String> generatedCode, |
| 443 String functionNamer(Element element)) { | 503 String functionNamer(Element element)) { |
| 444 generatedCode.forEach((Element element, String codeBlock) { | 504 generatedCode.forEach((Element element, String codeBlock) { |
| 445 if (!element.isInstanceMember()) { | 505 if (!element.isInstanceMember()) { |
| 446 buffer.add(isolatePrototype); | 506 String functionName = functionNamer(element); |
| 447 buffer.add('.${functionNamer(element)} = '); | 507 buffer.add('$isolateProperties.$functionName = $codeBlock;\n\n'); |
| 448 buffer.add(codeBlock); | |
| 449 buffer.add(';\n\n'); | |
| 450 } | 508 } |
| 451 }); | 509 }); |
| 452 } | 510 } |
| 453 | 511 |
| 454 void emitStaticFunctions(StringBuffer buffer) { | 512 void emitStaticFunctions(StringBuffer buffer) { |
| 455 emitStaticFunctionsWithNamer(buffer, | 513 emitStaticFunctionsWithNamer(buffer, |
| 456 compiler.universe.generatedCode, | 514 compiler.universe.generatedCode, |
| 457 namer.getName); | 515 namer.getName); |
| 458 emitStaticFunctionsWithNamer(buffer, | 516 emitStaticFunctionsWithNamer(buffer, |
| 459 compiler.universe.generatedBailoutCode, | 517 compiler.universe.generatedBailoutCode, |
| 460 namer.getBailoutName); | 518 namer.getBailoutName); |
| 461 } | 519 } |
| 462 | 520 |
| 463 void emitStaticFunctionGetters(StringBuffer buffer) { | 521 void emitStaticFunctionGetters(StringBuffer buffer) { |
| 464 Set<FunctionElement> functionsNeedingGetter = | 522 Set<FunctionElement> functionsNeedingGetter = |
| 465 compiler.universe.staticFunctionsNeedingGetter; | 523 compiler.universe.staticFunctionsNeedingGetter; |
| 466 for (FunctionElement element in functionsNeedingGetter) { | 524 for (FunctionElement element in functionsNeedingGetter) { |
| 467 // The static function does not have the correct name. Since | 525 // The static function does not have the correct name. Since |
| 468 // [addParameterStubs] use the name to create its stubs we simply | 526 // [addParameterStubs] use the name to create its stubs we simply |
| 469 // create a fake element with the correct name. | 527 // create a fake element with the correct name. |
| 470 // Note: the callElement will not have any enclosingElement. | 528 // Note: the callElement will not have any enclosingElement. |
| 471 FunctionElement callElement = | 529 FunctionElement callElement = |
| 472 new ClosureInvocationElement(Namer.CLOSURE_INVOCATION_NAME, element); | 530 new ClosureInvocationElement(Namer.CLOSURE_INVOCATION_NAME, element); |
| 473 String staticName = namer.getName(element); | 531 String staticName = namer.getName(element); |
| 474 int parameterCount = element.parameterCount(compiler); | 532 int parameterCount = element.parameterCount(compiler); |
| 475 String invocationName = | 533 String invocationName = |
| 476 namer.instanceMethodName(element.getLibrary(), callElement.name, | 534 namer.instanceMethodName(element.getLibrary(), callElement.name, |
| 477 parameterCount); | 535 parameterCount); |
| 478 buffer.add(isolatePrototype); | 536 String fieldAccess = '$isolateProperties.$staticName'; |
| 479 buffer.add(".$staticName.$invocationName = "); | 537 buffer.add("$fieldAccess.$invocationName = $fieldAccess;\n"); |
| 480 buffer.add(isolatePrototype); | |
| 481 buffer.add(".$staticName;\n"); | |
| 482 addParameterStubs(callElement, (String name, String value) { | 538 addParameterStubs(callElement, (String name, String value) { |
| 483 buffer.add('$isolatePrototype.$staticName.$name = $value;\n'); | 539 buffer.add('$fieldAccess.$name = $value;\n'); |
| 484 }); | 540 }); |
| 485 } | 541 } |
| 486 } | 542 } |
| 487 | 543 |
| 488 void emitDynamicFunctionGetter(FunctionElement member, | 544 void emitDynamicFunctionGetter(FunctionElement member, |
| 489 defineInstanceMember(String invocationName, | 545 defineInstanceMember(String invocationName, |
| 490 String definition)) { | 546 String definition)) { |
| 491 // For every method that has the same name as a property-get we create a | 547 // For every method that has the same name as a property-get we create a |
| 492 // getter that returns a bound closure. Say we have a class 'A' with method | 548 // getter that returns a bound closure. Say we have a class 'A' with method |
| 493 // 'foo' and somewhere in the code there is a dynamic property get of | 549 // 'foo' and somewhere in the code there is a dynamic property get of |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 579 } | 635 } |
| 580 String joined = Strings.join(arguments, ", "); | 636 String joined = Strings.join(arguments, ", "); |
| 581 defineInstanceMember( | 637 defineInstanceMember( |
| 582 invocationName, | 638 invocationName, |
| 583 "function($joined) { return $getter.$closureCallName($joined); }"); | 639 "function($joined) { return $getter.$closureCallName($joined); }"); |
| 584 } | 640 } |
| 585 } | 641 } |
| 586 } | 642 } |
| 587 | 643 |
| 588 void emitStaticNonFinalFieldInitializations(StringBuffer buffer) { | 644 void emitStaticNonFinalFieldInitializations(StringBuffer buffer) { |
| 589 // Adds initializations inside the Isolate constructor. | |
| 590 // Example: | |
| 591 // function Isolate() { | |
| 592 // this.staticNonFinal = Isolate.prototype.someVal; | |
| 593 // ... | |
| 594 // } | |
| 595 ConstantHandler handler = compiler.constantHandler; | 645 ConstantHandler handler = compiler.constantHandler; |
| 596 List<VariableElement> staticNonFinalFields = | 646 List<VariableElement> staticNonFinalFields = |
| 597 handler.getStaticNonFinalFieldsForEmission(); | 647 handler.getStaticNonFinalFieldsForEmission(); |
| 598 if (!staticNonFinalFields.isEmpty()) buffer.add('\n'); | |
| 599 for (Element element in staticNonFinalFields) { | 648 for (Element element in staticNonFinalFields) { |
| 600 buffer.add(' this.${namer.getName(element)} = '); | 649 buffer.add('$isolateProperties.${namer.getName(element)} = '); |
| 601 compiler.withCurrentElement(element, () { | 650 compiler.withCurrentElement(element, () { |
| 602 handler.writeJsCodeForVariable(buffer, element); | 651 handler.writeJsCodeForVariable(buffer, element); |
| 603 }); | 652 }); |
| 604 buffer.add(';\n'); | 653 buffer.add(';\n'); |
| 605 } | 654 } |
| 606 } | 655 } |
| 607 | 656 |
| 608 void emitCompileTimeConstants(StringBuffer buffer) { | 657 void emitCompileTimeConstants(StringBuffer buffer) { |
| 609 ConstantHandler handler = compiler.constantHandler; | 658 ConstantHandler handler = compiler.constantHandler; |
| 610 List<Constant> constants = handler.getConstantsForEmission(); | 659 List<Constant> constants = handler.getConstantsForEmission(); |
| 611 bool addedMakeConstantList = false; | 660 bool addedMakeConstantList = false; |
| 612 for (Constant constant in constants) { | 661 for (Constant constant in constants) { |
| 613 String name = handler.getNameForConstant(constant); | 662 String name = handler.getNameForConstant(constant); |
| 614 // The name is null when the constant is already a JS constant. | 663 // The name is null when the constant is already a JS constant. |
| 615 // TODO(floitsch): every constant should be registered, so that we can | 664 // TODO(floitsch): every constant should be registered, so that we can |
| 616 // share the ones that take up too much space (like some strings). | 665 // share the ones that take up too much space (like some strings). |
| 617 if (name === null) continue; | 666 if (name === null) continue; |
| 618 if (!addedMakeConstantList && constant.isList()) { | 667 if (!addedMakeConstantList && constant.isList()) { |
| 619 addedMakeConstantList = true; | 668 addedMakeConstantList = true; |
| 620 emitMakeConstantList(buffer); | 669 emitMakeConstantList(buffer); |
| 621 } | 670 } |
| 622 buffer.add('$isolatePrototype.$name = '); | 671 buffer.add('$isolateProperties.$name = '); |
| 623 handler.writeJsCode(buffer, constant); | 672 handler.writeJsCode(buffer, constant); |
| 624 buffer.add(';\n'); | 673 buffer.add(';\n'); |
| 625 } | 674 } |
| 626 } | 675 } |
| 627 | 676 |
| 628 void emitMakeConstantList(StringBuffer buffer) { | 677 void emitMakeConstantList(StringBuffer buffer) { |
| 629 buffer.add(isolatePrototype); | 678 buffer.add(namer.ISOLATE); |
| 630 buffer.add(@'''.makeConstantList = function(list) { | 679 buffer.add(@'''.makeConstantList = function(list) { |
| 631 list.immutable$list = true; | 680 list.immutable$list = true; |
| 632 list.fixed$length = true; | 681 list.fixed$length = true; |
| 633 return list; | 682 return list; |
| 634 }; | 683 }; |
| 635 '''); | 684 '''); |
| 636 } | 685 } |
| 637 | 686 |
| 638 void emitExtraAccessors(Element member, | 687 void emitExtraAccessors(Element member, |
| 639 void defineInstanceMember(String invocationName, | 688 void defineInstanceMember(String invocationName, |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 801 ${mainCall}; | 850 ${mainCall}; |
| 802 }); | 851 }); |
| 803 } else { | 852 } else { |
| 804 ${mainCall}; | 853 ${mainCall}; |
| 805 } | 854 } |
| 806 """); | 855 """); |
| 807 } | 856 } |
| 808 | 857 |
| 809 String assembleProgram() { | 858 String assembleProgram() { |
| 810 measure(() { | 859 measure(() { |
| 811 mainBuffer.add('function ${namer.ISOLATE}() {'); | 860 mainBuffer.add('function ${namer.ISOLATE}() {}\n'); |
| 812 emitStaticNonFinalFieldInitializations(mainBuffer); | |
| 813 mainBuffer.add('}\n'); | |
| 814 mainBuffer.add('init();\n\n'); | 861 mainBuffer.add('init();\n\n'); |
| 815 // Shorten the code by using [namer.CURRENT_ISOLATE] as temporary. | 862 // Shorten the code by using [namer.CURRENT_ISOLATE] as temporary. |
| 816 isolatePrototype = namer.CURRENT_ISOLATE; | 863 isolateProperties = namer.CURRENT_ISOLATE; |
| 817 mainBuffer.add('var $isolatePrototype = ${namer.ISOLATE}.prototype;\n'); | 864 mainBuffer.add('var $isolateProperties = $isolatePropertiesName;\n'); |
| 818 emitClasses(mainBuffer); | 865 emitClasses(mainBuffer); |
| 819 mainBuffer.add(boundClosureBuffer); | 866 mainBuffer.add(boundClosureBuffer); |
| 820 // Clear the buffer, so that we can reuse it for the native classes. | 867 // Clear the buffer, so that we can reuse it for the native classes. |
| 821 boundClosureBuffer.clear(); | 868 boundClosureBuffer.clear(); |
| 822 emitStaticFunctions(mainBuffer); | 869 emitStaticFunctions(mainBuffer); |
| 823 emitStaticFunctionGetters(mainBuffer); | 870 emitStaticFunctionGetters(mainBuffer); |
| 824 // We need to finish the classes before we construct compile time | 871 // We need to finish the classes before we construct compile time |
| 825 // constants. | 872 // constants. |
| 826 emitFinishClassesInvocationIfNecessary(mainBuffer); | 873 emitFinishClassesInvocationIfNecessary(mainBuffer); |
| 827 emitCompileTimeConstants(mainBuffer); | 874 emitCompileTimeConstants(mainBuffer); |
| 875 // Static field initializations require the classes and compile-time | |
| 876 // constants to be set up. | |
| 877 emitStaticNonFinalFieldInitializations(mainBuffer); | |
| 828 | 878 |
| 829 isolatePrototype = '${namer.ISOLATE}.prototype;\n'; | 879 isolateProperties = isolatePropertiesName; |
| 830 mainBuffer.add( | 880 // The following code should not use the short-hand for the |
| 831 'var ${namer.CURRENT_ISOLATE} = new ${namer.ISOLATE}();\n'); | 881 // initialStatics. |
| 882 mainBuffer.add('var ${namer.CURRENT_ISOLATE} = null;\n'); | |
| 832 nativeEmitter.emitDynamicDispatchMetadata(); | 883 nativeEmitter.emitDynamicDispatchMetadata(); |
| 833 nativeEmitter.assembleCode(mainBuffer); | |
| 834 mainBuffer.add(boundClosureBuffer); | 884 mainBuffer.add(boundClosureBuffer); |
| 835 emitFinishClassesInvocationIfNecessary(mainBuffer); | 885 emitFinishClassesInvocationIfNecessary(mainBuffer); |
| 886 | |
| 887 emitFinishIsolateConstructorInvocation(mainBuffer); | |
| 888 mainBuffer.add( | |
| 889 'var ${namer.CURRENT_ISOLATE} = new ${namer.ISOLATE}();\n'); | |
| 890 | |
| 891 nativeEmitter.assembleCode(mainBuffer); | |
| 836 emitMain(mainBuffer); | 892 emitMain(mainBuffer); |
| 837 mainBuffer.add('function init() {\n'); | 893 mainBuffer.add('function init() {\n'); |
| 894 mainBuffer.add(' $isolateProperties = {};\n'); | |
| 838 addDefineClassAndFinishClassFunctionsIfNecessary(mainBuffer); | 895 addDefineClassAndFinishClassFunctionsIfNecessary(mainBuffer); |
| 896 emitFinishIsolateConstructor(mainBuffer); | |
| 839 mainBuffer.add('}\n'); | 897 mainBuffer.add('}\n'); |
| 840 compiler.assembledCode = mainBuffer.toString(); | 898 compiler.assembledCode = mainBuffer.toString(); |
| 841 }); | 899 }); |
| 842 return compiler.assembledCode; | 900 return compiler.assembledCode; |
| 843 } | 901 } |
| 844 } | 902 } |
| OLD | NEW |