Exemplo n.º 1
0
void Compiler::handle_ik_cf(const JInst& jinst) {
    switch(jinst.opcode) {
    case OPCODE_IFNULL:
    case OPCODE_IFNONNULL:
    case OPCODE_IFEQ:
    case OPCODE_IFNE:
    case OPCODE_IFLT:
    case OPCODE_IFGE:
    case OPCODE_IFGT:
    case OPCODE_IFLE:
        gen_if(jinst.opcode, jinst.get_target(0));
        break;
    case OPCODE_IF_ACMPEQ:
    case OPCODE_IF_ACMPNE:
    case OPCODE_IF_ICMPEQ:
    case OPCODE_IF_ICMPNE:
    case OPCODE_IF_ICMPLT:
    case OPCODE_IF_ICMPGE:
    case OPCODE_IF_ICMPGT:
    case OPCODE_IF_ICMPLE:
        gen_if_icmp(jinst.opcode, jinst.get_target(0));
        break;
    case OPCODE_GOTO:
    case OPCODE_GOTO_W:
        gen_goto(jinst.get_target(0));
        break;
    case OPCODE_JSR:
    case OPCODE_JSR_W:
        gen_jsr(jinst.get_target(0));
        break;
    case OPCODE_RET:
        gen_ret(jinst.op0);
        break;
    case OPCODE_TABLESWITCH:
    case OPCODE_LOOKUPSWITCH:
        gen_switch(jinst);
        break;
    default: assert(false); break;
    }
}
Exemplo n.º 2
0
/**
 * begin a function
 * called from "parse", this routine tries to make a function out
 * of what follows
 * modified version.  p.l. woods
 */
