public static Class compile(Ruby ruby, IRScope scope, JRubyClassLoader jrubyClassLoader) { // run compiler JVMVisitor target = new JVMVisitor(); target.codegen(scope); // try { // FileOutputStream fos = new FileOutputStream("tmp.class"); // fos.write(target.code()); // fos.close(); // } catch (Exception e) { // e.printStackTrace(); // } return jrubyClassLoader.defineClass(JVM.scriptToClass(scope.getName()), target.code()); }
@Override public void BUndefInstr(BUndefInstr bundefinstr) { visit(bundefinstr.getArg1()); jvmMethod().pushUndefined(); jvmAdapter().if_acmpeq(getJVMLabel(bundefinstr.getJumpTarget())); }
private void jvmLoadLocal(Variable variable) { if (variable instanceof TemporaryLocalVariable) { switch (((TemporaryLocalVariable)variable).getType()) { case FLOAT: jvmAdapter().dload(getJVMLocalVarIndex(variable)); break; case FIXNUM: jvmAdapter().lload(getJVMLocalVarIndex(variable)); break; case BOOLEAN: jvmAdapter().iload(getJVMLocalVarIndex(variable)); break; default: jvmMethod().loadLocal(getJVMLocalVarIndex(variable)); break; } } else { jvmMethod().loadLocal(getJVMLocalVarIndex(variable)); } }
public byte[] compileToBytecode(IRScope scope, JVMVisitorMethodContext context) { file = scope.getFile(); lastLine = -1; codegenScope(scope, context); return code(); }
private void jvmStoreLocal(String specialVar) { jvmMethod().storeLocal(getJVMLocalVarIndex(specialVar)); }
@Override public void BEQInstr(BEQInstr beqInstr) { Operand[] args = beqInstr.getOperands(); jvm.method().loadLocal(0); visit(args[0]); visit(args[1]); jvm.method().invokeHelper("BEQ", boolean.class, ThreadContext.class, IRubyObject.class, IRubyObject.class); jvm.method().adapter.iftrue(getJVMLabel(beqInstr.getJumpTarget())); }
@Override public void ArrayDerefInstr(ArrayDerefInstr arrayderefinstr) { jvmMethod().loadContext(); jvmMethod().loadSelf(); visit(arrayderefinstr.getReceiver()); visit(arrayderefinstr.getKey()); jvmMethod().invokeArrayDeref(file, lastLine, arrayderefinstr); jvmStoreLocal(arrayderefinstr.getResult()); }
@Override public void NonlocalReturnInstr(NonlocalReturnInstr returninstr) { jvmMethod().loadContext(); jvmLoadLocal(DYNAMIC_SCOPE); jvmMethod().loadSelfBlock(); visit(returninstr.getReturnValue()); jvmMethod().invokeIRHelper("initiateNonLocalReturn", sig(IRubyObject.class, ThreadContext.class, DynamicScope.class, Block.class, IRubyObject.class)); jvmMethod().returnValue(); }
@Override public void UndefMethodInstr(UndefMethodInstr undefmethodinstr) { jvmMethod().loadContext(); visit(undefmethodinstr.getMethodName()); jvmLoadLocal(DYNAMIC_SCOPE); jvmMethod().loadSelf(); jvmMethod().invokeIRHelper("undefMethod", sig(IRubyObject.class, ThreadContext.class, Object.class, DynamicScope.class, IRubyObject.class)); jvmStoreLocal(undefmethodinstr.getResult()); }
@Override public void DefineClassInstr(DefineClassInstr defineclassinstr) { IRClassBody newIRClassBody = defineclassinstr.getNewIRClassBody(); jvmMethod().loadContext(); Handle handle = emitModuleBody(newIRClassBody); jvmMethod().pushHandle(handle); jvmAdapter().getstatic(jvm.clsData().clsName, handle.getName() + "_IRScope", ci(IRScope.class)); visit(defineclassinstr.getContainer()); visit(defineclassinstr.getSuperClass()); jvmMethod().invokeIRHelper("newCompiledClassBody", sig(DynamicMethod.class, ThreadContext.class, java.lang.invoke.MethodHandle.class, IRScope.class, Object.class, Object.class)); jvmStoreLocal(defineclassinstr.getResult()); }
@Override public void BreakInstr(BreakInstr breakInstr) { jvmMethod().loadContext(); jvmLoadLocal(DYNAMIC_SCOPE); visit(breakInstr.getReturnValue()); jvmMethod().loadSelfBlock(); jvmAdapter().invokestatic(p(IRRuntimeHelpers.class), "initiateBreak", sig(IRubyObject.class, ThreadContext.class, DynamicScope.class, IRubyObject.class, Block.class)); jvmMethod().returnValue(); }
protected Handle emitModuleBody(IRModuleBody method) { String name = JavaNameMangler.encodeScopeForBacktrace(method) + '$' + methodIndex++; Signature signature = signatureFor(method, false); emitScope(method, name, signature, false, true); return new Handle( Opcodes.H_INVOKESTATIC, jvm.clsData().clsName, name, sig(signature.type().returnType(), signature.type().parameterArray()), false); }
try { String key = SexpMaker.sha1(body.getIRScope()); JVMVisitor visitor = new JVMVisitor(jitCompiler.runtime); BlockJITClassGenerator generator = new BlockJITClassGenerator(className, methodName, key, jitCompiler.runtime, body, visitor); Class sourceClass = visitor.defineFromBytecode(body.getIRScope(), generator.bytecode(), new OneShotClassLoader(jitCompiler.runtime.getJRubyClassLoader()));
@Override public void BNilInstr(BNilInstr bnilinstr) { visit(bnilinstr.getArg1()); jvmMethod().branchIfNil(getJVMLabel(bnilinstr.getJumpTarget())); }
@Override public void OptArgMultipleAsgnInstr(OptArgMultipleAsgnInstr optargmultipleasgninstr) { visit(optargmultipleasgninstr.getArray()); jvmAdapter().checkcast(p(RubyArray.class)); jvmAdapter().ldc(optargmultipleasgninstr.getMinArgsLength()); jvmAdapter().ldc(optargmultipleasgninstr.getIndex()); jvmAdapter().invokestatic(p(IRRuntimeHelpers.class), "extractOptionalArgument", sig(IRubyObject.class, RubyArray.class, int.class, int.class)); jvmStoreLocal(optargmultipleasgninstr.getResult()); }
@Override public void ReifyClosureInstr(ReifyClosureInstr reifyclosureinstr) { jvmMethod().loadRuntime(); jvmLoadLocal("$blockArg"); jvmMethod().invokeIRHelper("newProc", sig(IRubyObject.class, Ruby.class, Block.class)); jvmStoreLocal(reifyclosureinstr.getResult()); }
public void emit(IRModuleBody method) { String name = method.getName(); if (name.indexOf("DUMMY_MC") != -1) { name = "METACLASS"; } name = emitScope(method, name, 0); // push a method handle for binding purposes jvm.method().pushHandle(jvm.clsData().clsName, name, method.getStaticScope().getRequiredArgs()); }
public void emitVariable(Variable variable) { // System.out.println("variable: " + variable); int index = getJVMLocalVarIndex(variable); // System.out.println("index: " + index); jvm.method().loadLocal(index); }
@Override public void CopyInstr(CopyInstr copyinstr) { int index = getJVMLocalVarIndex(copyinstr.getResult()); visit(copyinstr.getSource()); jvm.method().storeLocal(index); }
JVMVisitor visitor = new JVMVisitor(runtime); JVMVisitorMethodContext context = new JVMVisitorMethodContext(); bytecode = visitor.compileToBytecode(scope, context); Class compiled = visitor.defineFromBytecode(scope, bytecode, classLoader);