示例#1
0
文件: cfuns.c 项目: xcw0579/mudOS
void c_call(int  func, int  num_arg) {
    function_t *funp;
    
    func += function_index_offset;
    /*
     * Find the function in the function table. As the
     * function may have been redefined by inheritance, we
     * must look in the last table, which is pointed to by
     * current_object.
     */
    DEBUG_CHECK(func >= current_object->prog->last_inherited +
		current_object->prog->num_functions_defined,
		"Illegal function index\n");
    
    if (current_object->prog->function_flags[func] & FUNC_UNDEFINED)
	error("Undefined function: %s\n", function_name(current_object->prog, func));
    /* Save all important global stack machine registers */
    push_control_stack(FRAME_FUNCTION);
    
    caller_type = ORIGIN_LOCAL;
    /* This assigment must be done after push_control_stack() */
    current_prog = current_object->prog;
    /*
     * If it is an inherited function, search for the real
     * definition.
     */
    csp->num_local_variables = num_arg + num_varargs;
    num_varargs = 0;
    funp = setup_new_frame(func);
    csp->pc = pc;	/* The corrected return address */
    call_program(current_prog, funp->address);
}
示例#2
0
文件: cfuns.c 项目: xcw0579/mudOS
void c_call_inherited(int  inh, int  func, int  num_arg) {
    inherit_t *ip = current_prog->inherit + inh;
    program_t *temp_prog = ip->prog;
    function_t *funp;
    
    push_control_stack(FRAME_FUNCTION);

    caller_type = ORIGIN_LOCAL;
    current_prog = temp_prog;
		
    csp->num_local_variables = num_arg + num_varargs;
    num_varargs = 0;
    		
    function_index_offset += ip->function_index_offset;
    variable_index_offset += ip->variable_index_offset;
    
    funp = setup_inherited_frame(func);
    csp->pc = pc;

    call_program(current_prog, funp->address);
}
示例#3
0
svalue_t *
call_function_pointer (funptr_t * funp, int num_arg)
{
    static func_t *oefun_table = efun_table - BASE;
    array_t *v;
    
    if (!funp->hdr.owner || (funp->hdr.owner->flags & O_DESTRUCTED))
        error("Owner (/%s) of function pointer is destructed.\n",
              (funp->hdr.owner ? funp->hdr.owner->obname : "(null)"));
    setup_fake_frame(funp);
    if ((v=funp->hdr.args)) {
        check_for_destr(v);
        num_arg = merge_arg_lists(num_arg, v, 0);
    }

    switch (funp->hdr.type) {
    case FP_SIMUL:
        call_simul_efun(funp->f.simul.index, num_arg);
        break;
    case FP_EFUN:
        {
            int i, def;
            fp = sp - num_arg + 1;

            i = funp->f.efun.index;
            if (num_arg == instrs[i].min_arg - 1 && 
                ((def = instrs[i].Default) != DEFAULT_NONE)) {
                if (def == DEFAULT_THIS_OBJECT) {
                    push_object(current_object);
                } else {
                    push_number(def);
                }
                num_arg++;
            } else
                if (num_arg < instrs[i].min_arg) {
                    error("Too few arguments to efun %s in efun pointer.\n", query_instr_name(i));
                } else if (num_arg > instrs[i].max_arg && instrs[i].max_arg != -1) {
                    error("Too many arguments to efun %s in efun pointer.\n", query_instr_name(i));
                }
            /* possibly we should add TRACE, OPC, etc here;
               also on eval_cost here, which is ok for just 1 efun */
            {
                int j, n = num_arg;
                st_num_arg = num_arg;

                if (n >= 4 || instrs[i].max_arg == -1)
                    n = instrs[i].min_arg;

                for (j = 0; j < n; j++) {
                    CHECK_TYPES(sp - num_arg + j + 1, instrs[i].type[j], j + 1, i);
                }
                (*oefun_table[i])();

                free_svalue(&apply_ret_value, "call_function_pointer");
                if (instrs[i].ret_type == TYPE_NOVALUE)
                    apply_ret_value = const0;
                else
                    apply_ret_value = *sp--;
               	remove_fake_frame();
                return &apply_ret_value;
            }
        }
    case FP_LOCAL | FP_NOT_BINDABLE: {
        function_t *func;

        fp = sp - num_arg + 1;

        if (current_object->prog->function_flags[funp->f.local.index] & (FUNC_PROTOTYPE|FUNC_UNDEFINED))
            error("Undefined lfun pointer called: %s\n", function_name(current_object->prog, funp->f.local.index));
        push_control_stack(FRAME_FUNCTION);
        current_prog = funp->hdr.owner->prog;
        
        caller_type = ORIGIN_LOCAL;

        csp->num_local_variables = num_arg;
        func = setup_new_frame(funp->f.local.index);

        call_program(current_prog, func->address);
        break;
    }
    case FP_FUNCTIONAL: 
    case FP_FUNCTIONAL | FP_NOT_BINDABLE: {

        fp = sp - num_arg + 1;
        push_control_stack(FRAME_FUNP);
        current_prog = funp->f.functional.prog;
        csp->fr.funp = funp;
        
        caller_type = ORIGIN_FUNCTIONAL;

        setup_variables(num_arg, funp->f.functional.num_local,
                        funp->f.functional.num_arg);

        function_index_offset = funp->f.functional.fio;
        variable_index_offset = funp->f.functional.vio;
        call_program(funp->f.functional.prog, funp->f.functional.offset);
        break;
    }
    default:
        error("Unsupported function pointer type.\n");
    }
    free_svalue(&apply_ret_value, "call_function_pointer");
    apply_ret_value = *sp--;
    remove_fake_frame();
    return &apply_ret_value;
}