newfunc() {
    char n[NAMESIZE];
    int idx, type;
    fexitlab = getlabel();

    if (!symname(n)) {
        error("illegal function or declaration");
        kill();
        return;
    }
    if (idx = findglb(n)) {
        if (symbol_table[idx].identity != FUNCTION)
            multidef(n);
        else if (symbol_table[idx].offset == FUNCTION)
            multidef(n);
        else
            symbol_table[idx].offset = FUNCTION;
    } else
        add_global(n, FUNCTION, CINT, FUNCTION, PUBLIC);
    if (!match("("))
        error("missing open paren");
    output_string(n);
    output_label_terminator();
    newline();
    local_table_index = NUMBER_OF_GLOBALS; //locptr = STARTLOC;
    argstk = 0;
    // ANSI style argument declaration
    if (doAnsiArguments() == 0) {
        // K&R style argument declaration
        while (!match(")")) {
            if (symname(n)) {
                if (findloc(n))
                    multidef(n);
                else {
                    add_local(n, 0, 0, argstk, AUTO);
                    argstk = argstk + INTSIZE;
                }
            } else {
                error("illegal argument name");
                junk();
            }
            blanks();
            if (!streq(line + lptr, ")")) {
                if (!match(","))
                    error("expected comma");
            }
            if (endst())
                break;
        }
        stkp = 0;
        argtop = argstk;
        while (argstk) {
            if (type = get_type()) {
                getarg(type);
                need_semicolon();
            } else {
                error("wrong number args");
                break;
            }
        }
    }
    statement(YES);
    print_label(fexitlab);
    output_label_terminator();
    newline();
    gen_modify_stack(0);
    gen_ret();
    stkp = 0;
    local_table_index = NUMBER_OF_GLOBALS; //locptr = STARTLOC;
}
Exemplo n.º 3
0
void newfunc_typed(int storage, char *n, int type)
{
    int idx;
    SYMBOL *symbol;
    char an[NAMESIZE];

    fexitlab = getlabel();

    if ((idx = find_global(n)) > -1) {
        symbol = &symbol_table[idx];
        if (symbol->identity != FUNCTION)
            multidef(n);
    } else {
        /* extern implies global scope */
        idx = add_global(n, FUNCTION, CINT, 0, storage == EXTERN ? PUBLIC : storage);
        symbol = &symbol_table[idx];
    }
    local_table_index = NUMBER_OF_GLOBALS; //locptr = STARTLOC;
    argstk = 0;
    // ANSI style argument declaration
    if (doAnsiArguments()) {
        if (storage == EXTERN) {
            need_semicolon();
            return;
        }
        /* No body .. just a definition */
        if (match(";"))
            return;
    } else {
        // K&R style argument declaration
        while (!match(")")) {
            if (symname(an)) {
                if (find_locale(an) > -1)
                    multidef(an);
                else {
                    /* FIXME: struct */
                    add_local(an, 0, 0, argstk, AUTO);
                    argstk = argstk + INTSIZE;
                }
            } else {
                error("illegal argument name");
                junk();
            }
            blanks();
            if (!streq(line + lptr, ")")) {
                if (!match(","))
                    error("expected comma");
            }
            if (endst())
                break;
        }
        if (storage == EXTERN) {
            need_semicolon();
            return;
        }
        /* No body .. just a definition */
        if (match(";"))
            return;
        stkp = 0;
        argtop = argstk;
        while (argstk) {
            if ((type = get_type()) != -1) {
                notvoid(type);
                getarg(type);
                need_semicolon();
            } else {
                error("wrong number args");
                break;
            }
        }
    }
    if (symbol->offset == FUNCTION)
            multidef(n);
    symbol->offset = FUNCTION;
    output_string(n);
    output_label_terminator();
    newline();
    gen_prologue();
    statement(YES);
    print_label(fexitlab);
    output_label_terminator();
    newline();
    gen_epilogue();
    gen_modify_stack(0);
    gen_ret();
    stkp = 0;
    local_table_index = NUMBER_OF_GLOBALS; //locptr = STARTLOC;
}
Exemplo n.º 4
0
Arquivo: gen.c Projeto: catseye/Bhuna
static void
ast_gen_r(struct ast *a)
{
	int bpid_1, bpid_2;
	vm_label_t label;
	struct value *v;

	if (a == NULL)
		return;

	a->label = gptr;
	switch (a->type) {
	case AST_LOCAL:
		gen_push_local(a->u.local.index, a->u.local.upcount);
		break;
	case AST_VALUE:
		gen_push_value(a->u.value.value);
		if (a->u.value.value->type == VALUE_CLOSURE) {
			gen_set_activation();
			gen_jmp_bp(&bpid_1);
			a->u.value.value->v.k->label = gptr;
			ast_gen_r(a->u.value.value->v.k->ast);
			gen_ret();
			backpatch(bpid_1);
		}
		break;
	case AST_BUILTIN:
		if (a->u.builtin.bi->index == INDEX_BUILTIN_STORE) {
			struct ast *lvalue;
			
			lvalue = ast_find_local(a);
			gen_cow_local(lvalue->u.local.index, lvalue->u.local.upcount);
		}
		ast_gen_r(a->u.builtin.right);
		if (a->u.builtin.bi->arity == -1) {
			v = value_new_integer(ast_count_args(a->u.builtin.right));
			value_deregister(v);
			gen_push_value(v);
		}
		gen_builtin(a->u.builtin.bi);
		break;
	case AST_APPLY:
		ast_gen_r(a->u.apply.right);
		ast_gen_r(a->u.apply.left);
		gen_apply();
		break;
	case AST_ROUTINE:
		ast_gen_r(a->u.routine.body);
		break;
	case AST_ARG:
		ast_gen_r(a->u.arg.left);
		ast_gen_r(a->u.arg.right);
		break;
	case AST_STATEMENT:
		ast_gen_r(a->u.statement.left);
		ast_gen_r(a->u.statement.right);
		break;
	case AST_ASSIGNMENT:
		assert(a->u.assignment.left != NULL);
		assert(a->u.assignment.left->type == AST_LOCAL);
		ast_gen_r(a->u.assignment.right);
		if (a->u.assignment.defining) {
			/* XXX */
			/*
			gen_init_local(a->u.assignment.left->u.local.index,
			    a->u.assignment.left->u.local.upcount);
			*/
		} else {
			gen_pop_local(a->u.assignment.left->u.local.index,
			    a->u.assignment.left->u.local.upcount);
		}
		break;
	case AST_CONDITIONAL:
		ast_gen_r(a->u.conditional.test);
		gen_jz_bp(&bpid_1);
		ast_gen_r(a->u.conditional.yes);
		if (a->u.conditional.no != NULL)
			gen_jmp_bp(&bpid_2);
		backpatch(bpid_1);
		if (a->u.conditional.no != NULL) {
			ast_gen_r(a->u.conditional.no);
			backpatch(bpid_2);
		}
		break;
	case AST_WHILE_LOOP:
		label = gptr;
		ast_gen_r(a->u.while_loop.test);
		gen_jz_bp(&bpid_1);
		ast_gen_r(a->u.while_loop.body);
		gen_jmp(label);
		backpatch(bpid_1);
		break;
	case AST_RETR:
		ast_gen_r(a->u.retr.body);
		gen_ret();
		break;
	}
}