public void go(Object gotoToken) {
method.go_to((Label) gotoToken);
}
public void isConstantBranch(final BranchCallback setup, final String name) {
BranchCallback catchCode = new BranchCallback() {
public void branch(BodyCompiler context) {
// restore the original exception
loadThreadContext();
method.aload(getPreviousExceptionIndex());
invokeThreadContext("setErrorInfo", sig(IRubyObject.class, IRubyObject.class));
method.pop();
pushNull();
}
};
BranchCallback regularCode = new BranchCallback() {
public void branch(BodyCompiler context) {
setup.branch(BaseBodyCompiler.this);
method.ldc(name); //[C, C, String]
invokeUtilityMethod("getDefinedConstantOrBoundMethod", sig(RubyString.class, IRubyObject.class, String.class));
}
};
String mname = getNewRescueName();
SkinnyMethodAdapter mv = new SkinnyMethodAdapter(
script.getClassVisitor(),
ACC_PUBLIC | ACC_SYNTHETIC | ACC_STATIC,
mname,
sig(RubyString.class, "L" + script.getClassname() + ";", ThreadContext.class, IRubyObject.class, Block.class),
null,
null);
SkinnyMethodAdapter old_method = null;
SkinnyMethodAdapter var_old_method = null;
SkinnyMethodAdapter inv_old_method = null;
Label exitRescue = new Label();
boolean oldWithinProtection = inNestedMethod;
inNestedMethod = true;
Label[] oldLoopLabels = currentLoopLabels;
currentLoopLabels = null;
int oldArgCount = argParamCount;
argParamCount = 0; // synthetic methods always have zero arg parameters
try {
old_method = this.method;
var_old_method = getVariableCompiler().getMethodAdapter();
inv_old_method = getInvocationCompiler().getMethodAdapter();
this.method = mv;
getVariableCompiler().setMethodAdapter(mv);
getInvocationCompiler().setMethodAdapter(mv);
mv.start();
// store previous exception for restoration if we rescue something
loadThreadContext();
invokeThreadContext("getErrorInfo", sig(IRubyObject.class));
mv.astore(getPreviousExceptionIndex());
mv.aload(StandardASMCompiler.THREADCONTEXT_INDEX);
mv.invokevirtual(p(ThreadContext.class), "getCurrentScope", sig(DynamicScope.class));
mv.astore(getDynamicScopeIndex());
// if more than 4 vars, get values array too
if (scope.getNumberOfVariables() > 4) {
mv.aload(getDynamicScopeIndex());
mv.invokevirtual(p(DynamicScope.class), "getValues", sig(IRubyObject[].class));
mv.astore(getVarsArrayIndex());
}
Label beforeBody = new Label();
Label afterBody = new Label();
Label catchBlock = new Label();
mv.trycatch(beforeBody, afterBody, catchBlock, p(JumpException.class));
mv.label(beforeBody);
regularCode.branch(this);
mv.label(afterBody);
mv.go_to(exitRescue);
mv.label(catchBlock);
mv.astore(getExceptionIndex());