// File: /workspace/github_c_makefile_star2_O3/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, %r13d
movq %rsi, %r14
movq %rdi, %rbp
movq 0x280(%rsi), %rax
movq %rax, 0x18(%rsp)
movq (%rdi), %r15
leaq 0x30(%rsp), %rbx
movq %rbx, %rdi
xorl %esi, %esi
callq 0x45a0
movq 0xc8(%r15), %rax
testq %rax, %rax
je 0x10319
movl 0x50(%rax), %ecx
incl %ecx
jmp 0x1031e
movl $0x1, %ecx
movl %ecx, 0x80(%rsp)
movl %r13d, 0x84(%rsp)
movq %r12, 0x88(%rsp)
movq 0xc0(%r15), %rcx
movq %rcx, 0x90(%rsp)
movq %rax, 0x98(%rsp)
movq %rbx, 0xc0(%r15)
movq %r15, 0x10(%rsp)
movq %rbx, 0xc8(%r15)
movq %rbp, 0x20(%rsp)
movq 0x10(%rbp), %rbp
testq %rbp, %rbp
movq %r12, 0x8(%rsp)
je 0x103d1
leaq 0x8(%r12), %r15
leal -0x1(%r13), %r12d
cmpq $0x0, (%rbp)
jne 0x1039d
leaq 0x10(%rbp), %rbx
movq %rbx, %rdi
leaq 0x48a0(%rip), %rsi      # 0x14c30
callq 0x4320
testl %eax, %eax
je 0x10448
cmpl $0x2, %r13d
jl 0x103a8
movq (%r15), %rdx
jmp 0x103b1
movq 0x8(%rbp), %rdx
testq %rdx, %rdx
je 0x10403
leaq 0x10(%rbp), %rsi
movq %r14, %rdi
xorl %ecx, %ecx
callq 0x4460
movq (%rbp), %rbp
addq $0x8, %r15
movl %r12d, %r13d
testq %rbp, %rbp
jne 0x10377
jmp 0x103d4
movl %r13d, %r12d
cmpl $0x2, %r12d
jl 0x1048b
movq 0x8(%rsp), %rax
movq (%rax), %rdx
leaq 0x5c33(%rip), %rsi      # 0x16020
leaq 0x5c35(%rip), %rcx      # 0x16029
movq %r14, %rdi
xorl %r8d, %r8d
xorl %eax, %eax
callq 0x4510
jmp 0x10439
addq $0x10, %rbp
movq 0x8(%rsp), %rax
movq (%rax), %r8
movq $0x0, (%rsp)
leaq 0x5bdc(%rip), %rsi      # 0x15ffa
leaq 0x5bf4(%rip), %rcx      # 0x16019
leaq 0x3e83(%rip), %r9       # 0x142af
movq %r14, %rdi
movq %rbp, %rdx
xorl %eax, %eax
callq 0x4510
movl $0x1, %ebx
movq 0x10(%rsp), %r15
jmp 0x10512
xorl %eax, %eax
testl %r12d, %r12d
cmovlel %eax, %r12d
movq %r14, %rdi
movl %r12d, %esi
movq %r15, %rdx
callq 0x4520
movq %rax, %r15
movq %r14, %rdi
movq %rbx, %rsi
movq %rax, %rdx
xorl %ecx, %ecx
callq 0x4460
leaq 0x5ae4(%rip), %rdx      # 0x15f5d
movq 0x18(%rsp), %rdi
movq %r15, %rsi
movl $0x1dc, %ecx            # imm = 0x1DC
callq 0x4280
movq 0x20(%rsp), %rax
movq 0x8(%rax), %rdx
xorl %ebx, %ebx
leaq 0x28(%rsp), %r8
movq %r14, %rdi
xorl %esi, %esi
xorl %ecx, %ecx
callq 0x45c0
leal -0x1(%rax), %ecx
cmpl $0x3, %ecx
movq 0x10(%rsp), %r15
movq 0x8(%rsp), %rdx
ja 0x10510
leaq 0x5a7c(%rip), %rax      # 0x15f3c
movslq (%rax,%rcx,4), %rcx
addq %rax, %rcx
jmpq *%rcx
movq (%rdx), %rdx
movl 0x10(%r15), %ecx
leaq 0x5b6c(%rip), %rsi      # 0x16043
leaq 0xa0(%rsp), %rbx
movq %rbx, %rdi
xorl %eax, %eax
callq 0x45e0
movq %r14, %rdi
movq %rbx, %rsi
callq 0x4410
jmp 0x10509
leaq 0x3db4(%rip), %rax      # 0x142b1
jmp 0x10506
leaq 0x3dcd(%rip), %rax      # 0x142d3
movq %rax, (%r15)
movl $0x1, %ebx
jmp 0x10512
movl %eax, %ebx
leaq 0x30(%rsp), %rsi
movups 0x60(%rsi), %xmm0
movups %xmm0, 0xc0(%r15)
movq %r15, %rdi
callq 0x4350
movl %ebx, %eax
addq $0x108, %rsp            # imm = 0x108
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq