fixing compiler bugs regarding MAKE_FUNCTION and literal frame rebasing
This commit is contained in:
		| @ -1160,6 +1160,7 @@ hcl_logufmt (hcl, HCL_LOG_WARN, fmt, ustr, 0x6789); | |||||||
| } | } | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | #if 1 | ||||||
| 	if (xtn->reader_istty) | 	if (xtn->reader_istty) | ||||||
| 	{ | 	{ | ||||||
| 		hcl_bitmask_t trait; | 		hcl_bitmask_t trait; | ||||||
| @ -1174,6 +1175,7 @@ else | |||||||
| 	trait |= HCL_TRAIT_INTERACTIVE; | 	trait |= HCL_TRAIT_INTERACTIVE; | ||||||
| 	hcl_setoption (hcl, HCL_TRAIT, &trait); | 	hcl_setoption (hcl, HCL_TRAIT, &trait); | ||||||
| } | } | ||||||
|  | #endif | ||||||
|  |  | ||||||
| 	while (1) | 	while (1) | ||||||
| 	{ | 	{ | ||||||
|  | |||||||
| @ -86,7 +86,7 @@ static int add_literal (hcl_t* hcl, hcl_oop_t obj, hcl_oow_t* index) | |||||||
| 		/* this removes redundancy of symbols, characters, and integers. */ | 		/* this removes redundancy of symbols, characters, and integers. */ | ||||||
| 		if (((hcl_oop_oop_t)hcl->code.lit.arr)->slot[i] == obj) | 		if (((hcl_oop_oop_t)hcl->code.lit.arr)->slot[i] == obj) | ||||||
| 		{ | 		{ | ||||||
| 			*index = i; | 			*index = i - lfbase; | ||||||
| 			return i; | 			return i; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| @ -1070,7 +1070,7 @@ static int compile_lambda (hcl_t* hcl, hcl_oop_t src, int defun) | |||||||
| 		/* make_function nargs ntmprs lfbase lfsize */ | 		/* make_function nargs ntmprs lfbase lfsize */ | ||||||
| 		if (emit_double_param_instruction(hcl, HCL_CODE_MAKE_FUNCTION, nargs, ntmprs) <= -1) return -1; | 		if (emit_double_param_instruction(hcl, HCL_CODE_MAKE_FUNCTION, nargs, ntmprs) <= -1) return -1; | ||||||
| 		lfbase_pos = hcl->code.bc.len; | 		lfbase_pos = hcl->code.bc.len; | ||||||
| 		if (emit_long_param(hcl, hcl->code.lit.len) <= -1) return -1; /* lfbase */ | 		if (emit_long_param(hcl, hcl->code.lit.len - hcl->c->blk.info[hcl->c->blk.depth - 1].lfbase) <= -1) return -1; /* lfbase */ | ||||||
| 		lfsize_pos = hcl->code.bc.len; | 		lfsize_pos = hcl->code.bc.len; | ||||||
| 		if (emit_long_param(hcl, 0) <= -1) return -1; | 		if (emit_long_param(hcl, 0) <= -1) return -1; | ||||||
| 	} | 	} | ||||||
| @ -1637,7 +1637,6 @@ static HCL_INLINE int compile_symbol (hcl_t* hcl, hcl_oop_t obj) | |||||||
|  |  | ||||||
| 		if (add_literal(hcl, cons, &index) <= -1 || | 		if (add_literal(hcl, cons, &index) <= -1 || | ||||||
| 		    emit_single_param_instruction(hcl, HCL_CODE_PUSH_OBJECT_0, index) <= -1) return -1; | 		    emit_single_param_instruction(hcl, HCL_CODE_PUSH_OBJECT_0, index) <= -1) return -1; | ||||||
| HCL_DEBUG5 (hcl, "************* blk depth [%d] %O , index %d lfbase %d lit len %d\n", (int)hcl->c->blk.depth, cons, (int)index, (int)hcl->c->blk.info[hcl->c->blk.depth].lfbase, (int)hcl->code.lit.len); |  | ||||||
|  |  | ||||||
| 		return 0; | 		return 0; | ||||||
| 	} | 	} | ||||||
| @ -2513,7 +2512,6 @@ static HCL_INLINE int emit_lambda (hcl_t* hcl) | |||||||
| 	hcl_oow_t block_code_size, lfsize; | 	hcl_oow_t block_code_size, lfsize; | ||||||
| 	hcl_ooi_t jip; | 	hcl_ooi_t jip; | ||||||
|  |  | ||||||
| HCL_DEBUG1 (hcl, "emit_lambda   depth %d\n", (int)hcl->c->blk.depth); |  | ||||||
| 	cf = GET_TOP_CFRAME(hcl); | 	cf = GET_TOP_CFRAME(hcl); | ||||||
| 	HCL_ASSERT (hcl, cf->opcode == COP_EMIT_LAMBDA); | 	HCL_ASSERT (hcl, cf->opcode == COP_EMIT_LAMBDA); | ||||||
| 	HCL_ASSERT (hcl, HCL_OOP_IS_SMOOI(cf->operand)); | 	HCL_ASSERT (hcl, HCL_OOP_IS_SMOOI(cf->operand)); | ||||||
| @ -2600,7 +2598,6 @@ static HCL_INLINE int emit_set (hcl_t* hcl) | |||||||
|  |  | ||||||
| 		HCL_ASSERT (hcl, HCL_IS_SYMBOL(hcl, cf->operand)); | 		HCL_ASSERT (hcl, HCL_IS_SYMBOL(hcl, cf->operand)); | ||||||
|  |  | ||||||
| HCL_DEBUG2 (hcl, "emit_set....%O --- %d\n", cf->operand, (int)hcl->c->blk.depth); |  | ||||||
| 		cons = (hcl_oop_t)hcl_getatsysdic(hcl, cf->operand); | 		cons = (hcl_oop_t)hcl_getatsysdic(hcl, cf->operand); | ||||||
| 		if (!cons)  | 		if (!cons)  | ||||||
| 		{ | 		{ | ||||||
| @ -2646,9 +2643,39 @@ int hcl_compile (hcl_t* hcl, hcl_oop_t obj) | |||||||
|  |  | ||||||
| /* TODO: in case i implement all global variables as block arguments at the top level...what should i do? */ | /* TODO: in case i implement all global variables as block arguments at the top level...what should i do? */ | ||||||
|  |  | ||||||
| 	hcl->c->blk.depth++; | 	hcl->c->blk.depth++; /* this must be 0 here */ | ||||||
| HCL_DEBUG2 (hcl, "ENTERING DEPTH %d LIT LEN  %d\n", (int)hcl->c->blk.depth, (int)hcl->code.lit.len); |  | ||||||
| 	if (store_temporary_variable_count_for_block(hcl, hcl->c->tv.size, hcl->code.lit.len) <= -1) return -1; | 	/*  | ||||||
|  | 	 * In the non-INTERACTIVE mode, the literal frame base doesn't matter. | ||||||
|  | 	 * Only the initial function object contains the literal frame.  | ||||||
|  | 	 * No other function objects are created. All lambda defintions are | ||||||
|  | 	 * translated to base context objects instead. | ||||||
|  | 	 *  | ||||||
|  | 	 * In the INTERACTIVE mode, the literal frame base plays a key role. | ||||||
|  | 	 * hcl_compile() is called for the top-level expression andthe literal | ||||||
|  | 	 * frame base can be 0. The means it is ok for a top-level code to  | ||||||
|  | 	 * reference part of the literal frame reserved for a lambda function. | ||||||
|  | 	 * | ||||||
|  | 	 *  (set b 1) | ||||||
|  | 	 *  (defun set-a(x) (set a x)) | ||||||
|  | 	 *  (set a 2) | ||||||
|  | 	 *  (set-a 4) | ||||||
|  | 	 *  (printf "%d\n" a) | ||||||
|  | 	 *  | ||||||
|  | 	 * the global literal frame looks like this: | ||||||
|  | 	 *  @0         (b) | ||||||
|  | 	 *  @1         (a) | ||||||
|  | 	 *  @2         (set-a) | ||||||
|  | 	 *  @3         (printf . #<PRIM>) | ||||||
|  | 	 *  @4         "%d\n" | ||||||
|  | 	 * | ||||||
|  | 	 * @1 to @2 will be copied to a function object when defun is executed. | ||||||
|  | 	 * The literal frame of the created function object for set-a looks  | ||||||
|  | 	 * like this | ||||||
|  | 	 *  @0         (a) | ||||||
|  | 	 *  @1         (set-a)  | ||||||
|  | 	 */ | ||||||
|  | 	if (store_temporary_variable_count_for_block(hcl, hcl->c->tv.size, 0) <= -1) return -1; | ||||||
|  |  | ||||||
| 	PUSH_CFRAME (hcl, COP_COMPILE_OBJECT, obj); | 	PUSH_CFRAME (hcl, COP_COMPILE_OBJECT, obj); | ||||||
|  |  | ||||||
|  | |||||||
| @ -566,7 +566,6 @@ int hcl_decode (hcl_t* hcl, hcl_oow_t start, hcl_oow_t end) | |||||||
|  |  | ||||||
| 				HCL_ASSERT (hcl, b1 >= 0); | 				HCL_ASSERT (hcl, b1 >= 0); | ||||||
| 				HCL_ASSERT (hcl, b2 >= b1); | 				HCL_ASSERT (hcl, b2 >= b1); | ||||||
| 				HCL_ASSERT (hcl, b4 >= b3); |  | ||||||
| 				break; | 				break; | ||||||
|  |  | ||||||
| 			case HCL_CODE_MAKE_BLOCK: | 			case HCL_CODE_MAKE_BLOCK: | ||||||
|  | |||||||
| @ -1676,7 +1676,6 @@ static int execute (hcl_t* hcl) | |||||||
| 				LOG_INST_1 (hcl, "push_literal @%zu", b1); | 				LOG_INST_1 (hcl, "push_literal @%zu", b1); | ||||||
| 				/*HCL_STACK_PUSH (hcl, hcl->code.lit.arr->slot[b1]);*/ | 				/*HCL_STACK_PUSH (hcl, hcl->code.lit.arr->slot[b1]);*/ | ||||||
| 				HCL_STACK_PUSH (hcl, hcl->active_function->literal_frame[b1]); | 				HCL_STACK_PUSH (hcl, hcl->active_function->literal_frame[b1]); | ||||||
| HCL_DEBUG3 (hcl, "*** push literal %O    => %d active_function %p\n", hcl->active_function->literal_frame[b1], b1, hcl->active_function); |  | ||||||
| 				break; | 				break; | ||||||
|  |  | ||||||
| 			/* ------------------------------------------------- */ | 			/* ------------------------------------------------- */ | ||||||
| @ -1705,7 +1704,6 @@ HCL_DEBUG3 (hcl, "*** push literal %O    => %d active_function %p\n", hcl->activ | |||||||
| 			handle_object: | 			handle_object: | ||||||
| 				/*ass = hcl->code.lit.arr->slot[b1];*/ | 				/*ass = hcl->code.lit.arr->slot[b1];*/ | ||||||
| 				ass = (hcl_oop_cons_t)hcl->active_function->literal_frame[b1]; | 				ass = (hcl_oop_cons_t)hcl->active_function->literal_frame[b1]; | ||||||
| HCL_DEBUG3 (hcl, "handle object ass => %O   => %d active_function %p\n", ass, b1, hcl->active_function); |  | ||||||
| 				HCL_ASSERT (hcl, HCL_IS_CONS(hcl, ass)); | 				HCL_ASSERT (hcl, HCL_IS_CONS(hcl, ass)); | ||||||
|  |  | ||||||
| 				if ((bcode >> 3) & 1) | 				if ((bcode >> 3) & 1) | ||||||
| @ -2343,7 +2341,6 @@ HCL_DEBUG3 (hcl, "handle object ass => %O   => %d active_function %p\n", ass, b1 | |||||||
|  |  | ||||||
| 				HCL_ASSERT (hcl, b1 >= 0); | 				HCL_ASSERT (hcl, b1 >= 0); | ||||||
| 				HCL_ASSERT (hcl, b2 >= b1); | 				HCL_ASSERT (hcl, b2 >= b1); | ||||||
| 				HCL_ASSERT (hcl, b3 >= 0); |  | ||||||
|  |  | ||||||
| 				/* the MAKE_FUNCTION instruction is followed by the long JUMP_FORWARD_X instruction. | 				/* the MAKE_FUNCTION instruction is followed by the long JUMP_FORWARD_X instruction. | ||||||
| 				* i can decode the instruction and get the size of instructions | 				* i can decode the instruction and get the size of instructions | ||||||
| @ -2354,7 +2351,6 @@ HCL_DEBUG3 (hcl, "handle object ass => %O   => %d active_function %p\n", ass, b1 | |||||||
| 				joff = (joff << 8) | hcl->active_code[hcl->ip + 2]; | 				joff = (joff << 8) | hcl->active_code[hcl->ip + 2]; | ||||||
| 			#endif | 			#endif | ||||||
|  |  | ||||||
| HCL_DEBUG1(hcl, "****  MAKE FUNCTION joff = %zu\n", joff); |  | ||||||
| 				/* copy the byte codes from the active context to the new context */ | 				/* copy the byte codes from the active context to the new context */ | ||||||
| 			#if (HCL_HCL_CODE_LONG_PARAM_SIZE == 2) | 			#if (HCL_HCL_CODE_LONG_PARAM_SIZE == 2) | ||||||
| 				func = (hcl_oop_function_t)make_function(hcl, b4, &hcl->active_code[hcl->ip + 3], joff); | 				func = (hcl_oop_function_t)make_function(hcl, b4, &hcl->active_code[hcl->ip + 3], joff); | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user