/* * 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); } }
/* * 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); }
/* * 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_; }
/* * 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); } }