Search in sources :

Example 1 with Thunk

use of suite.instructionexecutor.InstructionUtil.Thunk in project suite by stupidsing.

the class InstructionExecutor method yawnThunk_.

private Node yawnThunk_(Thunk thunk0) {
    Frame f0 = new Frame(null, 2);
    f0.registers[0] = thunk0;
    Activation current = new Activation(f0, yawnEntryPoint, null);
    Node[] stack = new Node[Suite.stackSize];
    int ip = 0, sp = 0;
    Node returnValue = null;
    Exec exec = new Exec();
    exec.stack = stack;
    Comparer comparer = comparer();
    Tree tree;
    while (true) try {
        Frame frame = current.frame;
        Node[] regs = frame != null ? frame.registers : null;
        Instruction insn = instructions[ip = current.ip++];
        Thunk thunk;
        TermOp op;
        int i;
        switch(insn.insn) {
            case ASSIGNCONST___:
                regs[insn.op0] = constantPool.get(insn.op1);
                break;
            case ASSIGNFRAMEREG:
                i = insn.op1;
                while (i++ < 0) frame = frame.previous;
                regs[insn.op0] = frame.registers[insn.op2];
                break;
            case ASSIGNINT_____:
                regs[insn.op0] = number(insn.op1);
                break;
            case ASSIGNRESULT__:
                regs[insn.op0] = returnValue;
                break;
            case ASSIGNTHUNK___:
                regs[insn.op0] = new Thunk(frame, insn.op1);
                break;
            case ASSIGNTHUNKRES:
                regs[insn.op0] = returnValue;
                thunk = (Thunk) regs[insn.op1];
                // facilitates garbage collection
                thunk.frame = null;
                thunk.result = returnValue;
                break;
            case CALL__________:
                current = new Activation(frame, insn.op0, current);
                break;
            case CALLTHUNK_____:
                thunk = (Thunk) regs[insn.op0];
                if (thunk.result == null)
                    current = new Activation(thunk, current);
                else
                    returnValue = thunk.result;
                break;
            case ENTER_________:
                AnalyzedFrame af = analyzer.getFrame(ip);
                Frame parent = af.isRequireParent() ? frame : null;
                Instruction frameBegin = instructions[af.getFrameBeginIp()];
                current.frame = new Frame(parent, frameBegin.op0);
                break;
            case ERROR_________:
                Fail.t("error termination");
            case EVALADD_______:
                regs[insn.op0] = number(i(regs[insn.op1]) + i(regs[insn.op2]));
                break;
            case EVALDIV_______:
                regs[insn.op0] = number(i(regs[insn.op1]) / i(regs[insn.op2]));
                break;
            case EVALEQ________:
                i = comparer.compare(regs[insn.op1], regs[insn.op2]);
                regs[insn.op0] = atom(i == 0);
                break;
            case EVALLE________:
                i = comparer.compare(regs[insn.op1], regs[insn.op2]);
                regs[insn.op0] = atom(i <= 0);
                break;
            case EVALLT________:
                i = comparer.compare(regs[insn.op1], regs[insn.op2]);
                regs[insn.op0] = atom(i < 0);
                break;
            case EVALNE________:
                i = comparer.compare(regs[insn.op1], regs[insn.op2]);
                regs[insn.op0] = atom(i != 0);
                break;
            case EVALMOD_______:
                regs[insn.op0] = number(i(regs[insn.op1]) % i(regs[insn.op2]));
                break;
            case EVALMUL_______:
                regs[insn.op0] = number(i(regs[insn.op1]) * i(regs[insn.op2]));
                break;
            case EVALSUB_______:
                regs[insn.op0] = number(i(regs[insn.op1]) - i(regs[insn.op2]));
                break;
            case EXIT__________:
                return returnValue;
            case FORMTREE0_____:
                Node left = regs[insn.op0];
                Node right = regs[insn.op1];
                insn = instructions[current.ip++];
                op = TermOp.find(((Atom) constantPool.get(insn.op0)).name);
                regs[insn.op1] = Tree.of(op, left, right);
                break;
            case FRAMEBEGIN____:
            case FRAMEEND______:
                break;
            case IFFALSE_______:
                if (regs[insn.op0] != Atom.TRUE)
                    current.ip = insn.op1;
                break;
            case IFNOTCONS_____:
                if ((tree = Tree.decompose(regs[insn.op0], TermOp.OR____)) != null) {
                    stack[sp++] = tree.getLeft();
                    stack[sp++] = tree.getRight();
                } else
                    current.ip = insn.op1;
                break;
            case IFNOTPAIR_____:
                if ((tree = Tree.decompose(regs[insn.op0], TermOp.AND___)) != null) {
                    stack[sp++] = tree.getLeft();
                    stack[sp++] = tree.getRight();
                } else
                    current.ip = insn.op1;
                break;
            case IFNOTEQUALS___:
                if (regs[insn.op1] != regs[insn.op2])
                    current.ip = insn.op0;
                break;
            case JUMP__________:
                current.ip = insn.op0;
                break;
            case JUMPCLOSURE___:
                thunk = (Thunk) regs[insn.op0];
                current = current.previous;
                if (thunk.result == null)
                    current = new Activation(thunk, current);
                else
                    returnValue = thunk.result;
                break;
            case LEAVE_________:
                current.frame = current.frame.previous;
                break;
            case LOGREG________:
                LogUtil.info(regs[insn.op0].toString());
                break;
            case NEWNODE_______:
                regs[insn.op0] = new Reference();
                break;
            case PUSH__________:
                stack[sp++] = regs[insn.op0];
                break;
            case POP___________:
                regs[insn.op0] = stack[--sp];
                break;
            case POPANY________:
                --sp;
                break;
            case REMARK________:
                break;
            case RETURN________:
                current = current.previous;
                break;
            case SETRESULT_____:
                returnValue = regs[insn.op0];
                break;
            case TOP___________:
                regs[insn.op0] = stack[sp + insn.op1];
                break;
            default:
                exec.current = current;
                exec.sp = sp;
                handle(exec, insn);
                current = exec.current;
                sp = exec.sp;
        }
    } catch (Exception ex) {
        Fail.t("at IP = " + ip, ex);
    }
}
Also used : AnalyzedFrame(suite.instructionexecutor.InstructionAnalyzer.AnalyzedFrame) Frame(suite.instructionexecutor.InstructionUtil.Frame) Reference(suite.node.Reference) Node(suite.node.Node) Activation(suite.instructionexecutor.InstructionUtil.Activation) Instruction(suite.instructionexecutor.InstructionUtil.Instruction) Thunk(suite.instructionexecutor.InstructionUtil.Thunk) TermOp(suite.node.io.TermOp) Comparer(suite.node.util.Comparer) Tree(suite.node.Tree) AnalyzedFrame(suite.instructionexecutor.InstructionAnalyzer.AnalyzedFrame)

Aggregations

AnalyzedFrame (suite.instructionexecutor.InstructionAnalyzer.AnalyzedFrame)1 Activation (suite.instructionexecutor.InstructionUtil.Activation)1 Frame (suite.instructionexecutor.InstructionUtil.Frame)1 Instruction (suite.instructionexecutor.InstructionUtil.Instruction)1 Thunk (suite.instructionexecutor.InstructionUtil.Thunk)1 Node (suite.node.Node)1 Reference (suite.node.Reference)1 Tree (suite.node.Tree)1 TermOp (suite.node.io.TermOp)1 Comparer (suite.node.util.Comparer)1