// File: /workspace/github_c_makefile_star2_O3/haxlang[P]hax/haxVar.c
// Function: Hax_UntraceVar2
void
Hax_UntraceVar2(
    Hax_Interp *interp,		/* Interpreter containing traced variable. */
    char *part1,		/* Name of variable or array. */
    char *part2,		/* Name of element within array;  NULL means
				 * trace applies to scalar variable or array
				 * as-a-whole. */
    int flags,			/* OR-ed collection of bits describing
				 * current trace, including any of
				 * HAX_TRACE_READS, HAX_TRACE_WRITES,
				 * HAX_TRACE_UNSETS, and HAX_GLOBAL_ONLY. */
    Hax_VarTraceProc *proc,	/* Procedure assocated with trace. */
    ClientData clientData	/* Arbitrary argument to pass to proc. */)
{
    VarTrace *tracePtr;
    VarTrace *prevPtr;
    Var *varPtr;
    Interp *iPtr = (Interp *) interp;
    Hax_Memoryp *memoryp = iPtr->memoryp;
    Hax_HashEntry *hPtr;
    ActiveVarTrace *activePtr;

    /*
     * First, lookup the variable.
     */

    if ((flags & HAX_GLOBAL_ONLY) || (iPtr->varFramePtr == NULL)) {
	hPtr = Hax_FindHashEntry(&iPtr->globalTable, part1);
    } else {
	hPtr = Hax_FindHashEntry(&iPtr->varFramePtr->varTable, part1);
    }
    if (hPtr == NULL) {
	return;
    }
    varPtr = (Var *) Hax_GetHashValue(hPtr);
    if (varPtr->flags & VAR_UPVAR) {
	hPtr = varPtr->value.upvarPtr;
	varPtr = (Var *) Hax_GetHashValue(hPtr);
    }
    if (part2 != NULL) {
	if (!(varPtr->flags & VAR_ARRAY)) {
	    return;
	}
	hPtr = Hax_FindHashEntry(varPtr->value.tablePtr, part2);
	if (hPtr == NULL) {
	    return;
	}
	varPtr = (Var *) Hax_GetHashValue(hPtr);
    }

    flags &= (HAX_TRACE_READS | HAX_TRACE_WRITES | HAX_TRACE_UNSETS);
    for (tracePtr = varPtr->tracePtr, prevPtr = NULL; ;
	    prevPtr = tracePtr, tracePtr = tracePtr->nextPtr) {
	if (tracePtr == NULL) {
	    return;
	}
	if ((tracePtr->traceProc == proc) && (tracePtr->flags == flags)
		&& (tracePtr->clientData == clientData)) {
	    break;
	}
    }

    /*
     * The code below makes it possible to delete traces while traces
     * are active:  it makes sure that the deleted trace won't be
     * processed by CallTraces.
     */

    for (activePtr = iPtr->activeTracePtr; activePtr != NULL;
	    activePtr = activePtr->nextPtr) {
	if (activePtr->nextTracePtr == tracePtr) {
	    activePtr->nextTracePtr = tracePtr->nextPtr;
	}
    }
    if (prevPtr == NULL) {
	varPtr->tracePtr = tracePtr->nextPtr;
    } else {
	prevPtr->nextPtr = tracePtr->nextPtr;
    }
    ckfree(memoryp, (char *) tracePtr);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %r9, %r14
movq %r8, %r15
movl %ecx, %ebp
movq %rdx, %r13
movq %rdi, %r12
testb $0x1, %bpl
jne 0x12a74
movq 0xc8(%r12), %rdi
testq %rdi, %rdi
je 0x12a74
leaq 0x40(%rdi), %rax
jmp 0x12a81
leaq 0x68(%r12), %rdi
leaq 0xa8(%r12), %rax
movq 0x280(%r12), %rbx
callq *(%rax)
testq %rax, %rax
je 0x12af1
movq 0x18(%rax), %rax
testb $0x2, 0x20(%rax)
je 0x12aa2
movq 0x28(%rax), %rax
movq 0x18(%rax), %rax
testq %r13, %r13
je 0x12ac0
testb $0x1, 0x20(%rax)
je 0x12af1
movq 0x28(%rax), %rdi
movq %r13, %rsi
callq *0x40(%rdi)
testq %rax, %rax
je 0x12af1
movq 0x18(%rax), %rax
movq 0x10(%rax), %rdx
testq %rdx, %rdx
je 0x12af1
andl $0x70, %ebp
addq $0x10, %rax
xorl %esi, %esi
movq %rsi, %rcx
movq %rdx, %rsi
cmpq %r15, (%rdx)
jne 0x12ae8
cmpl %ebp, 0x10(%rsi)
jne 0x12ae8
cmpq %r14, 0x8(%rsi)
je 0x12b00
movq 0x18(%rsi), %rdx
testq %rdx, %rdx
jne 0x12ad2
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0xd0(%r12), %rdx
testq %rdx, %rdx
je 0x12b20
cmpq %rsi, 0x8(%rdx)
jne 0x12b1b
movq 0x18(%rsi), %rdi
movq %rdi, 0x8(%rdx)
movq (%rdx), %rdx
jmp 0x12b08
leaq 0x18(%rcx), %rdx
testq %rcx, %rcx
movq 0x18(%rsi), %rcx
cmoveq %rax, %rdx
movq %rcx, (%rdx)
leaq 0x368a(%rip), %rdx      # 0x161c3
movq %rbx, %rdi
movl $0x43c, %ecx            # imm = 0x43C
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x4280