// File: /workspace/github_c_makefile_star2_O2/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), %r15
leaq 0x30(%rsp), %rbx
movq %rbx, %rdi
xorl %esi, %esi
callq 0x45b0
movq 0xc8(%r15), %rax
testq %rax, %rax
je 0xf5af
movl 0x50(%rax), %ecx
incl %ecx
jmp 0xf5b2
pushq $0x1
popq %rcx
movl %ecx, 0x80(%rsp)
movl %ebp, 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 %r13, 0x20(%rsp)
addq $0x10, %r13
movq %r12, 0x8(%rsp)
leaq 0x8(%r12), %r15
leaq 0x4624(%rip), %r12      # 0x13c30
movq (%r13), %r13
testq %r13, %r13
je 0xf65c
cmpq $0x0, (%r13)
jne 0xf633
leaq 0x10(%r13), %rbx
movq %rbx, %rdi
movq %r12, %rsi
callq 0x4330
testl %eax, %eax
je 0xf6cb
cmpl $0x2, %ebp
jl 0xf63d
movq (%r15), %rdx
jmp 0xf646
movq 0x8(%r13), %rdx
testq %rdx, %rdx
je 0xf68a
leaq 0x10(%r13), %rsi
movq %r14, %rdi
xorl %ecx, %ecx
callq 0x4470
addq $0x8, %r15
decl %ebp
jmp 0xf60c
cmpl $0x2, %ebp
jl 0xf70d
movq 0x8(%rsp), %rax
movq (%rax), %rdx
leaq 0x597c(%rip), %rsi      # 0x14ff0
leaq 0x597e(%rip), %rcx      # 0x14ff9
movq %r14, %rdi
xorl %r8d, %r8d
xorl %eax, %eax
callq 0x4520
jmp 0xf6bd
addq $0x10, %r13
movq 0x8(%rsp), %rax
movq (%rax), %r8
andq $0x0, (%rsp)
leaq 0x5928(%rip), %rsi      # 0x14fca
leaq 0x5940(%rip), %rcx      # 0x14fe9
leaq 0x3bff(%rip), %r9       # 0x132af
movq %r14, %rdi
movq %r13, %rdx
xorl %eax, %eax
callq 0x4520
pushq $0x1
popq %r15
movq 0x10(%rsp), %r12
jmp 0xf797
decl %ebp
xorl %eax, %eax
testl %ebp, %ebp
cmovlel %eax, %ebp
movq %r14, %rdi
movl %ebp, %esi
movq %r15, %rdx
callq 0x4530
movq %rax, %r15
movq %r14, %rdi
movq %rbx, %rsi
movq %rax, %rdx
xorl %ecx, %ecx
callq 0x4470
leaq 0x5832(%rip), %rdx      # 0x14f2d
movq 0x18(%rsp), %rdi
movq %r15, %rsi
movl $0x1dc, %ecx            # imm = 0x1DC
callq 0x4280
movq 0x20(%rsp), %rax
movq 0x8(%rax), %rdx
xorl %r15d, %r15d
leaq 0x28(%rsp), %r8
movq %r14, %rdi
xorl %esi, %esi
xorl %ecx, %ecx
callq 0x45d0
leal -0x1(%rax), %ecx
cmpl $0x3, %ecx
movq 0x10(%rsp), %r12
ja 0xf794
leaq 0x57ce(%rip), %rax      # 0x14f0c
movslq (%rax,%rcx,4), %rcx
addq %rax, %rcx
jmpq *%rcx
movq 0x8(%rsp), %rax
movq (%rax), %rdx
movl 0x10(%r12), %ecx
leaq 0x58b8(%rip), %rsi      # 0x15013
leaq 0xa0(%rsp), %rbx
movq %rbx, %rdi
xorl %eax, %eax
callq 0x45f0
movq %r14, %rdi
movq %rbx, %rsi
callq 0x4420
jmp 0xf78e
leaq 0x3b30(%rip), %rax      # 0x132b1
jmp 0xf78a
leaq 0x3b49(%rip), %rax      # 0x132d3
movq %rax, (%r12)
pushq $0x1
popq %r15
jmp 0xf797
movl %eax, %r15d
leaq 0x30(%rsp), %rsi
movups 0x60(%rsi), %xmm0
movups %xmm0, 0xc0(%r12)
movq %r12, %rdi
callq 0x4360
movl %r15d, %eax
addq $0x108, %rsp            # imm = 0x108
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq