Class SAMweaver
- All Implemented Interfaces:
Constants,org.objectweb.asm.Opcodes
SAMweaver generates code to support functional interfaces (also known
as SAM, for Single Abstract Method), where the SAM method is pausable. What
makes SAM interfaces special compared to regular interfaces is that they can
represent a lambda function in java8. More on this later.
Imagine that a class called X uses a I of the
following form:
interface I {
int foo(double d) throws Pausable;
}
Since I is a SAM, CallWeaver replaces all
invokeinterface I.foo(double) with a static invocation of a tiny
wrapper method ('shim') in X like this:
invokestatic X.$shim$2(I callee, double d, Fiber f)
The shim method in turn turns around and calls I.foo(double):
private static int X.$shim$2(I callee, double d, Fiber f) {
int ret = callee.f(d, f);
f.setCallee(callee); // this is the purpose of the shim
return ret;
}
The purpose of SAMweaver is to generate the shim above.
Why?
Ordinarily, all hand-written code is modified by the weaver if it contains
definitions or invocations of pausable methods. Lambda expressions however
rely on the VM generating a class at run-time, which implements the
functional interface (I in the example). The problem is that
this class needs to be woven to support kilim Fibers, but we don't have an
easy portable hook to weave it at run-time.
As it turns out, practically all the weaving work is already complete at
compile time. This is because, the body of the lambda expression is already
available to the weaver as an ordinary method in the host class
X, and is treated like any another pausable method. In other
words, the transformations at the calling site and in the body of the called
method are as usual.
All that this is left for the shim to do is to capture the object's reference
(f.setCallee); the fiber needs it while resuming. The call to
setCallee is redundant for ordinary hand-written implementations of SAM
interfaces, but is necessary if the implementation happens to be generated by
the VM as described above.
Of course, all this applies only if the functional method is pausable.
-
Nested Class Summary
Nested classes/interfaces inherited from interface kilim.Constants
Constants.Util -
Field Summary
FieldsModifier and TypeFieldDescription(package private) KilimContext(package private) String(package private) int(package private) String(package private) boolean(package private) StringFields inherited from interface kilim.Constants
ALOAD_0, ASTORE_0, D_ARRAY_BOOLEAN, D_ARRAY_BYTE, D_ARRAY_CHAR, D_ARRAY_DOUBLE, D_ARRAY_FLOAT, D_ARRAY_INT, D_ARRAY_LONG, D_ARRAY_SHORT, D_BOOLEAN, D_BYTE, D_CHAR, D_DOUBLE, D_FIBER, D_FIBER_LAST_ARG, D_FLOAT, D_INT, D_LONG, D_NULL, D_OBJECT, D_PAUSABLE, D_RETURN_ADDRESS, D_SHORT, D_STATE, D_STRING, D_TASK, D_THROWABLE, D_UNDEFINED, D_VOID, DLOAD_0, DSTORE_0, FIBER_CLASS, FLOAD_0, FSTORE_0, ILOAD_0, ISTORE_0, KILIM_ASM, KILIM_VERSION, LDC2_W, LLOAD_0, LSTORE_0, NOT_PAUSABLE_CLASS, PAUSABLE_CLASS, SAM_SHIM_PREFIX, STATE_CLASS, TASK_CLASS, THROWABLE_CLASS, WOVEN_FIELDFields inherited from interface org.objectweb.asm.Opcodes
AALOAD, AASTORE, ACC_ABSTRACT, ACC_ANNOTATION, ACC_BRIDGE, ACC_DEPRECATED, ACC_ENUM, ACC_FINAL, ACC_INTERFACE, ACC_MANDATED, ACC_MODULE, ACC_NATIVE, ACC_OPEN, ACC_PRIVATE, ACC_PROTECTED, ACC_PUBLIC, ACC_RECORD, ACC_STATIC, ACC_STATIC_PHASE, ACC_STRICT, ACC_SUPER, ACC_SYNCHRONIZED, ACC_SYNTHETIC, ACC_TRANSIENT, ACC_TRANSITIVE, ACC_VARARGS, ACC_VOLATILE, ACONST_NULL, ALOAD, ANEWARRAY, ARETURN, ARRAYLENGTH, ASM10_EXPERIMENTAL, ASM4, ASM5, ASM6, ASM7, ASM8, ASM9, ASTORE, ATHROW, BALOAD, BASTORE, BIPUSH, CALOAD, CASTORE, CHECKCAST, D2F, D2I, D2L, DADD, DALOAD, DASTORE, DCMPG, DCMPL, DCONST_0, DCONST_1, DDIV, DLOAD, DMUL, DNEG, DOUBLE, DREM, DRETURN, DSTORE, DSUB, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1, DUP2_X2, F_APPEND, F_CHOP, F_FULL, F_NEW, F_SAME, F_SAME1, F2D, F2I, F2L, FADD, FALOAD, FASTORE, FCMPG, FCMPL, FCONST_0, FCONST_1, FCONST_2, FDIV, FLOAD, FLOAT, FMUL, FNEG, FREM, FRETURN, FSTORE, FSUB, GETFIELD, GETSTATIC, GOTO, H_GETFIELD, H_GETSTATIC, H_INVOKEINTERFACE, H_INVOKESPECIAL, H_INVOKESTATIC, H_INVOKEVIRTUAL, H_NEWINVOKESPECIAL, H_PUTFIELD, H_PUTSTATIC, I2B, I2C, I2D, I2F, I2L, I2S, IADD, IALOAD, IAND, IASTORE, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4, ICONST_5, ICONST_M1, IDIV, IF_ACMPEQ, IF_ACMPNE, IF_ICMPEQ, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ICMPLT, IF_ICMPNE, IFEQ, IFGE, IFGT, IFLE, IFLT, IFNE, IFNONNULL, IFNULL, IINC, ILOAD, IMUL, INEG, INSTANCEOF, INTEGER, INVOKEDYNAMIC, INVOKEINTERFACE, INVOKESPECIAL, INVOKESTATIC, INVOKEVIRTUAL, IOR, IREM, IRETURN, ISHL, ISHR, ISTORE, ISUB, IUSHR, IXOR, JSR, L2D, L2F, L2I, LADD, LALOAD, LAND, LASTORE, LCMP, LCONST_0, LCONST_1, LDC, LDIV, LLOAD, LMUL, LNEG, LONG, LOOKUPSWITCH, LOR, LREM, LRETURN, LSHL, LSHR, LSTORE, LSUB, LUSHR, LXOR, MONITORENTER, MONITOREXIT, MULTIANEWARRAY, NEW, NEWARRAY, NOP, NULL, POP, POP2, PUTFIELD, PUTSTATIC, RET, RETURN, SALOAD, SASTORE, SIPUSH, SOURCE_DEPRECATED, SOURCE_MASK, SWAP, T_BOOLEAN, T_BYTE, T_CHAR, T_DOUBLE, T_FLOAT, T_INT, T_LONG, T_SHORT, TABLESWITCH, TOP, UNINITIALIZED_THIS, V_PREVIEW, V1_1, V1_2, V1_3, V1_4, V1_5, V1_6, V1_7, V1_8, V10, V11, V12, V13, V14, V15, V16, V17, V18, V19, V20, V21, V22, V23, V24, V25, V26, V9 -
Constructor Summary
ConstructorsConstructorDescriptionSAMweaver(KilimContext context, String interfaceName, String methodName, String desc, boolean itf) -
Method Summary
Modifier and TypeMethodDescriptionvoidaccept(org.objectweb.asm.ClassVisitor cv) Generate a method like this:booleanprivate String[](package private) String(package private) StringinthashCode()(package private) static String[]internalName(String[] words) voidsetIndex(int index) toString()
-
Field Details
-
interfaceName
String interfaceName -
methodName
String methodName -
desc
String desc -
itf
boolean itf -
index
int index -
context
KilimContext context
-
-
Constructor Details
-
SAMweaver
public SAMweaver(KilimContext context, String interfaceName, String methodName, String desc, boolean itf)
-
-
Method Details
-
setIndex
public void setIndex(int index) -
equals
-
toString
-
hashCode
public int hashCode() -
getShimMethodName
String getShimMethodName() -
getShimDesc
String getShimDesc() -
accept
public void accept(org.objectweb.asm.ClassVisitor cv) Generate a method like this:private static $shim$1 (I callee, ...args..., f fiber) { load each arg call interface.method f.setCallee(arg0) xret }- Parameters:
cv-
-
internalName
-
getExceptions
-