// File: /workspace/github_c_makefile_star2_O1/hoobaa[P]ficl/vm.c
// Function: ficlVmExecuteString
int ficlVmExecuteString(ficlVm *vm, ficlString s)
{
    ficlSystem *system = vm->callback.system;
    ficlDictionary   *dictionary   = system->dictionary;

    int        except;
    jmp_buf    vmState;
    jmp_buf   *oldState;
    ficlTIB        saveficlTIB;

    FICL_VM_ASSERT(vm, vm);
    FICL_VM_ASSERT(vm, system->interpreterLoop[0]);

    ficlVmPushTib(vm, FICL_STRING_GET_POINTER(s), FICL_STRING_GET_LENGTH(s), &saveficlTIB);

    /*
    ** Save and restore VM's jmp_buf to enable nested calls to ficlExec 
    */
    oldState = vm->exceptionHandler;
    vm->exceptionHandler = &vmState; /* This has to come before the setjmp! */
    except = setjmp(vmState);

    switch (except)
    {
    case 0:
        if (vm->restart)
        {
            vm->runningWord->code(vm);
            vm->restart = 0;
        }
        else
        {   /* set VM up to interpret text */
            ficlVmPushIP(vm, &(system->interpreterLoop[0]));
        }

        ficlVmInnerLoop(vm, 0);
        break;

    case FICL_VM_STATUS_RESTART:
        vm->restart = 1;
        except = FICL_VM_STATUS_OUT_OF_TEXT;
        break;

    case FICL_VM_STATUS_OUT_OF_TEXT:
        ficlVmPopIP(vm);
        if ((vm->state != FICL_VM_STATE_COMPILE) && (vm->sourceId.i == 0))
            ficlVmTextOut(vm, FICL_PROMPT);
        break;

    case FICL_VM_STATUS_USER_EXIT:
    case FICL_VM_STATUS_INNER_EXIT:
    case FICL_VM_STATUS_BREAK:
        break;

    case FICL_VM_STATUS_QUIT:
        if (vm->state == FICL_VM_STATE_COMPILE)
        {
            ficlDictionaryAbortDefinition(dictionary);
#if FICL_WANT_LOCALS
            ficlDictionaryEmpty(system->locals, system->locals->forthWordlist->size);
#endif
        }
        ficlVmQuit(vm);
        break;

    case FICL_VM_STATUS_ERROR_EXIT:
    case FICL_VM_STATUS_ABORT:
    case FICL_VM_STATUS_ABORTQ:
    default:    /* user defined exit code?? */
        if (vm->state == FICL_VM_STATE_COMPILE)
        {
            ficlDictionaryAbortDefinition(dictionary);
#if FICL_WANT_LOCALS
            ficlDictionaryEmpty(system->locals, system->locals->forthWordlist->size);
#endif
        }
        ficlDictionaryResetSearchOrder(dictionary);
        ficlVmReset(vm);
        break;
   }

    vm->exceptionHandler    = oldState;
    ficlVmPopTib(vm, &saveficlTIB);
    return (except);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xe8, %rsp
movq %rdi, %rbx
movq 0x18(%rdi), %r13
movq 0x38(%r13), %r14
leaq 0x80(%rdi), %r15
movq 0x90(%rdi), %rax
movq %rax, 0x10(%rsp)
movups 0x80(%rdi), %xmm0
movaps %xmm0, (%rsp)
movq %rdx, 0x90(%rdi)
addq %rdx, %rsi
movq %rsi, 0x88(%rdi)
movq $0x0, 0x80(%rdi)
movq 0x30(%rdi), %r12
leaq 0x20(%rsp), %rdi
movq %rdi, 0x30(%rbx)
callq 0x3180
movl %eax, %ebp
movl %eax, %ecx
addl $0x105, %ecx            # imm = 0x105
cmpl $0x5, %ecx
ja 0x6da1
movl %ecx, %eax
leaq 0x7be8(%rip), %rcx      # 0xe970
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movw $0x1, 0x38(%rbx)
movl $0xfffffeff, %eax       # imm = 0xFFFFFEFF
jmp 0x6e88
cmpl $-0x38, %eax
je 0x6e1f
testl %eax, %eax
jne 0x6dca
cmpw $0x0, 0x38(%rbx)
je 0x6e65
movq 0x48(%rbx), %rax
movq %rbx, %rdi
callq *0x18(%rax)
movw $0x0, 0x38(%rbx)
jmp 0x6e7a
cmpq $0x1, 0x50(%rbx)
jne 0x6dd9
movq %r14, %rdi
callq 0xc044
movq %r14, %rdi
callq 0xc746
movq %rbx, %rdi
callq 0x5337
jmp 0x6e86
movq 0x68(%rbx), %rdi
callq 0x42f1
movq %rax, 0x40(%rbx)
movl $0xfffffeff, %ebp       # imm = 0xFFFFFEFF
cmpq $0x1, 0x50(%rbx)
je 0x6e86
cmpq $0x0, 0x78(%rbx)
jne 0x6e86
leaq 0x722c(%rip), %rsi      # 0xe041
movq %rbx, %rdi
callq 0xb9d4
jmp 0x6e86
cmpq $0x1, 0x50(%rbx)
jne 0x6e2e
movq %r14, %rdi
callq 0xc044
movq 0x68(%rbx), %rdi
callq 0x4261
movw $0x0, 0x38(%rbx)
movb $0x0, 0x118(%rbx)
xorps %xmm0, %xmm0
movups %xmm0, 0x40(%rbx)
movq $0x0, 0x50(%rbx)
movups %xmm0, 0x78(%rbx)
movups %xmm0, 0x88(%rbx)
movl $0xffffffc8, %eax       # imm = 0xFFFFFFC8
jmp 0x6e88
addq $0x48, %r13
movq 0x40(%rbx), %rsi
movq 0x68(%rbx), %rdi
callq 0x436a
movq %r13, 0x40(%rbx)
xorl %ebp, %ebp
movl %ebp, %esi
movq %rbx, %rdi
callq 0x53ba
movl %ebp, %eax
movq %r12, 0x30(%rbx)
movq 0x10(%rsp), %rcx
movq %rcx, 0x10(%r15)
movaps (%rsp), %xmm0
movups %xmm0, (%r15)
addq $0xe8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq