Beispiel #1
0
 RocksEngine::~RocksEngine() { cleanShutdown(); }
Beispiel #2
0
void InterpreterExecute(const LinkedProgram *program, int target)
{
    VM *masterVM;

    IVInit(&temp, 16);
    vmBytecode = program->bytecode;
    vmLineNumbers = program->lineNumbers;
    masterVM = VMCreate(program);
    initStackFrame(masterVM, &masterVM->ip, &masterVM->bp, target, 0);

    for (;;)
    {
        VMBase *vmBase = &masterVM->base;
        bool idle = true;

        /* Traverse VMs, letting all non-idle execute for a while. Note that the tree can change as
           a result of executing. */
        for (;;)
        {
            if (vmBase->fullVM)
            {
                VM *vm = (VM*)vmBase;
                if (!vm->idle)
                {
                    /* TODO: Cloning new VMs can cause infinite traversal. */
                    vm = execute(vm);
                    idle = false;
                }
                else if (vm->child)
                {
                    vmBase = vm->child;
                    continue;
                }
                {
                    VMBase *parent = vm->base.parent;
                    VMBase *child = &vm->base;
                    VMBase **p;
                    if (!parent)
                    {
                        break;
                    }
                    while (parent->fullVM ||
                           ((VMBranch*)parent)->children[
                               ((VMBranch*)parent)->childCount - 1] == child)
                    {
                        child = parent;
                        parent = parent->parent;
                        if (!parent)
                        {
                            goto done;
                        }
                    }
                    for (p = ((VMBranch*)parent)->children; *p != child; p++)
                    {
                        assert(p < ((VMBranch*)parent)->children + ((VMBranch*)parent)->childCount);
                    }
                    vmBase = *(p + 1);
                }
            }
            else
            {
                VMBranch *vmBranch = (VMBranch*)vmBase;
                assert(vmBranch->childCount);
                vmBase = vmBranch->children[0];
            }
        }
done:

        if (idle)
        {
            if (masterVM->job)
            {
                JobExecute(masterVM->job);
            }
            else if (masterVM->idle)
            {
                break;
            }
        }
    }

    if (masterVM->failMessage)
    {
        const char *filename;
        int line = BytecodeLineNumber(program->lineNumbers,
                                      (int)(masterVM->ip - vmBytecode), &filename);
        char *msg = VGetStringCopy(masterVM->failMessage);
        fprintf(stderr, "%s:%d: %s\n", filename, line, msg);
#ifdef VALGRIND
        free(msg);
#endif
        cleanShutdown(EXIT_FAILURE);
    }

#ifdef VALGRIND
    VMDispose(&masterVM->base);
    IVDispose(&temp);
#endif
}