255 final int LINKER_CALL = nameCursor++; |
255 final int LINKER_CALL = nameCursor++; |
256 Name[] names = arguments(nameCursor - ARG_LIMIT, mtype.invokerType()); |
256 Name[] names = arguments(nameCursor - ARG_LIMIT, mtype.invokerType()); |
257 assert(names.length == nameCursor); |
257 assert(names.length == nameCursor); |
258 if (doesAlloc) { |
258 if (doesAlloc) { |
259 // names = { argx,y,z,... new C, init method } |
259 // names = { argx,y,z,... new C, init method } |
260 names[NEW_OBJ] = new Name(NF_allocateInstance, names[DMH_THIS]); |
260 names[NEW_OBJ] = new Name(Lazy.NF_allocateInstance, names[DMH_THIS]); |
261 names[GET_MEMBER] = new Name(NF_constructorMethod, names[DMH_THIS]); |
261 names[GET_MEMBER] = new Name(Lazy.NF_constructorMethod, names[DMH_THIS]); |
262 } else if (needsInit) { |
262 } else if (needsInit) { |
263 names[GET_MEMBER] = new Name(NF_internalMemberNameEnsureInit, names[DMH_THIS]); |
263 names[GET_MEMBER] = new Name(Lazy.NF_internalMemberNameEnsureInit, names[DMH_THIS]); |
264 } else { |
264 } else { |
265 names[GET_MEMBER] = new Name(NF_internalMemberName, names[DMH_THIS]); |
265 names[GET_MEMBER] = new Name(Lazy.NF_internalMemberName, names[DMH_THIS]); |
266 } |
266 } |
267 Object[] outArgs = Arrays.copyOfRange(names, ARG_BASE, GET_MEMBER+1, Object[].class); |
267 Object[] outArgs = Arrays.copyOfRange(names, ARG_BASE, GET_MEMBER+1, Object[].class); |
268 assert(outArgs[outArgs.length-1] == names[GET_MEMBER]); // look, shifted args! |
268 assert(outArgs[outArgs.length-1] == names[GET_MEMBER]); // look, shifted args! |
269 int result = LambdaForm.LAST_RESULT; |
269 int result = LambdaForm.LAST_RESULT; |
270 if (doesAlloc) { |
270 if (doesAlloc) { |
635 final int LINKER_CALL = nameCursor++; |
635 final int LINKER_CALL = nameCursor++; |
636 final int POST_CAST = (needsCast && isGetter ? nameCursor++ : -1); |
636 final int POST_CAST = (needsCast && isGetter ? nameCursor++ : -1); |
637 final int RESULT = nameCursor-1; // either the call or the cast |
637 final int RESULT = nameCursor-1; // either the call or the cast |
638 Name[] names = arguments(nameCursor - ARG_LIMIT, mtype.invokerType()); |
638 Name[] names = arguments(nameCursor - ARG_LIMIT, mtype.invokerType()); |
639 if (needsInit) |
639 if (needsInit) |
640 names[INIT_BAR] = new Name(NF_ensureInitialized, names[DMH_THIS]); |
640 names[INIT_BAR] = new Name(Lazy.NF_ensureInitialized, names[DMH_THIS]); |
641 if (needsCast && !isGetter) |
641 if (needsCast && !isGetter) |
642 names[PRE_CAST] = new Name(NF_checkCast, names[DMH_THIS], names[SET_VALUE]); |
642 names[PRE_CAST] = new Name(Lazy.NF_checkCast, names[DMH_THIS], names[SET_VALUE]); |
643 Object[] outArgs = new Object[1 + linkerType.parameterCount()]; |
643 Object[] outArgs = new Object[1 + linkerType.parameterCount()]; |
644 assert(outArgs.length == (isGetter ? 3 : 4)); |
644 assert(outArgs.length == (isGetter ? 3 : 4)); |
645 outArgs[0] = UNSAFE; |
645 outArgs[0] = UNSAFE; |
646 if (isStatic) { |
646 if (isStatic) { |
647 outArgs[1] = names[F_HOLDER] = new Name(NF_staticBase, names[DMH_THIS]); |
647 outArgs[1] = names[F_HOLDER] = new Name(Lazy.NF_staticBase, names[DMH_THIS]); |
648 outArgs[2] = names[F_OFFSET] = new Name(NF_staticOffset, names[DMH_THIS]); |
648 outArgs[2] = names[F_OFFSET] = new Name(Lazy.NF_staticOffset, names[DMH_THIS]); |
649 } else { |
649 } else { |
650 outArgs[1] = names[OBJ_CHECK] = new Name(NF_checkBase, names[OBJ_BASE]); |
650 outArgs[1] = names[OBJ_CHECK] = new Name(Lazy.NF_checkBase, names[OBJ_BASE]); |
651 outArgs[2] = names[F_OFFSET] = new Name(NF_fieldOffset, names[DMH_THIS]); |
651 outArgs[2] = names[F_OFFSET] = new Name(Lazy.NF_fieldOffset, names[DMH_THIS]); |
652 } |
652 } |
653 if (!isGetter) { |
653 if (!isGetter) { |
654 outArgs[3] = (needsCast ? names[PRE_CAST] : names[SET_VALUE]); |
654 outArgs[3] = (needsCast ? names[PRE_CAST] : names[SET_VALUE]); |
655 } |
655 } |
656 for (Object a : outArgs) assert(a != null); |
656 for (Object a : outArgs) assert(a != null); |
657 names[LINKER_CALL] = new Name(linker, outArgs); |
657 names[LINKER_CALL] = new Name(linker, outArgs); |
658 if (needsCast && isGetter) |
658 if (needsCast && isGetter) |
659 names[POST_CAST] = new Name(NF_checkCast, names[DMH_THIS], names[LINKER_CALL]); |
659 names[POST_CAST] = new Name(Lazy.NF_checkCast, names[DMH_THIS], names[LINKER_CALL]); |
660 for (Name n : names) assert(n != null); |
660 for (Name n : names) assert(n != null); |
661 String fieldOrStatic = (isStatic ? "Static" : "Field"); |
661 String fieldOrStatic = (isStatic ? "Static" : "Field"); |
662 String lambdaName = (linkerName + fieldOrStatic); // significant only for debugging |
662 String lambdaName = (linkerName + fieldOrStatic); // significant only for debugging |
663 if (needsCast) lambdaName += "Cast"; |
663 if (needsCast) lambdaName += "Cast"; |
664 if (needsInit) lambdaName += "Init"; |
664 if (needsInit) lambdaName += "Init"; |
665 return new LambdaForm(lambdaName, ARG_LIMIT, names, RESULT); |
665 return new LambdaForm(lambdaName, ARG_LIMIT, names, RESULT); |
666 } |
666 } |
667 |
667 |
668 private static final NamedFunction |
668 /** |
669 NF_internalMemberName, |
669 * Pre-initialized NamedFunctions for bootstrapping purposes. |
670 NF_internalMemberNameEnsureInit, |
670 * Factored in an inner class to delay initialization until first usage. |
671 NF_ensureInitialized, |
671 */ |
672 NF_fieldOffset, |
672 private static class Lazy { |
673 NF_checkBase, |
673 static final NamedFunction |
674 NF_staticBase, |
674 NF_internalMemberName, |
675 NF_staticOffset, |
675 NF_internalMemberNameEnsureInit, |
676 NF_checkCast, |
676 NF_ensureInitialized, |
677 NF_allocateInstance, |
677 NF_fieldOffset, |
678 NF_constructorMethod; |
678 NF_checkBase, |
679 static { |
679 NF_staticBase, |
680 try { |
680 NF_staticOffset, |
681 NamedFunction nfs[] = { |
681 NF_checkCast, |
682 NF_internalMemberName = new NamedFunction(DirectMethodHandle.class |
682 NF_allocateInstance, |
683 .getDeclaredMethod("internalMemberName", Object.class)), |
683 NF_constructorMethod; |
684 NF_internalMemberNameEnsureInit = new NamedFunction(DirectMethodHandle.class |
684 static { |
685 .getDeclaredMethod("internalMemberNameEnsureInit", Object.class)), |
685 try { |
686 NF_ensureInitialized = new NamedFunction(DirectMethodHandle.class |
686 NamedFunction nfs[] = { |
687 .getDeclaredMethod("ensureInitialized", Object.class)), |
687 NF_internalMemberName = new NamedFunction(DirectMethodHandle.class |
688 NF_fieldOffset = new NamedFunction(DirectMethodHandle.class |
688 .getDeclaredMethod("internalMemberName", Object.class)), |
689 .getDeclaredMethod("fieldOffset", Object.class)), |
689 NF_internalMemberNameEnsureInit = new NamedFunction(DirectMethodHandle.class |
690 NF_checkBase = new NamedFunction(DirectMethodHandle.class |
690 .getDeclaredMethod("internalMemberNameEnsureInit", Object.class)), |
691 .getDeclaredMethod("checkBase", Object.class)), |
691 NF_ensureInitialized = new NamedFunction(DirectMethodHandle.class |
692 NF_staticBase = new NamedFunction(DirectMethodHandle.class |
692 .getDeclaredMethod("ensureInitialized", Object.class)), |
693 .getDeclaredMethod("staticBase", Object.class)), |
693 NF_fieldOffset = new NamedFunction(DirectMethodHandle.class |
694 NF_staticOffset = new NamedFunction(DirectMethodHandle.class |
694 .getDeclaredMethod("fieldOffset", Object.class)), |
695 .getDeclaredMethod("staticOffset", Object.class)), |
695 NF_checkBase = new NamedFunction(DirectMethodHandle.class |
696 NF_checkCast = new NamedFunction(DirectMethodHandle.class |
696 .getDeclaredMethod("checkBase", Object.class)), |
697 .getDeclaredMethod("checkCast", Object.class, Object.class)), |
697 NF_staticBase = new NamedFunction(DirectMethodHandle.class |
698 NF_allocateInstance = new NamedFunction(DirectMethodHandle.class |
698 .getDeclaredMethod("staticBase", Object.class)), |
699 .getDeclaredMethod("allocateInstance", Object.class)), |
699 NF_staticOffset = new NamedFunction(DirectMethodHandle.class |
700 NF_constructorMethod = new NamedFunction(DirectMethodHandle.class |
700 .getDeclaredMethod("staticOffset", Object.class)), |
701 .getDeclaredMethod("constructorMethod", Object.class)) |
701 NF_checkCast = new NamedFunction(DirectMethodHandle.class |
702 }; |
702 .getDeclaredMethod("checkCast", Object.class, Object.class)), |
703 for (NamedFunction nf : nfs) { |
703 NF_allocateInstance = new NamedFunction(DirectMethodHandle.class |
704 // Each nf must be statically invocable or we get tied up in our bootstraps. |
704 .getDeclaredMethod("allocateInstance", Object.class)), |
705 assert(InvokerBytecodeGenerator.isStaticallyInvocable(nf.member)) : nf; |
705 NF_constructorMethod = new NamedFunction(DirectMethodHandle.class |
706 nf.resolve(); |
706 .getDeclaredMethod("constructorMethod", Object.class)) |
|
707 }; |
|
708 for (NamedFunction nf : nfs) { |
|
709 // Each nf must be statically invocable or we get tied up in our bootstraps. |
|
710 assert(InvokerBytecodeGenerator.isStaticallyInvocable(nf.member)) : nf; |
|
711 nf.resolve(); |
|
712 } |
|
713 } catch (ReflectiveOperationException ex) { |
|
714 throw newInternalError(ex); |
707 } |
715 } |
708 } catch (ReflectiveOperationException ex) { |
|
709 throw newInternalError(ex); |
|
710 } |
716 } |
711 } |
717 } |
712 } |
718 } |