// File: /workspace/github_c_makefile_star2_O0/wahern[P]cqueues/src/thread.c
// Function: ct_enter
static void *ct_enter(void *arg) {
	struct cthread *ct = arg, **ud;
	lua_State *L = NULL;
	int error;

	/*
	 * Hold down deadman switch so ct_join can detect (on some systems)
	 * whether thread was killed or cancelled.
	 */
	hdl_hold(&ct->handle);

	/*
	 * Procedure for bootstrapping into a new Lua VM. Order is important
	 * because arg[0..N] are interned strings from the parent Lua VM.
	 *
	 *  1) Acquire lock.
	 *  -- BEGIN CRITICAL SECTION --
	 *  2) Grab struct cthread reference.
	 *  3) Open new main Lua thread.
	 *  4) Set Lua panic trap.
	 *  5) Load low-level components from memory as we might be
	 *     chroot'd and unable to load them from disk.
	 *  6) Load arg[0] as our Lua start routine.
	 *  7) Push reference to struct cthread.
	 *  8) Push reference to our socket.
	 *  9) Push strings arg[1..N].
	 *  -- END CRITICAL SECTION --
	 * 10) Release lock and signal parent.
	 * 11) Reset Lua panic trap.
	 * 12) Call Lua start routine.
	 *
	 * NOTE: Lua user code perceives this process differently. See
	 * thread.lua.
	 */
	pthread_mutex_lock(&ct->mutex);

	ct->refs++;

	if (!(L = luaL_newstate()))
		goto syerr;

	if ((error = pthread_once(&atpanic.once, &atpanic_once)))
		goto error;

	if ((error = pthread_setspecific(atpanic.key, ct)))
		goto error;

	lua_atpanic(L, &atpanic_trap);

	if ((error = _setjmp(ct->trap)))
		goto error;

	luaL_openlibs(L);
	cqs_openlibs(L);

	if (ct->tmp.arg[0].iscfunction) {
		lua_pushcfunction(L, EXTENSION (lua_CFunction)ct->tmp.arg[0].v.pointer);
	} else {
		luaL_loadbuffer(L, ct->tmp.arg[0].v.string.iov_base, ct->tmp.arg[0].v.string.iov_len, "[thread enter]");
	}

	ud = lua_newuserdata(L, sizeof *ud);
	*ud = NULL;

	luaL_getmetatable(L, CQS_THREAD);
	lua_setmetatable(L, -2);

	ct->refs++;
	*ud = ct;

	lua_pushvalue(L, -1);
	lua_rawsetp(L, LUA_REGISTRYINDEX, CQS_UNIQUE_LIGHTUSERDATA_MASK(&selfindex));

	if ((error = cqs_socket_fdopen(L, ct->tmp.fd[1], NULL)))
		goto error;

	ct->tmp.fd[1] = -1;

	for (struct cthread_arg *arg = &ct->tmp.arg[1]; arg < &ct->tmp.arg[ct->tmp.argc]; arg++) {
		switch (arg->type) {
		case LUA_TNUMBER:
			if (arg->isinteger) {
				lua_pushinteger(L, arg->v.integer);
			} else {
				lua_pushnumber(L, arg->v.number);
			}
			break;
		case LUA_TBOOLEAN:
			lua_pushboolean(L, arg->v.boolean);
			break;
		case LUA_TLIGHTUSERDATA:
			lua_pushlightuserdata(L, arg->v.pointer);
			break;
		case LUA_TSTRING:
			lua_pushlstring(L, arg->v.string.iov_base, arg->v.string.iov_len);
			break;
		case LUA_TFUNCTION:
			if (arg->iscfunction) {
				lua_pushcfunction(L, EXTENSION (lua_CFunction)arg->v.pointer);
			} else {
				luaL_loadbuffer(L, arg->v.string.iov_base, arg->v.string.iov_len, NULL);
			}
			break;
		default:
			lua_pushnil(L);
			break;
		}
	}

	free(ct->tmp.arg);
	ct->tmp.arg = NULL;
	ct->tmp.argc = 0;

	pthread_mutex_unlock(&ct->mutex);
	pthread_cond_signal(&ct->cond);

	if ((error = _setjmp(ct->trap))) {
		ct->error = error;
		goto close;
	}

	ct->status = lua_pcall(L, lua_gettop(L) - 1, 0, 0);

	if (ct->status != LUA_OK && lua_isstring(L, -1)) {
		if (!(ct->msg = strdup(lua_tostring(L, -1)))) {
			ct->error = errno;
		}
	}
close:
	if (L) {
		if (!(error = _setjmp(ct->trap))) {
			lua_close(L);
		} else if (!ct->error) {
			ct->error = error;
		}
	}

	cqs_closefd(&ct->pipe[1]);

	ct_release(ct);

	return 0;
syerr:
	error = errno;
error: /* NOTE: Only critical section errors reach here. */
	ct->error = error;

	pthread_mutex_unlock(&ct->mutex);
	pthread_cond_signal(&ct->cond);

	goto close;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x10(%rbp)
movq $0x0, -0x20(%rbp)
movq -0x10(%rbp), %rdi
addq $0x178, %rdi            # imm = 0x178
callq 0x25640
movq -0x10(%rbp), %rdi
addq $0x20, %rdi
callq 0x10510
movq -0x10(%rbp), %rax
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
callq 0x10500
movq %rax, -0x20(%rbp)
cmpq $0x0, %rax
jne 0x24be8
jmp 0x25030
leaq 0x38d69(%rip), %rdi     # 0x5d958
leaq 0xa9a(%rip), %rsi       # 0x25690
callq 0xfd40
movl %eax, -0x24(%rbp)
cmpl $0x0, %eax
je 0x24c08
jmp 0x2503a
movl 0x38d4e(%rip), %edi     # 0x5d95c
movq -0x10(%rbp), %rsi
callq 0xf290
movl %eax, -0x24(%rbp)
cmpl $0x0, %eax
je 0x24c24
jmp 0x2503a
movq -0x20(%rbp), %rdi
leaq 0xa81(%rip), %rsi       # 0x256b0
callq 0x10b90
movq -0x10(%rbp), %rdi
addq $0xb0, %rdi
callq 0x10480
movl %eax, -0x24(%rbp)
cmpl $0x0, %eax
je 0x24c51
jmp 0x2503a
movq -0x20(%rbp), %rdi
callq 0xf950
movq -0x20(%rbp), %rdi
callq 0x256f0
movq -0x10(%rbp), %rax
movq 0x1b8(%rax), %rax
movb 0x4(%rax), %al
shlb $0x7, %al
sarb $0x7, %al
movsbl %al, %eax
cmpl $0x0, %eax
je 0x24c9b
movq -0x20(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x1b8(%rax), %rax
movq 0x8(%rax), %rsi
xorl %edx, %edx
callq 0x10bf0
jmp 0x24cce
movq -0x20(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x1b8(%rax), %rax
movq 0x8(%rax), %rsi
movq -0x10(%rbp), %rax
movq 0x1b8(%rax), %rax
movq 0x10(%rax), %rdx
leaq 0x24540(%rip), %rcx     # 0x49204
xorl %eax, %eax
movl %eax, %r8d
callq 0xfd70
movq -0x20(%rbp), %rdi
movl $0x8, %esi
callq 0xfbe0
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rax
movq $0x0, (%rax)
movq -0x20(%rbp), %rdi
movl $0xfff0b9d8, %esi       # imm = 0xFFF0B9D8
leaq 0x24499(%rip), %rdx     # 0x49194
callq 0xf200
movq -0x20(%rbp), %rdi
movl $0xfffffffe, %esi       # imm = 0xFFFFFFFE
callq 0x10b10
movq -0x10(%rbp), %rax
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
movq -0x10(%rbp), %rcx
movq -0x18(%rbp), %rax
movq %rcx, (%rax)
movq -0x20(%rbp), %rdi
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
callq 0xfa50
movq -0x20(%rbp), %rdi
movl $0xfff0b9d8, %esi       # imm = 0xFFF0B9D8
leaq 0x2444e(%rip), %rdx     # 0x49190
callq 0xf180
movq -0x20(%rbp), %rdi
movq -0x10(%rbp), %rax
movl 0x1c8(%rax), %esi
xorl %eax, %eax
movl %eax, %edx
callq 0x102c0
movl %eax, -0x24(%rbp)
cmpl $0x0, %eax
je 0x24d6b
jmp 0x2503a
movq -0x10(%rbp), %rax
movl $0xffffffff, 0x1c8(%rax) # imm = 0xFFFFFFFF
movq -0x10(%rbp), %rax
movq 0x1b8(%rax), %rax
addq $0x18, %rax
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
movq -0x10(%rbp), %rcx
movq 0x1b8(%rcx), %rcx
movq -0x10(%rbp), %rdx
movl 0x1c0(%rdx), %edx
imulq $0x18, %rdx, %rdx
addq %rdx, %rcx
cmpq %rcx, %rax
jae 0x24ed0
movq -0x30(%rbp), %rax
movl (%rax), %eax
decl %eax
movl %eax, %ecx
movq %rcx, -0x38(%rbp)
subl $0x5, %eax
ja 0x24eb4
movq -0x38(%rbp), %rax
leaq 0x2438d(%rip), %rcx     # 0x49164
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0x30(%rbp), %rax
movb 0x4(%rax), %al
shlb $0x6, %al
sarb $0x7, %al
movsbl %al, %eax
cmpl $0x0, %eax
je 0x24e08
movq -0x20(%rbp), %rdi
movq -0x30(%rbp), %rax
movq 0x8(%rax), %rsi
callq 0xf9a0
jmp 0x24e1a
movq -0x20(%rbp), %rdi
movq -0x30(%rbp), %rax
movsd 0x8(%rax), %xmm0
callq 0xf300
jmp 0x24ebd
movq -0x20(%rbp), %rdi
movq -0x30(%rbp), %rax
movb 0x8(%rax), %al
andb $0x1, %al
movzbl %al, %esi
callq 0x109d0
jmp 0x24ebd
movq -0x20(%rbp), %rdi
movq -0x30(%rbp), %rax
movq 0x8(%rax), %rsi
callq 0x102a0
jmp 0x24ebd
movq -0x20(%rbp), %rdi
movq -0x30(%rbp), %rax
movq 0x8(%rax), %rsi
movq -0x30(%rbp), %rax
movq 0x10(%rax), %rdx
callq 0xf510
jmp 0x24ebd
movq -0x30(%rbp), %rax
movb 0x4(%rax), %al
shlb $0x7, %al
sarb $0x7, %al
movsbl %al, %eax
cmpl $0x0, %eax
je 0x24e91
movq -0x20(%rbp), %rdi
movq -0x30(%rbp), %rax
movq 0x8(%rax), %rsi
xorl %edx, %edx
callq 0x10bf0
jmp 0x24eb2
movq -0x20(%rbp), %rdi
movq -0x30(%rbp), %rax
movq 0x8(%rax), %rsi
movq -0x30(%rbp), %rax
movq 0x10(%rax), %rdx
xorl %eax, %eax
movl %eax, %r8d
movq %r8, %rcx
callq 0xfd70
jmp 0x24ebd
movq -0x20(%rbp), %rdi
callq 0xfa10
jmp 0x24ebf
movq -0x30(%rbp), %rax
addq $0x18, %rax
movq %rax, -0x30(%rbp)
jmp 0x24d8c
movq -0x10(%rbp), %rax
movq 0x1b8(%rax), %rdi
callq 0x10060
movq -0x10(%rbp), %rax
movq $0x0, 0x1b8(%rax)
movq -0x10(%rbp), %rax
movl $0x0, 0x1c0(%rax)
movq -0x10(%rbp), %rdi
addq $0x20, %rdi
callq 0xfa40
movq -0x10(%rbp), %rdi
addq $0x48, %rdi
callq 0xf040
movq -0x10(%rbp), %rdi
addq $0xb0, %rdi
callq 0x10480
movl %eax, -0x24(%rbp)
cmpl $0x0, %eax
je 0x24f3e
movl -0x24(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x4(%rax)
jmp 0x24fc9
movq -0x20(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x20(%rbp), %rdi
callq 0xf9b0
movq -0x40(%rbp), %rdi
movl %eax, %esi
subl $0x1, %esi
xorl %ecx, %ecx
xorl %eax, %eax
movl %eax, %r9d
movl %ecx, %edx
movq %r9, %r8
callq 0xfa20
movl %eax, %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x8(%rax)
movq -0x10(%rbp), %rax
cmpl $0x0, 0x8(%rax)
je 0x24fc7
movq -0x20(%rbp), %rdi
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
callq 0x108b0
cmpl $0x0, %eax
je 0x24fc7
movq -0x20(%rbp), %rdi
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
xorl %eax, %eax
movl %eax, %edx
callq 0xf130
movq %rax, %rdi
callq 0x10a90
movq -0x10(%rbp), %rcx
movq %rax, 0x10(%rcx)
cmpq $0x0, %rax
jne 0x24fc5
callq 0xf0a0
movl (%rax), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x4(%rax)
jmp 0x24fc7
jmp 0x24fc9
cmpq $0x0, -0x20(%rbp)
je 0x2500b
movq -0x10(%rbp), %rdi
addq $0xb0, %rdi
callq 0x10480
movl %eax, -0x24(%rbp)
cmpl $0x0, %eax
jne 0x24ff3
movq -0x20(%rbp), %rdi
callq 0xfa70
jmp 0x25009
movq -0x10(%rbp), %rax
cmpl $0x0, 0x4(%rax)
jne 0x25007
movl -0x24(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x4(%rax)
jmp 0x25009
jmp 0x2500b
movq -0x10(%rbp), %rdi
addq $0x1a8, %rdi            # imm = 0x1A8
addq $0x4, %rdi
callq 0x23980
movq -0x10(%rbp), %rdi
callq 0x23800
xorl %eax, %eax
addq $0x40, %rsp
popq %rbp
retq
callq 0xf0a0
movl (%rax), %eax
movl %eax, -0x24(%rbp)
movl -0x24(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x4(%rax)
movq -0x10(%rbp), %rdi
addq $0x20, %rdi
callq 0xfa40
movq -0x10(%rbp), %rdi
addq $0x48, %rdi
callq 0xf040
jmp 0x24fc9
nopw %cs:(%rax,%rax)