// File: /workspace/github_c_makefile_star2_O1/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 0x1926a
testl %eax, %eax
jle 0x1637e
movl %eax, %r13d
movl $0x1, %edi
callq 0x192b4
testq %rax, %rax
je 0x16397
cmpl $0x1, 0x1c(%rax)
jne 0x163b0
movq 0x10(%rax), %rdi
movl 0xc0(%rdi), %ecx
cmpl $0x4, %ecx
jne 0x163da
addq $0x10, %rdi
movl 0x18(%rax), %esi
incl %esi
callq 0x911c
leaq 0xf3f5(%rip), %rdx      # 0x25760
xorl %ebx, %ebx
cmpl $0x0, 0x18(%rdx)
je 0x16441
xorl %eax, %eax
jmp 0x16558
leaq 0xf3db(%rip), %rax      # 0x25760
movq 0xb8(%rax), %rsi
addq $-0x4, %rsi
movl $0x2d, %edi
jmp 0x163c7
leaq 0xf3c2(%rip), %rax      # 0x25760
movq 0xb8(%rax), %rsi
addq $-0x4, %rsi
movl $0x1a, %edi
jmp 0x163c7
leaq 0xf3a9(%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 0xd1a9
andl $-0x2, %ecx
cmpl $0x2, %ecx
jne 0x16428
leaq 0x5a83(%rip), %rax      # 0x1be6c
cvtsi2sdl (%rax), %xmm1
movsd 0x4c13(%rip), %xmm0     # 0x1b008
movl $0x1, %edi
callq 0x19324
leaq 0xf35a(%rip), %rax      # 0x25760
cmpl $0x2, 0x18(%rax)
jne 0x16413
movl $0x2c, 0x18(%rax)
cmpl $0x0, 0x18(%rax)
jne 0x16736
cvttsd2si %xmm0, %ebx
decl %ebx
jmp 0x16560
leaq 0xf331(%rip), %rax      # 0x25760
movq 0xb8(%rax), %rsi
addq $-0x4, %rsi
movl $0x25, %edi
jmp 0x163c7
leaq 0x5a24(%rip), %rcx      # 0x1be6c
movslq (%rcx), %rsi
testq %rsi, %rsi
jle 0x1653b
movq %r13, 0x38(%rsp)
movq (%rax), %r15
movq 0x10(%r15), %rax
addq $0x10, %rax
movq %rax, 0x10(%rsp)
xorl %ecx, %ecx
movq %rsi, 0x40(%rsp)
movslq 0x18(%r15), %rax
movq %rcx, 0x8(%rsp)
movq %rcx, %rdx
shlq $0x4, %rdx
leaq 0xec19(%rip), %rcx      # 0x250a0
movq %rdx, 0x48(%rsp)
leaq (%rdx,%rcx), %rbx
movq %rax, %rcx
shlq $0x20, %rcx
leal 0x1(%rax), %ebp
movq %rax, %r12
movq %rcx, %r13
movslq 0x18(%r15), %rax
movslq 0x1c(%r15), %r14
addq %rax, %r14
cmpq %r14, %r12
jge 0x164df
movq 0x10(%rsp), %rdi
movl %ebp, %esi
callq 0x911c
movq (%rbx), %rcx
movb (%rcx,%r12), %dl
cmpb %dl, (%rax)
jne 0x164df
leaq 0x1(%r12), %rax
movabsq $0x100000000, %rcx      # imm = 0x100000000
addq %r13, %rcx
incl %ebp
testb %dl, %dl
jne 0x1649a
cmpq %r14, %r12
jl 0x164ff
sarq $0x20, %r13
leaq 0xebb1(%rip), %rax      # 0x250a0
movq 0x48(%rsp), %rcx
movq (%rax,%rcx), %rax
cmpb $0x0, (%rax,%r13)
je 0x16525
movq 0x8(%rsp), %rcx
incq %rcx
movq 0x40(%rsp), %rsi
cmpq %rsi, %rcx
jne 0x16470
movl %esi, %ebx
movq 0x38(%rsp), %r13
leaq 0xf23d(%rip), %rdx      # 0x25760
jmp 0x1653b
movq 0x38(%rsp), %r13
movq 0x8(%rsp), %rbx
leaq 0xf22a(%rip), %rdx      # 0x25760
movq 0x40(%rsp), %rsi
movb $0x1, %al
cmpl %esi, %ebx
jne 0x16558
movq 0xb8(%rdx), %rsi
addq $-0x4, %rsi
movl $0x2c, %edi
callq 0xd1a9
xorl %eax, %eax
testb %al, %al
je 0x16736
xorl %eax, %eax
movl %eax, 0x4(%rsp)
movl %eax, (%rsp)
leaq 0xf1f0(%rip), %rax      # 0x25760
movb $0x1, 0x2a8(%rax)
cmpl $0x1, %r13d
jne 0x166bc
leaq 0xf1d8(%rip), %r15      # 0x25760
cmpl $0x0, 0x18(%r15)
jne 0x1672e
movq %rbx, %r14
movslq 0x4(%rsp), %rax
movslq (%rsp), %rbx
addq %rax, %rbx
leaq 0x8(,%rbx,8), %rdi
callq 0x81d0
testq %rax, %rax
je 0x16719
movq %rax, %r12
movslq %ebx, %rax
leaq 0x4(,%rax,8), %rdi
callq 0x81d0
testq %rax, %rax
je 0x16719
movq %r12, %rbx
movq %r12, 0x18(%rsp)
movq %rax, 0x10(%rsp)
movq %rax, 0x50(%rsp)
cmpl $0x1, %r13d
movq %r14, 0x8(%rsp)
jne 0x16745
movslq 0x4(%rsp), %rax
movslq (%rsp), %rdi
addq %rax, %rdi
movq %rbx, %rbp
movq 0x10(%rsp), %rax
movq %rax, (%rbx,%rdi,8)
leaq 0xf14c(%rip), %r14      # 0x25760
cmpl $0x0, 0x18(%r14)
jne 0x16636
movslq 0x8(%rsp), %rax
shlq $0x4, %rax
leaq 0xea75(%rip), %rcx      # 0x250a0
movq %rbp, %rsi
callq *0x8(%rcx,%rax)
movl %eax, 0x6c(%r14)
movq %rbp, 0x18(%rsp)
cmpl $0x1, %r13d
je 0x166a0
movq %r13, %rax
cmpl $0x3, %eax
movl $0x2, %r12d
cmovll %r12d, %eax
negl %eax
movq %rax, %rbx
leaq 0x20(%rsp), %r15
leaq 0x18(%rsp), %r13
movl %r12d, %edi
callq 0x192b4
movq %rax, 0x20(%rsp)
testq %rax, %rax
je 0x1668d
movl 0x18(%rax), %ecx
movl %ecx, 0x28(%rsp)
movl 0x1c(%rax), %eax
movl %eax, 0x2c(%rsp)
movq %r15, %rdi
movq %r13, %rsi
xorl %edx, %edx
callq 0xeacd
leal (%rbx,%r12), %eax
incl %eax
movl %r12d, %ecx
incl %ecx
movl %ecx, %r12d
cmpl $0x1, %eax
jne 0x16660
movq %rbp, %rdi
callq 0x81c0
movq 0x10(%rsp), %rdi
callq 0x81c0
movb $0x0, 0x2a8(%r14)
jmp 0x16736
movl $0x2, %ebp
leaq 0x20(%rsp), %r14
leaq 0x4(%rsp), %r15
movq %rsp, %r12
movl %ebp, %edi
callq 0x192b4
movq %rax, 0x20(%rsp)
testq %rax, %rax
je 0x1670c
movl 0x18(%rax), %ecx
movl %ecx, 0x28(%rsp)
movl 0x1c(%rax), %eax
movl %eax, 0x2c(%rsp)
movq %r14, %rdi
movq %r15, %rsi
movq %r12, %rdx
callq 0xe3b2
leaq 0xf05e(%rip), %rax      # 0x25760
cmpl $0x0, 0x18(%rax)
jne 0x16581
cmpl %r13d, %ebp
jge 0x16581
incl %ebp
jmp 0x166ce
movq 0xb8(%r15), %rsi
addq $-0x4, %rsi
movl $0x1, %edi
callq 0xd1a9
movb $0x0, 0x2a8(%r15)
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl $0x2, %ebp
leaq 0x20(%rsp), %r12
leaq 0x18(%rsp), %r14
leaq 0x50(%rsp), %r15
movl %ebp, %edi
callq 0x192b4
movq %rax, 0x20(%rsp)
testq %rax, %rax
je 0x16797
movl 0x18(%rax), %ecx
movl %ecx, 0x28(%rsp)
movl 0x1c(%rax), %eax
movl %eax, 0x2c(%rsp)
movq %r12, %rdi
movq %r14, %rsi
movq %r15, %rdx
callq 0xe3ed
leaq 0xefd3(%rip), %rax      # 0x25760
cmpl $0x0, 0x18(%rax)
jne 0x165f5
cmpl %r13d, %ebp
jge 0x165f5
incl %ebp
jmp 0x16759