// File: /workspace/github_c_makefile_star2_O1/haxlang[P]hax/haxProc.c
// Function: InterpProc
static int
InterpProc(
    ClientData clientData,	/* Record describing procedure to be
				 * interpreted. */
    Hax_Interp *interp,		/* Interpreter in which procedure was
				 * invoked. */
    int argc,			/* Count of number of arguments to this
				 * procedure. */
    char **argv			/* Argument values. */)
{
    Proc *procPtr = (Proc *) clientData;
    Arg *argPtr;
    Interp *iPtr = (Interp *) interp;
    Hax_Memoryp *memoryp = iPtr->memoryp;
    char **args;
    CallFrame frame;
    char *value, *end;
    int result;

    /*
     * Set up a call frame for the new procedure invocation.
     */

    iPtr = procPtr->iPtr;
    Hax_InitHashTable(&frame.varTable, HAX_STRING_KEYS);
    if (iPtr->varFramePtr != NULL) {
	frame.level = iPtr->varFramePtr->level + 1;
    } else {
	frame.level = 1;
    }
    frame.argc = argc;
    frame.argv = argv;
    frame.callerPtr = iPtr->framePtr;
    frame.callerVarPtr = iPtr->varFramePtr;
    iPtr->framePtr = &frame;
    iPtr->varFramePtr = &frame;

    /*
     * Match the actual arguments against the procedure's formal
     * parameters to compute local variables.
     */

    for (argPtr = procPtr->argPtr, args = argv+1, argc -= 1;
	    argPtr != NULL;
	    argPtr = argPtr->nextPtr, args++, argc--) {

	/*
	 * Handle the special case of the last formal being "args".  When
	 * it occurs, assign it a list consisting of all the remaining
	 * actual arguments.
	 */

	if ((argPtr->nextPtr == NULL)
		&& (strcmp(argPtr->name, "args") == 0)) {
	    if (argc < 0) {
		argc = 0;
	    }
	    value = Hax_Merge(interp, argc, args);
	    Hax_SetVar(interp, argPtr->name, value, 0);
	    ckfree(memoryp, value);
	    argc = 0;
	    break;
	} else if (argc > 0) {
	    value = *args;
	} else if (argPtr->defValue != NULL) {
	    value = argPtr->defValue;
	} else {
	    Hax_AppendResult(interp, "no value given for parameter \"",
		    argPtr->name, "\" to \"", argv[0], "\"",
		    (char *) NULL);
	    result = HAX_ERROR;
	    goto procDone;
	}
	Hax_SetVar(interp, argPtr->name, value, 0);
    }
    if (argc > 0) {
	Hax_AppendResult(interp, "called \"", argv[0],
		"\" with too many arguments", (char *) NULL);
	result = HAX_ERROR;
	goto procDone;
    }

    /*
     * Invoke the commands in the procedure's body.
     */

    result = Hax_Eval(interp, NULL, procPtr->command, 0, &end);
    if (result == HAX_RETURN) {
	result = HAX_OK;
    } else if (result == HAX_ERROR) {
	char msg[100];

	/*
	 * Record information telling where the error occurred.
	 */

	sprintf(msg, "\n    (procedure \"%.50s\" line %d)", argv[0],
		iPtr->errorLine);
	Hax_AddErrorInfo(interp, msg);
    } else if (result == HAX_BREAK) {
	iPtr->result = (char *) "invoked \"break\" outside of a loop";
	result = HAX_ERROR;
    } else if (result == HAX_CONTINUE) {
	iPtr->result = (char *) "invoked \"continue\" outside of a loop";
	result = HAX_ERROR;
    }

    /*
     * Delete the call frame for this procedure invocation (it's
     * important to remove the call frame from the interpreter
     * before deleting it, so that traces invoked during the
     * deletion don't see the partially-deleted frame).
     */

    procDone:
    iPtr->framePtr = frame.callerPtr;
    iPtr->varFramePtr = frame.callerVarPtr;
    HaxDeleteVars(iPtr, &frame.varTable);
    return result;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x108, %rsp            # imm = 0x108
movq %rcx, %r12
movl %edx, %ebp
movq %rsi, %r14
movq %rdi, %r13
movq 0x280(%rsi), %rax
movq %rax, 0x18(%rsp)
movq (%rdi), %rbx
leaq 0x30(%rsp), %r15
movq %r15, %rdi
xorl %esi, %esi
callq 0x4590
movq 0xc8(%rbx), %rax
testq %rax, %rax
je 0x109e1
movl 0x50(%rax), %ecx
incl %ecx
jmp 0x109e6
movl $0x1, %ecx
movl %ecx, 0x80(%rsp)
movl %ebp, 0x84(%rsp)
movq %r12, 0x88(%rsp)
movq 0xc0(%rbx), %rcx
movq %rcx, 0x90(%rsp)
movq %rax, 0x98(%rsp)
movq %r15, 0xc0(%rbx)
movq %r15, 0xc8(%rbx)
movq %r13, 0x20(%rsp)
movq 0x10(%r13), %r13
testq %r13, %r13
movq %r12, 0x10(%rsp)
je 0x10a8f
leaq 0x8(%r12), %r15
cmpq $0x0, (%r13)
jne 0x10a5b
leaq 0x10(%r13), %r12
movq %r12, %rdi
leaq 0x5386(%rip), %rsi      # 0x15dd4
callq 0x4310
testl %eax, %eax
je 0x10b5f
cmpl $0x2, %ebp
jl 0x10a65
movq (%r15), %rdx
jmp 0x10a72
movq 0x8(%r13), %rdx
testq %rdx, %rdx
je 0x10b27
leaq 0x10(%r13), %rsi
movq %r14, %rdi
xorl %ecx, %ecx
callq 0x4450
movq (%r13), %r13
decl %ebp
addq $0x8, %r15
testq %r13, %r13
jne 0x10a39
decl %ebp
testl %ebp, %ebp
movq 0x10(%rsp), %r12
movq 0x20(%rsp), %rax
jle 0x10ac3
movq (%r12), %rdx
leaq 0x6872(%rip), %rsi      # 0x1731c
leaq 0x6874(%rip), %rcx      # 0x17325
movq %r14, %rdi
xorl %r8d, %r8d
xorl %eax, %eax
callq 0x4500
jmp 0x10bbb
movq 0x8(%rax), %rdx
xorl %r15d, %r15d
leaq 0x28(%rsp), %r8
movq %r14, %rdi
xorl %esi, %esi
xorl %ecx, %ecx
callq 0x45b0
leal -0x1(%rax), %ecx
cmpl $0x3, %ecx
ja 0x10bf9
leaq 0x674a(%rip), %rax      # 0x17238
movslq (%rax,%rcx,4), %rcx
addq %rax, %rcx
jmpq *%rcx
movq (%r12), %rdx
movl 0x10(%rbx), %ecx
leaq 0x683a(%rip), %rsi      # 0x1733f
leaq 0xa0(%rsp), %r15
movq %r15, %rdi
xorl %eax, %eax
callq 0x45d0
movq %r14, %rdi
movq %r15, %rsi
callq 0x4400
jmp 0x10bbb
addq $0x10, %r13
movq 0x10(%rsp), %rax
movq (%rax), %r8
movq $0x0, (%rsp)
leaq 0x67b4(%rip), %rsi      # 0x172f6
leaq 0x67cc(%rip), %rcx      # 0x17315
leaq 0x475f(%rip), %r9       # 0x152af
movq %r14, %rdi
movq %r13, %rdx
xorl %eax, %eax
callq 0x4500
jmp 0x10bbb
decl %ebp
xorl %eax, %eax
testl %ebp, %ebp
cmovlel %eax, %ebp
movq %r14, %rdi
movl %ebp, %esi
movq %r15, %rdx
callq 0x4510
movq %rax, %r15
movq %r14, %rdi
movq %r12, %rsi
movq %rax, %rdx
xorl %ecx, %ecx
callq 0x4450
leaq 0x66ca(%rip), %rdx      # 0x17259
movq 0x18(%rsp), %rdi
movq %r15, %rsi
movl $0x1dc, %ecx            # imm = 0x1DC
callq 0x4280
xorl %ebp, %ebp
jmp 0x10a91
leaq 0x4702(%rip), %rax      # 0x152b1
jmp 0x10bb8
leaq 0x471b(%rip), %rax      # 0x152d3
movq %rax, (%rbx)
movl $0x1, %r15d
leaq 0x30(%rsp), %rsi
movq 0x60(%rsi), %rax
movq %rax, 0xc0(%rbx)
movq 0x68(%rsi), %rax
movq %rax, 0xc8(%rbx)
movq %rbx, %rdi
callq 0x4340
movl %r15d, %eax
addq $0x108, %rsp            # imm = 0x108
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl %eax, %r15d
jmp 0x10bc1