Chromium Code Reviews| 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..698902dcf62fac801d567317f4bf8d92f30c1d25 |
| --- /dev/null |
| +++ b/lib/compiler/implementation/js_backend/emitter_no_eval.dart |
| @@ -0,0 +1,133 @@ |
| +// 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__;'; |
|
kasperl
2012/10/18 09:36:21
Missing newline at end?
floitsch
2012/10/18 11:08:11
Done.
|
| + } |
| + |
| + 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; |
|
floitsch
2012/10/17 21:15:01
It is necessary to instantiate an object. Otherwis
kasperl
2012/10/18 09:36:21
Cool. Good to know.
|
| + } |
| + 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; }, |
|
kasperl
2012/10/18 09:36:21
I'd prefer to stuff the 'function $mangledName(sel
floitsch
2012/10/18 11:08:11
Done.
|
| +'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); |
| + }); |
| + |
| + String constructorName = namer.safeName(classElement.name.slowToString()); |
| + // Generate the constructor. |
| + buffer.add("'': function $constructorName("); |
| + buffer.add(Strings.join(fields, ", ")); |
| + buffer.add(") {"); |
|
kasperl
2012/10/18 09:36:21
Newline after {.
floitsch
2012/10/18 11:08:11
Done.
|
| + for (String field in fields) { |
| + buffer.add(" this.$field = $field;"); |
|
kasperl
2012/10/18 09:36:21
Two space indent and newline after ;.
floitsch
2012/10/18 11:08:11
Done.
|
| + } |
| + 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); |
| + } |
| + }); |
| + } |
| +} |