| Index: lib/compiler/implementation/js_backend/emitter_no_eval.dart
|
| diff --git a/lib/compiler/implementation/js_backend/emitter_no_eval.dart b/lib/compiler/implementation/js_backend/emitter_no_eval.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..f658c936bc21253742aa041d4ca1c1ab3ce167bd
|
| --- /dev/null
|
| +++ b/lib/compiler/implementation/js_backend/emitter_no_eval.dart
|
| @@ -0,0 +1,142 @@
|
| +// 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.
|
| +
|
| +class CodeEmitterNoEvalTask extends CodeEmitterTask {
|
| + CodeEmitterNoEvalTask(Compiler compiler,
|
| + Namer namer,
|
| + bool generateSourceMap)
|
| + : super(compiler, namer, generateSourceMap);
|
| +
|
| + String get generateGetterSetterFunction {
|
| + return """
|
| +function() {
|
| + throw 'Internal Error: no dynamic generation of getters and setters allowed';
|
| +}""";
|
| + }
|
| +
|
| + String get defineClassFunction {
|
| + return """
|
| +function(cls, constructor, prototype) {
|
| + constructor.prototype = prototype;
|
| + return constructor;
|
| +}""";
|
| + }
|
| +
|
| + String get protoSupportCheck {
|
| + // We don't modify the prototypes in CSP mode. Therefore we can have an
|
| + // easier prototype-check.
|
| + return 'var $supportsProtoName = !!{}.__proto__;\n';
|
| + }
|
| +
|
| + String get finishIsolateConstructorFunction {
|
| + // We replace the old Isolate function with a new one that initializes
|
| + // all its field with the initial (and often final) value of all globals.
|
| + //
|
| + // We also copy over old values like the prototype, and the
|
| + // isolateProperties themselves.
|
| + return """
|
| +function(oldIsolate) {
|
| + var isolateProperties = oldIsolate.${namer.ISOLATE_PROPERTIES};
|
| + function Isolate() {
|
| + for (var staticName in isolateProperties) {
|
| + if (Object.prototype.hasOwnProperty.call(isolateProperties, staticName)) {
|
| + this[staticName] = isolateProperties[staticName];
|
| + }
|
| + }
|
| + // Use the newly created object as prototype. In Chrome this creates a
|
| + // hidden class for the object and makes sure it is fast to access.
|
| + function ForceEfficientMap() {}
|
| + ForceEfficientMap.prototype = this;
|
| + new ForceEfficientMap;
|
| + }
|
| + Isolate.prototype = oldIsolate.prototype;
|
| + Isolate.prototype.constructor = Isolate;
|
| + Isolate.${namer.ISOLATE_PROPERTIES} = isolateProperties;
|
| + return Isolate;
|
| +}""";
|
| + }
|
| +
|
| + void emitBoundClosureClassHeader(String mangledName,
|
| + String superName,
|
| + CodeBuffer buffer) {
|
| + buffer.add("""
|
| +$classesCollector.$mangledName = {'': function $mangledName(self, target) {
|
| + this.self = self;
|
| + this.target = target;
|
| + },
|
| + 'super': '$superName',
|
| +""");
|
| + }
|
| +
|
| + void emitClassConstructor(ClassElement classElement, CodeBuffer buffer) {
|
| + // Say we have a class A with fields b, c and d, where c needs a getter and
|
| + // d needs both a getter and a setter. Then we produce:
|
| + // - a constructor (directly into the given [buffer]):
|
| + // function A(b, c, d) { this.b = b, this.c = c, this.d = d; }
|
| + // - getters and setters (stored in the [explicitGettersSetters] list):
|
| + // get$c : function() { return this.c; }
|
| + // get$d : function() { return this.d; }
|
| + // set$d : function(x) { this.d = x; }
|
| + List<String> fields = <String>[];
|
| + visitClassFields(classElement, (Element member,
|
| + String name,
|
| + bool needsGetter,
|
| + bool needsSetter,
|
| + bool needsCheckedSetter) {
|
| + fields.add(name);
|
| + });
|
| +
|
| + List<String> argumentNames = fields;
|
| + if (fields.length < ($z - $a)) {
|
| + argumentNames = new List<String>(fields.length);
|
| + for (int i = 0; i < fields.length; i++) {
|
| + argumentNames[i] = new String.fromCharCodes([$a + i]);
|
| + }
|
| + }
|
| + String constructorName = namer.safeName(classElement.name.slowToString());
|
| + // Generate the constructor.
|
| + buffer.add("'': function $constructorName(");
|
| + buffer.add(Strings.join(argumentNames, ", "));
|
| + buffer.add(") {\n");
|
| + for (int i = 0; i < fields.length; i++) {
|
| + buffer.add(" this.${fields[i]} = ${argumentNames[i]};\n");
|
| + }
|
| + buffer.add(' }');
|
| + }
|
| +
|
| + void emitClassFields(ClassElement classElement, CodeBuffer buffer) {
|
| + /* Do nothing. */
|
| + }
|
| +
|
| + void emitClassGettersSetters(ClassElement classElement, CodeBuffer buffer,
|
| + {bool omitLeadingComma: false}) {
|
| + emitComma() {
|
| + if (!omitLeadingComma) {
|
| + buffer.add(",\n ");
|
| + } else {
|
| + omitLeadingComma = false;
|
| + }
|
| + }
|
| +
|
| + visitClassFields(classElement, (Element member,
|
| + String name,
|
| + bool needsGetter,
|
| + bool needsSetter,
|
| + bool needsCheckedSetter) {
|
| + if (needsGetter) {
|
| + emitComma();
|
| + generateGetter(member, name, buffer);
|
| + }
|
| + if (needsSetter) {
|
| + emitComma();
|
| + generateSetter(member, name, buffer);
|
| + }
|
| + if (needsCheckedSetter) {
|
| + assert(!needsSetter);
|
| + emitComma();
|
| + generateCheckedSetter(member, name, buffer);
|
| + }
|
| + });
|
| + }
|
| +}
|
|
|