// File: /workspace/github_c_makefile_star2_O2/coyove[P]chann/./lib/unqlite/unqlite.c
// Function: VmJsonDecode
static sxi32 VmJsonDecode(
	json_decoder *pDecoder, /* JSON decoder */      
	jx9_value *pArrayKey    /* Key for the decoded array */
	){
	jx9_value *pWorker; /* Worker variable */
	sxi32 rc;
	/* Check if we do not nest to much */
	if( pDecoder->rec_count > 31 ){
		/* Nesting limit reached, abort decoding immediately */
		return SXERR_ABORT;
	}
	if( pDecoder->pIn->nType & (JSON_TK_STR|JSON_TK_ID|JSON_TK_TRUE|JSON_TK_FALSE|JSON_TK_NULL|JSON_TK_NUM) ){
		/* Scalar value */
		pWorker = jx9_context_new_scalar(pDecoder->pCtx);
		if( pWorker == 0 ){
			jx9_context_throw_error(pDecoder->pCtx, JX9_CTX_ERR, "JX9 is running out of memory");
			/* Abort the decoding operation immediately */
			return SXERR_ABORT;
		}
		/* Reflect the JSON image */
		if( pDecoder->pIn->nType & JSON_TK_NULL ){
			/* Nullify the value.*/
			jx9_value_null(pWorker);
		}else if( pDecoder->pIn->nType & (JSON_TK_TRUE|JSON_TK_FALSE) ){
			/* Boolean value */
			jx9_value_bool(pWorker, (pDecoder->pIn->nType & JSON_TK_TRUE) ? 1 : 0 );
		}else if( pDecoder->pIn->nType & JSON_TK_NUM ){
			SyString *pStr = &pDecoder->pIn->sData;
			/* 
			 * Numeric value.
			 * Get a string representation first then try to get a numeric
			 * value.
			 */
			jx9_value_string(pWorker, pStr->zString, (int)pStr->nByte);
			/* Obtain a numeric representation */
			jx9MemObjToNumeric(pWorker);
		}else if( pDecoder->pIn->nType & JSON_TK_ID ){
			SyString *pStr = &pDecoder->pIn->sData;
			jx9_value_string(pWorker, pStr->zString, (int)pStr->nByte);
		}else{
			/* Dequote the string */
			VmJsonDequoteString(&pDecoder->pIn->sData, pWorker);
		}
		/* Invoke the consumer callback */
		rc = pDecoder->xConsumer(pDecoder->pCtx, pArrayKey, pWorker, pDecoder->pUserData);
		if( rc == SXERR_ABORT ){
			return SXERR_ABORT;
		}
		/* All done, advance the stream cursor */
		pDecoder->pIn++;
	}else if( pDecoder->pIn->nType & JSON_TK_OSB /*'[' */) {
		ProcJSONConsumer xOld;
		void *pOld;
		/* Array representation*/
		pDecoder->pIn++;
		/* Create a working array */
		pWorker = jx9_context_new_array(pDecoder->pCtx);
		if( pWorker == 0 ){
			jx9_context_throw_error(pDecoder->pCtx, JX9_CTX_ERR, "JX9 is running out of memory");
			/* Abort the decoding operation immediately */
			return SXERR_ABORT;
		}
		/* Save the old consumer */
		xOld = pDecoder->xConsumer;
		pOld = pDecoder->pUserData;
		/* Set the new consumer */
		pDecoder->xConsumer = VmJsonArrayDecoder;
		pDecoder->pUserData = pWorker;
		/* Decode the array */
		for(;;){
			/* Jump trailing comma. Note that the standard JX9 engine will not let you
			 * do this.
			 */
			while( (pDecoder->pIn < pDecoder->pEnd) && (pDecoder->pIn->nType & JSON_TK_COMMA) ){
				pDecoder->pIn++;
			}
			if( pDecoder->pIn >= pDecoder->pEnd || (pDecoder->pIn->nType & JSON_TK_CSB) /*']'*/ ){
				if( pDecoder->pIn < pDecoder->pEnd ){
					pDecoder->pIn++; /* Jump the trailing ']' */
				}
				break;
			}
			/* Recurse and decode the entry */
			pDecoder->rec_count++;
			rc = VmJsonDecode(pDecoder, 0);
			pDecoder->rec_count--;
			if( rc == SXERR_ABORT ){
				/* Abort processing immediately */
				return SXERR_ABORT;
			}
			/*The cursor is automatically advanced by the VmJsonDecode() function */
			if( (pDecoder->pIn < pDecoder->pEnd) &&
				((pDecoder->pIn->nType & (JSON_TK_CSB/*']'*/|JSON_TK_COMMA/*','*/))==0) ){
					/* Unexpected token, abort immediatley */
					*pDecoder->pErr = SXERR_SYNTAX;
					return SXERR_ABORT;
			}
		}
		/* Restore the old consumer */
		pDecoder->xConsumer = xOld;
		pDecoder->pUserData = pOld;
		/* Invoke the old consumer on the decoded array */
		xOld(pDecoder->pCtx, pArrayKey, pWorker, pOld);
	}else if( pDecoder->pIn->nType & JSON_TK_OCB /*'{' */) {
		ProcJSONConsumer xOld;
		jx9_value *pKey;
		void *pOld;
		/* Object representation*/
		pDecoder->pIn++;
		/* Create a working array */
		pWorker = jx9_context_new_array(pDecoder->pCtx);
		pKey = jx9_context_new_scalar(pDecoder->pCtx);
		if( pWorker == 0 || pKey == 0){
			jx9_context_throw_error(pDecoder->pCtx, JX9_CTX_ERR, "JX9 is running out of memory");
			/* Abort the decoding operation immediately */
			return SXERR_ABORT;
		}
		/* Save the old consumer */
		xOld = pDecoder->xConsumer;
		pOld = pDecoder->pUserData;
		/* Set the new consumer */
		pDecoder->xConsumer = VmJsonArrayDecoder;
		pDecoder->pUserData = pWorker;
		/* Decode the object */
		for(;;){
			/* Jump trailing comma. Note that the standard JX9 engine will not let you
			 * do this.
			 */
			while( (pDecoder->pIn < pDecoder->pEnd) && (pDecoder->pIn->nType & JSON_TK_COMMA) ){
				pDecoder->pIn++;
			}
			if( pDecoder->pIn >= pDecoder->pEnd || (pDecoder->pIn->nType & JSON_TK_CCB) /*'}'*/ ){
				if( pDecoder->pIn < pDecoder->pEnd ){
					pDecoder->pIn++; /* Jump the trailing ']' */
				}
				break;
			}
			if( (pDecoder->pIn->nType & (JSON_TK_ID|JSON_TK_STR)) == 0 || &pDecoder->pIn[1] >= pDecoder->pEnd
				|| (pDecoder->pIn[1].nType & JSON_TK_COLON) == 0){
					/* Syntax error, return immediately */
					*pDecoder->pErr = SXERR_SYNTAX;
					return SXERR_ABORT;
			}
			if( pDecoder->pIn->nType & JSON_TK_ID ){
				SyString *pStr = &pDecoder->pIn->sData;
				jx9_value_string(pKey, pStr->zString, (int)pStr->nByte);
			}else{
				/* Dequote the key */
				VmJsonDequoteString(&pDecoder->pIn->sData, pKey);
			}
			/* Jump the key and the colon */
			pDecoder->pIn += 2; 
			/* Recurse and decode the value */
			pDecoder->rec_count++;
			rc = VmJsonDecode(pDecoder, pKey);
			pDecoder->rec_count--;
			if( rc == SXERR_ABORT ){
				/* Abort processing immediately */
				return SXERR_ABORT;
			}
			/* Reset the internal buffer of the key */
			jx9_value_reset_string_cursor(pKey);
			/*The cursor is automatically advanced by the VmJsonDecode() function */
		}
		/* Restore the old consumer */
		pDecoder->xConsumer = xOld;
		pDecoder->pUserData = pOld;
		/* Invoke the old consumer on the decoded object*/
		xOld(pDecoder->pCtx, pArrayKey, pWorker, pOld);
		/* Release the key */
		jx9_context_release_value(pDecoder->pCtx, pKey);
	}else{
		/* Unexpected token */
		return SXERR_ABORT; /* Abort immediately */
	}
	/* Release the worker variable */
	jx9_context_release_value(pDecoder->pCtx, pWorker);
	return SXRET_OK;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
pushq $-0xa
popq %rbx
cmpl $0x1f, 0x30(%rdi)
jg 0x46923
movq %rsi, %r15
movq %rdi, %r14
movq 0x20(%rdi), %rax
movl 0x10(%rax), %ecx
testw $0x81f, %cx             # imm = 0x81F
je 0x46686
movq (%r14), %rdi
callq 0x2a26a
testq %rax, %rax
je 0x46873
movq %rax, %r12
movq 0x20(%r14), %rdi
movl 0x10(%rdi), %esi
testb $0x8, %sil
jne 0x4679b
testb $0x3, %sil
je 0x4688a
andl $0x1, %esi
movq %r12, %rdi
callq 0x294f9
jmp 0x467a3
testb %cl, %cl
js 0x467c7
testb $0x20, %cl
je 0x46923
addq $0x20, %rax
movq %rax, 0x20(%r14)
movq (%r14), %rdi
callq 0x2a2b0
movq %rax, %r12
movq (%r14), %rdi
callq 0x2a26a
movq %rax, %r13
testq %r12, %r12
sete %al
testq %r13, %r13
sete %cl
orb %al, %cl
cmpb $0x1, %cl
je 0x46873
movq 0x8(%r14), %r8
movq 0x10(%r14), %rcx
leaq 0x30c(%rip), %rax       # 0x469e7
movq %rax, 0x8(%r14)
movq %r12, 0x10(%r14)
movq %r13, %rax
addq $0x18, %rax
movq %rax, -0x30(%rbp)
movq 0x20(%r14), %rdi
movq 0x28(%r14), %rax
cmpq %rax, %rdi
jae 0x468f7
movl 0x10(%rdi), %esi
btl $0xa, %esi
jae 0x46712
addq $0x20, %rdi
movq %rdi, 0x20(%r14)
jmp 0x466f6
testb $0x40, %sil
jne 0x468ef
testw $0x804, %si             # imm = 0x804
je 0x46864
leaq 0x20(%rdi), %rdx
cmpq %rax, %rdx
jae 0x46864
testb $0x2, 0x31(%rdi)
je 0x46864
movq %rcx, -0x38(%rbp)
movq %r8, -0x40(%rbp)
btl $0xb, %esi
jb 0x46756
movq %r13, %rsi
callq 0x46934
jmp 0x46764
movq (%rdi), %rsi
movl 0x8(%rdi), %edx
movq %r13, %rdi
callq 0x29588
addq $0x40, 0x20(%r14)
incl 0x30(%r14)
movq %r14, %rdi
movq %r13, %rsi
callq 0x46615
decl 0x30(%r14)
cmpl $-0xa, %eax
je 0x46923
movq -0x30(%rbp), %rdi
callq 0x31b1e
movq -0x40(%rbp), %r8
movq -0x38(%rbp), %rcx
jmp 0x466ee
movq %r12, %rdi
callq 0x296af
movq (%r14), %rdi
movq 0x10(%r14), %rcx
movq %r15, %rsi
movq %r12, %rdx
callq *0x8(%r14)
cmpl $-0xa, %eax
je 0x46923
addq $0x20, 0x20(%r14)
jmp 0x46916
addq $0x20, %rax
movq %rax, 0x20(%r14)
movq (%r14), %rdi
callq 0x2a2b0
testq %rax, %rax
je 0x46873
movq %rax, %r12
movq 0x8(%r14), %r13
movq 0x10(%r14), %rcx
leaq 0x1f5(%rip), %rax       # 0x469e7
movq %rax, 0x8(%r14)
movq %r12, 0x10(%r14)
movq 0x28(%r14), %rsi
movq 0x20(%r14), %rax
cmpq %rsi, %rax
jae 0x468d9
movl 0x10(%rax), %edx
btl $0xa, %edx
jae 0x4681e
addq $0x20, %rax
movq %rax, 0x20(%r14)
jmp 0x46802
btl $0x8, %edx
jb 0x468d1
movq %r15, -0x30(%rbp)
movq %rcx, %r15
incl 0x30(%r14)
movq %r14, %rdi
xorl %esi, %esi
callq 0x46615
decl 0x30(%r14)
cmpl $-0xa, %eax
je 0x46923
movq 0x20(%r14), %rax
movq 0x28(%r14), %rsi
cmpq %rsi, %rax
movq %r15, %rcx
movq -0x30(%rbp), %r15
jae 0x46802
testb $0x5, 0x11(%rax)
jne 0x46802
movq 0x38(%r14), %rax
movl $0xfffffff4, (%rax)     # imm = 0xFFFFFFF4
jmp 0x46923
movq (%r14), %rdi
leaq 0x1fa33(%rip), %rdx     # 0x662b0
pushq $0x1
popq %rsi
callq 0x2a0db
jmp 0x46923
testb $0x10, %sil
jne 0x468a3
btl $0xb, %esi
jb 0x468be
movq %r12, %rsi
callq 0x46934
jmp 0x467a3
movq (%rdi), %rsi
movl 0x8(%rdi), %edx
movq %r12, %rdi
callq 0x29588
movq %r12, %rdi
callq 0x3acd2
jmp 0x467a3
movq (%rdi), %rsi
movl 0x8(%rdi), %edx
movq %r12, %rdi
callq 0x29588
jmp 0x467a3
addq $0x20, %rax
movq %rax, 0x20(%r14)
movq %r13, 0x8(%r14)
movq %rcx, 0x10(%r14)
movq (%r14), %rdi
movq %r15, %rsi
movq %r12, %rdx
callq *%r13
jmp 0x46916
addq $0x20, %rdi
movq %rdi, 0x20(%r14)
movq %r8, 0x8(%r14)
movq %rcx, 0x10(%r14)
movq (%r14), %rdi
movq %r15, %rsi
movq %r12, %rdx
callq *%r8
movq (%r14), %rdi
movq %r13, %rsi
callq 0x2a2f6
movq (%r14), %rdi
movq %r12, %rsi
callq 0x2a2f6
xorl %ebx, %ebx
movl %ebx, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq