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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/ir/ir_pickler.dart

Issue 231863007: Support local variables in dart2dart. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Incorporated review comments. Created 6 years, 7 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) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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 library dart2js.ir_pickler; 5 library dart2js.ir_pickler;
6 6
7 import 'ir_nodes.dart' as ir; 7 import 'ir_nodes.dart' as ir;
8 import '../dart2jslib.dart' show 8 import '../dart2jslib.dart' show
9 Constant, FalseConstant, TrueConstant, IntConstant, DoubleConstant, 9 Constant, FalseConstant, TrueConstant, IntConstant, DoubleConstant,
10 StringConstant, NullConstant, ListConstant, MapConstant, 10 StringConstant, NullConstant, ListConstant, MapConstant,
(...skipping 22 matching lines...) Expand all
33 * int ::= see [writeInt] for number encoding 33 * int ::= see [writeInt] for number encoding
34 * 34 *
35 * string ::= byte(STRING_ASCII) int(length) {byte(ascii)} 35 * string ::= byte(STRING_ASCII) int(length) {byte(ascii)}
36 * | byte(STRING_UTF8) int(length) {byte(utf8)} 36 * | byte(STRING_UTF8) int(length) {byte(utf8)}
37 * 37 *
38 * node ::= byte(NODE_CONSTANT) constant node(next) 38 * node ::= byte(NODE_CONSTANT) constant node(next)
39 * | byte(NODE_LET_CONT) int(parameter count) node(next) node(body) 39 * | byte(NODE_LET_CONT) int(parameter count) node(next) node(body)
40 * | byte(NODE_INVOKE_STATIC) element selector 40 * | byte(NODE_INVOKE_STATIC) element selector
41 * reference(continuation) {reference(argument)} 41 * reference(continuation) {reference(argument)}
42 * | byte(NODE_INVOKE_CONTINUATION) reference(continuation) 42 * | byte(NODE_INVOKE_CONTINUATION) reference(continuation)
43 * reference(argument) 43 * {reference(argument)}
44 * 44 *
45 * reference ::= int(indexDelta) 45 * reference ::= int(indexDelta)
46 * 46 *
47 * constant ::= byte(CONST_BOOL) byte(0 or 1) 47 * constant ::= byte(CONST_BOOL) byte(0 or 1)
48 * | byte(CONST_DOUBLE) byte{8} 48 * | byte(CONST_DOUBLE) byte{8}
49 * | byte(CONST_INT) int(value) 49 * | byte(CONST_INT) int(value)
50 * | byte(CONST_STRING_LITERAL) string 50 * | byte(CONST_STRING_LITERAL) string
51 * | byte(CONST_STRING_RAW) string int(length) 51 * | byte(CONST_STRING_RAW) string int(length)
52 * | byte(CONST_STRING_ESCAPED) string int(length) 52 * | byte(CONST_STRING_ESCAPED) string int(length)
53 * | byte(CONST_STRING_CONS) constant(left) constant(right) 53 * | byte(CONST_STRING_CONS) constant(left) constant(right)
54 * | byte(CONST_NULL) 54 * | byte(CONST_NULL)
55 * 55 *
56 * selector ::= byte(BACKREFERENCE) reference 56 * selector ::= byte(BACKREFERENCE) reference
57 * | byte(SELECTOR_UNTYPED) int(kind) string(name) element(library) 57 * | byte(SELECTOR_UNTYPED) int(kind) string(name) element(library)
58 * int(argumentsCount) int(namedArgumentsCount) 58 * int(argumentsCount) int(namedArgumentsCount)
59 * {string(parameterName)} 59 * {string(parameterName)}
60 * 60 *
61 * element ::= int(constantPoolIndex) 61 * element ::= int(constantPoolIndex)
62 */ 62 */
63 class Pickles { 63 class Pickles {
64 static const int BACKREFERENCE = 1; 64 static const int BACKREFERENCE = 1;
65 65
66 static const int STRING_ASCII = BACKREFERENCE + 1; 66 static const int STRING_ASCII = BACKREFERENCE + 1;
67 static const int STRING_UTF8 = STRING_ASCII + 1; 67 static const int STRING_UTF8 = STRING_ASCII + 1;
68 68
69 static const int FIRST_NODE_TAG = STRING_UTF8 + 1; 69 static const int FIRST_NODE_TAG = STRING_UTF8 + 1;
70 static const int NODE_CONSTANT = FIRST_NODE_TAG; 70 static const int NODE_CONSTANT = FIRST_NODE_TAG;
71 static const int NODE_LET_CONT = NODE_CONSTANT + 1; 71 static const int NODE_IS_TRUE = NODE_CONSTANT + 1;
72 static const int NODE_LET_CONT = NODE_IS_TRUE + 1;
72 static const int NODE_INVOKE_STATIC = NODE_LET_CONT + 1; 73 static const int NODE_INVOKE_STATIC = NODE_LET_CONT + 1;
73 static const int NODE_INVOKE_CONTINUATION = NODE_INVOKE_STATIC + 1; 74 static const int NODE_INVOKE_CONTINUATION = NODE_INVOKE_STATIC + 1;
74 static const int LAST_NODE_TAG = NODE_INVOKE_CONTINUATION; 75 static const int NODE_BRANCH = NODE_INVOKE_CONTINUATION + 1;
76 static const int LAST_NODE_TAG = NODE_BRANCH;
75 77
76 static const int FIRST_CONST_TAG = LAST_NODE_TAG + 1; 78 static const int FIRST_CONST_TAG = LAST_NODE_TAG + 1;
77 static const int CONST_BOOL = FIRST_CONST_TAG; 79 static const int CONST_BOOL = FIRST_CONST_TAG;
78 static const int CONST_INT = CONST_BOOL + 1; 80 static const int CONST_INT = CONST_BOOL + 1;
79 static const int CONST_DOUBLE = CONST_INT + 1; 81 static const int CONST_DOUBLE = CONST_INT + 1;
80 static const int CONST_STRING_LITERAL = CONST_DOUBLE + 1; 82 static const int CONST_STRING_LITERAL = CONST_DOUBLE + 1;
81 static const int CONST_STRING_RAW = CONST_STRING_LITERAL + 1; 83 static const int CONST_STRING_RAW = CONST_STRING_LITERAL + 1;
82 static const int CONST_STRING_ESCAPED = CONST_STRING_RAW + 1; 84 static const int CONST_STRING_ESCAPED = CONST_STRING_RAW + 1;
83 static const int CONST_STRING_CONS = CONST_STRING_ESCAPED + 1; 85 static const int CONST_STRING_CONS = CONST_STRING_ESCAPED + 1;
84 static const int CONST_NULL = CONST_STRING_CONS + 1; 86 static const int CONST_NULL = CONST_STRING_CONS + 1;
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
166 * This buffer is used in [writeConstDouble] to obtain a byte representation 168 * This buffer is used in [writeConstDouble] to obtain a byte representation
167 * for doubles. 169 * for doubles.
168 */ 170 */
169 ByteData doubleData = new ByteData(8); 171 ByteData doubleData = new ByteData(8);
170 172
171 List<int> pickle(ir.FunctionDefinition function) { 173 List<int> pickle(ir.FunctionDefinition function) {
172 data = new Uint8List(INITIAL_SIZE); 174 data = new Uint8List(INITIAL_SIZE);
173 offset = 0; 175 offset = 0;
174 emitted = <Object, int>{}; 176 emitted = <Object, int>{};
175 index = 0; 177 index = 0;
176 function.accept(this); 178 visit(function);
177 179
178 int sizeOffset = offset; 180 int sizeOffset = offset;
179 writeInt(emitted.length); 181 writeInt(emitted.length);
180 int sizeBytes = offset - sizeOffset; 182 int sizeBytes = offset - sizeOffset;
181 183
182 // The array is longer than necessary, create a copy with the actual size. 184 // The array is longer than necessary, create a copy with the actual size.
183 Uint8List result = new Uint8List(offset); 185 Uint8List result = new Uint8List(offset);
184 // Emit the number or entries in the beginning. 186 // Emit the number or entries in the beginning.
185 for (int i = 0, j = sizeOffset; i < sizeBytes; i++, j++) { 187 for (int i = 0, j = sizeOffset; i < sizeBytes; i++, j++) {
186 result[i] = data[j]; 188 result[i] = data[j];
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 void recordForBackReference(Object entry) { 277 void recordForBackReference(Object entry) {
276 assert(emitted[entry] == null); 278 assert(emitted[entry] == null);
277 emitted[entry] = index++; 279 emitted[entry] = index++;
278 } 280 }
279 281
280 void writeBackReference(Object entry) { 282 void writeBackReference(Object entry) {
281 int entryIndex = emitted[entry]; 283 int entryIndex = emitted[entry];
282 writeInt(index - entryIndex); 284 writeInt(index - entryIndex);
283 } 285 }
284 286
285 void writeBackReferenceList(List entries) { 287 void writeBackReferenceList(int length, Iterable entries) {
286 writeInt(entries.length); 288 writeInt(length);
287 for (int i = 0; i < entries.length; i++) { 289 for (var x in entries) {
288 writeBackReference(entries[i]); 290 writeBackReference(x);
289 } 291 }
290 } 292 }
291 293
292 void writeConstBool(bool b) { 294 void writeConstBool(bool b) {
293 writeByte(Pickles.CONST_BOOL); 295 writeByte(Pickles.CONST_BOOL);
294 writeByte(b ? 1 : 0); 296 writeByte(b ? 1 : 0);
295 } 297 }
296 298
297 void writeConstInt(int n) { 299 void writeConstInt(int n) {
298 writeByte(Pickles.CONST_INT); 300 writeByte(Pickles.CONST_INT);
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
357 } 359 }
358 360
359 void visitFunctionDefinition(ir.FunctionDefinition node) { 361 void visitFunctionDefinition(ir.FunctionDefinition node) {
360 // The continuation parameter is bound in the body. 362 // The continuation parameter is bound in the body.
361 recordForBackReference(node.returnContinuation); 363 recordForBackReference(node.returnContinuation);
362 writeInt(node.parameters.length); 364 writeInt(node.parameters.length);
363 for (var parameter in node.parameters) { 365 for (var parameter in node.parameters) {
364 recordForBackReference(parameter); 366 recordForBackReference(parameter);
365 writeElement(parameter.element); 367 writeElement(parameter.element);
366 } 368 }
367 node.body.accept(this); 369 visit(node.body);
368 } 370 }
369 371
370 void visitLetPrim(ir.LetPrim node) { 372 void visitLetPrim(ir.LetPrim node) {
371 node.primitive.accept(this); 373 visit(node.primitive);
372 // The right-hand side is bound in the body. 374 // The right-hand side is bound in the body.
373 recordForBackReference(node.primitive); 375 recordForBackReference(node.primitive);
374 node.body.accept(this); 376 visit(node.body);
375 } 377 }
376 378
377 void visitLetCont(ir.LetCont node) { 379 void visitLetCont(ir.LetCont node) {
378 // There are two choices of which expression tree to write first---the 380 // There are two choices of which expression tree to write first---the
379 // continuation body or the LetCont body. The unpickler will unpickle the 381 // continuation body or the LetCont body. The unpickler will unpickle the
380 // the first recursively and the second iteratively. Since the hole in 382 // the first recursively and the second iteratively. Since the hole in
381 // LetCont contexts is in the continuation body, the continuation should be 383 // LetCont contexts is in the continuation body, the continuation should be
382 // written second. 384 // written second.
383 writeByte(Pickles.NODE_LET_CONT); 385 writeByte(Pickles.NODE_LET_CONT);
384 writeInt(node.continuation.parameters.length); 386 writeInt(node.continuation.parameters.length);
385 // The continuation is bound in the body. 387 // The continuation is bound in the body.
386 recordForBackReference(node.continuation); 388 recordForBackReference(node.continuation);
387 node.body.accept(this); 389 visit(node.body);
388 // The continuation parameters are bound in the continuation's body. 390 // The continuation parameters are bound in the continuation's body.
389 node.continuation.parameters.forEach(recordForBackReference); 391 node.continuation.parameters.forEach(recordForBackReference);
390 node.continuation.body.accept(this); 392 visit(node.continuation.body);
391 } 393 }
392 394
393 void visitInvokeStatic(ir.InvokeStatic node) { 395 void visitInvokeStatic(ir.InvokeStatic node) {
394 writeByte(Pickles.NODE_INVOKE_STATIC); 396 writeByte(Pickles.NODE_INVOKE_STATIC);
395 writeElement(node.target); 397 writeElement(node.target);
396 writeSelector(node.selector); 398 writeSelector(node.selector);
397 // TODO(lry): compact encoding when the arity of the selector and the 399 // TODO(lry): compact encoding when the arity of the selector and the
398 // arguments list are the same 400 // arguments list are the same
399 writeBackReference(node.continuation.definition); 401 writeBackReference(node.continuation.definition);
400 writeBackReferenceList(node.arguments.map( 402 writeBackReferenceList(node.arguments.length,
401 (a) => a.definition).toList(growable: false)); 403 node.arguments.map((a) => a.definition));
402 } 404 }
403 405
404 void visitInvokeContinuation(ir.InvokeContinuation node) { 406 void visitInvokeContinuation(ir.InvokeContinuation node) {
405 writeByte(Pickles.NODE_INVOKE_CONTINUATION); 407 writeByte(Pickles.NODE_INVOKE_CONTINUATION);
406 writeBackReference(node.continuation.definition); 408 writeBackReference(node.continuation.definition);
407 writeBackReference(node.argument.definition); 409 writeBackReferenceList(node.arguments.length,
410 node.arguments.map((a) => a.definition));
411 }
412
413 void visitBranch(ir.Branch node) {
414 writeByte(Pickles.NODE_BRANCH);
415 visit(node.condition);
416 writeBackReference(node.trueContinuation.definition);
417 writeBackReference(node.falseContinuation.definition);
408 } 418 }
409 419
410 void visitConstant(ir.Constant node) { 420 void visitConstant(ir.Constant node) {
411 writeByte(Pickles.NODE_CONSTANT); 421 writeByte(Pickles.NODE_CONSTANT);
412 node.value.accept(constantPickler); 422 node.value.accept(constantPickler);
413 } 423 }
414 424
425 void visitIsTrue(ir.IsTrue node) {
426 writeByte(Pickles.NODE_IS_TRUE);
427 writeBackReference(node.value.definition);
428 }
429
415 void visitNode(ir.Node node) { 430 void visitNode(ir.Node node) {
416 throw "Unexpected $node in pickler."; 431 throw "Unexpected $node in pickler.";
417 } 432 }
418 } 433 }
419 434
420 /** 435 /**
421 * A visitor for constants which writes the constant values to its [Pickler]. 436 * A visitor for constants which writes the constant values to its [Pickler].
422 */ 437 */
423 class ConstantPickler extends ConstantVisitor { 438 class ConstantPickler extends ConstantVisitor {
424 439
(...skipping 27 matching lines...) Expand all
452 void visitList(ListConstant constant) => abort(constant); 467 void visitList(ListConstant constant) => abort(constant);
453 void visitMap(MapConstant constant) => abort(constant); 468 void visitMap(MapConstant constant) => abort(constant);
454 void visitInterceptor(InterceptorConstant constant) => abort(constant); 469 void visitInterceptor(InterceptorConstant constant) => abort(constant);
455 void visitDummy(DummyConstant constant) => abort(constant); 470 void visitDummy(DummyConstant constant) => abort(constant);
456 void visitFunction(FunctionConstant constant) => abort(constant); 471 void visitFunction(FunctionConstant constant) => abort(constant);
457 void visitType(TypeConstant constant) => abort(constant); 472 void visitType(TypeConstant constant) => abort(constant);
458 void visitConstructed(ConstructedConstant constant) => abort(constant); 473 void visitConstructed(ConstructedConstant constant) => abort(constant);
459 474
460 void abort(Constant value) => throw "Can not pickle constant $value"; 475 void abort(Constant value) => throw "Can not pickle constant $value";
461 } 476 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698