Ejemplo n.º 1
0
void i_generate_return P1(struct parse_node *, node) {
  if (node) {
    i_generate_node(node);
  } else {
    ins_f_byte(F_CONST0);
  }
  ins_f_byte(F_RETURN);
}
Ejemplo n.º 2
0
void
i_generate_inherited_init_call P2(int, index, short, f) {
  ins_f_byte(F_CALL_INHERITED);
  ins_byte(index);
  ins_short(f);
  ins_byte(0);
  ins_f_byte(F_POP_VALUE);
}
Ejemplo n.º 3
0
void i_generate_continue() {
  if (switches) {
    ins_f_byte(F_POP_BREAK);
    ins_byte(switches);
  }
  /* form a linked list of the continue addresses */
  ins_f_byte(F_BRANCH);
  ins_short(cont_ptr->line);
  cont_ptr = cont_ptr->v.expr;
}
Ejemplo n.º 4
0
void
i_branch_backwards P2(char, b, int, addr) {
    if (b) {
	ins_f_byte(b);
	ins_short(CURRENT_PROGRAM_SIZE - addr);
    } 
}
Ejemplo n.º 5
0
static void
generate_lvalue_list P1(struct parse_node *, expr) {
    while (expr = expr->r.expr) {
      i_generate_node(expr->l.expr);
      ins_f_byte(F_VOID_ASSIGN);
    }
}
Ejemplo n.º 6
0
/*
 * Generate the code to push a number on the stack.
 * This varies since there are several opcodes (for
 * optimizing speed and/or size).
 */
