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

Side by Side Diff: frog/gen.dart

Issue 8591033: Support globals in frog isolates. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: john comments Created 9 years, 1 month 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
« no previous file with comments | « frog/frogsh ('k') | frog/lib/isolate.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, 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 /** 5 /**
6 * Top level generator object for writing code and keeping track of 6 * Top level generator object for writing code and keeping track of
7 * dependencies. 7 * dependencies.
8 * 8 *
9 * Should have two compilation models, but only one implemented so far. 9 * Should have two compilation models, but only one implemented so far.
10 * 10 *
11 * 1. Do a top-level resolution of all types and their members. 11 * 1. Do a top-level resolution of all types and their members.
12 * 2. Start from main and walk the call-graph compiling members as needed. 12 * 2. Start from main and walk the call-graph compiling members as needed.
13 * 2a. That includes compiling overriding methods and calling methods by 13 * 2a. That includes compiling overriding methods and calling methods by
14 * selector when invoked on var. 14 * selector when invoked on var.
15 * 3. Spit out all required code. 15 * 3. Spit out all required code.
16 */ 16 */
17 class WorldGenerator { 17 class WorldGenerator {
18 MethodMember main; 18 MethodMember main;
19 CodeWriter writer; 19 CodeWriter writer;
20
21 /**
22 * Whether the app has any static fields used. Note this could still be true
23 * and [globals] be empty if no static field has a default initialization.
24 */
25 bool hasStatics = false;
26
27 /** Global const and static field initializations. */
20 Map<String, GlobalValue> globals; 28 Map<String, GlobalValue> globals;
21 CoreJs corejs; 29 CoreJs corejs;
22 bool _inheritsGenerated = false; 30 bool _inheritsGenerated = false;
23 31
24 WorldGenerator(this.main, this.writer): globals = {}, corejs = new CoreJs(); 32 WorldGenerator(this.main, this.writer): globals = {}, corejs = new CoreJs();
25 33
26 run() { 34 run() {
27 var metaGen = new MethodGenerator(main, null); 35 var metaGen = new MethodGenerator(main, null);
28 var mainCall = main.invoke(metaGen, null, null, Arguments.EMPTY); 36 var mainCall = main.invoke(metaGen, null, null, Arguments.EMPTY);
29 main.declaringType.markUsed(); 37 main.declaringType.markUsed();
30 38
31 // TODO(jimhug): Better way to capture hidden control flow. 39 // TODO(jimhug): Better way to capture hidden control flow.
32 world.corelib.types['BadNumberFormatException'].markUsed(); 40 world.corelib.types['BadNumberFormatException'].markUsed();
33 world.coreimpl.types['NumImplementation'].markUsed(); 41 world.coreimpl.types['NumImplementation'].markUsed();
34 world.coreimpl.types['StringImplementation'].markUsed(); 42 world.coreimpl.types['StringImplementation'].markUsed();
35 genMethod( 43 genMethod(
36 world.coreimpl.types['StringImplementation'].getMember('contains')); 44 world.coreimpl.types['StringImplementation'].getMember('contains'));
37 45
38 // Only include isolate-specific code if isolates are used. 46 // Only include isolate-specific code if isolates are used.
39 if (world.corelib.types['Isolate'].isUsed 47 if (world.corelib.types['Isolate'].isUsed
40 || world.coreimpl.types['ReceivePortImpl'].isUsed) { 48 || world.coreimpl.types['ReceivePortImpl'].isUsed) {
41 corejs.useIsolates = true; 49 corejs.useIsolates = true;
42 MethodMember isolateMain = 50 MethodMember isolateMain =
43 world.coreimpl.topType.resolveMember('startAsIsolate').members[0]; 51 world.coreimpl.topType.resolveMember('startRootIsolate').members[0];
44 mainCall = isolateMain.invoke(metaGen, null, null, 52 mainCall = isolateMain.invoke(metaGen, null, null,
45 new Arguments(null, [main._get(metaGen, main.definition, null)])); 53 new Arguments(null, [main._get(metaGen, main.definition, null)]));
46 } 54 }
47 55
48 writeTypes(world.coreimpl); 56 writeTypes(world.coreimpl);
49 writeTypes(world.corelib); 57 writeTypes(world.corelib);
50 58
51 // Write the main library. This will cause all libraries to be written in 59 // Write the main library. This will cause all libraries to be written in
52 // the topographic sort order. 60 // the topographic sort order.
53 writeTypes(main.declaringType.library); 61 writeTypes(main.declaringType.library);
54 62
55 _writeGlobals(); 63 writeGlobals();
56 writer.writeln('${mainCall.code};'); 64 writer.writeln('${mainCall.code};');
57 } 65 }
58 66
59 GlobalValue globalForStaticField(FieldMember field, Value fieldValue, 67 GlobalValue globalForStaticField(FieldMember field, Value fieldValue,
60 List<Value> dependencies) { 68 List<Value> dependencies) {
69 hasStatics = true;
61 var fullname = "${field.declaringType.jsname}.${field.jsname}"; 70 var fullname = "${field.declaringType.jsname}.${field.jsname}";
62 if (!globals.containsKey(fullname)) { 71 if (!globals.containsKey(fullname)) {
63 globals[fullname] = new GlobalValue.fromStatic( 72 globals[fullname] = new GlobalValue.fromStatic(
64 field, fieldValue, dependencies); 73 field, fieldValue, dependencies);
65 } 74 }
66 return globals[fullname]; 75 return globals[fullname];
67 } 76 }
68 77
69 GlobalValue globalForConst(EvaluatedValue exp, List<Value> dependencies) { 78 GlobalValue globalForConst(EvaluatedValue exp, List<Value> dependencies) {
70 var code = exp.canonicalCode; 79 var code = exp.canonicalCode;
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
287 } 296 }
288 297
289 _writeStaticField(FieldMember field) { 298 _writeStaticField(FieldMember field) {
290 // Final static fields must be constants which will be folded and inlined. 299 // Final static fields must be constants which will be folded and inlined.
291 if (field.isFinal) return; 300 if (field.isFinal) return;
292 301
293 var fullname = "${field.declaringType.jsname}.${field.jsname}"; 302 var fullname = "${field.declaringType.jsname}.${field.jsname}";
294 if (globals.containsKey(fullname)) { 303 if (globals.containsKey(fullname)) {
295 var value = globals[fullname]; 304 var value = globals[fullname];
296 if (field.declaringType.isTop && !field.isNative) { 305 if (field.declaringType.isTop && !field.isNative) {
297 writer.writeln('var ${field.jsname} = ${value.exp.code};'); 306 writer.writeln('\$globals.${field.jsname} = ${value.exp.code};');
298 } else { 307 } else {
299 writer.writeln( 308 writer.writeln('\$globals.${field.declaringType.jsname}_${field.jsname}'
300 '${field.declaringType.jsname}.${field.jsname} = ${value.exp.code};'); 309 + ' = ${value.exp.code};');
301 } 310 }
302 } 311 }
303 // No need to write code for a static class field with no initial value. 312 // No need to write code for a static class field with no initial value.
304 } 313 }
305 314
306 _writeField(FieldMember field) { 315 _writeField(FieldMember field) {
307 // Generate declarations for static top-level fields with no value. 316 // Generate declarations for static top-level fields with no value.
308 if (field.declaringType.isTop && !field.isNative && field.value == null) { 317 if (field.declaringType.isTop && !field.isNative && field.value == null) {
309 writer.writeln('var ${field.jsname};'); 318 writer.writeln('var ${field.jsname};');
310 } 319 }
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
347 writer.exitBlock('});'); 356 writer.exitBlock('});');
348 } 357 }
349 } 358 }
350 359
351 _writeMethod(Member method) { 360 _writeMethod(Member method) {
352 if (method.generator != null) { 361 if (method.generator != null) {
353 method.generator.writeDefinition(writer, null); 362 method.generator.writeDefinition(writer, null);
354 } 363 }
355 } 364 }
356 365
357 _writeGlobals() { 366 writeGlobals() {
358 if (globals.length > 0) { 367 if (globals.length > 0) {
359 writer.comment('// ********** Globals **************'); 368 writer.comment('// ********** Globals **************');
369 var list = globals.getValues();
370 list.sort((a, b) => a.compareTo(b));
371
372 // put all static field initializations in a method
373 writer.enterBlock('function \$static_init(){');
374 for (var global in list) {
375 if (global.field != null) {
376 _writeStaticField(global.field);
377 }
378 }
379 writer.exitBlock('}');
380
381 // Keep const expressions shared across isolates. Note that the frog
382 // isolate library needs this because we wrote it's bootstrap and
383 // book-keeping directly in Dart. Specifically, that code uses
384 // [HashMapImplementation] which internally uses a constant expression.
385 for (var global in list) {
386 if (global.field == null) {
387 writer.writeln('${global.name} = ${global.exp.code};');
388 }
389 }
360 } 390 }
361 var list = globals.getValues(); 391
362 list.sort((a, b) => a.compareTo(b)); 392 if (!corejs.useIsolates) {
363 for (var global in list) { 393 if (hasStatics) {
364 if (global.field != null) { 394 writer.writeln('var \$globals = {};');
365 _writeStaticField(global.field); 395 }
366 } else { 396 if (globals.length > 0) {
367 writer.writeln('var ${global.name} = ${global.exp.code};'); 397 writer.writeln('\$static_init();');
368 } 398 }
369 } 399 }
370 } 400 }
371 401
372 /** Order a list of values in a Map by SourceSpan, then by name. */ 402 /** Order a list of values in a Map by SourceSpan, then by name. */
373 List _orderValues(Map map) { 403 List _orderValues(Map map) {
374 // TODO(jmesserly): should we copy the list? 404 // TODO(jmesserly): should we copy the list?
375 // Right now, the Maps are returning a copy already. 405 // Right now, the Maps are returning a copy already.
376 List values = map.getValues(); 406 List values = map.getValues();
377 values.sort(_compareMembers); 407 values.sort(_compareMembers);
(...skipping 1909 matching lines...) Expand 10 before | Expand all | Expand 10 after
2287 result.add(new Value(world.varType, '\$$i', null, /*needsTemp:*/false)); 2317 result.add(new Value(world.varType, '\$$i', null, /*needsTemp:*/false));
2288 } 2318 }
2289 for (int i = bareCount; i < length; i++) { 2319 for (int i = bareCount; i < length; i++) {
2290 var name = getName(i); 2320 var name = getName(i);
2291 if (name == null) name = '\$$i'; 2321 if (name == null) name = '\$$i';
2292 result.add(new Value(world.varType, name, null, /*needsTemp:*/false)); 2322 result.add(new Value(world.varType, name, null, /*needsTemp:*/false));
2293 } 2323 }
2294 return new Arguments(nodes, result); 2324 return new Arguments(nodes, result);
2295 } 2325 }
2296 } 2326 }
OLDNEW
« no previous file with comments | « frog/frogsh ('k') | frog/lib/isolate.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698