List of usage examples for org.objectweb.asm Opcodes INVOKESPECIAL
int INVOKESPECIAL
To view the source code for org.objectweb.asm Opcodes INVOKESPECIAL.
Click Source Link
From source file:io.syncframework.optimizer.OInterceptorStaticMethodVisitor.java
License:Apache License
public void visitInsn(int opcode) { if (opcode != Opcodes.RETURN) { mv.visitInsn(opcode);/*from www .ja v a2s .c o m*/ return; } Label start = new Label(); Label l1 = new Label(); Label l2 = new Label(); mv.visitCode(); mv.visitTryCatchBlock(start, l1, l2, "java/lang/Throwable"); /* * _asParameters = new HashMap<String,Class<?>>() */ { mv.visitLabel(start); mv.visitTypeInsn(Opcodes.NEW, "java/util/HashMap"); mv.visitInsn(Opcodes.DUP); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/util/HashMap", "<init>", "()V", false); mv.visitFieldInsn(Opcodes.PUTSTATIC, reflector.getClazzInternalName(), "_asParameters", "Ljava/util/Map;"); } /* * _asParameters.put("name", Type.class); */ for (String name : reflector.getParameters().keySet()) { Label l = new Label(); mv.visitLabel(l); mv.visitFieldInsn(Opcodes.GETSTATIC, reflector.getClazzInternalName(), "_asParameters", "Ljava/util/Map;"); mv.visitLdcInsn(name); mv.visitLdcInsn(Type.getType(reflector.getParameters().get(name))); mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/Map", "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", true); mv.visitInsn(Opcodes.POP); } /* * _asConverters = new HashMap<String,Class<?>>() */ { Label l = new Label(); mv.visitLabel(l); mv.visitTypeInsn(Opcodes.NEW, "java/util/HashMap"); mv.visitInsn(Opcodes.DUP); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/util/HashMap", "<init>", "()V", false); mv.visitFieldInsn(Opcodes.PUTSTATIC, reflector.getClazzInternalName(), "_asConverters", "Ljava/util/Map;"); } /* * _asConverters.put("name", Type.class); */ for (String name : reflector.getParameters().keySet()) { if (reflector.getConverters().get(name) != null) { Class<?> converter = reflector.getConverters().get(name); Label l = new Label(); mv.visitLabel(l); mv.visitFieldInsn(Opcodes.GETSTATIC, reflector.getClazzInternalName(), "_asConverters", "Ljava/util/Map;"); mv.visitLdcInsn(name); mv.visitLdcInsn(Type.getType(converter)); mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/Map", "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", true); mv.visitInsn(Opcodes.POP); } } /* * } * catch(Throwable t) { * throw t; * } */ Label throwableStart = new Label(); Label throwableEnd = new Label(); mv.visitLabel(l1); mv.visitJumpInsn(Opcodes.GOTO, throwableEnd); mv.visitLabel(l2); mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] { "java/lang/Throwable" }); mv.visitVarInsn(Opcodes.ASTORE, 0); mv.visitLabel(throwableStart); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitInsn(Opcodes.ATHROW); mv.visitLabel(throwableEnd); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); mv.visitInsn(Opcodes.RETURN); mv.visitLocalVariable("t", "Ljava/lang/Throwable;", null, throwableStart, throwableEnd, 0); }
From source file:jpcsp.Allegrex.compiler.CodeBlock.java
License:Open Source License
private void addConstructor(ClassVisitor cv) { MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null); mv.visitCode();/*from w ww .j a v a 2s.co m*/ mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, objectInternalName, "<init>", "()V"); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(1, 1); mv.visitEnd(); }
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 w w w. j a v a 2s . c om * 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
private void logSyscall(HLEModuleFunction func, String logPrefix, String logCheckFunction, String logFunction) { // Modules.getLogger(func.getModuleName()).warn("Unimplemented..."); loadModuleLoggger(func);//w w w. j a v a2 s . co m mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(Logger.class), logCheckFunction, "()Z"); Label loggingDisabled = new Label(); mv.visitJumpInsn(Opcodes.IFEQ, loggingDisabled); loadModuleLoggger(func); StringBuilder formatString = new StringBuilder(); if (logPrefix != null) { formatString.append(logPrefix); } formatString.append(func.getFunctionName()); ParameterInfo[] parameters = new ClassAnalyzer().getParameters(func.getFunctionName(), func.getHLEModuleMethod().getDeclaringClass()); if (parameters != null) { // Log message: // String.format( // "Unimplemented <function name> // <parameterIntegerName>=0x%X, // <parameterBooleanName>=%b, // <parameterLongName>=0x%X, // <parameterFloatName>=%f, // <parameterOtherTypeName>=%s", // new Object[] { // new Integer(parameterValueInteger), // new Boolean(parameterValueBoolean), // new Long(parameterValueLong), // new Float(parameterValueFloat), // parameterValueOtherTypes // }) loadImm(parameters.length); mv.visitTypeInsn(Opcodes.ANEWARRAY, Type.getInternalName(Object.class)); CompilerParameterReader parameterReader = new CompilerParameterReader(this); Annotation[][] paramsAnotations = func.getHLEModuleMethod().getParameterAnnotations(); int objectArrayIndex = 0; for (int paramIndex = 0; paramIndex < parameters.length; paramIndex++) { ParameterInfo parameter = parameters[paramIndex]; Class<?> parameterType = parameter.type; CompilerTypeInformation typeInformation = compilerTypeManager .getCompilerTypeInformation(parameterType); mv.visitInsn(Opcodes.DUP); loadImm(objectArrayIndex); formatString.append(paramIndex > 0 ? ", " : " "); formatString.append(parameter.name); formatString.append("="); formatString.append(typeInformation.formatString); if (typeInformation.boxingTypeInternalName != null) { mv.visitTypeInsn(Opcodes.NEW, typeInformation.boxingTypeInternalName); mv.visitInsn(Opcodes.DUP); } loadParameter(parameterReader, func, parameterType, paramsAnotations[paramIndex], null, null); if (typeInformation.boxingTypeInternalName != null) { mv.visitMethodInsn(Opcodes.INVOKESPECIAL, typeInformation.boxingTypeInternalName, "<init>", typeInformation.boxingMethodDescriptor); } mv.visitInsn(Opcodes.AASTORE); objectArrayIndex++; } mv.visitLdcInsn(formatString.toString()); mv.visitInsn(Opcodes.SWAP); mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(String.class), "format", "(" + Type.getDescriptor(String.class) + "[" + Type.getDescriptor(Object.class) + ")" + Type.getDescriptor(String.class)); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(Logger.class), logFunction, "(" + Type.getDescriptor(Object.class) + ")V"); parameterReader = new CompilerParameterReader(this); for (int paramIndex = 0; paramIndex < parameters.length; paramIndex++) { ParameterInfo parameter = parameters[paramIndex]; Class<?> parameterType = parameter.type; LengthInfo lengthInfo = BufferInfo.defaultLengthInfo; int length = BufferInfo.defaultLength; Usage usage = BufferInfo.defaultUsage; for (Annotation parameterAnnotation : paramsAnotations[paramIndex]) { if (parameterAnnotation instanceof BufferInfo) { BufferInfo bufferInfo = (BufferInfo) parameterAnnotation; lengthInfo = bufferInfo.lengthInfo(); length = bufferInfo.length(); usage = bufferInfo.usage(); } } boolean parameterRead = false; if ((usage == Usage.in || usage == Usage.inout) && (lengthInfo != LengthInfo.unknown || parameterType == TPointer16.class || parameterType == TPointer32.class || parameterType == TPointer64.class)) { loadModuleLoggger(func); loadImm(1); mv.visitTypeInsn(Opcodes.ANEWARRAY, Type.getInternalName(Object.class)); mv.visitInsn(Opcodes.DUP); loadImm(0); Label done = new Label(); Label addressNull = new Label(); parameterReader.loadNextInt(); parameterRead = true; mv.visitInsn(Opcodes.DUP); mv.visitJumpInsn(Opcodes.IFEQ, addressNull); String format = String.format("%s[%s]:%%s", parameter.name, usage); boolean useMemoryDump = true; switch (lengthInfo) { case fixedLength: loadImm(length); break; case nextNextParameter: parameterReader.skipNextInt(); paramIndex++; parameterReader.loadNextInt(); paramIndex++; break; case nextParameter: parameterReader.loadNextInt(); paramIndex++; break; case previousParameter: // Go back to the address parameter parameterReader.rewindPreviousInt(); // Go back to the previous parameter parameterReader.rewindPreviousInt(); // Load the length from the previous parameter parameterReader.loadNextInt(); // Skip again the address parameter // to come back to the above situation parameterReader.skipNextInt(); break; case variableLength: mv.visitInsn(Opcodes.DUP); loadMemory(); mv.visitInsn(Opcodes.SWAP); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, memoryInternalName, "read32", "(I)I"); break; case unknown: useMemoryDump = false; format = String.format("%s[%s]: 0x%%X", parameter.name, usage); loadMemory(); mv.visitInsn(Opcodes.SWAP); if (parameterType == TPointer64.class) { mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, memoryInternalName, "read64", "(I)J"); mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(Long.class)); mv.visitInsn(Opcodes.DUP); mv.visitInsn(Opcodes.DUP2_X2); mv.visitInsn(Opcodes.POP2); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(Long.class), "<init>", "(J)V"); } else if (parameterType == TPointer16.class) { mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, memoryInternalName, "read16", "(I)I"); mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(Integer.class)); mv.visitInsn(Opcodes.DUP_X1); mv.visitInsn(Opcodes.SWAP); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(Integer.class), "<init>", "(I)V"); } else { mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, memoryInternalName, "read32", "(I)I"); mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(Integer.class)); mv.visitInsn(Opcodes.DUP_X1); mv.visitInsn(Opcodes.SWAP); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(Integer.class), "<init>", "(I)V"); } break; default: log.error(String.format("Unimplemented lengthInfo=%s", lengthInfo)); break; } if (useMemoryDump) { mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(Utilities.class), "getMemoryDump", "(II)" + Type.getDescriptor(String.class)); } mv.visitInsn(Opcodes.AASTORE); mv.visitLdcInsn(format); mv.visitInsn(Opcodes.SWAP); mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(String.class), "format", "(" + Type.getDescriptor(String.class) + "[" + Type.getDescriptor(Object.class) + ")" + Type.getDescriptor(String.class)); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(Logger.class), logFunction, "(" + Type.getDescriptor(Object.class) + ")V"); mv.visitJumpInsn(Opcodes.GOTO, done); mv.visitLabel(addressNull); mv.visitInsn(Opcodes.POP); mv.visitInsn(Opcodes.POP2); mv.visitInsn(Opcodes.POP2); mv.visitLabel(done); } if (!parameterRead) { if (parameterType == long.class) { parameterReader.skipNextLong(); } else if (parameterType == float.class) { parameterReader.skipNextFloat(); } else { parameterReader.skipNextInt(); } } } } else { mv.visitLdcInsn(formatString.toString()); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(Logger.class), logFunction, "(" + Type.getDescriptor(Object.class) + ")V"); } mv.visitLabel(loggingDisabled); }
From source file:jpcsp.Allegrex.compiler.CompilerContext.java
License:Open Source License
private void logSyscallEnd(HLEModuleFunction func, boolean isErrorCode) { String loggingLevel = getLoggingLevel(func); if (loggingLevel == null) { return;//from www . j ava 2s .c o m } String logCheckFunction = getLogCheckFunction(loggingLevel); // if (Modules.getLogger(func.getModuleName()).isDebugEnabled()) { // Modules.getLogger(func.getModuleName()).debug(String.format("<function name> returning 0x%X", new Object[1] { new Integer(returnValue) })); // } loadModuleLoggger(func); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(Logger.class), logCheckFunction, "()Z"); Label notDebug = new Label(); mv.visitJumpInsn(Opcodes.IFEQ, notDebug); boolean isReturningVoid = func.getHLEModuleMethod().getReturnType() == void.class; mv.visitInsn(Opcodes.DUP); mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(Integer.class)); mv.visitInsn(Opcodes.DUP_X1); mv.visitInsn(Opcodes.SWAP); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(Integer.class), "<init>", "(I)V"); loadImm(1); mv.visitTypeInsn(Opcodes.ANEWARRAY, Type.getInternalName(Object.class)); mv.visitInsn(Opcodes.DUP_X1); mv.visitInsn(Opcodes.SWAP); loadImm(0); mv.visitInsn(Opcodes.SWAP); mv.visitInsn(Opcodes.AASTORE); String prefix = func.isUnimplemented() && !codeBlock.isHLEFunction() ? "Unimplemented " : ""; mv.visitLdcInsn(String.format("%s%s returning %s%s", prefix, func.getFunctionName(), isErrorCode ? "errorCode " : "", isReturningVoid ? "void" : "0x%X")); mv.visitInsn(Opcodes.SWAP); mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(String.class), "format", "(" + Type.getDescriptor(String.class) + "[" + Type.getDescriptor(Object.class) + ")" + Type.getDescriptor(String.class)); loadModuleLoggger(func); mv.visitInsn(Opcodes.SWAP); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(Logger.class), loggingLevel, "(" + Type.getDescriptor(Object.class) + ")V"); if (!isErrorCode) { ParameterInfo[] parameters = new ClassAnalyzer().getParameters(func.getFunctionName(), func.getHLEModuleMethod().getDeclaringClass()); if (parameters != null) { CompilerParameterReader parameterReader; if (parametersSavedToLocals) { parameterReader = new CompilerLocalVarParameterReader(this, LOCAL_FIRST_SAVED_PARAMETER); } else { parameterReader = new CompilerParameterReader(this); } Annotation[][] paramsAnotations = func.getHLEModuleMethod().getParameterAnnotations(); for (int paramIndex = 0; paramIndex < parameters.length; paramIndex++) { ParameterInfo parameter = parameters[paramIndex]; Class<?> parameterType = parameter.type; LengthInfo lengthInfo = BufferInfo.defaultLengthInfo; int length = BufferInfo.defaultLength; Usage usage = BufferInfo.defaultUsage; boolean debugMemory = false; for (Annotation parameterAnnotation : paramsAnotations[paramIndex]) { if (parameterAnnotation instanceof BufferInfo) { BufferInfo bufferInfo = (BufferInfo) parameterAnnotation; lengthInfo = bufferInfo.lengthInfo(); length = bufferInfo.length(); usage = bufferInfo.usage(); } else if (parameterAnnotation instanceof DebugMemory) { debugMemory = true; } } boolean parameterRead = false; if ((usage == Usage.out || usage == Usage.inout) && (lengthInfo != LengthInfo.unknown || parameterType == TPointer16.class || parameterType == TPointer32.class || parameterType == TPointer64.class)) { loadModuleLoggger(func); loadImm(1); mv.visitTypeInsn(Opcodes.ANEWARRAY, Type.getInternalName(Object.class)); mv.visitInsn(Opcodes.DUP); loadImm(0); Label done = new Label(); Label addressNull = new Label(); parameterReader.loadNextInt(); parameterRead = true; mv.visitInsn(Opcodes.DUP); mv.visitJumpInsn(Opcodes.IFEQ, addressNull); String format = String.format("%s[%s]:%%s", parameter.name, usage); boolean useMemoryDump = true; switch (lengthInfo) { case fixedLength: loadImm(length); break; case nextNextParameter: parameterReader.skipNextInt(); paramIndex++; parameterReader.loadNextInt(); paramIndex++; break; case nextParameter: parameterReader.loadNextInt(); paramIndex++; break; case previousParameter: // Go back to the address parameter parameterReader.rewindPreviousInt(); // Go back to the previous parameter parameterReader.rewindPreviousInt(); // Load the length from the previous parameter parameterReader.loadNextInt(); // Skip again the address parameter // to come back to the above situation parameterReader.skipNextInt(); break; case variableLength: mv.visitInsn(Opcodes.DUP); loadMemory(); mv.visitInsn(Opcodes.SWAP); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, memoryInternalName, "read32", "(I)I"); break; case returnValue: loadRegister(_v0); break; case unknown: useMemoryDump = false; format = String.format("%s[%s]: 0x%%X", parameter.name, usage); loadMemory(); mv.visitInsn(Opcodes.SWAP); if (parameterType == TPointer64.class) { if (debugMemory) { mv.visitInsn(Opcodes.DUP); loadImm(8); mv.visitMethodInsn(Opcodes.INVOKESTATIC, runtimeContextInternalName, "debugMemory", "(II)V"); } mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, memoryInternalName, "read64", "(I)J"); mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(Long.class)); mv.visitInsn(Opcodes.DUP); mv.visitInsn(Opcodes.DUP2_X2); mv.visitInsn(Opcodes.POP2); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(Long.class), "<init>", "(J)V"); } else if (parameterType == TPointer16.class) { if (debugMemory) { mv.visitInsn(Opcodes.DUP); loadImm(2); mv.visitMethodInsn(Opcodes.INVOKESTATIC, runtimeContextInternalName, "debugMemory", "(II)V"); } mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, memoryInternalName, "read16", "(I)I"); mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(Integer.class)); mv.visitInsn(Opcodes.DUP_X1); mv.visitInsn(Opcodes.SWAP); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(Integer.class), "<init>", "(I)V"); } else { if (debugMemory) { mv.visitInsn(Opcodes.DUP); loadImm(4); mv.visitMethodInsn(Opcodes.INVOKESTATIC, runtimeContextInternalName, "debugMemory", "(II)V"); } mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, memoryInternalName, "read32", "(I)I"); mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(Integer.class)); mv.visitInsn(Opcodes.DUP_X1); mv.visitInsn(Opcodes.SWAP); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(Integer.class), "<init>", "(I)V"); } break; default: log.error(String.format("Unimplemented lengthInfo=%s", lengthInfo)); break; } if (useMemoryDump) { if (debugMemory) { mv.visitInsn(Opcodes.DUP2); mv.visitMethodInsn(Opcodes.INVOKESTATIC, runtimeContextInternalName, "debugMemory", "(II)V"); } mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(Utilities.class), "getMemoryDump", "(II)" + Type.getDescriptor(String.class)); } mv.visitInsn(Opcodes.AASTORE); mv.visitLdcInsn(format); mv.visitInsn(Opcodes.SWAP); mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(String.class), "format", "(" + Type.getDescriptor(String.class) + "[" + Type.getDescriptor(Object.class) + ")" + Type.getDescriptor(String.class)); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(Logger.class), loggingLevel, "(" + Type.getDescriptor(Object.class) + ")V"); mv.visitJumpInsn(Opcodes.GOTO, done); mv.visitLabel(addressNull); mv.visitInsn(Opcodes.POP); mv.visitInsn(Opcodes.POP2); mv.visitInsn(Opcodes.POP2); mv.visitLabel(done); } if (!parameterRead) { if (parameterType == long.class) { parameterReader.skipNextLong(); } else if (parameterType == float.class) { parameterReader.skipNextFloat(); } else { parameterReader.skipNextInt(); } } } } } mv.visitLabel(notDebug); }
From source file:lapin.comp.asm.ASMByteCodeGenerator.java
License:Open Source License
private void generateConstructor(Env env) { /*//from ww w . j av a 2s .c o m * local variables (reserved) * 0: this * 1: env */ MethodVisitor mv = _cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", //"(Llapin/lang/Env;)V", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { TYPE_ENV }), null, null); mv.visitCode(); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitLdcInsn(super.classInfo.name().pname()); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "lapin/function/CompiledExpr", "<init>", //"(Ljava/lang/String;)V"); Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { TYPE_STRING })); Iterator it; // fields for constants it = constTable.keySet().iterator(); while (it.hasNext()) { Object key = it.next(); // key: object (const) String val = Data.string(constTable.get(key)); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitLdcInsn(Printer.prin1ToString(key, env)); mv.visitVarInsn(Opcodes.ALOAD, 1); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "lapin/function/CompiledExpr", "toSexp", Type.getMethodDescriptor(TYPE_OBJECT, new Type[] { TYPE_STRING, TYPE_ENV })); mv.visitFieldInsn(Opcodes.PUTFIELD, toInternalName(super.classInfo.classname()), val, TYPE_OBJECT.getDescriptor()); } // fields for vars it = varTable.keySet().iterator(); while (it.hasNext()) { Object key = it.next(); // key: symbol (var) String val = Data.string(varTable.get(key)); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitLdcInsn(Printer.prin1ToString(key, env)); mv.visitVarInsn(Opcodes.ALOAD, 1); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "lapin/function/CompiledExpr", "toSexp", Type.getMethodDescriptor(TYPE_OBJECT, new Type[] { TYPE_STRING, TYPE_ENV })); mv.visitMethodInsn(Opcodes.INVOKESTATIC, "lapin/lang/Data", "symbol", Type.getMethodDescriptor(TYPE_SYMBOL, new Type[] { TYPE_OBJECT })); mv.visitFieldInsn(Opcodes.PUTFIELD, toInternalName(super.classInfo.classname()), val, TYPE_SYMBOL.getDescriptor()); } // fields for lambdaLists it = llTable.keySet().iterator(); while (it.hasNext()) { Object key = it.next(); // key: lambdaList String val = Data.string(llTable.get(key)); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitLdcInsn(Printer.prin1ToString(Data.lambdaList(key).params(), env)); mv.visitVarInsn(Opcodes.ALOAD, 1); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "lapin/function/CompiledExpr", "toLambdaList", Type.getMethodDescriptor(TYPE_LAMBDA_LIST, new Type[] { TYPE_STRING, TYPE_ENV })); mv.visitFieldInsn(Opcodes.PUTFIELD, toInternalName(super.classInfo.classname()), val, TYPE_LAMBDA_LIST.getDescriptor()); } // field for SELF (static field) mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitFieldInsn(Opcodes.PUTSTATIC, toInternalName(super.classInfo.classname()), "SELF", toTypeDescriptor(super.classInfo.classname())); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(0, 0); mv.visitEnd(); }
From source file:me.rojo8399.placeholderapi.impl.placeholder.gen.ClassPlaceholderFactory.java
License:Open Source License
private static void nullCheck(MethodVisitor mv, boolean nullable, Consumer<MethodVisitor> success, boolean throwError) { if (nullable) { return;/*from w w w . ja v a 2 s.co m*/ } // assume null check obj already loaded to stack Label no = new Label(); mv.visitJumpInsn(IFNONNULL, no); if (throwError) { mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(NoValueException.class)); mv.visitVarInsn(ASTORE, 7); mv.visitVarInsn(ALOAD, 7); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(NoValueException.class), "<init>", "()V", false); mv.visitVarInsn(ALOAD, 7); mv.visitInsn(Opcodes.ATHROW); } else { mv.visitInsn(ACONST_NULL); mv.visitInsn(ARETURN); } mv.visitLabel(no); success.accept(mv); }
From source file:me.themallard.bitmmo.impl.plugin.SimplePlugin.java
License:Open Source License
private void createInstances(ClassNode cn) { for (MethodNode mn : cn.methods) { if (!new PatternBuilder().add(new LdcElement(new LdcInsnNode("PulpCore-Destroyer"))).build() .contains(mn.instructions)) continue; for (String clazz : instancesCreate) { InsnList inject = new InsnList(); inject.add(new TypeInsnNode(Opcodes.NEW, clazz)); inject.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, clazz, "<init>", "()V", false)); mn.instructions.insertBefore(mn.instructions.get(0), inject); }//from w ww . ja v a 2 s.c o m } }
From source file:net.petercashel.jmsDd.util.ASMTransformer.java
License:Apache License
public static byte[] transform(String name, byte[] bytes) { if (debug)/* w ww. ja v a 2 s. c o m*/ System.out.println(bytes.length); ClassNode classNode = new ClassNode(); String classNameASM = name.replace('.', '/'); ClassReader classReader = new ClassReader(bytes); classReader.accept(classNode, 0); boolean DoModInit = false; boolean HasInit = false; String initDesc = "()V"; boolean lockDesc = false; try { try { for (int i = 0; i < classNode.visibleAnnotations.size(); i++) { AnnotationNode ann = (AnnotationNode) classNode.visibleAnnotations.get(i); if (ann.desc.equalsIgnoreCase("Lnet/petercashel/jmsDd/module/Module;")) { try { if (debug) System.out.println("ANNOTE!"); DoModInit = true; Map<String, Object> values = asmList2Map(ann.values); ModuleSystem.modulesToLoad.put( values.get("ModuleName").toString().replace("[", "").replace("]", ""), classNode.name.replace("/", ".")); } catch (Exception e) { e.printStackTrace(); } } } } catch (Exception e) { } try { if (DoModInit) { for (int i = 0; i < classNode.methods.size(); i++) { MethodNode m = (MethodNode) classNode.methods.get(i); if (m.name.contentEquals("<init>")) { initDesc = m.desc; if (m.desc.contentEquals("()V")) { HasInit = true; if (debug) System.out.println("Found <init>"); } } } } } catch (Exception e) { e.printStackTrace(); } } catch (Exception e) { e.printStackTrace(); } if (debug) System.out.println("Still alive?"); try { // L0 // LINENUMBER 43 L0 // ALOAD 0 // INVOKESPECIAL // CLASSNAME FOR ASM // ()V ////// This is effectically a super() call but to the discovered constructor // L1 // LINENUMBER 44 L1 // INVOKESTATIC net/petercashel/jmsDd/API/API$Impl.getAPI ()Lnet/petercashel/jmsDd/API/API; // ALOAD 0 // INVOKEINTERFACE net/petercashel/jmsDd/API/API.registerEventBus (Ljava/lang/Object;)V // L2 // LINENUMBER 46 L2 // RETURN // L3 // LOCALVARIABLE this // "L" + CLASSNAME FOR ASM + ";" // L0 L3 0 // LOCALVARIABLE e Lnet/petercashel/jmsDd/event/module/DummyEvent; L0 L3 1 // MAXSTACK = 2 // MAXLOCALS = 2 if (DoModInit) { if (HasInit) { if (debug) System.out.println("Adding Extra Constructor to " + name); MethodNode constructor = new MethodNode(Opcodes.ACC_PUBLIC, "<init>", "(Lnet/petercashel/jmsDd/event/module/DummyEvent;)V", null, null); Label L0 = new Label(); constructor.visitLabel(L0); constructor.visitVarInsn(Opcodes.ALOAD, 0); constructor.visitMethodInsn(Opcodes.INVOKESPECIAL, classNameASM, "<init>", initDesc); Label L1 = new Label(); constructor.visitLabel(L1); constructor.visitMethodInsn(Opcodes.INVOKESTATIC, "net/petercashel/jmsDd/API/API$Impl", "getAPI", "()Lnet/petercashel/jmsDd/API/API;"); constructor.visitVarInsn(Opcodes.ALOAD, 0); constructor.visitMethodInsn(Opcodes.INVOKEINTERFACE, "net/petercashel/jmsDd/API/API", "registerEventBus", "(Ljava/lang/Object;)V"); Label L2 = new Label(); constructor.visitLabel(L2); constructor.visitInsn(Opcodes.RETURN); Label L3 = new Label(); constructor.visitLabel(L3); constructor.visitLocalVariable("this", "L" + classNameASM + ";", null, L0, L3, 0); constructor.visitLocalVariable("e", "Lnet/petercashel/jmsDd/event/module/DummyEvent;", null, L0, L3, 1); constructor.visitMaxs(2, 2); constructor.visitEnd(); classNode.methods.add(constructor); } else { System.err.println("WARNING! " + name + " Doesn't have a default no-args constructor. Module loader cannot chain load the constructor. \n If you are recieving this error and your module has no constructors defined, or a no-args constructor defined, \n please report the bug to the author of JMSDd."); MethodNode constructor = new MethodNode(Opcodes.ACC_PUBLIC, "<init>", "(Lnet/petercashel/jmsDd/event/module/DummyEvent;)V", null, null); Label L0 = new Label(); constructor.visitLabel(L0); constructor.visitVarInsn(Opcodes.ALOAD, 0); //INVOKESPECIAL java/lang/Object.<init> ()V ////// There is no other constructor, call super() to Object. constructor.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V"); Label L1 = new Label(); constructor.visitLabel(L1); constructor.visitMethodInsn(Opcodes.INVOKESTATIC, "net/petercashel/jmsDd/API/API$Impl", "getAPI", "()Lnet/petercashel/jmsDd/API/API;"); constructor.visitVarInsn(Opcodes.ALOAD, 0); constructor.visitMethodInsn(Opcodes.INVOKEINTERFACE, "net/petercashel/jmsDd/API/API", "registerEventBus", "(Ljava/lang/Object;)V"); Label L2 = new Label(); constructor.visitLabel(L2); constructor.visitInsn(Opcodes.RETURN); Label L3 = new Label(); constructor.visitLabel(L3); constructor.visitLocalVariable("this", "L" + classNameASM + ";", null, L0, L3, 0); constructor.visitLocalVariable("e", "Lnet/petercashel/jmsDd/event/module/DummyEvent;", null, L0, L3, 1); constructor.visitMaxs(2, 2); constructor.visitEnd(); classNode.methods.add(constructor); } classNode.visitEnd(); ClassWriter wr = new ClassWriter(0); classNode.accept(wr); bytes = wr.toByteArray(); } } catch (Exception e) { e.printStackTrace(); } if (debug) System.out.println("Still alive."); if (debug) System.out.println(bytes.length); if (plugins.size() > 0) { for (ASMPlugin p : plugins) { try { bytes = p.transform(name, bytes); } catch (Exception e) { } } } return bytes; }
From source file:net.roryclaasen.asm.rorysmodcore.transformer.WorldServerTransformer.java
License:Apache License
public byte[] patchTick(String name, byte[] bytes, boolean obfuscated) { RMLog.info("[WorldServer] [tick] Patching", true); String targetMethodName = ""; if (obfuscated == true) targetMethodName = "b"; else/*ww w.j av a 2 s . c o m*/ targetMethodName = "tick"; ClassNode classNode = new ClassNode(); ClassReader classReader = new ClassReader(bytes); classReader.accept(classNode, 0); Iterator<MethodNode> methods = classNode.methods.iterator(); while (methods.hasNext()) { MethodNode method = methods.next(); int invok_index = -1; if ((method.name.equals(targetMethodName) && method.desc.equals("()V"))) { AbstractInsnNode currentNode = null; AbstractInsnNode targetNode = null; Iterator<AbstractInsnNode> iter = method.instructions.iterator(); int index = -1; int INVOKEVIRTUAL_COUNT = 0; while (iter.hasNext()) { index++; currentNode = iter.next(); if (currentNode.getOpcode() == Opcodes.INVOKEVIRTUAL) { INVOKEVIRTUAL_COUNT++; if (INVOKEVIRTUAL_COUNT == 9) { targetNode = currentNode; invok_index = index; break; } } } if (targetNode == null || invok_index == -1) { RMLog.info("[WorldServer] Did not find all necessary target nodes! ABANDON CLASS!", true); return bytes; } AbstractInsnNode p1 = method.instructions.get(invok_index); MethodInsnNode a1 = new MethodInsnNode(Opcodes.INVOKESPECIAL, "net/minecraft/world/WorldServer", "resetRainAndThunder", "()V", false); method.instructions.set(p1, a1); break; } } ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS); classNode.accept(writer); return writer.toByteArray(); }