@Override public void Array(Array array) { jvmMethod().loadContext(); for (Operand operand : array.getElts()) { visit(operand); } jvmMethod().array(array.getElts().length); }
@Override public void Splat(Splat splat) { jvm.method().loadContext(); visit(splat.getArray()); jvm.method().invokeHelper("irSplat", RubyArray.class, ThreadContext.class, IRubyObject.class); }
&& callInstr.getCallType() == CallType.NORMAL) m.loadLocal(0); m.loadLocal(2); // dummy to satisfy signature of existing target linker (MathLinker) visit(callInstr.getReceiver()); m.invokeFixnumOp(name, ((Fixnum)args[0]).value); } else { m.loadLocal(0); visit(callInstr.getReceiver()); for (Operand operand : args) { case FUNCTIONAL: case VARIABLE: m.invokeSelf(name, numArgs); break; case NORMAL: m.invokeOther(name, numArgs); break; case SUPER: m.invokeSuper(name, numArgs); break;
@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(); }
private void compileCallCommon(IRBytecodeAdapter m, CallBase call) { Operand[] args = call.getCallArgs(); BlockPassType blockPassType = BlockPassType.fromIR(call); m.loadContext(); m.loadSelf(); // caller visit(call.getReceiver()); int arity = args.length; m.loadContext(); visit(call.getClosureArg()); m.invokeIRHelper("getBlockFromObject", sig(Block.class, ThreadContext.class, Object.class)); case FUNCTIONAL: case VARIABLE: m.invokeSelf(file, lastLine, currentScopeName, call, arity); break; case NORMAL: m.invokeOther(file, lastLine, currentScopeName, call, arity); break;
@Override public void BTrueInstr(BTrueInstr btrueinstr) { Operand arg1 = btrueinstr.getArg1(); // this is a gross hack because we don't have distinction in boolean instrs between boxed and unboxed if (arg1 instanceof TemporaryBooleanVariable || arg1 instanceof UnboxedBoolean) { // no need to unbox, just branch visit(arg1); jvmMethod().btrue(getJVMLabel(btrueinstr.getJumpTarget())); } else if ((arg1 instanceof Boolean && ((Boolean) arg1).isTrue()) || arg1 instanceof UnboxedFixnum || arg1 instanceof UnboxedFloat) { // always true, always branch jvmMethod().goTo(getJVMLabel(btrueinstr.getJumpTarget())); } else if ((arg1 instanceof Boolean && ((Boolean) arg1).isFalse()) || arg1 instanceof UnboxedFixnum || arg1 instanceof UnboxedFloat) { // always false, never branch } else { // unbox and branch visit(arg1); jvmMethod().branchIfTruthy(getJVMLabel(btrueinstr.getJumpTarget())); } }
@Override public void InheritanceSearchConstInstr(InheritanceSearchConstInstr inheritancesearchconstinstr) { jvmMethod().loadContext(); visit(inheritancesearchconstinstr.getCurrentModule()); jvmMethod().inheritanceSearchConst(inheritancesearchconstinstr.getId(), false); jvmStoreLocal(inheritancesearchconstinstr.getResult()); }
@Override public void InheritanceSearchConstInstr(InheritanceSearchConstInstr inheritancesearchconstinstr) { jvm.method().loadLocal(0); visit(inheritancesearchconstinstr.getCurrentModule()); // TODO: private consts jvm.method().inheritanceSearchConst(inheritancesearchconstinstr.getConstName()); jvmStoreLocal(inheritancesearchconstinstr.getResult()); }
@Override public void AttrAssignInstr(AttrAssignInstr attrAssignInstr) { jvm.method().loadLocal(0); visit(attrAssignInstr.getReceiver()); for (Operand operand : attrAssignInstr.getCallArgs()) { visit(operand); } jvm.method().invokeOther(attrAssignInstr.getMethodAddr().getName(), attrAssignInstr.getCallArgs().length); jvm.method().adapter.pop(); }
m.loadRuntime(); visit(definemetaclassinstr.getObject()); m.invokeHelper("getSingletonClass", RubyClass.class, Ruby.class, IRubyObject.class);
@Override public void NotInstr(NotInstr instr) { visit(instr.getOperands()[0]); // SSS FIXME: Does this really require a helper rather than being inlined? jvm.method().invokeHelper("irNot", IRubyObject.class, ThreadContext.class, IRubyObject.class); }
public void popmethod() { method().endMethod(); methodStack.pop(); } public ClassVisitor cls;
@Override public void GetFieldInstr(GetFieldInstr getfieldinstr) { visit(getfieldinstr.getSource()); jvmMethod().getField(getfieldinstr.getId()); jvmStoreLocal(getfieldinstr.getResult()); }
@Override public void JumpInstr(JumpInstr jumpinstr) { jvm.method().goTo(getJVMLabel(jumpinstr.getJumpTarget())); }
public void branchIfTruthy(Label target) { adapter.invokeinterface(p(IRubyObject.class), "isTrue", sig(boolean.class)); btrue(target); }
@Override public void BFalseInstr(BFalseInstr bFalseInstr) { Operand arg1 = bFalseInstr.getArg1(); // this is a gross hack because we don't have distinction in boolean instrs between boxed and unboxed if (arg1 instanceof TemporaryBooleanVariable || arg1 instanceof UnboxedBoolean) { // no need to unbox visit(arg1); jvmMethod().bfalse(getJVMLabel(bFalseInstr.getJumpTarget())); } else if ((arg1 instanceof Boolean && ((Boolean) arg1).isTrue()) || arg1 instanceof UnboxedFixnum || arg1 instanceof UnboxedFloat) { // always true, don't branch } else if ((arg1 instanceof Boolean && ((Boolean) arg1).isFalse()) || arg1 instanceof UnboxedFixnum || arg1 instanceof UnboxedFloat) { // always false, always branch jvmAdapter().go_to(getJVMLabel(bFalseInstr.getJumpTarget())); } else { // unbox visit(arg1); jvmAdapter().invokeinterface(p(IRubyObject.class), "isTrue", sig(boolean.class)); jvmMethod().bfalse(getJVMLabel(bFalseInstr.getJumpTarget())); } }