@Override public void Self(Self self) { // %self is in JVM-local-2 always jvm.method().loadLocal(2); }
@Override public void ReceiveOptArgInstr(ReceiveOptArgInstr instr) { // FIXME: Only works when args is in an array rather than being flattened out // FIXME: Missing kwargs 2.0 support (kwArgHashCount value) jvm.method().adapter.pushInt(instr.getArgIndex() + instr.numUsedArgs); // MIN reqd args jvm.method().adapter.pushInt(instr.getArgIndex() + instr.argOffset); // args array offset jvm.method().adapter.aload(3); // FIXME: what is the correct lvar index for args[]? jvm.method().invokeHelper("irLoadOptArg", IRubyObject.class, int.class, int.class, IRubyObject[].class); }
@Override public void ReceiveOptArgInstr(ReceiveOptArgInstr instr) { // FIXME: Only works when args is in an array rather than being flattened out // FIXME: Missing kwargs 2.0 support (kwArgHashCount value) jvm.method().adapter.pushInt(instr.getArgIndex() + instr.numUsedArgs); // MIN reqd args jvm.method().adapter.pushInt(instr.getArgIndex() + instr.argOffset); // args array offset jvm.method().adapter.aload(3); // FIXME: what is the correct lvar index for args[]? jvm.method().invokeHelper("irLoadOptArg", IRubyObject.class, int.class, int.class, IRubyObject[].class); }
@Override public void ConstMissingInstr(ConstMissingInstr constmissinginstr) { visit(constmissinginstr.getReceiver()); jvm.method().adapter.checkcast("org/jruby/RubyModule"); jvm.method().loadContext(); jvm.method().adapter.ldc("const_missing"); jvm.method().pushSymbol(constmissinginstr.getMissingConst()); jvm.method().invokeVirtual(Type.getType(RubyModule.class), Method.getMethod("org.jruby.runtime.builtin.IRubyObject callMethod(org.jruby.runtime.ThreadContext, java.lang.String, org.jruby.runtime.builtin.IRubyObject)")); }
@Override public void ReqdArgMultipleAsgnInstr(ReqdArgMultipleAsgnInstr reqdargmultipleasgninstr) { jvm.method().loadContext(); visit(reqdargmultipleasgninstr.getArrayArg()); jvm.method().adapter.checkcast("org/jruby/RubyArray"); jvm.method().adapter.pushInt(reqdargmultipleasgninstr.getPreArgsCount()); jvm.method().adapter.pushInt(reqdargmultipleasgninstr.getIndex()); jvm.method().adapter.pushInt(reqdargmultipleasgninstr.getPostArgsCount()); jvm.method().invokeHelper("irReqdArgMultipleAsgn", IRubyObject.class, ThreadContext.class, RubyArray.class, int.class, int.class, int.class); jvmStoreLocal(reqdargmultipleasgninstr.getResult()); }
@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 BNEInstr(BNEInstr bneinstr) { Operand[] args = bneinstr.getOperands(); jvm.method().loadLocal(0); visit(args[0]); visit(args[1]); jvm.method().invokeHelper("BNE", boolean.class, ThreadContext.class, IRubyObject.class, IRubyObject.class); jvm.method().adapter.iftrue(getJVMLabel(bneinstr.getJumpTarget())); }
@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 ToAryInstr(ToAryInstr toaryinstr) { jvm.method().loadContext(); visit(toaryinstr.getArrayArg()); jvm.method().adapter.ldc(toaryinstr.dontToAryArrays()); jvm.method().invokeHelper("irToAry", IRubyObject.class, ThreadContext.class, IRubyObject.class, boolean.class); jvmStoreLocal(toaryinstr.getResult()); }
@Override public void Range(Range range) { jvm.method().loadRuntime(); jvm.method().loadContext(); visit(range.getBegin()); visit(range.getEnd()); jvm.method().adapter.ldc(range.isExclusive()); jvm.method().adapter.invokestatic(p(RubyRange.class), "newRange", sig(RubyRange.class, Ruby.class, ThreadContext.class, IRubyObject.class, IRubyObject.class, boolean.class)); }
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()); }
@Override public void CopyInstr(CopyInstr copyinstr) { int index = getJVMLocalVarIndex(copyinstr.getResult()); visit(copyinstr.getSource()); jvm.method().storeLocal(index); }
@Override public void AliasInstr(AliasInstr aliasInstr) { IRBytecodeAdapter m = jvm.method(); m.loadLocal(0); m.loadLocal(getJVMLocalVarIndex(aliasInstr.getReceiver())); m.adapter.ldc(((StringLiteral) aliasInstr.getNewName()).string); m.adapter.ldc(((StringLiteral) aliasInstr.getOldName()).string); m.invokeHelper("defineAlias", IRubyObject.class, ThreadContext.class, IRubyObject.class, Object.class, Object.class); m.adapter.pop(); }
@Override public void HasInstanceVarInstr(HasInstanceVarInstr hasinstancevarinstr) { IRBytecodeAdapter m = jvm.method(); // TODO: This is suboptimal, not caching ivar offset at all m.loadRuntime(); visit(hasinstancevarinstr.getObject()); m.adapter.invokeinterface(p(IRubyObject.class), "getInstanceVariables", sig(InstanceVariables.class)); m.adapter.ldc(hasinstancevarinstr.getName().string); m.adapter.invokeinterface(p(InstanceVariables.class), "hasInstanceVariable", sig(boolean.class, String.class)); m.adapter.invokevirtual(p(Ruby.class), "newBoolean", sig(RubyBoolean.class, boolean.class)); jvmStoreLocal(hasinstancevarinstr.getResult()); }
@Override public void HasInstanceVarInstr(HasInstanceVarInstr hasinstancevarinstr) { IRBytecodeAdapter m = jvm.method(); // TODO: This is suboptimal, not caching ivar offset at all m.loadRuntime(); visit(hasinstancevarinstr.getObject()); m.adapter.invokeinterface(p(IRubyObject.class), "getInstanceVariables", sig(InstanceVariables.class)); m.adapter.ldc(hasinstancevarinstr.getName().string); m.adapter.invokeinterface(p(InstanceVariables.class), "hasInstanceVariable", sig(boolean.class, String.class)); m.adapter.invokevirtual(p(Ruby.class), "newBoolean", sig(RubyBoolean.class, boolean.class)); jvmStoreLocal(hasinstancevarinstr.getResult()); }