예제 #1
0
파일: makeform.c 프로젝트: OPENDAP/bes
static void check_old_style_EOL_var
	(
	 VARIABLE_PTR var
	)
{
	if (!strcmp("EOL", var->name) && IS_CONSTANT(var))
	{
		var->type &= ~FFV_DATA_TYPES;
		var->type |= FFV_EOL;
	}
}
예제 #2
0
파일: guess.c 프로젝트: Infinity17/luadec
int luaU_guess_locals(Proto* f, int main) {
	int blockend[255];
	int block;
	int regassign[MAXARG_A];
	int regusage[MAXARG_A];
	int regblock[MAXARG_A];
	int lastfree;
	int i,i2,x,y,pc;
	llist list_begin;
	llist* list_next = &list_begin;

	if (f->lineinfo != NULL) {
		return 0;
	}

	if (f->sizelocvars>0) {
		return 0;
	}

	list_begin.next = NULL;
	block = 0;
	lastfree = 0;
	blockend[block] = f->sizecode-1;

	for (i=0; i<f->maxstacksize; i++) {
		regassign[i] = 0;
		regusage[i] = 0;
		regblock[i] = 0;
	}

	// parameters, varargs, nil optimizations
	for (i = 0; i < f->numparams; i++) {
		list_next = add(list_next,0,blockend[block]);
		regassign[lastfree] = 0;
		regusage[lastfree] = 1;
		regblock[lastfree] = blockend[block];
		lastfree++;
	}
	if ((f->is_vararg==7) || ((f->is_vararg&2))) {
		if (main!=0) {
			list_next = add(list_next,0,blockend[block]);
			lastfree++;
			regassign[lastfree] = 0;
			regusage[lastfree] = 1;
			regblock[lastfree] = blockend[block];
			lastfree++;
		}
	}
	{
		Instruction i = f->code[0];
		OpCode o = GET_OPCODE(i);
		int a = GETARG_A(i);
		if ((o == OP_SETGLOBAL) || (o == OP_SETUPVAL)) {
			int ixx;
			for (ixx = lastfree; ixx <= a; ixx++) {
				if (ixx!=a) {
					list_next = add(list_next,0,blockend[block]);
					lastfree++;
				}
				regassign[lastfree] = 0;
				regusage[lastfree] = 1;
				regblock[lastfree] = blockend[block];
				lastfree++;
			}
		} else if (o != OP_JMP) {
			int ixx;
			for (ixx = lastfree; ixx <= a-1; ixx++) {
				list_next = add(list_next,0,blockend[block]);
				lastfree++;
				regassign[lastfree] = 0;
				regusage[lastfree] = 1;
				regblock[lastfree] = blockend[block];
				lastfree++;
			}
		}
	}

	// start code checking
	for (pc = 0; pc < f->sizecode; pc++) {
		Instruction instr = f->code[pc];
		OpCode o = GET_OPCODE(instr);
		int a = GETARG_A(instr);
		int b = GETARG_B(instr);
		int c = GETARG_C(instr);
		int bc = GETARG_Bx(instr);
		int sbc = GETARG_sBx(instr);
		int dest = 0;
		int setreg = -1;
		int setregto = -1;
		int setreg2 = -1;
		int loadreg = -1;
		int loadreg2 = -1;
		int loadreg3 = -1;
		int loadregto = -1;
		int intlocfrom = -1;
		int intlocto = -1;
		if ((o==OP_JMP) || (o==OP_FORPREP)) {
			dest = pc + sbc + 2;
		} else if ((pc+1!=f->sizecode) && (GET_OPCODE(f->code[pc+1])==OP_JMP)) {
			dest = pc+1+GETARG_sBx(f->code[pc+1])+2;
		}

		// check which registers were read or written to.
		switch (o) {
		case OP_MOVE:
			setreg = a;
			if (b<=a) {
				intlocfrom = b;
				intlocto = b;
			}
			loadreg = b;
			break;
		case OP_UNM:
		case OP_NOT:
		case OP_LEN:
			setreg = a;
			loadreg = b;
			break;
		case OP_LOADNIL:
			setreg = a;
			setregto = b;
			break;
		case OP_LOADK:
		case OP_GETUPVAL:
		case OP_GETGLOBAL:
		case OP_LOADBOOL:
		case OP_NEWTABLE:
		case OP_CLOSURE:
			setreg = a;
			break;
		case OP_GETTABLE:
			setreg = a;
			loadreg = b;
			if (!IS_CONSTANT(c)) {
				loadreg2 = c;
			}
			break;
		case OP_SETGLOBAL:
		case OP_SETUPVAL:
			loadreg = a;
			break;
		case OP_SETTABLE:
			loadreg = a;
			if (!IS_CONSTANT(b)) {
				loadreg2 = b;
			}
			if (!IS_CONSTANT(c)) {
				if (loadreg2==-1) {
					loadreg2 = c;
				} else {
					loadreg3 = c;
				}
				if ((a+1!=c) && (c>a)) {
					intlocto = c-1;
				}
			}
			intlocfrom = 0;
			if (a-1>=intlocto) {
				intlocto = a-1;
			}
			break;
		case OP_ADD:
		case OP_SUB:
		case OP_MUL:
		case OP_DIV:
		case OP_POW:
		case OP_MOD:
			setreg = a;
			if (!IS_CONSTANT(b)) {
				loadreg = b;
			}
			if (!IS_CONSTANT(c)) {
				if (loadreg==-1) {
					loadreg = c;
				} else {
					loadreg2 = c;
				}
			}
			break;
		case OP_CONCAT:
			setreg = a;
			loadreg = b;
			loadregto = c;
			break;
		case OP_CALL:
			if (c==0) {
				setreg = a;
				setregto = f->maxstacksize;
			} else if (c>=2) {
				setreg = a;
				setregto = a+c-2;
			} else if (c==1) {
				intlocfrom = 0;
				intlocto = a-1;
			}
			if (b==0) {
				loadreg = a;
				loadregto = f->maxstacksize;
			} else {
				loadreg = a;
				loadregto = a+b-1;
			}
			break;
		case OP_RETURN:
			if (b==0) {
				loadreg = a;
				loadregto = f->maxstacksize;
			} else if (b>=2) {
				loadreg = a;
				loadregto = a+b-2;
			}
			break;
		case OP_TAILCALL:
			if (b==0) {
				loadreg = a;
				loadregto = f->maxstacksize;
			} else {
				loadreg = a;
				loadregto = a+b-1;
			}
			break;
		case OP_VARARG:
			if (b==0) {
				setreg = a;
				setregto = f->maxstacksize;
			} else {
				setreg = a;
				setregto = a+b-1;
			}
			break;
		case OP_SELF:
			setreg = a;
			setregto = a+1;
			loadreg = b;
			if (a>b) {
				intlocfrom = 0;
				intlocto = b;
			}
			if (!IS_CONSTANT(c)) {
				loadreg2 = c;
			}
			break;
		case OP_EQ:
		case OP_LT:
		case OP_LE:
			if (!IS_CONSTANT(b)) {
				loadreg = b;
			}
			if (!IS_CONSTANT(c)) {
				if (loadreg==-1) {
					loadreg = c;
				} else {
					loadreg2 = c;
				}
			}
			break;
		case OP_TEST:
			loadreg = a;
			break;
		case OP_TESTSET: 
			setreg = a;
			loadreg = b;
			break;
		case OP_SETLIST:
			loadreg = a;
			if (b==0) {
				loadregto = f->maxstacksize;
			} else {
				loadregto = a+b;
			}
			break;
		case OP_FORLOOP:
			break;
		case OP_TFORLOOP:
			break;
		case OP_FORPREP:
			loadreg = a;
			loadregto = a+2;
			setreg = a;
			setregto = a+3;
			intlocfrom = a;
			intlocto = a+3;
			regassign[a] = pc;
			regassign[a+1] = pc;
			regassign[a+2] = pc;
			regassign[a+3] = pc+1;
			regblock[a] = dest;
			regblock[a+1] = dest;
			regblock[a+2] = dest;
			regblock[a+3] = dest-1;
			block++;
			blockend[block] = dest-1;
			if (GET_OPCODE(f->code[dest-2])==OP_JMP) {
				blockend[block]--;
			}
			break;
		case OP_JMP:
			if (GET_OPCODE(f->code[dest-1]) == OP_TFORLOOP) {
				int a = GETARG_A(f->code[dest-1]);
				int c = GETARG_C(f->code[dest-1]);
				setreg = a;
				setregto = a+c+2;
				loadreg = a;
				loadregto = a+2;
				intlocfrom = a;
				intlocto = a+c+2;
				regassign[a] = pc;
				regassign[a+1] = pc;
				regassign[a+2] = pc;
				regblock[a] = dest+1;
				regblock[a+1] = dest+1;
				regblock[a+2] = dest+1;
				for (x=a+3;x<=a+c+2;x++) {
					regassign[x] = pc+1;
					regblock[x] = dest-1;
				}
			}
			if (dest>pc) {
				block++;
				blockend[block] = dest-1;
			}
			if (GET_OPCODE(f->code[dest-2])==OP_JMP) {
				blockend[block]--;
			}
			break;
		case OP_CLOSE:
		default:
			break;
		}

		for (i=1; i<=block; i++) {
			x = blockend[i];
			i2 = i-1;
			while ((i2>=0) && (blockend[i2]<x)) {
				blockend[i2+1] = blockend[i2];
				i2 = i2-1;
			}
			blockend[i2+1] = x;
		}

		if (loadreg!=-1) {
			if (loadregto==-1)
				loadregto = loadreg;
			for (i=loadreg;i<=loadregto;i++) {
				regusage[i]--;
			}
			if (loadreg2!=-1) regusage[loadreg2]--;
			if (loadreg3!=-1) regusage[loadreg3]--;
		}

		if (setreg!=-1) {
			if (setregto==-1)
				setregto = setreg;
			for (i=setreg;i<=setregto;i++) {
				regusage[i]++;
			}
			if (setreg2!=-1) regusage[setreg2]++;
		}

		i2 = lastfree-1;
		for (i=lastfree; i<f->maxstacksize; i++) {
			if ((regusage[i]<0) || (regusage[i]>1)) {
				i2 = i;
			}
			if ((intlocfrom!=-1) && ((intlocfrom<=i) && (i<=intlocto))) {
				i2 = i;
			}
		}

		for (i=setreg; i<=setregto; i++) {
			if (i>i2) {
				regassign[i] = pc+1;
				regblock[i] = blockend[block];
			}
		}

		for (i=lastfree; i<=i2; i++) {
			//fprintf(stderr,"%d %d %d %d\n",i,regassign[i],regblock[i],block);
			list_next = add(list_next,regassign[i],regblock[i]);
			lastfree++;
		}

		while (blockend[block] <= pc+1) {
			block--;
		}
		while ((lastfree!=0) && (regblock[lastfree-1] <= pc+1)) {
			lastfree--;
			regusage[lastfree]=0;
		}

	}

	// print out information
	{
		int length = 0;
		llist* list = &list_begin;

		while (list->next!=NULL) {
			length++;
			list = list->next;
		}
		f->sizelocvars = length;
		if (f->sizelocvars>0) {
			f->locvars = luaM_newvector(glstate,f->sizelocvars,LocVar);
			list = &list_begin;
			length = 0;
			while (list->next != NULL) {
				char names[10];
				sprintf(names,"l_%d_%d",main,length);
				f->locvars[length].varname = luaS_new(glstate, names);
				f->locvars[length].startpc = list->startpc;
				f->locvars[length].endpc = list->endpc;
				length++;
				list = list->next;
			}
		}
	}

	deletellist(list_begin.next);

	// run with all functions
	for (i=0; i<f->sizep; i++) {
		luaU_guess_locals(f->p[i],main+i+1);
	}
	return 1;
}
예제 #3
0
// match optional expression
void match_exp (const char * exp)
{
	int state = 1;

	pline = exp;

	while(1)
	{
		//printf("state=%d\t",state);getch();
		switch(state)
		{
			//-----------------------------------------------------------------------
			// <CONSTANT>			=> 2
			// <ID>					=> 2
			// <UNARY OPR>			=> 1
			// (					=> 3
			// <FUNC>				=> 4
			case 1:
			{
				l_get_token();//printf("[%s]\n",token);
				if (token_type==OPR_SUB)
				{
					token_type = OPR_NEG;
					move(1);
				}
				else if (IS_OPR(token_type) && IS_UNARY_OPR(token_type))
				{
					move(1);
				}
				else if (IS_CONSTANT(token_type)) 
				{
					move(2);
				}
				else if (token_type==TT_ID)
				{
					move(5);
				}
				else if (token_type==TT_LBK)
				{
					move(3);
				}
				else if (IS_RESWORD(token_type))
				{
					move(4);
				}
				else
					merror_illegal_token();
			}break;
			//-----------------------------------------------------------------------
			// <OPR>				=> 1
			// <OTHER THINGS!>		=> END!
			case 2:
			{
				l_get_token();//printf("[%s]\n",token);
				if (IS_OPR(token_type))
				{
					if(IS_BINARY_OPR(token_type))
					{
						move(1);
					}
					else
					{
						merror_illegal_token();
					}
				}
				// END!
				l_put_back();
				return;
			}break;
			//-----------------------------------------------------------------------
			// 	<EXP> then )		=> 2
			case 3:
			{
				//puts("<match inner expr>");
				match_exp(pline);
				match_str(")");
				move(2);
			}break;
			//-----------------------------------------------------------------------
			// ( then <EXP>,<EXP>,<EXP>... then )	=> 2
			case 4:
			{
				int argc = token_ext,i;
				match_str("(");
				for(i=0;i<argc;++i)
				{
					match_exp(pline);
					if (i != argc-1)	match_str(",");
					else				match_str(")");
				}
				move(2);
			}break;
			//-----------------------------------------------------------------------
			// 
			case 5:
			{
				l_get_token();
				if (token_type==TT_LBK)	
				{
					move(3);
				}
				else
				{
					l_put_back();
					move(2);
				}
			}break;
		}
	}
}
예제 #4
0
파일: makeform.c 프로젝트: OPENDAP/bes
static int add_to_variable_list(char *text_line, FORMAT_PTR format)
{
	VARIABLE_PTR var = NULL;

	char save_char = STR_END;

	char *token = NULL;
	char *endptr = NULL;

	int error = 0;

	if (!format->variables)
	{
		format->variables = dll_init();
		if (!format->variables)
			return(ERR_MEM_LACK);
	}

	token = text_line;
	token = get_token(token, &save_char);
	if (FF_STRLEN(token))
	{
		var = ff_create_variable(token);
		if (var == NULL)
			return ERR_MEM_LACK;
#if 0
			error = ERR_MEM_LACK;
#endif
		if (var->name[0] == '"' && var->name[strlen(var->name) - 1] == '"')
		{
			memmove(var->name, var->name + 1, strlen(var->name) - 2);
			var->name[strlen(var->name) - 2] = STR_END;
		}
	}
	else
	{
		error = err_push(ERR_VARIABLE_DESC, "Expecting a variable name (\"%s\")", format->name);
		goto add_to_variable_list_exit;
	}

	if (!dll_add(format->variables))
	{
		ff_destroy_variable(var);
		error = ERR_MEM_LACK;
		goto add_to_variable_list_exit;
	}

	dll_assign(var, DLL_VAR, dll_last(format->variables));

	token = get_token(token, &save_char);
	if (FF_STRLEN(token))
	{
		errno = 0;
		var->start_pos = strtol(token, &endptr, 10);
		if (errno || FF_STRLEN(endptr))
		{
			error = err_push(errno ? errno : ERR_PARAM_VALUE, "Bad number for variable start position: %s", token);
			goto add_to_variable_list_exit;
		}
	}
	else
	{
		error = err_push(ERR_VARIABLE_DESC, "Expecting a start position for \"%s\"", var->name);
		goto add_to_variable_list_exit;
	}

	token = get_token(token, &save_char);
	if (FF_STRLEN(token))
	{
		errno = 0;
		var->end_pos = strtol(token, &endptr, 10);
		if (errno || FF_STRLEN(endptr))
		{
			error = err_push(errno ? errno : ERR_PARAM_VALUE, "Bad number for variable end position: %s", token);
			goto add_to_variable_list_exit;
		}
	}
	else
	{
		error = err_push(ERR_VARIABLE_DESC, "Expecting an end position for \"%s\"", var->name);
		goto add_to_variable_list_exit;
	}

	token = get_token(token, &save_char);
	if (FF_STRLEN(token))
	{
		FFV_TYPE(var) = ff_lookup_number(variable_types, token);
		if (FFV_TYPE(var) == FF_VAR_TYPE_FLAG)
		{
			if (os_strncmpi("ARRAY", token, 5) == 0)
			{
				RESTORE_CHAR(token, save_char);
				save_char = STR_END;
				error = parse_array_variable(&token, var);
				if (error)
					goto add_to_variable_list_exit;

				format->type |= FF_ARRAY;
			}
			else
			{
				/* Is this a keyworded variable type?  If so, remember name of keyword in record_title */
				if (IS_KEYWORDED_PARAMETER(token))
				{
					FFV_TYPE(var) = 0;

					assert(!var->record_title);

					if (var->record_title)
						memFree(var->record_title, "var->record_title");

					var->record_title = (char *)memStrdup(token, "token");
					if (!var->record_title)
					{
						error = err_push(ERR_MEM_LACK, "");
						goto add_to_variable_list_exit;
					}
				}
				else
				{
					error = err_push(ERR_UNKNOWN_VAR_TYPE, token);
					goto add_to_variable_list_exit;
				}
			}
		}
	}
	else
	{
		error = err_push(ERR_VARIABLE_DESC, "Expecting a variable type or array description for \"%s\"", var->name);
		goto add_to_variable_list_exit;
	}

	token = get_token(token, &save_char);
	if (FF_STRLEN(token))
	{
		errno = 0;
		var->precision = (short)strtol(token, &endptr, 10);
		if (errno || FF_STRLEN(endptr))
		{
			error = err_push(errno ? errno : ERR_PARAM_VALUE, "Bad number for variable precision: %s", token);
			goto add_to_variable_list_exit;
		}
	}
	else
	{
		if (IS_ARRAY(var))
		{
			error = err_push(ERR_VARIABLE_DESC, "Expecting a precision for \"%s\"", var->name);
			goto add_to_variable_list_exit;
		}
	}

	if (var->end_pos < var->start_pos)
	{
		error = err_push(ERR_VARIABLE_DESC,"End Position < Start Position\n%s", text_line);
		goto add_to_variable_list_exit;
	}

	/* Determine The Variable Type */
	if (var->start_pos == 0 && var->end_pos == 0)
	{
		if (IS_BINARY(format))
		{
			error = err_push(ERR_UNKNOWN_FORMAT_TYPE, "Illegal to have delimited binary format");
			goto add_to_variable_list_exit;
		}
		else if (IS_ARRAY(format))
		{
			error = err_push(ERR_UNKNOWN_FORMAT_TYPE, "Illegal to have delimited array format");
			goto add_to_variable_list_exit;
		}

		format->type |= FFF_VARIED;
	}

	if (NEED_TO_CHECK_VARIABLE_SIZE(format, var))
	{
		if (ffv_type_size(var->type) != var->end_pos - var->start_pos + 1)
		{
			char save_eol_char = STR_END;
			char *end_of_line = find_EOL(text_line);

			if (end_of_line)
			{
				save_eol_char = *end_of_line;
				*end_of_line = STR_END;
			}

			error = err_push(ERR_VARIABLE_SIZE,"Expecting ending position for binary field %s to be %d", var->name, var->start_pos + ffv_type_size(var->type) - 1);

			if (end_of_line)
				*end_of_line = save_eol_char;

			goto add_to_variable_list_exit;
		}
	}

	check_old_style_EOL_var(var);
	
	/* Does length of CONSTANT variable name equal length of variable? */
	if (IS_CONSTANT(var) && !IS_EOL(var))
	{
		if (FF_STRLEN(var->name) > FF_VAR_LENGTH(var))
		{
			error = err_push(ERR_VARIABLE_SIZE, "Constant variable initializer (%s) is too long for field", var->name);

			goto add_to_variable_list_exit;
		}
		else if (FF_STRLEN(var->name) < FF_VAR_LENGTH(var))
			error = err_push(ERR_WARNING_ONLY + ERR_VARIABLE_SIZE, "Constant variable initializer (%s) is shorter than field", var->name);
	}

	format->num_vars++;
	format->length = max(format->length, var->end_pos);

add_to_variable_list_exit:

	if (error)
	{
		char *cp;
		char EOL_char = STR_END;

		/* Don't destroy variable since it will be destroyed in ff_destroy_format */

		cp = find_EOL(text_line);
		if (cp)
		{
			EOL_char = *cp;
			*cp = STR_END;
		}

		error = err_push(ERR_VARIABLE_DESC + (error > ERR_WARNING_ONLY ? ERR_WARNING_ONLY : 0),text_line);

		if (cp)
			*cp = EOL_char;

	}

	RESTORE_CHAR(token, save_char);

	return(error);
}