final_realms_fluffos_v1/
final_realms_fluffos_v1/bin/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/ChangeLog.old/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/Win32/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/compat/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/compat/simuls/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/include/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/clone/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/command/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/data/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/etc/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/include/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/inherit/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/inherit/master/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/log/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/single/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/single/tests/compiler/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/single/tests/efuns/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/single/tests/operators/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/u/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/tmp/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/windows/
final_realms_fluffos_v1/lib/baseobs/guilds/
final_realms_fluffos_v1/lib/baseobs/misc/
final_realms_fluffos_v1/lib/baseobs/races/shadows/
final_realms_fluffos_v1/lib/cmds/god/
final_realms_fluffos_v1/lib/cmds/handlers/
final_realms_fluffos_v1/lib/cmds/handlers/cmds/
final_realms_fluffos_v1/lib/d/heaven/
final_realms_fluffos_v1/lib/d/heaven/heaven/ave/
final_realms_fluffos_v1/lib/d/mudlib/
final_realms_fluffos_v1/lib/d/newbie/
final_realms_fluffos_v1/lib/d/newbie/docs/
final_realms_fluffos_v1/lib/d/newbie/drow/armour/
final_realms_fluffos_v1/lib/d/newbie/drow/items/
final_realms_fluffos_v1/lib/d/newbie/drow/mobs/
final_realms_fluffos_v1/lib/d/newbie/drow/oldmobs/
final_realms_fluffos_v1/lib/d/newbie/drow/weapons/
final_realms_fluffos_v1/lib/d/newbie/duergar/weapons/
final_realms_fluffos_v1/lib/d/newbie/dwarf/weapons/
final_realms_fluffos_v1/lib/d/newbie/elf/cafe/
final_realms_fluffos_v1/lib/d/newbie/elf/chars/equip/
final_realms_fluffos_v1/lib/d/newbie/elf/items/armours/
final_realms_fluffos_v1/lib/d/newbie/elf/items/obj/
final_realms_fluffos_v1/lib/d/newbie/elf/items/weapons/
final_realms_fluffos_v1/lib/d/newbie/elf/quick_fix/
final_realms_fluffos_v1/lib/d/newbie/gnome/armour/
final_realms_fluffos_v1/lib/d/newbie/gnome/buildings/
final_realms_fluffos_v1/lib/d/newbie/gnome/items/
final_realms_fluffos_v1/lib/d/newbie/gnome/npcs/clones/
final_realms_fluffos_v1/lib/d/newbie/gnome/rooms/northrooms/
final_realms_fluffos_v1/lib/d/newbie/gnome/weapons/
final_realms_fluffos_v1/lib/d/newbie/goblin/armour/
final_realms_fluffos_v1/lib/d/newbie/goblin/items/
final_realms_fluffos_v1/lib/d/newbie/grads/log/
final_realms_fluffos_v1/lib/d/newbie/grads/npcs/
final_realms_fluffos_v1/lib/d/newbie/grads/rooms/
final_realms_fluffos_v1/lib/d/newbie/grads/rooms/cave1/
final_realms_fluffos_v1/lib/d/newbie/grads/temp/
final_realms_fluffos_v1/lib/d/newbie/guests/weapons/
final_realms_fluffos_v1/lib/d/newbie/half-elf/items/
final_realms_fluffos_v1/lib/d/newbie/half-elf/newroomss/
final_realms_fluffos_v1/lib/d/newbie/half-elf/rooms/
final_realms_fluffos_v1/lib/d/newbie/half-elf/rooms/castle/
final_realms_fluffos_v1/lib/d/newbie/half-elf/rooms/drows/
final_realms_fluffos_v1/lib/d/newbie/half-elf/rooms/savannah/
final_realms_fluffos_v1/lib/d/newbie/half-elf/rooms/secret/
final_realms_fluffos_v1/lib/d/newbie/half-elf/rooms/town/
final_realms_fluffos_v1/lib/d/newbie/halfling/
final_realms_fluffos_v1/lib/d/newbie/halfling/misc/
final_realms_fluffos_v1/lib/d/newbie/halfling/rooms/cave/
final_realms_fluffos_v1/lib/d/newbie/human/
final_realms_fluffos_v1/lib/d/newbie/human/armour/
final_realms_fluffos_v1/lib/d/newbie/human/monsters/
final_realms_fluffos_v1/lib/d/newbie/human/obj/
final_realms_fluffos_v1/lib/d/newbie/human/weapons/
final_realms_fluffos_v1/lib/d/newbie/lizard/armour/
final_realms_fluffos_v1/lib/d/newbie/lizard/items/
final_realms_fluffos_v1/lib/d/newbie/lizard/underwater/
final_realms_fluffos_v1/lib/d/newbie/lizard/weapons/
final_realms_fluffos_v1/lib/d/newbie/logs/
final_realms_fluffos_v1/lib/d/newbie/new_halfelf/
final_realms_fluffos_v1/lib/d/newbie/new_halfelf/npcs/
final_realms_fluffos_v1/lib/d/newbie/newdrow/npcs/
final_realms_fluffos_v1/lib/d/newbie/newdrow/rooms/
final_realms_fluffos_v1/lib/d/newbie/newelf/
final_realms_fluffos_v1/lib/d/newbie/newelf/chars/
final_realms_fluffos_v1/lib/d/newbie/newelf/npcs/
final_realms_fluffos_v1/lib/d/newbie/newelf/npcs/recopied/
final_realms_fluffos_v1/lib/d/newbie/newelf/obj/
final_realms_fluffos_v1/lib/d/newbie/newelf/quest_docs./
final_realms_fluffos_v1/lib/d/newbie/newken/
final_realms_fluffos_v1/lib/d/newbie/newken/chars/
final_realms_fluffos_v1/lib/d/newbie/newken/misc/
final_realms_fluffos_v1/lib/d/newbie/newken/npcs/
final_realms_fluffos_v1/lib/d/newbie/newken/obj/
final_realms_fluffos_v1/lib/d/newbie/newliz/
final_realms_fluffos_v1/lib/d/newbie/newliz/cave/
final_realms_fluffos_v1/lib/d/newbie/newliz/npcs/
final_realms_fluffos_v1/lib/d/newbie/orc/items/misc/
final_realms_fluffos_v1/lib/d/newbie/orc/items/weapons/
final_realms_fluffos_v1/lib/d/newbie/orc/tower/
final_realms_fluffos_v1/lib/d/vehicle/
final_realms_fluffos_v1/lib/doc/
final_realms_fluffos_v1/lib/doc/driver/
final_realms_fluffos_v1/lib/doc/driver/concepts/
final_realms_fluffos_v1/lib/doc/driver/driver/
final_realms_fluffos_v1/lib/doc/driver/efuns/arrays/
final_realms_fluffos_v1/lib/doc/driver/efuns/bitstrings/
final_realms_fluffos_v1/lib/doc/driver/efuns/communication/
final_realms_fluffos_v1/lib/doc/driver/efuns/core/
final_realms_fluffos_v1/lib/doc/driver/efuns/debugging/
final_realms_fluffos_v1/lib/doc/driver/efuns/filesystem/
final_realms_fluffos_v1/lib/doc/driver/efuns/interactive/
final_realms_fluffos_v1/lib/doc/driver/efuns/mappings/
final_realms_fluffos_v1/lib/doc/driver/efuns/objects/
final_realms_fluffos_v1/lib/doc/driver/efuns/security/
final_realms_fluffos_v1/lib/doc/driver/efuns/strings/
final_realms_fluffos_v1/lib/doc/driver/efuns/system/
final_realms_fluffos_v1/lib/doc/driver/efuns/types/
final_realms_fluffos_v1/lib/doc/driver/lpc/constructs/
final_realms_fluffos_v1/lib/doc/driver/lpc/types/
final_realms_fluffos_v1/lib/doc/driver/platforms/
final_realms_fluffos_v1/lib/doc/lpc/
final_realms_fluffos_v1/lib/doc/mail/
final_realms_fluffos_v1/lib/doc/man/
final_realms_fluffos_v1/lib/doc/man/html/
final_realms_fluffos_v1/lib/doc/man/html/applies/
final_realms_fluffos_v1/lib/doc/man/html/applies/parsing/
final_realms_fluffos_v1/lib/doc/man/html/driver/
final_realms_fluffos_v1/lib/doc/man/html/efuns/
final_realms_fluffos_v1/lib/doc/man/html/efuns/arrays/
final_realms_fluffos_v1/lib/doc/man/html/efuns/buffers/
final_realms_fluffos_v1/lib/doc/man/html/efuns/compile/
final_realms_fluffos_v1/lib/doc/man/html/efuns/floats/
final_realms_fluffos_v1/lib/doc/man/html/efuns/functions/
final_realms_fluffos_v1/lib/doc/man/html/efuns/general/
final_realms_fluffos_v1/lib/doc/man/html/efuns/numbers/
final_realms_fluffos_v1/lib/doc/man/html/efuns/parsing/
final_realms_fluffos_v1/lib/doc/man/local/
final_realms_fluffos_v1/lib/doc/man/local/applies/
final_realms_fluffos_v1/lib/doc/man/local/applies/interactive/
final_realms_fluffos_v1/lib/doc/man/local/applies/master/
final_realms_fluffos_v1/lib/doc/man/local/concepts/
final_realms_fluffos_v1/lib/doc/man/local/defines/
final_realms_fluffos_v1/lib/doc/man/local/driver/
final_realms_fluffos_v1/lib/doc/man/local/efuns/
final_realms_fluffos_v1/lib/doc/man/local/efuns/arrays/
final_realms_fluffos_v1/lib/doc/man/local/efuns/buffers/
final_realms_fluffos_v1/lib/doc/man/local/efuns/calls/
final_realms_fluffos_v1/lib/doc/man/local/efuns/compile/
final_realms_fluffos_v1/lib/doc/man/local/efuns/filesystem/
final_realms_fluffos_v1/lib/doc/man/local/efuns/floats/
final_realms_fluffos_v1/lib/doc/man/local/efuns/functions/
final_realms_fluffos_v1/lib/doc/man/local/efuns/general/
final_realms_fluffos_v1/lib/doc/man/local/efuns/interactive/
final_realms_fluffos_v1/lib/doc/man/local/efuns/internals/
final_realms_fluffos_v1/lib/doc/man/local/efuns/mappings/
final_realms_fluffos_v1/lib/doc/man/local/efuns/mudlib/
final_realms_fluffos_v1/lib/doc/man/local/efuns/numbers/
final_realms_fluffos_v1/lib/doc/man/local/efuns/objects/
final_realms_fluffos_v1/lib/doc/man/local/efuns/parsing/
final_realms_fluffos_v1/lib/doc/man/local/efuns/sockets/
final_realms_fluffos_v1/lib/doc/man/local/efuns/strings/
final_realms_fluffos_v1/lib/doc/man/local/efuns/system/
final_realms_fluffos_v1/lib/doc/man/local/historical/
final_realms_fluffos_v1/lib/doc/man/local/lfun/QC/
final_realms_fluffos_v1/lib/doc/man/local/lfun/events/
final_realms_fluffos_v1/lib/doc/man/local/lfun/monster/
final_realms_fluffos_v1/lib/doc/man/local/lfun/properties/
final_realms_fluffos_v1/lib/doc/man/local/lpc/
final_realms_fluffos_v1/lib/doc/man/local/lpc/constructs/
final_realms_fluffos_v1/lib/doc/man/local/lpc/types/
final_realms_fluffos_v1/lib/doc/man/local/standards/
final_realms_fluffos_v1/lib/doc/man/local/tutorials/
final_realms_fluffos_v1/lib/doc/man/local/tutorials/basic/
final_realms_fluffos_v1/lib/doc/man/local/tutorials/intermediate/
final_realms_fluffos_v1/lib/doc/man/mudos/applies/
final_realms_fluffos_v1/lib/doc/man/mudos/applies/interactive/
final_realms_fluffos_v1/lib/doc/man/mudos/applies/parsing/
final_realms_fluffos_v1/lib/doc/man/mudos/concepts/
final_realms_fluffos_v1/lib/doc/man/mudos/driver/
final_realms_fluffos_v1/lib/doc/man/mudos/efuns/arrays/
final_realms_fluffos_v1/lib/doc/man/mudos/efuns/buffers/
final_realms_fluffos_v1/lib/doc/man/mudos/efuns/calls/
final_realms_fluffos_v1/lib/doc/man/mudos/efuns/compile/
final_realms_fluffos_v1/lib/doc/man/mudos/efuns/filesystem/
final_realms_fluffos_v1/lib/doc/man/mudos/efuns/floats/
final_realms_fluffos_v1/lib/doc/man/mudos/efuns/functions/
final_realms_fluffos_v1/lib/doc/man/mudos/efuns/general/
final_realms_fluffos_v1/lib/doc/man/mudos/efuns/mappings/
final_realms_fluffos_v1/lib/doc/man/mudos/efuns/mixed/
final_realms_fluffos_v1/lib/doc/man/mudos/efuns/mudlib/
final_realms_fluffos_v1/lib/doc/man/mudos/efuns/numbers/
final_realms_fluffos_v1/lib/doc/man/mudos/efuns/parsing/
final_realms_fluffos_v1/lib/doc/man/mudos/lpc/constructs/
final_realms_fluffos_v1/lib/doc/man/mudos/lpc/types/
final_realms_fluffos_v1/lib/doc/races/
final_realms_fluffos_v1/lib/doc/races/old_race/
final_realms_fluffos_v1/lib/global/virtual/
final_realms_fluffos_v1/lib/global/wiz_backup/
final_realms_fluffos_v1/lib/net/config/
final_realms_fluffos_v1/lib/net/daemon/chars/
final_realms_fluffos_v1/lib/net/inherit/
final_realms_fluffos_v1/lib/net/intermud3/
final_realms_fluffos_v1/lib/net/intermud3/cmds/
final_realms_fluffos_v1/lib/net/intermud3/save/
final_realms_fluffos_v1/lib/net/intermud3/services/
final_realms_fluffos_v1/lib/net/obj/
final_realms_fluffos_v1/lib/net/old/
final_realms_fluffos_v1/lib/net/old/intermud/
final_realms_fluffos_v1/lib/net/old/intermud/adm/
final_realms_fluffos_v1/lib/net/old/intermud/services/
final_realms_fluffos_v1/lib/net/old/intermud/udp/
final_realms_fluffos_v1/lib/net/virtual/
final_realms_fluffos_v1/lib/obj/b_day/
final_realms_fluffos_v1/lib/obj/chars/
final_realms_fluffos_v1/lib/obj/handlers/lists/
final_realms_fluffos_v1/lib/obj/handlers/useless/
final_realms_fluffos_v1/lib/obj/monsters/
final_realms_fluffos_v1/lib/obj/roomgen/
final_realms_fluffos_v1/lib/obj/soul/
final_realms_fluffos_v1/lib/obj/vegetation/
final_realms_fluffos_v1/lib/obj/weapons/oldsys/
final_realms_fluffos_v1/lib/open/
final_realms_fluffos_v1/lib/players/g/
final_realms_fluffos_v1/lib/releasefiles/d/heaven/
final_realms_fluffos_v1/lib/releasefiles/d/mudlib/
final_realms_fluffos_v1/lib/releasefiles/d/newbie/
final_realms_fluffos_v1/lib/releasefiles/doc/
final_realms_fluffos_v1/lib/releasefiles/players/g/
final_realms_fluffos_v1/lib/releasefiles/save/
final_realms_fluffos_v1/lib/releasefiles/save/environ/
final_realms_fluffos_v1/lib/releasefiles/save/roomgen/
final_realms_fluffos_v1/lib/releasefiles/secure/
final_realms_fluffos_v1/lib/releasefiles/w/
final_realms_fluffos_v1/lib/releasefiles/w/god/
final_realms_fluffos_v1/lib/room/
final_realms_fluffos_v1/lib/save/
final_realms_fluffos_v1/lib/save/environ/
final_realms_fluffos_v1/lib/save/roomgen/
final_realms_fluffos_v1/lib/scripts/
final_realms_fluffos_v1/lib/secure/crerem/
final_realms_fluffos_v1/lib/secure/dom/
final_realms_fluffos_v1/lib/secure/log/
final_realms_fluffos_v1/lib/secure/misc/
final_realms_fluffos_v1/lib/std/adnd/
final_realms_fluffos_v1/lib/std/commands/shadows/
final_realms_fluffos_v1/lib/std/creator/
final_realms_fluffos_v1/lib/std/curses/
final_realms_fluffos_v1/lib/std/curses/old_sys/
final_realms_fluffos_v1/lib/std/curses/shadows/
final_realms_fluffos_v1/lib/std/dom/
final_realms_fluffos_v1/lib/std/effects/
final_realms_fluffos_v1/lib/std/effects/healing/
final_realms_fluffos_v1/lib/std/effects/other/
final_realms_fluffos_v1/lib/std/effects/poisons/
final_realms_fluffos_v1/lib/std/environ/
final_realms_fluffos_v1/lib/std/guilds/
final_realms_fluffos_v1/lib/std/guilds/priests/samples/
final_realms_fluffos_v1/lib/std/guilds/wizards/
final_realms_fluffos_v1/lib/std/living/baldy/
final_realms_fluffos_v1/lib/std/living/divstuff/
final_realms_fluffos_v1/lib/std/paran/
final_realms_fluffos_v1/lib/std/poisons/
final_realms_fluffos_v1/lib/std/poisons/shadows/
final_realms_fluffos_v1/lib/std/poisons/weapons/
final_realms_fluffos_v1/lib/std/race_groups/
final_realms_fluffos_v1/lib/std/room/
final_realms_fluffos_v1/lib/std/room/old/
final_realms_fluffos_v1/lib/std/rooms/
final_realms_fluffos_v1/lib/std/shadows/
final_realms_fluffos_v1/lib/std/shadows/test_shad/
final_realms_fluffos_v1/lib/std/socket/
final_realms_fluffos_v1/lib/std/spells/
final_realms_fluffos_v1/lib/std/vaults/
final_realms_fluffos_v1/lib/tmp/
final_realms_fluffos_v1/lib/w/
final_realms_fluffos_v1/lib/w/god/
final_realms_fluffos_v1/old/
final_realms_fluffos_v1/win32/
#define SUPPRESS_COMPILER_INLINES
#include "std.h"
#include "lpc_incl.h"
#include "eoperators.h"
#include "compiler.h"
#include "replace_program.h"

