diff --git a/src/object.c b/src/object.c index 9994d09e4e7acb818aa18364eea0adb23fbef866..2d5ea75b0c5f2322f1fd330f28303456cf3565ff 100644 --- a/src/object.c +++ b/src/object.c @@ -3259,6 +3259,97 @@ void init_object(void) exit_compiler(); } +static struct program *shm_program, *sbuf_program, *iobuf_program; + +struct sysmem { + unsigned char *p; + size_t size; +}; + +static struct sysmem *system_memory(struct object *o) +{ + if( !shm_program ) + { + push_text("System.Memory"); + SAFE_APPLY_MASTER("resolv", 1); + shm_program = program_from_svalue(Pike_sp - 1); + if (!shm_program) + return 0; + Pike_sp--; + } + return get_storage( o, shm_program ); +} + +static struct string_builder *string_buffer(struct object *o) +{ + if( !sbuf_program ) + { + push_text("String.Buffer"); + SAFE_APPLY_MASTER("resolv", 1); + sbuf_program = program_from_svalue(Pike_sp - 1); + if (!sbuf_program) + return 0; + Pike_sp--; + } + return get_storage( o, sbuf_program ); +} + +#include "modules/_Stdio/iobuffer.h" + +static IOBuffer *io_buffer(struct object *o) +{ + if( !iobuf_program ) + { + push_text("Stdio.IOBuffer"); + SAFE_APPLY_MASTER("resolv", 1); + iobuf_program = program_from_svalue(Pike_sp - 1); + if (!iobuf_program) + return 0; + Pike_sp--; + } + return get_storage( o, iobuf_program ); +} + +PMOD_EXPORT enum memobj_type get_memory_object_memory( struct object *o, void **ptr, size_t *len, int *shift ) +{ + union { + struct string_builder *b; + struct sysmem *s; + IOBuffer *io; + } src; + + if( (src.b = string_buffer(o)) ) + { + if( src.b->s->size_shift ) + { + if( shift ) + *shift = src.b->s->size_shift; + else + return MEMOBJ_NONE; + } + if( len ) *len = src.b->s->len; + if( ptr ) *ptr = src.b->s->str; + return MEMOBJ_STRING_BUFFER; + } + + if( (src.io = io_buffer( o )) ) + { + if( shift ) *shift=0; + if( len ) *len = src.io->len-src.io->offset; + if( ptr ) *ptr=src.io->buffer+src.io->offset; + return MEMOBJ_STDIO_IOBUFFER; + } + + if( (src.s = system_memory(o)) ) + { + if( shift ) *shift=0; + if( len ) *len = src.s->size; + if( ptr ) *ptr= src.s->p; + return MEMOBJ_SYSTEM_MEMORY; + } + return MEMOBJ_NONE; +} + void exit_object(void) { if (destruct_object_evaluator_callback) { @@ -3281,6 +3372,23 @@ void exit_object(void) destruct_objects_to_destruct(); + if( shm_program ) + { + free_program( shm_program ); + shm_program = 0; + } + if( sbuf_program ) + { + free_program( sbuf_program ); + sbuf_program = 0; + } + + if( iobuf_program ) + { + free_program( iobuf_program ); + iobuf_program = 0; + } + if(magic_index_program) { free_program(magic_index_program); diff --git a/src/object.h b/src/object.h index 4e3f6d91d2fb795d90bcba3db6791f0d8918bd6e..4d584093e57470414c124de9caea1b6e88689fd7 100644 --- a/src/object.h +++ b/src/object.h @@ -142,6 +142,17 @@ PMOD_EXPORT void visit_function (const struct svalue *s, int ref_type, void *extra); PMOD_EXPORT void gc_mark_object_as_referenced(struct object *o); PMOD_EXPORT void real_gc_cycle_check_object(struct object *o, int weak); + +enum memobj_type{ + MEMOBJ_NONE, + MEMOBJ_SYSTEM_MEMORY, + MEMOBJ_STRING_BUFFER, + MEMOBJ_STDIO_IOBUFFER, +}; + +PMOD_EXPORT enum memobj_type get_memory_object_memory( struct object *o, void **ptr, size_t *len, int *shift ); + + unsigned gc_touch_all_objects(void); void gc_check_all_objects(void); void gc_mark_all_objects(void);