use of org.objectweb.asm.Handle in project MinecraftForge by MinecraftForge.
the class SideTransformer method transform.
@Override
public byte[] transform(String name, String transformedName, byte[] bytes) {
if (bytes == null) {
return null;
}
ClassNode classNode = new ClassNode();
ClassReader classReader = new ClassReader(bytes);
classReader.accept(classNode, 0);
if (remove(classNode.visibleAnnotations, SIDE)) {
if (DEBUG) {
System.out.println(String.format("Attempted to load class %s for invalid side %s", classNode.name, SIDE));
}
throw new RuntimeException(String.format("Attempted to load class %s for invalid side %s", classNode.name, SIDE));
}
Iterator<FieldNode> fields = classNode.fields.iterator();
while (fields.hasNext()) {
FieldNode field = fields.next();
if (remove(field.visibleAnnotations, SIDE)) {
if (DEBUG) {
System.out.println(String.format("Removing Field: %s.%s", classNode.name, field.name));
}
fields.remove();
}
}
LambdaGatherer lambdaGatherer = new LambdaGatherer();
Iterator<MethodNode> methods = classNode.methods.iterator();
while (methods.hasNext()) {
MethodNode method = methods.next();
if (remove(method.visibleAnnotations, SIDE)) {
if (DEBUG) {
System.out.println(String.format("Removing Method: %s.%s%s", classNode.name, method.name, method.desc));
}
methods.remove();
lambdaGatherer.accept(method);
}
}
// remove dynamic lambda methods that are inside of removed methods
List<Handle> dynamicLambdaHandles = lambdaGatherer.getDynamicLambdaHandles();
if (!dynamicLambdaHandles.isEmpty()) {
methods = classNode.methods.iterator();
while (methods.hasNext()) {
MethodNode method = methods.next();
for (Handle dynamicLambdaHandle : dynamicLambdaHandles) {
if (method.name.equals(dynamicLambdaHandle.getName()) && method.desc.equals(dynamicLambdaHandle.getDesc())) {
if (DEBUG) {
System.out.println(String.format("Removing Method: %s.%s%s", classNode.name, method.name, method.desc));
}
methods.remove();
}
}
}
}
ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
classNode.accept(writer);
return writer.toByteArray();
}
use of org.objectweb.asm.Handle in project dex2jar by pxb1988.
the class J2IRConverter method buildInterpreter.
private Interpreter<JvmValue> buildInterpreter() {
return new Interpreter<JvmValue>(Opcodes.ASM4) {
@Override
public JvmValue newValue(Type type) {
return null;
}
@Override
public JvmValue newOperation(AbstractInsnNode insn) throws AnalyzerException {
switch(insn.getOpcode()) {
case ACONST_NULL:
return b(1, Exprs.nNull());
case ICONST_M1:
case ICONST_0:
case ICONST_1:
case ICONST_2:
case ICONST_3:
case ICONST_4:
case ICONST_5:
return b(1, Exprs.nInt(insn.getOpcode() - ICONST_0));
case LCONST_0:
case LCONST_1:
return b(2, Exprs.nLong(insn.getOpcode() - LCONST_0));
case FCONST_0:
case FCONST_1:
case FCONST_2:
return b(1, Exprs.nFloat(insn.getOpcode() - FCONST_0));
case DCONST_0:
case DCONST_1:
return b(2, Exprs.nDouble(insn.getOpcode() - DCONST_0));
case BIPUSH:
case SIPUSH:
return b(1, Exprs.nInt(((IntInsnNode) insn).operand));
case LDC:
Object cst = ((LdcInsnNode) insn).cst;
if (cst instanceof Integer) {
return b(1, Exprs.nInt((Integer) cst));
} else if (cst instanceof Float) {
return b(1, Exprs.nFloat((Float) cst));
} else if (cst instanceof Long) {
return b(2, Exprs.nLong((Long) cst));
} else if (cst instanceof Double) {
return b(2, Exprs.nDouble((Double) cst));
} else if (cst instanceof String) {
return b(1, Exprs.nString((String) cst));
} else if (cst instanceof Type) {
Type type = (Type) cst;
int sort = type.getSort();
if (sort == Type.OBJECT || sort == Type.ARRAY) {
return b(1, Exprs.nType(type.getDescriptor()));
} else if (sort == Type.METHOD) {
throw new UnsupportedOperationException("Not supported yet.");
} else {
throw new IllegalArgumentException("Illegal LDC constant " + cst);
}
} else if (cst instanceof Handle) {
throw new UnsupportedOperationException("Not supported yet.");
} else {
throw new IllegalArgumentException("Illegal LDC constant " + cst);
}
case JSR:
throw new UnsupportedOperationException("Not supported yet.");
case GETSTATIC:
FieldInsnNode fin = (FieldInsnNode) insn;
return b(Type.getType(fin.desc).getSize(), Exprs.nStaticField("L" + fin.owner + ";", fin.name, fin.desc));
case NEW:
return b(1, Exprs.nNew("L" + ((TypeInsnNode) insn).desc + ";"));
default:
throw new Error("Internal error.");
}
}
@Override
public JvmValue copyOperation(AbstractInsnNode insn, JvmValue value) throws AnalyzerException {
return b(value.getSize(), getLocal(value));
}
@Override
public JvmValue unaryOperation(AbstractInsnNode insn, JvmValue value0) throws AnalyzerException {
Local local = value0 == null ? null : getLocal(value0);
switch(insn.getOpcode()) {
case INEG:
return b(1, Exprs.nNeg(local, "I"));
case IINC:
return b(1, Exprs.nAdd(local, Exprs.nInt(((IincInsnNode) insn).incr), "I"));
case L2I:
return b(1, Exprs.nCast(local, "J", "I"));
case F2I:
return b(1, Exprs.nCast(local, "F", "I"));
case D2I:
return b(1, Exprs.nCast(local, "D", "I"));
case I2B:
return b(1, Exprs.nCast(local, "I", "B"));
case I2C:
return b(1, Exprs.nCast(local, "I", "C"));
case I2S:
return b(1, Exprs.nCast(local, "I", "S"));
case FNEG:
return b(1, Exprs.nNeg(local, "F"));
case I2F:
return b(1, Exprs.nCast(local, "I", "F"));
case L2F:
return b(1, Exprs.nCast(local, "J", "F"));
case D2F:
return b(1, Exprs.nCast(local, "D", "F"));
case LNEG:
return b(2, Exprs.nNeg(local, "J"));
case I2L:
return b(2, Exprs.nCast(local, "I", "J"));
case F2L:
return b(2, Exprs.nCast(local, "F", "J"));
case D2L:
return b(2, Exprs.nCast(local, "D", "J"));
case DNEG:
return b(2, Exprs.nNeg(local, "D"));
case I2D:
return b(2, Exprs.nCast(local, "I", "D"));
case L2D:
return b(2, Exprs.nCast(local, "J", "D"));
case F2D:
return b(2, Exprs.nCast(local, "F", "D"));
case IFEQ:
emit(Stmts.nIf(Exprs.nEq(local, Exprs.nInt(0), "I"), getLabel(((JumpInsnNode) insn).label)));
return null;
case IFNE:
emit(Stmts.nIf(Exprs.nNe(local, Exprs.nInt(0), "I"), getLabel(((JumpInsnNode) insn).label)));
return null;
case IFLT:
emit(Stmts.nIf(Exprs.nLt(local, Exprs.nInt(0), "I"), getLabel(((JumpInsnNode) insn).label)));
return null;
case IFGE:
emit(Stmts.nIf(Exprs.nGe(local, Exprs.nInt(0), "I"), getLabel(((JumpInsnNode) insn).label)));
return null;
case IFGT:
emit(Stmts.nIf(Exprs.nGt(local, Exprs.nInt(0), "I"), getLabel(((JumpInsnNode) insn).label)));
return null;
case IFLE:
emit(Stmts.nIf(Exprs.nLe(local, Exprs.nInt(0), "I"), getLabel(((JumpInsnNode) insn).label)));
return null;
case TABLESWITCH:
{
TableSwitchInsnNode ts = (TableSwitchInsnNode) insn;
LabelStmt[] targets = new LabelStmt[ts.labels.size()];
for (int i = 0; i < ts.labels.size(); i++) {
targets[i] = getLabel((LabelNode) ts.labels.get(i));
}
emit(Stmts.nTableSwitch(local, ts.min, targets, getLabel(ts.dflt)));
return null;
}
case LOOKUPSWITCH:
{
LookupSwitchInsnNode ls = (LookupSwitchInsnNode) insn;
LabelStmt[] targets = new LabelStmt[ls.labels.size()];
int[] lookupValues = new int[ls.labels.size()];
for (int i = 0; i < ls.labels.size(); i++) {
targets[i] = getLabel((LabelNode) ls.labels.get(i));
lookupValues[i] = (Integer) ls.keys.get(i);
}
emit(Stmts.nLookupSwitch(local, lookupValues, targets, getLabel(ls.dflt)));
return null;
}
case IRETURN:
case LRETURN:
case FRETURN:
case DRETURN:
case ARETURN:
// skip, move to returnOperation
return null;
case PUTSTATIC:
{
FieldInsnNode fin = (FieldInsnNode) insn;
emit(Stmts.nAssign(Exprs.nStaticField("L" + fin.owner + ";", fin.name, fin.desc), local));
return null;
}
case GETFIELD:
{
FieldInsnNode fin = (FieldInsnNode) insn;
Type fieldType = Type.getType(fin.desc);
return b(fieldType.getSize(), Exprs.nField(local, "L" + fin.owner + ";", fin.name, fin.desc));
}
case NEWARRAY:
switch(((IntInsnNode) insn).operand) {
case T_BOOLEAN:
return b(1, Exprs.nNewArray("Z", local));
case T_CHAR:
return b(1, Exprs.nNewArray("C", local));
case T_BYTE:
return b(1, Exprs.nNewArray("B", local));
case T_SHORT:
return b(1, Exprs.nNewArray("S", local));
case T_INT:
return b(1, Exprs.nNewArray("I", local));
case T_FLOAT:
return b(1, Exprs.nNewArray("F", local));
case T_DOUBLE:
return b(1, Exprs.nNewArray("D", local));
case T_LONG:
return b(1, Exprs.nNewArray("D", local));
default:
throw new AnalyzerException(insn, "Invalid array type");
}
case ANEWARRAY:
String desc = "L" + ((TypeInsnNode) insn).desc + ";";
return b(1, Exprs.nNewArray(desc, local));
case ARRAYLENGTH:
return b(1, Exprs.nLength(local));
case ATHROW:
emit(Stmts.nThrow(local));
return null;
case CHECKCAST:
String orgDesc = ((TypeInsnNode) insn).desc;
desc = orgDesc.startsWith("[") ? orgDesc : ("L" + orgDesc + ";");
return b(1, Exprs.nCheckCast(local, desc));
case INSTANCEOF:
return b(1, Exprs.nInstanceOf(local, "L" + ((TypeInsnNode) insn).desc + ";"));
case MONITORENTER:
emit(Stmts.nLock(local));
return null;
case MONITOREXIT:
emit(Stmts.nUnLock(local));
return null;
case IFNULL:
emit(Stmts.nIf(Exprs.nEq(local, Exprs.nNull(), "L"), getLabel(((JumpInsnNode) insn).label)));
return null;
case IFNONNULL:
emit(Stmts.nIf(Exprs.nNe(local, Exprs.nNull(), "L"), getLabel(((JumpInsnNode) insn).label)));
return null;
case // special case
GOTO:
emit(Stmts.nGoto(getLabel(((JumpInsnNode) insn).label)));
return null;
default:
throw new Error("Internal error.");
}
}
JvmValue b(int size, com.googlecode.dex2jar.ir.expr.Value value) {
Local local = newLocal();
emit(Stmts.nAssign(local, value));
return new JvmValue(size, local);
}
@Override
public JvmValue binaryOperation(AbstractInsnNode insn, JvmValue value10, JvmValue value20) throws AnalyzerException {
Local local1 = getLocal(value10);
Local local2 = getLocal(value20);
switch(insn.getOpcode()) {
case IALOAD:
return b(1, Exprs.nArray(local1, local2, "I"));
case BALOAD:
return b(1, Exprs.nArray(local1, local2, "B"));
case CALOAD:
return b(1, Exprs.nArray(local1, local2, "C"));
case SALOAD:
return b(1, Exprs.nArray(local1, local2, "S"));
case FALOAD:
return b(1, Exprs.nArray(local1, local2, "F"));
case AALOAD:
return b(1, Exprs.nArray(local1, local2, "L"));
case DALOAD:
return b(1, Exprs.nArray(local1, local2, "D"));
case LALOAD:
return b(1, Exprs.nArray(local1, local2, "J"));
case IADD:
return b(1, Exprs.nAdd(local1, local2, "I"));
case ISUB:
return b(1, Exprs.nSub(local1, local2, "I"));
case IMUL:
return b(1, Exprs.nMul(local1, local2, "I"));
case IDIV:
return b(1, Exprs.nDiv(local1, local2, "I"));
case IREM:
return b(1, Exprs.nRem(local1, local2, "I"));
case ISHL:
return b(1, Exprs.nShl(local1, local2, "I"));
case ISHR:
return b(1, Exprs.nShr(local1, local2, "I"));
case IUSHR:
return b(1, Exprs.nUshr(local1, local2, "I"));
case IAND:
return b(1, Exprs.nAnd(local1, local2, "I"));
case IOR:
return b(1, Exprs.nOr(local1, local2, "I"));
case IXOR:
return b(1, Exprs.nXor(local1, local2, "I"));
case FADD:
return b(1, Exprs.nAdd(local1, local2, "F"));
case FSUB:
return b(1, Exprs.nSub(local1, local2, "F"));
case FMUL:
return b(1, Exprs.nMul(local1, local2, "F"));
case FDIV:
return b(1, Exprs.nDiv(local1, local2, "F"));
case FREM:
return b(1, Exprs.nRem(local1, local2, "F"));
case LADD:
return b(2, Exprs.nAdd(local1, local2, "J"));
case LSUB:
return b(2, Exprs.nSub(local1, local2, "J"));
case LMUL:
return b(2, Exprs.nMul(local1, local2, "J"));
case LDIV:
return b(2, Exprs.nDiv(local1, local2, "J"));
case LREM:
return b(2, Exprs.nRem(local1, local2, "J"));
case LSHL:
return b(2, Exprs.nShl(local1, local2, "J"));
case LSHR:
return b(2, Exprs.nShr(local1, local2, "J"));
case LUSHR:
return b(2, Exprs.nUshr(local1, local2, "J"));
case LAND:
return b(2, Exprs.nAnd(local1, local2, "J"));
case LOR:
return b(2, Exprs.nOr(local1, local2, "J"));
case LXOR:
return b(2, Exprs.nXor(local1, local2, "J"));
case DADD:
return b(2, Exprs.nAdd(local1, local2, "D"));
case DSUB:
return b(2, Exprs.nSub(local1, local2, "D"));
case DMUL:
return b(2, Exprs.nMul(local1, local2, "D"));
case DDIV:
return b(2, Exprs.nDiv(local1, local2, "D"));
case DREM:
return b(2, Exprs.nRem(local1, local2, "D"));
case LCMP:
return b(2, Exprs.nLCmp(local1, local2));
case FCMPL:
return b(1, Exprs.nFCmpl(local1, local2));
case FCMPG:
return b(1, Exprs.nFCmpg(local1, local2));
case DCMPL:
return b(2, Exprs.nDCmpl(local1, local2));
case DCMPG:
return b(2, Exprs.nDCmpg(local1, local2));
case IF_ICMPEQ:
emit(Stmts.nIf(Exprs.nEq(local1, local2, "I"), getLabel(((JumpInsnNode) insn).label)));
return null;
case IF_ICMPNE:
emit(Stmts.nIf(Exprs.nNe(local1, local2, "I"), getLabel(((JumpInsnNode) insn).label)));
return null;
case IF_ICMPLT:
emit(Stmts.nIf(Exprs.nLt(local1, local2, "I"), getLabel(((JumpInsnNode) insn).label)));
return null;
case IF_ICMPGE:
emit(Stmts.nIf(Exprs.nGe(local1, local2, "I"), getLabel(((JumpInsnNode) insn).label)));
return null;
case IF_ICMPGT:
emit(Stmts.nIf(Exprs.nGt(local1, local2, "I"), getLabel(((JumpInsnNode) insn).label)));
return null;
case IF_ICMPLE:
emit(Stmts.nIf(Exprs.nLe(local1, local2, "I"), getLabel(((JumpInsnNode) insn).label)));
return null;
case IF_ACMPEQ:
emit(Stmts.nIf(Exprs.nEq(local1, local2, "L"), getLabel(((JumpInsnNode) insn).label)));
return null;
case IF_ACMPNE:
emit(Stmts.nIf(Exprs.nNe(local1, local2, "L"), getLabel(((JumpInsnNode) insn).label)));
return null;
case PUTFIELD:
FieldInsnNode fin = (FieldInsnNode) insn;
emit(Stmts.nAssign(Exprs.nField(local1, "L" + fin.owner + ";", fin.name, fin.desc), local2));
return null;
default:
throw new Error("Internal error.");
}
}
@Override
public JvmValue ternaryOperation(AbstractInsnNode insn, JvmValue value1, JvmValue value2, JvmValue value3) throws AnalyzerException {
Local local1 = getLocal(value1);
Local local2 = getLocal(value2);
Local local3 = getLocal(value3);
switch(insn.getOpcode()) {
case IASTORE:
emit(Stmts.nAssign(Exprs.nArray(local1, local2, "I"), local3));
break;
case LASTORE:
emit(Stmts.nAssign(Exprs.nArray(local1, local2, "J"), local3));
break;
case FASTORE:
emit(Stmts.nAssign(Exprs.nArray(local1, local2, "F"), local3));
break;
case DASTORE:
emit(Stmts.nAssign(Exprs.nArray(local1, local2, "D"), local3));
break;
case AASTORE:
emit(Stmts.nAssign(Exprs.nArray(local1, local2, "L"), local3));
break;
case BASTORE:
emit(Stmts.nAssign(Exprs.nArray(local1, local2, "B"), local3));
break;
case CASTORE:
emit(Stmts.nAssign(Exprs.nArray(local1, local2, "C"), local3));
break;
case SASTORE:
emit(Stmts.nAssign(Exprs.nArray(local1, local2, "S"), local3));
break;
}
return null;
}
public String[] toDescArray(Type[] ts) {
String[] ds = new String[ts.length];
for (int i = 0; i < ts.length; i++) {
ds[i] = ts[i].getDescriptor();
}
return ds;
}
@Override
public JvmValue naryOperation(AbstractInsnNode insn, List<? extends JvmValue> xvalues) throws AnalyzerException {
com.googlecode.dex2jar.ir.expr.Value[] values = new com.googlecode.dex2jar.ir.expr.Value[xvalues.size()];
for (int i = 0; i < xvalues.size(); i++) {
values[i] = getLocal(xvalues.get(i));
}
if (insn.getOpcode() == MULTIANEWARRAY) {
throw new UnsupportedOperationException("Not supported yet.");
} else {
MethodInsnNode mi = (MethodInsnNode) insn;
com.googlecode.dex2jar.ir.expr.Value v = null;
String ret = Type.getReturnType(mi.desc).getDescriptor();
String owner = "L" + mi.owner + ";";
String[] ps = toDescArray(Type.getArgumentTypes(mi.desc));
switch(insn.getOpcode()) {
case INVOKEVIRTUAL:
v = Exprs.nInvokeVirtual(values, owner, mi.name, ps, ret);
break;
case INVOKESPECIAL:
v = Exprs.nInvokeSpecial(values, owner, mi.name, ps, ret);
break;
case INVOKESTATIC:
v = Exprs.nInvokeStatic(values, owner, mi.name, ps, ret);
break;
case INVOKEINTERFACE:
v = Exprs.nInvokeInterface(values, owner, mi.name, ps, ret);
break;
case INVOKEDYNAMIC:
throw new UnsupportedOperationException("Not supported yet.");
}
if ("V".equals(ret)) {
emit(Stmts.nVoidInvoke(v));
return null;
} else {
return b(Type.getReturnType(mi.desc).getSize(), v);
}
}
}
@Override
public JvmValue merge(JvmValue v, JvmValue w) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public void returnOperation(AbstractInsnNode insn, JvmValue value, JvmValue expected) throws AnalyzerException {
switch(insn.getOpcode()) {
case IRETURN:
case LRETURN:
case FRETURN:
case DRETURN:
case ARETURN:
emit(Stmts.nReturn(getLocal(value)));
break;
case RETURN:
emit(Stmts.nReturnVoid());
break;
}
}
};
}
use of org.objectweb.asm.Handle in project byte-buddy by raphw.
the class MethodInvocationDynamicTest method testDynamicConstructorBootstrap.
@Test
public void testDynamicConstructorBootstrap() throws Exception {
when(methodDescription.isBootstrap()).thenReturn(true);
when(methodDescription.isConstructor()).thenReturn(true);
StackManipulation stackManipulation = MethodInvocation.invoke(methodDescription).dynamic(FOO, returnType, Arrays.asList(firstType, secondType), Collections.singletonList(argument));
assertThat(stackManipulation.isValid(), is(true));
StackManipulation.Size size = stackManipulation.apply(methodVisitor, implementationContext);
assertThat(size.getSizeImpact(), is(0));
assertThat(size.getMaximalSize(), is(0));
verify(methodVisitor).visitInvokeDynamicInsn(FOO, "(" + FOO + BAR + ")" + QUX, new Handle(Opcodes.H_NEWINVOKESPECIAL, BAR, QUX, BAZ, false), argument);
}
use of org.objectweb.asm.Handle in project byte-buddy by raphw.
the class MethodInvocationDynamicTest method testDynamicStaticBootstrap.
@Test
public void testDynamicStaticBootstrap() throws Exception {
when(methodDescription.isBootstrap()).thenReturn(true);
when(methodDescription.isStatic()).thenReturn(true);
StackManipulation stackManipulation = MethodInvocation.invoke(methodDescription).dynamic(FOO, returnType, Arrays.asList(firstType, secondType), Collections.singletonList(argument));
assertThat(stackManipulation.isValid(), is(true));
StackManipulation.Size size = stackManipulation.apply(methodVisitor, implementationContext);
assertThat(size.getSizeImpact(), is(0));
assertThat(size.getMaximalSize(), is(0));
verify(methodVisitor).visitInvokeDynamicInsn(FOO, "(" + FOO + BAR + ")" + QUX, new Handle(Opcodes.H_INVOKESTATIC, BAR, QUX, BAZ, false), argument);
}
use of org.objectweb.asm.Handle in project seph by seph-lang.
the class AbstractionCompiler method compileArgument.
private void compileArgument(Message argument, int currentMessageIndex, int argIndex, List<ArgumentEntry> currentArguments, Message last, List<Handle> mhsAndAsts) {
// printThisClass = true;
String keyword = null;
Message argumentToCompile = argument;
String name = argument.name();
if (name.endsWith(":")) {
keyword = name.substring(0, name.length() - 1);
argumentToCompile = argument.next();
}
final String codeName = "code_arg_" + currentMessageIndex + "_" + argIndex;
final String handleName = "handle_arg_" + currentMessageIndex + "_" + argIndex;
final String methodName = "argument_" + currentMessageIndex + "_" + argIndex;
ArgumentEntry ae = new ArgumentEntry(codeName, handleName, methodName, argument, keyword);
mhsAndAsts.add(new Handle(H_INVOKESTATIC, className, methodName, sig(SephObject.class, LexicalScope.class, SThread.class, LexicalScope.class, boolean.class, boolean.class)));
mhsAndAsts.add(new Handle(H_GETSTATIC, className, codeName, c(SephObject.class)));
arguments.add(ae);
currentArguments.add(ae);
cw.visitField(ACC_PRIVATE + ACC_STATIC, codeName, c(SephObject.class), null, null);
cw.visitField(ACC_PRIVATE + ACC_STATIC, handleName, c(MethodHandle.class), null, null);
MethodAdapter ma = new MethodAdapter(cw.visitMethod(ACC_PUBLIC + ACC_STATIC, methodName, sig(SephObject.class, LexicalScope.class, SThread.class, LexicalScope.class, boolean.class, boolean.class), null, null));
int[] layout = VARIABLE_LAYOUT_ARGUMENT_METHOD;
ma.loadLocalInt(layout[SHOULD_EVALUATE_IDX]);
ma.zero();
Label els = new Label();
ma.ifNotEqual(els);
ma.getStatic(className, codeName, SephObject.class);
ma.retValue();
ma.label(els);
Message current = argumentToCompile;
ma.loadLocal(layout[METHOD_SCOPE_IDX]);
ma.getField(LexicalScope.class, "ground", SephObject.class);
ma.dup();
ma.storeLocal(layout[RECEIVER_IDX]);
boolean first = true;
while (current != null) {
ma.line(current.line());
if (current.isLiteral()) {
compileLiteral(ma, current);
first = false;
} else if (current instanceof Terminator) {
compileTerminator(ma, current, layout);
first = true;
} else if (current instanceof Abstraction) {
ma.pop();
String aname = currentAssignment;
if (aname == null) {
aname = "__inline__";
}
String newName = AbstractionCompiler.compile(this.runtime, RT.seq(current.arguments()), ((Abstraction) current).scope, scope, aname);
ma.create(newName);
ma.dup();
ma.loadLocal(0);
ma.init(newName, Void.TYPE, LexicalScope.class);
first = false;
} else if (current instanceof Assignment) {
compileAssignment(ma, (Assignment) current, layout);
first = false;
} else {
compileMessageSend(ma, current, layout, first, last);
first = false;
}
current = current.next();
}
ma.retValue();
ma.end();
}
Aggregations