Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  package org.jruby.ir.interpreter;
  
  import java.util.HashMap;
  import java.util.HashSet;
  import java.util.Iterator;
  import java.util.List;
  import java.util.Set;
 
 import org.jruby.Ruby;
 
 public class Interpreter {
     private static class IRCallSite {
         IRScope  s;
         int      v// scope version
         CallBase call;
         long     count;
         InterpretedIRMethod tgtM;
 
         public IRCallSite() { }
 
         public IRCallSite(IRCallSite cs) {
             this.     = cs.s;
             this.     = cs.v;
             this.  = cs.call;
             this. = 0;
         }
 
         public int hashCode() {
             return (int)this..;
        }
    }
    private static class CallSiteProfile {
        IRCallSite cs;
        HashMap<IRScopeCountercounters;
        public CallSiteProfile(IRCallSite cs) {
            this. = new IRCallSite(cs);
            this. = new HashMap<IRScope,Counter>();
        }
    }
    private static IRCallSite callerSite = new IRCallSite();
    private static final Logger LOG = LoggerFactory.getLogger("Interpreter");
    private static int versionCount = 1;
    private static HashMap<IRScopeIntegerscopeVersionMap = new HashMap<IRScopeInteger>();
    private static int inlineCount = 0;
    private static int interpInstrsCount = 0;
    private static int codeModificationsCount = 0;
    private static int numCyclesWithNoModifications = 0;
    private static int globalThreadPollCount = 0;
    private static HashMap<IRScopeCounterscopeThreadPollCounts = new HashMap<IRScopeCounter>();
    private static HashMap<LongCallSiteProfilecallProfile = new HashMap<LongCallSiteProfile>();
    private static HashMap<OperationCounteropStats = new HashMap<OperationCounter>();
    private static IRScope getEvalContainerScope(Ruby runtimeStaticScope evalScope) {
        // SSS FIXME: Weirdness here.  We cannot get the containing IR scope from evalScope because of static-scope wrapping
        // that is going on
        // 1. In all cases, DynamicScope.getEvalScope wraps the executing static scope in a new local scope.
        // 2. For instance-eval (module-eval, class-eval) scenarios, there is an extra scope that is added to
        //    the stack in ThreadContext.java:preExecuteUnder
        // I dont know what rule to apply when.  However, in both these cases, since there is no IR-scope associated,
        // I have used the hack below where I first unwrap once and see if I get a non-null IR scope.  If that doesn't
        // work, I unwarp once more and I am guaranteed to get the IR scope I want.
        IRScope containingIRScope = ((IRStaticScope)evalScope.getEnclosingScope()).getIRScope();
        if (containingIRScope == nullcontainingIRScope = ((IRStaticScope)evalScope.getEnclosingScope().getEnclosingScope()).getIRScope();
        return containingIRScope;
    }
    public static IRubyObject interpretCommonEval(Ruby runtimeString fileint lineNumberString backtraceNameRootNode rootNodeIRubyObject selfBlock block) {
        // SSS FIXME: Is this required here since the IR version cannot change from eval-to-eval? This is much more of a global setting.
        boolean is_1_9 = runtime.is1_9();
        if (is_1_9) IRBuilder.setRubyVersion("1.9");
        StaticScope ss = rootNode.getStaticScope();
        IRScope containingIRScope = getEvalContainerScope(runtimess);
        IREvalScript evalScript = IRBuilder.createIRBuilder(runtimeruntime.getIRManager()).buildEvalRoot(sscontainingIRScopefilelineNumberrootNode);
        evalScript.prepareForInterpretation(false);
//        evalScript.runCompilerPass(new CallSplitter());
        ThreadContext context = runtime.getCurrentContext();
        runBeginEndBlocks(evalScript.getBeginBlocks(), contextselfnull); // FIXME: No temp vars yet right?
        IRubyObject rv = evalScript.call(contextselfevalScript.getStaticScope().getModule(), rootNode.getScope(), blockbacktraceName);
        runBeginEndBlocks(evalScript.getEndBlocks(), contextselfnull); // FIXME: No temp vars right?
        return rv;
    }
    public static IRubyObject interpretSimpleEval(Ruby runtimeString fileint lineNumberString backtraceNameNode nodeIRubyObject self) {
        return interpretCommonEval(runtimefilelineNumberbacktraceName, (RootNode)nodeself.);
    }
    public static IRubyObject interpretBindingEval(Ruby runtimeString fileint lineNumberString backtraceNameNode nodeIRubyObject selfBlock block) {
        return interpretCommonEval(runtimefilelineNumberbacktraceName, (RootNode)nodeselfblock);
    }
    public static void runBeginEndBlocks(List<IRClosurebeBlocksThreadContext contextIRubyObject selfObject[] temp) {
        if (beBlocks == nullreturn;
        for (IRClosure bbeBlocks) {
            // SSS FIXME: Should I piggyback on WrappedIRClosure.retrieve or just copy that code here?
            b.prepareForInterpretation(false);
            Block blk = (Block)(new WrappedIRClosure(b)).retrieve(contextselfcontext.getCurrentScope(), temp);
            blk.yield(contextnull);
        }
    }
    public static IRubyObject interpret(Ruby runtimeNode rootNodeIRubyObject self) {
        if (runtime.is1_9()) IRBuilder.setRubyVersion("1.9");
        IRScriptBody root = (IRScriptBody) IRBuilder.createIRBuilder(runtimeruntime.getIRManager()).buildRoot((RootNoderootNode);
        // We get the live object ball rolling here.  This give a valid value for the top
        // of this lexical tree.  All new scope can then retrieve and set based on lexical parent.
        if (root.getStaticScope().getModule() == null) { // If an eval this may already be setup.
            root.getStaticScope().setModule(runtime.getObject());
        }
        RubyModule currModule = root.getStaticScope().getModule();
        // Scope state for root?
        IRStaticScopeFactory.newIRLocalScope(null).setModule(currModule);
        ThreadContext context = runtime.getCurrentContext();
        try {
            runBeginEndBlocks(root.getBeginBlocks(), contextselfnull); // FIXME: No temp vars yet...not needed?
            InterpretedIRMethod method = new InterpretedIRMethod(rootcurrModule);
            IRubyObject rv =  method.call(contextselfcurrModule"(root)".);
            runBeginEndBlocks(root.getEndBlocks(), contextselfnull); // FIXME: No temp vars yet...not needed?
            if ((IRRuntimeHelpers.isDebug() || IRRuntimeHelpers.inProfileMode()) &&  > 10000) {
                .info("-- Interpreted instructions: {}");
                /*
                for (Operation o: opStats.keySet()) {
                    System.out.println(o + " = " + opStats.get(o).count);
                }
                */
            }
            return rv;
        } catch (IRBreakJump bj) {
            throw ..getException(context.runtime);
        }
    }
    private static void analyzeProfile() {
        ++;
        //if (inlineCount == 2) return;
        else  = 0;
         = 0;
        if ( < 3) return;
        // We are now good to go -- start analyzing the profile
        // System.out.println("-------------------start analysis-----------------------");
        final HashMap<IRScopeLongscopeCounts = new HashMap<IRScopeLong>();
        final ArrayList<IRCallSitecallSites = new ArrayList<IRCallSite>();
        HashMap<IRCallSiteLongcallSiteCounts = new HashMap<IRCallSiteLong>();
        // System.out.println("# call sites: " + callProfile.keySet().size());
        long total = 0;
        for (Long id.keySet()) {
            Long c;
            CallSiteProfile csp = .get(id);
            IRCallSite      cs  = csp.cs;
            if (cs.v != .get(cs.s).intValue()) {
                // System.out.println("Skipping callsite: <" + cs.s + "," + cs.v + "> with compiled version: " + scopeVersionMap.get(cs.s));
                continue;
            }
            Set<IRScopecalledScopes = csp.counters.keySet();
            cs.count = 0;
            for (IRScope scalledScopes) {
                c = scopeCounts.get(s);
                if (c == null) {
                    c = new Long(0);
                    scopeCounts.put(sc);
                }
                long x = csp.counters.get(s).;
                c += x;
                cs.count += x;
            }
            CallBase call = cs.call;
            if (calledScopes.size() == 1 && !call.inliningBlocked()) {
                CallSite runtimeCS = call.getCallSite();
                if (runtimeCS != null && (runtimeCS instanceof CachingCallSite)) {
                    CachingCallSite ccs = (CachingCallSite)runtimeCS;
                    CacheEntry ce = ccs.getCache();
                    if (!(ce.method instanceof InterpretedIRMethod)) {
                        // System.out.println("NOT IR-M!");
                        continue;
                    } else {
                        callSites.add(cs);
                        cs.tgtM = (InterpretedIRMethod)ce.method;
                    }
                }
            }
            total += cs.count;
        }
        Collections.sort(callSitesnew java.util.Comparator<IRCallSite> () {
            @Override
            public int compare(IRCallSite aIRCallSite b) {
                if (a.count == b.countreturn 0;
                return (a.count < b.count) ? 1 : -1;
            }
        });
        // Find top N call sites
        double freq = 0.0;
        int i = 0;
        boolean noInlining = true;
        Set<IRScopeinlinedScopes = new HashSet<IRScope>();
        for (IRCallSite ircscallSites) {
            double contrib = (ircs.count*100.0)/total;
            // 1% is arbitrary
            if (contrib < 1.0) break;
            i++;
            freq += contrib;
            // This check is arbitrary
            if (i == 100 || freq > 99.0) break;
            // System.out.println("Considering: " + ircs.call + " with id: " + ircs.call.callSiteId +
            // " in scope " + ircs.s + " with count " + ircs.count + "; contrib " + contrib + "; freq: " + freq);
            // Now inline here!
            CallBase call = ircs.call;
            IRScope hs = ircs.s;
            boolean isHotClosure = hs instanceof IRClosure;
            IRScope hc = isHotClosure ? hs : null;
            hs = isHotClosure ? hs.getLexicalParent() : hs;
            IRScope tgtMethod = ircs.tgtM.getIRMethod();
            Instr[] instrs = tgtMethod.getInstrsForInterpretation();
            // Dont inline large methods -- 500 is arbitrary
            // Can be null if a previously inlined method hasn't been rebuilt
            if ((instrs == null) || instrs.length > 500) {
                // if (instrs == null) System.out.println("no instrs!");
                // else System.out.println("large method with " + instrs.length + " instrs. skipping!");
                continue;
            }
            RubyModule implClass = ircs.tgtM.getImplementationClass();
            int classToken = implClass.getGeneration();
            String n = tgtMethod.getName();
            boolean inlineCall = true;
            if (isHotClosure) {
                Operand clArg = call.getClosureArg(null);
                inlineCall = (clArg instanceof WrappedIRClosure) && (((WrappedIRClosure)clArg).getClosure() == hc);
            }
            if (inlineCall) {
                noInlining = false;
                long start = new java.util.Date().getTime();
                hs.inlineMethod(tgtMethodimplClassclassTokennullcall);
                inlinedScopes.add(hs);
                long end = new java.util.Date().getTime();
                // System.out.println("Inlined " + tgtMethod + " in " + hs +
                //     " @ instr " + call + " in time (ms): "
                //     + (end-start) + " # instrs: " + instrs.length);
                ++;
            } else {
                //System.out.println("--no inlining--");
            }
        }
        for (IRScope xinlinedScopes) {
            // update version count for 'hs'
            .put(x);
            // System.out.println("Updating version of " + x + " to " + versionCount);
            //System.out.println("--- pre-inline-instrs ---");
            //System.out.println(x.getCFG().toStringInstrs());
            //System.out.println("--- post-inline-instrs ---");
            //System.out.println(x.getCFG().toStringInstrs());
        }
        // reset
         = 0;
         = new HashMap<LongCallSiteProfile>();
        // Every 1M thread polls, discard stats by reallocating the thread-poll count map
        if ( % 1000000 == 0)  {
             = 0;
        }
    }
    private static void outputProfileStats() {
        ArrayList<IRScopescopes = new ArrayList<IRScope>(.keySet());
        Collections.sort(scopesnew java.util.Comparator<IRScope> () {
            @Override
            public int compare(IRScope aIRScope b) {
                // In non-methods and non-closures, we may not have any thread poll instrs.
                int aden = a.getThreadPollInstrsCount();
                if (aden == 0) aden = 1;
                int bden = b.getThreadPollInstrsCount();
                if (bden == 0) bden = 1;
                // Use estimated instr count to order scopes -- rather than raw thread-poll count
                float aCount = .get(a). * (1.0f * a.getInstrsForInterpretation().length/aden);
                float bCount = .get(b). * (1.0f * b.getInstrsForInterpretation().length/bden);
                if (aCount == bCountreturn 0;
                return (aCount < bCount) ? 1 : -1;
            }
        });
        /*
        LOG.info("------------------------");
        LOG.info("Stats after " + globalThreadPollCount + " thread polls:");
        LOG.info("------------------------");
        LOG.info("# instructions: " + interpInstrsCount);
        LOG.info("# code modifications in this period : " + codeModificationsCount);
        LOG.info("------------------------");
        */
        int i = 0;
        float f1 = 0.0f;
        for (IRScope sscopes) {
            long n = .get(s).;
            float p1 =  ((n*1000)/)/10.0f;
            String msg = i + ". " + s + " [file:" + s.getFileName() + ":" + s.getLineNumber() + "] = " + n + "; (" + p1 + "%)";
            if (s instanceof IRClosure) {
                IRMethod m = s.getNearestMethod();
                //if (m != null) LOG.info(msg + " -- nearest enclosing method: " + m);
                //else LOG.info(msg + " -- no enclosing method --");
            } else {
                //LOG.info(msg);
            }
            i++;
            f1 += p1;
            // Top 20 or those that account for 95% of thread poll events.
            if (i == 20 || f1 >= 95.0) break;
        }
        // reset code modification counter
         = 0;
        // Every 1M thread polls, discard stats by reallocating the thread-poll count map
         if ( % 1000000 == 0)  {
            //System.out.println("---- resetting thread-poll counters ----");
             = new HashMap<IRScopeCounter>();
             = 0;
        }
    }
    private static Integer initProfiling(IRScope scope) {
        /* SSS: Not being used currently
        tpCount = scopeThreadPollCounts.get(scope);
        if (tpCount == null) {
            tpCount = new Counter();
            scopeThreadPollCounts.put(scope, tpCount);
        }
        */
        Integer scopeVersion = .get(scope);
        if (scopeVersion == null) {
            .put(scope);
            scopeVersion = new Integer();
        }
        if (. != null) {
            Long id = ..;
            CallSiteProfile csp = .get(id);
            if (csp == null) {
                csp = new CallSiteProfile();
                .put(idcsp);
            }
            Counter csCount = csp.counters.get(scope);
            if (csCount == null) {
                csCount = new Counter();
                csp.counters.put(scopecsCount);
            }
            csCount.count++;
        }
        return scopeVersion;
    }
    private static void setResult(Object[] tempDynamicScope currDynScopeVariable resultVarObject result) {
        if (resultVar instanceof TemporaryVariable) {
            temp[((TemporaryVariable)resultVar).] = result;
        } else {
            LocalVariable lv = (LocalVariable)resultVar;
            currDynScope.setValue((IRubyObject)resultlv.getLocation(), lv.getScopeDepth());
        }
    }
    private static void setResult(Object[] tempDynamicScope currDynScopeInstr instrObject result) {
        if (instr instanceof ResultInstr) {
            setResult(tempcurrDynScope, ((ResultInstr)instr).getResult(), result);
        }
    }
    private static Object retrieveOp(Operand rThreadContext contextIRubyObject selfDynamicScope currDynScopeObject[] temp) {
        Object res;
        if (r instanceof Self) {
            return self;
        } else if (r instanceof TemporaryVariable) {
            res = temp[((TemporaryVariable)r).];
            return res == null ? context.nil : res;
        } else if (r instanceof LocalVariable) {
            LocalVariable lv = (LocalVariable)r;
            res = currDynScope.getValue(lv.getLocation(), lv.getScopeDepth());
            return res == null ? context.nil : res;
        } else {
            return r.retrieve(contextselfcurrDynScopetemp);
        }
    }
    private static void updateCallSite(Instr instrIRScope scopeInteger scopeVersion) {
        if (instr instanceof CallBase) {
            . = scope;
            . = scopeVersion;
            . = (CallBase)instr;
        }
    }
    private static void receiveArg(ThreadContext contextInstr iOperation operationIRubyObject[] argsint kwArgHashCountDynamicScope currDynScopeObject[] tempObject exceptionBlock block) {
        Object result = null;
        ResultInstr instr = (ResultInstr)i;
        switch(operation) {
        case :
            int argIndex = ((ReceivePreReqdArgInstr)instr).getArgIndex();
            result = ((argIndex + kwArgHashCount) < args.length) ? args[argIndex] : context.nil// SSS FIXME: This check is only required for closures, not methods
            break;
        case :
            result = (block == .) ? context.nil : context.runtime.newProc(..block);
            break;
        case :
            result = ((ReceiveOptArgInstr)instr).receiveOptArg(argskwArgHashCount);
            break;
        case :
            result = ((ReceivePostReqdArgInstr)instr).receivePostReqdArg(argskwArgHashCount);
            // For blocks, missing arg translates to nil
            result = result == null ? context.nil : result;
            break;
        case :
            result = ((ReceiveRestArgInstr)instr).receiveRestArg(context.runtimeargskwArgHashCount);
            break;
        case :
            result = ((ReceiveKeywordArgInstr)instr).receiveKWArg(contextkwArgHashCountargs);
            break;
        case :
            result = ((ReceiveKeywordRestArgInstr)instr).receiveKWArg(contextkwArgHashCountargs);
            break;
        case : {
            ReceiveExceptionInstr rei = (ReceiveExceptionInstr)instr;
            result = (exception instanceof RaiseException && rei.checkType) ? ((RaiseException)exception).getException() : exception;
            break;
        }
        }
        setResult(tempcurrDynScopeinstr.getResult(), result);
    }
    private static void processCall(ThreadContext contextInstr instrOperation operationIRScope scopeDynamicScope currDynScopeObject[] tempIRubyObject selfBlock blockBlock.Type blockType) {
        Object result = null;
        switch(operation) {
        case : {
            RuntimeHelperCall rhc = (RuntimeHelperCall)instr;
            result = rhc.callHelper(contextcurrDynScopeselftempscopeblockType);
            setResult(tempcurrDynScoperhc.getResult(), result);
            break;
        }
        case : {
            OneFixnumArgNoBlockCallInstr call = (OneFixnumArgNoBlockCallInstr)instr;
            IRubyObject r = (IRubyObject)retrieveOp(call.getReceiver(), contextselfcurrDynScopetemp);
            result = call.getCallSite().call(contextselfrcall.getFixnumArg());
            setResult(tempcurrDynScopecall.getResult(), result);
            break;
        }
        case : {
            OneOperandArgNoBlockCallInstr call = (OneOperandArgNoBlockCallInstr)instr;
            IRubyObject r = (IRubyObject)retrieveOp(call.getReceiver(), contextselfcurrDynScopetemp);
            IRubyObject o = (IRubyObject)call.getArg1().retrieve(contextselfcurrDynScopetemp);
            result = call.getCallSite().call(contextselfro);
            setResult(tempcurrDynScopecall.getResult(), result);
            break;
        }
        case : {
            ZeroOperandArgNoBlockCallInstr call = (ZeroOperandArgNoBlockCallInstr)instr;
            IRubyObject r = (IRubyObject)retrieveOp(call.getReceiver(), contextselfcurrDynScopetemp);
            result = call.getCallSite().call(contextselfr);
            setResult(tempcurrDynScopecall.getResult(), result);
            break;
        }
        case : {
            IRubyObject r = (IRubyObject)retrieveOp(call.getReceiver(), contextselfcurrDynScopetemp);
            IRubyObject o = (IRubyObject)call.getArg1().retrieve(contextselfcurrDynScopetemp);
            call.getCallSite().call(contextselfro);
            break;
        }
        case :
            instr.interpret(contextcurrDynScopeselftempblock);
            break;
        case :
        default:
            result = instr.interpret(contextcurrDynScopeselftempblock);
            setResult(tempcurrDynScopeinstrresult);
            break;
        }
    }
    private static IRubyObject interpret(ThreadContext contextIRubyObject self,
            IRScope scopeVisibility visibilityRubyModule implClassIRubyObject[] argsBlock blockBlock.Type blockType) {
        Instr[] instrs = scope.getInstrsForInterpretation();
        // The base IR may not have been processed yet
        if (instrs == nullinstrs = scope.prepareForInterpretation(blockType == ..);
        int      numTempVars    = scope.getTemporaryVariableSize();
        Object[] temp           = numTempVars > 0 ? new Object[numTempVars] : null;
        int      n              = instrs.length;
        int      ipc            = 0;
        Instr    instr          = null;
        Object   exception      = null;
        int      kwArgHashCount = (scope.receivesKeywordArgs() && args[args.length - 1] instanceof RubyHash) ? 1 : 0;
        DynamicScope currDynScope = context.getCurrentScope();
        // Counter tpCount = null;
        // Init profiling this scope
        boolean debug   = IRRuntimeHelpers.isDebug();
        boolean profile = IRRuntimeHelpers.inProfileMode();
        Integer scopeVersion = profile ? initProfiling(scope) : 0;
        // Enter the looooop!
        while (ipc < n) {
            instr = instrs[ipc];
            ipc++;
            Operation operation = instr.getOperation();
            if (debug) {
                .info("I: {}"instr);
               ++;
            } else if (profile) {
                if (operation.modifiesCode()) ++;
               ++;
               /*
               Counter cnt = opStats.get(operation);
               if (cnt == null) {
                   cnt = new Counter();
                   opStats.put(operation, cnt);
               }
               cnt.count++;
               */
            }
            try {
                switch (operation.opClass) {
                case : {
                    receiveArg(contextinstroperationargskwArgHashCountcurrDynScopetempexceptionblock);
                    break;
                }
                case : {
                    if (operation == .) {
                        ipc = ((JumpInstr)instr).getJumpTarget().getTargetPC();
                    } else {
                        ipc = instr.interpretAndGetNewIPC(contextcurrDynScopeselftempipc);
                    }
                    break;
                }
                case : {
                    if (profileupdateCallSite(instrscopescopeVersion);
                    processCall(contextinstroperationscopecurrDynScopetempselfblockblockType);
                    break;
                }
                case : {
                    switch(operation) {
                    case : {
                        context.preMethodFrameAndClass(implClassscope.getName(), selfblockscope.getStaticScope());
                        context.setCurrentVisibility(visibility);
                        break;
                    }
                    case : {
                        // SSS NOTE: Method scopes only!
                        //
                        // Blocks are a headache -- so, these instrs. are only added to IRMethods.
                        // Blocks have more complicated logic for pushing a dynamic scope (see InterpretedIRBlockBody)
                        currDynScope = DynamicScope.newDynamicScope(scope.getStaticScope());
                        context.pushScope(currDynScope);
                        break;
                    }
                    case :
                        ((CheckArityInstr)instr).checkArity(context.runtimeargs.length);
                        break;
                    case :
                        context.popFrame();
                        context.popRubyClass();
                        break;
                    case :
                        context.popScope();
                        break;
                    case :
                        if (profile) {
                            // SSS: Not being used currently
                            // tpCount.count++;
                            ++;
                            // 20K is arbitrary
                            // Every 20K profile counts, spit out profile stats
                            if ( % 20000 == 0) {
                                analyzeProfile();
                                // outputProfileStats();
                            }
                        }
                        context.callThreadPoll();
                        break;
                    case :
                        context.setLine(((LineNumberInstr)instr).);
                        break;
                    case :
                        ((RecordEndBlockInstr)instr).interpret();
                        break;
                    }
                    break;
                }
                case : {
                    Object result = null;
                    switch(operation) {
                    // --------- Return flavored instructions --------
                    case : {
                        BreakInstr bi = (BreakInstr)instr;
                        IRubyObject rv = (IRubyObject)bi.getReturnValue().retrieve(contextselfcurrDynScopetemp);
                        // This also handles breaks in lambdas -- by converting them to a return
                        return IRRuntimeHelpers.initiateBreak(contextscopebi.getScopeToReturnTo().getScopeId(), rvblockType);
                    }
                    case : {
                        return (IRubyObject)retrieveOp(((ReturnBase)instr).getReturnValue(), contextselfcurrDynScopetemp);
                    }
                    case : {
                        NonlocalReturnInstr ri = (NonlocalReturnInstr)instr;
                        IRubyObject rv = (IRubyObject)retrieveOp(ri.getReturnValue(), contextselfcurrDynScopetemp);
                        ipc = n;
                        // If not in a lambda, check if this was a non-local return
                        if (!IRRuntimeHelpers.inLambda(blockType)) {
                            IRRuntimeHelpers.initiateNonLocalReturn(contextscoperi.methodToReturnFromrv);
                        }
                        return rv;
                    }
                    // ---------- Common instruction ---------
                    case : {
                        CopyInstr c = (CopyInstr)instr;
                        result = retrieveOp(c.getSource(), contextselfcurrDynScopetemp);
                        setResult(tempcurrDynScopec.getResult(), result);
                        break;
                    }
                    case : {
                        GetFieldInstr gfi = (GetFieldInstr)instr;
                        IRubyObject object = (IRubyObject)gfi.getSource().retrieve(contextselfcurrDynScopetemp);
                        VariableAccessor a = gfi.getAccessor(object);
                        result = a == null ? null : (IRubyObject)a.get(object);
                        if (result == null) {
                            result = context.nil;
                        }
                        setResult(tempcurrDynScopegfi.getResult(), result);
                        break;
                    }
                    case : {
                        SearchConstInstr sci = (SearchConstInstr)instr;
                        result = sci.getCachedConst();
                        if (!sci.isCached(contextresult)) result = sci.cache(contextcurrDynScopeselftemp);
                        setResult(tempcurrDynScopesci.getResult(), result);
                        break;
                    }
                    // ---------- All the rest ---------
                    default:
                        result = instr.interpret(contextcurrDynScopeselftempblock);
                        setResult(tempcurrDynScopeinstrresult);
                        break;
                    }
                    break;
                }
                }
            } catch (Throwable t) {
                // Unrescuable:
                //    IRReturnJump, ThreadKill, RubyContinuation, MainExitException, etc.
                //    These cannot be rescued -- only run ensure blocks
                //
                // Others:
                //    IRBreakJump, Ruby exceptions, errors, and other java exceptions.
                //    These can be rescued -- run rescue blocks
                if (debug.info("in scope: " + scope + ", caught Java throwable: " + t + "; excepting instr: " + instr);
                ipc = (t instanceof Unrescuable) ? scope.getEnsurerPC(instr) : scope.getRescuerPC(instr);
                if (debug.info("ipc for rescuer/ensurer: " + ipc);
                if (ipc == -1) {
                    Helpers.throwException((Throwable)t);
                } else {
                    exception = t;
                }
            }
        }
        // Control should never get here!
        // SSS FIXME: But looks like BEGIN/END blocks get here -- needs fixing
        return null;
    }
    public static IRubyObject INTERPRET_EVAL(ThreadContext contextIRubyObject self,
            IRScope scopeRubyModule clazzIRubyObject[] argsString nameBlock blockBlock.Type blockType) {
        try {
            ThreadContext.pushBacktrace(contextnamescope.getFileName(), context.getLine());
            return interpret(contextselfscopenullclazzargsblockblockType);
        } finally {
            ThreadContext.popBacktrace(context);
        }
    }
    public static IRubyObject INTERPRET_BLOCK(ThreadContext contextIRubyObject self,
            IRScope scopeIRubyObject[] argsString nameBlock blockBlock.Type blockType) {
        try {
            ThreadContext.pushBacktrace(contextnamescope.getFileName(), context.getLine());
            return interpret(contextselfscopenullnullargsblockblockType);
        } finally {
            ThreadContext.popBacktrace(context);
        }
    }
    public static IRubyObject INTERPRET_METHOD(ThreadContext contextInterpretedIRMethod irMethod,
        IRubyObject selfString nameIRubyObject[] argsBlock blockBlock.Type blockTypeboolean isTraceable) {
        Ruby       runtime   = context.runtime;
        IRScope    scope     = irMethod.getIRMethod();
        RubyModule implClass = irMethod.getImplementationClass();
        Visibility viz       = irMethod.getVisibility();
        boolean syntheticMethod = name == null || name.equals("");
        try {
            if (!syntheticMethod) ThreadContext.pushBacktrace(contextnamescope.getFileName(), context.getLine());
            if (isTraceablemethodPreTrace(runtimecontextnameimplClass);
            return interpret(contextselfscopevizimplClassargsblockblockType);
        } finally {
            if (isTraceable) {
                try {methodPostTrace(runtimecontextnameimplClass);}
                finally { if (!syntheticMethod) ThreadContext.popBacktrace(context);}
            } else {
                if (!syntheticMethod) ThreadContext.popBacktrace(context);
            }
        }
    }
    private static void methodPreTrace(Ruby runtimeThreadContext contextString nameRubyModule implClass) {
        if (runtime.hasEventHooks()) context.trace(.nameimplClass);
    }
    private static void methodPostTrace(Ruby runtimeThreadContext contextString nameRubyModule implClass) {
        if (runtime.hasEventHooks()) context.trace(.nameimplClass);
    }
New to GrepCode? Check out our FAQ X