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

Unified Diff: frog/leg/emitter.dart

Issue 9873021: Move frog/leg to lib/compiler/implementation. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « frog/leg/elements/elements.dart ('k') | frog/leg/enqueue.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: frog/leg/emitter.dart
===================================================================
--- frog/leg/emitter.dart (revision 5925)
+++ frog/leg/emitter.dart (working copy)
@@ -1,728 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/**
- * A function element that represents a closure call. The signature is copied
- * from the given element.
- */
-class ClosureInvocationElement extends FunctionElement {
- ClosureInvocationElement(SourceString name,
- FunctionElement other)
- : super.from(name, other, other.enclosingElement);
-
- isInstanceMember() => true;
-}
-
-/**
- * Generates the code for all used classes in the program. Static fields (even
- * in classes) are ignored, since they can be treated as non-class elements.
- *
- * The code for the containing (used) methods must exist in the [:universe:].
- */
-class CodeEmitterTask extends CompilerTask {
- static final String INHERIT_FUNCTION = '''
-function(child, parent) {
- if (child.prototype.__proto__) {
- child.prototype.__proto__ = parent.prototype;
- } else {
- function tmp() {};
- tmp.prototype = parent.prototype;
- child.prototype = new tmp();
- child.prototype.constructor = child;
- }
-}''';
-
- bool addedInheritFunction = false;
- final Namer namer;
- final NativeEmitter nativeEmitter;
- Set<ClassElement> generatedClasses;
- StringBuffer mainBuffer;
-
- CodeEmitterTask(Compiler compiler)
- : namer = compiler.namer,
- nativeEmitter = new NativeEmitter(compiler),
- generatedClasses = new Set<ClassElement>(),
- mainBuffer = new StringBuffer(),
- super(compiler);
-
- String get name() => 'CodeEmitter';
-
- String get inheritsName() => '${namer.ISOLATE}.\$inherits';
-
- String get objectClassName() {
- ClassElement objectClass =
- compiler.coreLibrary.find(const SourceString('Object'));
- return namer.isolatePropertyAccess(objectClass);
- }
-
- void addInheritFunctionIfNecessary() {
- if (addedInheritFunction) return;
- addedInheritFunction = true;
- mainBuffer.add('$inheritsName = ');
- mainBuffer.add(INHERIT_FUNCTION);
- mainBuffer.add(';\n');
- }
-
- void addParameterStub(FunctionElement member,
- String attachTo(String invocationName),
- StringBuffer buffer,
- Selector selector,
- bool isNative) {
- FunctionParameters parameters = member.computeParameters(compiler);
- int positionalArgumentCount = selector.positionalArgumentCount;
- if (positionalArgumentCount == parameters.parameterCount) {
- assert(selector.namedArgumentCount == 0);
- return;
- }
- ConstantHandler handler = compiler.constantHandler;
- List<SourceString> names = selector.getOrderedNamedArguments();
-
- String invocationName =
- namer.instanceMethodInvocationName(member.getLibrary(), member.name,
- selector);
- buffer.add('${attachTo(invocationName)} = function(');
-
- // The parameters that this stub takes.
- List<String> parametersBuffer = new List<String>(selector.argumentCount);
- // The arguments that will be passed to the real method.
- List<String> argumentsBuffer = new List<String>(parameters.parameterCount);
-
- // We fill the lists depending on the selector. For example,
- // take method foo:
- // foo(a, b, [c, d]);
- //
- // We may have multiple ways of calling foo:
- // (1) foo(1, 2, 3, 4)
- // (2) foo(1, 2);
- // (3) foo(1, 2, 3);
- // (4) foo(1, 2, c: 3);
- // (5) foo(1, 2, d: 4);
- // (6) foo(1, 2, c: 3, d: 4);
- // (7) foo(1, 2, d: 4, c: 3);
- //
- // What we generate at the call sites are:
- // (1) foo$4(1, 2, 3, 4)
- // (2) foo$2(1, 2);
- // (3) foo$3(1, 2, 3);
- // (4) foo$3$c(1, 2, 3);
- // (5) foo$3$d(1, 2, 4);
- // (6) foo$4$c$d(1, 2, 3, 4);
- // (7) foo$4$c$d(1, 2, 3, 4);
- //
- // The stubs we generate are (expressed in Dart):
- // (1) No stub generated, call is direct.
- // (2) foo$2(a, b) => foo$4(a, b, null, null)
- // (3) foo$3(a, b, c) => foo$4(a, b, c, null)
- // (4) foo$3$c(a, b, c) => foo$4(a, b, c, null);
- // (5) foo$3$d(a, b, d) => foo$4(a, b, null, d);
- // (6) foo$4$c$d(a, b, c, d) => foo$4(a, b, c, d);
- // (7) Same as (5).
- //
- // We need to generate a stub for (5) because the order of the
- // stub arguments and the real method may be different.
-
- int count = 0;
- int indexOfLastOptionalArgumentInParameters = positionalArgumentCount - 1;
- parameters.forEachParameter((Element element) {
- String jsName = JsNames.getValid(element.name.slowToString());
- if (count < positionalArgumentCount) {
- parametersBuffer[count] = jsName;
- argumentsBuffer[count] = jsName;
- } else {
- int index = names.indexOf(element.name);
- if (index != -1) {
- indexOfLastOptionalArgumentInParameters = count;
- // The order of the named arguments is not the same as the
- // one in the real method (which is in Dart source order).
- argumentsBuffer[count] = jsName;
- parametersBuffer[selector.positionalArgumentCount + index] = jsName;
- } else {
- Constant value = handler.initialVariableValues[element];
- if (value == null) {
- argumentsBuffer[count] = '(void 0)';
- } else {
- if (!value.isNull()) {
- // If the value is the null constant, we should not pass it
- // down to the native method.
- indexOfLastOptionalArgumentInParameters = count;
- }
- argumentsBuffer[count] =
- handler.writeJsCode(new StringBuffer(), value).toString();
- }
- }
- }
- count++;
- });
- String parametersString = Strings.join(parametersBuffer, ",");
- buffer.add('$parametersString) {\n');
-
- if (isNative) {
- nativeEmitter.emitParameterStub(
- member, invocationName, parametersString, argumentsBuffer,
- indexOfLastOptionalArgumentInParameters);
- } else {
- String arguments = Strings.join(argumentsBuffer, ",");
- buffer.add(' return this.${namer.getName(member)}($arguments)');
- }
- buffer.add('\n};\n');
- }
-
- void addParameterStubs(FunctionElement member,
- String attachTo(String invocationName),
- StringBuffer buffer,
- [bool isNative = false]) {
- Set<Selector> selectors = compiler.universe.invokedNames[member.name];
- if (selectors == null) return;
- FunctionParameters parameters = member.computeParameters(compiler);
- for (Selector selector in selectors) {
- if (!selector.applies(parameters)) continue;
- addParameterStub(member, attachTo, buffer, selector, isNative);
- }
- }
-
- void addInstanceMember(Element member,
- String attachTo(String name),
- StringBuffer buffer,
- [bool isNative = false]) {
- // TODO(floitsch): we don't need to deal with members of
- // uninstantiated classes, that have been overwritten by subclasses.
-
- if (member.kind === ElementKind.FUNCTION
- || member.kind === ElementKind.GENERATIVE_CONSTRUCTOR_BODY
- || member.kind === ElementKind.GETTER
- || member.kind === ElementKind.SETTER) {
- if (member.modifiers !== null && member.modifiers.isAbstract()) return;
- String codeBlock = compiler.universe.generatedCode[member];
- if (codeBlock == null) return;
- buffer.add('${attachTo(namer.getName(member))} = $codeBlock;\n');
- codeBlock = compiler.universe.generatedBailoutCode[member];
- if (codeBlock !== null) {
- String name = compiler.namer.getBailoutName(member);
- buffer.add('${attachTo(name)} = $codeBlock;\n');
- }
- FunctionElement function = member;
- FunctionParameters parameters = function.computeParameters(compiler);
- if (!parameters.optionalParameters.isEmpty()) {
- addParameterStubs(member, attachTo, buffer, isNative: isNative);
- }
- } else if (member.kind === ElementKind.FIELD) {
- // TODO(ngeoffray): Have another class generate the code for the
- // fields.
- if ((member.modifiers === null || !member.modifiers.isFinal()) &&
- compiler.universe.invokedSetters.contains(member.name)) {
- String setterName = namer.setterName(member.getLibrary(), member.name);
- String name =
- isNative ? member.name.slowToString() : namer.getName(member);
- buffer.add('${attachTo(setterName)} = function(v){\n');
- buffer.add(' this.$name = v;\n};\n');
- }
- if (compiler.universe.invokedGetters.contains(member.name)) {
- String getterName = namer.getterName(member.getLibrary(), member.name);
- String name =
- isNative ? member.name.slowToString() : namer.getName(member);
- buffer.add('${attachTo(getterName)} = function(){\n');
- buffer.add(' return this.$name;\n};\n');
- }
- } else {
- compiler.internalError('unexpected kind: "${member.kind}"',
- element: member);
- }
- emitExtraAccessors(member, attachTo, buffer);
- }
-
- bool generateFieldInits(ClassElement classElement,
- StringBuffer argumentsBuffer,
- StringBuffer bodyBuffer) {
- bool isFirst = true;
- do {
- // TODO(floitsch): make sure there are no name clashes.
- String className = namer.getName(classElement);
-
- void generateFieldInit(Element member) {
- if (member.isInstanceMember() && member.kind == ElementKind.FIELD) {
- if (!isFirst) argumentsBuffer.add(', ');
- isFirst = false;
- String memberName = namer.instanceFieldName(member.getLibrary(),
- member.name);
- argumentsBuffer.add('${className}_$memberName');
- bodyBuffer.add(' this.$memberName = ${className}_$memberName;\n');
- }
- }
-
- for (Element element in classElement.members) {
- generateFieldInit(element);
- }
- for (Element element in classElement.backendMembers) {
- generateFieldInit(element);
- }
-
- classElement = classElement.superclass;
- } while(classElement !== null);
- }
-
- void emitInherits(ClassElement cls, StringBuffer buffer) {
- ClassElement superclass = cls.superclass;
- if (superclass !== null) {
- addInheritFunctionIfNecessary();
- String className = namer.isolatePropertyAccess(cls);
- String superName = namer.isolatePropertyAccess(superclass);
- buffer.add('${inheritsName}($className, $superName);\n');
- }
- }
-
- void ensureGenerated(ClassElement classElement, StringBuffer buffer) {
- if (classElement == null) return;
- if (generatedClasses.contains(classElement)) return;
- generatedClasses.add(classElement);
- generateClass(classElement, buffer);
- }
-
- void generateClass(ClassElement classElement, StringBuffer buffer) {
- ensureGenerated(classElement.superclass, buffer);
-
- if (classElement.isNative()) {
- nativeEmitter.generateNativeClass(classElement);
- return;
- } else {
- // TODO(ngeoffray): Instead of switching between buffer, we
- // should create code sections, and decide where to emit them at
- // the end.
- buffer = mainBuffer;
- }
-
- String className = namer.isolatePropertyAccess(classElement);
- String constructorName = namer.safeName(classElement.name.slowToString());
- buffer.add('$className = function $constructorName(');
- StringBuffer bodyBuffer = new StringBuffer();
- // If the class is never instantiated we still need to set it up for
- // inheritance purposes, but we can leave its JavaScript constructor empty.
- if (compiler.universe.instantiatedClasses.contains(classElement)) {
- generateFieldInits(classElement, buffer, bodyBuffer);
- }
- buffer.add(') {\n');
- buffer.add(bodyBuffer);
- buffer.add('};\n');
-
- emitInherits(classElement, buffer);
-
- String attachTo(String name) => '$className.prototype.$name';
- for (Element member in classElement.members) {
- if (member.isInstanceMember()) {
- addInstanceMember(member, attachTo, buffer);
- }
- }
- for (Element member in classElement.backendMembers) {
- if (member.isInstanceMember()) {
- addInstanceMember(member, attachTo, buffer);
- }
- }
- generateTypeTests(classElement, (Element other) {
- buffer.add('${attachTo(namer.operatorIs(other))} = ');
- if (nativeEmitter.requiresNativeIsCheck(other)) {
- buffer.add('function() { return true; }');
- } else {
- buffer.add('true');
- }
- buffer.add(';\n');
- });
-
- if (classElement === compiler.objectClass && compiler.enabledNoSuchMethod) {
- // Emit the noSuchMethods on the Object prototype now, so that
- // the code in the dynamicMethod can find them. Note that the
- // code in dynamicMethod is invoked before analyzing the full JS
- // script.
- emitNoSuchMethodCalls(buffer);
- }
- }
-
- void generateTypeTests(ClassElement cls,
- void generateTypeTest(ClassElement element)) {
- if (compiler.universe.isChecks.contains(cls)) {
- generateTypeTest(cls);
- }
- generateInterfacesIsTests(cls, generateTypeTest, new Set<Element>());
- }
-
- void generateInterfacesIsTests(ClassElement cls,
- void generateTypeTest(ClassElement element),
- Set<Element> alreadyGenerated) {
- for (Type interfaceType in cls.interfaces) {
- Element element = interfaceType.element;
- if (!alreadyGenerated.contains(element) &&
- compiler.universe.isChecks.contains(element)) {
- alreadyGenerated.add(element);
- generateTypeTest(element);
- }
- generateInterfacesIsTests(element, generateTypeTest, alreadyGenerated);
- }
- }
-
- void emitClasses(StringBuffer buffer) {
- for (ClassElement element in compiler.universe.instantiatedClasses) {
- ensureGenerated(element, buffer);
- }
- }
-
- void emitStaticFunctionsWithNamer(StringBuffer buffer,
- Map<Element, String> generatedCode,
- String functionNamer(Element element)) {
- generatedCode.forEach((Element element, String codeBlock) {
- if (!element.isInstanceMember()) {
- buffer.add('${functionNamer(element)} = ');
- buffer.add(codeBlock);
- buffer.add(';\n\n');
- }
- });
- }
-
- void emitStaticFunctions(StringBuffer buffer) {
- emitStaticFunctionsWithNamer(buffer,
- compiler.universe.generatedCode,
- namer.isolatePropertyAccess);
- emitStaticFunctionsWithNamer(buffer,
- compiler.universe.generatedBailoutCode,
- namer.isolateBailoutPropertyAccess);
- }
-
- void emitStaticFunctionGetters(StringBuffer buffer) {
- Set<FunctionElement> functionsNeedingGetter =
- compiler.universe.staticFunctionsNeedingGetter;
- for (FunctionElement element in functionsNeedingGetter) {
- // The static function does not have the correct name. Since
- // [addParameterStubs] use the name to create its stubs we simply
- // create a fake element with the correct name.
- // Note: the callElement will not have any enclosingElement.
- FunctionElement callElement =
- new ClosureInvocationElement(Namer.CLOSURE_INVOCATION_NAME, element);
- String staticName = namer.isolatePropertyAccess(element);
- int parameterCount = element.parameterCount(compiler);
- String invocationName =
- namer.instanceMethodName(element.getLibrary(), callElement.name,
- parameterCount);
- buffer.add("$staticName.$invocationName = $staticName;\n");
- addParameterStubs(callElement, (name) => '$staticName.$name', buffer);
- }
- }
-
- void emitDynamicFunctionGetter(StringBuffer buffer,
- String attachTo(String invocationName),
- FunctionElement member) {
- // For every method that has the same name as a property-get we create a
- // getter that returns a bound closure. Say we have a class 'A' with method
- // 'foo' and somewhere in the code there is a dynamic property get of
- // 'foo'. Then we generate the following code (in pseudo Dart):
- //
- // class A {
- // foo(x, y, z) { ... } // Original function.
- // get foo() { return new BoundClosure499(this); }
- // }
- // class BoundClosure499 extends Closure {
- // var self;
- // BoundClosure499(this.self);
- // $call3(x, y, z) { return self.foo(x, y, z); }
- // }
-
- // TODO(floitsch): share the closure classes with other classes
- // if they share methods with the same signature.
-
- // The closure class.
- SourceString name = const SourceString("BoundClosure");
- ClassElement closureClassElement =
- new ClosureClassElement(compiler, member.getCompilationUnit());
- String isolateAccess = namer.isolatePropertyAccess(closureClassElement);
- ensureGenerated(closureClassElement.superclass, buffer);
-
- // Define the constructor with a name so that Object.toString can
- // find the class name of the closure class.
- buffer.add("$isolateAccess = function $name(self) ");
- buffer.add("{ this.self = self; };\n");
- emitInherits(closureClassElement, buffer);
-
- String prototype = "$isolateAccess.prototype";
-
- // Now add the methods on the closure class. The instance method does not
- // have the correct name. Since [addParameterStubs] use the name to create
- // its stubs we simply create a fake element with the correct name.
- // Note: the callElement will not have any enclosingElement.
- FunctionElement callElement =
- new ClosureInvocationElement(Namer.CLOSURE_INVOCATION_NAME, member);
-
- int parameterCount = member.parameterCount(compiler);
- String invocationName =
- namer.instanceMethodName(member.getLibrary(),
- callElement.name, parameterCount);
- String targetName = namer.instanceMethodName(member.getLibrary(),
- member.name, parameterCount);
- List<String> arguments = new List<String>(parameterCount);
- for (int i = 0; i < parameterCount; i++) {
- arguments[i] = "arg$i";
- }
- String joinedArgs = Strings.join(arguments, ", ");
- buffer.add("$prototype.$invocationName = function($joinedArgs) {\n");
- buffer.add(" return this.self.$targetName($joinedArgs);\n");
- buffer.add("};\n");
- addParameterStubs(callElement,
- (invocationName) => '$prototype.$invocationName',
- buffer);
-
- // And finally the getter.
- String getterName = namer.getterName(member.getLibrary(), member.name);
- String closureClass = namer.isolateAccess(closureClassElement);
- buffer.add("${attachTo(getterName)} = function() {\n");
- buffer.add(" return new $closureClass(this);\n");
- buffer.add("};\n");
- }
-
- void emitCallStubForGetter(StringBuffer buffer,
- String attachTo(String name),
- Element member,
- Set<Selector> selectors) {
- String getter;
- if (member.kind == ElementKind.GETTER) {
- getter = "this.${namer.getterName(member.getLibrary(), member.name)}()";
- } else {
- getter =
- "this.${namer.instanceFieldName(member.getLibrary(), member.name)}";
- }
- for (Selector selector in selectors) {
- String invocationName =
- namer.instanceMethodInvocationName(member.getLibrary(), member.name,
- selector);
- SourceString callName = Namer.CLOSURE_INVOCATION_NAME;
- String closureCallName =
- namer.instanceMethodInvocationName(member.getLibrary(), callName,
- selector);
- List<String> arguments = <String>[];
- for (int i = 0; i < selector.argumentCount; i++) {
- arguments.add("arg$i");
- }
- String joined = Strings.join(arguments, ", ");
- buffer.add("${attachTo(invocationName)} = function($joined) {\n");
- buffer.add(" return $getter.$closureCallName($joined);\n");
- buffer.add("};\n");
- }
- }
-
- void emitStaticNonFinalFieldInitializations(StringBuffer buffer) {
- // Adds initializations inside the Isolate constructor.
- // Example:
- // function Isolate() {
- // this.staticNonFinal = Isolate.prototype.someVal;
- // ...
- // }
- ConstantHandler handler = compiler.constantHandler;
- List<VariableElement> staticNonFinalFields =
- handler.getStaticNonFinalFieldsForEmission();
- if (!staticNonFinalFields.isEmpty()) buffer.add('\n');
- for (Element element in staticNonFinalFields) {
- buffer.add(' this.${namer.getName(element)} = ');
- compiler.withCurrentElement(element, () {
- handler.writeJsCodeForVariable(buffer, element);
- });
- buffer.add(';\n');
- }
- }
-
- void emitCompileTimeConstants(StringBuffer buffer) {
- ConstantHandler handler = compiler.constantHandler;
- List<Constant> constants = handler.getConstantsForEmission();
- String prototype = "${namer.ISOLATE}.prototype";
- bool addedMakeConstantList = false;
- for (Constant constant in constants) {
- if (!addedMakeConstantList && constant.isList()) {
- addedMakeConstantList = true;
- emitMakeConstantList(prototype, buffer);
- }
- String name = handler.getNameForConstant(constant);
- buffer.add('$prototype.$name = ');
- handler.writeJsCode(buffer, constant);
- buffer.add(';\n');
- }
- }
-
- void emitMakeConstantList(String prototype, StringBuffer buffer) {
- buffer.add(prototype);
- buffer.add(@'''.makeConstantList = function(list) {
- list.immutable$list = true;
- list.fixed$length = true;
- return list;
-};
-''');
- }
-
- void emitStaticFinalFieldInitializations(StringBuffer buffer) {
- ConstantHandler handler = compiler.constantHandler;
- List<VariableElement> staticFinalFields =
- handler.getStaticFinalFieldsForEmission();
- for (VariableElement element in staticFinalFields) {
- buffer.add('${namer.isolatePropertyAccess(element)} = ');
- compiler.withCurrentElement(element, () {
- handler.writeJsCodeForVariable(buffer, element);
- });
- buffer.add(';\n');
- }
- }
-
- void emitExtraAccessors(Element member,
- String attachTo(String name),
- StringBuffer buffer) {
- if (member.kind == ElementKind.GETTER || member.kind == ElementKind.FIELD) {
- Set<Selector> selectors = compiler.universe.invokedNames[member.name];
- if (selectors !== null && !selectors.isEmpty()) {
- compiler.emitter.emitCallStubForGetter(
- buffer, attachTo, member, selectors);
- }
- } else if (member.kind == ElementKind.FUNCTION) {
- if (compiler.universe.invokedGetters.contains(member.name)) {
- compiler.emitter.emitDynamicFunctionGetter(
- buffer, attachTo, member);
- }
- }
- }
-
- void emitNoSuchMethodCalls(StringBuffer buffer) {
- // Do not generate no such method calls if there is no class.
- if (compiler.universe.instantiatedClasses.isEmpty()) return;
-
- ClassElement objectClass =
- compiler.coreLibrary.find(const SourceString('Object'));
- String className = namer.isolatePropertyAccess(objectClass);
- String prototype = '$className.prototype';
- String noSuchMethodName =
- namer.instanceMethodName(null, Compiler.NO_SUCH_METHOD, 2);
- Collection<LibraryElement> libraries =
- compiler.universe.libraries.getValues();
-
- void generateMethod(String methodName, String jsName, Selector selector) {
- buffer.add('$prototype.$jsName = function');
- StringBuffer args = new StringBuffer();
- for (int i = 0; i < selector.argumentCount; i++) {
- if (i != 0) args.add(', ');
- args.add('arg$i');
- }
- // We need to check if the object has a noSuchMethod. If not, it
- // means the object is a native object, and we can just call our
- // generic noSuchMethod. Note that when calling this method, the
- // 'this' object is not a Dart object.
- buffer.add(' ($args) {\n');
- buffer.add(' return this.$noSuchMethodName\n');
- buffer.add(" ? this.$noSuchMethodName('$methodName', [$args])\n");
- buffer.add(" : $objectClassName.prototype.$noSuchMethodName.call(");
- buffer.add("this, '$methodName', [$args])\n");
- buffer.add('}\n');
- }
-
- compiler.universe.invokedNames.forEach((SourceString methodName,
- Set<Selector> selectors) {
- if (objectClass.lookupLocalMember(methodName) === null
- && methodName != Namer.OPERATOR_EQUALS) {
- for (Selector selector in selectors) {
- if (methodName.isPrivate()) {
- for (LibraryElement lib in libraries) {
- String jsName =
- namer.instanceMethodInvocationName(lib, methodName, selector);
- generateMethod(methodName.slowToString(), jsName, selector);
- }
- } else {
- String jsName =
- namer.instanceMethodInvocationName(null, methodName, selector);
- generateMethod(methodName.slowToString(), jsName, selector);
- }
- }
- }
- });
-
- compiler.universe.invokedGetters.forEach((SourceString getterName) {
- if (getterName.isPrivate()) {
- for (LibraryElement lib in libraries) {
- String jsName = namer.getterName(lib, getterName);
- generateMethod('get ${getterName.slowToString()}', jsName,
- Selector.GETTER);
- }
- } else {
- String jsName = namer.getterName(null, getterName);
- generateMethod('get ${getterName.slowToString()}', jsName,
- Selector.GETTER);
- }
- });
-
- compiler.universe.invokedSetters.forEach((SourceString setterName) {
- if (setterName.isPrivate()) {
- for (LibraryElement lib in libraries) {
- String jsName = namer.setterName(lib, setterName);
- generateMethod('set ${setterName.slowToString()}', jsName,
- Selector.SETTER);
- }
- } else {
- String jsName = namer.setterName(null, setterName);
- generateMethod('set ${setterName.slowToString()}', jsName,
- Selector.SETTER);
- }
- });
- }
-
- String buildIsolateSetup(Element appMain, Element isolateMain) {
- String mainAccess = "${namer.isolateAccess(appMain)}";
- String currentIsolate = "${namer.CURRENT_ISOLATE}";
- String mainEnsureGetter = '';
- // Since we pass the closurized version of the main method to
- // the isolate method, we must make sure that it exists.
- if (!compiler.universe.staticFunctionsNeedingGetter.contains(appMain)) {
- String invocationName =
- "${namer.closureInvocationName(Selector.INVOCATION_0)}";
- mainEnsureGetter = "$mainAccess.$invocationName = $mainAccess";
- }
-
- // TODO(ngeoffray): These globals are currently required by the isolate
- // library, but since leg already generates code on an Isolate object, they
- // are not really needed. We should remove them once Leg replaces Frog.
- return """
-var \$globalThis = $currentIsolate;
-var \$globalState;
-var \$globals;
-function \$static_init(){};
-
-function \$initGlobals(context) {
- context.isolateStatics = new ${namer.ISOLATE}();
-}
-function \$setGlobals(context) {
- $currentIsolate = context.isolateStatics;
- \$globalThis = $currentIsolate;
-}
-$mainEnsureGetter
-${namer.isolateAccess(isolateMain)}($mainAccess);""";
- }
-
- emitMain(StringBuffer buffer) {
- if (compiler.isMockCompilation) return;
- Element main = compiler.mainApp.find(Compiler.MAIN);
- if (compiler.isolateLibrary != null) {
- Element isolateMain =
- compiler.isolateLibrary.find(Compiler.START_ROOT_ISOLATE);
- buffer.add(buildIsolateSetup(main, isolateMain));
- } else {
- buffer.add('${namer.isolateAccess(main)}();\n');
- }
- }
-
- String assembleProgram() {
- measure(() {
- mainBuffer.add('function ${namer.ISOLATE}() {');
- emitStaticNonFinalFieldInitializations(mainBuffer);
- mainBuffer.add('}\n\n');
- emitClasses(mainBuffer);
- emitStaticFunctions(mainBuffer);
- emitStaticFunctionGetters(mainBuffer);
- emitCompileTimeConstants(mainBuffer);
- emitStaticFinalFieldInitializations(mainBuffer);
- nativeEmitter.emitDynamicDispatchMetadata();
- mainBuffer.add(
- 'var ${namer.CURRENT_ISOLATE} = new ${namer.ISOLATE}();\n');
- nativeEmitter.assembleCode(mainBuffer);
- emitMain(mainBuffer);
- compiler.assembledCode = mainBuffer.toString();
- });
- return compiler.assembledCode;
- }
-}
« no previous file with comments | « frog/leg/elements/elements.dart ('k') | frog/leg/enqueue.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698