INLINE void
dealloc_funp (funptr_t * fp)
{
    program_t *prog = 0;

    switch (fp->hdr.type) {
        case FP_LOCAL | FP_NOT_BINDABLE:
            if (fp->hdr.owner)
                prog = fp->hdr.owner->prog;
            break;
        case FP_FUNCTIONAL:
        case FP_FUNCTIONAL | FP_NOT_BINDABLE:
            prog = fp->f.functional.prog;
            break;
    }

    if (fp->hdr.owner)
        free_object(&fp->hdr.owner, "free_funp");
    if (fp->hdr.args)
        free_array(fp->hdr.args);

    if (prog) {
        prog->func_ref--;
        debug(d_flag, ("subtr func ref /%s: now %i\n",
                    prog->filename, prog->func_ref));
        if (!prog->func_ref && !prog->ref)
            deallocate_program(prog);
    }

    FREE(fp);
}

INLINE void
free_funp (funptr_t * fp)
{
    fp->hdr.ref--;
    if (fp->hdr.ref > 0) {
        return;
    }
    dealloc_funp(fp);
}

INLINE void
push_refed_funp (funptr_t * fp)
{
    STACK_INC;
    sp->type = T_FUNCTION;
    sp->u.fp = fp;
}

INLINE void
push_funp (funptr_t * fp)
{
    STACK_INC;
    sp->type = T_FUNCTION;
    sp->u.fp = fp;
    fp->hdr.ref++;
}

