/* load image data */ void CVmObjClass::load_image_data(VMG_ vm_obj_id_t self, const char *ptr, size_t siz) { /* make sure the length is valid */ if (siz < 8) err_throw(VMERR_INVAL_METACLASS_DATA); /* allocate or reallocate the extension */ vm_intcls_ext *ext = alloc_ext(vmg0_); /* * read the metaclass index and modifier object ID; note that modifier * objects are always root set objects, so there's no need to worry * about fixups */ ext->meta_idx = osrp2(ptr+2); ext->mod_obj = (vm_obj_id_t)t3rp4u(ptr+4); /* if we have a class state value, read it */ ext->class_state.set_nil(); if (siz >= 2+4+VMB_DATAHOLDER) vmb_get_dh(ptr+8, &ext->class_state); /* register myself */ register_meta(vmg_ self); }
/* * construction */ CVmObjFrameDesc::CVmObjFrameDesc(VMG_ vm_obj_id_t fref, int frame_idx, uint ret_ofs) { /* allocate our extension */ ext_ = 0; alloc_ext(vmg_ fref, frame_idx, ret_ofs); }
/* * restore from a file */ void CVmObjClass::restore_from_file(VMG_ vm_obj_id_t self, CVmFile *fp, CVmObjFixup *fixups) { /* allocate/reallocate the extension */ vm_intcls_ext *ext = alloc_ext(vmg0_); /* read the length */ size_t len = fp->read_uint2(); const size_t expected_len = 2+2+4+VMB_DATAHOLDER; /* * read the metaclass index and modifier object ID; note that modifier * objects are always root set objects, so there's no need to worry * about fixups */ ext->meta_idx = fp->read_uint2(); ext->mod_obj = (vm_obj_id_t)fp->read_uint4(); /* if we have a class state value, read it */ ext->class_state.set_nil(); if (len >= 2+2+4+VMB_DATAHOLDER) { char buf[VMB_DATAHOLDER]; fp->read_bytes(buf, VMB_DATAHOLDER); fixups->fix_dh(vmg_ buf); vmb_get_dh(buf, &ext->class_state); } /* skip any extra data we don't recognize */ if (len > expected_len) fp->set_pos_from_cur(len - expected_len); /* register myself with the metaclass table */ register_meta(vmg_ self); }
/* * restore */ void CVmObjFrameRef::restore_from_file(VMG_ vm_obj_id_t self, class CVmFile *fp, class CVmObjFixup *fixups) { char buf[VMB_DATAHOLDER]; /* read the variables counts */ int nlocals = fp->read_int2(); int nparams = fp->read_int2(); /* allocate the extension */ vm_frameref_ext *ext = alloc_ext(vmg_ nlocals, nparams); /* * Since stack frames are inherently transient, a saved frame ref * object can't point back to a live stack frame, so on restore we have * to assume that our stack frame is inactive. */ get_ext()->fp = 0; /* load the entry pointer */ fp->read_bytes(buf, VMB_DATAHOLDER); fixups->fix_dh(vmg_ buf); vmb_get_dh(buf, &ext->entry); /* after other objects are loaded, resolve the entry pointer */ G_obj_table->request_post_load_init(self); /* restore the method context values */ fp->read_bytes(buf, VMB_DATAHOLDER); fixups->fix_dh(vmg_ buf); vmb_get_dh(buf, &ext->self); ext->defobj = (vm_obj_id_t)fp->read_uint4(); if (ext->defobj != VM_INVALID_OBJ) ext->defobj = fixups->get_new_id(vmg_ ext->defobj); ext->targobj = (vm_obj_id_t)fp->read_uint4(); if (ext->targobj != VM_INVALID_OBJ) ext->targobj = fixups->get_new_id(vmg_ ext->targobj); ext->targprop = (vm_prop_id_t)fp->read_uint2(); fp->read_bytes(buf, VMB_DATAHOLDER); fixups->fix_dh(vmg_ buf); vmb_get_dh(buf, &ext->invokee); /* load the snapshot values */ int i; vm_val_t *v; for (i = nlocals + nparams, v = ext->vars ; i > 0 ; --i, ++v) { fp->read_bytes(buf, VMB_DATAHOLDER); fixups->fix_dh(vmg_ buf); vmb_get_dh(buf, v); } }
/* * load or reload our image data */ void CVmObjFrameDesc::load_image_data(VMG_ vm_obj_id_t self, const char *ptr, size_t siz) { /* read the frame information */ vm_obj_id_t fref = vmb_get_objid(ptr); int frame_idx = osrp2(ptr + VMB_OBJECT_ID); uint ret_ofs = osrp2(ptr + VMB_OBJECT_ID + 2); /* allocate the extension */ alloc_ext(vmg_ fref, frame_idx, ret_ofs); }
/* * restore */ void CVmObjFrameDesc::restore_from_file(VMG_ vm_obj_id_t self, class CVmFile *fp, class CVmObjFixup *fixups) { /* read the values */ vm_obj_id_t fref = fixups->get_new_id(vmg_ (vm_obj_id_t)fp->read_uint4()); int frame_idx = fp->read_int2(); uint ret_ofs = fp->read_uint2(); /* allocate the extension */ alloc_ext(vmg_ fref, frame_idx, ret_ofs); }
/* * load or reload our image data */ void CVmObjFrameRef::load_image_data(VMG_ vm_obj_id_t self, const char *ptr, size_t siz) { /* read the number of variables */ int nlocals = osrp2(ptr); int nparams = osrp2(ptr+2); ptr += 4; /* allocate the extension */ vm_frameref_ext *ext = alloc_ext(vmg_ nlocals, nparams); /* * Since stack frames are inherently transient, a saved frame ref * object can't point back to a live stack frame, so on restore we have * to assume that our stack frame is inactive. */ ext->fp = 0; /* load the entry pointer */ vmb_get_dh(ptr, &ext->entry); ptr += VMB_DATAHOLDER; /* after other objects are loaded, resolve the entry pointer */ G_obj_table->request_post_load_init(self); /* load the method context variables */ vmb_get_dh(ptr, &ext->self); ptr += VMB_DATAHOLDER; ext->defobj = vmb_get_objid(ptr); ptr += VMB_OBJECT_ID; ext->targobj = vmb_get_objid(ptr); ptr += VMB_OBJECT_ID; ext->targprop = vmb_get_propid(ptr); ptr += VMB_PROP_ID; vmb_get_dh(ptr, &ext->invokee); ptr += VMB_DATAHOLDER; /* read the variable snapshot values */ int i; vm_val_t *v; for (i = nlocals + nparams, v = ext->vars ; i > 0 ; --i, ++v) { vmb_get_dh(ptr, v); ptr += VMB_DATAHOLDER; } }
/* * create with a given dependency index */ CVmObjClass::CVmObjClass(VMG_ int in_root_set, uint meta_idx, vm_obj_id_t self) { /* calls of this form can't come from the image file */ assert(!in_root_set); /* allocate the extension */ ext_ = 0; vm_intcls_ext *ext = alloc_ext(vmg0_); /* set up the extension */ ext->meta_idx = meta_idx; ext->mod_obj = VM_INVALID_OBJ; ext->class_state.set_nil(); ext->changed = FALSE; /* register myself with the metaclass table */ register_meta(vmg_ self); }
/* * construction */ CVmObjFrameRef::CVmObjFrameRef(VMG_ vm_val_t *fp, const uchar *entry) { /* set up a function pointer */ CVmFuncPtr f(entry); /* * figure the total number of variable snapshot slots we need to * allocate: this is the number of local variables plus the number of * actual arguments */ int nlocals = f.get_local_cnt(); int nparams = G_interpreter->get_argc_from_frame(vmg_ fp); /* allocate our extension */ ext_ = 0; vm_frameref_ext *ext = alloc_ext(vmg_ nlocals, nparams); /* save the extra frame information */ ext->fp = fp; ext->entryp = entry; /* get the function pointer value for the entry pointer */ f.get_fnptr(vmg_ &ext->entry); /* initialize the variable slots to nil */ for (int i = 0 ; i < nlocals + nparams ; ++i) ext->vars[i].set_nil(); /* * save the method context variables - these are immutable, so we can * save them immediately */ ext->self = *G_interpreter->get_self_val_from_frame(vmg_ fp); ext->defobj = G_interpreter->get_defining_obj_from_frame(vmg_ fp); ext->targobj = G_interpreter->get_orig_target_obj_from_frame(vmg_ fp); ext->defobj = G_interpreter->get_defining_obj_from_frame(vmg_ fp); }