fixed issues related to the new make_block, make_function instruction scheme
This commit is contained in:
		
							
								
								
									
										113
									
								
								hcl/lib/comp.c
									
									
									
									
									
								
							
							
						
						
									
										113
									
								
								hcl/lib/comp.c
									
									
									
									
									
								
							| @ -397,17 +397,6 @@ static int emit_single_param_instruction (hcl_t* hcl, int cmd, hcl_oow_t param_1 | |||||||
| 		case HCL_CODE_POP_INTO_BYTEARRAY: | 		case HCL_CODE_POP_INTO_BYTEARRAY: | ||||||
| 			bc = cmd; | 			bc = cmd; | ||||||
| 			goto write_long; | 			goto write_long; | ||||||
|  |  | ||||||
| 		/* MAKE_FUNCTION is a quad-parameter instruction.  |  | ||||||
| 		 * The caller must emit two more parameters after the call to this function. |  | ||||||
| 		 * however the instruction format is the same up to the second |  | ||||||
| 		 * parameters between MAKE_FUNCTION and MAKE_BLOCK. |  | ||||||
| 		 */ |  | ||||||
| 		case HCL_CODE_MAKE_FUNCTION: |  | ||||||
| 		case HCL_CODE_MAKE_BLOCK: |  | ||||||
| 			/* write_long2 produces two parameters */ |  | ||||||
| 			bc = cmd; |  | ||||||
| 			goto write_long2; |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	hcl_seterrnum (hcl, HCL_EINVAL); | 	hcl_seterrnum (hcl, HCL_EINVAL); | ||||||
| @ -479,6 +468,16 @@ static int emit_double_param_instruction (hcl_t* hcl, int cmd, hcl_oow_t param_1 | |||||||
| 				bc = cmd | 0x80;  | 				bc = cmd | 0x80;  | ||||||
| 				goto write_long; | 				goto write_long; | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
|  | 		/* MAKE_FUNCTION is a quad-parameter instruction.  | ||||||
|  | 		 * The caller must emit two more parameters after the call to this function. | ||||||
|  | 		 * however the instruction format is the same up to the second | ||||||
|  | 		 * parameters between MAKE_FUNCTION and MAKE_BLOCK. | ||||||
|  | 		 */ | ||||||
|  | 		case HCL_CODE_MAKE_BLOCK: | ||||||
|  | 		case HCL_CODE_MAKE_FUNCTION: | ||||||
|  | 			bc = cmd; | ||||||
|  | 			goto write_long; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	hcl_seterrnum (hcl, HCL_EINVAL); | 	hcl_seterrnum (hcl, HCL_EINVAL); | ||||||
| @ -497,9 +496,9 @@ write_long: | |||||||
| 	} | 	} | ||||||
| #if (HCL_CODE_LONG_PARAM_SIZE == 2) | #if (HCL_CODE_LONG_PARAM_SIZE == 2) | ||||||
| 	if (emit_byte_instruction(hcl, bc, srcloc) <= -1 || | 	if (emit_byte_instruction(hcl, bc, srcloc) <= -1 || | ||||||
| 	    emit_byte_instruction(hcl, param_1 >> 8, HCL_NULL) <= -1 || | 	    emit_byte_instruction(hcl, (param_1 >> 8) & 0xFF, HCL_NULL) <= -1 || | ||||||
| 	    emit_byte_instruction(hcl, param_1 & 0xFF, HCL_NULL) <= -1 || | 	    emit_byte_instruction(hcl, param_1 & 0xFF, HCL_NULL) <= -1 || | ||||||
| 	    emit_byte_instruction(hcl, param_2 >> 8, HCL_NULL) <= -1 || | 	    emit_byte_instruction(hcl, (param_2 >> 8) & 0xFF, HCL_NULL) <= -1 || | ||||||
| 	    emit_byte_instruction(hcl, param_2 & 0xFF, HCL_NULL) <= -1) return -1; | 	    emit_byte_instruction(hcl, param_2 & 0xFF, HCL_NULL) <= -1) return -1; | ||||||
| #else | #else | ||||||
| 	if (emit_byte_instruction(hcl, bc, srcloc) <= -1 || | 	if (emit_byte_instruction(hcl, bc, srcloc) <= -1 || | ||||||
| @ -614,22 +613,29 @@ static HCL_INLINE void patch_long_param (hcl_t* hcl, hcl_ooi_t ip, hcl_oow_t par | |||||||
| #endif | #endif | ||||||
| } | } | ||||||
|  |  | ||||||
| static HCL_INLINE void patch_double_long_params (hcl_t* hcl, hcl_ooi_t ip, hcl_ooi_t param_1, hcl_ooi_t param_2) | static HCL_INLINE void patch_double_long_params (hcl_t* hcl, hcl_ooi_t ip, hcl_oow_t param_1, hcl_oow_t param_2) | ||||||
| { | { | ||||||
| #if (HCL_CODE_LONG_PARAM_SIZE == 2) | #if (HCL_CODE_LONG_PARAM_SIZE == 2) | ||||||
| 	if (param_1 >= 0) | 	patch_instruction (hcl, ip, param_1 >> 8); | ||||||
| 	{ | 	patch_instruction (hcl, ip + 1, param_1 & 0xFF); | ||||||
| 		patch_instruction (hcl, ip, param_1 >> 8); | 	patch_instruction (hcl, ip + 2, param_2 >> 8); | ||||||
| 		patch_instruction (hcl, ip + 1, param_1 & 0xFF); | 	patch_instruction (hcl, ip + 3, param_2 & 0xFF); | ||||||
| 	} |  | ||||||
| 	if (param_2 >= 0) |  | ||||||
| 	{ |  | ||||||
| 		patch_instruction (hcl, ip + 2, param_2 >> 8); |  | ||||||
| 		patch_instruction (hcl, ip + 3, param_2 & 0xFF); |  | ||||||
| 	} |  | ||||||
| #else | #else | ||||||
| 	if (param_1 >= 0) patch_instruction (hcl, ip, param_1); | 	patch_instruction (hcl, ip, param_1); | ||||||
| 	if (param_2 >= 0) patch_instruction (hcl, ip + 1, param_2); | 	patch_instruction (hcl, ip + 1, param_2); | ||||||
|  | #endif | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static HCL_INLINE void patch_double_long_params_with_oow (hcl_t* hcl, hcl_ooi_t ip, hcl_oow_t param) | ||||||
|  | { | ||||||
|  | #if (HCL_CODE_LONG_PARAM_SIZE == 2) | ||||||
|  | 	patch_instruction (hcl, ip,     (param >> 24) & 0xFF); | ||||||
|  | 	patch_instruction (hcl, ip + 1, (param >> 16) & 0xFF); | ||||||
|  | 	patch_instruction (hcl, ip + 2, (param >> 8) & 0xFF); | ||||||
|  | 	patch_instruction (hcl, ip + 3, (param >> 0) & 0xFF); | ||||||
|  | #else | ||||||
|  | 	patch_instruction (hcl, ip,     (param >> 8) & 9xFF); | ||||||
|  | 	patch_instruction (hcl, ip + 1, (param >> 0) & 0xFF); | ||||||
| #endif | #endif | ||||||
| } | } | ||||||
|  |  | ||||||
| @ -717,24 +723,15 @@ static int push_fnblk (hcl_t* hcl, const hcl_ioloc_t* errloc, | |||||||
|  |  | ||||||
| static void pop_fnblk (hcl_t* hcl) | static void pop_fnblk (hcl_t* hcl) | ||||||
| { | { | ||||||
| 	hcl_oow_t mip; | 	hcl_fnblk_info_t* fbi; | ||||||
| 	 | 	 | ||||||
| 	HCL_ASSERT (hcl, hcl->c->fnblk.depth >= 0); | 	HCL_ASSERT (hcl, hcl->c->fnblk.depth >= 0); | ||||||
| 	/* if pop_cblk() has been called properly, the following assertion must be true | 	/* if pop_cblk() has been called properly, the following assertion must be true | ||||||
| 	 * and the assignment on the next line isn't necessary */ | 	 * and the assignment on the next line isn't necessary */ | ||||||
|  |  | ||||||
| 	/* patch the temporary mask in the MAKE_BLOCK or MAKE_FUNCTION instruction */ | 	fbi = &hcl->c->fnblk.info[hcl->c->fnblk.depth]; | ||||||
| 	mip = hcl->c->fnblk.info[hcl->c->fnblk.depth].make_inst_pos; | 	HCL_ASSERT (hcl, hcl->c->cblk.depth == fbi->cblk_base);  | ||||||
| 	if (mip < hcl->code.bc.len) | 	hcl->c->cblk.depth = fbi->cblk_base; | ||||||
| 	{ |  | ||||||
| 		HCL_ASSERT (hcl, hcl->code.bc.ptr[mip] == HCL_CODE_MAKE_BLOCK ||  |  | ||||||
| 		                 hcl->code.bc.ptr[mip] == HCL_CODE_MAKE_FUNCTION);  |  | ||||||
| /* TODO: update the tmpr_mask... */ |  | ||||||
| 		patch_double_long_params (hcl, mip + 1, -1, hcl->c->fnblk.info[hcl->c->fnblk.depth].tmprcnt); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	HCL_ASSERT (hcl, hcl->c->cblk.depth == hcl->c->fnblk.info[hcl->c->fnblk.depth].cblk_base);  |  | ||||||
| 	hcl->c->cblk.depth = hcl->c->fnblk.info[hcl->c->fnblk.depth].cblk_base; |  | ||||||
| 	/* keep hcl->code.lit.len without restoration */ | 	/* keep hcl->code.lit.len without restoration */ | ||||||
|  |  | ||||||
| 	hcl->c->fnblk.depth--; | 	hcl->c->fnblk.depth--; | ||||||
| @ -749,6 +746,22 @@ static void pop_fnblk (hcl_t* hcl) | |||||||
| 		hcl->c->tv.s.len = 0; | 		hcl->c->tv.s.len = 0; | ||||||
| 		hcl->c->tv.wcount = 0; | 		hcl->c->tv.wcount = 0; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if (fbi->make_inst_pos < hcl->code.bc.len) | ||||||
|  | 	{ | ||||||
|  | 		hcl_oow_t tmpr_mask; | ||||||
|  |  | ||||||
|  | 		/* patch the temporary mask parameter for the MAKE_BLOCK or MAKE_FUNCTION instruction */ | ||||||
|  | 		HCL_ASSERT (hcl, hcl->code.bc.ptr[fbi->make_inst_pos] == HCL_CODE_MAKE_BLOCK ||  | ||||||
|  | 		                 hcl->code.bc.ptr[fbi->make_inst_pos] == HCL_CODE_MAKE_FUNCTION);  | ||||||
|  |  | ||||||
|  | 		/* the total number of temporaries in this function block must be the sum of  | ||||||
|  | 		 * the number of arguments, return variables and local variables */ | ||||||
|  | 		HCL_ASSERT (hcl, fbi->tmprcnt - hcl->c->tv.wcount == fbi->tmpr_nargs + fbi->tmpr_nrvars + fbi->tmpr_nlvars); | ||||||
|  |  | ||||||
|  | 		tmpr_mask = ENCODE_BLKTMPR_MASK(fbi->tmpr_va, fbi->tmpr_nargs, fbi->tmpr_nrvars, fbi->tmpr_nlvars); | ||||||
|  | 		patch_double_long_params_with_oow (hcl, fbi->make_inst_pos + 1, tmpr_mask); | ||||||
|  | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| static int push_cblk (hcl_t* hcl, const hcl_ioloc_t* errloc, hcl_cblk_type_t type) | static int push_cblk (hcl_t* hcl, const hcl_ioloc_t* errloc, hcl_cblk_type_t type) | ||||||
| @ -1628,7 +1641,7 @@ static int collect_local_vardcl (hcl_t* hcl, hcl_cnode_t* obj, hcl_cnode_t** nex | |||||||
| static int compile_lambda (hcl_t* hcl, hcl_cnode_t* src, int defun) | static int compile_lambda (hcl_t* hcl, hcl_cnode_t* src, int defun) | ||||||
| { | { | ||||||
| 	hcl_cnode_t* cmd, * obj, * args; | 	hcl_cnode_t* cmd, * obj, * args; | ||||||
| 	hcl_oow_t nargs, nlvars, tmpr_mask; | 	hcl_oow_t nargs, nrvars, nlvars; | ||||||
| 	hcl_ooi_t jump_inst_pos, lfbase_pos, lfsize_pos; | 	hcl_ooi_t jump_inst_pos, lfbase_pos, lfsize_pos; | ||||||
| 	hcl_oow_t saved_tv_wcount, tv_dup_start; | 	hcl_oow_t saved_tv_wcount, tv_dup_start; | ||||||
| 	hcl_cnode_t* defun_name; | 	hcl_cnode_t* defun_name; | ||||||
| @ -1759,6 +1772,14 @@ static int compile_lambda (hcl_t* hcl, hcl_cnode_t* src, int defun) | |||||||
| 		return -1; | 		return -1; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	nrvars = 0; /* TODO: support return variables , */ | ||||||
|  | 	if (nrvars > MAX_CODE_NBLKLVARS) | ||||||
|  | 	{ | ||||||
|  | 		hcl_setsynerrbfmt (hcl, HCL_SYNERR_VARFLOOD, HCL_CNODE_GET_LOC(args), HCL_NULL, "too many(%zu) return variables in %.*js", nlvars, HCL_CNODE_GET_TOKLEN(cmd), HCL_CNODE_GET_TOKPTR(cmd));  | ||||||
|  | 		return -1; | ||||||
|  | 	} | ||||||
|  | 	HCL_ASSERT (hcl, nargs + nrvars == hcl->c->tv.wcount - saved_tv_wcount); | ||||||
|  |  | ||||||
| 	obj = HCL_CNODE_CONS_CDR(obj); | 	obj = HCL_CNODE_CONS_CDR(obj); | ||||||
| 	tv_dup_start = hcl->c->tv.s.len; | 	tv_dup_start = hcl->c->tv.s.len; | ||||||
| 	if (collect_local_vardcl(hcl, obj, &obj, tv_dup_start, &nlvars) <= -1) return -1; | 	if (collect_local_vardcl(hcl, obj, &obj, tv_dup_start, &nlvars) <= -1) return -1; | ||||||
| @ -1769,15 +1790,14 @@ static int compile_lambda (hcl_t* hcl, hcl_cnode_t* src, int defun) | |||||||
| 		return -1; | 		return -1; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	HCL_ASSERT (hcl, nargs + nlvars == hcl->c->tv.wcount - saved_tv_wcount); | 	HCL_ASSERT (hcl, nargs + nrvars + nlvars == hcl->c->tv.wcount - saved_tv_wcount); | ||||||
|  |  | ||||||
| 	if (push_fnblk(hcl, HCL_CNODE_GET_LOC(src), 0, nargs, 0, nlvars, hcl->c->tv.wcount, hcl->c->tv.s.len, hcl->code.bc.len, hcl->code.lit.len) <= -1) return -1; | 	if (push_fnblk(hcl, HCL_CNODE_GET_LOC(src), 0, nargs, nrvars, nlvars, hcl->c->tv.wcount, hcl->c->tv.s.len, hcl->code.bc.len, hcl->code.lit.len) <= -1) return -1; | ||||||
| 	 | 	 | ||||||
| 	tmpr_mask = ENCODE_BLKTMPR_MASK(0, nargs, 0, nlvars); |  | ||||||
| 	if (hcl->option.trait & HCL_TRAIT_INTERACTIVE) | 	if (hcl->option.trait & HCL_TRAIT_INTERACTIVE) | ||||||
| 	{ | 	{ | ||||||
| 		/* make_function tmpr_mask lfbase lfsize */ | 		/* MAKE_FUNCTION tmpr_mask_1 tmpr_mask_2 lfbase lfsize */ | ||||||
| 		if (emit_single_param_instruction(hcl, HCL_CODE_MAKE_FUNCTION, tmpr_mask, HCL_CNODE_GET_LOC(cmd)) <= -1) return -1; | 		if (emit_double_param_instruction(hcl, HCL_CODE_MAKE_FUNCTION, 0, 0, HCL_CNODE_GET_LOC(cmd)) <= -1) return -1; | ||||||
| 		lfbase_pos = hcl->code.bc.len; | 		lfbase_pos = hcl->code.bc.len; | ||||||
| 		if (emit_long_param(hcl, hcl->code.lit.len - hcl->c->fnblk.info[hcl->c->fnblk.depth - 1].lfbase) <= -1) return -1; /* literal frame base */ | 		if (emit_long_param(hcl, hcl->code.lit.len - hcl->c->fnblk.info[hcl->c->fnblk.depth - 1].lfbase) <= -1) return -1; /* literal frame base */ | ||||||
| 		lfsize_pos = hcl->code.bc.len; /* literal frame size */ | 		lfsize_pos = hcl->code.bc.len; /* literal frame size */ | ||||||
| @ -1785,7 +1805,8 @@ static int compile_lambda (hcl_t* hcl, hcl_cnode_t* src, int defun) | |||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
| 		if (emit_single_param_instruction(hcl, HCL_CODE_MAKE_BLOCK, tmpr_mask, HCL_CNODE_GET_LOC(cmd)) <= -1) return -1; | 		/* MAKE_BLOCK tmpr_mask_1 tmpr_mask_2 - will patch tmpr_mask in pop_fnblk() */ | ||||||
|  | 		if (emit_double_param_instruction(hcl, HCL_CODE_MAKE_BLOCK, 0, 0, HCL_CNODE_GET_LOC(cmd)) <= -1) return -1; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	HCL_ASSERT (hcl, hcl->code.bc.len < HCL_SMOOI_MAX);  /* guaranteed in emit_byte_instruction() */ | 	HCL_ASSERT (hcl, hcl->code.bc.len < HCL_SMOOI_MAX);  /* guaranteed in emit_byte_instruction() */ | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user