Exemplo n.º 1
0
/*
 *   Execute an image file.  If an exception occurs, we'll display a
 *   message on the console, and we'll return the error code; we'll return
 *   zero on success.  If an error occurs, we'll fill in 'errbuf' with a
 *   message describing the problem.  
 */
int vm_run_image(CVmMainClientIfc *clientifc,
                 const char *image_file_name,
                 class CVmHostIfc *hostifc,
                 const char *const *prog_argv, int prog_argc,
                 const char *script_file, int script_quiet,
                 const char *log_file, const char *cmd_log_file,
                 int load_from_exe, int show_banner,
                 const char *charset, const char *log_charset,
                 const char *saved_state, const char *res_dir)
{
    CVmFile *fp = 0;
    CVmImageLoader *volatile loader = 0;
    CVmImageFile *volatile imagefp = 0;
    unsigned long image_file_base = 0;
    int retval;
    vm_globals *vmg__;

    /* presume we will return success */
    retval = 0;

    /* create the file object */
    fp = new CVmFile();

    /* initialize the VM */
    vm_init_options opts(hostifc, clientifc, charset, log_charset);
    vm_initialize(&vmg__, &opts);

    /* tell the client system to initialize */
    clientifc->client_init(VMGLOB_ADDR, script_file, script_quiet,
                           log_file, cmd_log_file,
                           show_banner ? T3VM_BANNER_STRING : 0);

    /* catch any errors that occur during loading and running */
    err_try
    {
        /* remember the name of the byte-code file */
        strncpy(G_os_gamename, image_file_name, sizeof(G_os_gamename));
        G_os_gamename[sizeof(G_os_gamename) - 1] = '\0';

        if (load_from_exe)
        {
            osfildef *exe_fp;

            /* find the image within the executable */
            exe_fp = os_exeseek(image_file_name, "TGAM");
            if (exe_fp == 0)
                err_throw(VMERR_NO_IMAGE_IN_EXE);

            /* 
             *   set up to read from the executable at the location of the
             *   embedded image file that we just found 
             */
            image_file_base = osfpos(exe_fp);
            fp->set_file(exe_fp, image_file_base);
        }
        else
        {
            /* reading from a normal file - open the file */
            fp->open_read(image_file_name, OSFTT3IMG);
        }

        /* create the loader */
        imagefp = new CVmImageFileExt(fp);
        loader = new CVmImageLoader(imagefp, image_file_name,
                                    image_file_base);

        /* load the image */
        loader->load(vmg0_);

        /* if we have a resource root path, tell the host interface */
        if (res_dir != 0)
            hostifc->set_res_dir(res_dir);

        /* let the client prepare for execution */
        clientifc->pre_exec(VMGLOB_ADDR);

        /* run the program from the main entrypoint */
        loader->run(vmg_ prog_argv, prog_argc, 0, saved_state);

        /* tell the client we're done with execution */
        clientifc->post_exec(VMGLOB_ADDR);
    }
    err_catch(exc)
    {
        char errbuf[512];

        /* tell the client execution failed due to an error */
        clientifc->post_exec_err(VMGLOB_ADDR);

        /* note the error code for returning to the caller */
        retval = exc->get_error_code();

        /* get the message for the error */
        CVmRun::get_exc_message(vmg_ exc, errbuf, sizeof(errbuf), TRUE);
        
        /* display the message */
        clientifc->display_error(VMGLOB_ADDR, errbuf, FALSE);
    }
    err_end;

    /* unload the image */
    if (loader != 0)
        loader->unload(vmg0_);

    /* delete the loader and the image file object */
    if (loader != 0)
        delete loader;
    if (imagefp != 0)
        delete imagefp;

    /* notify the client */
    clientifc->client_terminate(VMGLOB_ADDR);

    /* terminate the VM */
    vm_terminate(vmg__, clientifc);

    /* delete the file */
    if (fp != 0)
        delete fp;

    /* return the status code */
    return retval;
}
Exemplo n.º 2
0
/*
 *   Run pre-initialization 
 */
void vm_run_preinit(CVmFile *origfp, const char *image_fname,
                    CVmFile *newfp, class CVmHostIfc *hostifc,
                    class CVmMainClientIfc *clientifc, 
                    const char *const *argv, int argc,
                    class CVmRuntimeSymbols *runtime_symtab,
                    class CVmRuntimeSymbols *runtime_macros)
{
    vm_globals *vmg__;
    CVmImageLoader *volatile loader = 0;
    CVmImageFile *volatile imagefp = 0;