/* num_arg args are on the stack, and the args from the array vec should be
 * put in front of them.  This is so that the order of arguments is logical.
 * 
 * evaluate( (: f, a :), b) -> f(a,b) and not f(b, a) which would happen
 * if we simply pushed the args from vec at this point.  (Note that the
 * old function pointers are broken in this regard)
 */
int merge_arg_lists (int num_arg, array_t * arr, int start) {
    int num_arr_arg = arr->size - start;
    svalue_t *sptr;
    
    if (num_arr_arg) {
        CHECK_STACK_OVERFLOW(num_arr_arg);
        sptr = (sp += num_arr_arg);
        if (num_arg) {
            /* We need to do some stack movement so that the order
               of arguments is logical */
            while (num_arg--) {
                *sptr = *(sptr - num_arr_arg);
                sptr--;
            }
        }
        num_arg = arr->size;
        while (--num_arg >= start)
            assign_svalue_no_free(sptr--, &arr->item[num_arg]);
        /* could just return num_arr_arg if num_arg is 0 but .... -Sym */
        return (sp - sptr);
    }       
    return num_arg;
}

INLINE funptr_t *
make_efun_funp (int opcode, svalue_t * args)
{
    funptr_t *fp;
    
    fp = (funptr_t *)DXALLOC(sizeof(funptr_t),
                             TAG_FUNP, "make_efun_funp");
    fp->hdr.owner = current_object;
    add_ref( current_object, "make_efun_funp" );
    fp->hdr.type = FP_EFUN;
    
    fp->f.efun.index = opcode;
    
    if (args->type == T_ARRAY) {
        fp->hdr.args = args->u.arr;
        args->u.arr->ref++;
    } else
        fp->hdr.args = 0;
    
    fp->hdr.ref = 1;
    return fp;
}

