improving find_variable_backward() to resolve instance variables
This commit is contained in:
		
							
								
								
									
										190
									
								
								hcl/lib/comp.c
									
									
									
									
									
								
							
							
						
						
									
										190
									
								
								hcl/lib/comp.c
									
									
									
									
									
								
							| @ -29,29 +29,13 @@ | |||||||
| enum | enum | ||||||
| { | { | ||||||
| 	VAR_NAMED, | 	VAR_NAMED, | ||||||
| 	VAR_INDEXED | 	VAR_INDEXED, | ||||||
|  | 	VAR_INST | ||||||
| }; | }; | ||||||
|  |  | ||||||
| #define TV_BUFFER_ALIGN 256 | #define TV_BUFFER_ALIGN 256 | ||||||
| #define BLK_INFO_BUFFER_ALIGN 128 | #define BLK_INFO_BUFFER_ALIGN 128 | ||||||
|  |  | ||||||
|  |  | ||||||
| struct var_info_t |  | ||||||
| { |  | ||||||
| 	int type; |  | ||||||
|  |  | ||||||
|  |  | ||||||
| 	/* ctx_offset 0 means the current context. |  | ||||||
| 	 *            1 means current->home. |  | ||||||
| 	 *            2 means current->home->home.  |  | ||||||
| 	 * index_in_ctx is a relative index within the context found. |  | ||||||
| 	 */ |  | ||||||
| 	hcl_oow_t ctx_offset; /* context offset */ |  | ||||||
| 	hcl_oow_t index_in_ctx; /* index in the current scope */ |  | ||||||
| }; |  | ||||||
| typedef struct var_info_t var_info_t; |  | ||||||
|  |  | ||||||
|  |  | ||||||
| /* -------------------------------------------- | /* -------------------------------------------- | ||||||
|  |  | ||||||
|                                                       |                                                       | ||||||
| @ -224,48 +208,10 @@ static int find_temporary_variable_backward (hcl_t* hcl, const hcl_oocs_t* name, | |||||||
| 	return __find_word_in_string(&hcl->c->tv.s, name, 1, index); | 	return __find_word_in_string(&hcl->c->tv.s, name, 1, index); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static int find_variable_backward (hcl_t* hcl, const hcl_oocs_t* name, hcl_var_info_t* vi) | ||||||
|  |  | ||||||
|  |  | ||||||
| #if 0 |  | ||||||
| 	HCL_ASSERT (hcl, hcl->c->fnblk.depth >= 0); |  | ||||||
| 	fbi = &hcl->c->fnblk.info[hcl->c->fnblk.depth]; |  | ||||||
|  |  | ||||||
| 	/* if a temporary variable is accessed inside a block, |  | ||||||
| 	 * use a special instruction to indicate it */ |  | ||||||
| 	HCL_ASSERT (hcl, index < fbi->tmprcnt); |  | ||||||
| 	for (i = hcl->c->fnblk.depth; i >= 0; i--) |  | ||||||
| 	{ |  | ||||||
| 		hcl_oow_t parent_tmprcnt; |  | ||||||
|  |  | ||||||
| 		parent_tmprcnt = (i > 0)? hcl->c->fnblk.info[i - 1].tmprcnt: 0; |  | ||||||
| 		if (index >= parent_tmprcnt) |  | ||||||
| 		{ |  | ||||||
| 			hcl_oow_t ctx_offset, index_in_ctx; |  | ||||||
| 			ctx_offset = hcl->c->fnblk.depth - i; |  | ||||||
| 			index_in_ctx = index - parent_tmprcnt; |  | ||||||
| 			/* ctx_offset 0 means the current context. |  | ||||||
| 			 *            1 means current->home. |  | ||||||
| 			 *            2 means current->home->home.  |  | ||||||
| 			 * index_in_ctx is a relative index within the context found. |  | ||||||
| 			 */ |  | ||||||
| 			if (emit_double_param_instruction(hcl, baseinst1, ctx_offset, index_in_ctx, srcloc) <= -1) return -1; |  | ||||||
| 			if (ctx_offset > 0)  |  | ||||||
| 			{ |  | ||||||
| 				fbi->access_outer = 1; /* the current function block accesses temporaries in an outer function block */ |  | ||||||
| 				hcl->c->fnblk.info[i].accessed_by_inner = 1; /* temporaries in an outer function block is accessed by the current function block */ |  | ||||||
| 			} |  | ||||||
| 			return 0; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| static int find_variable_backward (hcl_t* hcl, const hcl_oocs_t* name, var_info_t* vi) |  | ||||||
| { | { | ||||||
| 	hcl_fnblk_info_t* fbi; | 	hcl_oow_t i; | ||||||
| 	hcl_oow_t parent_tmprcnt, parent_tmprlen; | 	 | ||||||
| 	hcl_oow_t i, index; |  | ||||||
| 	hcl_oocs_t haystack; |  | ||||||
|  |  | ||||||
| 	HCL_ASSERT (hcl, hcl->c->fnblk.depth >= 0); | 	HCL_ASSERT (hcl, hcl->c->fnblk.depth >= 0); | ||||||
| 	HCL_ASSERT (hcl, hcl->c->fnblk.info[hcl->c->fnblk.depth].tmprlen == hcl->c->tv.s.len); | 	HCL_ASSERT (hcl, hcl->c->fnblk.info[hcl->c->fnblk.depth].tmprlen == hcl->c->tv.s.len); | ||||||
| @ -274,7 +220,31 @@ static int find_variable_backward (hcl_t* hcl, const hcl_oocs_t* name, var_info_ | |||||||
| 	 * to avoid an extra exit check without it */ | 	 * to avoid an extra exit check without it */ | ||||||
| 	for (i = hcl->c->fnblk.depth + 1; i > 0; ) | 	for (i = hcl->c->fnblk.depth + 1; i > 0; ) | ||||||
| 	{ | 	{ | ||||||
|  | 		hcl_fnblk_info_t* fbi; | ||||||
|  | 		hcl_oocs_t haystack; | ||||||
|  | 		hcl_oow_t parent_tmprcnt, parent_tmprlen, index; | ||||||
|  |  | ||||||
| 		fbi = &hcl->c->fnblk.info[--i]; | 		fbi = &hcl->c->fnblk.info[--i]; | ||||||
|  |  | ||||||
|  | 		if (fbi->clsblk_top >= 0) | ||||||
|  | 		{ | ||||||
|  | 			/* this function block has a class defined */ | ||||||
|  | 			hcl_clsblk_info_t* clsbi; | ||||||
|  |  | ||||||
|  | 			clsbi = &hcl->c->clsblk.info[fbi->clsblk_top]; | ||||||
|  |  | ||||||
|  | 			haystack.ptr = clsbi->ivars_str; | ||||||
|  | 			haystack.len = hcl_count_oocstr(clsbi->ivars_str); | ||||||
|  | 			if (__find_word_in_string(&haystack, name, 1, &index) >= 0) | ||||||
|  | 			{ | ||||||
|  | 				vi->type = VAR_INST; | ||||||
|  | 				vi->ctx_offset = 0; | ||||||
|  | 				vi->index_in_ctx = index; | ||||||
|  | HCL_INFO4 (hcl, "FOUND INST VAR ...[%.*js]................ ===> ctx_offset %d index %d\n", name->len, name->ptr, (int)(vi->ctx_offset), (int)vi->index_in_ctx); | ||||||
|  | 			} | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  |  | ||||||
| 		if (HCL_LIKELY(i > 0)) | 		if (HCL_LIKELY(i > 0)) | ||||||
| 		{ | 		{ | ||||||
| 			parent_tmprlen = hcl->c->fnblk.info[i - 1].tmprlen; | 			parent_tmprlen = hcl->c->fnblk.info[i - 1].tmprlen; | ||||||
| @ -296,8 +266,7 @@ static int find_variable_backward (hcl_t* hcl, const hcl_oocs_t* name, var_info_ | |||||||
| 			vi->type = VAR_INDEXED; | 			vi->type = VAR_INDEXED; | ||||||
| 			vi->ctx_offset = hcl->c->fnblk.depth - i; /* context offset */ | 			vi->ctx_offset = hcl->c->fnblk.depth - i; /* context offset */ | ||||||
| 			vi->index_in_ctx = index; | 			vi->index_in_ctx = index; | ||||||
| HCL_INFO4 (hcl, "FOUND ...[%.*js]................ ===> ctx_offset %d index %d\n", name->len, name->ptr, (int)(vi->ctx_offset), (int)vi->index_in_ctx); | //HCL_INFO4 (hcl, "FOUND ...[%.*js]................ ===> ctx_offset %d index %d\n", name->len, name->ptr, (int)(vi->ctx_offset), (int)vi->index_in_ctx); | ||||||
|  |  | ||||||
|  |  | ||||||
| 			if (vi->ctx_offset > 0) | 			if (vi->ctx_offset > 0) | ||||||
| 			{ | 			{ | ||||||
| @ -311,7 +280,7 @@ HCL_INFO4 (hcl, "FOUND ...[%.*js]................ ===> ctx_offset %d index %d\n" | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| HCL_INFO2 (hcl, "NOT FOUND => %.*js\n", name->len, name->ptr); | //HCL_INFO2 (hcl, "NOT FOUND => %.*js\n", name->len, name->ptr); | ||||||
| 	return -1; | 	return -1; | ||||||
| } | } | ||||||
|  |  | ||||||
| @ -598,7 +567,7 @@ write_short: | |||||||
| write_long: | write_long: | ||||||
| 	if (param_1 > MAX_CODE_PARAM || param_2 > MAX_CODE_PARAM) | 	if (param_1 > MAX_CODE_PARAM || param_2 > MAX_CODE_PARAM) | ||||||
| 	{ | 	{ | ||||||
| 		hcl_seterrbfmt (hcl, HCL_ERANGE, "parameter too large to double-parameter instruction %u", (unsigned int)cmd); | 		hcl_seterrbfmt (hcl, HCL_ERANGE, "parameter too large to double-parameter instruction 0x%u - param_1 0x%zu param_2 0x%zu", (unsigned int)cmd, param_1, param_2); | ||||||
| 		return -1; | 		return -1; | ||||||
| 	} | 	} | ||||||
| #if (HCL_CODE_LONG_PARAM_SIZE == 2) | #if (HCL_CODE_LONG_PARAM_SIZE == 2) | ||||||
| @ -746,6 +715,7 @@ static HCL_INLINE void patch_double_long_params_with_oow (hcl_t* hcl, hcl_ooi_t | |||||||
| #endif | #endif | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #if 0 | ||||||
| static int emit_indexed_variable_access (hcl_t* hcl, hcl_oow_t index, hcl_oob_t baseinst1, hcl_oob_t baseinst2, const hcl_ioloc_t* srcloc) | static int emit_indexed_variable_access (hcl_t* hcl, hcl_oow_t index, hcl_oob_t baseinst1, hcl_oob_t baseinst2, const hcl_ioloc_t* srcloc) | ||||||
| { | { | ||||||
| 	hcl_oow_t i; | 	hcl_oow_t i; | ||||||
| @ -787,6 +757,14 @@ static int emit_indexed_variable_access (hcl_t* hcl, hcl_oow_t index, hcl_oob_t | |||||||
| 	if (emit_single_param_instruction(hcl, baseinst2, index, srcloc) <= -1) return -1; | 	if (emit_single_param_instruction(hcl, baseinst2, index, srcloc) <= -1) return -1; | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  | #else | ||||||
|  | static int emit_indexed_variable_access (hcl_t* hcl, hcl_oob_t baseinst, const hcl_var_info_t* vi, const hcl_ioloc_t* srcloc) | ||||||
|  | { | ||||||
|  | 	HCL_ASSERT (hcl, vi->type == VAR_INDEXED); | ||||||
|  | 	/* baseinst - HCL_CODE_PUSH_CTXTEMPVAR_0, HCL_CODE_POP_INTO_CTXTEMPVAR_0, HCL_CODE_STORE_INTO_CTXTEMPVAR_0 */ | ||||||
|  | 	return emit_double_param_instruction(hcl, baseinst, vi->ctx_offset, vi->index_in_ctx, srcloc); | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  |  | ||||||
| #if 0 | #if 0 | ||||||
| static int emit_instance_variable_access (hcl_t* hcl, hcl_oow_t index, hcl_oob_t baseinst1, hcl_oob_t baseinst2, const hcl_ioloc_t* srcloc) | static int emit_instance_variable_access (hcl_t* hcl, hcl_oow_t index, hcl_oob_t baseinst1, hcl_oob_t baseinst2, const hcl_ioloc_t* srcloc) | ||||||
| @ -796,9 +774,7 @@ static int emit_instance_variable_access (hcl_t* hcl, hcl_oow_t index, hcl_oob_t | |||||||
| 		/* inside a class context */ | 		/* inside a class context */ | ||||||
| 		hcl_clsblk_info_t* cbi; | 		hcl_clsblk_info_t* cbi; | ||||||
| 		HCL_ASSERT (hcl, fbi->clsblk_base >= 0 && fbi->clsblk_base <= fbi->clsblk_top); | 		HCL_ASSERT (hcl, fbi->clsblk_base >= 0 && fbi->clsblk_base <= fbi->clsblk_top); | ||||||
|  |  | ||||||
| 		cbi = &hcl->c->clsblk.info[fbi->clsblk_top]; /* can only find the self variable?? */ | 		cbi = &hcl->c->clsblk.info[fbi->clsblk_top]; /* can only find the self variable?? */ | ||||||
| 		 |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return 0; | 	return 0; | ||||||
| @ -2109,26 +2085,22 @@ static HCL_INLINE int compile_class_p2 (hcl_t* hcl) | |||||||
| 		 * the block has been exited(blk.depth--) before finding 'x' in the outer scope. | 		 * the block has been exited(blk.depth--) before finding 'x' in the outer scope. | ||||||
| 		 */ | 		 */ | ||||||
| 		hcl_cnode_t* class_name = cf->operand; | 		hcl_cnode_t* class_name = cf->operand; | ||||||
|  | 		hcl_var_info_t vi; | ||||||
|  |  | ||||||
| 		hcl_oow_t index; | 		if (find_variable_backward(hcl, HCL_CNODE_GET_TOK(defun_name), &vi) <= -1) | ||||||
|  |  | ||||||
|  |  | ||||||
| 		if (find_temporary_variable_backward(hcl, HCL_CNODE_GET_TOK(defun_name), &index) <= -1) |  | ||||||
| 		{ | 		{ | ||||||
| 			SWITCH_TOP_CFRAME (hcl, COP_EMIT_SET, defun_name); | 			SWITCH_TOP_CFRAME (hcl, COP_EMIT_SET, defun_name); | ||||||
| 			cf = GET_TOP_CFRAME(hcl); | 			cf = GET_TOP_CFRAME(hcl); | ||||||
| 			cf->u.set.var_type = VAR_NAMED; | 			cf->u.set.vi.type = VAR_NAMED; | ||||||
| 		} | 		} | ||||||
| 		else | 		else | ||||||
| 		{ | 		{ | ||||||
| 			HCL_ASSERT (hcl, index <= HCL_SMOOI_MAX);  | 			HCL_ASSERT (hcl, index <= HCL_SMOOI_MAX);  | ||||||
| 			SWITCH_TOP_CFRAME (hcl, COP_EMIT_SET, defun_name);  | 			SWITCH_TOP_CFRAME (hcl, COP_EMIT_SET, defun_name);  | ||||||
| 			cf = GET_TOP_CFRAME(hcl); | 			cf = GET_TOP_CFRAME(hcl); | ||||||
| 			cf->u.set.var_type = VAR_INDEXED; | 			cf->u.set.vi = vi; | ||||||
| 			cf->u.set.index = index; |  | ||||||
| 		} | 		} | ||||||
| 		cf->u.set.pop = 0; | 		cf->u.set.pop = 0; | ||||||
|  |  | ||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
| @ -2138,7 +2110,6 @@ static HCL_INLINE int compile_class_p2 (hcl_t* hcl) | |||||||
| /* should i make the assignment in POST?  or after variable declarations immediately? */ | /* should i make the assignment in POST?  or after variable declarations immediately? */ | ||||||
| /* TODO: emit instruction to store into the class name...? */ | /* TODO: emit instruction to store into the class name...? */ | ||||||
| /* TODO: NEED TO EMIT POP_STACKTOP???? IN THIS CASE CLASS_EXIT MUST PUSH SOMETHING? */ | /* TODO: NEED TO EMIT POP_STACKTOP???? IN THIS CASE CLASS_EXIT MUST PUSH SOMETHING? */ | ||||||
|  |  | ||||||
| 	if (emit_byte_instruction(hcl, HCL_CODE_CLASS_EXIT, HCL_CNODE_GET_LOC(cf->operand)) <= -1) return -1; | 	if (emit_byte_instruction(hcl, HCL_CODE_CLASS_EXIT, HCL_CNODE_GET_LOC(cf->operand)) <= -1) return -1; | ||||||
| 	printf ("end of CLASS DEFINITION\n"); | 	printf ("end of CLASS DEFINITION\n"); | ||||||
| 	POP_CFRAME (hcl); | 	POP_CFRAME (hcl); | ||||||
| @ -2483,7 +2454,7 @@ static int compile_set (hcl_t* hcl, hcl_cnode_t* src) | |||||||
| 	hcl_cframe_t* cf; | 	hcl_cframe_t* cf; | ||||||
| 	hcl_cnode_t* cmd, * obj, * var, * val; | 	hcl_cnode_t* cmd, * obj, * var, * val; | ||||||
| 	hcl_oow_t index; | 	hcl_oow_t index; | ||||||
| 	var_info_t vi; | 	hcl_var_info_t vi; | ||||||
|  |  | ||||||
| 	HCL_ASSERT (hcl, HCL_CNODE_IS_CONS(src)); | 	HCL_ASSERT (hcl, HCL_CNODE_IS_CONS(src)); | ||||||
| 	HCL_ASSERT (hcl, HCL_CNODE_IS_SYMBOL_SYNCODED(HCL_CNODE_CONS_CAR(src), HCL_SYNCODE_SET)); | 	HCL_ASSERT (hcl, HCL_CNODE_IS_SYMBOL_SYNCODED(HCL_CNODE_CONS_CAR(src), HCL_SYNCODE_SET)); | ||||||
| @ -2538,12 +2509,11 @@ static int compile_set (hcl_t* hcl, hcl_cnode_t* src) | |||||||
|  |  | ||||||
| 	SWITCH_TOP_CFRAME (hcl, COP_COMPILE_OBJECT, val); | 	SWITCH_TOP_CFRAME (hcl, COP_COMPILE_OBJECT, val); | ||||||
|  |  | ||||||
| 	//if (find_temporary_variable_backward(hcl, HCL_CNODE_GET_TOK(var), &index) <= -1) | 	if (find_variable_backward(hcl, HCL_CNODE_GET_TOK(var), &vi) <= -1) | ||||||
| 	if (find_temporary_variable_backward(hcl, HCL_CNODE_GET_TOK(var), &vi) <= -1) |  | ||||||
| 	{ | 	{ | ||||||
| 		PUSH_SUBCFRAME (hcl, COP_EMIT_SET, var); /* set doesn't evaluate the variable name */ | 		PUSH_SUBCFRAME (hcl, COP_EMIT_SET, var); /* set doesn't evaluate the variable name */ | ||||||
| 		cf = GET_SUBCFRAME(hcl); | 		cf = GET_SUBCFRAME(hcl); | ||||||
| 		cf->u.set.var_type = VAR_NAMED; | 		cf->u.set.vi.type = VAR_NAMED; | ||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
| @ -2552,9 +2522,7 @@ static int compile_set (hcl_t* hcl, hcl_cnode_t* src) | |||||||
|  |  | ||||||
| 		PUSH_SUBCFRAME (hcl, COP_EMIT_SET, cmd);  | 		PUSH_SUBCFRAME (hcl, COP_EMIT_SET, cmd);  | ||||||
| 		cf = GET_SUBCFRAME(hcl); | 		cf = GET_SUBCFRAME(hcl); | ||||||
| 		cf->u.set.var_type = VAR_INDEXED; | 		cf->u.set.vi = vi; | ||||||
| 		cf->u.set.ctx_offset = vi.ctx_offset; |  | ||||||
| 		cf->u.set.index_in_ctx = vi.index_in_ctx; |  | ||||||
| 	} | 	} | ||||||
| 	cf->u.set.pop = 0; | 	cf->u.set.pop = 0; | ||||||
|  |  | ||||||
| @ -2566,7 +2534,7 @@ static int compile_set_r (hcl_t* hcl, hcl_cnode_t* src) | |||||||
| 	hcl_cframe_t* cf; | 	hcl_cframe_t* cf; | ||||||
| 	hcl_cnode_t* cmd, * obj, * var, * val, * var_start; | 	hcl_cnode_t* cmd, * obj, * var, * val, * var_start; | ||||||
| 	hcl_oow_t index, nvars, i; | 	hcl_oow_t index, nvars, i; | ||||||
| 	var_info_t vi; | 	hcl_var_info_t vi; | ||||||
|  |  | ||||||
| 	HCL_ASSERT (hcl, HCL_CNODE_IS_CONS(src)); | 	HCL_ASSERT (hcl, HCL_CNODE_IS_CONS(src)); | ||||||
| 	HCL_ASSERT (hcl, HCL_CNODE_IS_SYMBOL_SYNCODED(HCL_CNODE_CONS_CAR(src), HCL_SYNCODE_SET_R)); | 	HCL_ASSERT (hcl, HCL_CNODE_IS_SYMBOL_SYNCODED(HCL_CNODE_CONS_CAR(src), HCL_SYNCODE_SET_R)); | ||||||
| @ -2636,25 +2604,21 @@ static int compile_set_r (hcl_t* hcl, hcl_cnode_t* src) | |||||||
| 	for (i  = 0, obj = var_start; i < nvars; i++, obj = HCL_CNODE_CONS_CDR(obj)) | 	for (i  = 0, obj = var_start; i < nvars; i++, obj = HCL_CNODE_CONS_CDR(obj)) | ||||||
| 	{ | 	{ | ||||||
| 		var = HCL_CNODE_CONS_CAR(obj); | 		var = HCL_CNODE_CONS_CAR(obj); | ||||||
| 		//if (find_temporary_variable_backward(hcl, HCL_CNODE_GET_TOK(var), &index) <= -1) |  | ||||||
| 		if (find_temporary_variable_backward(hcl, HCL_CNODE_GET_TOK(var), &vi) <= -1) | 		if (find_variable_backward(hcl, HCL_CNODE_GET_TOK(var), &vi) <= -1) | ||||||
| 		{ | 		{ | ||||||
| 			PUSH_SUBCFRAME (hcl, COP_EMIT_SET, var); /* set_r doesn't evaluate the variable name */ | 			PUSH_SUBCFRAME (hcl, COP_EMIT_SET, var); /* set_r doesn't evaluate the variable name */ | ||||||
| 			cf = GET_SUBCFRAME(hcl); | 			cf = GET_SUBCFRAME(hcl); | ||||||
| 			cf->u.set.var_type = VAR_NAMED; | 			cf->u.set.vi.type = VAR_NAMED; | ||||||
| 		} | 		} | ||||||
| 		else | 		else | ||||||
| 		{ | 		{ | ||||||
| 			/* the check in compile_lambda() must ensure this condition */ | 			/* the check in compile_lambda() must ensure this condition */ | ||||||
| 			HCL_ASSERT (hcl, index <= HCL_SMOOI_MAX); | 			HCL_ASSERT (hcl, index <= HCL_SMOOI_MAX); | ||||||
|  |  | ||||||
| 			PUSH_SUBCFRAME (hcl, COP_EMIT_SET, cmd);  | 			PUSH_SUBCFRAME (hcl, COP_EMIT_SET, cmd);  | ||||||
| 			cf = GET_SUBCFRAME(hcl); | 			cf = GET_SUBCFRAME(hcl); | ||||||
| 			cf->u.set.var_type = VAR_INDEXED; | 			cf->u.set.vi = vi; | ||||||
| 			cf->u.set.ctx_offset = vi.ctx_offset; |  | ||||||
| 			cf->u.set.index_in_ctx = vi.index_in_ctx; |  | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		cf->u.set.pop = (i > 0); /* STORE_INTO or POP_INTO  */ | 		cf->u.set.pop = (i > 0); /* STORE_INTO or POP_INTO  */ | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @ -2757,7 +2721,8 @@ static HCL_INLINE int compile_catch (hcl_t* hcl) | |||||||
| 	hcl_cnode_t* cmd, * obj, * src, * exarg; | 	hcl_cnode_t* cmd, * obj, * src, * exarg; | ||||||
| 	hcl_cframe_t* cf; | 	hcl_cframe_t* cf; | ||||||
| 	hcl_ooi_t jump_inst_pos; | 	hcl_ooi_t jump_inst_pos; | ||||||
| 	hcl_oow_t exarg_offset, exarg_index; | 	hcl_oow_t exarg_offset; | ||||||
|  | 	hcl_var_info_t vi; | ||||||
| 	hcl_fnblk_info_t* fbi; | 	hcl_fnblk_info_t* fbi; | ||||||
|  |  | ||||||
| 	cf = GET_TOP_CFRAME(hcl); | 	cf = GET_TOP_CFRAME(hcl); | ||||||
| @ -2798,12 +2763,18 @@ static HCL_INLINE int compile_catch (hcl_t* hcl) | |||||||
|  |  | ||||||
| 	/* add the exception variable to the local variable list. increase the number of local variables */ | 	/* add the exception variable to the local variable list. increase the number of local variables */ | ||||||
| 	exarg_offset = hcl->c->tv.s.len + 1; /* when the variable name is added, its offset will be the current length + 1 for a space character added */ | 	exarg_offset = hcl->c->tv.s.len + 1; /* when the variable name is added, its offset will be the current length + 1 for a space character added */ | ||||||
| 	exarg_index = hcl->c->tv.wcount; |  | ||||||
|  | 	/* fill the variable information structure as if it's found by find_variable_backward(). | ||||||
|  | 	 * we know it's the last variable as add_temporary_variable() is called below.  | ||||||
|  | 	 * there is no need to call find_variable_backward() */ | ||||||
|  | 	vi.type = VAR_INDEXED; | ||||||
|  | 	vi.ctx_offset = 0; | ||||||
|  | 	vi.index_in_ctx = hcl->c->tv.wcount; | ||||||
| 	if (add_temporary_variable(hcl, HCL_CNODE_GET_TOK(exarg), hcl->c->tv.s.len) <= -1) return -1; | 	if (add_temporary_variable(hcl, HCL_CNODE_GET_TOK(exarg), hcl->c->tv.s.len) <= -1) return -1; | ||||||
|  |  | ||||||
| 	fbi = &hcl->c->fnblk.info[hcl->c->fnblk.depth]; | 	fbi = &hcl->c->fnblk.info[hcl->c->fnblk.depth]; | ||||||
| 	HCL_ASSERT (hcl, fbi->tmprlen == hcl->c->tv.s.len - HCL_CNODE_GET_TOKLEN(exarg) - 1); | 	HCL_ASSERT (hcl, fbi->tmprlen == hcl->c->tv.s.len - HCL_CNODE_GET_TOKLEN(exarg) - 1); | ||||||
| 	HCL_ASSERT (hcl, fbi->tmprcnt == exarg_index); | 	HCL_ASSERT (hcl, fbi->tmprcnt == vi.index_in_ctx); | ||||||
| 	fbi->tmprlen = hcl->c->tv.s.len; | 	fbi->tmprlen = hcl->c->tv.s.len; | ||||||
| 	fbi->tmprcnt = hcl->c->tv.wcount; | 	fbi->tmprcnt = hcl->c->tv.wcount; | ||||||
| 	fbi->tmpr_nlvars = fbi->tmpr_nlvars + 1; | 	fbi->tmpr_nlvars = fbi->tmpr_nlvars + 1; | ||||||
| @ -2815,8 +2786,7 @@ static HCL_INLINE int compile_catch (hcl_t* hcl) | |||||||
| 	patch_nearest_post_try (hcl, &jump_inst_pos);  | 	patch_nearest_post_try (hcl, &jump_inst_pos);  | ||||||
|  |  | ||||||
| 	/* produce an instruction to store the exception value to an exception variable pushed by the 'throw' instruction */ | 	/* produce an instruction to store the exception value to an exception variable pushed by the 'throw' instruction */ | ||||||
| 	//if (emit_indexed_variable_access(hcl, exarg_index, HCL_CODE_POP_INTO_CTXTEMPVAR_0, HCL_CODE_POP_INTO_TEMPVAR_0, HCL_CNODE_GET_LOC(src)) <= -1) return -1; | 	if (emit_indexed_variable_access(hcl, HCL_CODE_POP_INTO_CTXTEMPVAR_0, &vi, HCL_CNODE_GET_LOC(src)) <= -1) return -1; | ||||||
| 	if (emit_double_param_instruction(hcl, HCL_CODE_POP_INTO_CTXTEMPVAR_0, 0, exarg_index, HCL_CNODE_GET_LOC(src)) <= -1) return -1; |  | ||||||
|  |  | ||||||
| 	SWITCH_TOP_CFRAME (hcl, COP_COMPILE_OBJECT_LIST, obj); | 	SWITCH_TOP_CFRAME (hcl, COP_COMPILE_OBJECT_LIST, obj); | ||||||
|  |  | ||||||
| @ -3262,7 +3232,7 @@ static int compile_cons_xlist_expression (hcl_t* hcl, hcl_cnode_t* obj, int nret | |||||||
|  |  | ||||||
| static HCL_INLINE int compile_symbol (hcl_t* hcl, hcl_cnode_t* obj) | static HCL_INLINE int compile_symbol (hcl_t* hcl, hcl_cnode_t* obj) | ||||||
| { | { | ||||||
| 	var_info_t vi; | 	hcl_var_info_t vi; | ||||||
|  |  | ||||||
| 	HCL_ASSERT (hcl, HCL_CNODE_IS_SYMBOL(obj)); | 	HCL_ASSERT (hcl, HCL_CNODE_IS_SYMBOL(obj)); | ||||||
|  |  | ||||||
| @ -3273,7 +3243,6 @@ static HCL_INLINE int compile_symbol (hcl_t* hcl, hcl_cnode_t* obj) | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	/* check if a symbol is a local variable */ | 	/* check if a symbol is a local variable */ | ||||||
| 	//if (find_temporary_variable_backward(hcl, HCL_CNODE_GET_TOK(obj), &index) <= -1) |  | ||||||
| 	if (find_variable_backward(hcl, HCL_CNODE_GET_TOK(obj), &vi) <= -1) | 	if (find_variable_backward(hcl, HCL_CNODE_GET_TOK(obj), &vi) <= -1) | ||||||
| 	{ | 	{ | ||||||
| 		hcl_oop_t sym, cons; | 		hcl_oop_t sym, cons; | ||||||
| @ -3299,8 +3268,8 @@ static HCL_INLINE int compile_symbol (hcl_t* hcl, hcl_cnode_t* obj) | |||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
| 		//return emit_indexed_variable_access(hcl, index, HCL_CODE_PUSH_CTXTEMPVAR_0, HCL_CODE_PUSH_TEMPVAR_0, HCL_CNODE_GET_LOC(obj)); | 		HCL_ASSERT (hcl, vi.type == VAR_INDEXED); | ||||||
| 		return emit_double_param_instruction(hcl, HCL_CODE_PUSH_CTXTEMPVAR_0, vi.ctx_offset, vi.index_in_ctx, HCL_CNODE_GET_LOC(obj)); | 		return emit_indexed_variable_access(hcl, HCL_CODE_PUSH_CTXTEMPVAR_0, &vi, HCL_CNODE_GET_LOC(obj)); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| @ -4407,23 +4376,20 @@ static HCL_INLINE int post_lambda (hcl_t* hcl) | |||||||
| 		 */ | 		 */ | ||||||
| 		hcl_cnode_t* defun_name = cf->operand; | 		hcl_cnode_t* defun_name = cf->operand; | ||||||
| 		hcl_oow_t index; | 		hcl_oow_t index; | ||||||
| 		var_info_t vi; | 		hcl_var_info_t vi; | ||||||
|  |  | ||||||
| 		//if (find_temporary_variable_backward(hcl, HCL_CNODE_GET_TOK(defun_name), &index) <= -1) |  | ||||||
| 		if (find_variable_backward(hcl, HCL_CNODE_GET_TOK(defun_name), &vi) <= -1) | 		if (find_variable_backward(hcl, HCL_CNODE_GET_TOK(defun_name), &vi) <= -1) | ||||||
| 		{ | 		{ | ||||||
| 			SWITCH_TOP_CFRAME (hcl, COP_EMIT_SET, defun_name); | 			SWITCH_TOP_CFRAME (hcl, COP_EMIT_SET, defun_name); | ||||||
| 			cf = GET_TOP_CFRAME(hcl); | 			cf = GET_TOP_CFRAME(hcl); | ||||||
| 			cf->u.set.var_type = VAR_NAMED; | 			cf->u.set.vi.type = VAR_NAMED; | ||||||
| 		} | 		} | ||||||
| 		else | 		else | ||||||
| 		{ | 		{ | ||||||
| 			HCL_ASSERT (hcl, index <= HCL_SMOOI_MAX);  | 			HCL_ASSERT (hcl, index <= HCL_SMOOI_MAX);  | ||||||
| 			SWITCH_TOP_CFRAME (hcl, COP_EMIT_SET, defun_name);  | 			SWITCH_TOP_CFRAME (hcl, COP_EMIT_SET, defun_name);  | ||||||
| 			cf = GET_TOP_CFRAME(hcl); | 			cf = GET_TOP_CFRAME(hcl); | ||||||
| 			cf->u.set.var_type = VAR_INDEXED; | 			cf->u.set.vi = vi; | ||||||
| 			cf->u.set.ctx_offset = vi.ctx_offset; |  | ||||||
| 			cf->u.set.index_in_ctx = vi.index_in_ctx; |  | ||||||
| 		} | 		} | ||||||
| 		cf->u.set.pop = 0; | 		cf->u.set.pop = 0; | ||||||
| 	} | 	} | ||||||
| @ -4474,7 +4440,7 @@ static HCL_INLINE int emit_set (hcl_t* hcl) | |||||||
| 	cf = GET_TOP_CFRAME(hcl); | 	cf = GET_TOP_CFRAME(hcl); | ||||||
| 	HCL_ASSERT (hcl, cf->opcode == COP_EMIT_SET); | 	HCL_ASSERT (hcl, cf->opcode == COP_EMIT_SET); | ||||||
|  |  | ||||||
| 	if (cf->u.set.var_type == VAR_NAMED) | 	if (cf->u.set.vi.type == VAR_NAMED) | ||||||
| 	{ | 	{ | ||||||
| 		hcl_oow_t index; | 		hcl_oow_t index; | ||||||
| 		hcl_oop_t cons, sym; | 		hcl_oop_t cons, sym; | ||||||
| @ -4496,22 +4462,18 @@ static HCL_INLINE int emit_set (hcl_t* hcl) | |||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
| 		HCL_ASSERT (hcl, cf->u.set.var_type == VAR_INDEXED); | 		HCL_ASSERT (hcl, cf->u.set.vi.type == VAR_INDEXED); | ||||||
| 		HCL_ASSERT (hcl, cf->operand != HCL_NULL); | 		HCL_ASSERT (hcl, cf->operand != HCL_NULL); | ||||||
| 		//if (emit_indexed_variable_access(hcl, cf->u.set.index_in_ctx,  |  | ||||||
| 		//	(cf->u.set.pop? HCL_CODE_POP_INTO_CTXTEMPVAR_0: HCL_CODE_STORE_INTO_CTXTEMPVAR_0), | 		if (emit_indexed_variable_access(hcl,  | ||||||
| 		//	(cf->u.set.pop? HCL_CODE_POP_INTO_TEMPVAR_0: HCL_CODE_STORE_INTO_TEMPVAR_0), |  | ||||||
| 		//	HCL_CNODE_GET_LOC(cf->operand)) <= -1) return -1; |  | ||||||
| 		if (emit_double_param_instruction(hcl,  |  | ||||||
| 			(cf->u.set.pop? HCL_CODE_POP_INTO_CTXTEMPVAR_0: HCL_CODE_STORE_INTO_CTXTEMPVAR_0), | 			(cf->u.set.pop? HCL_CODE_POP_INTO_CTXTEMPVAR_0: HCL_CODE_STORE_INTO_CTXTEMPVAR_0), | ||||||
| 			cf->u.set.ctx_offset, cf->u.set.index_in_ctx, HCL_CNODE_GET_LOC(cf->operand)) <= -1) return -1; | 			&cf->u.set.vi, HCL_CNODE_GET_LOC(cf->operand)) <= -1) return -1; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	POP_CFRAME (hcl); | 	POP_CFRAME (hcl); | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| static HCL_INLINE int emit_throw (hcl_t* hcl) | static HCL_INLINE int emit_throw (hcl_t* hcl) | ||||||
| { | { | ||||||
| 	hcl_cframe_t* cf; | 	hcl_cframe_t* cf; | ||||||
|  | |||||||
| @ -276,6 +276,20 @@ struct hcl_cnode_t | |||||||
| 	} u; | 	} u; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | struct hcl_var_info_t | ||||||
|  | { | ||||||
|  | 	int type; | ||||||
|  | 	/* ctx_offset 0 means the current context. | ||||||
|  | 	 *            1 means current->home. | ||||||
|  | 	 *            2 means current->home->home.  | ||||||
|  | 	 * index_in_ctx is a relative index within the context found. | ||||||
|  | 	 */ | ||||||
|  | 	hcl_oow_t ctx_offset; /* context offset */ | ||||||
|  | 	hcl_oow_t index_in_ctx; /* index in the current scope */ | ||||||
|  | }; | ||||||
|  | typedef struct hcl_var_info_t hcl_var_info_t; | ||||||
|  |  | ||||||
|  |  | ||||||
| /* NOTE: hcl_cframe_t used by the built-in compiler is not an OOP object */ | /* NOTE: hcl_cframe_t used by the built-in compiler is not an OOP object */ | ||||||
| struct hcl_cframe_t | struct hcl_cframe_t | ||||||
| { | { | ||||||
| @ -301,9 +315,7 @@ struct hcl_cframe_t | |||||||
| 		struct | 		struct | ||||||
| 		{ | 		{ | ||||||
| 			int pop; | 			int pop; | ||||||
| 			int var_type; | 			hcl_var_info_t vi; | ||||||
| 			hcl_ooi_t ctx_offset; |  | ||||||
| 			hcl_ooi_t index_in_ctx; |  | ||||||
| 		} set; | 		} set; | ||||||
|  |  | ||||||
| 		struct | 		struct | ||||||
| @ -362,7 +374,6 @@ struct hcl_cframe_t | |||||||
| 			hcl_ooi_t index; | 			hcl_ooi_t index; | ||||||
| 		} dic_list; | 		} dic_list; | ||||||
|  |  | ||||||
|  |  | ||||||
| 		/* COP_EMIT_LAMBDA */ | 		/* COP_EMIT_LAMBDA */ | ||||||
| 		struct | 		struct | ||||||
| 		{ | 		{ | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user