in progress of fixing a bug in instruction elimination
This commit is contained in:
		| @ -110,7 +110,8 @@ class MyObject(Object) | ||||
|  | ||||
| 	} | ||||
| 	 | ||||
| 	method(#class) main | ||||
| 	 | ||||
| 	method(#class) main_xx | ||||
| 	{ | ||||
| 		|a k| | ||||
| 		 | ||||
| @ -214,6 +215,17 @@ class MyObject(Object) | ||||
| 		nil. | ||||
| 		## end of elimination. | ||||
|  | ||||
| 		## PROBLEM: the following double loop will exhaust the stack  | ||||
| 		while (true) | ||||
| 		{ | ||||
| 			while (true)  | ||||
| 			{  | ||||
| 				##[:j :q | (j + q) dump] value: (if (true) { 20 }) value: (if (true) { break }). | ||||
| 				(1 + (if (false) {} else { break })) dump. | ||||
| 			}. | ||||
| 		}. | ||||
|  | ||||
| 		 | ||||
| 		a :=999. | ||||
| 		a := #{ | ||||
| 			1,  | ||||
| @ -228,19 +240,20 @@ class MyObject(Object) | ||||
| 		 | ||||
| 		(* Dictionary ??? | ||||
| 		a := #{ | ||||
| 			"a": 20, | ||||
| 			b : 30 | ||||
| 		}.  | ||||
| 		a := #{ | ||||
| 			{ key, value }, | ||||
| 			{ key, value }, | ||||
| 			{ key, value }, | ||||
| 			{ key, value } | ||||
| 			:( key, value ), | ||||
| 			:( key, value ), | ||||
| 			:( key, value ), | ||||
| 			:( key, value ) | ||||
| 		} | ||||
| 		 | ||||
| 		a := :{ | ||||
| 			:( key, value ), | ||||
| 		} | ||||
| 		*) | ||||
|  | ||||
| 		abc := { key, value }. | ||||
| 		{ key, value } dump. | ||||
|  | ||||
| 	(*	abc := { key, value }. | ||||
| 		{ key, value } dump. *) | ||||
| 		 | ||||
| 		a do: [ :v | v dump]. | ||||
|  | ||||
| @ -254,4 +267,22 @@ class MyObject(Object) | ||||
| 		'---------- END ------------' dump. | ||||
| 		##Processor sleepFor: 20. | ||||
| 	} | ||||
| 	 | ||||
| 	method(#class) main | ||||
| 	{ | ||||
| 			## PROBLEM: the following double loop will exhaust the stack  | ||||
| 		while (true) | ||||
| 		{ | ||||
| 		##111 dump. | ||||
| 			while (true)  | ||||
| 			{  | ||||
| 				##[:j :q | (j + q) dump] value: (if (true) { 20 }) value: (if (true) { break }). | ||||
| 				(1 + (if (false) {} else { break })) dump. | ||||
| 				##break. | ||||
| 				##[:j :q | (j + q) dump] value: 10 value: 20. | ||||
| 				##if (false) {} else { break }. | ||||
| 			}. | ||||
| 		}. | ||||
| 	} | ||||
| ##  | ||||
| } | ||||
|  | ||||
							
								
								
									
										103
									
								
								moo/lib/comp.c
									
									
									
									
									
								
							
							
						
						
									
										103
									
								
								moo/lib/comp.c
									
									
									
									
									
								
							| @ -1508,6 +1508,16 @@ retry: | ||||