INLINE funptr_t *
make_lfun_funp (int index, svalue_t * args)
{
    funptr_t *fp;
    int newindex;

    if (replace_program_pending(current_object))
        error("cannot bind an lfun fp to an object with a pending replace_program()\n");

    fp = (funptr_t *)DXALLOC(sizeof(funptr_hdr_t) + sizeof(local_ptr_t),
                             TAG_FUNP, "make_lfun_funp");
    fp->hdr.owner = current_object;
    add_ref( current_object, "make_lfun_funp" );
    fp->hdr.type = FP_LOCAL | FP_NOT_BINDABLE;
    
    fp->hdr.owner->prog->func_ref++;
    debug(d_flag, ("add func ref /%s: now %i\n",
                fp->hdr.owner->prog->filename,
                fp->hdr.owner->prog->func_ref));
    
    newindex = index + function_index_offset;
    if (current_object->prog->function_flags[newindex] & FUNC_ALIAS)
        newindex = current_object->prog->function_flags[newindex] & ~FUNC_ALIAS;
    fp->f.local.index = newindex;
    
    if (args->type == T_ARRAY) {
        fp->hdr.args = args->u.arr;
        args->u.arr->ref++;
    } else
        fp->hdr.args = 0;
    
    fp->hdr.ref = 1;
    return fp;
}

