// File: /workspace/github_c_makefile_star2_O3/heltilda[P]cicada/ciclib.c
// Function: cclib_call
void cclib_call()
{
    window *functionNameWindow;
    view argView;
    char **pointerList, **argvHandles;
    ccInt functionID, charCounter, argCounter, numArgs, numDataWindows, numStrings, theType;
    arg_info *infoList, *argvInfo;
    ccBool match;
    
    numArgs = numBIF_args();
    if (numArgs < 1)  {  setError(wrong_argument_count_err, pcCodePtr-1);  return;  }
    
    
        // get first argument:  the function name/ID number
    
    functionNameWindow = getBIFmember(1);
    if (functionNameWindow == NULL)  {  setError(void_member_err, pcCodePtr-1);  return;  }
    if (functionNameWindow->width != 1)  {  setError(multiple_indices_not_allowed_err, pcCodePtr-1);  return;  }
    
    
        // if the user passed a name, then find its position in the UserFunctions list
    
    theType = functionNameWindow->variable_ptr->type;
    if (theType == string_type)    {
        
        window *functionNameCharWindow = LL_member(functionNameWindow->variable_ptr, functionNameWindow->offset+1)->memberWindow; 
        linkedlist *functionNameString = &(functionNameCharWindow->variable_ptr->mem.data); 
        if (errCode != passed)  return;   
        
        for (functionID = 0; functionID < userFunctionsNum; functionID++)   {
            match = ccTrue;
            for (charCounter = functionNameCharWindow->offset; 
                            charCounter < functionNameCharWindow->offset+functionNameCharWindow->width; charCounter++)   {
                if ((*(char *) element(functionNameString, charCounter+1) != UserFunctions[functionID].functionName[charCounter]) ||
                                    (UserFunctions[functionID].functionName[charCounter] == 0))   {
                    {  match = ccFalse;  break;  }    // 2nd condition to prevent crash if 0 is in the functionID string
            }   }
            if (UserFunctions[functionID].functionName[charCounter] != 0)  match = ccFalse;
            if (match)  break;     }
        
        if (functionID == userFunctionsNum)
            {  setError(user_function_not_found_err, pcCodePtr-1);  return;  }    }
    
    
        // if the user passed the position directly, we have less work to do
    
    else if ((theType >= int_type) && (theType <= double_type))  {
        
        functionID = (ccInt) getBIFnumArg(1, 1., (ccFloat) userFunctionsNum) - 1;
        if (errCode == out_of_range_err)  errCode = user_function_not_found_err;
        if (errCode != passed)  return;     }
    
    else  {  setError(string_expected_err, pcCodePtr-1);  return;  }
    
    
        // Now count the number of primitive arrays to pass to the function (note that variables count as arrays of 1)
        // These come from arguments 2-the last.
    
    numDataWindows = 0;
    numStrings = 0;
    
    extCallMode = ccTrue;
    
    for (argCounter = 2; argCounter <= numArgs; argCounter++)  {
        argView.windowPtr = getBIFmember(argCounter);
        if (argView.windowPtr != NULL)   {
            argView.offset = argView.windowPtr->offset;
            argView.width = argView.windowPtr->width;
            countDataLists(&argView, (void *) &numDataWindows, (void *) &numStrings);
            if (errCode != passed)  break;
    }   }
    if (errCode != passed)  {  extCallMode = ccFalse;  return;  }
    
    
        // Allocate space both for our argument pointers and for the info list that Cicada provides.
    
    pointerList = (char **) malloc((numDataWindows+numStrings+1)*sizeof(char *));
    if (pointerList == NULL)  {  setError(out_of_memory_err, pcCodePtr-1);  extCallMode = ccFalse;  return;  }
    infoList = (arg_info *) malloc((numDataWindows+numStrings)*sizeof(arg_info) + 4);     //  avoid size-0 malloc
    if (infoList == NULL)  {  setError(out_of_memory_err, pcCodePtr-1);  extCallMode = ccFalse;  return;  }
    
    
        // Now fill the argument pointer/info lists.
    
    argvHandles = pointerList;
    argvInfo = infoList;
    for (argCounter = 2; argCounter <= numArgs; argCounter++)  {
        argView.windowPtr = getBIFmember(argCounter);
        if (argView.windowPtr != NULL)  {
            argView.offset = argView.windowPtr->offset;
            argView.width = argView.windowPtr->width;
            argvFillHandles(&argView, (void *) &argvHandles, (void *) &argvInfo);
            if (errCode != passed)  break;
    }   }
    pointerList[numDataWindows+numStrings] = (char *) infoList;
    
    
        // store the return value of the function in intRegister
    
    if (errCode == passed)
        intRegister = (ccInt) UserFunctions[functionID].functionPtr(numDataWindows+numStrings, (char **) pointerList);
    
    
        // fix the string windows (in case the string linked lists were resized) and clean up
    
    argvHandles = pointerList;
    for (argCounter = 2; argCounter <= numArgs; argCounter++)  {
        argView.windowPtr = getBIFmember(argCounter);
        if (argView.windowPtr != NULL)  {
            argView.offset = argView.windowPtr->offset;
            argView.width = argView.windowPtr->width;
            argvFixStrings(&argView, (void *) &argvHandles, NULL);
    }   }
    
    free((void *) pointerList);
    free((void *) infoList);
    
    extCallMode = ccFalse;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x58, %rsp
callq 0x19254
testl %eax, %eax
jle 0x163e5
movl %eax, %ebx
movl $0x1, %edi
callq 0x1929e
testq %rax, %rax
je 0x163fe
cmpl $0x1, 0x1c(%rax)
jne 0x16417
movq 0x10(%rax), %rdi
movl 0xc0(%rdi), %ecx
cmpl $0x4, %ecx
jne 0x16441
addq $0x10, %rdi
movl 0x18(%rax), %esi
incl %esi
callq 0x91d8
leaq 0xf436(%rip), %rcx      # 0x25760
cmpl $0x0, 0x18(%rcx)
jne 0x16610
movq %rbx, 0x18(%rsp)
leaq 0x5b0c(%rip), %rcx      # 0x1be4c
movslq (%rcx), %rdx
movq %rdx, 0x10(%rsp)
testq %rdx, %rdx
jle 0x164af
movq (%rax), %r12
movq 0x10(%r12), %r14
addq $0x10, %r14
xorl %r15d, %r15d
movslq 0x18(%r12), %rbx
movq %r15, 0x20(%rsp)
shlq $0x4, %r15
addq 0xbc63(%rip), %r15      # 0x21fd8
movq %rbx, %r13
shlq $0x20, %r13
leal 0x1(%rbx), %ebp
movslq 0x18(%r12), %rax
movslq 0x1c(%r12), %rcx
addq %rax, %rcx
cmpq %rcx, %rbx
jge 0x163bd
movq %r14, %rdi
movl %ebp, %esi
callq 0x91d8
movq (%r15), %rcx
movb (%rcx,%rbx), %cl
cmpb %cl, (%rax)
jne 0x163d1
incq %rbx
movabsq $0x100000000, %rax      # imm = 0x100000000
addq %rax, %r13
incl %ebp
testb %cl, %cl
jne 0x1637f
jmp 0x163d1
jl 0x163d1
sarq $0x20, %r13
movq (%r15), %rax
cmpb $0x0, (%rax,%r13)
je 0x164b3
movq 0x20(%rsp), %r15
incq %r15
cmpq 0x10(%rsp), %r15
jne 0x16360
jmp 0x164be
leaq 0xf374(%rip), %rax      # 0x25760
movq 0xb8(%rax), %rsi
addq $-0x4, %rsi
movl $0x2d, %edi
jmp 0x1642e
leaq 0xf35b(%rip), %rax      # 0x25760
movq 0xb8(%rax), %rsi
addq $-0x4, %rsi
movl $0x1a, %edi
jmp 0x1642e
leaq 0xf342(%rip), %rax      # 0x25760
movq 0xb8(%rax), %rsi
addq $-0x4, %rsi
movl $0x1f, %edi
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0xcfa3
andl $-0x2, %ecx
cmpl $0x2, %ecx
jne 0x16489
leaq 0x59fc(%rip), %rax      # 0x1be4c
cvtsi2sdl (%rax), %xmm1
movsd 0x4bac(%rip), %xmm0     # 0x1b008
movl $0x1, %edi
callq 0x1930e
leaq 0xf2f3(%rip), %rax      # 0x25760
movl 0x18(%rax), %ecx
testl %ecx, %ecx
je 0x164a2
cmpl $0x2, %ecx
jne 0x16610
movl $0x2c, 0x18(%rax)
jmp 0x16610
leaq 0xf2d0(%rip), %rax      # 0x25760
movq 0xb8(%rax), %rsi
addq $-0x4, %rsi
movl $0x25, %edi
jmp 0x1642e
movq %rbx, 0x18(%rsp)
cvttsd2si %xmm0, %eax
decl %eax
jmp 0x164da
xorl %eax, %eax
jmp 0x164b8
movq 0x20(%rsp), %rax
cmpl 0x10(%rsp), %eax
jne 0x164da
leaq 0xf29b(%rip), %rax      # 0x25760
movq 0xb8(%rax), %rsi
addq $-0x4, %rsi
movl $0x2c, %edi
jmp 0x1642e
movq %rax, 0x20(%rsp)
xorl %eax, %eax
movl %eax, 0xc(%rsp)
movl %eax, 0x8(%rsp)
leaq 0xf270(%rip), %r15      # 0x25760
movb $0x1, 0x2a8(%r15)
cmpl $0x1, 0x18(%rsp)
je 0x1656d
movq 0x18(%rsp), %rax
cmpl $0x3, %eax
movl $0x2, %r14d
movl $0x2, %ebx
cmovgel %eax, %ebx
negl %ebx
leaq 0x38(%rsp), %rbp
leaq 0xc(%rsp), %r12
leaq 0x8(%rsp), %r13
movl %r14d, %edi
callq 0x1929e
movq %rax, 0x38(%rsp)
testq %rax, %rax
je 0x1655a
movq 0x18(%rax), %rax
movq %rax, 0x40(%rsp)
movq %rbp, %rdi
movq %r12, %rsi
movq %r13, %rdx
callq 0xe19c
cmpl $0x0, 0x18(%r15)
jne 0x16608
leal (%rbx,%r14), %eax
incl %eax
movl %r14d, %ecx
incl %ecx
movl %ecx, %r14d
cmpl $0x1, %eax
jne 0x16526
cmpl $0x0, 0x18(%r15)
jne 0x16608
movslq 0xc(%rsp), %rax
movslq 0x8(%rsp), %r12
addq %rax, %r12
leaq 0x8(,%r12,8), %rdi
callq 0x81d0
testq %rax, %rax
je 0x165f3
movq %rax, %r13
movslq %r12d, %rbx
leaq 0x4(,%rbx,8), %rdi
callq 0x81d0
testq %rax, %rax
je 0x165f3
movq %r13, 0x28(%rsp)
movq %rax, 0x50(%rsp)
movq 0x18(%rsp), %rbp
cmpl $0x1, %ebp
movq %rax, 0x10(%rsp)
jne 0x1661f
movq %rax, (%r13,%rbx,8)
movslq 0x20(%rsp), %rax
shlq $0x4, %rax
leaq 0xeac3(%rip), %rcx      # 0x250a0
movl %r12d, %edi
movq %r13, %rsi
callq *0x8(%rcx,%rax)
movq %r15, %r14
movl %eax, 0x6c(%r15)
jmp 0x166d9
movq 0xb8(%r15), %rsi
addq $-0x4, %rsi
movl $0x1, %edi
callq 0xcfa3
movb $0x0, 0x2a8(%r15)
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %r13, 0x30(%rsp)
movq %r15, %r14
cmpl $0x3, %ebp
movl $0x2, %r12d
movl $0x2, %ebx
movq %rbp, %r15
cmovgel %ebp, %ebx
negl %ebx
leaq 0x28(%rsp), %r13
leaq 0x50(%rsp), %rbp
movl %r12d, %edi
callq 0x1929e
movq %rax, 0x38(%rsp)
testq %rax, %rax
je 0x16679
movq 0x18(%rax), %rax
movq %rax, 0x40(%rsp)
leaq 0x38(%rsp), %rdi
movq %r13, %rsi
movq %rbp, %rdx
callq 0xe1d7
cmpl $0x0, 0x18(%r14)
jne 0x166ba
leal (%rbx,%r12), %eax
incl %eax
movl %r12d, %ecx
incl %ecx
movl %ecx, %r12d
cmpl $0x1, %eax
jne 0x16647
movslq 0xc(%rsp), %rax
movslq 0x8(%rsp), %r12
addq %rax, %r12
cmpl $0x0, 0x18(%r14)
movq 0x30(%rsp), %r13
movq 0x10(%rsp), %rax
movq %rax, (%r13,%r12,8)
movq %r15, %rbp
jne 0x166d9
movq %r14, %r15
jmp 0x165cd
movslq 0xc(%rsp), %rax
movslq 0x8(%rsp), %rcx
addq %rax, %rcx
movq 0x30(%rsp), %r13
movq 0x10(%rsp), %rax
movq %rax, (%r13,%rcx,8)
movq %r15, %rbp
movq %r13, %rbx
movq %r13, 0x28(%rsp)
cmpl $0x1, %ebp
je 0x1673a
cmpl $0x3, %ebp
movl $0x2, %r12d
cmovll %r12d, %ebp
negl %ebp
leaq 0x38(%rsp), %r15
leaq 0x28(%rsp), %r13
movl %r12d, %edi
callq 0x1929e
movq %rax, 0x38(%rsp)
testq %rax, %rax
je 0x16727
movq 0x18(%rax), %rax
movq %rax, 0x40(%rsp)
movq %r15, %rdi
movq %r13, %rsi
xorl %edx, %edx
callq 0xe885
leal (%r12,%rbp), %eax
incl %eax
movl %r12d, %ecx
incl %ecx
movl %ecx, %r12d
cmpl $0x1, %eax
jne 0x166ff
movq %rbx, %rdi
callq 0x81c0
movq 0x10(%rsp), %rdi
callq 0x81c0
movb $0x0, 0x2a8(%r14)
jmp 0x16610