// File: /workspace/github_c_makefile_star2_O2/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
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)
andq $0x0, 0x80(%rdi)
leaq 0x80(%rdi), %r15
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 0x6a06
movl %ecx, %eax
leaq 0x7f83(%rip), %rcx      # 0xe970
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movw $0x1, 0x38(%rbx)
movl $0xfffffeff, %eax       # imm = 0xFFFFFEFF
jmp 0x6aad
cmpl $-0x38, %eax
je 0x6a74
testl %eax, %eax
jne 0x6a27
cmpw $0x0, 0x38(%rbx)
je 0x6a90
movq 0x48(%rbx), %rax
movq %rbx, %rdi
callq *0x18(%rax)
andw $0x0, 0x38(%rbx)
jmp 0x6a9f
cmpq $0x1, 0x50(%rbx)
jne 0x6a36
movq %r14, %rdi
callq 0xb798
movq %r14, %rdi
callq 0xbd69
movq %rbx, %rdi
callq 0x51e7
jmp 0x6aab
movq %rbx, %rdi
callq 0x6835
movl $0xfffffeff, %ebp       # imm = 0xFFFFFEFF
cmpq $0x1, 0x50(%rbx)
je 0x6aab
cmpq $0x0, 0x78(%rbx)
jne 0x6aab
leaq 0x75d7(%rip), %rsi      # 0xe041
movq %rbx, %rdi
callq 0xb1ac
jmp 0x6aab
cmpq $0x1, 0x50(%rbx)
jne 0x6a83
movq %r14, %rdi
callq 0xb798
movq %rbx, %rdi
callq 0x68ba
pushq $-0x38
popq %rax
jmp 0x6aad
movq %r13, %rsi
addq $0x48, %rsi
movq %rbx, %rdi
callq 0x6848
xorl %ebp, %ebp
movl %ebp, %esi
movq %rbx, %rdi
callq 0x523f
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