Java 类java.lang.invoke.LambdaForm.Name 实例源码
项目:jdk-1.7-annotated
文件:InvokerBytecodeGenerator.java
/**
* Emit an invoke for the given name.
*
* @param name
*/
void emitInvoke(Name name) {
if (true) {
// push receiver
MethodHandle target = name.function.resolvedHandle;
assert(target != null) : name.exprString();
mv.visitLdcInsn(constantPlaceholder(target));
mv.visitTypeInsn(Opcodes.CHECKCAST, MH);
} else {
// load receiver
emitAloadInsn(0);
mv.visitTypeInsn(Opcodes.CHECKCAST, MH);
mv.visitFieldInsn(Opcodes.GETFIELD, MH, "form", LF_SIG);
mv.visitFieldInsn(Opcodes.GETFIELD, LF, "names", LFN_SIG);
// TODO more to come
}
// push arguments
for (int i = 0; i < name.arguments.length; i++) {
emitPushArgument(name, i);
}
// invocation
MethodType type = name.function.methodType();
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, MH, "invokeBasic", type.basicType().toMethodDescriptorString());
}
项目:jdk-1.7-annotated
文件:InvokerBytecodeGenerator.java
/**
*
* @param name
* @param paramIndex
*/
private void emitPushArgument(Name name, int paramIndex) {
Object arg = name.arguments[paramIndex];
char ptype = name.function.parameterType(paramIndex);
MethodType mtype = name.function.methodType();
if (arg instanceof Name) {
Name n = (Name) arg;
emitLoadInsn(n.type, n.index());
emitImplicitConversion(n.type, mtype.parameterType(paramIndex));
} else if ((arg == null || arg instanceof String) && ptype == 'L') {
emitConst(arg);
} else {
if (Wrapper.isWrapperType(arg.getClass()) && ptype != 'L') {
emitConst(arg);
} else {
mv.visitLdcInsn(constantPlaceholder(arg));
emitImplicitConversion('L', mtype.parameterType(paramIndex));
}
}
}
项目:OLD-OpenJDK8
文件:InvokerBytecodeGenerator.java
/**
* Emit an invoke for the given name.
*/
void emitInvoke(Name name) {
if (true) {
// push receiver
MethodHandle target = name.function.resolvedHandle;
assert(target != null) : name.exprString();
mv.visitLdcInsn(constantPlaceholder(target));
mv.visitTypeInsn(Opcodes.CHECKCAST, MH);
} else {
// load receiver
emitAloadInsn(0);
mv.visitTypeInsn(Opcodes.CHECKCAST, MH);
mv.visitFieldInsn(Opcodes.GETFIELD, MH, "form", LF_SIG);
mv.visitFieldInsn(Opcodes.GETFIELD, LF, "names", LFN_SIG);
// TODO more to come
}
// push arguments
for (int i = 0; i < name.arguments.length; i++) {
emitPushArgument(name, i);
}
// invocation
MethodType type = name.function.methodType();
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, MH, "invokeBasic", type.basicType().toMethodDescriptorString());
}
项目:OLD-OpenJDK8
文件:InvokerBytecodeGenerator.java
private void emitPushArgument(Name name, int paramIndex) {
Object arg = name.arguments[paramIndex];
char ptype = name.function.parameterType(paramIndex);
MethodType mtype = name.function.methodType();
if (arg instanceof Name) {
Name n = (Name) arg;
emitLoadInsn(n.type, n.index());
emitImplicitConversion(n.type, mtype.parameterType(paramIndex));
} else if ((arg == null || arg instanceof String) && ptype == 'L') {
emitConst(arg);
} else {
if (Wrapper.isWrapperType(arg.getClass()) && ptype != 'L') {
emitConst(arg);
} else {
mv.visitLdcInsn(constantPlaceholder(arg));
emitImplicitConversion('L', mtype.parameterType(paramIndex));
}
}
}
项目:openjdk-jdk7u-jdk
文件:InvokerBytecodeGenerator.java
/**
* Emit an invoke for the given name.
*
* @param name
*/
void emitInvoke(Name name) {
if (true) {
// push receiver
MethodHandle target = name.function.resolvedHandle;
assert(target != null) : name.exprString();
mv.visitLdcInsn(constantPlaceholder(target));
mv.visitTypeInsn(Opcodes.CHECKCAST, MH);
} else {
// load receiver
emitAloadInsn(0);
mv.visitTypeInsn(Opcodes.CHECKCAST, MH);
mv.visitFieldInsn(Opcodes.GETFIELD, MH, "form", LF_SIG);
mv.visitFieldInsn(Opcodes.GETFIELD, LF, "names", LFN_SIG);
// TODO more to come
}
// push arguments
for (int i = 0; i < name.arguments.length; i++) {
emitPushArgument(name, i);
}
// invocation
MethodType type = name.function.methodType();
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, MH, "invokeBasic", type.basicType().toMethodDescriptorString());
}
项目:openjdk-jdk7u-jdk
文件:InvokerBytecodeGenerator.java
/**
*
* @param name
* @param paramIndex
*/
private void emitPushArgument(Name name, int paramIndex) {
Object arg = name.arguments[paramIndex];
char ptype = name.function.parameterType(paramIndex);
MethodType mtype = name.function.methodType();
if (arg instanceof Name) {
Name n = (Name) arg;
emitLoadInsn(n.type, n.index());
emitImplicitConversion(n.type, mtype.parameterType(paramIndex));
} else if ((arg == null || arg instanceof String) && ptype == 'L') {
emitConst(arg);
} else {
if (Wrapper.isWrapperType(arg.getClass()) && ptype != 'L') {
emitConst(arg);
} else {
mv.visitLdcInsn(constantPlaceholder(arg));
emitImplicitConversion('L', mtype.parameterType(paramIndex));
}
}
}
项目:openjdk-icedtea7
文件:InvokerBytecodeGenerator.java
/**
* Emit an invoke for the given name.
*
* @param name
*/
void emitInvoke(Name name) {
if (true) {
// push receiver
MethodHandle target = name.function.resolvedHandle;
assert(target != null) : name.exprString();
mv.visitLdcInsn(constantPlaceholder(target));
mv.visitTypeInsn(Opcodes.CHECKCAST, MH);
} else {
// load receiver
emitAloadInsn(0);
mv.visitTypeInsn(Opcodes.CHECKCAST, MH);
mv.visitFieldInsn(Opcodes.GETFIELD, MH, "form", LF_SIG);
mv.visitFieldInsn(Opcodes.GETFIELD, LF, "names", LFN_SIG);
// TODO more to come
}
// push arguments
for (int i = 0; i < name.arguments.length; i++) {
emitPushArgument(name, i);
}
// invocation
MethodType type = name.function.methodType();
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, MH, "invokeBasic", type.basicType().toMethodDescriptorString());
}
项目:openjdk-icedtea7
文件:InvokerBytecodeGenerator.java
/**
*
* @param name
* @param paramIndex
*/
private void emitPushArgument(Name name, int paramIndex) {
Object arg = name.arguments[paramIndex];
char ptype = name.function.parameterType(paramIndex);
MethodType mtype = name.function.methodType();
if (arg instanceof Name) {
Name n = (Name) arg;
emitLoadInsn(n.type, n.index());
emitImplicitConversion(n.type, mtype.parameterType(paramIndex));
} else if ((arg == null || arg instanceof String) && ptype == 'L') {
emitConst(arg);
} else {
if (Wrapper.isWrapperType(arg.getClass()) && ptype != 'L') {
emitConst(arg);
} else {
mv.visitLdcInsn(constantPlaceholder(arg));
emitImplicitConversion('L', mtype.parameterType(paramIndex));
}
}
}
项目:jdk-1.7-annotated
文件:BoundMethodHandle.java
/**
* Wrap a constructor call in a {@link LambdaForm}.
*
* If constructors ({@code <init>} methods) are called in LFs, problems might arise if the LFs
* are turned into bytecode, because the call to the allocator is routed through an MH, and the
* verifier cannot find a {@code NEW} instruction preceding the {@code INVOKESPECIAL} to
* {@code <init>}. To avoid this, we add an indirection by invoking {@code <init>} through
* {@link MethodHandle#linkToSpecial}.
*
* The last {@link LambdaForm#Name Name} in the argument's form is expected to be the {@code void}
* result of the {@code <init>} invocation. This entry is replaced.
*/
private static MethodHandle linkConstructor(MethodHandle cmh) {
final LambdaForm lf = cmh.form;
final int initNameIndex = lf.names.length - 1;
final Name initName = lf.names[initNameIndex];
final MemberName ctorMN = initName.function.member;
final MethodType ctorMT = ctorMN.getInvocationType();
// obtain function member (call target)
// linker method type replaces initial parameter (BMH species) with BMH to avoid naming a species (anonymous class!)
final MethodType linkerMT = ctorMT.changeParameterType(0, BoundMethodHandle.class).appendParameterTypes(MemberName.class);
MemberName linkerMN = new MemberName(MethodHandle.class, "linkToSpecial", linkerMT, REF_invokeStatic);
try {
linkerMN = MemberName.getFactory().resolveOrFail(REF_invokeStatic, linkerMN, null, NoSuchMethodException.class);
assert(linkerMN.isStatic());
} catch (ReflectiveOperationException ex) {
throw newInternalError(ex);
}
// extend arguments array
Object[] newArgs = Arrays.copyOf(initName.arguments, initName.arguments.length + 1);
newArgs[newArgs.length - 1] = ctorMN;
// replace function
final NamedFunction nf = new NamedFunction(linkerMN);
final Name linkedCtor = new Name(nf, newArgs);
linkedCtor.initIndex(initNameIndex);
lf.names[initNameIndex] = linkedCtor;
return cmh;
}
项目:jdk-1.7-annotated
文件:InvokerBytecodeGenerator.java
/**
* Emit an invoke for the given name, using the MemberName directly.
*
* @param name
*/
void emitStaticInvoke(MemberName member, Name name) {
assert(member.equals(name.function.member()));
String cname = getInternalName(member.getDeclaringClass());
String mname = member.getName();
String mtype;
byte refKind = member.getReferenceKind();
if (refKind == REF_invokeSpecial) {
// in order to pass the verifier, we need to convert this to invokevirtual in all cases
assert(member.canBeStaticallyBound()) : member;
refKind = REF_invokeVirtual;
}
// push arguments
for (int i = 0; i < name.arguments.length; i++) {
emitPushArgument(name, i);
}
// invocation
if (member.isMethod()) {
mtype = member.getMethodType().toMethodDescriptorString();
mv.visitMethodInsn(refKindOpcode(refKind), cname, mname, mtype);
} else {
mtype = MethodType.toFieldDescriptorString(member.getFieldType());
mv.visitFieldInsn(refKindOpcode(refKind), cname, mname, mtype);
}
}
项目:jdk-1.7-annotated
文件:InvokerBytecodeGenerator.java
/**
* Emit bytecode for the selectAlternative idiom.
*
* The pattern looks like (Cf. MethodHandleImpl.makeGuardWithTest):
*
* Lambda(a0:L,a1:I)=>{
* t2:I=foo.test(a1:I);
* t3:L=MethodHandleImpl.selectAlternative(t2:I,(MethodHandle(int)int),(MethodHandle(int)int));
* t4:I=MethodHandle.invokeBasic(t3:L,a1:I);t4:I}
*
* @param selectAlternativeName
* @param invokeBasicName
*/
private void emitSelectAlternative(Name selectAlternativeName, Name invokeBasicName) {
MethodType type = selectAlternativeName.function.methodType();
Name receiver = (Name) invokeBasicName.arguments[0];
Label L_fallback = new Label();
Label L_done = new Label();
// load test result
emitPushArgument(selectAlternativeName, 0);
mv.visitInsn(Opcodes.ICONST_1);
// if_icmpne L_fallback
mv.visitJumpInsn(Opcodes.IF_ICMPNE, L_fallback);
// invoke selectAlternativeName.arguments[1]
MethodHandle target = (MethodHandle) selectAlternativeName.arguments[1];
emitPushArgument(selectAlternativeName, 1); // get 2nd argument of selectAlternative
emitAstoreInsn(receiver.index()); // store the MH in the receiver slot
emitInvoke(invokeBasicName);
// goto L_done
mv.visitJumpInsn(Opcodes.GOTO, L_done);
// L_fallback:
mv.visitLabel(L_fallback);
// invoke selectAlternativeName.arguments[2]
MethodHandle fallback = (MethodHandle) selectAlternativeName.arguments[2];
emitPushArgument(selectAlternativeName, 2); // get 3rd argument of selectAlternative
emitAstoreInsn(receiver.index()); // store the MH in the receiver slot
emitInvoke(invokeBasicName);
// L_done:
mv.visitLabel(L_done);
}
项目:OLD-OpenJDK8
文件:BoundMethodHandle.java
/**
* Wrap a constructor call in a {@link LambdaForm}.
*
* If constructors ({@code <init>} methods) are called in LFs, problems might arise if the LFs
* are turned into bytecode, because the call to the allocator is routed through an MH, and the
* verifier cannot find a {@code NEW} instruction preceding the {@code INVOKESPECIAL} to
* {@code <init>}. To avoid this, we add an indirection by invoking {@code <init>} through
* {@link MethodHandle#linkToSpecial}.
*
* The last {@link LambdaForm.Name Name} in the argument's form is expected to be the {@code void}
* result of the {@code <init>} invocation. This entry is replaced.
*/
private static MethodHandle linkConstructor(MethodHandle cmh) {
final LambdaForm lf = cmh.form;
final int initNameIndex = lf.names.length - 1;
final Name initName = lf.names[initNameIndex];
final MemberName ctorMN = initName.function.member;
final MethodType ctorMT = ctorMN.getInvocationType();
// obtain function member (call target)
// linker method type replaces initial parameter (BMH species) with BMH to avoid naming a species (anonymous class!)
final MethodType linkerMT = ctorMT.changeParameterType(0, BoundMethodHandle.class).appendParameterTypes(MemberName.class);
MemberName linkerMN = new MemberName(MethodHandle.class, "linkToSpecial", linkerMT, REF_invokeStatic);
try {
linkerMN = MemberName.getFactory().resolveOrFail(REF_invokeStatic, linkerMN, null, NoSuchMethodException.class);
assert(linkerMN.isStatic());
} catch (ReflectiveOperationException ex) {
throw newInternalError(ex);
}
// extend arguments array
Object[] newArgs = Arrays.copyOf(initName.arguments, initName.arguments.length + 1);
newArgs[newArgs.length - 1] = ctorMN;
// replace function
final NamedFunction nf = new NamedFunction(linkerMN);
final Name linkedCtor = new Name(nf, newArgs);
linkedCtor.initIndex(initNameIndex);
lf.names[initNameIndex] = linkedCtor;
return cmh;
}
项目:OLD-OpenJDK8
文件:InvokerBytecodeGenerator.java
/**
* Emit an invoke for the given name, using the MemberName directly.
*/
void emitStaticInvoke(MemberName member, Name name) {
assert(member.equals(name.function.member()));
String cname = getInternalName(member.getDeclaringClass());
String mname = member.getName();
String mtype;
byte refKind = member.getReferenceKind();
if (refKind == REF_invokeSpecial) {
// in order to pass the verifier, we need to convert this to invokevirtual in all cases
assert(member.canBeStaticallyBound()) : member;
refKind = REF_invokeVirtual;
}
if (member.getDeclaringClass().isInterface() && refKind == REF_invokeVirtual) {
// Methods from Object declared in an interface can be resolved by JVM to invokevirtual kind.
// Need to convert it back to invokeinterface to pass verification and make the invocation works as expected.
refKind = REF_invokeInterface;
}
// push arguments
for (int i = 0; i < name.arguments.length; i++) {
emitPushArgument(name, i);
}
// invocation
if (member.isMethod()) {
mtype = member.getMethodType().toMethodDescriptorString();
mv.visitMethodInsn(refKindOpcode(refKind), cname, mname, mtype,
member.getDeclaringClass().isInterface());
} else {
mtype = MethodType.toFieldDescriptorString(member.getFieldType());
mv.visitFieldInsn(refKindOpcode(refKind), cname, mname, mtype);
}
}
项目:OLD-OpenJDK8
文件:InvokerBytecodeGenerator.java
/**
* Emit bytecode for the selectAlternative idiom.
*
* The pattern looks like (Cf. MethodHandleImpl.makeGuardWithTest):
* <blockquote><pre>{@code
* Lambda(a0:L,a1:I)=>{
* t2:I=foo.test(a1:I);
* t3:L=MethodHandleImpl.selectAlternative(t2:I,(MethodHandle(int)int),(MethodHandle(int)int));
* t4:I=MethodHandle.invokeBasic(t3:L,a1:I);t4:I}
* }</pre></blockquote>
*/
private void emitSelectAlternative(Name selectAlternativeName, Name invokeBasicName) {
MethodType type = selectAlternativeName.function.methodType();
Name receiver = (Name) invokeBasicName.arguments[0];
Label L_fallback = new Label();
Label L_done = new Label();
// load test result
emitPushArgument(selectAlternativeName, 0);
mv.visitInsn(Opcodes.ICONST_1);
// if_icmpne L_fallback
mv.visitJumpInsn(Opcodes.IF_ICMPNE, L_fallback);
// invoke selectAlternativeName.arguments[1]
MethodHandle target = (MethodHandle) selectAlternativeName.arguments[1];
emitPushArgument(selectAlternativeName, 1); // get 2nd argument of selectAlternative
emitAstoreInsn(receiver.index()); // store the MH in the receiver slot
emitInvoke(invokeBasicName);
// goto L_done
mv.visitJumpInsn(Opcodes.GOTO, L_done);
// L_fallback:
mv.visitLabel(L_fallback);
// invoke selectAlternativeName.arguments[2]
MethodHandle fallback = (MethodHandle) selectAlternativeName.arguments[2];
emitPushArgument(selectAlternativeName, 2); // get 3rd argument of selectAlternative
emitAstoreInsn(receiver.index()); // store the MH in the receiver slot
emitInvoke(invokeBasicName);
// L_done:
mv.visitLabel(L_done);
}
项目:openjdk-jdk7u-jdk
文件:BoundMethodHandle.java
/**
* Wrap a constructor call in a {@link LambdaForm}.
*
* If constructors ({@code <init>} methods) are called in LFs, problems might arise if the LFs
* are turned into bytecode, because the call to the allocator is routed through an MH, and the
* verifier cannot find a {@code NEW} instruction preceding the {@code INVOKESPECIAL} to
* {@code <init>}. To avoid this, we add an indirection by invoking {@code <init>} through
* {@link MethodHandle#linkToSpecial}.
*
* The last {@link LambdaForm#Name Name} in the argument's form is expected to be the {@code void}
* result of the {@code <init>} invocation. This entry is replaced.
*/
private static MethodHandle linkConstructor(MethodHandle cmh) {
final LambdaForm lf = cmh.form;
final int initNameIndex = lf.names.length - 1;
final Name initName = lf.names[initNameIndex];
final MemberName ctorMN = initName.function.member;
final MethodType ctorMT = ctorMN.getInvocationType();
// obtain function member (call target)
// linker method type replaces initial parameter (BMH species) with BMH to avoid naming a species (anonymous class!)
final MethodType linkerMT = ctorMT.changeParameterType(0, BoundMethodHandle.class).appendParameterTypes(MemberName.class);
MemberName linkerMN = new MemberName(MethodHandle.class, "linkToSpecial", linkerMT, REF_invokeStatic);
try {
linkerMN = MemberName.getFactory().resolveOrFail(REF_invokeStatic, linkerMN, null, NoSuchMethodException.class);
assert(linkerMN.isStatic());
} catch (ReflectiveOperationException ex) {
throw newInternalError(ex);
}
// extend arguments array
Object[] newArgs = Arrays.copyOf(initName.arguments, initName.arguments.length + 1);
newArgs[newArgs.length - 1] = ctorMN;
// replace function
final NamedFunction nf = new NamedFunction(linkerMN);
final Name linkedCtor = new Name(nf, newArgs);
linkedCtor.initIndex(initNameIndex);
lf.names[initNameIndex] = linkedCtor;
return cmh;
}
项目:openjdk-jdk7u-jdk
文件:InvokerBytecodeGenerator.java
/**
* Emit an invoke for the given name, using the MemberName directly.
*
* @param name
*/
void emitStaticInvoke(MemberName member, Name name) {
assert(member.equals(name.function.member()));
String cname = getInternalName(member.getDeclaringClass());
String mname = member.getName();
String mtype;
byte refKind = member.getReferenceKind();
if (refKind == REF_invokeSpecial) {
// in order to pass the verifier, we need to convert this to invokevirtual in all cases
assert(member.canBeStaticallyBound()) : member;
refKind = REF_invokeVirtual;
}
// push arguments
for (int i = 0; i < name.arguments.length; i++) {
emitPushArgument(name, i);
}
// invocation
if (member.isMethod()) {
mtype = member.getMethodType().toMethodDescriptorString();
mv.visitMethodInsn(refKindOpcode(refKind), cname, mname, mtype);
} else {
mtype = MethodType.toFieldDescriptorString(member.getFieldType());
mv.visitFieldInsn(refKindOpcode(refKind), cname, mname, mtype);
}
}
项目:openjdk-jdk7u-jdk
文件:InvokerBytecodeGenerator.java
/**
* Emit bytecode for the selectAlternative idiom.
*
* The pattern looks like (Cf. MethodHandleImpl.makeGuardWithTest):
*
* Lambda(a0:L,a1:I)=>{
* t2:I=foo.test(a1:I);
* t3:L=MethodHandleImpl.selectAlternative(t2:I,(MethodHandle(int)int),(MethodHandle(int)int));
* t4:I=MethodHandle.invokeBasic(t3:L,a1:I);t4:I}
*
* @param selectAlternativeName
* @param invokeBasicName
*/
private void emitSelectAlternative(Name selectAlternativeName, Name invokeBasicName) {
MethodType type = selectAlternativeName.function.methodType();
Name receiver = (Name) invokeBasicName.arguments[0];
Label L_fallback = new Label();
Label L_done = new Label();
// load test result
emitPushArgument(selectAlternativeName, 0);
mv.visitInsn(Opcodes.ICONST_1);
// if_icmpne L_fallback
mv.visitJumpInsn(Opcodes.IF_ICMPNE, L_fallback);
// invoke selectAlternativeName.arguments[1]
MethodHandle target = (MethodHandle) selectAlternativeName.arguments[1];
emitPushArgument(selectAlternativeName, 1); // get 2nd argument of selectAlternative
emitAstoreInsn(receiver.index()); // store the MH in the receiver slot
emitInvoke(invokeBasicName);
// goto L_done
mv.visitJumpInsn(Opcodes.GOTO, L_done);
// L_fallback:
mv.visitLabel(L_fallback);
// invoke selectAlternativeName.arguments[2]
MethodHandle fallback = (MethodHandle) selectAlternativeName.arguments[2];
emitPushArgument(selectAlternativeName, 2); // get 3rd argument of selectAlternative
emitAstoreInsn(receiver.index()); // store the MH in the receiver slot
emitInvoke(invokeBasicName);
// L_done:
mv.visitLabel(L_done);
}
项目:openjdk-icedtea7
文件:BoundMethodHandle.java
/**
* Wrap a constructor call in a {@link LambdaForm}.
*
* If constructors ({@code <init>} methods) are called in LFs, problems might arise if the LFs
* are turned into bytecode, because the call to the allocator is routed through an MH, and the
* verifier cannot find a {@code NEW} instruction preceding the {@code INVOKESPECIAL} to
* {@code <init>}. To avoid this, we add an indirection by invoking {@code <init>} through
* {@link MethodHandle#linkToSpecial}.
*
* The last {@link LambdaForm#Name Name} in the argument's form is expected to be the {@code void}
* result of the {@code <init>} invocation. This entry is replaced.
*/
private static MethodHandle linkConstructor(MethodHandle cmh) {
final LambdaForm lf = cmh.form;
final int initNameIndex = lf.names.length - 1;
final Name initName = lf.names[initNameIndex];
final MemberName ctorMN = initName.function.member;
final MethodType ctorMT = ctorMN.getInvocationType();
// obtain function member (call target)
// linker method type replaces initial parameter (BMH species) with BMH to avoid naming a species (anonymous class!)
final MethodType linkerMT = ctorMT.changeParameterType(0, BoundMethodHandle.class).appendParameterTypes(MemberName.class);
MemberName linkerMN = new MemberName(MethodHandle.class, "linkToSpecial", linkerMT, REF_invokeStatic);
try {
linkerMN = MemberName.getFactory().resolveOrFail(REF_invokeStatic, linkerMN, null, NoSuchMethodException.class);
assert(linkerMN.isStatic());
} catch (ReflectiveOperationException ex) {
throw newInternalError(ex);
}
// extend arguments array
Object[] newArgs = Arrays.copyOf(initName.arguments, initName.arguments.length + 1);
newArgs[newArgs.length - 1] = ctorMN;
// replace function
final NamedFunction nf = new NamedFunction(linkerMN);
final Name linkedCtor = new Name(nf, newArgs);
linkedCtor.initIndex(initNameIndex);
lf.names[initNameIndex] = linkedCtor;
return cmh;
}
项目:openjdk-icedtea7
文件:InvokerBytecodeGenerator.java
/**
* Emit an invoke for the given name, using the MemberName directly.
*
* @param name
*/
void emitStaticInvoke(MemberName member, Name name) {
assert(member.equals(name.function.member()));
String cname = getInternalName(member.getDeclaringClass());
String mname = member.getName();
String mtype;
byte refKind = member.getReferenceKind();
if (refKind == REF_invokeSpecial) {
// in order to pass the verifier, we need to convert this to invokevirtual in all cases
assert(member.canBeStaticallyBound()) : member;
refKind = REF_invokeVirtual;
}
// push arguments
for (int i = 0; i < name.arguments.length; i++) {
emitPushArgument(name, i);
}
// invocation
if (member.isMethod()) {
mtype = member.getMethodType().toMethodDescriptorString();
mv.visitMethodInsn(refKindOpcode(refKind), cname, mname, mtype);
} else {
mtype = MethodType.toFieldDescriptorString(member.getFieldType());
mv.visitFieldInsn(refKindOpcode(refKind), cname, mname, mtype);
}
}
项目:openjdk-icedtea7
文件:InvokerBytecodeGenerator.java
/**
* Emit bytecode for the selectAlternative idiom.
*
* The pattern looks like (Cf. MethodHandleImpl.makeGuardWithTest):
*
* Lambda(a0:L,a1:I)=>{
* t2:I=foo.test(a1:I);
* t3:L=MethodHandleImpl.selectAlternative(t2:I,(MethodHandle(int)int),(MethodHandle(int)int));
* t4:I=MethodHandle.invokeBasic(t3:L,a1:I);t4:I}
*
* @param selectAlternativeName
* @param invokeBasicName
*/
private void emitSelectAlternative(Name selectAlternativeName, Name invokeBasicName) {
MethodType type = selectAlternativeName.function.methodType();
Name receiver = (Name) invokeBasicName.arguments[0];
Label L_fallback = new Label();
Label L_done = new Label();
// load test result
emitPushArgument(selectAlternativeName, 0);
mv.visitInsn(Opcodes.ICONST_1);
// if_icmpne L_fallback
mv.visitJumpInsn(Opcodes.IF_ICMPNE, L_fallback);
// invoke selectAlternativeName.arguments[1]
MethodHandle target = (MethodHandle) selectAlternativeName.arguments[1];
emitPushArgument(selectAlternativeName, 1); // get 2nd argument of selectAlternative
emitAstoreInsn(receiver.index()); // store the MH in the receiver slot
emitInvoke(invokeBasicName);
// goto L_done
mv.visitJumpInsn(Opcodes.GOTO, L_done);
// L_fallback:
mv.visitLabel(L_fallback);
// invoke selectAlternativeName.arguments[2]
MethodHandle fallback = (MethodHandle) selectAlternativeName.arguments[2];
emitPushArgument(selectAlternativeName, 2); // get 3rd argument of selectAlternative
emitAstoreInsn(receiver.index()); // store the MH in the receiver slot
emitInvoke(invokeBasicName);
// L_done:
mv.visitLabel(L_done);
}
项目:jdk-1.7-annotated
文件:BoundMethodHandle.java
/**
* Return a {@link LambdaForm.Name} containing a {@link LambdaForm.NamedFunction} that
* represents a MH bound to a generic invoker, which in turn forwards to the corresponding
* getter.
*/
Name getterName(Name mhName, int i) {
MethodHandle mh = getters[i];
assert(mh != null) : this+"."+i;
return new Name(mh, mhName);
}
项目:jdk-1.7-annotated
文件:InvokerBytecodeGenerator.java
/**
* Generate an invoker method for the passed {@link LambdaForm}.
*/
private byte[] generateCustomizedCodeBytes() {
classFilePrologue();
// Suppress this method in backtraces displayed to the user.
mv.visitAnnotation("Ljava/lang/invoke/LambdaForm$Hidden;", true);
// Mark this method as a compiled LambdaForm
mv.visitAnnotation("Ljava/lang/invoke/LambdaForm$Compiled;", true);
// Force inlining of this invoker method.
mv.visitAnnotation("Ljava/lang/invoke/ForceInline;", true);
// iterate over the form's names, generating bytecode instructions for each
// start iterating at the first name following the arguments
for (int i = lambdaForm.arity; i < lambdaForm.names.length; i++) {
Name name = lambdaForm.names[i];
MemberName member = name.function.member();
if (isSelectAlternative(member)) {
// selectAlternative idiom
// FIXME: make sure this idiom is really present!
emitSelectAlternative(name, lambdaForm.names[i + 1]);
i++; // skip MH.invokeBasic of the selectAlternative result
} else if (isStaticallyInvocable(member)) {
emitStaticInvoke(member, name);
} else {
emitInvoke(name);
}
// store the result from evaluating to the target name in a local if required
// (if this is the last value, i.e., the one that is going to be returned,
// avoid store/load/return and just return)
if (i == lambdaForm.names.length - 1 && i == lambdaForm.result) {
// return value - do nothing
} else if (name.type != 'V') {
// non-void: actually assign
emitStoreInsn(name.type, name.index());
}
}
// return statement
emitReturn();
classFileEpilogue();
bogusMethod(lambdaForm);
final byte[] classFile = cw.toByteArray();
maybeDump(className, classFile);
return classFile;
}
项目:jdk-1.7-annotated
文件:InvokerBytecodeGenerator.java
/**
* Emits a return statement from a LF invoker. If required, the result type is cast to the correct return type.
*/
private void emitReturn() {
// return statement
if (lambdaForm.result == -1) {
// void
mv.visitInsn(Opcodes.RETURN);
} else {
LambdaForm.Name rn = lambdaForm.names[lambdaForm.result];
char rtype = Wrapper.basicTypeChar(invokerType.returnType());
// put return value on the stack if it is not already there
if (lambdaForm.result != lambdaForm.names.length - 1) {
emitLoadInsn(rn.type, lambdaForm.result);
}
// potentially generate cast
// rtype is the return type of the invoker - generated code must conform to this
// rn.type is the type of the result Name in the LF
if (rtype != rn.type) {
// need cast
if (rtype == 'L') {
// possibly cast the primitive to the correct type for boxing
char boxedType = Wrapper.forWrapperType(invokerType.returnType()).basicTypeChar();
if (boxedType != rn.type) {
emitPrimCast(rn.type, boxedType);
}
// cast primitive to reference ("boxing")
emitBoxing(invokerType.returnType());
} else {
// to-primitive cast
if (rn.type != 'L') {
// prim-to-prim cast
emitPrimCast(rn.type, rtype);
} else {
// ref-to-prim cast ("unboxing")
throw new InternalError("no ref-to-prim (unboxing) casts supported right now");
}
}
}
// generate actual return statement
emitReturnInsn(invokerType.returnType());
}
}
项目:OLD-OpenJDK8
文件:BoundMethodHandle.java
/**
* Return a {@link LambdaForm.Name} containing a {@link LambdaForm.NamedFunction} that
* represents a MH bound to a generic invoker, which in turn forwards to the corresponding
* getter.
*/
Name getterName(Name mhName, int i) {
MethodHandle mh = getters[i];
assert(mh != null) : this+"."+i;
return new Name(mh, mhName);
}
项目:OLD-OpenJDK8
文件:InvokerBytecodeGenerator.java
/**
* Generate an invoker method for the passed {@link LambdaForm}.
*/
private byte[] generateCustomizedCodeBytes() {
classFilePrologue();
// Suppress this method in backtraces displayed to the user.
mv.visitAnnotation("Ljava/lang/invoke/LambdaForm$Hidden;", true);
// Mark this method as a compiled LambdaForm
mv.visitAnnotation("Ljava/lang/invoke/LambdaForm$Compiled;", true);
// Force inlining of this invoker method.
mv.visitAnnotation("Ljava/lang/invoke/ForceInline;", true);
// iterate over the form's names, generating bytecode instructions for each
// start iterating at the first name following the arguments
for (int i = lambdaForm.arity; i < lambdaForm.names.length; i++) {
Name name = lambdaForm.names[i];
MemberName member = name.function.member();
if (isSelectAlternative(member)) {
// selectAlternative idiom
// FIXME: make sure this idiom is really present!
emitSelectAlternative(name, lambdaForm.names[i + 1]);
i++; // skip MH.invokeBasic of the selectAlternative result
} else if (isStaticallyInvocable(member)) {
emitStaticInvoke(member, name);
} else {
emitInvoke(name);
}
// store the result from evaluating to the target name in a local if required
// (if this is the last value, i.e., the one that is going to be returned,
// avoid store/load/return and just return)
if (i == lambdaForm.names.length - 1 && i == lambdaForm.result) {
// return value - do nothing
} else if (name.type != 'V') {
// non-void: actually assign
emitStoreInsn(name.type, name.index());
}
}
// return statement
emitReturn();
classFileEpilogue();
bogusMethod(lambdaForm);
final byte[] classFile = cw.toByteArray();
maybeDump(className, classFile);
return classFile;
}
项目:OLD-OpenJDK8
文件:InvokerBytecodeGenerator.java
/**
* Emits a return statement from a LF invoker. If required, the result type is cast to the correct return type.
*/
private void emitReturn() {
// return statement
if (lambdaForm.result == -1) {
// void
mv.visitInsn(Opcodes.RETURN);
} else {
LambdaForm.Name rn = lambdaForm.names[lambdaForm.result];
char rtype = Wrapper.basicTypeChar(invokerType.returnType());
// put return value on the stack if it is not already there
if (lambdaForm.result != lambdaForm.names.length - 1) {
emitLoadInsn(rn.type, lambdaForm.result);
}
// potentially generate cast
// rtype is the return type of the invoker - generated code must conform to this
// rn.type is the type of the result Name in the LF
if (rtype != rn.type) {
// need cast
if (rtype == 'L') {
// possibly cast the primitive to the correct type for boxing
char boxedType = Wrapper.forWrapperType(invokerType.returnType()).basicTypeChar();
if (boxedType != rn.type) {
emitPrimCast(rn.type, boxedType);
}
// cast primitive to reference ("boxing")
emitBoxing(invokerType.returnType());
} else {
// to-primitive cast
if (rn.type != 'L') {
// prim-to-prim cast
emitPrimCast(rn.type, rtype);
} else {
// ref-to-prim cast ("unboxing")
throw new InternalError("no ref-to-prim (unboxing) casts supported right now");
}
}
}
// generate actual return statement
emitReturnInsn(invokerType.returnType());
}
}
项目:openjdk-jdk7u-jdk
文件:BoundMethodHandle.java
/**
* Return a {@link LambdaForm.Name} containing a {@link LambdaForm.NamedFunction} that
* represents a MH bound to a generic invoker, which in turn forwards to the corresponding
* getter.
*/
Name getterName(Name mhName, int i) {
MethodHandle mh = getters[i];
assert(mh != null) : this+"."+i;
return new Name(mh, mhName);
}
项目:openjdk-jdk7u-jdk
文件:InvokerBytecodeGenerator.java
/**
* Generate an invoker method for the passed {@link LambdaForm}.
*/
private byte[] generateCustomizedCodeBytes() {
classFilePrologue();
// Suppress this method in backtraces displayed to the user.
mv.visitAnnotation("Ljava/lang/invoke/LambdaForm$Hidden;", true);
// Mark this method as a compiled LambdaForm
mv.visitAnnotation("Ljava/lang/invoke/LambdaForm$Compiled;", true);
// Force inlining of this invoker method.
mv.visitAnnotation("Ljava/lang/invoke/ForceInline;", true);
// iterate over the form's names, generating bytecode instructions for each
// start iterating at the first name following the arguments
for (int i = lambdaForm.arity; i < lambdaForm.names.length; i++) {
Name name = lambdaForm.names[i];
MemberName member = name.function.member();
if (isSelectAlternative(member)) {
// selectAlternative idiom
// FIXME: make sure this idiom is really present!
emitSelectAlternative(name, lambdaForm.names[i + 1]);
i++; // skip MH.invokeBasic of the selectAlternative result
} else if (isStaticallyInvocable(member)) {
emitStaticInvoke(member, name);
} else {
emitInvoke(name);
}
// store the result from evaluating to the target name in a local if required
// (if this is the last value, i.e., the one that is going to be returned,
// avoid store/load/return and just return)
if (i == lambdaForm.names.length - 1 && i == lambdaForm.result) {
// return value - do nothing
} else if (name.type != 'V') {
// non-void: actually assign
emitStoreInsn(name.type, name.index());
}
}
// return statement
emitReturn();
classFileEpilogue();
bogusMethod(lambdaForm);
final byte[] classFile = cw.toByteArray();
maybeDump(className, classFile);
return classFile;
}
项目:openjdk-jdk7u-jdk
文件:InvokerBytecodeGenerator.java
/**
* Emits a return statement from a LF invoker. If required, the result type is cast to the correct return type.
*/
private void emitReturn() {
// return statement
if (lambdaForm.result == -1) {
// void
mv.visitInsn(Opcodes.RETURN);
} else {
LambdaForm.Name rn = lambdaForm.names[lambdaForm.result];
char rtype = Wrapper.basicTypeChar(invokerType.returnType());
// put return value on the stack if it is not already there
if (lambdaForm.result != lambdaForm.names.length - 1) {
emitLoadInsn(rn.type, lambdaForm.result);
}
// potentially generate cast
// rtype is the return type of the invoker - generated code must conform to this
// rn.type is the type of the result Name in the LF
if (rtype != rn.type) {
// need cast
if (rtype == 'L') {
// possibly cast the primitive to the correct type for boxing
char boxedType = Wrapper.forWrapperType(invokerType.returnType()).basicTypeChar();
if (boxedType != rn.type) {
emitPrimCast(rn.type, boxedType);
}
// cast primitive to reference ("boxing")
emitBoxing(invokerType.returnType());
} else {
// to-primitive cast
if (rn.type != 'L') {
// prim-to-prim cast
emitPrimCast(rn.type, rtype);
} else {
// ref-to-prim cast ("unboxing")
throw new InternalError("no ref-to-prim (unboxing) casts supported right now");
}
}
}
// generate actual return statement
emitReturnInsn(invokerType.returnType());
}
}
项目:openjdk-icedtea7
文件:BoundMethodHandle.java
/**
* Return a {@link LambdaForm.Name} containing a {@link LambdaForm.NamedFunction} that
* represents a MH bound to a generic invoker, which in turn forwards to the corresponding
* getter.
*/
Name getterName(Name mhName, int i) {
MethodHandle mh = getters[i];
assert(mh != null) : this+"."+i;
return new Name(mh, mhName);
}
项目:openjdk-icedtea7
文件:InvokerBytecodeGenerator.java
/**
* Generate an invoker method for the passed {@link LambdaForm}.
*/
private byte[] generateCustomizedCodeBytes() {
classFilePrologue();
// Suppress this method in backtraces displayed to the user.
mv.visitAnnotation("Ljava/lang/invoke/LambdaForm$Hidden;", true);
// Mark this method as a compiled LambdaForm
mv.visitAnnotation("Ljava/lang/invoke/LambdaForm$Compiled;", true);
// Force inlining of this invoker method.
mv.visitAnnotation("Ljava/lang/invoke/ForceInline;", true);
// iterate over the form's names, generating bytecode instructions for each
// start iterating at the first name following the arguments
for (int i = lambdaForm.arity; i < lambdaForm.names.length; i++) {
Name name = lambdaForm.names[i];
MemberName member = name.function.member();
if (isSelectAlternative(member)) {
// selectAlternative idiom
// FIXME: make sure this idiom is really present!
emitSelectAlternative(name, lambdaForm.names[i + 1]);
i++; // skip MH.invokeBasic of the selectAlternative result
} else if (isStaticallyInvocable(member)) {
emitStaticInvoke(member, name);
} else {
emitInvoke(name);
}
// store the result from evaluating to the target name in a local if required
// (if this is the last value, i.e., the one that is going to be returned,
// avoid store/load/return and just return)
if (i == lambdaForm.names.length - 1 && i == lambdaForm.result) {
// return value - do nothing
} else if (name.type != 'V') {
// non-void: actually assign
emitStoreInsn(name.type, name.index());
}
}
// return statement
emitReturn();
classFileEpilogue();
bogusMethod(lambdaForm);
final byte[] classFile = cw.toByteArray();
maybeDump(className, classFile);
return classFile;
}
项目:openjdk-icedtea7
文件:InvokerBytecodeGenerator.java
/**
* Emits a return statement from a LF invoker. If required, the result type is cast to the correct return type.
*/
private void emitReturn() {
// return statement
if (lambdaForm.result == -1) {
// void
mv.visitInsn(Opcodes.RETURN);
} else {
LambdaForm.Name rn = lambdaForm.names[lambdaForm.result];
char rtype = Wrapper.basicTypeChar(invokerType.returnType());
// put return value on the stack if it is not already there
if (lambdaForm.result != lambdaForm.names.length - 1) {
emitLoadInsn(rn.type, lambdaForm.result);
}
// potentially generate cast
// rtype is the return type of the invoker - generated code must conform to this
// rn.type is the type of the result Name in the LF
if (rtype != rn.type) {
// need cast
if (rtype == 'L') {
// possibly cast the primitive to the correct type for boxing
char boxedType = Wrapper.forWrapperType(invokerType.returnType()).basicTypeChar();
if (boxedType != rn.type) {
emitPrimCast(rn.type, boxedType);
}
// cast primitive to reference ("boxing")
emitBoxing(invokerType.returnType());
} else {
// to-primitive cast
if (rn.type != 'L') {
// prim-to-prim cast
emitPrimCast(rn.type, rtype);
} else {
// ref-to-prim cast ("unboxing")
throw new InternalError("no ref-to-prim (unboxing) casts supported right now");
}
}
}
// generate actual return statement
emitReturnInsn(invokerType.returnType());
}
}