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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/js_backend/emitter_no_eval.dart

Issue 12388018: Re-enable support for --disallow-unsafe-eval. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address review feedback. Created 7 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 part of js_backend; 5 part of js_backend;
6 6
7 class CodeEmitterNoEvalTask extends CodeEmitterTask { 7 class CodeEmitterNoEvalTask extends CodeEmitterTask {
8 CodeEmitterNoEvalTask(Compiler compiler, 8 CodeEmitterNoEvalTask(Compiler compiler,
9 Namer namer, 9 Namer namer,
10 bool generateSourceMap) 10 bool generateSourceMap)
11 : super(compiler, namer, generateSourceMap); 11 : super(compiler, namer, generateSourceMap);
12 12
13 String get generateGetterSetterFunction { 13 bool get getterAndSetterCanBeImplementedByFieldSpec => false;
14 return """
15 function() {
16 throw 'Internal Error: no dynamic generation of getters and setters allowed';
17 }""";
18 }
19 14
20 String get defineClassFunction { 15 void emitSuper(String superName, ClassBuilder builder) {
21 return """ 16 if (superName != '') {
22 function(cls, constructor, prototype) { 17 builder.addProperty('super', js.string(superName));
23 constructor.prototype = prototype;
24 constructor.builtin\$cls = cls;
25 return constructor;
26 }""";
27 }
28
29 String get protoSupportCheck {
30 // We don't modify the prototypes in CSP mode. Therefore we can have an
31 // easier prototype-check.
32 return 'var $supportsProtoName = !!{}.__proto__;\n';
33 }
34
35 String get finishIsolateConstructorFunction {
36 // We replace the old Isolate function with a new one that initializes
37 // all its field with the initial (and often final) value of all globals.
38 //
39 // We also copy over old values like the prototype, and the
40 // isolateProperties themselves.
41 return """
42 function(oldIsolate) {
43 var isolateProperties = oldIsolate.${namer.isolatePropertiesName};
44 function Isolate() {
45 for (var staticName in isolateProperties) {
46 if (Object.prototype.hasOwnProperty.call(isolateProperties, staticName)) {
47 this[staticName] = isolateProperties[staticName];
48 }
49 } 18 }
50 // Use the newly created object as prototype. In Chrome this creates a
51 // hidden class for the object and makes sure it is fast to access.
52 function ForceEfficientMap() {}
53 ForceEfficientMap.prototype = this;
54 new ForceEfficientMap;
55 }
56 Isolate.prototype = oldIsolate.prototype;
57 Isolate.prototype.constructor = Isolate;
58 Isolate.${namer.isolatePropertiesName} = isolateProperties;
59 return Isolate;
60 }""";
61 }
62
63 String get lazyInitializerFunction {
64 return """
65 function(prototype, staticName, fieldName, getterName, lazyValue, getter) {
66 $lazyInitializerLogic
67 }""";
68 }
69
70 js.Expression buildLazyInitializedGetter(VariableElement element) {
71 String isolate = namer.CURRENT_ISOLATE;
72 return js.fun([],
73 js.block1(
74 js.return_(
75 js.fieldAccess(js.use(isolate), namer.getName(element)))));
76 }
77
78 js.Expression buildConstructor(String mangledName, List<String> fieldNames) {
79 return new js.NamedFunction(
80 new js.VariableDeclaration(mangledName),
81 new js.Fun(
82 fieldNames
83 .map((fieldName) => new js.Parameter(fieldName))
84 .toList(),
85 new js.Block(
86 fieldNames.map((fieldName) =>
87 new js.ExpressionStatement(
88 new js.Assignment(
89 new js.This().dot(fieldName),
90 new js.VariableUse(fieldName))))
91 .toList())));
92 } 19 }
93 20
94 void emitBoundClosureClassHeader(String mangledName, 21 void emitBoundClosureClassHeader(String mangledName,
95 String superName, 22 String superName,
96 List<String> fieldNames, 23 List<String> fieldNames,
97 ClassBuilder builder) { 24 ClassBuilder builder) {
98 builder.addProperty('', buildConstructor(mangledName, fieldNames)); 25 builder.addProperty('', buildConstructor(mangledName, fieldNames));
99 builder.addProperty('super', js.string(superName)); 26 emitSuper(superName, builder);
27 }
28
29
30 void emitClassFields(ClassElement classElement,
31 ClassBuilder builder,
32 { String superClass: "",
33 bool classIsNative: false }) {
34 // Class fields are dynamically generated so they have to be
35 // emitted using getters and setters instead.
100 } 36 }
101 37
102 void emitClassConstructor(ClassElement classElement, ClassBuilder builder) { 38 void emitClassConstructor(ClassElement classElement, ClassBuilder builder) {
103 // Say we have a class A with fields b, c and d, where c needs a getter and 39 // Say we have a class A with fields b, c and d, where c needs a getter and
104 // d needs both a getter and a setter. Then we produce: 40 // d needs both a getter and a setter. Then we produce:
105 // - a constructor (directly into the given [buffer]): 41 // - a constructor (directly into the given [buffer]):
106 // function A(b, c, d) { this.b = b, this.c = c, this.d = d; } 42 // function A(b, c, d) { this.b = b, this.c = c, this.d = d; }
107 // - getters and setters (stored in the [explicitGettersSetters] list): 43 // - getters and setters (stored in the [explicitGettersSetters] list):
108 // get$c : function() { return this.c; } 44 // get$c : function() { return this.c; }
109 // get$d : function() { return this.d; } 45 // get$d : function() { return this.d; }
110 // set$d : function(x) { this.d = x; } 46 // set$d : function(x) { this.d = x; }
111 List<String> fields = <String>[]; 47 List<String> fields = <String>[];
112 visitClassFields(classElement, (Element member, 48 visitClassFields(classElement, (Element member,
113 String name, 49 String name,
114 String accessorName, 50 String accessorName,
115 bool needsGetter, 51 bool needsGetter,
116 bool needsSetter, 52 bool needsSetter,
117 bool needsCheckedSetter) { 53 bool needsCheckedSetter) {
118 fields.add(name); 54 fields.add(name);
119 }); 55 });
120 String constructorName = namer.safeName(classElement.name.slowToString()); 56 String constructorName = namer.safeName(classElement.name.slowToString());
121
122 builder.addProperty('', buildConstructor(constructorName, fields)); 57 builder.addProperty('', buildConstructor(constructorName, fields));
123 } 58 }
124 59
125 void emitSuper(String superName, ClassBuilder builder) { 60 List get defineClassFunction {
126 if (superName != '') { 61 return [new jsAst.FunctionDeclaration(
127 builder.addProperty('super', js.string(superName)); 62 new jsAst.VariableDeclaration('defineClass'),
128 } 63 js.fun(['cls', 'constructor', 'prototype'],
64 [js[r'constructor.prototype = prototype'],
65 js[r'constructor.builtin$cls = cls'],
66 js.return_('constructor')]))];
129 } 67 }
130 68
131 void emitClassFields(ClassElement classElement, 69 List buildProtoSupportCheck() {
132 ClassBuilder builder, 70 // We don't modify the prototypes in CSP mode. Therefore we can have an
133 { String superClass: "", 71 // easier prototype-check.
134 bool classIsNative: false}) { 72 return [js['var $supportsProtoName = !(!({}.__proto__))']];
135 } 73 }
136 74
137 bool get getterAndSetterCanBeImplementedByFieldSpec => false; 75 jsAst.Expression buildConstructor(String mangledName,
76 List<String> fieldNames) {
77 return new jsAst.NamedFunction(
78 new jsAst.VariableDeclaration(mangledName),
79 js.fun(fieldNames, fieldNames.map(
80 (name) => js['this.$name = $name']).toList()));
81 }
82
83 jsAst.FunctionDeclaration get generateAccessorFunction {
84 String message =
85 'Internal error: no dynamic generation of accessors allowed.';
86 return new jsAst.FunctionDeclaration(
87 new jsAst.VariableDeclaration('generateAccessor'),
88 js.fun([], new jsAst.Throw(js.string(message))));
89 }
90
91 jsAst.Expression buildLazyInitializedGetter(VariableElement element) {
92 String isolate = namer.CURRENT_ISOLATE;
93 String name = namer.getName(element);
94 return js.fun([], js.return_(js['$isolate.$name']));
95 }
96
97 jsAst.Fun get lazyInitializerFunction {
98 // function(prototype, staticName, fieldName,
99 // getterName, lazyValue, getter) {
100 var parameters = <String>['prototype', 'staticName', 'fieldName',
101 'getterName', 'lazyValue', 'getter'];
102 return js.fun(parameters, addLazyInitializerLogic());
103 }
104
105 jsAst.Fun get finishIsolateConstructorFunction {
106 // We replace the old Isolate function with a new one that initializes
107 // all its fields with the initial (and often final) value of all globals.
108 //
109 // We also copy over old values like the prototype, and the
110 // isolateProperties themselves.
111 return js.fun('oldIsolate', [
112 js['var isolateProperties = oldIsolate.${namer.isolatePropertiesName}'],
113 new jsAst.FunctionDeclaration(
114 new jsAst.VariableDeclaration('Isolate'),
115 js.fun([], [
116 js['var hasOwnProperty = Object.prototype.hasOwnProperty'],
117 js.forIn('staticName', 'isolateProperties',
118 js.if_(js['hasOwnProperty.call(isolateProperties, staticName)'],
119 js['this[staticName] = isolateProperties[staticName]'])),
120 // Use the newly created object as prototype. In Chrome,
121 // this creates a hidden class for the object and makes
122 // sure it is fast to access.
123 new jsAst.FunctionDeclaration(
124 new jsAst.VariableDeclaration('ForceEfficientMap'),
125 js.fun([], [])),
126 js['ForceEfficientMap.prototype = this'],
127 js['new ForceEfficientMap()']])),
128 js['Isolate.prototype = oldIsolate.prototype'],
129 js['Isolate.prototype.constructor = Isolate'],
130 js['Isolate.${namer.isolatePropertiesName} = isolateProperties'],
131 js.return_('Isolate')]);
132 }
138 } 133 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698