| OLD | NEW |
| 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 part of dart2js.js_emitter; | 5 part of dart2js.js_emitter; |
| 6 | 6 |
| 7 /// This class should morph into something that makes it easy to build | 7 /// This class should morph into something that makes it easy to build |
| 8 /// JavaScript representations of libraries, class-sides, and instance-sides. | 8 /// JavaScript representations of libraries, class-sides, and instance-sides. |
| 9 /// Initially, it is just a placeholder for code that is moved from | 9 /// Initially, it is just a placeholder for code that is moved from |
| 10 /// [CodeEmitterTask]. | 10 /// [CodeEmitterTask]. |
| (...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 381 } | 381 } |
| 382 } else { | 382 } else { |
| 383 canTearOff = | 383 canTearOff = |
| 384 compiler.codegenWorld.staticFunctionsNeedingGetter.contains(member) || | 384 compiler.codegenWorld.staticFunctionsNeedingGetter.contains(member) || |
| 385 canBeReflected; | 385 canBeReflected; |
| 386 tearOffName = namer.getStaticClosureName(member); | 386 tearOffName = namer.getStaticClosureName(member); |
| 387 } | 387 } |
| 388 final bool canBeApplied = compiler.enabledFunctionApply && | 388 final bool canBeApplied = compiler.enabledFunctionApply && |
| 389 compiler.world.getMightBePassedToApply(member); | 389 compiler.world.getMightBePassedToApply(member); |
| 390 | 390 |
| 391 final bool hasSuperAlias = backend.isAliasedSuperMember(member); |
| 392 |
| 391 final bool needStructuredInfo = | 393 final bool needStructuredInfo = |
| 392 canTearOff || canBeReflected || canBeApplied; | 394 canTearOff || canBeReflected || canBeApplied || hasSuperAlias; |
| 395 |
| 393 | 396 |
| 394 if (canTearOff) { | 397 if (canTearOff) { |
| 395 assert(invariant(member, !member.isGenerativeConstructor)); | 398 assert(invariant(member, !member.isGenerativeConstructor)); |
| 396 assert(invariant(member, !member.isGenerativeConstructorBody)); | 399 assert(invariant(member, !member.isGenerativeConstructorBody)); |
| 397 assert(invariant(member, !member.isConstructor)); | 400 assert(invariant(member, !member.isConstructor)); |
| 398 } | 401 } |
| 399 | 402 |
| 400 return new MemberInfo( | 403 return new MemberInfo( |
| 401 member, | 404 member, |
| 402 name, | 405 name, |
| 403 parameters, | 406 parameters, |
| 404 code, | 407 code, |
| 405 needsStubs: needsStubs, | 408 needsStubs: needsStubs, |
| 406 canTearOff: canTearOff, | 409 canTearOff: canTearOff, |
| 407 isClosure: isClosure, | 410 isClosure: isClosure, |
| 408 tearOffName: tearOffName, | 411 tearOffName: tearOffName, |
| 409 canBeReflected: canBeReflected, | 412 canBeReflected: canBeReflected, |
| 410 canBeApplied: canBeApplied, | 413 canBeApplied: canBeApplied, |
| 411 needStructuredInfo: needStructuredInfo); | 414 hasSuperAlias: hasSuperAlias, |
| 412 | 415 needStructuredInfo: needStructuredInfo |
| 416 ); |
| 413 } | 417 } |
| 414 | 418 |
| 415 void addMemberMethodFromInfo(MemberInfo info, ClassBuilder builder) { | 419 void addMemberMethodFromInfo(MemberInfo info, ClassBuilder builder) { |
| 416 final FunctionElement member = info.member; | 420 final FunctionElement member = info.member; |
| 417 final String name = info.name; | 421 String name = info.name; |
| 418 final FunctionSignature parameters = info.parameters; | 422 final FunctionSignature parameters = info.parameters; |
| 419 jsAst.Expression code = info.code; | 423 jsAst.Expression code = info.code; |
| 420 final bool needsStubs = info.needsStubs; | 424 final bool needsStubs = info.needsStubs; |
| 421 final bool canTearOff = info.canTearOff; | 425 final bool canTearOff = info.canTearOff; |
| 422 final bool isClosure = info.isClosure; | 426 final bool isClosure = info.isClosure; |
| 423 final String tearOffName = info.tearOffName; | 427 final String tearOffName = info.tearOffName; |
| 424 final bool canBeReflected = info.canBeReflected; | 428 final bool canBeReflected = info.canBeReflected; |
| 425 final bool canBeApplied = info.canBeApplied; | 429 final bool canBeApplied = info.canBeApplied; |
| 426 final bool needStructuredInfo = info.needStructuredInfo; | 430 final bool needStructuredInfo = info.needStructuredInfo; |
| 431 final bool hasSuperAlias = info.hasSuperAlias; |
| 427 | 432 |
| 428 emitter.interceptorEmitter.recordMangledNameOfMemberMethod(member, name); | 433 emitter.interceptorEmitter.recordMangledNameOfMemberMethod(member, name); |
| 429 | 434 |
| 430 if (!needStructuredInfo) { | 435 if (!needStructuredInfo) { |
| 431 compiler.dumpInfoTask.registerElementAst(member, | 436 compiler.dumpInfoTask.registerElementAst(member, |
| 432 builder.addProperty(name, code)); | 437 builder.addProperty(name, code)); |
| 433 if (needsStubs) { | 438 if (needsStubs) { |
| 434 addParameterStubs( | 439 addParameterStubs( |
| 435 member, | 440 member, |
| 436 (Selector selector, jsAst.Fun function) { | 441 (Selector selector, jsAst.Fun function) { |
| 437 compiler.dumpInfoTask.registerElementAst(member, | 442 compiler.dumpInfoTask.registerElementAst(member, |
| 438 builder.addProperty(namer.invocationName(selector), function))
; | 443 builder.addProperty(namer.invocationName(selector), |
| 444 function)); |
| 439 }); | 445 }); |
| 440 } | 446 } |
| 441 return; | 447 return; |
| 442 } | 448 } |
| 443 | 449 |
| 444 | 450 |
| 445 // This element is needed for reflection or needs additional stubs. So we | 451 // This element is needed for reflection or needs additional stubs or has a |
| 446 // need to retain additional information. | 452 // super alias. So we need to retain additional information. |
| 447 | 453 |
| 448 // The information is stored in an array with this format: | 454 // The information is stored in an array with this format: |
| 449 // | 455 // |
| 450 // 1. The JS function for this member. | 456 // 1. The alias name for this function (optional). |
| 451 // 2. First stub. | 457 // 2. The JS function for this member. |
| 452 // 3. Name of first stub. | 458 // 3. First stub. |
| 459 // 4. Name of first stub. |
| 453 // ... | 460 // ... |
| 454 // M. Call name of this member. | 461 // M. Call name of this member. |
| 455 // M+1. Call name of first stub. | 462 // M+1. Call name of first stub. |
| 456 // ... | 463 // ... |
| 457 // N. Getter name for tearOff. | 464 // N. Getter name for tearOff. |
| 458 // N+1. (Required parameter count << 1) + (member.isAccessor ? 1 : 0). | 465 // N+1. (Required parameter count << 1) + (member.isAccessor ? 1 : 0). |
| 459 // N+2. (Optional parameter count << 1) + | 466 // N+2. (Optional parameter count << 1) + |
| 460 // (parameters.optionalParametersAreNamed ? 1 : 0). | 467 // (parameters.optionalParametersAreNamed ? 1 : 0). |
| 461 // N+3. Index to function type in constant pool. | 468 // N+3. Index to function type in constant pool. |
| 462 // N+4. First default argument. | 469 // N+4. First default argument. |
| 463 // ... | 470 // ... |
| 464 // O. First parameter name (if needed for reflection or Function.apply). | 471 // O. First parameter name (if needed for reflection or Function.apply). |
| 465 // ... | 472 // ... |
| 466 // P. Unmangled name (if reflectable). | 473 // P. Unmangled name (if reflectable). |
| 467 // P+1. First metadata (if reflectable). | 474 // P+1. First metadata (if reflectable). |
| 468 // ... | 475 // ... |
| 469 // TODO(ahe): Consider one of the parameter counts can be replaced by the | 476 // TODO(ahe): Consider one of the parameter counts can be replaced by the |
| 470 // length property of the JavaScript function object. | 477 // length property of the JavaScript function object. |
| 471 | 478 |
| 472 List<jsAst.Expression> expressions = <jsAst.Expression>[]; | 479 List<jsAst.Expression> expressions = <jsAst.Expression>[]; |
| 473 | 480 |
| 481 // Create the optional aliasing entry if this method is called via super. |
| 482 if (backend.isAliasedSuperMember(member)) { |
| 483 expressions.add(new jsAst.LiteralString( |
| 484 '"${namer.getNameOfAliasedSuperMember(member)}"')); |
| 485 } |
| 486 |
| 487 expressions.add(code); |
| 488 |
| 489 final bool onlyNeedsSuperAlias = |
| 490 !(canTearOff || canBeReflected || canBeApplied || needsStubs); |
| 491 |
| 492 if (onlyNeedsSuperAlias) { |
| 493 jsAst.ArrayInitializer arrayInit = |
| 494 new jsAst.ArrayInitializer.from(expressions); |
| 495 compiler.dumpInfoTask.registerElementAst(member, |
| 496 builder.addProperty(name, arrayInit)); |
| 497 return; |
| 498 } |
| 499 |
| 474 String callSelectorString = 'null'; | 500 String callSelectorString = 'null'; |
| 475 if (member.isFunction) { | 501 if (member.isFunction) { |
| 476 Selector callSelector = new Selector.fromElement(member).toCallSelector(); | 502 Selector callSelector = new Selector.fromElement(member).toCallSelector(); |
| 477 callSelectorString = '"${namer.invocationName(callSelector)}"'; | 503 callSelectorString = '"${namer.invocationName(callSelector)}"'; |
| 478 } | 504 } |
| 479 | 505 |
| 480 // On [requiredParameterCount], the lower bit is set if this method can be | 506 // On [requiredParameterCount], the lower bit is set if this method can be |
| 481 // called reflectively. | 507 // called reflectively. |
| 482 int requiredParameterCount = parameters.requiredParameterCount << 1; | 508 int requiredParameterCount = parameters.requiredParameterCount << 1; |
| 483 if (member.isAccessor) requiredParameterCount++; | 509 if (member.isAccessor) requiredParameterCount++; |
| 484 | 510 |
| 485 int optionalParameterCount = parameters.optionalParameterCount << 1; | 511 int optionalParameterCount = parameters.optionalParameterCount << 1; |
| 486 if (parameters.optionalParametersAreNamed) optionalParameterCount++; | 512 if (parameters.optionalParametersAreNamed) optionalParameterCount++; |
| 487 | 513 |
| 488 expressions.add(code); | |
| 489 | |
| 490 // TODO(sra): Don't use LiteralString for non-strings. | 514 // TODO(sra): Don't use LiteralString for non-strings. |
| 491 List tearOffInfo = [new jsAst.LiteralString(callSelectorString)]; | 515 List tearOffInfo = [new jsAst.LiteralString(callSelectorString)]; |
| 492 | 516 |
| 493 if (needsStubs || canTearOff) { | 517 if (needsStubs || canTearOff) { |
| 494 addParameterStubs(member, (Selector selector, jsAst.Fun function) { | 518 addParameterStubs(member, (Selector selector, jsAst.Fun function) { |
| 495 expressions.add(function); | 519 expressions.add(function); |
| 496 if (member.isInstanceMember) { | 520 if (member.isInstanceMember) { |
| 497 Set invokedSelectors = | 521 Set invokedSelectors = |
| 498 compiler.codegenWorld.invokedNames[member.name]; | 522 compiler.codegenWorld.invokedNames[member.name]; |
| 499 expressions.add(js.string(namer.invocationName(selector))); | 523 expressions.add(js.string(namer.invocationName(selector))); |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 574 js.string(namer.privateName(member.library, member.name)); | 598 js.string(namer.privateName(member.library, member.name)); |
| 575 } | 599 } |
| 576 expressions | 600 expressions |
| 577 ..add(reflectionName) | 601 ..add(reflectionName) |
| 578 ..addAll(emitter.metadataEmitter | 602 ..addAll(emitter.metadataEmitter |
| 579 .computeMetadata(member).map(js.number)); | 603 .computeMetadata(member).map(js.number)); |
| 580 } else if (isClosure && canBeApplied) { | 604 } else if (isClosure && canBeApplied) { |
| 581 expressions.add(js.string(namer.privateName(member.library, | 605 expressions.add(js.string(namer.privateName(member.library, |
| 582 member.name))); | 606 member.name))); |
| 583 } | 607 } |
| 608 |
| 584 jsAst.ArrayInitializer arrayInit = | 609 jsAst.ArrayInitializer arrayInit = |
| 585 new jsAst.ArrayInitializer.from(expressions); | 610 new jsAst.ArrayInitializer.from(expressions); |
| 586 compiler.dumpInfoTask.registerElementAst(member, | 611 compiler.dumpInfoTask.registerElementAst(member, |
| 587 builder.addProperty(name, arrayInit)); | 612 builder.addProperty(name, arrayInit)); |
| 588 } | 613 } |
| 589 | 614 |
| 590 void addMemberField(VariableElement member, ClassBuilder builder) { | 615 void addMemberField(VariableElement member, ClassBuilder builder) { |
| 591 // For now, do nothing. | 616 // For now, do nothing. |
| 592 } | 617 } |
| 593 } | 618 } |
| (...skipping 14 matching lines...) Expand all Loading... |
| 608 final bool isClosure; | 633 final bool isClosure; |
| 609 | 634 |
| 610 final String tearOffName; | 635 final String tearOffName; |
| 611 | 636 |
| 612 final bool canBeReflected; | 637 final bool canBeReflected; |
| 613 | 638 |
| 614 final bool canBeApplied; | 639 final bool canBeApplied; |
| 615 | 640 |
| 616 final bool needStructuredInfo; | 641 final bool needStructuredInfo; |
| 617 | 642 |
| 643 final bool hasSuperAlias; |
| 644 |
| 618 MemberInfo( | 645 MemberInfo( |
| 619 this.member, | 646 this.member, |
| 620 this.name, | 647 this.name, |
| 621 this.parameters, | 648 this.parameters, |
| 622 this.code, | 649 this.code, |
| 623 {this.needsStubs, | 650 {this.needsStubs, |
| 624 this.canTearOff, | 651 this.canTearOff, |
| 625 this.isClosure, | 652 this.isClosure, |
| 626 this.tearOffName, | 653 this.tearOffName, |
| 627 this.canBeReflected, | 654 this.canBeReflected, |
| 628 this.canBeApplied, | 655 this.canBeApplied, |
| 656 this.hasSuperAlias, |
| 629 this.needStructuredInfo}) { | 657 this.needStructuredInfo}) { |
| 630 assert(member != null); | 658 assert(member != null); |
| 631 assert(name != null); | 659 assert(name != null); |
| 632 assert(parameters != null); | 660 assert(parameters != null); |
| 633 assert(code != null); | 661 assert(code != null); |
| 634 assert(needsStubs != null); | 662 assert(needsStubs != null); |
| 635 assert(canTearOff != null); | 663 assert(canTearOff != null); |
| 636 assert(isClosure != null); | 664 assert(isClosure != null); |
| 637 assert(tearOffName != null || !canTearOff); | 665 assert(tearOffName != null || !canTearOff); |
| 638 assert(canBeReflected != null); | 666 assert(canBeReflected != null); |
| 639 assert(canBeApplied != null); | 667 assert(canBeApplied != null); |
| 668 assert(hasSuperAlias != null); |
| 640 assert(needStructuredInfo != null); | 669 assert(needStructuredInfo != null); |
| 641 } | 670 } |
| 642 } | 671 } |
| OLD | NEW |