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

Side by Side Diff: pkg/compiler/lib/src/js_emitter/new_emitter/model_emitter.dart

Issue 889703004: dart2js: emit tear-offs in new emitter. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Incorporated Stephan's CL + fixes. Created 5 years, 10 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) 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 library dart2js.new_js_emitter.model_emitter; 5 library dart2js.new_js_emitter.model_emitter;
6 6
7 import '../../dart2jslib.dart' show Compiler; 7 import '../../dart2jslib.dart' show Compiler;
8 import '../../js/js.dart' as js; 8 import '../../js/js.dart' as js;
9 import '../../js_backend/js_backend.dart' show 9 import '../../js_backend/js_backend.dart' show
10 JavaScriptBackend, 10 JavaScriptBackend,
11 Namer, 11 Namer,
12 ConstantEmitter; 12 ConstantEmitter;
13 13
14 import 'package:_internal/compiler/js_lib/shared/embedded_names.dart' show 14 import 'package:_internal/compiler/js_lib/shared/embedded_names.dart' show
15 DEFERRED_LIBRARY_URIS, 15 DEFERRED_LIBRARY_URIS,
16 DEFERRED_LIBRARY_HASHES, 16 DEFERRED_LIBRARY_HASHES,
17 GET_TYPE_FROM_NAME, 17 GET_TYPE_FROM_NAME,
18 INITIALIZE_LOADED_HUNK, 18 INITIALIZE_LOADED_HUNK,
19 IS_HUNK_INITIALIZED, 19 IS_HUNK_INITIALIZED,
20 IS_HUNK_LOADED, 20 IS_HUNK_LOADED,
21 MANGLED_GLOBAL_NAMES, 21 MANGLED_GLOBAL_NAMES,
22 METADATA, 22 METADATA,
23 TYPE_TO_INTERCEPTOR_MAP; 23 TYPE_TO_INTERCEPTOR_MAP;
24 24
25 import '../js_emitter.dart' show NativeGenerator; 25 import '../js_emitter.dart' show NativeGenerator, buildTearOffCode;
26 import '../model.dart'; 26 import '../model.dart';
27 27
28 class ModelEmitter { 28 class ModelEmitter {
29 final Compiler compiler; 29 final Compiler compiler;
30 final Namer namer; 30 final Namer namer;
31 final ConstantEmitter constantEmitter; 31 final ConstantEmitter constantEmitter;
32 32
33 JavaScriptBackend get backend => compiler.backend; 33 JavaScriptBackend get backend => compiler.backend;
34 34
35 /// For deferred loading we communicate the initializers via this global var. 35 /// For deferred loading we communicate the initializers via this global var.
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
101 } else { 101 } else {
102 nativeBoilerplate = js.js.statement(";"); 102 nativeBoilerplate = js.js.statement(";");
103 } 103 }
104 104
105 js.Expression code = new js.ArrayInitializer(elements); 105 js.Expression code = new js.ArrayInitializer(elements);
106 106
107 return js.js.statement( 107 return js.js.statement(
108 boilerplate, 108 boilerplate,
109 {'deferredInitializer': emitDeferredInitializerGlobal(program.loadMap), 109 {'deferredInitializer': emitDeferredInitializerGlobal(program.loadMap),
110 'holders': emitHolders(fragment.holders), 110 'holders': emitHolders(fragment.holders),
111 'tearOff': buildTearOffCode(backend),
112 'parseFunctionDescriptor':
113 js.js.statement(parseFunctionDescriptorBoilerplate),
111 'cyclicThrow': 114 'cyclicThrow':
112 backend.emitter.staticFunctionAccess(backend.getCyclicThrowHelper()), 115 backend.emitter.staticFunctionAccess(backend.getCyclicThrowHelper()),
113 'outputContainsConstantList': program.outputContainsConstantList, 116 'outputContainsConstantList': program.outputContainsConstantList,
114 'embeddedGlobals': emitEmbeddedGlobals(program), 117 'embeddedGlobals': emitEmbeddedGlobals(program),
115 'constants': emitConstants(fragment.constants), 118 'constants': emitConstants(fragment.constants),
116 'staticNonFinals': 119 'staticNonFinals':
117 emitStaticNonFinalFields(fragment.staticNonFinalFields), 120 emitStaticNonFinalFields(fragment.staticNonFinalFields),
118 'nativeBoilerplate': nativeBoilerplate, 121 'nativeBoilerplate': nativeBoilerplate,
119 'operatorIsPrefix': js.string(namer.operatorIsPrefix), 122 'operatorIsPrefix': js.string(namer.operatorIsPrefix),
120 'eagerClasses': emitEagerClassInitializations(fragment.libraries), 123 'eagerClasses': emitEagerClassInitializations(fragment.libraries),
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after
388 List elements = [js.string(cls.superclassName), 391 List elements = [js.string(cls.superclassName),
389 js.number(cls.superclassHolderIndex)]; 392 js.number(cls.superclassHolderIndex)];
390 393
391 if (cls.isMixinApplication) { 394 if (cls.isMixinApplication) {
392 MixinApplication mixin = cls; 395 MixinApplication mixin = cls;
393 elements.add(js.string(mixin.mixinClass.name)); 396 elements.add(js.string(mixin.mixinClass.name));
394 elements.add(js.number(mixin.mixinClass.holder.index)); 397 elements.add(js.number(mixin.mixinClass.holder.index));
395 } else { 398 } else {
396 elements.add(_generateConstructor(cls)); 399 elements.add(_generateConstructor(cls));
397 } 400 }
398 Iterable<Method> methods = cls.methods.expand((Method method) { 401 Iterable<Method> methods = cls.methods;
399 // TODO(floitsch): can there be anything else than a DartMethod?
400 if (method is DartMethod) {
401 return [method]..addAll(method.parameterStubs);
402 } else {
403 return [method];
404 }
405 });
406 Iterable<Method> isChecks = cls.isChecks; 402 Iterable<Method> isChecks = cls.isChecks;
407 Iterable<Method> gettersSetters = _generateGettersSetters(cls); 403 Iterable<Method> gettersSetters = _generateGettersSetters(cls);
408 Iterable<Method> allMethods = 404 Iterable<Method> allMethods =
409 [methods, isChecks, gettersSetters].expand((x) => x); 405 [methods, isChecks, gettersSetters].expand((x) => x);
410 elements.addAll(allMethods.expand((e) => [js.string(e.name), e.code])); 406 elements.addAll(allMethods.expand(emitInstanceMethod));
411 return unparse(compiler, new js.ArrayInitializer(elements)); 407 return unparse(compiler, new js.ArrayInitializer(elements));
412 } 408 }
413 409
414 js.Expression emitLazyInitializer(StaticField field) { 410 js.Expression emitLazyInitializer(StaticField field) {
415 assert(field.isLazy); 411 assert(field.isLazy);
416 return unparse(compiler, field.code); 412 return unparse(compiler, field.code);
417 } 413 }
418 414
415 static final String parseFunctionDescriptorBoilerplate = r"""
416 function parseFunctionDescriptor(proto, name, desc) {
417 if (desc instanceof Array) {
zarah 2015/02/02 08:20:10 It would be nice with a comment here describing th
418 proto[name] = desc[0];
419 var funs = [desc[0]];
420 funs[0].$callName = desc[1];
421 for (var pos = 4; pos < desc.length; pos += 3) {
422 var stub = desc[pos+2];
423 stub.$callName = desc[pos+1];
424 proto[desc[pos]] = stub;
425 funs.push(stub);
426 }
427 if (desc[2] != null) {
428 // TODO(floitsch): desc[3] should be the reflectionInfo, not
429 // isIntercepted.
430 var isIntercepted = desc[3];
431 var reflectionInfo = null;
432 proto[desc[2]] = tearOff(funs, reflectionInfo, false, name, isIntercepted) ;
433 }
434 } else {
435 proto[name] = desc;
436 }
437 }
438 """;
439
440 Iterable<js.Expression> emitInstanceMethod(Method method) {
441
442 List<js.Expression> makeNameCodePair(Method method) {
443 return [js.string(method.name), method.code];
444 }
445
446 List<js.Expression> makeNameCallNameCodeTriplet(ParameterStubMethod stub) {
447 js.Expression callName = stub.callName == null
448 ? new js.LiteralNull()
449 : js.string(stub.callName);
450 return [js.string(stub.name), callName, stub.code];
451 }
452
453 if (method is DartMethod) {
454 if (method.needsTearOff) {
455 bool isIntercepted = backend.isInterceptedMethod(method.element);
456 // [name, [function, callName, tearOffName, functionType,
457 // stub1_name, stub1_callName, stub1_code, ...]
458 var data = [method.code];
459 data.add(js.string(method.callName));
460 data.add(js.string(method.tearOffName));
461 // TODO(floitsch): this field should be the type, not the bool if the
462 // method is intercepted.
463 // data.add(new js.LiteralNull());
464 data.add(new js.LiteralBool(isIntercepted));
465 data.addAll(method.parameterStubs.expand(makeNameCallNameCodeTriplet));
466 return [js.string(method.name), new js.ArrayInitializer(data)];
467 } else {
468 // TODO(floitsch): not the most efficient way...
469 return ([method]..addAll(method.parameterStubs)).expand(makeNameCodePair );
zarah 2015/02/02 08:20:11 long line.
470 }
471 } else {
472 return makeNameCodePair(method);
473 }
474 }
475
419 Iterable<js.Expression> emitStaticMethod(StaticMethod method) { 476 Iterable<js.Expression> emitStaticMethod(StaticMethod method) {
420 js.Expression holderIndex = js.number(method.holder.index); 477 js.Expression holderIndex = js.number(method.holder.index);
421 List<js.Expression> output = <js.Expression>[]; 478 List<js.Expression> output = <js.Expression>[];
422 479
423 void _addMethod(Method method) { 480 void _addMethod(Method method) {
424 js.Expression unparsed = unparse(compiler, method.code); 481 js.Expression unparsed = unparse(compiler, method.code);
425 output.add(js.string(method.name)); 482 output.add(js.string(method.name));
426 output.add(holderIndex); 483 output.add(holderIndex);
427 output.add(unparsed); 484 output.add(unparsed);
428 } 485 }
429 486
430 _addMethod(method); 487 _addMethod(method);
431 // TODO(floitsch): can there be anything else than a StaticDartMethod? 488 // TODO(floitsch): can there be anything else than a StaticDartMethod?
432 if (method is StaticDartMethod) { 489 if (method is StaticDartMethod) {
433 method.parameterStubs.forEach(_addMethod); 490 method.parameterStubs.forEach(_addMethod);
434 } 491 }
435 return output; 492 return output;
436 } 493 }
437 494
438 static final String boilerplate = """ 495 static final String boilerplate = """
439 { 496 {
440 // Declare deferred-initializer global. 497 // Declare deferred-initializer global.
441 #deferredInitializer; 498 #deferredInitializer;
442 499
443 !function(start, program) { 500 !function(start, program) {
444 501 var functionCounter = 0;
445 // Initialize holder objects. 502 // Initialize holder objects.
446 #holders; 503 #holders;
447 504
448 function setupProgram() { 505 function setupProgram() {
449 for (var i = 0; i < program.length - 1; i++) { 506 for (var i = 0; i < program.length - 1; i++) {
450 setupLibrary(program[i]); 507 setupLibrary(program[i]);
451 } 508 }
452 setupLazyStatics(program[i]); 509 setupLazyStatics(program[i]);
453 } 510 }
454 511
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
523 constructor.apply(object, arguments); 580 constructor.apply(object, arguments);
524 return object; 581 return object;
525 }; 582 };
526 583
527 // We store the ensureResolved function on the patch function to make it 584 // We store the ensureResolved function on the patch function to make it
528 // possible to resolve superclass references without constructing instances. 585 // possible to resolve superclass references without constructing instances.
529 patch.ensureResolved = ensureResolved; 586 patch.ensureResolved = ensureResolved;
530 holder[name] = patch; 587 holder[name] = patch;
531 } 588 }
532 589
590 #tearOff;
591
592 #parseFunctionDescriptor;
593
533 function compileConstructor(name, descriptor) { 594 function compileConstructor(name, descriptor) {
534 descriptor = compile(name, descriptor); 595 descriptor = compile(name, descriptor);
535 var prototype = determinePrototype(descriptor); 596 var prototype = determinePrototype(descriptor);
536 var constructor; 597 var constructor;
537 // $mixinFormatDescription. 598 // $mixinFormatDescription.
538 if (typeof descriptor[2] !== 'function') { 599 if (typeof descriptor[2] !== 'function') {
539 constructor = compileMixinConstructor(name, prototype, descriptor); 600 constructor = compileMixinConstructor(name, prototype, descriptor);
540 for (var i = 4; i < descriptor.length; i += 2) { 601 for (var i = 4; i < descriptor.length; i += 2) {
541 prototype[descriptor[i]] = descriptor[i + 1]; 602 parseFunctionDescriptor(prototype, descriptor);
542 } 603 }
543 } else { 604 } else {
544 constructor = descriptor[2]; 605 constructor = descriptor[2];
545 for (var i = 3; i < descriptor.length; i += 2) { 606 for (var i = 3; i < descriptor.length; i += 2) {
546 prototype[descriptor[i]] = descriptor[i + 1]; 607 parseFunctionDescriptor(prototype, descriptor[i], descriptor[i+1]);
547 } 608 }
548 } 609 }
549 constructor.builtin\$cls = name; // Needed for RTI. 610 constructor.builtin\$cls = name; // Needed for RTI.
550 constructor.prototype = prototype; 611 constructor.prototype = prototype;
551 prototype[#operatorIsPrefix + name] = constructor; 612 prototype[#operatorIsPrefix + name] = constructor;
552 prototype.constructor = constructor; 613 prototype.constructor = constructor;
553 return constructor; 614 return constructor;
554 } 615 }
555 616
556 function compileMixinConstructor(name, prototype, descriptor) { 617 function compileMixinConstructor(name, prototype, descriptor) {
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
623 684
624 var end = Date.now(); 685 var end = Date.now();
625 print('Setup: ' + (end - start) + ' ms.'); 686 print('Setup: ' + (end - start) + ' ms.');
626 687
627 #main(); // Start main. 688 #main(); // Start main.
628 689
629 }(Date.now(), #code) 690 }(Date.now(), #code)
630 }"""; 691 }""";
631 692
632 } 693 }
OLDNEW
« no previous file with comments | « no previous file | sdk/lib/_internal/compiler/js_lib/js_helper.dart » ('j') | sdk/lib/_internal/compiler/js_lib/js_helper.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698