Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 '../../dart_types.dart' show DartType; | 8 import '../../dart_types.dart' show DartType; |
| 9 import '../../elements/elements.dart' show ClassElement; | 9 import '../../elements/elements.dart' show ClassElement; |
| 10 import '../../js/js.dart' as js; | 10 import '../../js/js.dart' as js; |
| (...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 500 assert(field.isLazy); | 500 assert(field.isLazy); |
| 501 return unparse(compiler, field.code); | 501 return unparse(compiler, field.code); |
| 502 } | 502 } |
| 503 | 503 |
| 504 /// JavaScript code template that implements parsing of a function descriptor. | 504 /// JavaScript code template that implements parsing of a function descriptor. |
| 505 /// Descriptors are used in place of the actual JavaScript function | 505 /// Descriptors are used in place of the actual JavaScript function |
| 506 /// definition in the output if additional information needs to be passed to | 506 /// definition in the output if additional information needs to be passed to |
| 507 /// facilitate the generation of tearOffs at runtime. The format is an array | 507 /// facilitate the generation of tearOffs at runtime. The format is an array |
| 508 /// with the following fields: | 508 /// with the following fields: |
| 509 /// | 509 /// |
| 510 /// [InstanceMethod.aliasName] (optional). | |
| 510 /// [Method.code] | 511 /// [Method.code] |
| 511 /// [DartMethod.callName] | 512 /// [DartMethod.callName] |
| 513 /// [JavaScriptBackend.isInterceptedMethod] | |
|
floitsch
2015/02/09 16:04:24
No need to drag "JavaScriptBackend" into this.
jus
floitsch
2015/02/09 16:04:24
That one is optional too, no?
zarah
2015/02/10 09:07:17
yes, added a comment to the following two as well.
zarah
2015/02/10 09:07:17
Done.
| |
| 512 /// [DartMethod.tearOffName] | 514 /// [DartMethod.tearOffName] |
| 513 /// [JavaScriptBackend.isInterceptedMethod] | |
| 514 /// functionType | 515 /// functionType |
| 515 /// [InstanceMethod.aliasName] | |
| 516 /// | 516 /// |
| 517 /// followed by | 517 /// followed by |
| 518 /// | 518 /// |
| 519 /// [ParameterStubMethod.name] | 519 /// [ParameterStubMethod.name] |
| 520 /// [ParameterStubMethod.code] | 520 /// [ParameterStubMethod.code] |
| 521 /// | 521 /// |
| 522 /// for each stub in [DartMethod.parameterStubs]. | 522 /// for each stub in [DartMethod.parameterStubs]. |
| 523 | 523 |
| 524 static final String parseFunctionDescriptorBoilerplate = r""" | 524 static final String parseFunctionDescriptorBoilerplate = r""" |
| 525 function parseFunctionDescriptor(proto, name, descriptor) { | 525 function parseFunctionDescriptor(proto, name, descriptor) { |
| 526 if (descriptor instanceof Array) { | 526 if (descriptor instanceof Array) { |
| 527 proto[name] = descriptor[0]; | 527 var f, pos = -1; |
|
floitsch
2015/02/09 16:04:24
// `pos` points to the last read entry.
zarah
2015/02/10 09:07:17
Done.
| |
| 528 var funs = [descriptor[0]]; | 528 var aliasOrFunction = descriptor[++pos]; |
| 529 funs[0].$callName = descriptor[1]; | 529 if (typeof aliasOrFunction == "string") { |
| 530 for (var pos = 6; pos < descriptor.length; pos += 3) { | 530 // Install the alias for super calls on the prototype chain. |
| 531 proto[aliasOrFunction] = f = descriptor[++pos]; | |
| 532 } else { | |
| 533 f = aliasOrFunction; | |
| 534 } | |
| 535 | |
| 536 proto[name] = f; | |
| 537 var funs = [f]; | |
| 538 funs[0].$callName = descriptor[++pos]; | |
|
floitsch
2015/02/09 16:04:24
might as well use "f" directly here.
zarah
2015/02/10 09:07:17
Done.
| |
| 539 | |
| 540 | |
| 541 var isInterceptedOrParameterStubName = descriptor[pos + 1]; | |
| 542 var isIntercepted, tearOffName, reflectionInfo; | |
| 543 if (typeof isInterceptedOrParameterStubName == "boolean") { | |
| 544 isIntercepted = descriptor[++pos]; | |
| 545 tearOffName = descriptor[++pos]; | |
| 546 reflectionInfo = descriptor[++pos]; | |
| 547 } | |
| 548 | |
| 549 for (++pos; pos < descriptor.length; pos += 3) { | |
| 531 var stub = descriptor[pos + 2]; | 550 var stub = descriptor[pos + 2]; |
| 532 stub.$callName = descriptor[pos + 1]; | 551 stub.$callName = descriptor[pos + 1]; |
| 533 proto[descriptor[pos]] = stub; | 552 proto[descriptor[pos]] = stub; |
| 534 funs.push(stub); | 553 funs.push(stub); |
| 535 } | 554 } |
| 536 if (descriptor[2] != null) { | 555 |
| 537 var isIntercepted = descriptor[3]; | 556 if (tearOffName) { |
| 538 var reflectionInfo = descriptor[4]; | 557 proto[tearOffName] = |
| 539 proto[descriptor[2]] = | |
| 540 tearOff(funs, reflectionInfo, false, name, isIntercepted); | 558 tearOff(funs, reflectionInfo, false, name, isIntercepted); |
| 541 } | 559 } |
| 542 // Install the alias for super calls on the prototype chain. | 560 |
| 543 if (descriptor[5] != null) { | |
| 544 proto[descriptor[5]] = descriptor[0]; | |
| 545 } | |
| 546 } else { | 561 } else { |
| 547 proto[name] = descriptor; | 562 proto[name] = descriptor; |
| 548 } | 563 } |
| 549 } | 564 } |
| 550 """; | 565 """; |
| 551 | 566 |
| 552 js.Expression _generateFunctionType(DartType memberType) { | 567 js.Expression _generateFunctionType(DartType memberType) { |
| 553 if (memberType.containsTypeVariables) { | 568 if (memberType.containsTypeVariables) { |
| 554 js.Expression thisAccess = js.js(r'this.$receiver'); | 569 js.Expression thisAccess = js.js(r'this.$receiver'); |
| 555 return backend.rti.getSignatureEncoding(memberType, thisAccess); | 570 return backend.rti.getSignatureEncoding(memberType, thisAccess); |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 568 js.Expression callName = stub.callName == null | 583 js.Expression callName = stub.callName == null |
| 569 ? new js.LiteralNull() | 584 ? new js.LiteralNull() |
| 570 : js.string(stub.callName); | 585 : js.string(stub.callName); |
| 571 return [js.string(stub.name), callName, stub.code]; | 586 return [js.string(stub.name), callName, stub.code]; |
| 572 } | 587 } |
| 573 | 588 |
| 574 if (method is InstanceMethod) { | 589 if (method is InstanceMethod) { |
| 575 if (method.needsTearOff || method.aliasName != null) { | 590 if (method.needsTearOff || method.aliasName != null) { |
| 576 /// See [parseFunctionDescriptorBoilerplate] for a full description of | 591 /// See [parseFunctionDescriptorBoilerplate] for a full description of |
| 577 /// the format. | 592 /// the format. |
| 578 // [name, [function, callName, tearOffName, isIntercepted, functionType, | 593 // [name, [aliasName, function, callName, isIntercepted, tearOffName, |
| 579 // aliasName, stub1_name, stub1_callName, stub1_code, ...] | 594 // functionType, stub1_name, stub1_callName, stub1_code, ...] |
| 580 bool isIntercepted = backend.isInterceptedMethod(method.element); | 595 var data = []; |
| 581 var data = [method.code]; | |
| 582 data.add(js.string(method.callName)); | |
| 583 data.add(js.string(method.tearOffName)); | |
| 584 data.add(new js.LiteralBool(isIntercepted)); | |
| 585 data.add(_generateFunctionType(method.type)); | |
| 586 if (method.aliasName != null) { | 596 if (method.aliasName != null) { |
| 587 data.add(js.string(method.aliasName)); | 597 data.add(js.string(method.aliasName)); |
| 588 } else { | |
| 589 data.add(new js.LiteralNull()); | |
| 590 } | 598 } |
| 599 data.add(method.code); | |
| 600 data.add(js.string(method.callName)); | |
| 601 | |
| 602 if (method.needsTearOff) { | |
| 603 bool isIntercepted = backend.isInterceptedMethod(method.element); | |
| 604 data.add(new js.LiteralBool(isIntercepted)); | |
| 605 data.add(js.string(method.tearOffName)); | |
| 606 data.add(_generateFunctionType(method.type)); | |
| 607 } | |
| 608 | |
| 591 data.addAll(method.parameterStubs.expand(makeNameCallNameCodeTriplet)); | 609 data.addAll(method.parameterStubs.expand(makeNameCallNameCodeTriplet)); |
| 592 return [js.string(method.name), new js.ArrayInitializer(data)]; | 610 return [js.string(method.name), new js.ArrayInitializer(data)]; |
| 593 } else { | 611 } else { |
| 594 // TODO(floitsch): not the most efficient way... | 612 // TODO(floitsch): not the most efficient way... |
| 595 return ([method]..addAll(method.parameterStubs)) | 613 return ([method]..addAll(method.parameterStubs)) |
| 596 .expand(makeNameCodePair); | 614 .expand(makeNameCodePair); |
| 597 } | 615 } |
| 598 } else { | 616 } else { |
| 599 return makeNameCodePair(method); | 617 return makeNameCodePair(method); |
| 600 } | 618 } |
| (...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 913 | 931 |
| 914 var end = Date.now(); | 932 var end = Date.now(); |
| 915 print('Setup: ' + (end - start) + ' ms.'); | 933 print('Setup: ' + (end - start) + ' ms.'); |
| 916 | 934 |
| 917 #main(); // Start main. | 935 #main(); // Start main. |
| 918 | 936 |
| 919 }(Date.now(), #code) | 937 }(Date.now(), #code) |
| 920 }"""; | 938 }"""; |
| 921 | 939 |
| 922 } | 940 } |
| OLD | NEW |