Ejemplo n.º 1
0
void enter_object_hash P1(struct object *, ob)
{
    int h = ObjHash(ob->name);
    IF_DEBUG(struct object *s);

    IF_DEBUG(s = find_obj_n(ob->name));

    DEBUG_CHECK1(s && s != ob, "Duplicate object \"%s\" in object hash table",
		 ob->name);
    DEBUG_CHECK1(s, "Entering object \"%s\" twice in object table",
		 ob->name);
    DEBUG_CHECK1(ob->next_hash,
		 "Object \"%s\" not found in object table but next link not null", ob->name);

    ob->next_hash = obj_table[h];
    obj_table[h] = ob;
    objs_in_table++;
    return;
}
Ejemplo n.º 2
0
void
free_string (const char * str)
{
    block_t **prev, *b;
    int h;

    b = BLOCK(str);
    DEBUG_CHECK1(b != findblock(str),"stralloc.c: free_string called on non-shared string: %s.\n", str);
    
    /*
     * if a string has been ref'd USHRT_MAX times then we assume that its used
     * often enough to justify never freeing it.
     */
    if (!REFS(b))
        return;

    REFS(b)--;
    SUB_STRING(SIZE(b));

    NDBG(b);
    if (REFS(b) > 0)
        return;

    h = StrHash(str);
    prev = base_table + h;
    while ((b = *prev)) {
        if (STRING(b) == str) {
            *prev = NEXT(b);
            break;
        }
        prev = &(NEXT(b));
    }

    DEBUG_CHECK1(!b, "free_string: not found in string table! (\"%s\")\n", str);

    SUB_NEW_STRING(SIZE(b), sizeof(block_t));
    FREE(b);
    CHECK_STRING_STATS;
}
Ejemplo n.º 3
0
void remove_object_hash P1(struct object *, ob)
{
    int h = ObjHash(ob->name);
    struct object *s;

    s = find_obj_n(ob->name);

    DEBUG_CHECK1(s != ob, "Remove object \"%s\": found a different object!",
		 ob->name);

    obj_table[h] = ob->next_hash;
    ob->next_hash = 0;
    objs_in_table--;
    return;
}
Ejemplo n.º 4
0
void
deallocate_string (char * str)
{
    int h;
    block_t *b, **prev;

    h = StrHash(str);
    prev = base_table + h;
    while ((b = *prev)) {
        if (STRING(b) == str) {
            *prev = NEXT(b);
            break;
        }
        prev = &(NEXT(b));
    }
    DEBUG_CHECK1(!b,"stralloc.c: deallocate_string called on non-shared string: %s.\n", str);

    FREE(b);
}
Ejemplo n.º 5
0
void remove_living_name (object_t * ob)
{
    object_t **hl;

    ob->flags &= ~O_ENABLE_COMMANDS;
    if (!ob->living_name)
	return;

    num_living_names--;
    DEBUG_CHECK(!ob->living_name, "remove_living_name: no living name set.\n");
    hl = &hashed_living[hash_living_name(ob->living_name)];
    while (*hl) {
	if (*hl == ob)
	    break;
	hl = &(*hl)->next_hashed_living;
    }
    DEBUG_CHECK1(*hl == 0,
		 "remove_living_name: Object named %s no in hash list.\n",
		 ob->living_name);
    *hl = ob->next_hashed_living;
    free_string(ob->living_name);
    ob->next_hashed_living = 0;
    ob->living_name = 0;
}
Ejemplo n.º 6
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);
   }
}