static void write_number P1(int, val)
{
    if (val == 0) {
	ins_f_byte(F_CONST0);
    } else if (val == 1) {
	ins_f_byte(F_CONST1);
    } else if (val > 0 && val < 256) {
	ins_f_byte(F_BYTE);
	ins_byte(val);
    } else if (val < 0 && val > -256) {
	ins_f_byte(F_NBYTE);
	ins_byte(-val);
    } else {
	ins_f_byte(F_NUMBER);
	ins_int(val);
    }
}
Ejemplo n.º 7
0
void
i_generate_else() {
  /* set up a new branch to after the end of the if */
  ins_f_byte(F_BRANCH);
  /* save the old saved value here */
  ins_short(read_short(current_forward_branch));
  /* update the old branch to point to this point */
  upd_short(current_forward_branch, CURRENT_PROGRAM_SIZE - current_forward_branch);
  /* point current_forward_branch at the new branch we made */
  current_forward_branch = CURRENT_PROGRAM_SIZE - 2;
}
Ejemplo n.º 8
0
void i_generate_forward_branch P1(char, b) {
    ins_f_byte(b);
    ins_short(current_forward_branch);
    current_forward_branch = CURRENT_PROGRAM_SIZE - 2;
}
Ejemplo n.º 9
0
void
i_pop_value() {
  ins_f_byte(F_POP_VALUE);
}
Ejemplo n.º 10
0
void
i_generate_function_call P2(short, f, char, num) {
  ins_f_byte(F_CALL_FUNCTION_BY_ADDRESS);
  ins_short(f);
  ins_byte(0);
}
Ejemplo n.º 11
0
void
i_generate_node P1(struct parse_node *, expr) {
    if (!expr) return;

    if (expr->line && expr->line != line_being_generated)
	switch_to_line(expr->line);
    switch (expr->kind) {
    case F_OR:
    case F_XOR:
    case F_AND:
    case F_EQ:
    case F_NE:
    case F_GT:
    case F_GE:
    case F_LT:
    case F_LE:
    case F_LSH:
    case F_RSH:
    case F_ADD:
    case F_SUBTRACT:
    case F_MULTIPLY:
    case F_DIVIDE:
    case F_MOD:
	i_generate_node(expr->l.expr);
	/* fall through */
    case F_RETURN:
    case F_POP_VALUE:
    case F_PRE_INC:
    case F_PRE_DEC:
    case F_INC:
    case F_DEC:
    case F_POST_INC:
    case F_POST_DEC:
    case F_NOT:
    case F_COMPL:
    case F_NEGATE:
	i_generate_node(expr->r.expr);
	/* fall through */
    case F_CONST0:
    case F_CONST1:
#ifdef DEBUG
    case F_BREAK_POINT:
#endif
    case F_BREAK:
	ins_f_byte(expr->kind);
	break;
    case F_ASSIGN: /* note these are backwards */
    case F_VOID_ASSIGN:
    case F_VOID_ADD_EQ:
    case F_ADD_EQ:
    case F_AND_EQ:
    case F_OR_EQ:
    case F_XOR_EQ:
    case F_LSH_EQ:
    case F_RSH_EQ:
    case F_SUB_EQ:
    case F_MULT_EQ:
    case F_MOD_EQ:
    case F_DIV_EQ:
    case F_INDEX_LVALUE:
    case F_INDEX:
    case F_RINDEX:
    case F_RINDEX_LVALUE:
	i_generate_node(expr->r.expr);
	i_generate_node(expr->l.expr);
	ins_f_byte(expr->kind);
	break;
    case F_NN_RANGE:
    case F_RN_RANGE:
    case F_RR_RANGE:
    case F_NR_RANGE:
    case F_NN_RANGE_LVALUE:
    case F_RN_RANGE_LVALUE:
    case F_NR_RANGE_LVALUE:
    case F_RR_RANGE_LVALUE:
	i_generate_node(expr->l.expr);
	i_generate_node(expr->r.expr);
	i_generate_node(expr->v.expr);
	ins_f_byte(expr->kind);
	break;
    case NODE_NE_RANGE_LVALUE:
        i_generate_node(expr->l.expr);
        ins_f_byte(F_CONST1);
        i_generate_node(expr->v.expr);
        ins_f_byte(F_NR_RANGE_LVALUE);
        break;
    case NODE_RE_RANGE_LVALUE:
        i_generate_node(expr->l.expr);
        ins_f_byte(F_CONST1);
        i_generate_node(expr->v.expr);
        ins_f_byte(F_RR_RANGE_LVALUE);
        break;
    case F_RE_RANGE:
    case F_NE_RANGE:
        i_generate_node(expr->l.expr);
        i_generate_node(expr->v.expr);
        ins_f_byte(expr->kind);
        break;
    case F_STRING:
	if (expr->v.number <= 0xff) {
	    ins_f_byte(F_SHORT_STRING);
	    ins_byte(expr->v.number);
	} else {
	    ins_f_byte(F_STRING);
	    ins_short(expr->v.number);
	}
	break;
    case F_REAL:
	ins_f_byte(F_REAL);
	ins_real(expr->v.real);
	break;
    case F_NBYTE:
    case F_BYTE:
	ins_f_byte(expr->kind);
	ins_byte(expr->v.number);
	break;
    case F_NUMBER:
	write_number(expr->v.number);
	break;
    case F_LOR:
    case F_LAND:
	i_generate_node(expr->l.expr);
	i_generate_forward_branch(expr->kind);
	i_generate_node(expr->r.expr);
	if (expr->l.expr->kind == NODE_BRANCH_LINK){
	    i_update_forward_branch_links(expr->kind,expr->l.expr);
	}
	else i_update_forward_branch();
	break;
    case NODE_BRANCH_LINK:
	i_generate_node(expr->l.expr);
	ins_byte(0);
	expr->line = CURRENT_PROGRAM_SIZE;
	ins_short(0);
	i_generate_node(expr->r.expr);
        break;
    case F_AGGREGATE:
    case F_AGGREGATE_ASSOC:
	generate_expr_list(expr->r.expr);
	ins_f_byte(expr->kind);
	ins_short(expr->v.number);
	break;
    case NODE_COMMA:
    case NODE_ASSOC:
	i_generate_node(expr->l.expr);
	i_generate_node(expr->r.expr);
	break;
    case NODE_BREAK:
	ins_f_byte(F_BRANCH);
	expr->v.expr = break_ptr;
	expr->line = CURRENT_PROGRAM_SIZE;
	expr->type = 0;
	ins_short(0);
	break_ptr = expr;
	break;
    case NODE_CONTINUE:
	if (switches) {
	    ins_f_byte(F_POP_BREAK);
	    ins_byte(switches);
	}
	ins_f_byte(F_BRANCH);
	expr->v.expr = cont_ptr;
	expr->line = CURRENT_PROGRAM_SIZE;
	expr->type = 0;
	ins_short(0);
	cont_ptr = expr;
	break;
    case NODE_STATEMENTS:
	i_generate_node(expr->l.expr);
	i_generate_node(expr->r.expr);
	break;
    case NODE_PARAMETER:
	ins_f_byte(F_LOCAL);
	ins_byte(expr->v.number + current_num_values);
	break;
    case NODE_PARAMETER_LVALUE:
	ins_f_byte(F_LOCAL_LVALUE);
	ins_byte(expr->v.number + current_num_values);
	break;
    case NODE_VALUE:
	ins_f_byte(F_LOCAL);
	ins_byte(expr->v.number);
	break;
    case NODE_LVALUE:
	ins_f_byte(F_LOCAL_LVALUE);
	ins_byte(expr->v.number);
	break;
    case NODE_IF:
	if (expr->v.expr->kind == F_NOT) {
	    i_generate_node(expr->v.expr->r.expr);
	    i_generate_forward_branch(F_BRANCH_WHEN_NON_ZERO);
	} else {
	    i_generate_node(expr->v.expr);
	    i_generate_forward_branch(F_BRANCH_WHEN_ZERO);
	}
	i_generate_node(expr->l.expr);
	if (expr->r.expr) {
	    i_generate_else();
	    i_generate_node(expr->r.expr);
	}
	i_update_forward_branch();
	break;
    case NODE_FOR:
	{
	    int forever = node_always_true(expr->l.expr->v.expr), pos;
	    
	    i_save_loop_info();
	    i_generate_node(expr->l.expr->l.expr);
	    if (!forever) 
		i_generate_forward_branch(F_BRANCH);
	    pos = CURRENT_PROGRAM_SIZE;
	    i_generate_node(expr->r.expr);
	    i_update_continues();
	    i_generate_node(expr->l.expr->r.expr);
	    if (!forever)
		i_update_forward_branch();
	    if (expr->l.expr->v.expr->kind == F_LOOP_COND){
	        i_generate_node(expr->l.expr->v.expr);
		ins_short(CURRENT_PROGRAM_SIZE - pos);
	    } else
	        i_branch_backwards(generate_conditional_branch(expr->l.expr->v.expr), pos);
	    i_update_breaks();
	    i_restore_loop_info();
	}
	break;
    case NODE_WHILE:
	{
	    int forever = node_always_true(expr->l.expr), pos;
	    i_save_loop_info();
	    if (!forever)
		i_generate_forward_branch(F_BRANCH);
	    pos =  CURRENT_PROGRAM_SIZE;
	    i_generate_node(expr->r.expr);
	    if (!forever)
		i_update_forward_branch();
	    i_update_continues();
	    if (expr->l.expr->kind == F_LOOP_COND){
	        i_generate_node(expr->l.expr);
		ins_short(CURRENT_PROGRAM_SIZE - pos);
	    } else 
	        i_branch_backwards(generate_conditional_branch(expr->l.expr), pos);
	    i_update_breaks();
	    i_restore_loop_info();
	}
	break;
    case NODE_DO_WHILE:
        {
	    int pos;
            i_save_loop_info();
	    pos = CURRENT_PROGRAM_SIZE;
            i_generate_node(expr->l.expr);
            i_update_continues();
            i_branch_backwards(generate_conditional_branch(expr->r.expr), pos);
            i_update_breaks();
            i_restore_loop_info();
	}
        break;
    case NODE_CASE_NUMBER:
    case NODE_CASE_STRING:
	if (expr->v.expr) {
	    struct parse_node *other = expr->v.expr;
	    expr->v.number = 1;
	    other->l.expr = expr->l.expr;
	    other->v.number = CURRENT_PROGRAM_SIZE;
	    expr->l.expr = other;
	} else {
	    expr->v.number = CURRENT_PROGRAM_SIZE;
	}
      break;
    case NODE_DEFAULT:
	expr->v.number = CURRENT_PROGRAM_SIZE;
	break;
    case NODE_SWITCH_STRINGS:
    case NODE_SWITCH_NUMBERS:
    case NODE_SWITCH_DIRECT:
	{
	    int addr;

	    i_generate_node(expr->l.expr);
	    switches++;
	    ins_f_byte(F_SWITCH);
	    ins_byte(0xff); /* kind of table */
	    addr = CURRENT_PROGRAM_SIZE;
	    ins_short(0); /* address of table */
	    ins_short(0); /* break address to push, table is entered before */
	    ins_short(0); /* default address */
	    i_generate_node(expr->r.expr);
	    if (expr->v.expr && expr->v.expr->kind == NODE_DEFAULT) {
		upd_short(addr + 4, expr->v.expr->v.number);
		expr->v.expr = expr->v.expr->l.expr;
	    } else {
		upd_short(addr + 4, CURRENT_PROGRAM_SIZE);
	    }
	    /* just in case the last case doesn't have a break */
	    ins_f_byte(F_BREAK);
	    /* build table */
	    upd_short(addr, CURRENT_PROGRAM_SIZE);
#ifdef BINARIES
	    if (expr->kind == NODE_SWITCH_STRINGS) {
		short sw;
		sw = addr - 2;
		add_to_mem_block(A_PATCH, (char *)&sw, sizeof sw);
	    }
#endif
	    if (expr->kind == NODE_SWITCH_DIRECT) {
		struct parse_node *pn = expr->v.expr;
		while (pn) {
		    ins_short((short)pn->v.number);
		    pn = pn->l.expr;
		}
		ins_int(expr->v.expr->r.number);
		mem_block[current_block].block[addr-1] = (char)0xfe;
	    } else {
		int table_size = 0;
		int power_of_two = 1;
		int i = 0;
		struct parse_node *pn = expr->v.expr;
		
		while (pn) {
		    INS_POINTER((POINTER_INT)pn->r.expr);
		    ins_short((short)pn->v.number);
		    pn = pn->l.expr;
		    table_size += 1;
		}
		while ((power_of_two<<1) <= table_size) {
		    power_of_two <<= 1;
		    i++;
		}
		if (expr->kind == NODE_SWITCH_NUMBERS)
		    mem_block[current_block].block[addr-1] = (char)(0xf0+i);
		else
		    mem_block[current_block].block[addr-1] = (char)(i*0x10+0x0f);
	    }
	    upd_short(addr + 2, CURRENT_PROGRAM_SIZE);
	    break;
	}
    case NODE_CONDITIONAL:
	{
	    int addr;
	    
	    i_generate_node(expr->l.expr);
	    ins_f_byte(F_BRANCH_WHEN_ZERO);
	    addr = CURRENT_PROGRAM_SIZE;
	    ins_short(0);
	    
	    i_generate_node(expr->r.expr->l.expr);
	    upd_short(addr, CURRENT_PROGRAM_SIZE - addr + 3); /*over the branch */
	    ins_f_byte(F_BRANCH);
	    addr = CURRENT_PROGRAM_SIZE;
	    ins_short(0);
	    
	    i_generate_node(expr->r.expr->r.expr);
	    upd_short(addr, CURRENT_PROGRAM_SIZE - addr);
	}
	break;
    case F_CATCH:
	{
	    int addr;
	    
	    ins_f_byte(F_CATCH);
	    addr = CURRENT_PROGRAM_SIZE;
	    ins_short(0);
	    i_generate_node(expr->r.expr);
	    ins_f_byte(F_END_CATCH);
	    upd_short(addr, CURRENT_PROGRAM_SIZE - addr);
	    break;
	}
    case F_SSCANF:
	i_generate_node(expr->l.expr->l.expr);
	i_generate_node(expr->l.expr->r.expr);
	ins_f_byte(F_SSCANF);
	ins_byte(expr->r.expr->v.number);
	generate_lvalue_list(expr->r.expr);
	break;
    case F_PARSE_COMMAND:
	i_generate_node(expr->l.expr->l.expr);
	i_generate_node(expr->l.expr->r.expr->l.expr);
	i_generate_node(expr->l.expr->r.expr->r.expr);
	ins_f_byte(F_PARSE_COMMAND);
	ins_byte(expr->r.expr->v.number);
	generate_lvalue_list(expr->r.expr);
	break;
    case F_TIME_EXPRESSION:
	ins_f_byte(F_TIME_EXPRESSION);
	i_generate_node(expr->r.expr);
	ins_f_byte(F_END_TIME_EXPRESSION);
	break;
    case F_TO_FLOAT:
    case F_TO_INT:
	generate_expr_list(expr->r.expr);
	ins_f_byte(expr->kind);
	break;
    case F_GLOBAL_LVALUE:
    case F_GLOBAL:
    case F_LOCAL_LVALUE:
    case F_LOCAL:
    case F_LOOP_INCR:
    case F_WHILE_DEC:
	ins_f_byte(expr->kind);
	ins_byte(expr->v.number);
	break;
    case F_LOOP_COND:
	{
	    int i;
	    
	    ins_f_byte(F_LOOP_COND);
	    ins_byte(expr->l.expr->v.number);
	    /* expand this into a number so we can pull it fast at runtime */
	    if (expr->r.expr->kind == F_LOCAL) {
		i_generate_node(expr->r.expr);
	    } else {
		ins_f_byte(F_NUMBER);
		switch (expr->r.expr->kind) {
		case F_CONST0: i = 0; break;
		case F_CONST1: i = 1; break;
		case F_NBYTE: i = - expr->r.expr->v.number; break;
		case F_BYTE:
		case F_NUMBER:
		    i = expr->r.expr->v.number; break;
		default:
		    fatal("Unknown node %i in F_LOOP_COND\n", expr->r.expr->kind);
		}
		ins_int(i);
	    }
	    break;
	}
    case F_SIMUL_EFUN:
    case F_CALL_FUNCTION_BY_ADDRESS:
	generate_expr_list(expr->r.expr);
	ins_f_byte(expr->kind);
	ins_short(expr->v.number);
	ins_byte((expr->r.expr ? expr->r.expr->kind : 0));
	break;
    case F_CALL_INHERITED:
	generate_expr_list(expr->r.expr);
	ins_f_byte(F_CALL_INHERITED);
	ins_byte(expr->v.number & 0xff);
	ins_short(expr->v.number >> 8);
	ins_byte((expr->r.expr ? expr->r.expr->kind : 0));
	break;
    case F_EVALUATE:
#ifdef NEW_FUNCTIONS
	generate_expr_list(expr->r.expr);
	ins_f_byte(F_EVALUATE);
#else
	i_generate_node(expr->l.expr);
	ins_f_byte(F_EVALUATE);
	generate_expr_list(expr->r.expr);
	ins_f_byte(F_CALL_OTHER);
#endif
	ins_byte(expr->v.number);
	break;
    case F_FUNCTION_CONSTRUCTOR:
#ifdef NEW_FUNCTIONS
	if ((expr->v.number & 0xff) == FP_CALL_OTHER) {
	    i_generate_node(expr->l.expr);
	    i_generate_node(expr->r.expr);
	    ins_f_byte(F_FUNCTION_CONSTRUCTOR);
	    ins_f_byte(FP_CALL_OTHER);
	    break;
	}
	if (expr->r.expr) {
	    generate_expr_list(expr->r.expr);
	    ins_f_byte(F_AGGREGATE);
	    ins_short(expr->r.expr->kind);
	} else 
	    ins_f_byte(F_CONST0);
	ins_f_byte(F_FUNCTION_CONSTRUCTOR);
	ins_byte(expr->v.number & 0xff);

	switch (expr->v.number & 0xff) {
	case FP_SIMUL:
	case FP_LOCAL:
	    ins_short(expr->v.number >> 8);
	    break;
	case FP_EFUN:
	    ins_f_byte(predefs[expr->v.number >> 8].token);
	    break;
	case FP_FUNCTIONAL:
	case FP_FUNCTIONAL | FP_NOT_BINDABLE:
	    {
		int addr, save_current_num_values = current_num_values;
		ins_byte(expr->v.number >> 8);
		addr = CURRENT_PROGRAM_SIZE;
		ins_short(0);
		current_num_values = expr->r.expr ? expr->r.expr->kind : 0;
		i_generate_node(expr->l.expr);
		current_num_values = save_current_num_values;
		ins_f_byte(F_RETURN);
		upd_short(addr, CURRENT_PROGRAM_SIZE - addr - 2);
		break;
	    }
	}
#else
	if (expr->l.expr) i_generate_node(expr->l.expr);
	i_generate_node(expr->r.expr);
	ins_f_byte(F_FUNCTION_CONSTRUCTOR);
	ins_byte(expr->v.number);
#endif
	break;
#ifdef NEW_FUNCTIONS
    case NODE_ANON_FUNC:
	{
	    int addr;
	    
	    ins_f_byte(F_FUNCTION_CONSTRUCTOR);
	    ins_byte(FP_ANONYMOUS);
	    ins_byte(expr->v.number);
	    ins_byte(expr->l.number);
	    addr = CURRENT_PROGRAM_SIZE;
	    ins_short(0);
	    i_generate_node(expr->r.expr);
	    upd_short(addr, CURRENT_PROGRAM_SIZE - addr - 2);
	    break;
	}
#endif
    default:
	DEBUG_CHECK1(expr->kind < BASE,
		     "Unknown eoperator %s in i_generate_node.\n",
		     get_f_name(expr->kind));
	generate_expr_list(expr->r.expr);
	ins_f_byte(expr->kind);
	if (expr->v.number != -1)
	    ins_byte(expr->v.number);
   }
}
Ejemplo n.º 12
0
void ins_f_byte_with_arg(unsigned int a, INT32 b)
{
  ins_f_byte(a);
  add_to_program((PIKE_OPCODE_T)b);
}