@Override public Instr clone(CloneInfo ii) { return new ModuleVersionGuardInstr(module, expectedVersion, getCandidateObject().cloneForInlining(ii), ii.getRenamedLabel(getFailurePathLabel())); }
@Override public int interpretAndGetNewIPC(ThreadContext context, DynamicScope currDynScope, StaticScope currScope, IRubyObject self, Object[] temp, int ipc) { return versionMatches(context, currScope, currDynScope, self, temp) ? ipc : getFailurePathLabel().getTargetPC(); }
/** The object whose metaclass token has to be verified*/ public Operand getCandidateObject() { return getOperand1(); }
@Override public Instr cloneForBlockCloning(InlinerInfo ii) { return new ModuleVersionGuardInstr(module, expectedVersion, candidateObj.cloneForInlining(ii), failurePathLabel); }
private boolean versionMatches(ThreadContext context, StaticScope currScope, DynamicScope currDynScope, IRubyObject self, Object[] temp) { IRubyObject receiver = (IRubyObject) getCandidateObject().retrieve(context, self, currScope, currDynScope, temp); // if (module.getGeneration() != expectedVersion) ... replace this instr with a direct jump // // SSS FIXME: This is not always correct. Implementation class is not always receiver.getMetaClass() // as we know from how we add instance-methods. We add it to rubyClass value on the stack. So, how // do we handle this sticky situation? return (receiver.getMetaClass().getGeneration() == getExpectedVersion()); }
/** Where to jump if the version assumption fails? */ public Label getFailurePathLabel() { return (Label) getOperand2(); }
@Override public Instr cloneForBlockCloning(InlinerInfo ii) { return new ModuleVersionGuardInstr(module, expectedVersion, candidateObj.cloneForInlining(ii), failurePathLabel); }
private boolean versionMatches(ThreadContext context, StaticScope currScope, DynamicScope currDynScope, IRubyObject self, Object[] temp) { IRubyObject receiver = (IRubyObject) getCandidateObject().retrieve(context, self, currScope, currDynScope, temp); // if (module.getGeneration() != expectedVersion) ... replace this instr with a direct jump // // SSS FIXME: This is not always correct. Implementation class is not always receiver.getMetaClass() // as we know from how we add instance-methods. We add it to rubyClass value on the stack. So, how // do we handle this sticky situation? return (receiver.getMetaClass().getGeneration() == getExpectedVersion()); }
/** Where to jump if the version assumption fails? */ public Label getFailurePathLabel() { return (Label) getOperand2(); }
@Override public int interpretAndGetNewIPC(ThreadContext context, DynamicScope currDynScope, StaticScope currScope, IRubyObject self, Object[] temp, int ipc) { return versionMatches(context, currScope, currDynScope, self, temp) ? ipc : getFailurePathLabel().getTargetPC(); }
@Override public Instr clone(CloneInfo ii) { return new ModuleVersionGuardInstr(module, expectedVersion, getCandidateObject().cloneForInlining(ii), ii.getRenamedLabel(getFailurePathLabel())); }
@Override public Instr cloneForInlinedScope(InlinerInfo ii) { return new ModuleVersionGuardInstr(module, expectedVersion, candidateObj.cloneForInlining(ii), ii.getRenamedLabel(failurePathLabel)); }
/** The object whose metaclass token has to be verified*/ public Operand getCandidateObject() { return getOperand1(); }
@Override public int interpretAndGetNewIPC(ThreadContext context, DynamicScope currDynScope, IRubyObject self, Object[] temp, int ipc) { return versionMatches(context, currDynScope, self, temp) ? ipc : getFailurePathLabel().getTargetPC(); }
@Override public Instr cloneForInlinedScope(InlinerInfo ii) { return new ModuleVersionGuardInstr(module, expectedVersion, candidateObj.cloneForInlining(ii), ii.getRenamedLabel(failurePathLabel)); }
@Override public int interpretAndGetNewIPC(ThreadContext context, DynamicScope currDynScope, IRubyObject self, Object[] temp, int ipc) { return versionMatches(context, currDynScope, self, temp) ? ipc : getFailurePathLabel().getTargetPC(); }
callBB.addInstr(new ModuleVersionGuardInstr(implClass, classToken, call.getReceiver(), failurePathLabel));
callBB.addInstr(new ModuleVersionGuardInstr(implClass, classToken, call.getReceiver(), failurePathLabel));
beforeInlineBB.addInstr(new ModuleVersionGuardInstr(implClass, classToken, call.getReceiver(), failurePathLabel));
beforeInlineBB.addInstr(new ModuleVersionGuardInstr(implClass, classToken, call.getReceiver(), failurePathLabel));