Exemple #1
0
/*
 *   save
 */
void CVmObjFrameRef::save_to_file(VMG_ class CVmFile *fp)
{
    char buf[VMB_DATAHOLDER];
    
    /* get our extension */
    vm_frameref_ext *ext = get_ext();
    
    /* 
     *   If our frame is still active, make a snapshot of the variables.  The
     *   stack frame itself is inherently transient, so we can only save the
     *   snapshot version.  
     */
    if (ext->fp != 0)
        make_snapshot(vmg0_);

    /* save the variable counts */
    fp->write_uint2(ext->nlocals);
    fp->write_uint2(ext->nparams);

    /* save the entry pointer */
    vmb_put_dh(buf, &ext->entry);
    fp->write_bytes(buf, VMB_DATAHOLDER);

    /* save the method context values */
    vmb_put_dh(buf, &ext->self);
    fp->write_bytes(buf, VMB_DATAHOLDER);
    fp->write_uint4(ext->defobj);
    fp->write_uint4(ext->targobj);
    fp->write_uint2(ext->targprop);
    vmb_put_dh(buf, &ext->invokee);
    fp->write_bytes(buf, VMB_DATAHOLDER);

    /* save the variable snapshot values */
    int i;
    const vm_val_t *v;
    for (i = ext->nparams + ext->nlocals, v = ext->vars ; i > 0 ; --i, ++v)
    {
        vmb_put_dh(buf, v);
        fp->write_bytes(buf, VMB_DATAHOLDER);
    }
}
Exemple #2
0
/* 
 *   save to a file 
 */
void CVmObjClass::save_to_file(VMG_ class CVmFile *fp)
{
    /* write our data: data size, meta table index, mod ID, class state */
    vm_intcls_ext *ext = get_ext();
    fp->write_uint2(2 + 2 + 4 + VMB_DATAHOLDER);
    fp->write_uint2(ext->meta_idx);
    fp->write_uint4(ext->mod_obj);

    char buf[VMB_DATAHOLDER];
    vmb_put_dh(buf, &ext->class_state);
    fp->write_bytes(buf, VMB_DATAHOLDER);
}
Exemple #3
0
/*
 *   write a symbolic name item 
 */
void CVmImageWriter::write_sym_item(const char *nm, size_t len,
                                    const vm_val_t *val)
{
    char buf[VMB_DATAHOLDER + 1];

    /* prepare the data holder in the prefix */
    vmb_put_dh(buf, val);

    /* limit the length to 255 bytes */
    if (len > 255)
        len = 255;

    /* add the length to the prefix */
    buf[VMB_DATAHOLDER] = (char)len;

    /* write the prefix */
    fp_->write_bytes(buf, VMB_DATAHOLDER + 1);

    /* write the string */
    fp_->write_bytes(nm, len);

    /* count it */
    ++symd_cnt_;
}
Exemple #4
0
/*
 *   Object Property list entry - value node
 */
void CTPNObjProp::gen_code(int, int)
{
    vm_val_t val;
    char buf[VMB_DATAHOLDER];
    CTcDataStream *str;

    /* get the correct data stream */
    str = obj_stm_->get_obj_sym()->get_stream();

    /* set the current source location for error reporting */
    G_tok->set_line_info(file_, linenum_);

    /* generate code for our expression or our code body, as appropriate */
    if (expr_ != 0)
    {
        /* 
         *   if my value is constant, write out a dataholder for the
         *   constant value to the stream; otherwise, write out our code
         *   and store a pointer to the code 
         */
        if (expr_->is_const())
        {
            /* write the constant value to the object stream */
            G_cg->write_const_as_dh(str, str->get_ofs(),
                                    expr_->get_const_val());
        }
        else if (expr_->is_dstring())
        {
            CTPNDstr *dstr;
            
            /* it's a double-quoted string node */
            dstr = (CTPNDstr *)expr_;
            
            /* 
             *   Add the string to the constant pool.  Note that the fixup
             *   will be one byte from the current object stream offset,
             *   since we need to write the type byte first.  
             */
            G_cg->add_const_str(dstr->get_str(), dstr->get_str_len(),
                                str, str->get_ofs() + 1);

            /* 
             *   Set up the dstring value.  Use a zero placeholder for
             *   now; add_const_str() already added a fixup for us that
             *   will supply the correct value at link time.  
             */
            val.set_dstring(0);
            vmb_put_dh(buf, &val);
            str->write(buf, VMB_DATAHOLDER);
        }
        else
        {
            /* we should never get here */
            G_tok->throw_internal_error(TCERR_INVAL_PROP_CODE_GEN);
        }
    }
    else if (code_body_ != 0)
    {
        char buf[VMB_DATAHOLDER];
        vm_val_t val;

        /* if this is a constructor, mark the code body accordingly */
        if (prop_sym_->get_prop() == G_prs->get_constructor_prop())
            code_body_->set_constructor(TRUE);

        /* if it's static, do some extra work */
        if (is_static_)
        {
            /* mark the code body as static */
            code_body_->set_static();

            /* 
             *   add the obj.prop to the static ID stream, so the VM knows
             *   to invoke this initializer at start-up 
             */
            G_static_init_id_stream
                ->write_obj_id(obj_stm_->get_obj_sym()->get_obj_id());
            G_static_init_id_stream
                ->write_prop_id(prop_sym_->get_prop());
        }
        
        /* tell our code body to generate the code */
        code_body_->gen_code(FALSE, FALSE);
        
        /* 
         *   Set up our code offset value.  Write a code offset of zero
         *   for now, since we won't know the correct offset until link
         *   time.  
         */
        val.set_codeofs(0);
        
        /* 
         *   Add a fixup to the code body's fixup list for our dataholder,
         *   so that we fix up the property value when we link.  Note that
         *   the fixup is one byte into our object stream from the current
         *   offset, because the first byte is the type.  
         */
        CTcAbsFixup::add_abs_fixup(code_body_->get_fixup_list_head(),
                                   str, str->get_ofs() + 1);
        
        /* write out our value in DATAHOLDER format */
        vmb_put_dh(buf, &val);
        str->write(buf, VMB_DATAHOLDER);
    }
}