Exemplo n.º 1
0
static void
gen_relation(dfwork_t *dfw, dfvm_opcode_t op, stnode_t *st_arg1, stnode_t *st_arg2)
{
	dfvm_insn_t	*insn;
	dfvm_value_t	*val1, *val2;
	dfvm_value_t	*jmp1 = NULL, *jmp2 = NULL;
	int		reg1 = -1, reg2 = -1;

    /* Create code for the LHS and RHS of the relation */
    reg1 = gen_entity(dfw, st_arg1, &jmp1);
    reg2 = gen_entity(dfw, st_arg2, &jmp2);

    /* Then combine them in a DFVM insruction */
	insn = dfvm_insn_new(op);
	val1 = dfvm_value_new(REGISTER);
	val1->value.numeric = reg1;
	val2 = dfvm_value_new(REGISTER);
	val2->value.numeric = reg2;
	insn->arg1 = val1;
	insn->arg2 = val2;
	dfw_append_insn(dfw, insn);

    /* If either of the relation argumnents need an "exit" instruction
     * to jump to (on failure), mark them */
	if (jmp1) {
		jmp1->value.numeric = dfw->next_insn_id;
	}

	if (jmp2) {
		jmp2->value.numeric = dfw->next_insn_id;
	}
}
Exemplo n.º 2
0
/* returns register number */
static int
dfw_append_mk_range(dfwork_t *dfw, stnode_t *node, dfvm_value_t **p_jmp)
{
	int			hf_reg, reg;
	stnode_t                *entity;
	dfvm_insn_t		*insn;
	dfvm_value_t		*val;

	entity = sttype_range_entity(node);

	/* XXX, check if p_jmp logic is OK */
	hf_reg = gen_entity(dfw, entity, p_jmp);

	insn = dfvm_insn_new(MK_RANGE);

	val = dfvm_value_new(REGISTER);
	val->value.numeric = hf_reg;
	insn->arg1 = val;

	val = dfvm_value_new(REGISTER);
	reg =dfw->next_register++;
	val->value.numeric = reg;
	insn->arg2 = val;

	val = dfvm_value_new(DRANGE);
	val->value.drange = sttype_range_drange(node);
	insn->arg3 = val;

	sttype_range_remove_drange(node);

	dfw_append_insn(dfw, insn);

	return reg;
}
Exemplo n.º 3
0
/* returns register number that the functions's result will be in. */
static int
dfw_append_function(dfwork_t *dfw, stnode_t *node, dfvm_value_t **p_jmp)
{
	GSList *params;
	int i, num_params, reg;
	dfvm_value_t **jmps;
	dfvm_insn_t	*insn;
	dfvm_value_t	*val1, *val2, *val;

	params = sttype_function_params(node);
	num_params = g_slist_length(params);

	/* Array to hold the instructions that need to jump to
	 * an instruction if they fail. */
	jmps = (dfvm_value_t **)g_malloc(num_params * sizeof(dfvm_value_t*));

	/* Create the new DFVM instruction */
	insn = dfvm_insn_new(CALL_FUNCTION);

	val1 = dfvm_value_new(FUNCTION_DEF);
	val1->value.funcdef = sttype_function_funcdef(node);
	insn->arg1 = val1;
	val2 = dfvm_value_new(REGISTER);
	val2->value.numeric = dfw->next_register++;
	insn->arg2 = val2;
	insn->arg3 = NULL;
	insn->arg4 = NULL;

	i = 0;
	while (params) {
		jmps[i] = NULL;
		reg = gen_entity(dfw, (stnode_t *)params->data, &jmps[i]);

		val = dfvm_value_new(REGISTER);
		val->value.numeric = reg;

		switch(i) {
			case 0:
				insn->arg3 = val;
				break;
			case 1:
				insn->arg4 = val;
				break;
			default:
				g_assert_not_reached();
		}

		params = params->next;
		i++;
	}

	dfw_append_insn(dfw, insn);

	/* If any of our parameters failed, send them to
	 * our own failure instruction. This *has* to be done
	 * after we caled dfw_append_insn above so that
	 * we know what the next DFVM insruction is, via
	 * dfw->next_insn_id */
	for (i = 0; i < num_params; i++) {
		if (jmps[i]) {
			jmps[i]->value.numeric = dfw->next_insn_id;
		}
	}

	/* We need another instruction to jump to another exit
	 * place, if the call() of our function failed for some reaosn */
	insn = dfvm_insn_new(IF_FALSE_GOTO);
	g_assert(p_jmp);
	*p_jmp = dfvm_value_new(INSN_NUMBER);
	insn->arg1 = *p_jmp;
	dfw_append_insn(dfw, insn);

	g_free(jmps);

	return val2->value.numeric;
}