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

Side by Side Diff: pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart

Issue 742873002: Isolates: allow sending of arbitrary objects in dart2js. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Support CSP mode. Created 6 years 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) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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 dart2js.js_emitter; 5 part of dart2js.js_emitter;
6 6
7 7
8 class OldEmitter implements Emitter { 8 class OldEmitter implements Emitter {
9 final Compiler compiler; 9 final Compiler compiler;
10 final CodeEmitterTask task; 10 final CodeEmitterTask task;
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
67 67
68 CodeBuffer get mainBuffer { 68 CodeBuffer get mainBuffer {
69 return getBuffer(compiler.deferredLoadTask.mainOutputUnit); 69 return getBuffer(compiler.deferredLoadTask.mainOutputUnit);
70 } 70 }
71 71
72 /** 72 /**
73 * List of expressions and statements that will be included in the 73 * List of expressions and statements that will be included in the
74 * precompiled function. 74 * precompiled function.
75 * 75 *
76 * To save space, dart2js normally generates constructors and accessors 76 * To save space, dart2js normally generates constructors and accessors
77 * dynamically. This doesn't work in CSP mode, and may impact startup time 77 * dynamically. This doesn't work in CSP mode, so dart2js emits them directly
78 * negatively. So dart2js will emit these functions to a separate file that 78 * when in CSP mode.
79 * can be optionally included to support CSP mode or for faster startup.
80 */ 79 */
81 Map<OutputUnit, List<jsAst.Node>> _cspPrecompiledFunctions = 80 Map<OutputUnit, List<jsAst.Node>> _cspPrecompiledFunctions =
82 new Map<OutputUnit, List<jsAst.Node>>(); 81 new Map<OutputUnit, List<jsAst.Node>>();
83 82
84 Map<OutputUnit, List<jsAst.Expression>> _cspPrecompiledConstructorNames = 83 Map<OutputUnit, List<jsAst.Expression>> _cspPrecompiledConstructorNames =
85 new Map<OutputUnit, List<jsAst.Expression>>(); 84 new Map<OutputUnit, List<jsAst.Expression>>();
86 85
87 /** 86 /**
88 * Accumulate properties for classes and libraries, describing their 87 * Accumulate properties for classes and libraries, describing their
89 * static/top-level members. 88 * static/top-level members.
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
159 String get finishIsolateConstructorName 158 String get finishIsolateConstructorName
160 => '${namer.isolateName}.\$finishIsolateConstructor'; 159 => '${namer.isolateName}.\$finishIsolateConstructor';
161 String get isolatePropertiesName 160 String get isolatePropertiesName
162 => '${namer.isolateName}.${namer.isolatePropertiesName}'; 161 => '${namer.isolateName}.${namer.isolatePropertiesName}';
163 String get lazyInitializerName 162 String get lazyInitializerName
164 => '${namer.isolateName}.\$lazy'; 163 => '${namer.isolateName}.\$lazy';
165 String get initName => 'init'; 164 String get initName => 'init';
166 String get makeConstListProperty 165 String get makeConstListProperty
167 => namer.getMappedInstanceName('makeConstantList'); 166 => namer.getMappedInstanceName('makeConstantList');
168 167
168 /// The name of the property that contains all field names.
169 ///
170 /// This property is added to constructors when isolate support is enabled.
171 static const String FIELD_NAMES_PROPERTY_NAME = r"$__fields__";
172
169 /// For deferred loading we communicate the initializers via this global var. 173 /// For deferred loading we communicate the initializers via this global var.
170 final String deferredInitializers = r"$dart_deferred_initializers"; 174 final String deferredInitializers = r"$dart_deferred_initializers";
171 175
172 /// All the global state can be passed around with this variable. 176 /// All the global state can be passed around with this variable.
173 String get globalsHolder => namer.getMappedGlobalName("globalsHolder"); 177 String get globalsHolder => namer.getMappedGlobalName("globalsHolder");
174 178
175 jsAst.Expression generateEmbeddedGlobalAccess(String global) { 179 jsAst.Expression generateEmbeddedGlobalAccess(String global) {
176 return js(generateEmbeddedGlobalAccessString(global)); 180 return js(generateEmbeddedGlobalAccessString(global));
177 } 181 }
178 182
179 String generateEmbeddedGlobalAccessString(String global) { 183 String generateEmbeddedGlobalAccessString(String global) {
180 // TODO(floitsch): don't use 'init' as global embedder storage. 184 // TODO(floitsch): don't use 'init' as global embedder storage.
181 return '$initName.$global'; 185 return '$initName.$global';
182 } 186 }
183 187
184 jsAst.Expression isolateLazyInitializerAccess(Element element) { 188 jsAst.Expression isolateLazyInitializerAccess(Element element) {
185 return jsAst.js('#.#', [namer.globalObjectFor(element), 189 return jsAst.js('#.#', [namer.globalObjectFor(element),
186 namer.getLazyInitializerName(element)]); 190 namer.getLazyInitializerName(element)]);
187 } 191 }
188 192
189 jsAst.Expression isolateStaticClosureAccess(Element element) { 193 jsAst.Expression isolateStaticClosureAccess(Element element) {
190 return jsAst.js('#.#()', 194 return jsAst.js('#.#()',
191 [namer.globalObjectFor(element), namer.getStaticClosureName(element)]); 195 [namer.globalObjectFor(element), namer.getStaticClosureName(element)]);
192 } 196 }
193 197
194 jsAst.PropertyAccess globalPropertyAccess(Element element) { 198 jsAst.PropertyAccess globalPropertyAccess(Element element) {
195 String name = namer.getNameX(element); 199 String name = namer.getNameX(element);
196 jsAst.PropertyAccess pa = new jsAst.PropertyAccess.field( 200 jsAst.PropertyAccess pa = new jsAst.PropertyAccess.field(
197 new jsAst.VariableUse(namer.globalObjectFor(element)), 201 new jsAst.VariableUse(namer.globalObjectFor(element)),
198 name); 202 name);
199 return pa; 203 return pa;
200 } 204 }
201 205
202 jsAst.PropertyAccess staticFieldAccess(Element element) { 206 jsAst.PropertyAccess staticFieldAccess(Element element) {
203 return globalPropertyAccess(element); 207 return globalPropertyAccess(element);
204 } 208 }
205 209
206 jsAst.PropertyAccess staticFunctionAccess(Element element) { 210 jsAst.PropertyAccess staticFunctionAccess(Element element) {
207 return globalPropertyAccess(element); 211 return globalPropertyAccess(element);
208 } 212 }
209 213
210 jsAst.PropertyAccess classAccess(Element element) { 214 jsAst.PropertyAccess classAccess(Element element) {
211 return globalPropertyAccess(element); 215 return globalPropertyAccess(element);
212 } 216 }
213 217
214 jsAst.PropertyAccess typedefAccess(Element element) { 218 jsAst.PropertyAccess typedefAccess(Element element) {
215 return globalPropertyAccess(element); 219 return globalPropertyAccess(element);
216 } 220 }
217 221
218 jsAst.FunctionDeclaration get generateAccessorFunction { 222 jsAst.FunctionDeclaration get generateAccessorFunction {
219 const RANGE1_SIZE = RANGE1_LAST - RANGE1_FIRST + 1; 223 const RANGE1_SIZE = RANGE1_LAST - RANGE1_FIRST + 1;
220 const RANGE2_SIZE = RANGE2_LAST - RANGE2_FIRST + 1; 224 const RANGE2_SIZE = RANGE2_LAST - RANGE2_FIRST + 1;
221 const RANGE1_ADJUST = - (FIRST_FIELD_CODE - RANGE1_FIRST); 225 const RANGE1_ADJUST = - (FIRST_FIELD_CODE - RANGE1_FIRST);
222 const RANGE2_ADJUST = - (FIRST_FIELD_CODE + RANGE1_SIZE - RANGE2_FIRST); 226 const RANGE2_ADJUST = - (FIRST_FIELD_CODE + RANGE1_SIZE - RANGE2_FIRST);
223 const RANGE3_ADJUST = 227 const RANGE3_ADJUST =
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
281 accessors.push(property + "\$reflectable(" + fn + ");\\n"); 285 accessors.push(property + "\$reflectable(" + fn + ");\\n");
282 else 286 else
283 accessors.push(property + fn + ";\\n"); 287 accessors.push(property + fn + ";\\n");
284 } 288 }
285 } 289 }
286 290
287 return field; 291 return field;
288 }'''); 292 }''');
289 } 293 }
290 294
291 List get defineClassFunction { 295 List<jsAst.Node> get defineClassFunction {
292 // First the class name, then the field names in an array and the members 296 // First the class name, then the field names in an array and the members
293 // (inside an Object literal). 297 // (inside an Object literal).
294 // The caller can also pass in the constructor as a function if needed. 298 // The caller can also pass in the constructor as a function if needed.
295 // 299 //
296 // Example: 300 // Example:
297 // defineClass("A", ["x", "y"], { 301 // defineClass("A", ["x", "y"], {
298 // foo$1: function(y) { 302 // foo$1: function(y) {
299 // print(this.x + y); 303 // print(this.x + y);
300 // }, 304 // },
301 // bar$2: function(t, v) { 305 // bar$2: function(t, v) {
302 // this.x = t - v; 306 // this.x = t - v;
303 // }, 307 // },
304 // }); 308 // });
305 309
306 var defineClass = js('''function(name, fields) { 310 bool hasIsolateSupport = compiler.hasIsolateSupport;
307 var accessors = []; 311 String fieldNamesProperty = FIELD_NAMES_PROPERTY_NAME;
308 312
309 var str = "function " + name + "("; 313 jsAst.Expression defineClass = js('''
310 var body = ""; 314 function(name, fields) {
315 var accessors = [];
316
317 var str = "function " + name + "(";
318 var body = "";
319 if (#hasIsolateSupport) { var fieldNames = ""; }
320
321 for (var i = 0; i < fields.length; i++) {
322 if(i != 0) str += ", ";
323
324 var field = generateAccessor(fields[i], accessors, name);
325 if (#hasIsolateSupport) { fieldNames += "'" + field + "',"; }
326 var parameter = "parameter_" + field;
327 str += parameter;
328 body += ("this." + field + " = " + parameter + ";\\n");
329 }
330 str += ") {\\n" + body + "}\\n";
331 str += name + ".builtin\$cls=\\"" + name + "\\";\\n";
332 str += "\$desc=\$collectedClasses." + name + ";\\n";
333 str += "if(\$desc instanceof Array) \$desc = \$desc[1];\\n";
334 str += name + ".prototype = \$desc;\\n";
335 if (typeof defineClass.name != "string") {
336 str += name + ".name=\\"" + name + "\\";\\n";
337 }
338 if (#hasIsolateSupport) {
339 str += name + ".$fieldNamesProperty=[" + fieldNames + "];\\n";
340 }
341 str += accessors.join("");
342
343 return str;
344 }''', { 'hasIsolateSupport': hasIsolateSupport });
311 345
312 for (var i = 0; i < fields.length; i++) {
313 if(i != 0) str += ", ";
314
315 var field = generateAccessor(fields[i], accessors, name);
316 var parameter = "parameter_" + field;
317 str += parameter;
318 body += ("this." + field + " = " + parameter + ";\\n");
319 }
320 str += ") {\\n" + body + "}\\n";
321 str += name + ".builtin\$cls=\\"" + name + "\\";\\n";
322 str += "\$desc=\$collectedClasses." + name + ";\\n";
323 str += "if(\$desc instanceof Array) \$desc = \$desc[1];\\n";
324 str += name + ".prototype = \$desc;\\n";
325 if (typeof defineClass.name != "string") {
326 str += name + ".name=\\"" + name + "\\";\\n";
327 }
328 str += accessors.join("");
329
330 return str;
331 }''');
332 // Declare a function called "generateAccessor". This is used in 346 // Declare a function called "generateAccessor". This is used in
333 // defineClassFunction (it's a local declaration in init()). 347 // defineClassFunction (it's a local declaration in init()).
334 List<jsAst.Node> saveDefineClass = []; 348 List result = <jsAst.Node>[
335 if (compiler.hasIncrementalSupport) {
336 saveDefineClass.add(
337 js(r'self.$dart_unsafe_eval.defineClass = defineClass'));
338 }
339 return [
340 generateAccessorFunction, 349 generateAccessorFunction,
341 js('$generateAccessorHolder = generateAccessor'), 350 js('$generateAccessorHolder = generateAccessor'),
342 new jsAst.FunctionDeclaration( 351 new jsAst.FunctionDeclaration(
343 new jsAst.VariableDeclaration('defineClass'), defineClass) ] 352 new jsAst.VariableDeclaration('defineClass'), defineClass) ];
344 ..addAll(saveDefineClass); 353
354 if (compiler.hasIncrementalSupport) {
355 result.add(
356 js(r'self.$dart_unsafe_eval.defineClass = defineClass'));
357 }
358
359 if (hasIsolateSupport) {
360 jsAst.Expression classIdExtractorAccess =
361 generateEmbeddedGlobalAccess(embeddedNames.CLASS_ID_EXTRACTOR);
362 var classIdExtractorAssignment =
363 js('# = function(o) { return o.constructor.name; }',
364 classIdExtractorAccess);
365
366 jsAst.Expression classFieldsExtractorAccess =
367 generateEmbeddedGlobalAccess(embeddedNames.CLASS_FIELDS_EXTRACTOR);
368 var classFieldsExtractorAssignment = js('''
369 # = function(o) {
370 var fieldNames = o.constructor.$fieldNamesProperty;
371 if (!fieldNames) return []; // TODO(floitsch): do something else here.
372 var result = [];
373 result.length = fieldNames.length;
374 for (var i = 0; i < fieldNames.length; i++) {
375 result[i] = o[fieldNames[i]];
376 }
377 return result;
378 }''', classFieldsExtractorAccess);
379
380 jsAst.Expression instanceFromClassIdAccess =
381 generateEmbeddedGlobalAccess(embeddedNames.INSTANCE_FROM_CLASS_ID);
382 jsAst.Expression allClassesAccess =
383 generateEmbeddedGlobalAccess(embeddedNames.ALL_CLASSES);
384 var instanceFromClassIdAssignment =
385 js('# = function(name) { return new #[name](); }',
386 [instanceFromClassIdAccess, allClassesAccess]);
387
388 jsAst.Expression initializeEmptyInstanceAccess =
389 generateEmbeddedGlobalAccess(embeddedNames.INITIALIZE_EMPTY_INSTANCE);
390 var initializeEmptyInstanceAssignment = js('''
391 # = function(name, o, fields) {
392 #[name].apply(o, fields);
393 return o;
394 }''', [ initializeEmptyInstanceAccess, allClassesAccess ]);
395
396 result.addAll([classIdExtractorAssignment,
397 classFieldsExtractorAssignment,
398 instanceFromClassIdAssignment,
399 initializeEmptyInstanceAssignment]);
400 }
401
402 return result;
345 } 403 }
346 404
347 /** Needs defineClass to be defined. */ 405 /** Needs defineClass to be defined. */
348 jsAst.Expression buildInheritFrom() { 406 jsAst.Expression buildInheritFrom() {
349 jsAst.Expression result = js(r''' 407 jsAst.Expression result = js(r'''
350 function() { 408 function() {
351 function tmp() {} 409 function tmp() {}
352 var hasOwnProperty = Object.prototype.hasOwnProperty; 410 var hasOwnProperty = Object.prototype.hasOwnProperty;
353 return function (constructor, superConstructor) { 411 return function (constructor, superConstructor) {
354 tmp.prototype = superConstructor.prototype; 412 tmp.prototype = superConstructor.prototype;
(...skipping 948 matching lines...) Expand 10 before | Expand all | Expand 10 after
1303 ..write(',$_') 1361 ..write(',$_')
1304 ..write(jsAst.prettyPrint(initializers, 1362 ..write(jsAst.prettyPrint(initializers,
1305 compiler, 1363 compiler,
1306 monitor: compiler.dumpInfoTask)) 1364 monitor: compiler.dumpInfoTask))
1307 ..write(library == compiler.mainApp ? ',${n}1' : "") 1365 ..write(library == compiler.mainApp ? ',${n}1' : "")
1308 ..write('],$n'); 1366 ..write('],$n');
1309 } 1367 }
1310 1368
1311 void emitPrecompiledConstructor(OutputUnit outputUnit, 1369 void emitPrecompiledConstructor(OutputUnit outputUnit,
1312 String constructorName, 1370 String constructorName,
1313 jsAst.Expression constructorAst) { 1371 jsAst.Expression constructorAst,
1372 List<String> fields) {
1314 cspPrecompiledFunctionFor(outputUnit).add( 1373 cspPrecompiledFunctionFor(outputUnit).add(
1315 new jsAst.FunctionDeclaration( 1374 new jsAst.FunctionDeclaration(
1316 new jsAst.VariableDeclaration(constructorName), constructorAst)); 1375 new jsAst.VariableDeclaration(constructorName), constructorAst));
1317 cspPrecompiledFunctionFor(outputUnit).add( 1376
1318 js.statement(r'''{ 1377 String fieldNamesProperty = FIELD_NAMES_PROPERTY_NAME;
1319 #.builtin$cls = #; 1378 bool hasIsolateSupport = compiler.hasIsolateSupport;
1320 if (!"name" in #) 1379 jsAst.Node fieldNamesArray =
1321 #.name = #; 1380 hasIsolateSupport ? js.stringArray(fields) : new jsAst.LiteralNull();
1322 $desc=$collectedClasses.#; 1381
1382 cspPrecompiledFunctionFor(outputUnit).add(js.statement(r'''
1383 {
1384 #constructorName.builtin$cls = #constructorNameString;
1385 if (!"name" in #constructorName)
1386 #constructorName.name = #constructorNameString;
1387 $desc = $collectedClasses.#constructorName;
1323 if ($desc instanceof Array) $desc = $desc[1]; 1388 if ($desc instanceof Array) $desc = $desc[1];
1324 #.prototype = $desc; 1389 #constructorName.prototype = $desc;
1390 ''' /* next string is not a raw string */ '''
1391 if (#hasIsolateSupport) {
1392 #constructorName.$fieldNamesProperty = #fieldNamesArray;
1393 }
1325 }''', 1394 }''',
1326 [ constructorName, js.string(constructorName), 1395 {"constructorName": constructorName,
1327 constructorName, 1396 "constructorNameString": js.string(constructorName),
1328 constructorName, js.string(constructorName), 1397 "hasIsolateSupport": hasIsolateSupport,
1329 constructorName, 1398 "fieldNamesArray": fieldNamesArray}));
1330 constructorName
1331 ]));
1332 1399
1333 cspPrecompiledConstructorNamesFor(outputUnit).add(js('#', constructorName)); 1400 cspPrecompiledConstructorNamesFor(outputUnit).add(js('#', constructorName));
1334 } 1401 }
1335 1402
1336 /// Extracts the output name of the compiler's outputUri. 1403 /// Extracts the output name of the compiler's outputUri.
1337 String deferredPartFileName(OutputUnit outputUnit, 1404 String deferredPartFileName(OutputUnit outputUnit,
1338 {bool addExtension: true}) { 1405 {bool addExtension: true}) {
1339 String outPath = compiler.outputUri != null 1406 String outPath = compiler.outputUri != null
1340 ? compiler.outputUri.path 1407 ? compiler.outputUri.path
1341 : "out"; 1408 : "out";
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1384 js.string(typeReference)); 1451 js.string(typeReference));
1385 jsAst.Node declaration = new jsAst.ObjectInitializer([descriptor]); 1452 jsAst.Node declaration = new jsAst.ObjectInitializer([descriptor]);
1386 String mangledName = namer.getNameX(typedef); 1453 String mangledName = namer.getNameX(typedef);
1387 String reflectionName = getReflectionName(typedef, mangledName); 1454 String reflectionName = getReflectionName(typedef, mangledName);
1388 getElementDescriptor(library) 1455 getElementDescriptor(library)
1389 ..addProperty(mangledName, declaration) 1456 ..addProperty(mangledName, declaration)
1390 ..addProperty("+$reflectionName", js.string('')); 1457 ..addProperty("+$reflectionName", js.string(''));
1391 // Also emit a trivial constructor for CSP mode. 1458 // Also emit a trivial constructor for CSP mode.
1392 String constructorName = mangledName; 1459 String constructorName = mangledName;
1393 jsAst.Expression constructorAst = js('function() {}'); 1460 jsAst.Expression constructorAst = js('function() {}');
1461 List<String> fieldNames = [];
1394 emitPrecompiledConstructor(mainOutputUnit, 1462 emitPrecompiledConstructor(mainOutputUnit,
1395 constructorName, 1463 constructorName,
1396 constructorAst); 1464 constructorAst,
1465 fieldNames);
1397 } 1466 }
1398 } 1467 }
1399 1468
1400 void emitMangledNames() { 1469 void emitMangledNames() {
1401 if (!mangledFieldNames.isEmpty) { 1470 if (!mangledFieldNames.isEmpty) {
1402 var keys = mangledFieldNames.keys.toList(); 1471 var keys = mangledFieldNames.keys.toList();
1403 keys.sort(); 1472 keys.sort();
1404 var properties = []; 1473 var properties = [];
1405 for (String key in keys) { 1474 for (String key in keys) {
1406 var value = js.string('${mangledFieldNames[key]}'); 1475 var value = js.string('${mangledFieldNames[key]}');
(...skipping 696 matching lines...) Expand 10 before | Expand all | Expand 10 after
2103 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) { 2172 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) {
2104 if (element.isInstanceMember) { 2173 if (element.isInstanceMember) {
2105 cachedClassBuilders.remove(element.enclosingClass); 2174 cachedClassBuilders.remove(element.enclosingClass);
2106 2175
2107 nativeEmitter.cachedBuilders.remove(element.enclosingClass); 2176 nativeEmitter.cachedBuilders.remove(element.enclosingClass);
2108 2177
2109 } 2178 }
2110 } 2179 }
2111 } 2180 }
2112 } 2181 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698