// File: /workspace/github_c_makefile_star2_O0/haxlang[P]hax/haxVar.c
// Function: Hax_UnsetVar2
int
Hax_UnsetVar2(
    Hax_Interp *interp,		/* Command interpreter in which varName is
				 * to be looked up. */
    char *part1,		/* Name of variable or array. */
    char *part2,		/* Name of element within array or NULL. */
    int flags			/* OR-ed combination of any of
				 * HAX_GLOBAL_ONLY or HAX_LEAVE_ERR_MSG. */)
{
    Hax_HashEntry *hPtr, dummyEntry;
    Var *varPtr, dummyVar;
    Interp *iPtr = (Interp *) interp;
    Hax_Memoryp *memoryp = iPtr->memoryp;
    Var *arrayPtr = NULL;

    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) {
	if (flags & HAX_LEAVE_ERR_MSG) {
	    VarErrMsg(interp, part1, part2, (char *) "unset",
		(char *) noSuchVar);
	}
	return -1;
    }
    varPtr = (Var *) Hax_GetHashValue(hPtr);

    /*
     * For global variables referenced in procedures, leave the procedure's
     * reference variable in place, but unset the global variable.  Can't
     * decrement the actual variable's use count, since we didn't delete
     * the reference variable.
     */

    if (varPtr->flags & VAR_UPVAR) {
	hPtr = varPtr->value.upvarPtr;
	varPtr = (Var *) Hax_GetHashValue(hPtr);
    }

    /*
     * If the variable being deleted is an element of an array, then
     * remember trace procedures on the overall array and find the
     * element to delete.
     */

    if (part2 != NULL) {
	if (!(varPtr->flags & VAR_ARRAY)) {
	    if (flags & HAX_LEAVE_ERR_MSG) {
		VarErrMsg(interp, part1, part2, (char *) "unset",
		    (char *) needArray);
	    }
	    return -1;
	}
	if (varPtr->searchPtr != NULL) {
	    DeleteSearches(interp, varPtr);
	}
	arrayPtr = varPtr;
	hPtr = Hax_FindHashEntry(varPtr->value.tablePtr, part2);
	if (hPtr == NULL) {
	    if (flags & HAX_LEAVE_ERR_MSG) {
		VarErrMsg(interp, part1, part2, (char *) "unset",
		    (char *) noSuchElement);
	    }
	    return -1;
	}
	varPtr = (Var *) Hax_GetHashValue(hPtr);
    }

    /*
     * If there is a trace active on this variable or if the variable
     * is already being deleted then don't delete the variable:  it
     * isn't safe, since there are procedures higher up on the stack
     * that will use pointers to the variable.  Also don't delete an
     * array if there are traces active on any of its elements.
     */

    if (varPtr->flags &
	    (VAR_TRACE_ACTIVE|VAR_ELEMENT_ACTIVE)) {
	if (flags & HAX_LEAVE_ERR_MSG) {
	    VarErrMsg(interp, part1, part2, (char *) "unset",
		(char *) traceActive);
	}
	return -1;
    }

    /*
     * The code below is tricky, because of the possibility that
     * a trace procedure might try to access a variable being
     * deleted.  To handle this situation gracefully, copy the
     * contents of the variable and its hash table entry to
     * dummy variables, then clean up the actual variable so that
     * it's been completely deleted before the traces are called.
     * Then call the traces, and finally clean up the variable's
     * storage using the dummy copies.
     */

    dummyVar = *varPtr;
    Hax_SetHashValue(&dummyEntry, &dummyVar);
    if (varPtr->upvarUses == 0) {
	Hax_DeleteHashEntry(interp, hPtr);
	ckfree(memoryp, (char *) varPtr);
    } else {
	varPtr->flags = VAR_UNDEFINED;
	varPtr->tracePtr = NULL;
    }

    /*
     * Call trace procedures for the variable being deleted and delete
     * its traces.
     */

    if ((dummyVar.tracePtr != NULL)
	    || ((arrayPtr != NULL) && (arrayPtr->tracePtr != NULL))) {
	(void) CallTraces(iPtr, arrayPtr, &dummyEntry, part1, part2,
		(flags & HAX_GLOBAL_ONLY) | HAX_TRACE_UNSETS);
	while (dummyVar.tracePtr != NULL) {
	    VarTrace *tracePtr = dummyVar.tracePtr;
	    dummyVar.tracePtr = tracePtr->nextPtr;
	    ckfree(memoryp, (char *) tracePtr);
	}
    }

    /*
     * If the variable is an array, delete all of its elements.  This
     * must be done after calling the traces on the array, above (that's
     * the way traces are defined).
     */

    if (dummyVar.flags & VAR_ARRAY) {
	DeleteArray(iPtr, part1, &dummyVar,
	    (flags & HAX_GLOBAL_ONLY) | HAX_TRACE_UNSETS);
    }
    if (dummyVar.flags & VAR_UNDEFINED) {
	if (flags & HAX_LEAVE_ERR_MSG) {
	    VarErrMsg(interp, part1, part2, (char *) "unset",
		(part2 == NULL) ? (char *) noSuchVar : (char *) noSuchElement);
	}
	return -1;
    }
    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xd0, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movl %ecx, -0x24(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x98(%rbp)
movq -0x98(%rbp), %rax
movq 0x280(%rax), %rax
movq %rax, -0xa0(%rbp)
movq $0x0, -0xa8(%rbp)
movl -0x24(%rbp), %eax
andl $0x1, %eax
cmpl $0x0, %eax
jne 0x1a461
movq -0x98(%rbp), %rax
cmpq $0x0, 0xc8(%rax)
jne 0x1a486
movq -0x98(%rbp), %rax
movq 0xa8(%rax), %rax
movq -0x98(%rbp), %rdi
addq $0x68, %rdi
movq -0x18(%rbp), %rsi
callq *%rax
movq %rax, -0x30(%rbp)
jmp 0x1a4b0
movq -0x98(%rbp), %rax
movq 0xc8(%rax), %rax
movq 0x40(%rax), %rax
movq -0x98(%rbp), %rcx
movq 0xc8(%rcx), %rdi
movq -0x18(%rbp), %rsi
callq *%rax
movq %rax, -0x30(%rbp)
cmpq $0x0, -0x30(%rbp)
jne 0x1a4ef
movl -0x24(%rbp), %eax
andl $0x200, %eax            # imm = 0x200
cmpl $0x0, %eax
je 0x1a4e3
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x20(%rbp), %rdx
movq 0x9389(%rip), %r8       # 0x23860
leaq 0x2f11(%rip), %rcx      # 0x1d3ef
callq 0x19900
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x1a806
movq -0x30(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x60(%rbp)
movq -0x60(%rbp), %rax
movl 0x20(%rax), %eax
andl $0x2, %eax
cmpl $0x0, %eax
je 0x1a522
movq -0x60(%rbp), %rax
movq 0x28(%rax), %rax
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x60(%rbp)
cmpq $0x0, -0x20(%rbp)
je 0x1a600
movq -0x60(%rbp), %rax
movl 0x20(%rax), %eax
andl $0x1, %eax
cmpl $0x0, %eax
jne 0x1a574
movl -0x24(%rbp), %eax
andl $0x200, %eax            # imm = 0x200
cmpl $0x0, %eax
je 0x1a568
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x20(%rbp), %rdx
movq 0x930c(%rip), %r8       # 0x23868
leaq 0x2e8c(%rip), %rcx      # 0x1d3ef
callq 0x19900
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x1a806
movq -0x60(%rbp), %rax
cmpq $0x0, 0x18(%rax)
je 0x1a58c
movq -0x10(%rbp), %rdi
movq -0x60(%rbp), %rsi
callq 0x1a2a0
movq -0x60(%rbp), %rax
movq %rax, -0xa8(%rbp)
movq -0x60(%rbp), %rax
movq 0x28(%rax), %rax
movq 0x40(%rax), %rax
movq -0x60(%rbp), %rcx
movq 0x28(%rcx), %rdi
movq -0x20(%rbp), %rsi
callq *%rax
movq %rax, -0x30(%rbp)
cmpq $0x0, -0x30(%rbp)
jne 0x1a5f4
movl -0x24(%rbp), %eax
andl $0x200, %eax            # imm = 0x200
cmpl $0x0, %eax
je 0x1a5e8
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x20(%rbp), %rdx
movq 0x9294(%rip), %r8       # 0x23870
leaq 0x2e0c(%rip), %rcx      # 0x1d3ef
callq 0x19900
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x1a806
movq -0x30(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x60(%rbp)
movq -0x60(%rbp), %rax
movl 0x20(%rax), %eax
andl $0x30, %eax
cmpl $0x0, %eax
je 0x1a647
movl -0x24(%rbp), %eax
andl $0x200, %eax            # imm = 0x200
cmpl $0x0, %eax
je 0x1a63b
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x20(%rbp), %rdx
movq 0x9251(%rip), %r8       # 0x23880
leaq 0x2db9(%rip), %rcx      # 0x1d3ef
callq 0x19900
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x1a806
movq -0x60(%rbp), %rsi
leaq -0x90(%rbp), %rdi
movl $0x30, %edx
callq 0x4390
leaq -0x90(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x60(%rbp), %rax
cmpl $0x0, 0x8(%rax)
jne 0x1a69c
movq -0x10(%rbp), %rdi
movq -0x30(%rbp), %rsi
callq 0x42d0
movq -0xa0(%rbp), %rdi
movq -0x60(%rbp), %rsi
leaq 0x521f(%rip), %rdx      # 0x1f8af
movl $0x2bb, %ecx            # imm = 0x2BB
callq 0x4260
jmp 0x1a6b3
movq -0x60(%rbp), %rax
movl $0x4, 0x20(%rax)
movq -0x60(%rbp), %rax
movq $0x0, 0x10(%rax)
cmpq $0x0, -0x80(%rbp)
jne 0x1a6d2
cmpq $0x0, -0xa8(%rbp)
je 0x1a741
movq -0xa8(%rbp), %rax
cmpq $0x0, 0x10(%rax)
je 0x1a741
movq -0x98(%rbp), %rdi
movq -0xa8(%rbp), %rsi
movq -0x18(%rbp), %rcx
movq -0x20(%rbp), %r8
movl -0x24(%rbp), %r9d
andl $0x1, %r9d
orl $0x40, %r9d
leaq -0x58(%rbp), %rdx
callq 0x199a0
cmpq $0x0, -0x80(%rbp)
je 0x1a73f
movq -0x80(%rbp), %rax
movq %rax, -0xb0(%rbp)
movq -0xb0(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x80(%rbp)
movq -0xa0(%rbp), %rdi
movq -0xb0(%rbp), %rsi
leaq 0x517c(%rip), %rdx      # 0x1f8af
movl $0x2cd, %ecx            # imm = 0x2CD
callq 0x4260
jmp 0x1a6fd
jmp 0x1a741
movl -0x70(%rbp), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x1a76c
movq -0x98(%rbp), %rdi
movq -0x18(%rbp), %rsi
movl -0x24(%rbp), %ecx
andl $0x1, %ecx
orl $0x40, %ecx
leaq -0x90(%rbp), %rdx
callq 0x1a820
movl -0x70(%rbp), %eax
andl $0x4, %eax
cmpl $0x0, %eax
je 0x1a7ff
movl -0x24(%rbp), %eax
andl $0x200, %eax            # imm = 0x200
cmpl $0x0, %eax
je 0x1a7f6
movq -0x10(%rbp), %rax
movq %rax, -0xc8(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0xc0(%rbp)
movq -0x20(%rbp), %rax
movq %rax, -0xb8(%rbp)
cmpq $0x0, -0x20(%rbp)
jne 0x1a7c0
movq 0x90a9(%rip), %rax      # 0x23860
movq %rax, -0xd0(%rbp)
jmp 0x1a7ce
movq 0x90a9(%rip), %rax      # 0x23870
movq %rax, -0xd0(%rbp)
movq -0xb8(%rbp), %rdx
movq -0xc0(%rbp), %rsi
movq -0xc8(%rbp), %rdi
movq -0xd0(%rbp), %r8
leaq 0x2bfe(%rip), %rcx      # 0x1d3ef
callq 0x19900
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x1a806
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0xd0, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)