// File: /workspace/github_c_makefile_star2_O0/hoobaa[P]ficl/system.c
// Function: ficlSystemCreate
ficlSystem *ficlSystemCreate(ficlSystemInformation *fsi)
{
    ficlInteger dictionarySize;
    ficlInteger environmentSize;
	ficlInteger stackSize;
    ficlSystem *system;
	ficlCallback callback;
	ficlSystemInformation fauxInfo;
	ficlDictionary *environment;



	if (fsi == NULL)
	{
		fsi = &fauxInfo;
		ficlSystemInformationInitialize(fsi);
	}

	callback.context = fsi->context;
	callback.textOut = fsi->textOut;
	callback.errorOut = fsi->errorOut;
	callback.system = NULL;
	callback.vm = NULL;

    FICL_ASSERT(&callback, sizeof(ficlInteger) >= sizeof(void *));
    FICL_ASSERT(&callback, sizeof(ficlUnsigned) >= sizeof(void *));
#if (FICL_WANT_FLOAT)
    FICL_ASSERT(&callback, sizeof(ficlFloat) <= sizeof(ficlInteger));
#endif

    system = ficlMalloc(sizeof(ficlSystem));

    FICL_ASSERT(&callback, system);

    memset(system, 0, sizeof(ficlSystem));

    dictionarySize = fsi->dictionarySize;
    if (dictionarySize <= 0)
        dictionarySize = FICL_DEFAULT_DICTIONARY_SIZE;

    environmentSize = fsi->environmentSize;
    if (environmentSize <= 0)
        environmentSize = FICL_DEFAULT_DICTIONARY_SIZE;

    stackSize = fsi->stackSize;
    if (stackSize < FICL_DEFAULT_STACK_SIZE)
        stackSize = FICL_DEFAULT_STACK_SIZE;

    system->dictionary = ficlDictionaryCreateHashed(system, (unsigned)dictionarySize, FICL_HASH_SIZE);
    system->dictionary->forthWordlist->name = "forth-wordlist";

    environment = ficlDictionaryCreate(system, (unsigned)environmentSize);
    system->environment = environment;
    system->environment->forthWordlist->name = "environment";

    system->callback.textOut = fsi->textOut;
    system->callback.errorOut = fsi->errorOut;
    system->callback.context = fsi->context;
    system->callback.system = system;
    system->callback.vm = NULL;
    system->stackSize = stackSize;

#if FICL_WANT_LOCALS
    /*
    ** The locals dictionary is only searched while compiling,
    ** but this is where speed is most important. On the other
    ** hand, the dictionary gets emptied after each use of locals
    ** The need to balance search speed with the cost of the 'empty'
    ** operation led me to select a single-threaded list...
    */
    system->locals = ficlDictionaryCreate(system, (unsigned)FICL_MAX_LOCALS * FICL_CELLS_PER_WORD);
#endif /* FICL_WANT_LOCALS */

    /*
    ** Build the precompiled dictionary and load softwords. We need a temporary
    ** VM to do this - ficlNewVM links one to the head of the system VM list.
    ** ficlCompilePlatform (defined in win32.c, for example) adds platform specific words.
    */
    ficlSystemCompileCore(system);
    ficlSystemCompilePrefix(system);

#if FICL_WANT_FLOAT
    ficlSystemCompileFloat(system);
#endif /* FICL_WANT_FLOAT */

#if FICL_WANT_PLATFORM
    ficlSystemCompilePlatform(system);
#endif /* FICL_WANT_PLATFORM */

    ficlSystemSetVersion(system);

    /*
    ** Establish the parse order. Note that prefixes precede numbers -
    ** this allows constructs like "0b101010" which might parse as a
    ** hex value otherwise.
    */
    ficlSystemAddPrimitiveParseStep(system, "?word", ficlVmParseWord);
    ficlSystemAddPrimitiveParseStep(system, "?prefix", ficlVmParsePrefix);
    ficlSystemAddPrimitiveParseStep(system, "?number", ficlVmParseNumber);
#if FICL_WANT_FLOAT
    ficlSystemAddPrimitiveParseStep(system, "?float", ficlVmParseFloatNumber);
#endif

    /*
    ** Now create a temporary VM to compile the softwords. Since all VMs are
    ** linked into the vmList of ficlSystem, we don't have to pass the VM
    ** to ficlCompileSoftCore -- it just hijacks whatever it finds in the VM list.
    ** Ficl 2.05: vmCreate no longer depends on the presence of INTERPRET in the
    ** dictionary, so a VM can be created before the dictionary is built. It just
    ** can't do much...
    */
    ficlSystemCreateVm(system);
#define ADD_COMPILE_FLAG(name) ficlDictionarySetConstant(environment, #name, name)
	ADD_COMPILE_FLAG(FICL_WANT_LZ_SOFTCORE);
	ADD_COMPILE_FLAG(FICL_WANT_FILE);
	ADD_COMPILE_FLAG(FICL_WANT_FLOAT);
	ADD_COMPILE_FLAG(FICL_WANT_DEBUGGER);
	ADD_COMPILE_FLAG(FICL_WANT_EXTENDED_PREFIX);
	ADD_COMPILE_FLAG(FICL_WANT_USER);
	ADD_COMPILE_FLAG(FICL_WANT_LOCALS);
	ADD_COMPILE_FLAG(FICL_WANT_OOP);
	ADD_COMPILE_FLAG(FICL_WANT_SOFTWORDS);
	ADD_COMPILE_FLAG(FICL_WANT_MULTITHREADED);
	ADD_COMPILE_FLAG(FICL_WANT_OPTIMIZE);
	ADD_COMPILE_FLAG(FICL_WANT_VCALL);

	ADD_COMPILE_FLAG(FICL_PLATFORM_ALIGNMENT);

	ADD_COMPILE_FLAG(FICL_ROBUST);

#define ADD_COMPILE_STRING(name) ficlDictionarySetConstantString(environment, #name, name)
	ADD_COMPILE_STRING(FICL_PLATFORM_ARCHITECTURE);
	ADD_COMPILE_STRING(FICL_PLATFORM_OS);

    ficlSystemCompileSoftCore(system);
    ficlSystemDestroyVm(system->vmList);

	if (ficlSystemGlobal == NULL)
		ficlSystemGlobal = system;

    return system;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x90, %rsp
movq %rdi, -0x8(%rbp)
cmpq $0x0, -0x8(%rbp)
jne 0x3578
leaq -0x80(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rdi
xorl %esi, %esi
movl $0x30, %edx
callq 0x3120
movq -0x8(%rbp), %rax
movl $0x30, (%rax)
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x50(%rbp)
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x48(%rbp)
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rax
movq %rax, -0x40(%rbp)
movq $0x0, -0x38(%rbp)
movq $0x0, -0x30(%rbp)
movl $0xc8, %edi
callq 0xf930
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rdi
xorl %esi, %esi
movl $0xc8, %edx
callq 0x3120
movq -0x8(%rbp), %rax
movslq 0x10(%rax), %rax
movq %rax, -0x10(%rbp)
cmpq $0x0, -0x10(%rbp)
jg 0x35e5
movq $0x3000, -0x10(%rbp)    # imm = 0x3000
movq -0x8(%rbp), %rax
movslq 0x28(%rax), %rax
movq %rax, -0x18(%rbp)
cmpq $0x0, -0x18(%rbp)
jg 0x3600
movq $0x3000, -0x18(%rbp)    # imm = 0x3000
movq -0x8(%rbp), %rax
movslq 0x14(%rax), %rax
movq %rax, -0x20(%rbp)
cmpq $0x80, -0x20(%rbp)
jge 0x361e
movq $0x80, -0x20(%rbp)
movq -0x28(%rbp), %rdi
movq -0x10(%rbp), %rax
movl %eax, %esi
movl $0xf1, %edx
callq 0x11970
movq %rax, %rcx
movq -0x28(%rbp), %rax
movq %rcx, 0x38(%rax)
movq -0x28(%rbp), %rax
movq 0x38(%rax), %rax
movq 0x18(%rax), %rax
leaq 0x119f6(%rip), %rcx     # 0x15046
movq %rcx, 0x8(%rax)
movq -0x28(%rbp), %rdi
movq -0x18(%rbp), %rax
movl %eax, %esi
callq 0x11940
movq %rax, -0x88(%rbp)
movq -0x88(%rbp), %rcx
movq -0x28(%rbp), %rax
movq %rcx, 0x40(%rax)
movq -0x28(%rbp), %rax
movq 0x40(%rax), %rax
movq 0x18(%rax), %rax
leaq 0x119c9(%rip), %rcx     # 0x15055
movq %rcx, 0x8(%rax)
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rcx
movq -0x28(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rcx
movq -0x28(%rbp), %rax
movq %rcx, 0x10(%rax)
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rcx
movq -0x28(%rbp), %rax
movq %rcx, (%rax)
movq -0x28(%rbp), %rcx
movq -0x28(%rbp), %rax
movq %rcx, 0x18(%rax)
movq -0x28(%rbp), %rax
movq $0x0, 0x20(%rax)
movq -0x20(%rbp), %rcx
movq -0x28(%rbp), %rax
movq %rcx, 0xb0(%rax)
movq -0x28(%rbp), %rdi
callq 0x9fc0
movq -0x28(%rbp), %rdi
callq 0x4730
movq -0x28(%rbp), %rdi
callq 0x42b0
movq -0x28(%rbp), %rdi
callq 0xfac0
movq -0x28(%rbp), %rdi
callq 0x3930
movq -0x28(%rbp), %rdi
leaq 0x11943(%rip), %rsi     # 0x15061
leaq 0x65fb(%rip), %rdx      # 0x9d20
callq 0x39d0
movq -0x28(%rbp), %rdi
leaq 0x11932(%rip), %rsi     # 0x15067
leaq 0xee4(%rip), %rdx       # 0x4620
callq 0x39d0
movq -0x28(%rbp), %rdi
leaq 0x11923(%rip), %rsi     # 0x1506f
leaq 0x633d(%rip), %rdx      # 0x9a90
callq 0x39d0
movq -0x28(%rbp), %rdi
leaq 0x11914(%rip), %rsi     # 0x15077
leaq 0x786(%rip), %rdx       # 0x3ef0
callq 0x39d0
movq -0x28(%rbp), %rdi
callq 0x3a30
movq -0x88(%rbp), %rdi
leaq 0x118f8(%rip), %rsi     # 0x1507e
movl $0x1, %edx
callq 0x11540
movq -0x88(%rbp), %rdi
leaq 0x118f6(%rip), %rsi     # 0x15094
movl $0x1, %edx
callq 0x11540
movq -0x88(%rbp), %rdi
leaq 0x118ed(%rip), %rsi     # 0x150a3
movl $0x1, %edx
callq 0x11540
movq -0x88(%rbp), %rdi
leaq 0x118e5(%rip), %rsi     # 0x150b3
movl $0x1, %edx
callq 0x11540
movq -0x88(%rbp), %rdi
leaq 0x118e0(%rip), %rsi     # 0x150c6
xorl %eax, %eax
movl %eax, %edx
callq 0x11540
movq -0x88(%rbp), %rdi
leaq 0x118e3(%rip), %rsi     # 0x150e0
movl $0x1, %edx
callq 0x11540
movq -0x88(%rbp), %rdi
leaq 0x118da(%rip), %rsi     # 0x150ef
xorl %eax, %eax
movl %eax, %edx
callq 0x11540
movq -0x88(%rbp), %rdi
leaq 0x118d4(%rip), %rsi     # 0x15100
xorl %eax, %eax
movl %eax, %edx
callq 0x11540
movq -0x88(%rbp), %rdi
leaq 0x118cb(%rip), %rsi     # 0x1510e
movl $0x1, %edx
callq 0x11540
movq -0x88(%rbp), %rdi
leaq 0x118c7(%rip), %rsi     # 0x15122
xorl %eax, %eax
movl %eax, %edx
callq 0x11540
movq -0x88(%rbp), %rdi
leaq 0x118c8(%rip), %rsi     # 0x1513a
movl $0x1, %edx
callq 0x11540
movq -0x88(%rbp), %rdi
leaq 0x118c3(%rip), %rsi     # 0x1514d
xorl %eax, %eax
movl %eax, %edx
callq 0x11540
movq -0x88(%rbp), %rdi
leaq 0x118bc(%rip), %rsi     # 0x1515d
movl $0x8, %edx
callq 0x11540
movq -0x88(%rbp), %rdi
leaq 0x118bc(%rip), %rsi     # 0x15175
xorl %eax, %eax
movl %eax, %edx
callq 0x11540
movq -0x88(%rbp), %rdi
leaq 0x118b1(%rip), %rsi     # 0x15181
leaq 0x118c5(%rip), %rdx     # 0x1519c
callq 0x116a0
movq -0x88(%rbp), %rdi
leaq 0x118ba(%rip), %rsi     # 0x151a4
leaq 0x118c4(%rip), %rdx     # 0x151b5
callq 0x116a0
movq -0x28(%rbp), %rdi
callq 0x4830
movq -0x28(%rbp), %rax
movq 0x30(%rax), %rdi
callq 0x3ac0
cmpq $0x0, 0x1bba4(%rip)     # 0x1f4b8
jne 0x3921
movq -0x28(%rbp), %rax
movq %rax, 0x1bb97(%rip)     # 0x1f4b8
movq -0x28(%rbp), %rax
addq $0x90, %rsp
popq %rbp
retq
nop