| 				SET_TOKEN_TYPE (moo, MOO_IOTOK_ASSIGN); | ||||
| 				ADD_TOKEN_CHAR (moo, c); | ||||
| 			} | ||||
| 			else if (c == '{') | ||||
| 			{ | ||||
| 				SET_TOKEN_TYPE (moo, MOO_IOTOK_DICBRACE); | ||||
| 				ADD_TOKEN_CHAR (moo, c); | ||||
| 			} | ||||
| 			else if (c == '(') | ||||
| 			{ | ||||
| 				SET_TOKEN_TYPE (moo, MOO_IOTOK_ASSPAREN); | ||||
| 				ADD_TOKEN_CHAR (moo, c); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				unget_char (moo, &moo->c->lxc); | ||||
| @ -1577,7 +1587,7 @@ retry: | ||||
| 				case '[': | ||||
| 					/* #[ - byte array literal */ | ||||
| 					ADD_TOKEN_CHAR(moo, c); | ||||
| 					SET_TOKEN_TYPE (moo, MOO_IOTOK_BAPAREN); | ||||
| 					SET_TOKEN_TYPE (moo, MOO_IOTOK_BABRACK); | ||||
| 					break; | ||||
|  | ||||
| 				case '{': | ||||
| @ -2211,6 +2221,32 @@ static int patch_long_forward_jump_instruction (moo_t* moo, moo_oow_t jip, moo_o | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static void eliminate_instructions (moo_t* moo, moo_oow_t start, moo_oow_t end) | ||||
| { | ||||
| 	moo_oow_t last; | ||||
|  | ||||
| 	MOO_ASSERT (moo, moo->c->mth.code.len >= 1); | ||||
|  | ||||
| MOO_DEBUG2 (moo, "ELIMINATE INSTRUCTION FROM %zu TO %zu\n", start, end); | ||||
| 	last = moo->c->mth.code.len - 1; | ||||
|  | ||||
| 	if (end >= last) | ||||
| 	{ | ||||
| 		/* eliminate all instructions starting from the start index. | ||||
| 		 * setting the length to the start length will achieve this */ | ||||
| 		moo->c->mth.code.len = start; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		/* eliminate a chunk in the middle of the instruction buffer. | ||||
| 		 * some copying is required */ | ||||
| 		if (end > last) end = last; | ||||
| 		MOO_MEMMOVE (&moo->c->mth.code.ptr[start], &moo->c->mth.code.ptr[end + 1], moo->c->mth.code.len - end - 1); | ||||
| 		moo->c->mth.code.len--; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| /* --------------------------------------------------------------------- | ||||
|  * Compiler | ||||
|  * --------------------------------------------------------------------- */ | ||||
| @ -3884,7 +3920,7 @@ if index is too large, switch to at:put? (or don't care as it's too large???). | ||||
| 				moo->c->mth.arlit_count = saved_arlit_count; | ||||
| 				break; | ||||
|  | ||||
| 			case MOO_IOTOK_BAPAREN: /* #[ */ | ||||
| 			case MOO_IOTOK_BABRACK: /* #[ */ | ||||
| 			/*case MOO_IOTOK_LBRACK:*/ /* [ */ | ||||
| 				GET_TOKEN (moo); | ||||
| 				if (__read_byte_array_literal (moo, &lit) <= -1) return -1; | ||||
| @ -4218,7 +4254,7 @@ static int compile_expression_primary (moo_t* moo, const moo_oocs_t* ident, cons | ||||
| 				break; | ||||
| 			} | ||||
|  | ||||
| 			case MOO_IOTOK_BAPAREN: /* #[ */ | ||||
| 			case MOO_IOTOK_BABRACK: /* #[ */ | ||||
| 				/*GET_TOKEN (moo);*/ | ||||
| 				if (compile_byte_array_literal(moo) <= -1) return -1; | ||||
| 				break; | ||||
| @ -4464,8 +4500,10 @@ static int compile_message_expression (moo_t* moo, int to_super) | ||||
| 				if (TOKEN_TYPE(moo) == MOO_IOTOK_BINSEL) | ||||
| 				{ | ||||
| 					MOO_ASSERT (moo, moo->c->mth.code.len > noop_pos); | ||||
| 					MOO_MEMMOVE (&moo->c->mth.code.ptr[noop_pos], &moo->c->mth.code.ptr[noop_pos + 1], moo->c->mth.code.len - noop_pos - 1); | ||||
| 					moo->c->mth.code.len--; | ||||
| 					/*MOO_MEMMOVE (&moo->c->mth.code.ptr[noop_pos], &moo->c->mth.code.ptr[noop_pos + 1], moo->c->mth.code.len - noop_pos - 1); | ||||
| 					moo->c->mth.code.len--;*/ | ||||
| 					/* eliminate the NOOP instruction */ | ||||
| 					eliminate_instructions (moo, noop_pos, noop_pos); | ||||
|  | ||||
| 					noop_pos = moo->c->mth.code.len; | ||||
| 					if (emit_byte_instruction(moo, BCODE_NOOP) <= -1) return -1; | ||||
| @ -4475,8 +4513,10 @@ static int compile_message_expression (moo_t* moo, int to_super) | ||||
| 				if (TOKEN_TYPE(moo) == MOO_IOTOK_KEYWORD) | ||||
| 				{ | ||||
| 					MOO_ASSERT (moo, moo->c->mth.code.len > noop_pos); | ||||
| 					MOO_MEMMOVE (&moo->c->mth.code.ptr[noop_pos], &moo->c->mth.code.ptr[noop_pos + 1], moo->c->mth.code.len - noop_pos - 1); | ||||
| 					moo->c->mth.code.len--; | ||||
| 					/*MOO_MEMMOVE (&moo->c->mth.code.ptr[noop_pos], &moo->c->mth.code.ptr[noop_pos + 1], moo->c->mth.code.len - noop_pos - 1); | ||||
| 					moo->c->mth.code.len--;*/ | ||||
| 					/* eliminate the NOOP instruction */ | ||||
| 					eliminate_instructions (moo, noop_pos, noop_pos); | ||||
|  | ||||
| 					noop_pos = moo->c->mth.code.len; | ||||
| 					if (emit_byte_instruction(moo, BCODE_NOOP) <= -1) return -1; | ||||
| @ -4492,8 +4532,10 @@ static int compile_message_expression (moo_t* moo, int to_super) | ||||
| 				if (TOKEN_TYPE(moo) == MOO_IOTOK_KEYWORD) | ||||
| 				{ | ||||
| 					MOO_ASSERT (moo, moo->c->mth.code.len > noop_pos); | ||||
| 					MOO_MEMMOVE (&moo->c->mth.code.ptr[noop_pos], &moo->c->mth.code.ptr[noop_pos + 1], moo->c->mth.code.len - noop_pos - 1); | ||||
| 					moo->c->mth.code.len--; | ||||
| 					/*MOO_MEMMOVE (&moo->c->mth.code.ptr[noop_pos], &moo->c->mth.code.ptr[noop_pos + 1], moo->c->mth.code.len - noop_pos - 1); | ||||
| 					moo->c->mth.code.len--;*/ | ||||
| 					/* eliminate the NOOP instruction */ | ||||
| 					eliminate_instructions (moo, noop_pos, noop_pos); | ||||
|  | ||||
| 					noop_pos = moo->c->mth.code.len; | ||||
| 					if (emit_byte_instruction(moo, BCODE_NOOP) <= -1) return -1; | ||||
| @ -4521,10 +4563,11 @@ static int compile_message_expression (moo_t* moo, int to_super) | ||||
| 		} | ||||
| 		else  | ||||
| 		{ | ||||
| 			/* delete the NOOP instruction inserted  */ | ||||
| 			MOO_ASSERT (moo, moo->c->mth.code.len > noop_pos); | ||||
| 			MOO_MEMMOVE (&moo->c->mth.code.ptr[noop_pos], &moo->c->mth.code.ptr[noop_pos + 1], moo->c->mth.code.len - noop_pos - 1); | ||||
| 			moo->c->mth.code.len--; | ||||
| 			/*MOO_MEMMOVE (&moo->c->mth.code.ptr[noop_pos], &moo->c->mth.code.ptr[noop_pos + 1], moo->c->mth.code.len - noop_pos - 1); | ||||
| 			moo->c->mth.code.len--;*/ | ||||
| 			/* eliminate the NOOP instruction */ | ||||
| 			eliminate_instructions (moo, noop_pos, noop_pos); | ||||
| 			goto done; | ||||
| 		} | ||||
| 	} | ||||
| @ -4673,7 +4716,7 @@ static int compile_if_expression (moo_t* moo) | ||||
| 			falseblock = 0; | ||||
|  | ||||
| 			/* eliminate PUSH_TRUE as well */ | ||||
| 			moo->c->mth.code.len = precondpos; | ||||
| 			eliminate_instructions (moo, precondpos, moo->c->mth.code.len - 1); | ||||
| 			postcondpos = precondpos; | ||||
| 		} | ||||
| 		else if (precondpos + 1 == postcondpos && moo->c->mth.code.ptr[precondpos] == BCODE_PUSH_FALSE) | ||||
| @ -4699,7 +4742,9 @@ static int compile_if_expression (moo_t* moo) | ||||
| 		{ | ||||
| 			if (falseblock)  | ||||
| 			{ | ||||
| 				moo->c->mth.code.len = precondpos; | ||||
| 				/* the conditional was false. elimiate instructions emitted | ||||
| 				 * for the block attached to the conditional */ | ||||
| 				eliminate_instructions (moo, precondpos, moo->c->mth.code.len - 1); | ||||
| 				postcondpos = precondpos; | ||||
| 			} | ||||
| 			else if (endoftrueblock == INVALID_IP)  | ||||
| @ -4713,8 +4758,8 @@ static int compile_if_expression (moo_t* moo) | ||||
| 			if (endoftrueblock == INVALID_IP) | ||||
| 			{ | ||||
| 				/* emit an instruction to jump to the end */ | ||||
| 				if (add_to_oow_pool(moo, &jumptoend, moo->c->mth.code.len) <= -1) goto oops; | ||||
| 				if (emit_single_param_instruction (moo, BCODE_JUMP_FORWARD_0, MAX_CODE_JUMP) <= -1) goto oops; | ||||
| 				if (add_to_oow_pool(moo, &jumptoend, moo->c->mth.code.len) <= -1 || | ||||
| 				    emit_single_param_instruction (moo, BCODE_JUMP_FORWARD_0, MAX_CODE_JUMP) <= -1) goto oops; | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| @ -4739,7 +4784,7 @@ static int compile_if_expression (moo_t* moo) | ||||
| 	if (endoftrueblock != INVALID_IP) | ||||
| 	{ | ||||
| 		/* eliminate all instructions after the end of the first true block found */ | ||||
| 		moo->c->mth.code.len = endoftrueblock; | ||||
| 		eliminate_instructions (moo, endoftrueblock, moo->c->mth.code.len - 1); | ||||
| 	} | ||||
|  | ||||
| 	/* patch instructions that jumps to the end of if expression */ | ||||
| @ -4777,6 +4822,7 @@ static int compile_while_expression (moo_t* moo) | ||||
| 	if (compile_conditional (moo) <= -1) goto oops; | ||||
|  | ||||
| 	postcondpos = moo->c->mth.code.len; | ||||
| #if 0 | ||||
| 	if (precondpos + 1 == postcondpos) | ||||
| 	{ | ||||
| 		/* simple optimization -  | ||||
| @ -4786,7 +4832,7 @@ static int compile_while_expression (moo_t* moo) | ||||
| 		{ | ||||
| 			/* the conditional is always true */ | ||||
| 			cond_style = 1; | ||||
| 			moo->c->mth.code.len = precondpos; | ||||
| 			eliminate_instructions (moo, precondpos, moo->c->mth.code.len - 1); | ||||
| 			postcondpos = precondpos; | ||||
| 		} | ||||
| 		else if (moo->c->mth.code.ptr[precondpos] == BCODE_PUSH_FALSE) | ||||
| @ -4795,6 +4841,7 @@ static int compile_while_expression (moo_t* moo) | ||||
| 			cond_style = -1; | ||||
| 		} | ||||
| 	} | ||||
| #endif | ||||
|  | ||||
| 	if (cond_style != 1) | ||||
| 	{ | ||||
| @ -4819,7 +4866,7 @@ static int compile_while_expression (moo_t* moo) | ||||
| 		/* optimization - | ||||
| 		 *  the braced block is kind of empty as it only pushes nil. | ||||
| 		 *  get rid of this push instruction and don't generate the POP_STACKTOP */ | ||||
| 		moo->c->mth.code.len = prebbpos; | ||||
| 		eliminate_instructions (moo, prebbpos, moo->c->mth.code.len - 1); | ||||
| 	} | ||||
| 	else if (prebbpos < postbbpos) | ||||
| 	{ | ||||
| @ -4841,15 +4888,15 @@ static int compile_while_expression (moo_t* moo) | ||||
|  | ||||
| 	if (cond_style != 1) | ||||
| 	{ | ||||
| 		/* patch the jump instruction. */ | ||||
| 		/* patch the jump instruction */ | ||||
| 		if (patch_long_forward_jump_instruction (moo, postcondpos, moo->c->mth.code.len, BCODE_JUMP2_FORWARD_IF_FALSE, &brace_loc) <= -1) goto oops; | ||||
| 	} | ||||
|  | ||||
| 	if (cond_style == -1)  | ||||
| 	{ | ||||
| 		/* optimization - get rid of code generated for the while | ||||
| 		 * loop including the conditional */ | ||||
| 		moo->c->mth.code.len = precondpos; | ||||
| 		/* optimization - get rid of instructions generated for the while | ||||
| 		 * loop including the conditional as the condition was false */ | ||||
| 		eliminate_instructions (moo, precondpos, moo->c->mth.code.len - 1); | ||||
| 	} | ||||
|  | ||||
| 	/* patch the jump instructions for break */ | ||||
| @ -4903,7 +4950,7 @@ static int compile_do_while_expression (moo_t* moo) | ||||
| 		/* optimization - | ||||
| 		 *  the braced block is kind of empty as it only pushes nil. | ||||
| 		 *  get rid of this push instruction and don't generate the POP_STACKTOP */ | ||||
| 		moo->c->mth.code.len = prebbpos; | ||||
| 		eliminate_instructions (moo, prebbpos, moo->c->mth.code.len - 1); | ||||
| 		precondpos = prebbpos; | ||||
| 	} | ||||
| 	else if (prebbpos < postbbpos) | ||||
| @ -4932,14 +4979,14 @@ static int compile_do_while_expression (moo_t* moo) | ||||
| 		if (moo->c->mth.code.ptr[precondpos] == BCODE_PUSH_TRUE) | ||||
| 		{ | ||||
| 			/* the conditional is always true. eliminate PUSH_TRUE and emit an absolute jump */ | ||||
| 			moo->c->mth.code.len = precondpos; | ||||
| 			eliminate_instructions (moo, precondpos, moo->c->mth.code.len - 1); | ||||
| 			postcondpos = precondpos; | ||||
| 			jbinst = BCODE_JUMP_BACKWARD_0; | ||||
| 		} | ||||
| 		else if (moo->c->mth.code.ptr[precondpos] == BCODE_PUSH_FALSE) | ||||
| 		{ | ||||
| 			/* the conditional is always false. eliminate PUSH_FALSE and don't emit jump */ | ||||
| 			moo->c->mth.code.len = precondpos; | ||||
| 			eliminate_instructions (moo, precondpos, moo->c->mth.code.len - 1); | ||||
| 			postcondpos = precondpos; | ||||
| 			goto skip_emitting_jump_backward; | ||||
| 		} | ||||
| @ -5237,7 +5284,7 @@ static int compile_method_statement (moo_t* moo) | ||||
| 					case BCODE_PUSH_TWO: | ||||
| 						/* eliminate the unneeded push instruction */ | ||||
| 						n = 0; | ||||
| 						moo->c->mth.code.len = preexprpos; | ||||
| 						eliminate_instructions (moo, preexprpos, moo->c->mth.code.len - 1); | ||||
| 						break; | ||||
| 					default: | ||||
| 						goto pop_stacktop; | ||||
| @ -6252,7 +6299,7 @@ static int __compile_pooldic_definition (moo_t* moo) | ||||
| 				if (!lit) return -1; | ||||
| 				goto add_literal; | ||||
|  | ||||
| 			case MOO_IOTOK_BAPAREN: /* #[ - byte array literal parenthesis */ | ||||
| 			case MOO_IOTOK_BABRACK: /* #[ - byte array literal parenthesis */ | ||||
| 				if (read_byte_array_literal(moo, &lit) <= -1) return -1; | ||||
| 				goto add_literal; | ||||
|  | ||||
|  | ||||
| @ -323,9 +323,11 @@ struct moo_iotok_t | ||||
| 		MOO_IOTOK_RBRACK, | ||||
| 		MOO_IOTOK_LPAREN, | ||||
| 		MOO_IOTOK_RPAREN, | ||||
| 		MOO_IOTOK_APAREN,  /* #( */ | ||||
| 		MOO_IOTOK_BAPAREN, /* #[ */ | ||||
| 		MOO_IOTOK_ABRACE,  /* #{ */ | ||||
| 		MOO_IOTOK_APAREN,   /* #( - array literal */ | ||||
| 		MOO_IOTOK_BABRACK,  /* #[ - byte array literal */ | ||||
| 		MOO_IOTOK_ABRACE,   /* #{ - array expression */ | ||||
| 		MOO_IOTOK_DICBRACE, /* :{ - dictionary expression */ | ||||
| 		MOO_IOTOK_ASSPAREN, /* :( - association expression */ | ||||
| 		MOO_IOTOK_PERIOD, | ||||
| 		MOO_IOTOK_COMMA, | ||||
| 		MOO_IOTOK_SEMICOLON, | ||||
|  | ||||
| @ -979,11 +979,11 @@ struct moo_t | ||||
| #endif | ||||
| }; | ||||
|  | ||||
|  | ||||
| /* TODO: stack bound check when pushing */ | ||||
| /* TODO: proper stack bound check when pushing */ | ||||
| #define MOO_STACK_PUSH(moo,v) \ | ||||
| 	do { \ | ||||
| 		(moo)->sp = (moo)->sp + 1; \ | ||||
| 		MOO_ASSERT (moo, (moo)->sp < (unsigned int)(MOO_OBJ_GET_SIZE((moo)->processor->active) - MOO_PROCESS_NAMED_INSTVARS)); \ | ||||
| 		(moo)->processor->active->slot[(moo)->sp] = v; \ | ||||
| 	} while (0) | ||||
|  | ||||
|  | ||||
		Reference in New Issue
	
	Block a user