List of usage examples for org.objectweb.asm Opcodes IFNE
int IFNE
To view the source code for org.objectweb.asm Opcodes IFNE.
Click Source Link
From source file:edu.umd.cs.guitar.testcase.plugin.edg.ClassDBVisitor.java
License:Open Source License
@Override public void visitJumpInsn(int opcode, Label label) { currentMethod.setEmpty(false);/*from w ww .ja v a 2s . com*/ currentMethod.setEmpty(false); switch (opcode) { case Opcodes.IFEQ: case Opcodes.IFNE: case Opcodes.IFLT: case Opcodes.IFGE: case Opcodes.IFGT: case Opcodes.IFLE: case Opcodes.IF_ICMPEQ: case Opcodes.IF_ICMPNE: case Opcodes.IF_ICMPLT: case Opcodes.IF_ICMPGE: case Opcodes.IF_ICMPGT: case Opcodes.IF_ICMPLE: case Opcodes.IF_ACMPEQ: case Opcodes.IF_ACMPNE: // case Opcodes.GOTO: // case Opcodes.JSR: case Opcodes.IFNULL: case Opcodes.IFNONNULL: // add all label reads/writes as condition reads/writes currentMethod.getConditionReads().addAll(labelReads); currentMethod.getConditionWrites().addAll(labelWrites); break; } }
From source file:gnu.classpath.tools.rmic.ClassRmicCompiler.java
License:Open Source License
private void generateSkel() throws IOException { skelname = fullclassname + "_Skel"; String skelclassname = classname + "_Skel"; File file = new File(destination == null ? "" : destination + File.separator + skelname.replace('.', File.separatorChar) + ".class"); if (verbose)/*from w w w.ja v a 2s . c o m*/ System.out.println("[Generating class " + skelname + "]"); final ClassWriter skel = new ClassWriter(true); classInternalName = skelname.replace('.', '/'); skel.visit(Opcodes.V1_1, Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL, classInternalName, Type.getInternalName(Object.class), null, new String[] { Type.getType(Skeleton.class).getInternalName() }); skel.visitField(Opcodes.ACC_PRIVATE + Opcodes.ACC_STATIC + Opcodes.ACC_FINAL, "interfaceHash", Type.LONG_TYPE.getDescriptor(), null, new Long(RMIHashes.getInterfaceHash(clazz))); skel.visitField(Opcodes.ACC_PRIVATE + Opcodes.ACC_STATIC + Opcodes.ACC_FINAL, "operations", Type.getDescriptor(Operation[].class), null, null); MethodVisitor clinit = skel.visitMethod(Opcodes.ACC_STATIC, "<clinit>", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] {}), null, null); fillOperationArray(clinit); clinit.visitInsn(Opcodes.RETURN); clinit.visitMaxs(-1, -1); // no arg public constructor MethodVisitor init = skel.visitMethod(Opcodes.ACC_PUBLIC, "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] {}), null, null); init.visitVarInsn(Opcodes.ALOAD, 0); init.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(Object.class), "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] {})); init.visitInsn(Opcodes.RETURN); init.visitMaxs(-1, -1); /* * public Operation[] getOperations() * returns a clone of the operations array */ MethodVisitor getOp = skel.visitMethod(Opcodes.ACC_PUBLIC, "getOperations", Type.getMethodDescriptor(Type.getType(Operation[].class), new Type[] {}), null, null); getOp.visitFieldInsn(Opcodes.GETSTATIC, classInternalName, "operations", Type.getDescriptor(Operation[].class)); getOp.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(Object.class), "clone", Type.getMethodDescriptor(Type.getType(Object.class), new Type[] {})); getOp.visitTypeInsn(Opcodes.CHECKCAST, typeArg(Operation[].class)); getOp.visitInsn(Opcodes.ARETURN); getOp.visitMaxs(-1, -1); // public void dispatch(Remote, RemoteCall, int opnum, long hash) MethodVisitor dispatch = skel.visitMethod(Opcodes.ACC_PUBLIC, "dispatch", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { Type.getType(Remote.class), Type.getType(RemoteCall.class), Type.INT_TYPE, Type.LONG_TYPE }), null, new String[] { Type.getInternalName(Exception.class) }); Variables var = new Variables(); var.declare("this"); var.declare("remoteobj"); var.declare("remotecall"); var.declare("opnum"); var.declareWide("hash"); /* * if opnum >= 0 * XXX it is unclear why there is handling of negative opnums */ dispatch.visitVarInsn(Opcodes.ILOAD, var.get("opnum")); Label nonNegativeOpnum = new Label(); Label opnumSet = new Label(); dispatch.visitJumpInsn(Opcodes.IFGE, nonNegativeOpnum); for (int i = 0; i < remotemethods.length; i++) { // assign opnum if hash matches supplied hash dispatch.visitVarInsn(Opcodes.LLOAD, var.get("hash")); dispatch.visitLdcInsn(new Long(remotemethods[i].hash)); Label notIt = new Label(); dispatch.visitInsn(Opcodes.LCMP); dispatch.visitJumpInsn(Opcodes.IFNE, notIt); // opnum = <opnum> dispatch.visitLdcInsn(new Integer(i)); dispatch.visitVarInsn(Opcodes.ISTORE, var.get("opnum")); dispatch.visitJumpInsn(Opcodes.GOTO, opnumSet); dispatch.visitLabel(notIt); } // throw new SkeletonMismatchException Label mismatch = new Label(); dispatch.visitJumpInsn(Opcodes.GOTO, mismatch); dispatch.visitLabel(nonNegativeOpnum); // if opnum is already set, check that the hash matches the interface dispatch.visitVarInsn(Opcodes.LLOAD, var.get("hash")); dispatch.visitFieldInsn(Opcodes.GETSTATIC, classInternalName, "interfaceHash", Type.LONG_TYPE.getDescriptor()); dispatch.visitInsn(Opcodes.LCMP); dispatch.visitJumpInsn(Opcodes.IFEQ, opnumSet); dispatch.visitLabel(mismatch); dispatch.visitTypeInsn(Opcodes.NEW, typeArg(SkeletonMismatchException.class)); dispatch.visitInsn(Opcodes.DUP); dispatch.visitLdcInsn("interface hash mismatch"); dispatch.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(SkeletonMismatchException.class), "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { Type.getType(String.class) })); dispatch.visitInsn(Opcodes.ATHROW); // opnum has been set dispatch.visitLabel(opnumSet); dispatch.visitVarInsn(Opcodes.ALOAD, var.get("remoteobj")); dispatch.visitTypeInsn(Opcodes.CHECKCAST, typeArg(clazz)); dispatch.visitVarInsn(Opcodes.ASTORE, var.get("remoteobj")); Label deflt = new Label(); Label[] methLabels = new Label[remotemethods.length]; for (int i = 0; i < methLabels.length; i++) methLabels[i] = new Label(); // switch on opnum dispatch.visitVarInsn(Opcodes.ILOAD, var.get("opnum")); dispatch.visitTableSwitchInsn(0, remotemethods.length - 1, deflt, methLabels); // Method dispatch for (int i = 0; i < remotemethods.length; i++) { dispatch.visitLabel(methLabels[i]); Method m = remotemethods[i].meth; generateMethodSkel(dispatch, m, var); } dispatch.visitLabel(deflt); dispatch.visitTypeInsn(Opcodes.NEW, typeArg(UnmarshalException.class)); dispatch.visitInsn(Opcodes.DUP); dispatch.visitLdcInsn("invalid method number"); dispatch.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(UnmarshalException.class), "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { Type.getType(String.class) })); dispatch.visitInsn(Opcodes.ATHROW); dispatch.visitMaxs(-1, -1); skel.visitEnd(); byte[] classData = skel.toByteArray(); if (!noWrite) { if (file.exists()) file.delete(); if (file.getParentFile() != null) file.getParentFile().mkdirs(); FileOutputStream fos = new FileOutputStream(file); fos.write(classData); fos.flush(); fos.close(); } }
From source file:jpcsp.Allegrex.compiler.CodeInstruction.java
License:Open Source License
private int loadRegistersForBranchingOpcodeBranch2(CompilerContext context, MethodVisitor mv, int branchingOpcode) { boolean loadRs = true; boolean loadRt = true; if (context.getRsRegisterIndex() == context.getRtRegisterIndex()) { if (branchingOpcode == Opcodes.IF_ICMPEQ) { loadRs = false;/*from w w w. j av a 2 s . c o m*/ loadRt = false; branchingOpcode = Opcodes.GOTO; // The ASM library has problems with small frames having no // stack (NullPointerException). Generate a dummy stack requirement: // ILOAD 0 // POP context.loadImm(0); context.getMethodVisitor().visitInsn(Opcodes.POP); } else if (branchingOpcode == Opcodes.IF_ICMPNE) { loadRs = false; loadRt = false; branchingOpcode = Opcodes.NOP; } } else if (context.isRsRegister0()) { if (branchingOpcode == Opcodes.IF_ICMPEQ) { loadRs = false; branchingOpcode = Opcodes.IFEQ; } else if (branchingOpcode == Opcodes.IF_ICMPNE) { loadRs = false; branchingOpcode = Opcodes.IFNE; } } else if (context.isRtRegister0()) { if (branchingOpcode == Opcodes.IF_ICMPEQ) { loadRt = false; branchingOpcode = Opcodes.IFEQ; } else if (branchingOpcode == Opcodes.IF_ICMPNE) { loadRt = false; branchingOpcode = Opcodes.IFNE; } } if (loadRs) { context.loadRs(); } if (loadRt) { context.loadRt(); } return branchingOpcode; }
From source file:jpcsp.Allegrex.compiler.CodeInstruction.java
License:Open Source License
private int getBranchingOpcode(CompilerContext context, MethodVisitor mv) { int branchingOpcode = Opcodes.NOP; if (insn == Instructions.BEQ) { branchingOpcode = getBranchingOpcodeBranch2(context, mv, Opcodes.IF_ICMPEQ, Opcodes.IF_ICMPNE); } else if (insn == Instructions.BEQL) { branchingOpcode = getBranchingOpcodeBranch2L(context, mv, Opcodes.IF_ICMPEQ, Opcodes.IF_ICMPNE); } else if (insn == Instructions.BNE) { branchingOpcode = getBranchingOpcodeBranch2(context, mv, Opcodes.IF_ICMPNE, Opcodes.IF_ICMPEQ); } else if (insn == Instructions.BNEL) { branchingOpcode = getBranchingOpcodeBranch2L(context, mv, Opcodes.IF_ICMPNE, Opcodes.IF_ICMPEQ); } else if (insn == Instructions.BGEZ) { branchingOpcode = getBranchingOpcodeBranch1(context, mv, Opcodes.IFGE, Opcodes.IFLT); } else if (insn == Instructions.BGEZL) { branchingOpcode = getBranchingOpcodeBranch1L(context, mv, Opcodes.IFGE, Opcodes.IFLT); } else if (insn == Instructions.BGTZ) { branchingOpcode = getBranchingOpcodeBranch1(context, mv, Opcodes.IFGT, Opcodes.IFLE); } else if (insn == Instructions.BGTZL) { branchingOpcode = getBranchingOpcodeBranch1L(context, mv, Opcodes.IFGT, Opcodes.IFLE); } else if (insn == Instructions.BLEZ) { branchingOpcode = getBranchingOpcodeBranch1(context, mv, Opcodes.IFLE, Opcodes.IFGT); } else if (insn == Instructions.BLEZL) { branchingOpcode = getBranchingOpcodeBranch1L(context, mv, Opcodes.IFLE, Opcodes.IFGT); } else if (insn == Instructions.BLTZ) { branchingOpcode = getBranchingOpcodeBranch1(context, mv, Opcodes.IFLT, Opcodes.IFGE); } else if (insn == Instructions.BLTZL) { branchingOpcode = getBranchingOpcodeBranch1L(context, mv, Opcodes.IFLT, Opcodes.IFGE); } else if (insn == Instructions.J) { branchingOpcode = getBranchingOpcodeBranch0(context, mv); } else if (insn == Instructions.JAL) { branchingOpcode = getBranchingOpcodeCall0(context, mv); } else if (insn == Instructions.BLTZAL) { branchingOpcode = getBranchingOpcodeCall1(context, mv, Opcodes.IFLT, Opcodes.IFGE); } else if (insn == Instructions.BLTZALL) { branchingOpcode = getBranchingOpcodeCall1L(context, mv, Opcodes.IFLT, Opcodes.IFGE); } else if (insn == Instructions.BGEZAL) { branchingOpcode = getBranchingOpcodeCall1(context, mv, Opcodes.IFGE, Opcodes.IFLT); } else if (insn == Instructions.BGEZALL) { branchingOpcode = getBranchingOpcodeCall1L(context, mv, Opcodes.IFGE, Opcodes.IFLT); } else if (insn == Instructions.BC1F) { branchingOpcode = getBranchingOpcodeBC1(context, mv, Opcodes.IFEQ, Opcodes.IFNE); } else if (insn == Instructions.BC1FL) { branchingOpcode = getBranchingOpcodeBC1L(context, mv, Opcodes.IFEQ, Opcodes.IFNE); } else if (insn == Instructions.BC1T) { branchingOpcode = getBranchingOpcodeBC1(context, mv, Opcodes.IFNE, Opcodes.IFEQ); } else if (insn == Instructions.BC1TL) { branchingOpcode = getBranchingOpcodeBC1L(context, mv, Opcodes.IFNE, Opcodes.IFEQ); } else if (insn == Instructions.BVF) { branchingOpcode = getBranchingOpcodeBV(context, mv, Opcodes.IFEQ, Opcodes.IFNE); } else if (insn == Instructions.BVT) { branchingOpcode = getBranchingOpcodeBV(context, mv, Opcodes.IFNE, Opcodes.IFEQ); } else if (insn == Instructions.BVFL) { branchingOpcode = getBranchingOpcodeBVL(context, mv, Opcodes.IFEQ, Opcodes.IFNE); } else if (insn == Instructions.BVTL) { branchingOpcode = getBranchingOpcodeBVL(context, mv, Opcodes.IFNE, Opcodes.IFEQ); } else {//from w ww. jav a 2s . c o m log.error("CodeInstruction.getBranchingOpcode: unknown instruction " + insn.disasm(getAddress(), getOpcode())); } return branchingOpcode; }
From source file:jpcsp.Allegrex.compiler.CompilerContext.java
License:Open Source License
/** * Generate the required Java code to load one parameter for * the syscall function from the CPU registers. * * The following code is generated based on the parameter type: * Processor: parameterValue = RuntimeContext.processor * int: parameterValue = cpu.gpr[paramIndex++] * float: parameterValue = cpu.fpr[paramFloatIndex++] * long: parameterValue = (cpu.gpr[paramIndex++] & 0xFFFFFFFFL) + ((long) cpu.gpr[paramIndex++]) << 32) * boolean: parameterValue = cpu.gpr[paramIndex++] * TPointer,/*from ww w .j ava2s. c o m*/ * TPointer8, * TPointer16, * TPointer32, * TPointer64, * TErrorPointer32: * if (checkMemoryAccess()) { * if (canBeNullParam && address == 0) { * goto addressGood; * } * if (RuntimeContext.checkMemoryPointer(address)) { * goto addressGood; * } * cpu.gpr[_v0] = SceKernelErrors.ERROR_INVALID_POINTER; * pop all the parameters already prepared on the stack; * goto afterSyscall; * addressGood: * } * <parameterType> pointer = new <parameterType>(address); * if (parameterType == TErrorPointer32.class) { * parameterReader.setHasErrorPointer(true); * localVar[LOCAL_ERROR_POINTER] = pointer; * } * parameterValue = pointer * HLEUidClass defined in annotation: * <parameterType> uidObject = HLEUidObjectMapping.getObject("<parameterType>", uid); * if (uidObject == null) { * cpu.gpr[_v0] = errorValueOnNotFound; * pop all the parameters already prepared on the stack; * goto afterSyscall; * } * parameterValue = uidObject * * And then common for all the types: * try { * parameterValue = <module>.<methodToCheck>(parameterValue); * } catch (SceKernelErrorException e) { * goto catchSceKernelErrorException; * } * push parameterValue on stack * * @param parameterReader the current parameter state * @param func the syscall function * @param parameterType the type of the parameter * @param afterSyscallLabel the Label pointing after the call to the syscall function * @param catchSceKernelErrorException the Label pointing to the SceKernelErrorException catch handler */ private void loadParameter(CompilerParameterReader parameterReader, HLEModuleFunction func, Class<?> parameterType, Annotation[] parameterAnnotations, Label afterSyscallLabel, Label catchSceKernelErrorException) { if (parameterType == Processor.class) { loadProcessor(); parameterReader.incrementCurrentStackSize(); } else if (parameterType == CpuState.class) { loadCpu(); parameterReader.incrementCurrentStackSize(); } else if (parameterType == int.class) { parameterReader.loadNextInt(); parameterReader.incrementCurrentStackSize(); } else if (parameterType == float.class) { parameterReader.loadNextFloat(); parameterReader.incrementCurrentStackSize(); } else if (parameterType == long.class) { parameterReader.loadNextLong(); parameterReader.incrementCurrentStackSize(2); } else if (parameterType == boolean.class) { parameterReader.loadNextInt(); parameterReader.incrementCurrentStackSize(); } else if (parameterType == String.class) { parameterReader.loadNextInt(); int maxLength = 16 * 1024; for (Annotation parameterAnnotation : parameterAnnotations) { if (parameterAnnotation instanceof StringInfo) { StringInfo stringInfo = ((StringInfo) parameterAnnotation); maxLength = stringInfo.maxLength(); break; } } loadImm(maxLength); mv.visitMethodInsn(Opcodes.INVOKESTATIC, runtimeContextInternalName, "readStringNZ", "(II)" + Type.getDescriptor(String.class)); parameterReader.incrementCurrentStackSize(); } else if (parameterType == PspString.class) { parameterReader.loadNextInt(); int maxLength = 16 * 1024; boolean canBeNull = false; for (Annotation parameterAnnotation : parameterAnnotations) { if (parameterAnnotation instanceof StringInfo) { StringInfo stringInfo = ((StringInfo) parameterAnnotation); maxLength = stringInfo.maxLength(); } if (parameterAnnotation instanceof CanBeNull) { canBeNull = true; } } loadImm(maxLength); loadImm(canBeNull); mv.visitMethodInsn(Opcodes.INVOKESTATIC, runtimeContextInternalName, "readPspStringNZ", "(IIZ)" + Type.getDescriptor(PspString.class)); parameterReader.incrementCurrentStackSize(); } else if (parameterType == TPointer.class || parameterType == TPointer8.class || parameterType == TPointer16.class || parameterType == TPointer32.class || parameterType == TPointer64.class || parameterType == TErrorPointer32.class) { // if (checkMemoryAccess()) { // if (canBeNullParam && address == 0) { // goto addressGood; // } // if (RuntimeContext.checkMemoryPointer(address)) { // goto addressGood; // } // cpu.gpr[_v0] = SceKernelErrors.ERROR_INVALID_POINTER; // pop all the parameters already prepared on the stack; // goto afterSyscall; // addressGood: // } // <parameterType> pointer = new <parameterType>(address); // if (parameterType == TErrorPointer32.class) { // parameterReader.setHasErrorPointer(true); // localVar[LOCAL_ERROR_POINTER] = pointer; // } mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(parameterType)); mv.visitInsn(Opcodes.DUP); loadMemory(); parameterReader.loadNextInt(); boolean canBeNull = false; for (Annotation parameterAnnotation : parameterAnnotations) { if (parameterAnnotation instanceof CanBeNull) { canBeNull = true; break; } } if (checkMemoryAccess() && afterSyscallLabel != null) { Label addressGood = new Label(); if (canBeNull) { mv.visitInsn(Opcodes.DUP); mv.visitJumpInsn(Opcodes.IFEQ, addressGood); } mv.visitInsn(Opcodes.DUP); mv.visitMethodInsn(Opcodes.INVOKESTATIC, runtimeContextInternalName, "checkMemoryPointer", "(I)Z"); mv.visitJumpInsn(Opcodes.IFNE, addressGood); storeRegister(_v0, SceKernelErrors.ERROR_INVALID_POINTER); parameterReader.popAllStack(4); mv.visitJumpInsn(Opcodes.GOTO, afterSyscallLabel); mv.visitLabel(addressGood); } if (parameterType == TPointer8.class || parameterType == TPointer16.class || parameterType == TPointer32.class || parameterType == TPointer64.class) { loadImm(canBeNull); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(parameterType), "<init>", "(" + memoryDescriptor + "IZ)V"); } else { mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(parameterType), "<init>", "(" + memoryDescriptor + "I)V"); } if (parameterType == TErrorPointer32.class) { parameterReader.setHasErrorPointer(true); mv.visitInsn(Opcodes.DUP); mv.visitVarInsn(Opcodes.ASTORE, LOCAL_ERROR_POINTER); } parameterReader.incrementCurrentStackSize(); } else if (pspAbstractMemoryMappedStructure.class.isAssignableFrom(parameterType)) { parameterReader.loadNextInt(); boolean canBeNull = false; for (Annotation parameterAnnotation : parameterAnnotations) { if (parameterAnnotation instanceof CanBeNull) { canBeNull = true; break; } } if (checkMemoryAccess() && afterSyscallLabel != null) { Label addressGood = new Label(); if (canBeNull) { mv.visitInsn(Opcodes.DUP); mv.visitJumpInsn(Opcodes.IFEQ, addressGood); } mv.visitInsn(Opcodes.DUP); mv.visitMethodInsn(Opcodes.INVOKESTATIC, runtimeContextInternalName, "checkMemoryPointer", "(I)Z"); mv.visitJumpInsn(Opcodes.IFNE, addressGood); storeRegister(_v0, SceKernelErrors.ERROR_INVALID_POINTER); parameterReader.popAllStack(1); mv.visitJumpInsn(Opcodes.GOTO, afterSyscallLabel); mv.visitLabel(addressGood); } mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(parameterType)); mv.visitInsn(Opcodes.DUP); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(parameterType), "<init>", "()V"); mv.visitInsn(Opcodes.DUP_X1); mv.visitInsn(Opcodes.SWAP); loadMemory(); mv.visitInsn(Opcodes.SWAP); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(parameterType), "read", "(" + memoryDescriptor + "I)V"); parameterReader.incrementCurrentStackSize(); } else { HLEUidClass hleUidClass = parameterType.getAnnotation(HLEUidClass.class); if (hleUidClass != null) { int errorValueOnNotFound = hleUidClass.errorValueOnNotFound(); // <parameterType> uidObject = HLEUidObjectMapping.getObject("<parameterType>", uid); // if (uidObject == null) { // cpu.gpr[_v0] = errorValueOnNotFound; // pop all the parameters already prepared on the stack; // goto afterSyscall; // } mv.visitLdcInsn(parameterType.getName()); // Load the UID parameterReader.loadNextInt(); // Load the UID Object mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(HLEUidObjectMapping.class), "getObject", "(" + Type.getDescriptor(String.class) + "I)" + Type.getDescriptor(Object.class)); if (afterSyscallLabel != null) { Label foundUid = new Label(); mv.visitInsn(Opcodes.DUP); mv.visitJumpInsn(Opcodes.IFNONNULL, foundUid); storeRegister(_v0, errorValueOnNotFound); parameterReader.popAllStack(1); mv.visitJumpInsn(Opcodes.GOTO, afterSyscallLabel); mv.visitLabel(foundUid); } mv.visitTypeInsn(Opcodes.CHECKCAST, Type.getInternalName(parameterType)); parameterReader.incrementCurrentStackSize(); } else { log.error(String.format("Unsupported sycall parameter type '%s'", parameterType.getName())); Emulator.PauseEmuWithStatus(Emulator.EMU_STATUS_UNIMPLEMENTED); } } Method methodToCheck = null; if (afterSyscallLabel != null) { for (Annotation parameterAnnotation : parameterAnnotations) { if (parameterAnnotation instanceof CheckArgument) { CheckArgument checkArgument = (CheckArgument) parameterAnnotation; try { methodToCheck = func.getHLEModule().getClass().getMethod(checkArgument.value(), parameterType); } catch (Exception e) { log.error(String.format("CheckArgument method '%s' not found in %s", checkArgument.value(), func.getModuleName()), e); } break; } } } if (methodToCheck != null) { // try { // parameterValue = <module>.<methodToCheck>(parameterValue); // } catch (SceKernelErrorException e) { // goto catchSceKernelErrorException; // } loadModule(func.getModuleName()); mv.visitInsn(Opcodes.SWAP); Label tryStart = new Label(); Label tryEnd = new Label(); mv.visitTryCatchBlock(tryStart, tryEnd, catchSceKernelErrorException, Type.getInternalName(SceKernelErrorException.class)); mv.visitLabel(tryStart); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(methodToCheck.getDeclaringClass()), methodToCheck.getName(), "(" + Type.getDescriptor(parameterType) + ")" + Type.getDescriptor(parameterType)); mv.visitLabel(tryEnd); } parameterReader.incrementCurrentParameterIndex(); }
From source file:jpcsp.Allegrex.compiler.CompilerContext.java
License:Open Source License
/** * Generate the required Java code to call a syscall function. * The code generated must match the Java behavior implemented in * jpcsp.HLE.modules.HLEModuleFunctionReflection * * The following code is generated:/* w w w .j a v a2 s. c o m*/ * if (func.getFirmwareVersion() <= RuntimeContext.firmwareVersion) { * if (!fastSyscall) { * RuntimeContext.preSyscall(); * } * if (func.checkInsideInterrupt()) { * if (IntrManager.getInstance.isInsideInterrupt()) { * cpu.gpr[_v0] = SceKernelErrors.ERROR_KERNEL_CANNOT_BE_CALLED_FROM_INTERRUPT; * goto afterSyscall; * } * } * if (func.checkDispatchThreadEnabled()) { * if (!Modules.ThreadManForUserModule.isDispatchThreadEnabled()) { * cpu.gpr[_v0] = SceKernelErrors.ERROR_KERNEL_WAIT_CAN_NOT_WAIT; * goto afterSyscall; * } * } * if (func.isUnimplemented()) { * Modules.getLogger(func.getModuleName()).warn("Unimplemented <function name> parameterName1=parameterValue1, parameterName2=parameterValue2, ..."); * } * foreach parameter { * loadParameter(parameter); * } * try { * returnValue = <module name>.<function name>(...parameters...); * storeReturnValue(); * if (parameterReader.hasErrorPointer()) { * errorPointer.setValue(0); * } * } catch (SceKernelErrorException e) { * errorCode = e.errorCode; * if (Modules.getLogger(func.getModuleName()).isDebugEnabled()) { * Modules.getLogger(func.getModuleName()).debug(String.format("<function name> return errorCode 0x%08X", errorCode)); * } * if (parameterReader.hasErrorPointer()) { * errorPointer.setValue(errorCode); * cpu.gpr[_v0] = 0; * } else { * cpu.gpr[_v0] = errorCode; * } * reload cpu.gpr[_ra]; // an exception is always clearing the whole stack * } * afterSyscall: * if (fastSyscall) { * RuntimeContext.postSyscallFast(); * } else { * RuntimeContext.postSyscall(); * } * } else { * Modules.getLogger(func.getModuleName()).warn("<function name> is not supported in firmware version <firmwareVersion>, it requires at least firmware version <function firmwareVersion>"); * cpu.gpr[_v0] = -1; * } * * @param func the syscall function * @param fastSyscall true if this is a fast syscall (i.e. without context switching) * false if not (i.e. a syscall where context switching could happen) */ private void visitSyscall(HLEModuleFunction func, boolean fastSyscall) { // The compilation of a syscall requires more stack size than usual maxStackSize = SYSCALL_MAX_STACK_SIZE; boolean needFirmwareVersionCheck = true; if (func.getFirmwareVersion() >= 999) { // Dummy version number meaning valid for all versions needFirmwareVersionCheck = false; } else if (isCodeInstructionInKernelMemory()) { // When compiling code in the kernel memory space, do not perform any version check. // This is used by overwritten HLE functions. needFirmwareVersionCheck = false; } else { // When compiling code loaded from flash0, do not perform any version check. // This is used by overwritten HLE functions. SceModule module = Managers.modules.getModuleByAddress(codeInstruction.getAddress()); if (module != null && module.pspfilename != null && module.pspfilename.startsWith("flash0:")) { if (log.isDebugEnabled()) { log.debug(String.format("syscall from a flash0 module(%s, '%s'), no firmware version check", module, module.pspfilename)); } needFirmwareVersionCheck = false; } } Label unsupportedVersionLabel = null; if (needFirmwareVersionCheck) { unsupportedVersionLabel = new Label(); loadImm(func.getFirmwareVersion()); mv.visitFieldInsn(Opcodes.GETSTATIC, runtimeContextInternalName, "firmwareVersion", "I"); mv.visitJumpInsn(Opcodes.IF_ICMPGT, unsupportedVersionLabel); } // Save the syscall parameter to locals for debugging if (!fastSyscall) { saveParametersToLocals(); } if (!fastSyscall) { mv.visitMethodInsn(Opcodes.INVOKESTATIC, runtimeContextInternalName, "preSyscall", "()V"); } Label afterSyscallLabel = new Label(); if (func.checkInsideInterrupt()) { // if (IntrManager.getInstance().isInsideInterrupt()) { // if (Modules.getLogger(func.getModuleName()).isDebugEnabled()) { // Modules.getLogger(func.getModuleName()).debug("<function name> return errorCode 0x80020064 (ERROR_KERNEL_CANNOT_BE_CALLED_FROM_INTERRUPT)"); // } // cpu.gpr[_v0] = SceKernelErrors.ERROR_KERNEL_CANNOT_BE_CALLED_FROM_INTERRUPT; // goto afterSyscall // } mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(IntrManager.class), "getInstance", "()" + Type.getDescriptor(IntrManager.class)); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(IntrManager.class), "isInsideInterrupt", "()Z"); Label notInsideInterrupt = new Label(); mv.visitJumpInsn(Opcodes.IFEQ, notInsideInterrupt); loadModuleLoggger(func); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(Logger.class), "isDebugEnabled", "()Z"); Label notDebug = new Label(); mv.visitJumpInsn(Opcodes.IFEQ, notDebug); loadModuleLoggger(func); mv.visitLdcInsn( String.format("%s returning errorCode 0x%08X (ERROR_KERNEL_CANNOT_BE_CALLED_FROM_INTERRUPT)", func.getFunctionName(), SceKernelErrors.ERROR_KERNEL_CANNOT_BE_CALLED_FROM_INTERRUPT)); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(Logger.class), "debug", "(" + Type.getDescriptor(Object.class) + ")V"); mv.visitLabel(notDebug); storeRegister(_v0, SceKernelErrors.ERROR_KERNEL_CANNOT_BE_CALLED_FROM_INTERRUPT); mv.visitJumpInsn(Opcodes.GOTO, afterSyscallLabel); mv.visitLabel(notInsideInterrupt); } if (func.checkDispatchThreadEnabled()) { // if (!Modules.ThreadManForUserModule.isDispatchThreadEnabled() || !Interrupts.isInterruptsEnabled()) { // if (Modules.getLogger(func.getModuleName()).isDebugEnabled()) { // Modules.getLogger(func.getModuleName()).debug("<function name> return errorCode 0x800201A7 (ERROR_KERNEL_WAIT_CAN_NOT_WAIT)"); // } // cpu.gpr[_v0] = SceKernelErrors.ERROR_KERNEL_WAIT_CAN_NOT_WAIT; // goto afterSyscall // } loadModule("ThreadManForUser"); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(ThreadManForUser.class), "isDispatchThreadEnabled", "()Z"); Label returnError = new Label(); mv.visitJumpInsn(Opcodes.IFEQ, returnError); loadProcessor(); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(Processor.class), "isInterruptsEnabled", "()Z"); Label noError = new Label(); mv.visitJumpInsn(Opcodes.IFNE, noError); mv.visitLabel(returnError); loadModuleLoggger(func); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(Logger.class), "isDebugEnabled", "()Z"); Label notDebug = new Label(); mv.visitJumpInsn(Opcodes.IFEQ, notDebug); loadModuleLoggger(func); mv.visitLdcInsn(String.format("%s returning errorCode 0x%08X (ERROR_KERNEL_WAIT_CAN_NOT_WAIT)", func.getFunctionName(), SceKernelErrors.ERROR_KERNEL_WAIT_CAN_NOT_WAIT)); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(Logger.class), "debug", "(" + Type.getDescriptor(Object.class) + ")V"); mv.visitLabel(notDebug); storeRegister(_v0, SceKernelErrors.ERROR_KERNEL_WAIT_CAN_NOT_WAIT); mv.visitJumpInsn(Opcodes.GOTO, afterSyscallLabel); mv.visitLabel(noError); } logSyscallStart(func); if (func.hasStackUsage()) { loadMemory(); loadRegister(_sp); loadImm(func.getStackUsage()); mv.visitInsn(Opcodes.ISUB); loadImm(0); loadImm(func.getStackUsage()); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, memoryInternalName, "memset", "(IBI)V"); } // Collecting the parameters and calling the module function... CompilerParameterReader parameterReader = new CompilerParameterReader(this); loadModule(func.getModuleName()); parameterReader.incrementCurrentStackSize(); Label tryStart = new Label(); Label tryEnd = new Label(); Label catchSceKernelErrorException = new Label(); mv.visitTryCatchBlock(tryStart, tryEnd, catchSceKernelErrorException, Type.getInternalName(SceKernelErrorException.class)); Class<?>[] parameterTypes = func.getHLEModuleMethod().getParameterTypes(); Class<?> returnType = func.getHLEModuleMethod().getReturnType(); StringBuilder methodDescriptor = new StringBuilder(); methodDescriptor.append("("); Annotation[][] paramsAnotations = func.getHLEModuleMethod().getParameterAnnotations(); int paramIndex = 0; for (Class<?> parameterType : parameterTypes) { methodDescriptor.append(Type.getDescriptor(parameterType)); loadParameter(parameterReader, func, parameterType, paramsAnotations[paramIndex], afterSyscallLabel, catchSceKernelErrorException); paramIndex++; } methodDescriptor.append(")"); methodDescriptor.append(Type.getDescriptor(returnType)); mv.visitLabel(tryStart); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(func.getHLEModuleMethod().getDeclaringClass()), func.getFunctionName(), methodDescriptor.toString()); storeReturnValue(func, returnType); if (parameterReader.hasErrorPointer()) { // errorPointer.setValue(0); mv.visitVarInsn(Opcodes.ALOAD, LOCAL_ERROR_POINTER); loadImm(0); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(TErrorPointer32.class), "setValue", "(I)V"); } loadRegister(_v0); logSyscallEnd(func, false); mv.visitInsn(Opcodes.POP); mv.visitLabel(tryEnd); mv.visitJumpInsn(Opcodes.GOTO, afterSyscallLabel); // catch (SceKernelErrorException e) { // errorCode = e.errorCode; // if (Modules.log.isDebugEnabled()) { // Modules.log.debug(String.format("<function name> return errorCode 0x%08X", errorCode)); // } // if (hasErrorPointer()) { // errorPointer.setValue(errorCode); // cpu.gpr[_v0] = 0; // } else { // cpu.gpr[_v0] = errorCode; // } // } mv.visitLabel(catchSceKernelErrorException); mv.visitFieldInsn(Opcodes.GETFIELD, Type.getInternalName(SceKernelErrorException.class), "errorCode", "I"); logSyscallEnd(func, true); if (parameterReader.hasErrorPointer()) { // errorPointer.setValue(errorCode); // cpu.gpr[_v0] = 0; mv.visitVarInsn(Opcodes.ALOAD, LOCAL_ERROR_POINTER); mv.visitInsn(Opcodes.SWAP); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(TErrorPointer32.class), "setValue", "(I)V"); storeRegister(_v0, 0); } else { // cpu.gpr[_v0] = errorCode; storeRegister(_v0); } // Reload the $ra register, the stack is lost after an exception CodeInstruction previousInstruction = codeBlock.getCodeInstruction(codeInstruction.getAddress() - 4); if (previousInstruction != null && previousInstruction.getInsn() == Instructions.JR) { int jumpRegister = (previousInstruction.getOpcode() >> 21) & 0x1F; loadRegister(jumpRegister); } mv.visitLabel(afterSyscallLabel); if (fastSyscall) { mv.visitMethodInsn(Opcodes.INVOKESTATIC, runtimeContextInternalName, "postSyscallFast", "()V"); } else { mv.visitMethodInsn(Opcodes.INVOKESTATIC, runtimeContextInternalName, "postSyscall", "()V"); } if (needFirmwareVersionCheck) { Label afterVersionCheckLabel = new Label(); mv.visitJumpInsn(Opcodes.GOTO, afterVersionCheckLabel); mv.visitLabel(unsupportedVersionLabel); loadModuleLoggger(func); mv.visitLdcInsn(String.format( "%s is not supported in firmware version %d, it requires at least firmware version %d", func.getFunctionName(), RuntimeContext.firmwareVersion, func.getFirmwareVersion())); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(Logger.class), "warn", "(" + Type.getDescriptor(Object.class) + ")V"); storeRegister(_v0, -1); mv.visitLabel(afterVersionCheckLabel); } }
From source file:jpcsp.Allegrex.compiler.CompilerContext.java
License:Open Source License
private void startPfxCompiled(VfpuPfxState vfpuPfxState, String name, String descriptor, String internalName, boolean isFloat) { if (vfpuPfxState.isUnknown()) { if (interpretPfxLabel == null) { interpretPfxLabel = new Label(); }/*from ww w. jav a 2s.c om*/ loadVcr(); mv.visitFieldInsn(Opcodes.GETFIELD, Type.getInternalName(Vcr.class), name, descriptor); mv.visitFieldInsn(Opcodes.GETFIELD, internalName, "enabled", "Z"); mv.visitJumpInsn(Opcodes.IFNE, interpretPfxLabel); } }
From source file:jpcsp.Allegrex.compiler.CompilerContext.java
License:Open Source License
@Override public void compileVFPUInstr(Object cstBefore, int opcode, String mathFunction) { int vsize = getVsize(); boolean useVt = getCodeInstruction().hasFlags(Instruction.FLAG_USES_VFPU_PFXT); if (mathFunction == null && opcode == Opcodes.NOP && !useVt && cstBefore == null && canUseVFPUInt(vsize)) { // VMOV should use int instead of float startPfxCompiled(false);//from w w w. ja v a 2 s.c o m for (int n = 0; n < vsize; n++) { prepareVdForStoreInt(n); loadVsInt(n); storeVdInt(n); } endPfxCompiled(vsize, false); } else { startPfxCompiled(true); for (int n = 0; n < vsize; n++) { prepareVdForStore(n); if (cstBefore != null) { mv.visitLdcInsn(cstBefore); } loadVs(n); if (useVt) { loadVt(n); } if (mathFunction != null) { if ("abs".equals(mathFunction)) { mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(Math.class), mathFunction, "(F)F"); } else if ("max".equals(mathFunction) || "min".equals(mathFunction)) { mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(Math.class), mathFunction, "(FF)F"); } else { mv.visitInsn(Opcodes.F2D); mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(Math.class), mathFunction, "(D)D"); mv.visitInsn(Opcodes.D2F); } } Label doneStore = null; if (opcode != Opcodes.NOP) { Label doneOpcode = null; if (opcode == Opcodes.FDIV && cstBefore == null) { // if (value1 == 0f && value2 == 0f) { // result = PSP-NaN | (sign(value1) ^ sign(value2)); // } else { // result = value1 / value2; // } doneOpcode = new Label(); doneStore = new Label(); Label notZeroByZero = new Label(); Label notZeroByZeroPop = new Label(); mv.visitInsn(Opcodes.DUP2); mv.visitInsn(Opcodes.FCONST_0); mv.visitInsn(Opcodes.FCMPG); mv.visitJumpInsn(Opcodes.IFNE, notZeroByZeroPop); mv.visitInsn(Opcodes.FCONST_0); mv.visitInsn(Opcodes.FCMPG); mv.visitJumpInsn(Opcodes.IFNE, notZeroByZero); convertVFloatToInt(); loadImm(0x80000000); mv.visitInsn(Opcodes.IAND); mv.visitInsn(Opcodes.SWAP); convertVFloatToInt(); loadImm(0x80000000); mv.visitInsn(Opcodes.IAND); mv.visitInsn(Opcodes.IXOR); storeTmp1(); // Store the NaN value as an "int" to not loose any bit. // Storing as float results in 0x7FC00001 instead of 0x7F800001. mv.visitInsn(Opcodes.DUP2_X2); mv.visitInsn(Opcodes.POP2); loadPspNaNInt(); loadTmp1(); mv.visitInsn(Opcodes.IOR); int preparedRegister = preparedRegisterForStore; storeVdInt(n); preparedRegisterForStore = preparedRegister; mv.visitJumpInsn(Opcodes.GOTO, doneStore); mv.visitLabel(notZeroByZeroPop); mv.visitInsn(Opcodes.POP); mv.visitLabel(notZeroByZero); } mv.visitInsn(opcode); if (doneOpcode != null) { mv.visitLabel(doneOpcode); } } storeVd(n); if (doneStore != null) { mv.visitLabel(doneStore); } } endPfxCompiled(vsize, true); } }
From source file:lapin.comp.asm.ASMByteCodeGenerator.java
License:Open Source License
private void generateCall(CallableInfo ci, Env env) { /*//from w w w. j a va2 s. c o m * local variables * <Callable#call> * 0: this * 1: args (list of arguments) * 2: env * * <Callable0#call0> * 0: this * 1: env * * <Callable1#call1> * 0: this * 1: arg0 * 2: env * * <Callable2#call2> * 0: this * 1: arg0 * 2: arg1 * 3: env * * ... * */ MethodVisitor mv = _cw.visitMethod( ci.mi.implCallable() ? Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL : Opcodes.ACC_FINAL, ci.mi.name(), Type.getMethodDescriptor(ci.retType, ci.paramTypes), null, null); // instruction list int len = ci.mi.instLen(); // label Label label = null; // generate code for (int i = 0; i < len; i++) { Object inst = ci.mi.getInst(i); if (Logger.tracelevelp(env)) Logger.trace("[asm:gen]" + i + ":\t~S", Lists.list(inst), env); // inst is symbol // -> convert tag (Symbol) to label (ASMe Label object) if (Data.isSymbol(inst)) { Symbol tag = Data.symbol(inst); Label l = (Label) ci.labelTable.get(tag); if (l == null) { throw new NotReachedException("label is null: ~S.", Lists.list(tag)); } else if (l != label) { mv.visitLabel(l); label = l; if (Logger.tracelevelp(env)) Logger.trace("[asm:gen]" + i + ":\ttag ~S -> label ~S", Lists.list(tag, l), env); } else { if (Logger.tracelevelp(env)) Logger.trace("[asm:gen]" + i + ":\ttag ~S -> label ~S" + " (dup)", Lists.list(tag, l), env); } continue; } // inst must be the form of (id <arg1> <arg2> ....) Object id = Lists.car(inst); if (id == Insts.CONST) { /* push const on the stack. */ Object obj = Lists.cadr(inst); String val = Data.string(constTable.get(obj)); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitFieldInsn(Opcodes.GETFIELD, toInternalName(super.classInfo.classname()), val, TYPE_OBJECT.getDescriptor()); } else if (id == Insts.VAR) { /* push var on the stack */ Object var = Lists.cadr(inst); String val = Data.string(varTable.get(var)); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitFieldInsn(Opcodes.GETFIELD, toInternalName(super.classInfo.classname()), val, TYPE_SYMBOL.getDescriptor()); } else if (id == Insts.LAMBDA_LIST) { /* push lambdaList on the stack */ Object var = Lists.cadr(inst); /* push _ll_<i> on the stack */ String val = Data.string(llTable.get(var)); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitFieldInsn(Opcodes.GETFIELD, toInternalName(super.classInfo.classname()), val, TYPE_LAMBDA_LIST.getDescriptor()); } else if (id == Insts.ENV_GET) { /* env.get */ Class type = Data.javaClass(Lists.cadr(inst)); if (type.equals(int.class)) { mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, TYPE_ENV.getInternalName(), "getInt", Type.getMethodDescriptor(Type.INT_TYPE, new Type[] { TYPE_SYMBOL })); } else if (type.equals(double.class)) { mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, TYPE_ENV.getInternalName(), "getDouble", Type.getMethodDescriptor(Type.DOUBLE_TYPE, new Type[] { TYPE_SYMBOL })); } else if (type.equals(char.class)) { mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, TYPE_ENV.getInternalName(), "getChar", Type.getMethodDescriptor(Type.CHAR_TYPE, new Type[] { TYPE_SYMBOL })); } else if (Object.class.isAssignableFrom(type)) { mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, TYPE_ENV.getInternalName(), "get", Type.getMethodDescriptor(TYPE_OBJECT, new Type[] { TYPE_SYMBOL })); } else { throw new NotReachedException("unsupported type: ~S.", Lists.list(type)); } } else if (id == Insts.ENV_SET) { /* env.set */ Class type = Data.javaClass(Lists.cadr(inst)); if (type.equals(int.class)) { mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, TYPE_ENV.getInternalName(), "set", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { TYPE_SYMBOL, Type.INT_TYPE })); } else if (type.equals(double.class)) { mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, TYPE_ENV.getInternalName(), "set", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { TYPE_SYMBOL, Type.DOUBLE_TYPE })); } else if (type.equals(char.class)) { mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, TYPE_ENV.getInternalName(), "set", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { TYPE_SYMBOL, Type.CHAR_TYPE })); } else if (Object.class.isAssignableFrom(type)) { mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, TYPE_ENV.getInternalName(), "set", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { TYPE_SYMBOL, TYPE_OBJECT })); } else { throw new NotReachedException("unsupported type: ~S.", Lists.list(type)); } } else if (id == Insts.ENV_BIND) { /* env.bind */ Class type = Data.javaClass(Lists.cadr(inst)); if (type.equals(int.class)) { mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, TYPE_ENV.getInternalName(), "bind", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { TYPE_SYMBOL, Type.INT_TYPE })); } else if (type.equals(double.class)) { mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, TYPE_ENV.getInternalName(), "bind", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { TYPE_SYMBOL, Type.DOUBLE_TYPE })); } else if (type.equals(char.class)) { mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, TYPE_ENV.getInternalName(), "bind", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { TYPE_SYMBOL, Type.CHAR_TYPE })); } else if (Object.class.isAssignableFrom(type)) { mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, TYPE_ENV.getInternalName(), "bind", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { TYPE_SYMBOL, TYPE_OBJECT })); } else { throw new NotReachedException("unsupported type: ~S.", Lists.list(type)); } } else if (id == Insts.ENV_UNBIND) { /* env.unbind */ Class type = Data.javaClass(Lists.cadr(inst)); if (type.equals(int.class)) { mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, TYPE_ENV.getInternalName(), "unbindInt", Type.getMethodDescriptor(Type.INT_TYPE, new Type[] { TYPE_SYMBOL })); } else if (type.equals(double.class)) { mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, TYPE_ENV.getInternalName(), "unbindDouble", Type.getMethodDescriptor(Type.DOUBLE_TYPE, new Type[] { TYPE_SYMBOL })); } else if (type.equals(char.class)) { mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, TYPE_ENV.getInternalName(), "unbindChar", Type.getMethodDescriptor(Type.CHAR_TYPE, new Type[] { TYPE_SYMBOL })); } else if (Object.class.isAssignableFrom(type)) { mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, TYPE_ENV.getInternalName(), "unbind", Type.getMethodDescriptor(TYPE_OBJECT, new Type[] { TYPE_SYMBOL })); } else { throw new NotReachedException("unsupported type: ~S.", Lists.list(type)); } } else if (id == Insts.ENV_CHILD) { /* env.child */ Object oldEnvVar = Lists.cadr(inst); Object newEnvVar = Lists.caddr(inst); Object oldSlot = Lists.cadr(oldEnvVar); Object newSlot = Lists.cadr(newEnvVar); int oldLocal = Data.fixnum(ci.localTable.get(oldSlot)).intValue(); int newLocal = Data.fixnum(ci.localTable.get(newSlot)).intValue(); if (Logger.tracelevelp(env)) Logger.trace("[asm:gen]" + i + ":\tenv-child: local ~S -> ~S", Lists.list(Data.toFixnum(oldLocal), Data.toFixnum(newLocal)), env); mv.visitVarInsn(Opcodes.ALOAD, oldLocal); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, TYPE_ENV.getInternalName(), "child", Type.getMethodDescriptor(TYPE_ENV, TYPE_NO_ARGS)); mv.visitVarInsn(Opcodes.ASTORE, newLocal); } else if (id == Insts.CALL) { /* funcall */ int nargs = Data.fixnum(Lists.cadr(inst)).intValue(); String className = "lapin.eval.Funcall"; String methodName = nargs < 0 ? "funcall" : "funcall" + nargs; Class rType = Object.class; Class[] pTypes; if (nargs < 0) { pTypes = new Class[] { Function.class, Object.class, // list of args Env.class }; } else { pTypes = new Class[nargs + 2]; pTypes[0] = Function.class; for (int j = 0; j < nargs; j++) { pTypes[j + 1] = Object.class; } pTypes[nargs + 1] = Env.class; } Type retType = Type.getType(rType); Type[] paramTypes = new Type[pTypes.length]; for (int j = 0; j < pTypes.length; j++) paramTypes[j] = Type.getType(pTypes[j]); mv.visitMethodInsn(Opcodes.INVOKESTATIC, toInternalName(className), methodName, Type.getMethodDescriptor(retType, paramTypes)); } else if (id == Insts.CALL_DIRECT) { /* * public class Foo * extends CompiledExpr implements Callable2 { * public Object call2(Object arg0, Object arg1, Env env) { * ... * } * } */ MethodInfo mi = (MethodInfo) Lists.cadr(inst); String className = mi.classInfo().classname(); int nargs = mi.nargs(); boolean rest = mi.rest(); String methodName = mi.name(); Class rType = mi.retType(); Class[] pTypes = mi.paramTypes(); Type retType = Type.getType(rType); Type[] paramTypes = new Type[pTypes.length]; for (int j = 0; j < pTypes.length; j++) paramTypes[j] = Type.getType(pTypes[j]); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, toInternalName(className), methodName, Type.getMethodDescriptor(retType, paramTypes)); } else if (id == Insts.COMPILED_EXPR) { /* * public class Foo extends CompiledExpr { * static public Foo SELF; * ... * } */ String className = Data.string(Lists.cadr(inst)); String fieldName = "SELF"; String typeName = className; mv.visitFieldInsn(Opcodes.GETSTATIC, toInternalName(className), fieldName, toTypeDescriptor(typeName)); } else if (id == Insts.RETURN) { /* return */ Class type = Data.javaClass(Lists.cadr(inst)); if (type.equals(int.class) || type.equals(short.class) || type.equals(byte.class) || type.equals(char.class)) { mv.visitInsn(Opcodes.IRETURN); } else if (type.equals(long.class)) { mv.visitInsn(Opcodes.LRETURN); } else if (type.equals(float.class)) { mv.visitInsn(Opcodes.FRETURN); } else if (type.equals(double.class)) { mv.visitInsn(Opcodes.DRETURN); } else if (type.equals(void.class)) { //mv.visitInsn(Opcodes.RETURN); throw new NotReachedException("unsupported returnType: ~S.", Lists.list(type)); } else { mv.visitInsn(Opcodes.ARETURN); } } else if (id == Insts.IFEQ) { /* conditional jump */ Symbol tag = Data.symbol(Lists.cadr(inst)); Label l = (Label) ci.labelTable.get(tag); if (l == null) { throw new NotReachedException("label not found: ~S.", Lists.list(tag)); } mv.visitJumpInsn(Opcodes.IFEQ, l); } else if (id == Insts.IFNE) { /* conditional jump */ Symbol tag = Data.symbol(Lists.cadr(inst)); Label l = (Label) ci.labelTable.get(tag); if (l == null) { throw new NotReachedException("label not found: ~S.", Lists.list(tag)); } mv.visitJumpInsn(Opcodes.IFNE, l); } else if (id == Insts.GOTO) { /* jump */ Symbol tag = Data.symbol(Lists.cadr(inst)); Label l = (Label) ci.labelTable.get(tag); if (l == null) { throw new NotReachedException("label not found: ~S.", Lists.list(tag)); } mv.visitJumpInsn(Opcodes.GOTO, l); } else if (id == Insts.LOAD) { /* local -> stack */ Object localVar = Lists.cadr(inst); Object slot = Lists.cadr(localVar); Class type = Data.javaClass(Lists.caddr(localVar)); int local = Data.fixnum(ci.localTable.get(slot)).intValue(); int op = Type.getType(type).getOpcode(Opcodes.ILOAD); if (Logger.tracelevelp(env)) Logger.trace("[asm:gen]" + i + ":\tload: local=~S type=~S", Lists.list(Data.toFixnum(local), type), env); mv.visitVarInsn(op, local); } else if (id == Insts.STORE) { /* stack -> local */ Object localVar = Lists.cadr(inst); Object slot = Lists.cadr(localVar); Class type = Data.javaClass(Lists.caddr(localVar)); int local = Data.fixnum(ci.localTable.get(slot)).intValue(); int op = Type.getType(type).getOpcode(Opcodes.ISTORE); if (Logger.tracelevelp(env)) Logger.trace("[asm:gen]" + i + ":\tstore: local=~S type=~S", Lists.list(Data.toFixnum(local), type), env); mv.visitVarInsn(op, local); } else if (id == Insts.POP) { /* pop a value and discard it */ Class type = Data.javaClass(Lists.cadr(inst)); int op; switch (Classes.sizeOf(type)) { case 1: op = Opcodes.POP; break; case 2: op = Opcodes.POP2; break; default: throw new NotReachedException("unsupported type: ~S.", Lists.list(type)); } mv.visitInsn(op); } else if (id == Insts.DUP) { /* peek a value and duplicate it */ Class type = Data.javaClass(Lists.cadr(inst)); int op; switch (Classes.sizeOf(type)) { case 1: op = Opcodes.DUP; break; case 2: op = Opcodes.DUP2; break; default: throw new NotReachedException("unsupported type: ~S.", Lists.list(type)); } mv.visitInsn(op); } else if (id == Insts.PUSH) { /* push a constant */ Object val = Lists.cadr(inst); if (Data.isJavaBoolean(val)) { if (Data.javaBoolean(val).booleanValue()) mv.visitInsn(Opcodes.ICONST_1); else mv.visitInsn(Opcodes.ICONST_0); } else if (val instanceof Byte || val instanceof Short || val instanceof Integer) { int n = Data.javaNumber(val).intValue(); if (n == -1) mv.visitInsn(Opcodes.ICONST_M1); else if (n == 0) mv.visitInsn(Opcodes.ICONST_0); else if (n == 1) mv.visitInsn(Opcodes.ICONST_1); else if (n == 2) mv.visitInsn(Opcodes.ICONST_2); else if (n == 3) mv.visitInsn(Opcodes.ICONST_3); else if (n == 4) mv.visitInsn(Opcodes.ICONST_4); else if (n == 5) mv.visitInsn(Opcodes.ICONST_5); else if (Byte.MIN_VALUE <= n && n <= Byte.MAX_VALUE) mv.visitIntInsn(Opcodes.BIPUSH, n); else if (Short.MIN_VALUE <= n && n <= Short.MAX_VALUE) mv.visitIntInsn(Opcodes.SIPUSH, n); else mv.visitLdcInsn(Data.toFixnum(n)); } else if (val instanceof Long) { long n = Data.javaNumber(val).longValue(); if (n == 0L) mv.visitInsn(Opcodes.LCONST_0); else if (n == 1L) mv.visitInsn(Opcodes.LCONST_1); else mv.visitLdcInsn(val); } else if (val instanceof Float) { float n = Data.javaNumber(val).floatValue(); if (n == 0.0f) mv.visitInsn(Opcodes.FCONST_0); else if (n == 1.0f) mv.visitInsn(Opcodes.FCONST_1); else if (n == 2.0f) mv.visitInsn(Opcodes.FCONST_2); else mv.visitLdcInsn(val); } else if (val instanceof Double) { double n = Data.javaNumber(val).doubleValue(); if (n == 0.0) mv.visitInsn(Opcodes.DCONST_0); else if (n == 1.0) mv.visitInsn(Opcodes.DCONST_1); else mv.visitLdcInsn(val); } else if (Data.isCharacter(val)) { Character c = Data.character(val); int n = (int) c.charValue(); if (Byte.MIN_VALUE <= n && n <= Byte.MAX_VALUE) mv.visitIntInsn(Opcodes.BIPUSH, n); else if (Short.MIN_VALUE <= n && n <= Short.MAX_VALUE) mv.visitIntInsn(Opcodes.SIPUSH, n); else mv.visitLdcInsn(Data.toFixnum(n)); } else if (Data.isString(val)) { mv.visitLdcInsn(val); } else { throw new NotReachedException("cannot push: ~S.", Lists.list(val)); } } else if (id == Insts.GET) { Field f = Data.javaField(Lists.cadr(inst)); String fieldName = f.getName(); Class c = f.getDeclaringClass(); String className = c.getName(); Class t = f.getType(); String typeName = t.getName(); boolean isStatic = Classes.isStatic(f); int op = isStatic ? Opcodes.GETSTATIC : Opcodes.GETFIELD; mv.visitFieldInsn(op, toInternalName(className), fieldName, toTypeDescriptor(typeName)); } else if (id == Insts.PUT) { Field f = Data.javaField(Lists.cadr(inst)); String fieldName = f.getName(); Class c = f.getDeclaringClass(); String className = c.getName(); Class t = f.getType(); String typeName = t.getName(); boolean isStatic = Classes.isStatic(f); int op = isStatic ? Opcodes.PUTSTATIC : Opcodes.PUTFIELD; mv.visitFieldInsn(op, toInternalName(className), fieldName, toTypeDescriptor(typeName)); } else if (id == Insts.INVOKE) { Method m = Data.javaMethod(Lists.cadr(inst)); String methodName = m.getName(); Class c = m.getDeclaringClass(); String className = c.getName(); Class rType = m.getReturnType(); Class[] pTypes = m.getParameterTypes(); if (rType.equals(void.class)) { throw new NotReachedException("unsupported returnType: ~S.", Lists.list(rType)); } Type retType = Type.getType(rType); Type[] paramTypes = new Type[pTypes.length]; for (int j = 0; j < pTypes.length; j++) paramTypes[j] = Type.getType(pTypes[j]); boolean isStatic = Classes.isStatic(m); boolean isInterface = c.isInterface(); int op = isStatic ? Opcodes.INVOKESTATIC : isInterface ? Opcodes.INVOKEINTERFACE : Opcodes.INVOKEVIRTUAL; mv.visitMethodInsn(op, toInternalName(className), methodName, Type.getMethodDescriptor(retType, paramTypes)); } else if (id == Insts.CHECKCAST) { Class c = Data.javaClass(Lists.cadr(inst)); Type t = Type.getType(c); mv.visitTypeInsn(Opcodes.CHECKCAST, t.getInternalName()); } else if (id == Insts.THROW) { mv.visitInsn(Opcodes.ATHROW); } else if (id == Insts.CATCH) { Symbol tagS = Data.symbol(Lists.cadr(inst)); Symbol tagE = Data.symbol(Lists.caddr(inst)); Symbol tagH = Data.symbol(Lists.cadddr(inst)); String className; if (Lists.isEnd(Lists.cddddr(inst))) { className = null; } else { Class c = Data.javaClass(Lists.car(Lists.cddddr(inst))); className = toInternalName(c.getName()); } Label labelS = (Label) ci.labelTable.get(tagS); if (labelS == null) { throw new NotReachedException("label not found: ~S.", Lists.list(tagS)); } Label labelE = (Label) ci.labelTable.get(tagE); if (labelE == null) { throw new NotReachedException("label not found: ~S.", Lists.list(tagE)); } Label labelH = (Label) ci.labelTable.get(tagH); if (labelH == null) { throw new NotReachedException("label not found: ~S.", Lists.list(tagH)); } mv.visitTryCatchBlock(labelS, labelE, labelH, className); } //else if (id == Insts.CATCH_FROM || // id == Insts.CATCH_TO || // id == Insts.CATCH_HANDLER) { // /* nothing emitted */ // continue; //} else { throw new NotReachedException("unknown inst: ~S.", Lists.list(inst)); } } mv.visitMaxs(0, 0); mv.visitEnd(); }
From source file:lucee.transformer.bytecode.op.OpBool.java
License:Open Source License
/** * * @see lucee.transformer.bytecode.expression.ExpressionBase#_writeOut(org.objectweb.asm.commons.GeneratorAdapter, int) *///from www .ja va 2s . c om public Type _writeOut(BytecodeContext bc, int mode) throws BytecodeException { GeneratorAdapter adapter = bc.getAdapter(); if (mode == MODE_REF) { _writeOut(bc, MODE_VALUE); adapter.invokeStatic(Types.CASTER, Methods.METHOD_TO_BOOLEAN_FROM_BOOLEAN); return Types.BOOLEAN; } Label doFalse = new Label(); Label end = new Label(); if (operation == AND) { left.writeOut(bc, MODE_VALUE); adapter.ifZCmp(Opcodes.IFEQ, doFalse); right.writeOut(bc, MODE_VALUE); adapter.ifZCmp(Opcodes.IFEQ, doFalse); adapter.push(true); adapter.visitJumpInsn(Opcodes.GOTO, end); adapter.visitLabel(doFalse); adapter.push(false); adapter.visitLabel(end); } if (operation == OR) { left.writeOut(bc, MODE_VALUE); adapter.ifZCmp(Opcodes.IFNE, doFalse); right.writeOut(bc, MODE_VALUE); adapter.ifZCmp(Opcodes.IFNE, doFalse); adapter.push(false); adapter.visitJumpInsn(Opcodes.GOTO, end); adapter.visitLabel(doFalse); adapter.push(true); adapter.visitLabel(end); } else if (operation == XOR) { left.writeOut(bc, MODE_VALUE); right.writeOut(bc, MODE_VALUE); adapter.visitInsn(Opcodes.IXOR); } else if (operation == EQV) { left.writeOut(bc, MODE_VALUE); right.writeOut(bc, MODE_VALUE); adapter.invokeStatic(Types.OPERATOR, Methods_Operator.OPERATOR_EQV_BV_BV); } else if (operation == IMP) { left.writeOut(bc, MODE_VALUE); right.writeOut(bc, MODE_VALUE); adapter.invokeStatic(Types.OPERATOR, Methods_Operator.OPERATOR_IMP_BV_BV); } return Types.BOOLEAN_VALUE; }