INLINE funptr_t *
make_simul_funp (int index, svalue_t * args)
{
    funptr_t *fp;
    
    fp = (funptr_t *)DXALLOC(sizeof(funptr_hdr_t) + sizeof(simul_ptr_t),
                             TAG_FUNP, "make_simul_funp");
    fp->hdr.owner = current_object;
    add_ref( current_object, "make_simul_funp" );
    fp->hdr.type = FP_SIMUL;
    
    fp->f.simul.index = index;
    
    if (args->type == T_ARRAY) {
        fp->hdr.args = args->u.arr;
        args->u.arr->ref++;
    } else
        fp->hdr.args = 0;
    
    fp->hdr.ref = 1;
    return fp;
}

INLINE funptr_t *
make_functional_funp (short num_arg, short num_local, short len, svalue_t * args, int flag)
{
    funptr_t *fp;

    if (replace_program_pending(current_object))
        error("cannot bind a functional to an object with a pending replace_program()\n");
    
    fp = (funptr_t *)DXALLOC(sizeof(funptr_hdr_t) + sizeof(functional_t), 
                             TAG_FUNP, "make_functional_funp");
    fp->hdr.owner = current_object;
    add_ref( current_object, "make_functional_funp" );
    fp->hdr.type = FP_FUNCTIONAL + flag;
    
    current_prog->func_ref++;
    debug(d_flag, ("add func ref /%s: now %i\n",
               current_prog->filename,
               current_prog->func_ref));
    
    fp->f.functional.prog = current_prog;
    fp->f.functional.offset = pc - current_prog->program;
    fp->f.functional.num_arg = num_arg;
    fp->f.functional.num_local = num_local;
    fp->f.functional.fio = function_index_offset;
    fp->f.functional.vio = variable_index_offset;
    pc += len;
    
    if (args && args->type == T_ARRAY) {
        fp->hdr.args = args->u.arr;
        args->u.arr->ref++;
        fp->f.functional.num_arg += args->u.arr->size;
    } else
        fp->hdr.args = 0;
    
    fp->hdr.ref = 1;
    return fp;
}

typedef void (*func_t) (void);
extern func_t efun_table[];

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;
}

svalue_t *
safe_call_function_pointer (funptr_t * funp, int num_arg)
{
    error_context_t econ;
    svalue_t *ret;

    if (!save_context(&econ))
        return 0;
    if (!SETJMP(econ.context)) {
        ret = call_function_pointer(funp, num_arg);
    } else {
        restore_context(&econ);
        /* condition was restored to where it was when we came in */
        pop_n_elems(num_arg);
        ret = 0;
    }
    pop_context(&econ);
    return ret;
}