fixing compiler bugs regarding MAKE_FUNCTION and literal frame rebasing
This commit is contained in:
		| @ -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. */ | ||||
| 		if (((hcl_oop_oop_t)hcl->code.lit.arr)->slot[i] == obj) | ||||
| 		{ | ||||
| 			*index = i; | ||||
| 			*index = i - lfbase; | ||||
| 			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 */ | ||||
| 		if (emit_double_param_instruction(hcl, HCL_CODE_MAKE_FUNCTION, nargs, ntmprs) <= -1) return -1; | ||||
| 		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; | ||||
| 		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 || | ||||
| 		    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; | ||||
| 	} | ||||
| @ -2513,7 +2512,6 @@ static HCL_INLINE int emit_lambda (hcl_t* hcl) | ||||
| 	hcl_oow_t block_code_size, lfsize; | ||||
| 	hcl_ooi_t jip; | ||||
|  | ||||
| HCL_DEBUG1 (hcl, "emit_lambda   depth %d\n", (int)hcl->c->blk.depth); | ||||
| 	cf = GET_TOP_CFRAME(hcl); | ||||
| 	HCL_ASSERT (hcl, cf->opcode == COP_EMIT_LAMBDA); | ||||
| 	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_DEBUG2 (hcl, "emit_set....%O --- %d\n", cf->operand, (int)hcl->c->blk.depth); | ||||
| 		cons = (hcl_oop_t)hcl_getatsysdic(hcl, cf->operand); | ||||
| 		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? */ | ||||
|  | ||||
| 	hcl->c->blk.depth++; | ||||
| 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; | ||||
| 	hcl->c->blk.depth++; /* this must be 0 here */ | ||||
|  | ||||
| 	/*  | ||||
| 	 * 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); | ||||
|  | ||||
|  | ||||
		Reference in New Issue
	
	Block a user