// File: /workspace/github_c_makefile_star2_O0/goodpaul6[P]generic/script.c
// Function: unmarshal
static script_value_t* unmarshal(script_t* script, const char** pdesc, char** pmem)
{
#define ALIGN(m, type) (*m = (char*)((intptr_t)(*m) + (ALIGNOF(type) - 1) & -ALIGNOF(type)))
#define ALIGNOF(type) ((size_t)&((struct { char c; type d; } *)0)->d)
	
	const char* desc = *pdesc;
	
	switch (*desc)
	{
		case 'b':
		{
			ALIGN(pmem, char);
				
			script_value_t* val = new_value(script, VAL_BOOL);

			val->boolean = (char)*(char*)(*pmem);

			*pmem += sizeof(char);
			*pdesc += 1;

			return val;
		} break;
			
		case 'i':
		{
			ALIGN(pmem, int);

			script_value_t* val = new_value(script, VAL_NUMBER);
			val->number = (double)*(int*)(*pmem);

			*pmem += sizeof(int);
			*pdesc += 1;

			return val;
		} break;

		case 'g':
		{
			ALIGN(pmem, double);

			script_value_t* val = new_value(script, VAL_NUMBER);
			val->number = *(double*)(*pmem);

			*pmem += sizeof(double);
			*pdesc += 1;

			return val;
		} break;

		case 's':
		{
			ALIGN(pmem, const char*);

			const char* str = *(const char**)(*pmem);

			*pdesc += 1;

			if (!str)
				return new_value(script, VAL_NULL);
			else
			{
				script_value_t* val = new_value(script, VAL_STRING);

				val->string.length = strlen(str);
				val->string.data = emalloc(val->string.length + 1);

				strcpy(val->string.data, str);

				*pmem += sizeof(const char*);

				return val;
			}
		} break;

		case 'c':
		{
			int n = 1;
			int i = 1;

			if (isdigit(desc[i]))
			{
				n = 0;
				while (isdigit(desc[i]))
				{
					n = n * 10 + (desc[i] - '0');
					++i;
				}
			}
			*pdesc += i;

			if (n == 1)
			{
				script_value_t* val = new_value(script, VAL_CHAR);
				val->code = *(char*)(*pmem);

				*pmem += 1;

				return val;
			}
			else if (n > 1)
			{
				script_value_t* val = new_value(script, VAL_STRING);

				// TODO: Maybe check for buffer overflow etc
				const char* str = (const char*)(*pmem);

				val->string.length = strlen(str);
				val->string.data = emalloc(n);

				strcpy(val->string.data, str);

				*pmem += n;

				return val;
			}

			assert(0);
		} break;

		case 'p':
		{
			if (desc[1] == '{')
			{
				ALIGN(pmem, char*);

				*pdesc += 1;
				if (*pmem)
				{
					char* mem = *(char**)(*pmem);
					script_value_t* val = unmarshal(script, pdesc, &mem);
					return val;
				}

				*pmem += sizeof(char*);

				return new_value(script, VAL_NULL);
			}
			else
			{
				ALIGN(pmem, void*);

				script_value_t* val = new_value(script, VAL_NATIVE);

				val->nat.value = *(void**)(*pmem);
				val->nat.on_mark = val->nat.on_delete = NULL;
					
				*pmem += sizeof(void*);
				*pdesc += 1;

				return val;
			}
		} break;

		case '{':
		case '[':
		{
			char is_array = desc[0] == '[';

			int i = 1;
			int dp = 0;
			char nestedDesc[256];
			
			int bracket_count = 1;

			while (bracket_count)
			{
				if (dp >= 255)
				{
					printf("'unmarshal' exceeded maximum description length.\n");
					*pdesc += i + 1;
					return new_value(script, VAL_NULL);
				}
				
				if (desc[i] == '{' || desc[i] == '[')
					++bracket_count;

				if (desc[i] == '}' || desc[i] == ']')
					--bracket_count;

				if(bracket_count > 0)
					nestedDesc[dp++] = desc[i++];
			}
			nestedDesc[dp] = '\0';

			*pdesc += i + 1;

			char* ndp = nestedDesc;

			if (!is_array)
			{
				script_value_t* result = new_value(script, VAL_STRUCT_INSTANCE);
				vec_init(&result->ds.members, sizeof(script_value_t*));

				while(*ndp)
				{
					script_value_t* val = unmarshal(script, &ndp, pmem);
					vec_push_back(&result->ds.members, &val);
				}

				return result;
			}
			else
			{
				ALIGN(pmem, vector_t);

				vector_t* vec = (vector_t*)(*pmem);

				script_value_t* result = new_value(script, VAL_ARRAY);
				vec_init(&result->array, sizeof(script_value_t*));

				for(int i = 0; i < vec->length; ++i)
				{
					void* mem = vec_get(vec, i);

					script_value_t* val = unmarshal(script, &ndp, &mem);
					vec_push_back(&result->array, &val);

					ndp = nestedDesc;
				}

				return result;
			}
		} break;

		case '&':
		{
			script_value_t* val = new_value(script, VAL_NATIVE);

			val->nat.value = *pmem;
			val->nat.on_mark = val->nat.on_delete = NULL;

			*pdesc += 1;

			return val;
		} break;
	}

#undef ALIGNOF
#undef ALIGN

	return NULL;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x200, %rsp            # imm = 0x200
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq -0x18(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rax
movsbl (%rax), %eax
addl $-0x26, %eax
movl %eax, %ecx
movq %rcx, -0x1f8(%rbp)
subl $0x55, %eax
ja 0x9425
movq -0x1f8(%rbp), %rax
leaq 0xa5dc(%rip), %rcx      # 0x131b8
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0x20(%rbp), %rax
movq (%rax), %rcx
xorl %eax, %eax
addq $0x1, %rax
subq $0x1, %rax
addq %rax, %rcx
xorl %eax, %eax
movq %rax, %rdx
addq $0x1, %rdx
subq %rdx, %rax
andq %rax, %rcx
movq -0x20(%rbp), %rax
movq %rcx, (%rax)
movq -0x10(%rbp), %rdi
movl $0x1, %esi
callq 0x3350
movq %rax, -0x30(%rbp)
movq -0x20(%rbp), %rax
movq (%rax), %rax
movb (%rax), %cl
movq -0x30(%rbp), %rax
movb %cl, 0x20(%rax)
movq -0x20(%rbp), %rax
movq (%rax), %rcx
addq $0x1, %rcx
movq %rcx, (%rax)
movq -0x18(%rbp), %rax
movq (%rax), %rcx
addq $0x1, %rcx
movq %rcx, (%rax)
movq -0x30(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x942d
movq -0x20(%rbp), %rax
movq (%rax), %rcx
xorl %eax, %eax
addq $0x4, %rax
subq $0x1, %rax
addq %rax, %rcx
xorl %eax, %eax
movq %rax, %rdx
addq $0x4, %rdx
subq %rdx, %rax
andq %rax, %rcx
movq -0x20(%rbp), %rax
movq %rcx, (%rax)
movq -0x10(%rbp), %rdi
movl $0x3, %esi
callq 0x3350
movq %rax, -0x38(%rbp)
movq -0x20(%rbp), %rax
movq (%rax), %rax
cvtsi2sdl (%rax), %xmm0
movq -0x38(%rbp), %rax
movsd %xmm0, 0x20(%rax)
movq -0x20(%rbp), %rax
movq (%rax), %rcx
addq $0x4, %rcx
movq %rcx, (%rax)
movq -0x18(%rbp), %rax
movq (%rax), %rcx
addq $0x1, %rcx
movq %rcx, (%rax)
movq -0x38(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x942d
movq -0x20(%rbp), %rax
movq (%rax), %rcx
xorl %eax, %eax
addq $0x8, %rax
subq $0x1, %rax
addq %rax, %rcx
xorl %eax, %eax
movq %rax, %rdx
addq $0x8, %rdx
subq %rdx, %rax
andq %rax, %rcx
movq -0x20(%rbp), %rax
movq %rcx, (%rax)
movq -0x10(%rbp), %rdi
movl $0x3, %esi
callq 0x3350
movq %rax, -0x40(%rbp)
movq -0x20(%rbp), %rax
movq (%rax), %rax
movsd (%rax), %xmm0
movq -0x40(%rbp), %rax
movsd %xmm0, 0x20(%rax)
movq -0x20(%rbp), %rax
movq (%rax), %rcx
addq $0x8, %rcx
movq %rcx, (%rax)
movq -0x18(%rbp), %rax
movq (%rax), %rcx
addq $0x1, %rcx
movq %rcx, (%rax)
movq -0x40(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x942d
movq -0x20(%rbp), %rax
movq (%rax), %rcx
xorl %eax, %eax
addq $0x8, %rax
subq $0x1, %rax
addq %rax, %rcx
xorl %eax, %eax
movq %rax, %rdx
addq $0x8, %rdx
subq %rdx, %rax
andq %rax, %rcx
movq -0x20(%rbp), %rax
movq %rcx, (%rax)
movq -0x20(%rbp), %rax
movq (%rax), %rax
movq (%rax), %rax
movq %rax, -0x48(%rbp)
movq -0x18(%rbp), %rax
movq (%rax), %rcx
addq $0x1, %rcx
movq %rcx, (%rax)
cmpq $0x0, -0x48(%rbp)
jne 0x8dad
movq -0x10(%rbp), %rdi
xorl %esi, %esi
callq 0x3350
movq %rax, -0x8(%rbp)
jmp 0x942d
movq -0x10(%rbp), %rdi
movl $0x4, %esi
callq 0x3350
movq %rax, -0x50(%rbp)
movq -0x48(%rbp), %rdi
callq 0x20a0
movl %eax, %ecx
movq -0x50(%rbp), %rax
movl %ecx, 0x20(%rax)
movq -0x50(%rbp), %rax
movl 0x20(%rax), %eax
addl $0x1, %eax
movl %eax, %eax
movl %eax, %edi
callq 0x3580
movq %rax, %rcx
movq -0x50(%rbp), %rax
movq %rcx, 0x28(%rax)
movq -0x50(%rbp), %rax
movq 0x28(%rax), %rdi
movq -0x48(%rbp), %rsi
callq 0x2050
movq -0x20(%rbp), %rax
movq (%rax), %rcx
addq $0x8, %rcx
movq %rcx, (%rax)
movq -0x50(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x942d
movl $0x1, -0x54(%rbp)
movl $0x1, -0x58(%rbp)
callq 0x2230
movq (%rax), %rax
movq -0x28(%rbp), %rcx
movslq -0x58(%rbp), %rdx
movsbl (%rcx,%rdx), %ecx
movslq %ecx, %rcx
movzwl (%rax,%rcx,2), %eax
andl $0x800, %eax            # imm = 0x800
cmpl $0x0, %eax
je 0x8e9f
movl $0x0, -0x54(%rbp)
callq 0x2230
movq (%rax), %rax
movq -0x28(%rbp), %rcx
movslq -0x58(%rbp), %rdx
movsbl (%rcx,%rdx), %ecx
movslq %ecx, %rcx
movzwl (%rax,%rcx,2), %eax
andl $0x800, %eax            # imm = 0x800
cmpl $0x0, %eax
je 0x8e9d
imull $0xa, -0x54(%rbp), %eax
movq -0x28(%rbp), %rcx
movslq -0x58(%rbp), %rdx
movsbl (%rcx,%rdx), %ecx
subl $0x30, %ecx
addl %ecx, %eax
movl %eax, -0x54(%rbp)
movl -0x58(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x58(%rbp)
jmp 0x8e55
jmp 0x8e9f
movl -0x58(%rbp), %edx
movq -0x18(%rbp), %rax
movq (%rax), %rcx
movslq %edx, %rdx
addq %rdx, %rcx
movq %rcx, (%rax)
cmpl $0x1, -0x54(%rbp)
jne 0x8ef5
movq -0x10(%rbp), %rdi
movl $0x2, %esi
callq 0x3350
movq %rax, -0x60(%rbp)
movq -0x20(%rbp), %rax
movq (%rax), %rax
movb (%rax), %cl
movq -0x60(%rbp), %rax
movb %cl, 0x20(%rax)
movq -0x20(%rbp), %rax
movq (%rax), %rcx
addq $0x1, %rcx
movq %rcx, (%rax)
movq -0x60(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x942d
cmpl $0x1, -0x54(%rbp)
jle 0x8f6f
movq -0x10(%rbp), %rdi
movl $0x4, %esi
callq 0x3350
movq %rax, -0x68(%rbp)
movq -0x20(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x70(%rbp)
movq -0x70(%rbp), %rdi
callq 0x20a0
movl %eax, %ecx
movq -0x68(%rbp), %rax
movl %ecx, 0x20(%rax)
movslq -0x54(%rbp), %rdi
callq 0x3580
movq %rax, %rcx
movq -0x68(%rbp), %rax
movq %rcx, 0x28(%rax)
movq -0x68(%rbp), %rax
movq 0x28(%rax), %rdi
movq -0x70(%rbp), %rsi
callq 0x2050
movl -0x54(%rbp), %edx
movq -0x20(%rbp), %rax
movq (%rax), %rcx
movslq %edx, %rdx
addq %rdx, %rcx
movq %rcx, (%rax)
movq -0x68(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x942d
jmp 0x8f71
leaq 0xacac(%rip), %rdi      # 0x13c24
leaq 0xaca7(%rip), %rsi      # 0x13c26
movl $0x10a7, %edx           # imm = 0x10A7
leaq 0xaca4(%rip), %rcx      # 0x13c2f
callq 0x20f0
movq -0x28(%rbp), %rax
movsbl 0x1(%rax), %eax
cmpl $0x7b, %eax
jne 0x9035
movq -0x20(%rbp), %rax
movq (%rax), %rcx
xorl %eax, %eax
addq $0x8, %rax
subq $0x1, %rax
addq %rax, %rcx
xorl %eax, %eax
movq %rax, %rdx
addq $0x8, %rdx
subq %rdx, %rax
andq %rax, %rcx
movq -0x20(%rbp), %rax
movq %rcx, (%rax)
movq -0x18(%rbp), %rax
movq (%rax), %rcx
addq $0x1, %rcx
movq %rcx, (%rax)
movq -0x20(%rbp), %rax
cmpq $0x0, (%rax)
je 0x9013
movq -0x20(%rbp), %rax
movq (%rax), %rax
movq (%rax), %rax
movq %rax, -0x78(%rbp)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
leaq -0x78(%rbp), %rdx
callq 0x8b90
movq %rax, -0x80(%rbp)
movq -0x80(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x942d
movq -0x20(%rbp), %rax
movq (%rax), %rcx
addq $0x8, %rcx
movq %rcx, (%rax)
movq -0x10(%rbp), %rdi
xorl %esi, %esi
callq 0x3350
movq %rax, -0x8(%rbp)
jmp 0x942d
movq -0x20(%rbp), %rax
movq (%rax), %rcx
xorl %eax, %eax
addq $0x8, %rax
subq $0x1, %rax
addq %rax, %rcx
xorl %eax, %eax
movq %rax, %rdx
addq $0x8, %rdx
subq %rdx, %rax
andq %rax, %rcx
movq -0x20(%rbp), %rax
movq %rcx, (%rax)
movq -0x10(%rbp), %rdi
movl $0x8, %esi
callq 0x3350
movq %rax, -0x88(%rbp)
movq -0x20(%rbp), %rax
movq (%rax), %rax
movq (%rax), %rcx
movq -0x88(%rbp), %rax
movq %rcx, 0x20(%rax)
movq -0x88(%rbp), %rax
movq $0x0, 0x30(%rax)
movq -0x88(%rbp), %rax
movq $0x0, 0x28(%rax)
movq -0x20(%rbp), %rax
movq (%rax), %rcx
addq $0x8, %rcx
movq %rcx, (%rax)
movq -0x18(%rbp), %rax
movq (%rax), %rcx
addq $0x1, %rcx
movq %rcx, (%rax)
movq -0x88(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x942d
movq -0x28(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x5b, %eax
sete %al
andb $0x1, %al
movzbl %al, %eax
movb %al, -0x89(%rbp)
movl $0x1, -0x90(%rbp)
movl $0x0, -0x94(%rbp)
movl $0x1, -0x1a4(%rbp)
cmpl $0x0, -0x1a4(%rbp)
je 0x920e
cmpl $0xff, -0x94(%rbp)
jl 0x915d
leaq 0xab44(%rip), %rdi      # 0x13c6d
movb $0x0, %al
callq 0x20c0
movl -0x90(%rbp), %edx
addl $0x1, %edx
movq -0x18(%rbp), %rax
movq (%rax), %rcx
movslq %edx, %rdx
addq %rdx, %rcx
movq %rcx, (%rax)
movq -0x10(%rbp), %rdi
xorl %esi, %esi
callq 0x3350
movq %rax, -0x8(%rbp)
jmp 0x942d
movq -0x28(%rbp), %rax
movslq -0x90(%rbp), %rcx
movsbl (%rax,%rcx), %eax
cmpl $0x7b, %eax
je 0x9185
movq -0x28(%rbp), %rax
movslq -0x90(%rbp), %rcx
movsbl (%rax,%rcx), %eax
cmpl $0x5b, %eax
jne 0x9194
movl -0x1a4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1a4(%rbp)
movq -0x28(%rbp), %rax
movslq -0x90(%rbp), %rcx
movsbl (%rax,%rcx), %eax
cmpl $0x7d, %eax
je 0x91bc
movq -0x28(%rbp), %rax
movslq -0x90(%rbp), %rcx
movsbl (%rax,%rcx), %eax
cmpl $0x5d, %eax
jne 0x91cb
movl -0x1a4(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x1a4(%rbp)
cmpl $0x0, -0x1a4(%rbp)
jle 0x9209
movq -0x28(%rbp), %rax
movl -0x90(%rbp), %ecx
movl %ecx, %edx
addl $0x1, %edx
movl %edx, -0x90(%rbp)
movslq %ecx, %rcx
movb (%rax,%rcx), %cl
movl -0x94(%rbp), %eax
movl %eax, %edx
addl $0x1, %edx
movl %edx, -0x94(%rbp)
cltq
movb %cl, -0x1a0(%rbp,%rax)
jmp 0x9109
movslq -0x94(%rbp), %rax
movb $0x0, -0x1a0(%rbp,%rax)
movl -0x90(%rbp), %edx
addl $0x1, %edx
movq -0x18(%rbp), %rax
movq (%rax), %rcx
movslq %edx, %rdx
addq %rdx, %rcx
movq %rcx, (%rax)
leaq -0x1a0(%rbp), %rax
movq %rax, -0x1b0(%rbp)
cmpb $0x0, -0x89(%rbp)
jne 0x92c7
movq -0x10(%rbp), %rdi
movl $0x7, %esi
callq 0x3350
movq %rax, -0x1b8(%rbp)
movq -0x1b8(%rbp), %rdi
addq $0x20, %rdi
movl $0x8, %esi
callq 0x114e0
movq -0x1b0(%rbp), %rax
cmpb $0x0, (%rax)
je 0x92b7
movq -0x10(%rbp), %rdi
movq -0x20(%rbp), %rdx
leaq -0x1b0(%rbp), %rsi
callq 0x8b90
movq %rax, -0x1c0(%rbp)
movq -0x1b8(%rbp), %rdi
addq $0x20, %rdi
leaq -0x1c0(%rbp), %rsi
callq 0x11960
jmp 0x9277
movq -0x1b8(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x942d
movq -0x20(%rbp), %rax
movq (%rax), %rcx
xorl %eax, %eax
addq $0x8, %rax
subq $0x1, %rax
addq %rax, %rcx
xorl %eax, %eax
movq %rax, %rdx
addq $0x8, %rdx
subq %rdx, %rax
andq %rax, %rcx
movq -0x20(%rbp), %rax
movq %rcx, (%rax)
movq -0x20(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x1c8(%rbp)
movq -0x10(%rbp), %rdi
movl $0x6, %esi
callq 0x3350
movq %rax, -0x1d0(%rbp)
movq -0x1d0(%rbp), %rdi
addq $0x20, %rdi
movl $0x8, %esi
callq 0x114e0
movl $0x0, -0x1d4(%rbp)
movslq -0x1d4(%rbp), %rax
movq -0x1c8(%rbp), %rcx
cmpq 0x10(%rcx), %rax
jae 0x93b8
movq -0x1c8(%rbp), %rdi
movslq -0x1d4(%rbp), %rsi
callq 0x11890
movq %rax, -0x1e0(%rbp)
movq -0x10(%rbp), %rdi
leaq -0x1b0(%rbp), %rsi
leaq -0x1e0(%rbp), %rdx
callq 0x8b90
movq %rax, -0x1e8(%rbp)
movq -0x1d0(%rbp), %rdi
addq $0x20, %rdi
leaq -0x1e8(%rbp), %rsi
callq 0x11960
leaq -0x1a0(%rbp), %rax
movq %rax, -0x1b0(%rbp)
movl -0x1d4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1d4(%rbp)
jmp 0x9333
movq -0x1d0(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x942d
movq -0x10(%rbp), %rdi
movl $0x8, %esi
callq 0x3350
movq %rax, -0x1f0(%rbp)
movq -0x20(%rbp), %rax
movq (%rax), %rcx
movq -0x1f0(%rbp), %rax
movq %rcx, 0x20(%rax)
movq -0x1f0(%rbp), %rax
movq $0x0, 0x30(%rax)
movq -0x1f0(%rbp), %rax
movq $0x0, 0x28(%rax)
movq -0x18(%rbp), %rax
movq (%rax), %rcx
addq $0x1, %rcx
movq %rcx, (%rax)
movq -0x1f0(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x942d
movq $0x0, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x200, %rsp            # imm = 0x200
popq %rbp
retq
nopw (%rax,%rax)