    /* initialize the VM */
    vm_init_options opts(hostifc, clientifc);
    vm_initialize(&vmg__, &opts);

    /* 
     *   turn off "more" on the console - when running preinitialization,
     *   any output is purely diagnostic information for the programmer
     *   and thus should be formatted as simple stdio-style console output 
     */
    G_console->set_more_state(FALSE);

    err_try
    {
        /* note where the image file starts */
        long start_pos = origfp->get_pos();
        
        /* create the loader */
        imagefp = new CVmImageFileExt(origfp);
        loader = new CVmImageLoader(imagefp, image_fname, 0);

        /* load the image */
        loader->load(vmg0_);

        /* set pre-init mode */
        G_preinit_mode = TRUE;

        /* run it, using the runtime symbols the caller sent us */
        loader->run(vmg_ argv, argc, runtime_symtab, runtime_macros, 0);

        /* 
         *   seek back to the start of the image file, since we need to
         *   copy parts of the original file to the new file 
         */
        origfp->set_pos(start_pos);

        /* save the new image file */
        vm_rewrite_image(vmg_ origfp, newfp, loader->get_static_cs_ofs());
    }
    err_finally
    {
        /* detach the pools from the image file */
        if (loader != 0)
            loader->unload(vmg0_);

        /* delete the loader and the image file object */
        if (loader != 0)
            delete loader;
        if (imagefp != 0)
            delete imagefp;

        /* terminate the VM */
        vm_terminate(vmg__, clientifc);
    }
    err_end;
}
Exemplo n.º 3
0
int main(int argc, char **argv)
{
    CImageFile *imagefp;
    vm_val_t val;
    vm_val_t *stkval;
    vm_globals *vmg__;
    CVmHostIfc *hostifc;
    CVmMainClientConsole clientifc;

    /* initialize for testing */
    test_init();

    /* initialize the VM */
    hostifc = new CVmHostIfcStdio(argv[0]);
    vm_initialize(&vmg__, &vm_init_options(hostifc, &clientifc,
                                           "us-ascii", "us_ascii"));

    /* create a fake host file object */
    imagefp = new CImageFile();

    /* create the constant pool */
    G_const_pool->attach_backing_store(imagefp);

    /* create a couple of objects and push them on the stack */
    val.set_obj(CVmObjTads::create(vmg_ FALSE, 0, 4));
    G_stk->push(&val);
    val.set_obj(CVmObjTads::create(vmg_ FALSE, 0, 4));
    G_stk->push(&val);

    /* 
     *   create another object, and store it in a property of the first
     *   object 
     */
    val.set_obj(CVmObjTads::create(vmg_ FALSE, 0, 4));
    stkval = G_stk->get(1);
    vm_objp(vmg_ stkval->val.obj)->
        set_prop(vmg_ G_undo, stkval->val.obj, PROP_A, &val);

    /* collect garbage - nothing should be deleted at this point */
    G_obj_table->gc_full(vmg0_);

    /* 
     *   forget about the second object by popping it off the stack, then
     *   collect garbage again -- the second object should be deleted at
     *   this point, because it's no longer reachable 
     */
    G_stk->discard();
    G_obj_table->gc_full(vmg0_);

    /*
     *   Force the first object's property table to expand by filling up
     *   its initial table 
     */
    stkval = G_stk->get(0);
    val.set_nil();
    vm_objp(vmg_ stkval->val.obj)->
        set_prop(vmg_ G_undo, stkval->val.obj, PROP_A, &val);
    vm_objp(vmg_ stkval->val.obj)->
        set_prop(vmg_ G_undo, stkval->val.obj, PROP_B, &val);
    vm_objp(vmg_ stkval->val.obj)->
        set_prop(vmg_ G_undo, stkval->val.obj, PROP_C, &val);
    vm_objp(vmg_ stkval->val.obj)->
        set_prop(vmg_ G_undo, stkval->val.obj, PROP_D, &val);
    vm_objp(vmg_ stkval->val.obj)->
        set_prop(vmg_ G_undo, stkval->val.obj, PROP_E, &val);

    /* set an existing property */
    vm_objp(vmg_ stkval->val.obj)->
        set_prop(vmg_ G_undo, stkval->val.obj, PROP_B, &val);
    
    /* we're done, so delete all of our managers */
    G_const_pool->detach_backing_store();
    delete imagefp;

    /* shut down the VM */
    vm_terminate(vmg__, &clientifc);

    /* delete the host interface */
    delete hostifc;

    /* terminate */
    return 0;
}