rev 749 - in trunk: include/prothon modules/DBM modules/OS modules/Prosist modules/Re modules/SQLite src

SVN User <[email protected]> Sun, 18 Jul 2004 00:26:54 -0400
Newsgroups gmane.comp.lang.prothon.cvs
Message-ID <[email protected]>
Author: mark
Date: 2004-07-18 00:26:50 -0400 (Sun, 18 Jul 2004)
New Revision: 749

Added:
   trunk/src/ob_malloc.c
Modified:
   trunk/include/prothon/prothon.h
   trunk/include/prothon/prothon_dll.h
   trunk/modules/DBM/DBM.c
   trunk/modules/OS/OS.c
   trunk/modules/Prosist/Prosist.c
   trunk/modules/Re/Re.c
   trunk/modules/SQLite/SQLite.c
   trunk/src/builtins-attrdict.c
   trunk/src/builtins-bytes.c
   trunk/src/builtins-core.c
   trunk/src/builtins-dict.c
   trunk/src/builtins-file.c
   trunk/src/builtins-float.c
   trunk/src/builtins-int.c
   trunk/src/builtins-list.c
   trunk/src/builtins-protolist.c
   trunk/src/builtins-string.c
   trunk/src/builtins-thread.c
   trunk/src/builtins-time.c
   trunk/src/builtins-tuple.c
   trunk/src/dict.h
   trunk/src/interp.c
   trunk/src/lock.c
   trunk/src/main.c
   trunk/src/memory_mgr.c
   trunk/src/object.c
   trunk/src/object.h
   trunk/src/parser_routines.c
   trunk/src/prlist.h
   trunk/src/src.vcproj
   trunk/src/symbol.c
   trunk/src/sys.c
   trunk/src/thread.h
Log:
added obmalloc.c, and optimized allocator just for the objects, and I split the objects into hdr and body in prepraration for new garbage collector

Modified: trunk/include/prothon/prothon.h
===================================================================
--- trunk/include/prothon/prothon.h	2004-07-17 08:33:55 UTC (rev 748)
+++ trunk/include/prothon/prothon.h	2004-07-18 04:26:50 UTC (rev 749)
@@ -155,10 +155,10 @@
 typedef struct obj_s*	obj_p;
 
 typedef enum {
-	OBJ_STATE_INVALID = -1,
+	OBJ_STATE_UNMARKED = -2,
+	OBJ_STATE_DELETED,
+	OBJ_STATE_INVALID,
 	OBJ_STATE_NEW_OR_MARKED,
-	OBJ_STATE_UNMARKED,
-	OBJ_STATE_DELETED
 } obj_state_t;
 
 typedef struct {
@@ -190,16 +190,16 @@
 } attr_proto_t;
 
 typedef enum {
-	DATA_TYPE_NONE = 0,
+	DATA_TYPE_DATAPTR = -2,
+	DATA_TYPE_EXTPTR,
+	DATA_TYPE_NONE,
 	DATA_TYPE_IMMDATA,
-	DATA_TYPE_DATAPTR,
-	DATA_TYPE_EXTPTR
 } data_type_t;
 
 typedef u32_t data_size_t;
 
 #define IMM_DATA_LEN 8
-#define DATA_SIZE(obj)	(*((data_size_t*)((obj)->data.ptr)))
+#define DATA_SIZE(obj)	(*((data_size_t*)((obj)->body->data.ptr)))
 
 typedef struct {
 	u8_t	b0;
@@ -226,26 +226,33 @@
 #define ACC_USER2	2
 #define ACC_SYSTEM	3
 
+typedef struct objb_s {
+	unsigned		rd_access		:2;	
+	unsigned		wr_access		:2;	
+	unsigned		archived		:1;	
+	unsigned		rd_notify		:1;	
+	unsigned		wr_notify		:1;	
+	unsigned		del_notify		:1;	
+	unsigned		unclonable		:1;
+	unsigned		immutable		:1;
+	unsigned 		has_attrs		:1;
+	unsigned		imm_data_len	:4;
+	data_type_t		data_type		:2;
+	attr_proto_t	attr_proto;
+	obj_data_t		data;
+} objb_t;
+
+typedef objb_t* objb_p;
+
 typedef struct obj_s {
-	obj_state_t		state			:3; // u8_t :2 when not debugging
-	u8_t			scanned			:1;	
-	data_type_t		data_type		:3; // u8_t :2 when not debugging
-	u8_t			imm_data_len	:4;
-	access_t		rd_access		:2;	
-	access_t		wr_access		:2;	
-	u8_t			archived		:1;	
-	u8_t			rd_notify		:1;	
-	u8_t			wr_notify		:1;	
-	u8_t			del_notify		:1;	
-	u8_t 			has_attrs		:1;
-	u8_t			unclonable		:1;
-	u8_t			immutable		:1;
-	u8_t			del_locked		:1;
-	u8_t			rdlock_cnt		:7;
-	u8_t			wrlock_req_cnt	:7;
+	objb_p			body;
+	objb_p			saved_body;
 	i32_t			wrlock;
-	attr_proto_t	attr_proto;
-	obj_data_t		data;
+	unsigned		rdlock_cnt		:16;
+	unsigned		wrlock_req_cnt	:12;
+	unsigned		del_locked		:1;
+	unsigned		scanned			:1;
+	obj_state_t		state			:2;
 	obj_p			next_obj;
 } obj_t;
 
@@ -571,13 +578,13 @@
 
 // SET_TYPE_IF_EXC: Set data type and owner, throw exception if already set
 #define SET_TYPE_IF_EXC(owner, obj, type)				\
-	if ((obj)->data_type != DATA_TYPE_NONE)				\
+	if ((obj)->body->data_type != DATA_TYPE_NONE)				\
 		raise_exception(ist, OBJ(INTERNAL_EXC),			\
           "object binary data overwrite attempt");		\
-	else { (obj)->data_type = (type);					\
+	else { (obj)->body->data_type = (type);					\
 		    obj_set_data_owner(ist, obj, owner);		\
 	} if (ist->exception_obj)							\
-			(obj)->data_type = DATA_TYPE_NONE;			\
+			(obj)->body->data_type = DATA_TYPE_NONE;			\
 	if (ist->exception_obj) 
   
 // PROTO_OWNS_BINARY: Prototype owns binary data in obj
@@ -737,13 +744,13 @@
 
 // PR_STRLEN: macro to retreive string length of a string object (type data_size_t)
 #define pr_strlen(str_obj)																		    \
-	( ((str_obj)->data_type == DATA_TYPE_IMMDATA) ? (((data_size_t)((str_obj)->imm_data_len))/3):	\
-	 (((str_obj)->data_type == DATA_TYPE_DATAPTR) ? ((DATA_SIZE(str_obj)-sizeof(str_t))/3) : 0 ) )
+	( ((str_obj)->body->data_type == DATA_TYPE_IMMDATA) ? (((data_size_t)((str_obj)->body->imm_data_len))/3):	\
+	 (((str_obj)->body->data_type == DATA_TYPE_DATAPTR) ? ((DATA_SIZE(str_obj)-sizeof(str_t))/3) : 0 ) )
 
 // PR_CH3PTR: macro to retreive ptr to chars for a string object (type ch3_p)
 #define pr_ch3ptr(str_obj)																		\
-	( ((str_obj)->data_type == DATA_TYPE_IMMDATA) ? (str_obj->data.str)					:		\
-	 (((str_obj)->data_type == DATA_TYPE_DATAPTR) ? (((str_p)(str_obj->data.ptr))->str) : NULL ) )
+	( ((str_obj)->body->data_type == DATA_TYPE_IMMDATA) ? (str_obj->body->data.str)					:		\
+	 (((str_obj)->body->data_type == DATA_TYPE_DATAPTR) ? (((str_p)(str_obj->body->data.ptr))->str) : NULL ) )
 
 // NEW_TIME_OBJ: Create a new time object with a given initial time
 obj_p new_time_obj(isp ist, i64_t usecs);
@@ -1085,7 +1092,7 @@
 				"expected a float in parameter " #index);					\
 		return NULL;														\
 	}																		\
-	(var) = (index > 0 ? parms[((index)-1)*2+1] : list_item(ist, parms[1], -index))->data.f64;	}
+	(var) = (index > 0 ? parms[((index)-1)*2+1] : list_item(ist, parms[1], -index))->body->data.f64;	}
 
 #define STRBIN_PARAM(index, var)	/* apr_datum_t var; */					\
 {	if (!has_proto(ist, (index > 0 ? parms[((index)-1)*2+1] : list_item(ist, parms[1], -index)), OBJ(STRING_PROTO))) {	\
@@ -1232,14 +1239,14 @@
 // OBJ_DATAPTR: returns the C ptr to the data area for an object.
 #define obj_dataptr(obj)														\
 	(                                  !obj ?   NULL            :				\
-	( (obj)->data_type == DATA_TYPE_IMMDATA ? &((obj)->data)    :				\
-	( (obj)->data_type == DATA_TYPE_DATAPTR ?   (obj)->data.ptr :	NULL ) ) )
+	( (obj)->body->data_type == DATA_TYPE_IMMDATA ? &((obj)->body->data)    :				\
+	( (obj)->body->data_type == DATA_TYPE_DATAPTR ?   (obj)->body->data.ptr :	NULL ) ) )
 
 // OBJ_DATALEN: returns the data length for an object.
 #define obj_datalen(obj)														    \
 	(                                  !obj ? 0                     :				\
-	( (obj)->data_type == DATA_TYPE_IMMDATA ? (obj)->imm_data_len   :				\
-	( (obj)->data_type == DATA_TYPE_DATAPTR ? DATA_SIZE(obj)        :	NULL ) ) )
+	( (obj)->body->data_type == DATA_TYPE_IMMDATA ? (obj)->body->imm_data_len   :				\
+	( (obj)->body->data_type == DATA_TYPE_DATAPTR ? DATA_SIZE(obj)        :	NULL ) ) )
 
 
 //************************** OBJECT LOCKING ***********************************

Modified: trunk/include/prothon/prothon_dll.h
===================================================================
--- trunk/include/prothon/prothon_dll.h	2004-07-17 08:33:55 UTC (rev 748)
+++ trunk/include/prothon/prothon_dll.h	2004-07-18 04:26:50 UTC (rev 749)
@@ -193,7 +193,7 @@
 		       obj_p* parms, obj_p dlocals)
 
 #define BIN_EMPTY_CHK()									\
-	if (self->data_type != DATA_TYPE_NONE) {			\
+	if (self->body->data_type != DATA_TYPE_NONE) {			\
 		raise_exception(ist, OBJ(INTERNAL_EXC),			\
 			"object has data, expected none");	\
 		return NULL; }									
@@ -201,23 +201,23 @@
 	//if (self == slf##_OBJ)										
 	//	return call_func(ist, self, SYM(STR_), 0, NULL, slf##_OBJ);	
 #define BIN_STR_CHK(slf)											\
-	if (self->data_type == DATA_TYPE_NONE) {						\
+	if (self->body->data_type == DATA_TYPE_NONE) {						\
 		char msg[80];												\
 		apr_snprintf(msg, sizeof(msg), "<%s:Uninitialized>", #slf);	\
 		return NEW_STRING(msg); }										
 
 #define BIN_EMPTY_OR_NOT_CHK(slf)								\
-	if (self->data_type != DATA_TYPE_NONE) {					\
+	if (self->body->data_type != DATA_TYPE_NONE) {					\
 		if (!proto_owns_binary(ist, slf##_OBJ, self) ) {		\
 		raise_exception(ist, OBJ(INTERNAL_EXC),					\
 			"object has wrong binary data, expected %s", #slf);	\
 		return NULL; }											\
-		if (self->data_type == DATA_TYPE_DATAPTR)				\
-			pr_free(self->data.ptr);							\
-		self->data_type = DATA_TYPE_NONE; }
+		if (self->body->data_type == DATA_TYPE_DATAPTR)				\
+			pr_free(self->body->data.ptr);							\
+		self->body->data_type = DATA_TYPE_NONE; }
 
 #define BIN_CONTENT_CHK(slf)									\
-	if (self->data_type == DATA_TYPE_NONE) {					\
+	if (self->body->data_type == DATA_TYPE_NONE) {					\
 		raise_exception(ist, OBJ(INTERNAL_EXC),					\
 			"object has no binary data, expected %s", #slf);	\
 		return NULL; }											\

Modified: trunk/modules/DBM/DBM.c
===================================================================
--- trunk/modules/DBM/DBM.c	2004-07-17 08:33:55 UTC (rev 748)
+++ trunk/modules/DBM/DBM.c	2004-07-18 04:26:50 UTC (rev 749)
@@ -89,19 +89,19 @@
 	set_obj_doc(DBM_OBJ, "DBM module");
 	set_obj_id(DBM_OBJ, *, DBM);
 	MODULE_ADD_TO_BASE(DBM);
-	DBM_OBJ->unclonable = TRUE;
+	DBM_OBJ->body->unclonable = TRUE;
 
 	DB_OBJ = NEW_OBJ(NULL);
 	set_obj_doc(DB_OBJ, "DBM DB object prototype");
 	set_obj_id(DB_OBJ, DBM, DB);
 	MODULE_ADD_TO_OBJ(DB, DBM_OBJ, "DB");
-	DBM_OBJ->unclonable = TRUE;
+	DBM_OBJ->body->unclonable = TRUE;
 
 	DBM_Exc_OBJ = NEW_OBJ(NULL);
 	set_obj_doc(DBM_Exc_OBJ, "DBM DB error");
 	set_obj_id(DBM_Exc_OBJ, DBM, DBMError);
 	MODULE_ADD_TO_OBJ(DBM_Exc, DBM_OBJ, "DBMError");
-	DBM_OBJ->unclonable = TRUE;
+	DBM_OBJ->body->unclonable = TRUE;
 
 	MODULE_CONSTANT_INT(DBM, READONLY,   APR_DBM_READONLY  ); // read-only access
 	MODULE_CONSTANT_INT(DBM, READWRITE,  APR_DBM_READWRITE ); // read-write access
@@ -172,14 +172,14 @@
 	read_lock(ist, self);
 
 	SET_TYPE_IF_EXC(DB_OBJ, self, DATA_TYPE_DATAPTR) return NULL;
-	self->data.ptr  = db;
+	self->body->data.ptr  = db;
 
 	return OBJ(NONE);
 }
 
 DEF(DB, fetch, FPARM1(key, NULL)) {
 	apr_status_t aprerr;
-	apr_dbm_p db = self->data.ptr;
+	apr_dbm_p db = self->body->data.ptr;
 	apr_datum_t key, value;
 
 	BIN_CONTENT_CHK(DB);
@@ -197,7 +197,7 @@
 
 DEF(DB, store, FPARM2(key, NULL, value, NULL)) {
 	apr_status_t aprerr;
-	apr_dbm_p db = self->data.ptr;
+	apr_dbm_p db = self->body->data.ptr;
 	apr_datum_t key, value;
 
 	BIN_CONTENT_CHK(DB);
@@ -213,7 +213,7 @@
 
 DEF(DB, delete, FPARM1(key, NULL)) {
 	apr_status_t aprerr;
-	apr_dbm_p db = self->data.ptr;
+	apr_dbm_p db = self->body->data.ptr;
 	apr_datum_t key;
 
 	BIN_CONTENT_CHK(DB);
@@ -227,7 +227,7 @@
 }
 
 DEF(DB, exists_QUES, FPARM1(key, NULL)) {
-	apr_dbm_p db = self->data.ptr;
+	apr_dbm_p db = self->body->data.ptr;
 	apr_datum_t key;
 
 	BIN_CONTENT_CHK(DB);
@@ -240,7 +240,7 @@
 
 DEF(DB, firstKey, NULL) {
 	apr_status_t aprerr;
-	apr_dbm_p db = self->data.ptr;
+	apr_dbm_p db = self->body->data.ptr;
 	apr_datum_t key;
 
 	BIN_CONTENT_CHK(DB);
@@ -257,7 +257,7 @@
 
 DEF(DB, nextKey, FPARM1(key, NULL)) {
 	apr_status_t aprerr;
-	apr_dbm_p db = self->data.ptr;
+	apr_dbm_p db = self->body->data.ptr;
 	apr_datum_t key;
 
 	BIN_CONTENT_CHK(DB);
@@ -274,7 +274,7 @@
 }
 
 DEF(DB, freeDatum, FPARM1(data, NULL)) {
-	apr_dbm_p db = self->data.ptr;
+	apr_dbm_p db = self->body->data.ptr;
 	apr_datum_t data;
 
 	BIN_CONTENT_CHK(DB);
@@ -286,15 +286,15 @@
 }
 
 DEF(DB, close, NULL) {
-	apr_dbm_p db = self->data.ptr;
+	apr_dbm_p db = self->body->data.ptr;
 	BIN_CONTENT_CHK(DB);
 	if (db) apr_dbm_close(db);
-	self->data.ptr = NULL;
+	self->body->data.ptr = NULL;
 	return self;
 }
 
 DEF(DB, closed_QUES, NULL) {
-	apr_dbm_p db = self->data.ptr;
+	apr_dbm_p db = self->body->data.ptr;
 	BIN_CONTENT_CHK(DB);
 	if (db) return OBJ(PR_FALSE);
 	else    return OBJ(PR_TRUE);
Modified: trunk/modules/OS/OS.c
===================================================================
--- trunk/modules/OS/OS.c	2004-07-17 08:33:55 UTC (rev 748)
+++ trunk/modules/OS/OS.c	2004-07-18 04:26:50 UTC (rev 749)
@@ -108,7 +108,7 @@
 DEF(os, system, FPARM1(cmd, NULL)) {
 	if (!has_proto(ist, parms[1], OBJ(STRING_PROTO))) {
 		ist->exception_obj = NEW_OBJ(OBJ(TYPE_EXC));
-		ist->exception_obj->wr_access = ACC_GUEST;
+		ist->exception_obj->body->wr_access = ACC_GUEST;
 		set_obj_doc(ist->exception_obj, "object is not of type string");
 		return NULL;										
 	}
@@ -215,7 +215,7 @@
 		aprerr = apr_procattr_detach_set(attr, APR_PROC_DETACH_DAEMONIZE); 
 		IF_APR_ERR("error in apr_procattr_detach_set") return NULL;
 	}
-	procp = self->data.ptr = pr_malloc(sizeof(proc_t));
+	procp = self->body->data.ptr = pr_malloc(sizeof(proc_t));
 	DATA_SIZE(self) = (data_size_t) sizeof(proc_t);
 	procp->pool = pool;
 
@@ -233,7 +233,7 @@
 		set_file_obj_data( ist, file_obj, NEW_STRING("stdInPipe"), NEW_STRING("w"), 
 							    procp->proc.in, 0, APR_WRITE );
 		set_attr(ist, file_obj, sym(ist, "encoding"), NEW_STRING("ASCII"));
-		file_obj->unclonable = TRUE;
+		file_obj->body->unclonable = TRUE;
 		read_unlock(ist, self);
 		set_attr(ist, self, sym(ist, "stdInPipe"), file_obj);
 		read_lock(ist, self);
@@ -244,7 +244,7 @@
 		set_file_obj_data( ist, file_obj, NEW_STRING("stdOutPipe"), NEW_STRING("r"), 
 							    procp->proc.out, 0, APR_READ );
 		set_attr(ist, file_obj, sym(ist, "encoding"), NEW_STRING("ASCII"));
-		file_obj->unclonable = TRUE;
+		file_obj->body->unclonable = TRUE;
 		read_unlock(ist, self);
 		set_attr(ist, self, sym(ist, "stdOutPipe"), file_obj);
 		read_lock(ist, self);
@@ -255,7 +255,7 @@
 		set_file_obj_data( ist, file_obj, NEW_STRING("stdErrPipe"), NEW_STRING("r"), 
 							    procp->proc.err, 0, APR_READ );
 		set_attr(ist, file_obj, sym(ist, "encoding"), NEW_STRING("ASCII"));
-		file_obj->unclonable = TRUE;
+		file_obj->body->unclonable = TRUE;
 		read_unlock(ist, self);
 		set_attr(ist, self, sym(ist, "stdErrPipe"), file_obj);
 		read_lock(ist, self);
@@ -279,7 +279,7 @@
 	obj_p res = NULL;
 	apr_exit_why_e exit_why;
 	BIN_CONTENT_CHK(Process);
-	procp = self->data.ptr;
+	procp = self->body->data.ptr;
 	aprerr = apr_proc_wait(&procp->proc, &exitcode, &exit_why, APR_NOWAIT);
 	IF_APR_ERR("error in apr_proc_wait") return NULL;
 	if (aprerr & APR_CHILD_DONE)    res = OBJ(PR_FALSE);
@@ -303,7 +303,7 @@
 	apr_exit_why_e exit_why;
 
 	BIN_CONTENT_CHK(Process);
-	procp = self->data.ptr;
+	procp = self->body->data.ptr;
 	aprerr = apr_proc_wait(&procp->proc, &exitcode, &exit_why, APR_WAIT);
 	IF_APR_ERR("error in apr_proc_wait") return NULL;
 	if (parms[1] == OBJ(PR_TRUE)) {
@@ -322,7 +322,7 @@
 
 	BIN_CONTENT_CHK(Process);
 	INT_32_PARAM(1, sig);
-	procp = self->data.ptr;
+	procp = self->body->data.ptr;
 	aprerr = apr_proc_kill(&procp->proc, sig); 
 	IF_APR_ERR("error in apr_proc_kill") return NULL;
 	return self;

Modified: trunk/modules/Prosist/Prosist.c
===================================================================
--- trunk/modules/Prosist/Prosist.c	2004-07-17 08:33:55 UTC (rev 748)
+++ trunk/modules/Prosist/Prosist.c	2004-07-18 04:26:50 UTC (rev 749)
@@ -151,7 +151,7 @@
 obj_p new_mutwrap_obj(isp ist, obj_p obj) {
 	obj_p mutwrap_obj = new_object(ist, MutWrap_OBJ);
 	SET_TYPE_IF_EXC(MutWrap_OBJ, mutwrap_obj, DATA_TYPE_DATAPTR) return NULL;
-	mutwrap_obj->data.ptr = obj;
+	mutwrap_obj->body->data.ptr = obj;
 	set_immutable(mutwrap_obj);
 	return mutwrap_obj;
 }
@@ -250,7 +250,7 @@
 		raise_exception(ist, ProsistExc_OBJ, "obj_to_id called on obj with no id");
 	} else {
 		del_unlock(id_obj);
-		res = (psid_t) id_obj->data.i64;
+		res = (psid_t) id_obj->body->data.i64;
 	}
 	del_unlock(mw_obj);
 	return res;
@@ -321,11 +321,11 @@
 		akey = attr_next_key(ist, proxy_obj, akey);
 	}
 	if (added_attr) { _idx--; ADD_CHR(';'); }
-	if (proxy_obj->data_type == DATA_TYPE_IMMDATA) {
+	if (proxy_obj->body->data_type == DATA_TYPE_IMMDATA) {
 		ADD_CHR('i');
-		ADD_NUM(proxy_obj->imm_data_len);
+		ADD_NUM(proxy_obj->body->imm_data_len);
 		ADD_CHR(':');
-		ADD_MEM(&(proxy_obj->data), 8);
+		ADD_MEM(&(proxy_obj->body->data), 8);
 	}
 	if (has_proto(ist, proxy_obj, OBJ(STRING_PROTO))) {
 		ADD_CHR('s');
@@ -366,7 +366,7 @@
 		obj_p item = list_item(ist, olst, i);
 		if (item != PSNONE) {
 			if (has_proto(ist, item, MutWrap_OBJ))
-				item = (obj_p) item->data.ptr;
+				item = (obj_p) item->body->data.ptr;
 			read_unlock(ist, item);				
 		}
 	}											
@@ -380,7 +380,7 @@
 		obj_p item = list_item(ist, olst, i);
 		if (item != PSNONE) {
 			if (has_proto(ist, item, MutWrap_OBJ))
-				item = (obj_p) item->data.ptr;
+				item = (obj_p) item->body->data.ptr;
 			read_unlock(ist, item);				
 		}
 	}											
@@ -398,7 +398,7 @@
 	mw_obj = NEW_MW(obj);
 	id_obj = dict_item(ist, psrecp->obj_to_id, mw_obj);
 	if (id_obj) {
-		id = (psid_t) id_obj->data.i64;
+		id = (psid_t) id_obj->body->data.i64;
 		obj_known = TRUE;
 	}
 	reuse_proxy = obj_known && rback_flg && is_archived(obj);
@@ -489,13 +489,13 @@
 			return;
 		}
 		if (obj != proxy_obj) {
-			if (obj->has_attrs && obj->attr_proto.attrs)
-				pr_free(obj->attr_proto.attrs);
-			if (obj->data_type == DATA_TYPE_DATAPTR && obj->data.ptr) {
-				pr_free(obj->data.ptr);
+			if (obj->body->has_attrs && obj->body->attr_proto.attrs)
+				pr_free(obj->body->attr_proto.attrs);
+			if (obj->body->data_type == DATA_TYPE_DATAPTR && obj->body->data.ptr) {
+				pr_free(obj->body->data.ptr);
 			}
 			memcpy(obj, res, sizeof(*obj)-2*sizeof(obj->next_obj));
-			obj->data = res->data;
+			obj->body->data = res->body->data;
 			read_lock(ist, obj);
 		}
 	}
@@ -514,7 +514,7 @@
 			del_unlock(proxy_obj); 
 			return;
 		}
-		if (proxy_obj->data_type == DATA_TYPE_DATAPTR) {
+		if (proxy_obj->body->data_type == DATA_TYPE_DATAPTR) {
 			tuple_type = has_proto(ist, proxy_obj, OBJ(TUPLE_PROTO));
 			if (!tuple_type && !has_proto(ist, proxy_obj, OBJ(STRING_PROTO))) {
 				raise_exception(ist, ProsistExc_OBJ, "unstorable object (data ptr) found in tree");
@@ -578,7 +578,7 @@
 	char *p, *end;
 	obj_p res, obj;
 
-	id = (psid_t) id_obj->data.i64;
+	id = (psid_t) id_obj->body->data.i64;
 	value = load_obj_by_id(psrecp, id);  if_exc_return NULL;
 	p = value.dptr;
 	end = p + value.dsize;
@@ -640,8 +640,8 @@
 				SET_TYPE_IF_EXC(OBJ(INT_PROTO), obj, DATA_TYPE_IMMDATA) return NULL;
 				for(n=0,p++; *p != ':'; p++)
 					n = n*10 + *p - '0';
-				obj->imm_data_len = n;
-				memcpy(&(obj->data), p+1, sizeof(obj->data));
+				obj->body->imm_data_len = n;
+				memcpy(&(obj->body->data), p+1, sizeof(obj->body->data));
 				set_immutable(obj);
 				goto done;
 			case 's':
@@ -892,7 +892,7 @@
 	idlist = new_list_obj(ist, 20);
 	append_load_ids(ist, psrecp, idlist, 0); if_exc_return NULL;
 	for (; idx < (int) list_len(ist, idlist); idx++) {
-		psid_t id = (psid_t) (list_item(ist, idlist, idx)->data.i64);
+		psid_t id = (psid_t) (list_item(ist, idlist, idx)->body->data.i64);
 		append_load_ids(ist, psrecp, idlist, id); if_exc_return NULL;
 	}
 	llen = (int) list_len(ist, idlist);
@@ -927,7 +927,7 @@
 	MODULE_SET_DOC(MutWrap, "wrapper to make any object immutable and storable by object id");
 	MODULE_ADD_TO_OBJ(MutWrap, Prosist_OBJ, "MutWrap");
 
-	Prosist_OBJ->unclonable = TRUE;
+	Prosist_OBJ->body->unclonable = TRUE;
 	set_obj_rdacc(Prosist_OBJ, ACC_USER1);
 	
 	MODULE_CONSTANT_INT(Prosist, READONLY,   APR_DBM_READONLY ); // read-only access
@@ -973,7 +973,7 @@
 	IF_APR_ERR("opening Prosist database") return NULL;
 
 	SET_TYPE_IF_EXC(Prosist_OBJ, self, DATA_TYPE_DATAPTR) return NULL;
-	self->data.ptr		= psrecp = pr_malloc(sizeof(psrec_t));
+	self->body->data.ptr		= psrecp = pr_malloc(sizeof(psrec_t));
 	psrecp->db			= db;
 	psrecp->pool		= cntxt;
 	psrecp->id_to_idobj = NEW_DICT(4*INITIAL_OBJ_COUNT);
@@ -999,7 +999,7 @@
 }
 
 DEF(Prosist, rollBack, NULL) {
-	psrec_p psrecp = self->data.ptr;
+	psrec_p psrecp = self->body->data.ptr;
 	BIN_CONTENT_CHK(Prosist);
 	if (psrecp) 
 		rollback_db(ist, psrecp);
@@ -1011,7 +1011,7 @@
 }
 
 DEF(Prosist, commit, NULL) {
-	psrec_p psrecp = self->data.ptr;
+	psrec_p psrecp = self->body->data.ptr;
 	BIN_CONTENT_CHK(Prosist);
 	if (psrecp) 
 		commit_db(ist, psrecp);
@@ -1024,19 +1024,19 @@
 
 
 DEF(Prosist, close, NULL) { 
-	psrec_p psrecp = self->data.ptr;
+	psrec_p psrecp = self->body->data.ptr;
 	BIN_CONTENT_CHK(Prosist);
 	if (psrecp) {
 		apr_dbm_close(psrecp->db);
 		apr_pool_destroy(psrecp->pool);
-		self->data.ptr = NULL;
+		self->body->data.ptr = NULL;
 	}
 	return self;
 }
 
 DEF(Prosist, closed_QUES, NULL) { 
 	BIN_CONTENT_CHK(Prosist);
-	if (self->data.ptr) return OBJ(PR_FALSE);
+	if (self->body->data.ptr) return OBJ(PR_FALSE);
 	else                return OBJ(PR_TRUE);
 }
 
@@ -1046,13 +1046,13 @@
 
 DEF(MutWrap, hash_, NULL) {
 	BIN_CONTENT_CHK(MutWrap);
-	return new_hash_obj(ist, (i32_t)(intptr_t) self->data.ptr);
+	return new_hash_obj(ist, (i32_t)(intptr_t) self->body->data.ptr);
 }
 
 DEF(MutWrap, eq__QUES, FORM_RPARAM) {
 	BIN_CONTENT_CHK(MutWrap);
 	CHECK_TYPE_EXC(parms[1], MutWrap_OBJ, "immutable object wrapper");
-	if (self->data.ptr == parms[1]->data.ptr) return OBJ(PR_TRUE);
+	if (self->body->data.ptr == parms[1]->body->data.ptr) return OBJ(PR_TRUE);
 	else									  return OBJ(PR_FALSE);
 }
 

Modified: trunk/modules/Re/Re.c
===================================================================
--- trunk/modules/Re/Re.c	2004-07-17 08:33:55 UTC (rev 748)
+++ trunk/modules/Re/Re.c	2004-07-18 04:26:50 UTC (rev 749)
@@ -61,7 +61,7 @@
 #define MAX_GROUPS   99
 #define PROTO_FLAGS  REG_EXTENDED
 
-#define numgrps(re_obj) (((regex_t*)((re_obj)->data.ptr))->re_nsub)
+#define numgrps(re_obj) (((regex_t*)((re_obj)->body->data.ptr))->re_nsub)
 
 static obj_p reException_OBJ; 
 static obj_p i_flg, s_flg;
@@ -121,7 +121,7 @@
 	}
 	re_obj = NEW_OBJ(reCompiled_OBJ);
 	SET_TYPE_IF_EXC(reCompiled_OBJ, re_obj, DATA_TYPE_DATAPTR) return NULL;
-	re_obj->data.ptr = e;
+	re_obj->body->data.ptr = e;
 	set_attr(ist, re_obj, sym(ist, "pattern"), parms[1]);
 	set_attr(ist, re_obj, sym(ist, "flags"),   parms[3]);
 	return re_obj;
@@ -142,7 +142,7 @@
 	obj_p res, tuple_obj;
 	regoff_t sp, ep;
 	int i, err, ngrps = numgrps(self);
-	regex_t* e = self->data.ptr;
+	regex_t* e = self->body->data.ptr;
 
 	BIN_CONTENT_CHK(reCompiled);
 	STRING_PARAM(1, s);
@@ -184,7 +184,7 @@
 				else          list_append(ist, tuple_obj, NEW_STRINGN(s+sp,ep-sp));
 			}
 			list_append(ist, res, tuple_obj);
-			tuple_obj->immutable = TRUE;
+			tuple_obj->body->immutable = TRUE;
 		}
 	}
 	pr_free(m);
@@ -199,7 +199,7 @@
 	unsigned int i, last_index=0, ngrps = numgrps(self);
 	char* s;
 	regmatch_t* m;
-	regex_t* e = self->data.ptr;
+	regex_t* e = self->body->data.ptr;
 	i64_t start, end;
 
 	BIN_CONTENT_CHK(reCompiled);
@@ -247,7 +247,7 @@
 	regmatch_t* m;
 	obj_p res;
 	regoff_t sp, ep, last_split;
-	regex_t* e = self->data.ptr;
+	regex_t* e = self->body->data.ptr;
 	int i, split_count=0, maxsplit, err, ngrps = numgrps(self);
 	char* s;
 
@@ -356,8 +356,8 @@
 						n = (c2-'0')*10+(c3-'0');
 					else {(*p1)--; n = c2-'0';}
 					if (n >= list_len(ist, mlist)/2) goto err;
-					sp = (int)list_item(ist, mlist, n*2  )->data.i64;
-					ep = (int)list_item(ist, mlist, n*2+1)->data.i64;
+					sp = (int)list_item(ist, mlist, n*2  )->body->data.i64;
+					ep = (int)list_item(ist, mlist, n*2+1)->body->data.i64;
 					if (sp == -1) continue;
 					for(t=orig_s+sp; t < orig_s+ep; t++) {
 						*(*p2) = *t;
@@ -386,7 +386,7 @@
 	regmatch_t* m;
 	regoff_t last_split;
 	obj_p lastindex_obj, repl_obj, res_obj, match_obj, arr[2];
-	regex_t* e = self->data.ptr;
+	regex_t* e = self->body->data.ptr;
 	char *repl = "", *orig_s, *p1, *p2, *s, *s_lim, *res;
 	int i, last_index=0, repl_is_func=FALSE, count, err, ngrps = numgrps(self);
 
@@ -445,7 +445,7 @@
 			list_append(ist, match_obj, NEW_INT(m[i].rm_so));
 			list_append(ist, match_obj, NEW_INT(m[i].rm_eo));
 		}
-		lastindex_obj->data.i64 = last_index;
+		lastindex_obj->body->data.i64 = last_index;
 		if (repl_is_func) {
 			read_unlock(ist, parms[1]);
 			repl_obj = call_func(ist, NULL, parms[1], NULL, 2, arr, NULL); 
@@ -490,8 +490,8 @@
 }
 
 DEF(reCompiled, final_, NULL) {
-	if (self->data.ptr)
-		regfree((regex_t*)(self->data.ptr));
+	if (self->body->data.ptr)
+		regfree((regex_t*)(self->body->data.ptr));
 	return OBJ(NONE);
 }
 
@@ -552,7 +552,7 @@
 	res = NEW_TUPLE(2);
 	list_append(ist, res, list_item(ist, self, 2*grp  ));
 	list_append(ist, res, list_item(ist, self, 2*grp+1));
-	res->immutable = TRUE;
+	res->body->immutable = TRUE;
 	return res;
 }
 
@@ -597,7 +597,7 @@
 				raise_exception(ist, OBJ(TYPE_EXC), "groupid parameters must be integers");
 				return NULL;
 			}
-			j = (int)(item->data.i64);
+			j = (int)(item->body->data.i64);
 			if (j < 0 || j > ngrps) {
 				raise_exception(ist, OBJ(TYPE_EXC), "groupid value out of range");
 				return NULL;
@@ -607,22 +607,22 @@
 	orig_s_obj = get_attr(ist, self, sym(ist, "string")); if_exc_return NULL;
 	orig_s = pr2c_strptr(ist, orig_s_obj);
 	if (!parms[3] || !(llen = (int)list_len(ist, parms[3]))) {
-		j = (int)(parms[1]->data.i64);
-		sp = (int)(list_item(ist, self, j*2  )->data.i64);
-		ep = (int)(list_item(ist, self, j*2+1)->data.i64);
+		j = (int)(parms[1]->body->data.i64);
+		sp = (int)(list_item(ist, self, j*2  )->body->data.i64);
+		ep = (int)(list_item(ist, self, j*2+1)->body->data.i64);
 		if (sp == -1) return OBJ(NONE);
 		else		  return NEW_STRINGN(orig_s+sp, ep-sp);
 	} else { 
 		res = NEW_TUPLE(llen);
 		for (i=0; i < llen; i++) {
 			obj_p item = list_item(ist, parms[3], i);
-			j = (int)(item->data.i64);
-			sp = (int)(list_item(ist, self, j*2  )->data.i64);
-			ep = (int)(list_item(ist, self, j*2+1)->data.i64);
+			j = (int)(item->body->data.i64);
+			sp = (int)(list_item(ist, self, j*2  )->body->data.i64);
+			ep = (int)(list_item(ist, self, j*2+1)->body->data.i64);
 			if (sp == -1) list_append(ist, res, OBJ(NONE));
 			else		  list_append(ist, res, NEW_STRINGN(orig_s+sp, ep-sp));
 		}
-		res->immutable = TRUE;
+		res->body->immutable = TRUE;
 		return res;
 	}
 }
@@ -635,12 +635,12 @@
 	orig_s = pr2c_strptr(ist, orig_s_obj);
 	BIN_CONTENT_CHK(reMatch);
 	for (i=0; i < ngrps; i++) {
-		sp = (int)(list_item(ist, self, i*2  )->data.i64);
-		ep = (int)(list_item(ist, self, i*2+1)->data.i64);
+		sp = (int)(list_item(ist, self, i*2  )->body->data.i64);
+		ep = (int)(list_item(ist, self, i*2+1)->body->data.i64);
 		if (sp == -1) list_append(ist, res, parms[1]);
 		else		  list_append(ist, res, NEW_STRINGN(orig_s+sp, ep-sp));
 	}
-	res->immutable = TRUE;
+	res->body->immutable = TRUE;
 	return res;
 }
 

Modified: trunk/modules/SQLite/SQLite.c
===================================================================
--- trunk/modules/SQLite/SQLite.c	2004-07-17 08:33:55 UTC (rev 748)
+++ trunk/modules/SQLite/SQLite.c	2004-07-18 04:26:50 UTC (rev 749)
@@ -95,9 +95,9 @@
 	MODULE_SET_DOC(Error, "sqlite db error");
 	MODULE_ADD_TO_OBJ(Error, sqlite_OBJ, "Error");
 
-	Connection_OBJ->unclonable = TRUE;
+	Connection_OBJ->body->unclonable = TRUE;
 	set_obj_rdacc(Connection_OBJ, ACC_USER1);
-	Cursor_OBJ->unclonable = TRUE;
+	Cursor_OBJ->body->unclonable = TRUE;
 	set_obj_rdacc(Cursor_OBJ, ACC_USER1);
 }
 
@@ -108,10 +108,10 @@
 	filename = pr2c_strptr(ist, parms[1]);
 	conn_obj = NEW_OBJ(Connection_OBJ);
 	set_obj_doc(conn_obj, "sqlite connection");
-	conn_obj->unclonable = TRUE;
+	conn_obj->body->unclonable = TRUE;
 	set_obj_rdacc(conn_obj, ACC_USER1);
 	SET_TYPE_IF_EXC(Connection_OBJ, conn_obj, DATA_TYPE_DATAPTR) return NULL;
-	conn_obj->data.ptr = sqlite_open(filename, 0, &errmsg);
+	conn_obj->body->data.ptr = sqlite_open(filename, 0, &errmsg);
 	if (errmsg) {
 		raise_exception(ist, Error_OBJ, errmsg);
 		return NULL;
@@ -121,12 +121,12 @@
 
 DEF(Connection, cursor, NULL) {
 	BIN_CONTENT_CHK(Connection);
-	if (self->data.ptr) {
+	if (self->body->data.ptr) {
 		cursor_p cursorp;
 		obj_p curs_obj = NEW_OBJ(Cursor_OBJ);
 		set_obj_doc(curs_obj, "sqlite cursor");
 		SET_TYPE_IF_EXC(Cursor_OBJ, curs_obj, DATA_TYPE_DATAPTR) return NULL;
-		cursorp = curs_obj->data.ptr  = pr_malloc(sizeof(cursor_t));
+		cursorp = curs_obj->body->data.ptr  = pr_malloc(sizeof(cursor_t));
 		cursorp->ist	  = ist;
 		cursorp->conn_obj = self;
 		cursorp->row_list = NEW_LIST(INITIAL_ROW_LIST_SIZE);
@@ -140,7 +140,7 @@
 
 DEF(Connection, rollBack, NULL) {
 	BIN_CONTENT_CHK(Connection);
-	if (self->data.ptr) {
+	if (self->body->data.ptr) {
 		raise_exception(ist, Error_OBJ, "rollBack not implemented yet, use query");
 		return NULL;
 	} else {
@@ -151,7 +151,7 @@
 
 DEF(Connection, commit, NULL) {
 	BIN_CONTENT_CHK(Connection);
-	if (self->data.ptr) {
+	if (self->body->data.ptr) {
 		raise_exception(ist, Error_OBJ, "commit not implemented yet, use query");
 		return NULL;
 	} else {
@@ -162,9 +162,9 @@
 
 DEF(Connection, close, NULL) {
 	BIN_CONTENT_CHK(Connection);
-	if (self->data.ptr) {
-		sqlite_close((sqlite_p)(self->data.ptr));
-		self->data.ptr = NULL;
+	if (self->body->data.ptr) {
+		sqlite_close((sqlite_p)(self->body->data.ptr));
+		self->body->data.ptr = NULL;
 	}
 	return OBJ(NONE);
 }
@@ -199,10 +199,10 @@
 		raise_exception(ist, Error_OBJ, "parameters not implemented yet");
 		return NULL;
 	}
-	cursorp  = (cursor_p)(self->data.ptr);
+	cursorp  = (cursor_p)(self->body->data.ptr);
 	clr_immutable(cursorp->row_list);
 	list_clear(ist, cursorp->row_list);
-	db = (sqlite_p)(cursorp->conn_obj->data.ptr);
+	db = (sqlite_p)(cursorp->conn_obj->body->data.ptr);
 	sqlite_exec(db, sql, xCallback, cursorp, &errmsg);
 	if (errmsg) {
 		raise_exception(ist, Error_OBJ, errmsg);
@@ -217,7 +217,7 @@
 DEF(Cursor, fetchOne, NULL) {
 	int llen, p;
 	obj_p res;
-	cursor_p cursorp  = (cursor_p)(self->data.ptr);
+	cursor_p cursorp  = (cursor_p)(self->body->data.ptr);
 
 	BIN_CONTENT_CHK(Cursor);
 	p = cursorp->row_ptr;
@@ -233,11 +233,11 @@
 DEF(Cursor, fetchMany, list2(ist, sym(ist, "n"), NULL)) {
 	int i, n, llen, p, e;
 	obj_p res;
-	cursor_p cursorp  = (cursor_p)(self->data.ptr);
+	cursor_p cursorp  = (cursor_p)(self->body->data.ptr);
 
 	BIN_CONTENT_CHK(Cursor);
 	CHECK_TYPE_EXC(parms[1], OBJ(INT_PROTO), "integer");
-	n = (int) parms[1]->data.i64;
+	n = (int) parms[1]->body->data.i64;
 	p = cursorp->row_ptr;
 	llen = (int) list_len(ist, cursorp->row_list);
 	e = p+n;
@@ -254,7 +254,7 @@
 DEF(Cursor, fetchAll, NULL) {
 	int i, llen, p;
 	obj_p res;
-	cursor_p cursorp  = (cursor_p)(self->data.ptr);
+	cursor_p cursorp  = (cursor_p)(self->body->data.ptr);
 
 	BIN_CONTENT_CHK(Cursor);
 	p = cursorp->row_ptr;
@@ -269,7 +269,7 @@
 }
 
 DEF(Cursor, rowCount, NULL) {
-	cursor_p cursorp  = (cursor_p)(self->data.ptr);
+	cursor_p cursorp  = (cursor_p)(self->body->data.ptr);
 	BIN_CONTENT_CHK(Cursor);
 	if (cursorp->row_list) 
 		return NEW_INT(list_len(ist, cursorp->row_list));
@@ -277,8 +277,8 @@
 }
 
 DEF(Cursor, objList_, FORM_RPARAM) {
-	cursor_p cursorp  = (cursor_p)(self->data.ptr);
-	if (!self->data.ptr) return parms[1];
+	cursor_p cursorp  = (cursor_p)(self->body->data.ptr);
+	if (!self->body->data.ptr) return parms[1];
 	if (cursorp->row_list)
 		return cursorp->row_list;
 	return parms[1];

Modified: trunk/src/builtins-attrdict.c
===================================================================
--- trunk/src/builtins-attrdict.c	2004-07-17 08:33:55 UTC (rev 748)
+++ trunk/src/builtins-attrdict.c	2004-07-18 04:26:50 UTC (rev 749)
@@ -70,7 +70,7 @@
 obj_p new_attrdict_obj(isp ist, obj_p obj) {
 	obj_p self = new_object(ist, AttrDict_OBJ);
 	SET_TYPE_IF_EXC(AttrDict_OBJ, self, DATA_TYPE_EXTPTR) return NULL;
-	self->data.ptr  = obj;
+	self->body->data.ptr  = obj;
 	set_unclonable(self);
 	return self;
 }
@@ -82,11 +82,11 @@
 	attr_p attrp;
 	obj_p dict_obj;
 	rdlock_rtrn(self) NULL;
-	if (!self->has_attrs) {
+	if (!self->body->has_attrs) {
 		read_unlock(ist, self);
 		return NEW_DICT(0);
 	}
-	attrp = self->attr_proto.attrs;
+	attrp = self->body->attr_proto.attrs;
 	asize = attr_asize(attrp);
 	alen  = attr_alen(attrp);
 	dict_obj = NEW_DICT((int)alen);
@@ -107,8 +107,8 @@
 	if_exc_return;
 
 	write_lock(ist, obj);
-	if (obj->has_attrs) {
-		attr_p attrp = obj->attr_proto.attrs;
+	if (obj->body->has_attrs) {
+		attr_p attrp = obj->body->attr_proto.attrs;
 		memset(attr_ap(attrp, 0), 0, attr_asize(attrp) * sizeof(attr_t));
 		attr_alen(attrp) = 0;
 	} else if (llen) {
@@ -141,14 +141,14 @@
 	set_attr(ist, OBJ(OBJECT), sym(ist, "AttrDict"), AttrDict_OBJ);
 
 	SET_TYPE_IF_EXC(AttrDict_OBJ, AttrDict_OBJ, DATA_TYPE_EXTPTR) return;
-	AttrDict_OBJ->data.ptr  = OBJ(OBJECT);
+	AttrDict_OBJ->body->data.ptr  = OBJ(OBJECT);
 	set_unclonable(AttrDict_OBJ);
 }
 
 DEF(AttrDict, init_, FORM_RPARAM) {
     BIN_EMPTY_CHK();
 	SET_TYPE_IF_EXC(AttrDict_OBJ, self, DATA_TYPE_EXTPTR) return NULL;
-	self->data.ptr  = parms[1];
+	self->body->data.ptr  = parms[1];
 	set_unclonable(self);
 	return OBJ(NONE);
 }
@@ -156,7 +156,7 @@
 DEF(AttrDict, str_, NULL) {
 	obj_p res, dict;
 	BIN_STR_CHK(AttrDict_OBJ);
-	dict = attr2dict(ist, self->data.ptr); if_exc_return NULL;
+	dict = attr2dict(ist, self->body->data.ptr); if_exc_return NULL;
 	res = call_func0(ist, dict, SYM(STR_));
 	del_unlock(dict);
 	return res;
@@ -165,7 +165,7 @@
 DEF(AttrDict, hasKey_QUES, FPARM1(k, OBJ(NODEF))) {
 	obj_p res, dict;
 	BIN_CONTENT_CHK(AttrDict);
-	dict = attr2dict(ist, self->data.ptr); if_exc_return NULL;
+	dict = attr2dict(ist, self->body->data.ptr); if_exc_return NULL;
 	res = call_func1( ist, dict, sym(ist, "hasKey_QUES"), parms[1] );
 	del_unlock(dict);
 	return res;
@@ -174,7 +174,7 @@
 DEF(AttrDict, get, FPARM2(k, OBJ(NODEF), x, OBJ(NONE))) {
 	obj_p res, dict;
 	BIN_CONTENT_CHK(AttrDict);
-	res = call_func2( ist, dict = attr2dict(ist, self->data.ptr), 
+	res = call_func2( ist, dict = attr2dict(ist, self->body->data.ptr), 
 						   sym(ist, "get"), parms[1], parms[3] );
 	del_unlock(dict);
 	return res;
@@ -183,7 +183,7 @@
 DEF(AttrDict, rIn__QUES, FORM_RPARAM) {
 	obj_p res, dict;
 	BIN_CONTENT_CHK(AttrDict);
-	res = call_func1( ist, dict = attr2dict(ist, self->data.ptr), 
+	res = call_func1( ist, dict = attr2dict(ist, self->body->data.ptr), 
 						   sym(ist, "rIn__QUES"), parms[1] );
 	del_unlock(dict);
 	return res;
@@ -192,7 +192,7 @@
 DEF(AttrDict, rNotIn__QUES, FORM_RPARAM) {
 	obj_p res, dict;
 	BIN_CONTENT_CHK(AttrDict);
-	res = call_func1( ist, dict = attr2dict(ist, self->data.ptr), 
+	res = call_func1( ist, dict = attr2dict(ist, self->body->data.ptr), 
 						   sym(ist, "rNotIn__QUES"), parms[1] );
 	del_unlock(dict);
 	return res;
@@ -210,9 +210,9 @@
 	} else
 		index = parms[1];
 	if (has_proto(ist, index, OBJ(SYMBOL_PROTO)))
-		res = get_attr(ist, self->data.ptr, index);
+		res = get_attr(ist, self->body->data.ptr, index);
 	else if (has_proto(ist, index, OBJ(STRING_PROTO))) {
-		res = get_attr(ist, self->data.ptr, sym(ist, pr2c_strptr(ist, index)));
+		res = get_attr(ist, self->body->data.ptr, sym(ist, pr2c_strptr(ist, index)));
 	} else
 		raise_exception(ist, OBJ(TYPE_EXC), "attrs_ index must be a string or symbol");
 	return res;
@@ -230,9 +230,9 @@
 	} else
 		index = parms[1];
 	if (has_proto(ist, index, OBJ(SYMBOL_PROTO)))
-		set_attr(ist, self->data.ptr, index, parms[3]);
+		set_attr(ist, self->body->data.ptr, index, parms[3]);
 	else if (has_proto(ist, index, OBJ(STRING_PROTO))) {
-		set_attr(ist, self->data.ptr, sym(ist, pr2c_strptr(ist, index)), parms[3]);
+		set_attr(ist, self->body->data.ptr, sym(ist, pr2c_strptr(ist, index)), parms[3]);
 	} else
 		raise_exception(ist, OBJ(TYPE_EXC), "attrs_ index must be a string or symbol");
 	return NULL;
@@ -250,9 +250,9 @@
 	} else
 		index = parms[1];
 	if (has_proto(ist, index, OBJ(SYMBOL_PROTO)))
-		del_attr(ist, self->data.ptr, index);
+		del_attr(ist, self->body->data.ptr, index);
 	else if (has_proto(ist, index, OBJ(STRING_PROTO))) {
-		del_attr(ist, self->data.ptr, sym(ist, pr2c_strptr(ist, index)));
+		del_attr(ist, self->body->data.ptr, sym(ist, pr2c_strptr(ist, index)));
 	} else
 		raise_exception(ist, OBJ(TYPE_EXC), "attrs_ index must be a string or symbol");
 	return NULL;
@@ -262,9 +262,9 @@
 	obj_p obj;
 	int res;
 	BIN_CONTENT_CHK(AttrDict);
-	obj = self->data.ptr;
-	if (obj->has_attrs)
-		res = attr_alen(obj->attr_proto.attrs);
+	obj = self->body->data.ptr;
+	if (obj->body->has_attrs)
+		res = attr_alen(obj->body->attr_proto.attrs);
 	else
 		res = 0;
 	return NEW_INT(res);
@@ -273,7 +273,7 @@
 DEF(AttrDict, items, NULL) {
 	obj_p res, dict;
 	BIN_CONTENT_CHK(AttrDict);
-	res = dict_keys_values(ist, dict = attr2dict(ist, self->data.ptr), 3 );
+	res = dict_keys_values(ist, dict = attr2dict(ist, self->body->data.ptr), 3 );
 	del_unlock(dict);
 	return res;
 }
@@ -281,7 +281,7 @@
 DEF(AttrDict, keys, NULL) {
 	obj_p res, dict;
 	BIN_CONTENT_CHK(AttrDict);
-	res = dict_keys_values(ist, dict = attr2dict(ist, self->data.ptr), 1 );
+	res = dict_keys_values(ist, dict = attr2dict(ist, self->body->data.ptr), 1 );
 	del_unlock(dict);
 	return res;
 }
@@ -289,7 +289,7 @@
 DEF(AttrDict, values, NULL) {
 	obj_p res, dict;
 	BIN_CONTENT_CHK(AttrDict);
-	res = dict_keys_values(ist, dict = attr2dict(ist, self->data.ptr), 0 );
+	res = dict_keys_values(ist, dict = attr2dict(ist, self->body->data.ptr), 0 );
 	del_unlock(dict);
 	return res;
 }
@@ -298,9 +298,9 @@
 	obj_p obj;
 	attr_p attrp;
 	BIN_CONTENT_CHK(AttrDict);
-	obj = self->data.ptr;
+	obj = self->body->data.ptr;
 	write_lock(ist, obj);
-	attrp = obj->attr_proto.attrs;
+	attrp = obj->body->attr_proto.attrs;
 	memset(attr_ap(attrp, 0), 0, attr_asize(attrp) * sizeof(attr_t));
 	attr_alen(attrp) = 0;
 	write_unlock(ist, obj);
Modified: trunk/src/builtins-bytes.c
===================================================================
--- trunk/src/builtins-bytes.c	2004-07-17 08:33:55 UTC (rev 748)
+++ trunk/src/builtins-bytes.c	2004-07-18 04:26:50 UTC (rev 749)
@@ -72,15 +72,15 @@
 	obj = NEW_OBJ(OBJ(BYTES_PROTO));
 	if (len <= IMM_DATA_LEN) {
 		SET_TYPE_IF_EXC(OBJ(BYTES_PROTO), obj, DATA_TYPE_IMMDATA) return NULL;
-		obj->imm_data_len = (int) len;
+		obj->body->imm_data_len = (int) len;
 		if (len)
-			memcpy(obj->data.bytes, byt, len);
+			memcpy(obj->body->data.bytes, byt, len);
 	} else {
 		obj_byt = obj_malloc(ist, OBJ(BYTES_PROTO), obj, sizeof(byt_t)+len); if_exc_return NULL;
 		obj_byt->size = (data_size_t) (sizeof(byt_t)+len);
 		memcpy(&(obj_byt->byt[0]), byt, len);
 	}
-	obj->immutable = TRUE;
+	obj->body->immutable = TRUE;
 	return obj;
 }
 
@@ -89,20 +89,20 @@
 	byt_p obj_byt;
 	if (len <= IMM_DATA_LEN) {
 		SET_TYPE_IF_EXC(OBJ(BYTES_PROTO), obj, DATA_TYPE_IMMDATA) return;
-		obj->imm_data_len = (int) len;
-		memcpy(obj->data.bytes, byt, len);
+		obj->body->imm_data_len = (int) len;
+		memcpy(obj->body->data.bytes, byt, len);
 	} else {
 		obj_byt = obj_malloc(ist, OBJ(BYTES_PROTO), obj, sizeof(byt_t)+len); if_exc_return;
 		obj_byt->size = (data_size_t) sizeof(byt_t)+len;
 		memcpy(&(obj_byt->byt[0]), byt, len);
 	}
-	obj->immutable = TRUE;
+	obj->body->immutable = TRUE;
 	return;
 }
 
 //********************************* bytes_ptr *********************************
 u8_t* bytes_ptr(obj_p obj) {
-	if (obj->data_type == DATA_TYPE_IMMDATA) 
+	if (obj->body->data_type == DATA_TYPE_IMMDATA) 
 		return obj_dataptr(obj);
 	else
 		return ((u8_t*) obj_dataptr(obj)) + sizeof(data_size_t);
@@ -110,8 +110,8 @@
 
 //********************************* bytes_len *********************************
 size_t bytes_len(obj_p obj) {
-	if (obj->data_type == DATA_TYPE_IMMDATA) 
-		return obj->imm_data_len;
+	if (obj->body->data_type == DATA_TYPE_IMMDATA) 
+		return obj->body->imm_data_len;
 	else
 		return DATA_SIZE(obj)-sizeof(data_size_t);
 }
@@ -125,7 +125,7 @@
 	set_obj_id(Bytes_OBJ, *, Bytes);
 	set_attr(ist, OBJ(OBJECT), sym(ist, "Bytes"), Bytes_OBJ);
 	SET_TYPE_IF_EXC(Bytes_OBJ, Bytes_OBJ, DATA_TYPE_IMMDATA) return;
-	Bytes_OBJ->imm_data_len = 0;
+	Bytes_OBJ->body->imm_data_len = 0;
 }
 
 DEF(Bytes, init_, FPARM2(value, OBJ(NODEF), encoding, NEW_STRING("ASCII"))) {
@@ -147,15 +147,15 @@
 		len = pr_strlen(parms[1]);
 		if (len <= IMM_DATA_LEN) {
 			SET_TYPE_IF_EXC(OBJ(BYTES_PROTO), self, DATA_TYPE_IMMDATA) return NULL;
-			self->imm_data_len = (int) len;
-			buf = self->data.bytes;
+			self->body->imm_data_len = (int) len;
+			buf = self->body->data.bytes;
 		} else {
 			obj_byt = obj_malloc(ist, OBJ(BYTES_PROTO), self, sizeof(byt_t)+len); if_exc_return NULL;
 			obj_byt->size = (data_size_t) (sizeof(byt_t)+len);
 			buf = &(obj_byt->byt[0]);
 		}
 		pr_str2bytes(ist, buf, parms[1], latin);
-		self->immutable = TRUE;
+		self->body->immutable = TRUE;
 		return OBJ(NONE);
 	} else if (has_proto(ist, parms[1], OBJ(LIST_PROTO))) {
 		obj_p list = parms[1];
@@ -163,8 +163,8 @@
 		u8_t* bufp;
 		if (len <= IMM_DATA_LEN) {
 			SET_TYPE_IF_EXC(OBJ(BYTES_PROTO), self, DATA_TYPE_IMMDATA) return NULL;
-			self->imm_data_len = (int) len;
-			bufp = self->data.bytes;
+			self->body->imm_data_len = (int) len;
+			bufp = self->body->data.bytes;
 		} else {
 			obj_byt = obj_malloc(ist, OBJ(BYTES_PROTO), self, sizeof(byt_t)+len); if_exc_return NULL;
 			obj_byt->size = (data_size_t) (sizeof(byt_t)+len);
@@ -184,7 +184,7 @@
 			}
 			*(bufp++) = (u8_t) val;
 		}
-		self->immutable = TRUE;
+		self->body->immutable = TRUE;
 		return OBJ(NONE);
 	} else if (has_proto(ist, parms[1], OBJ(BYTES_PROTO))) {
 		return copy_object(ist, parms[1]);
@@ -353,7 +353,7 @@
 	BIN_CONTENT_CHK(Bytes);
 	gen_obj = NEW_OBJ(BytesGen_OBJ);
 	SET_TYPE_IF_EXC(BytesGen_OBJ, gen_obj, DATA_TYPE_DATAPTR) return NULL;
-	bytgenp = gen_obj->data.ptr = pr_malloc(sizeof(bytgen_t) + bytes_len(self));
+	bytgenp = gen_obj->body->data.ptr = pr_malloc(sizeof(bytgen_t) + bytes_len(self));
 	bytgenp->size = DATA_SIZE(self);
 	bytgenp->ptr  = ((u8_t*)bytgenp) + sizeof(bytgen_t);
 	memcpy(bytgenp->ptr, bytes_ptr(self), bytes_len(self));
@@ -374,8 +374,8 @@
 
 		BIN_CONTENT_CHK(BytesGen);
         def_write_lock(self);
-        bytgenp = (bytgen_p)(self->data.ptr);
-		limit = ((u8_t*)(self->data.ptr)) + (bytgenp->size);
+        bytgenp = (bytgen_p)(self->body->data.ptr);
+		limit = ((u8_t*)(self->body->data.ptr)) + (bytgenp->size);
 		if (bytgenp->ptr == limit) {
 			raise_exception(ist, OBJ(STOP_ITERATION_EXC), NULL);
 			return NULL;
Modified: trunk/src/builtins-core.c
===================================================================
--- trunk/src/builtins-core.c	2004-07-17 08:33:55 UTC (rev 748)
+++ trunk/src/builtins-core.c	2004-07-18 04:26:50 UTC (rev 749)
@@ -199,15 +199,15 @@
 
 DEF(Object, copy, NULL) {
 	obj_p copy;
-	if (self->unclonable) {
+	if (self->body->unclonable) {
 		raise_exception(ist, OBJ(TYPE_EXC), "copy() not supported on this object");
 		return NULL;
 	}
 	copy = copy_object(ist, self);
-	if (self->data_type == DATA_TYPE_DATAPTR) {
+	if (self->body->data_type == DATA_TYPE_DATAPTR) {
 		data_size_t data_size = DATA_SIZE(self);
-		copy->data.ptr = pr_malloc(data_size);
-		memcpy(copy->data.ptr, self->data.ptr, data_size);
+		copy->body->data.ptr = pr_malloc(data_size);
+		memcpy(copy->body->data.ptr, self->body->data.ptr, data_size);
 	}
 	return copy;
 }
@@ -292,7 +292,7 @@
 		raise_exception(ist, OBJ(PERMISSION_EXC), "write access permission error");	
 		return NULL;
 	}
-	set_obj_rdacc(self, (int) parms[1]->data.i64);
+	set_obj_rdacc(self, (int) parms[1]->body->data.i64);
 	return parms[1];
 }
 
@@ -316,7 +316,7 @@
 		raise_exception(ist, OBJ(PERMISSION_EXC), "write access permission error");	
 		return NULL;
 	}
-	set_obj_wracc(self, (int) parms[1]->data.i64);
+	set_obj_wracc(self, (int) parms[1]->body->data.i64);
 	return parms[1];
 }
 
@@ -443,7 +443,7 @@
 	obj_p thd;
 	CHECK_TYPE_EXC(parms[1], OBJ(FLOAT_PROTO), "float");
 	thd = os_thread_2_obj(apr_os_thread_current());
-	call_func1(ist, thd, sym(ist, "sleep"), NEW_FLOAT(parms[1]->data.f64));
+	call_func1(ist, thd, sym(ist, "sleep"), NEW_FLOAT(parms[1]->body->data.f64));
 	return parms[1];
 }
 
@@ -629,7 +629,7 @@
 
 DEF(Local, str_, NULL) {
 	BIN_STR_CHK(Local);
-	return call_func0(ist, self->data.ptr, SYM(STR_));
+	return call_func0(ist, self->body->data.ptr, SYM(STR_));
 }
 
 DEF(Local, objList_, FORM_RPARAM) {
@@ -647,7 +647,7 @@
 
 DEF(Super, str_, NULL) {
 	BIN_STR_CHK(Super);
-	return call_func0(ist, self->data.ptr, SYM(STR_));
+	return call_func0(ist, self->body->data.ptr, SYM(STR_));
 }
 
 DEF(Super, objList_, FORM_RPARAM) {
@@ -878,18 +878,18 @@
 	
 	BIN_EMPTY_CHK();
 	FUNC___PARAM(1, other);
-	optr = other->data.ptr;
+	optr = other->body->data.ptr;
 	if (!optr) {
 		raise_exception(ist, OBJ(INTERNAL_EXC), "Func init_ param not initialized");
 		return NULL;
 	}
-	self->data_type = other->data_type;
-	if (self->data_type == DATA_TYPE_DATAPTR) {
+	self->body->data_type = other->body->data_type;
+	if (self->body->data_type == DATA_TYPE_DATAPTR) {
 		size = DATA_SIZE(other);
-		self->data.ptr = pr_malloc(size);
-		memcpy(self->data.ptr, other->data.ptr, size);
+		self->body->data.ptr = pr_malloc(size);
+		memcpy(self->body->data.ptr, other->body->data.ptr, size);
 	} else 
-		self->data.ptr = other->data.ptr;
+		self->body->data.ptr = other->body->data.ptr;
 	read_unlock(ist, self);
 	if ((fparms = get_attr(ist,  other, SYM(FPARAMS_))))
 		 set_attr(ist, self, SYM(FPARAMS_), copy_list_obj(ist, fparms));
@@ -903,7 +903,7 @@
 
 	BIN_STR_CHK(Func);
 	apr_snprintf(str, sizeof(str), "<func:%"APR_UINT64_T_HEX_FMT, (apr_uint64_t)(intptr_t) self);
-	if (self->data_type == DATA_TYPE_EXTPTR)
+	if (self->body->data_type == DATA_TYPE_EXTPTR)
 		strcat(str, ":c");
 	if ((bobj = get_attr(ist, self, SYM(BINDOBJ_)))) {
 		strcat(str, ":bound:");
@@ -958,7 +958,7 @@
 	}
 	range_obj = NEW_OBJ(RangeGen_OBJ);
 	SET_TYPE_IF_EXC(RangeGen_OBJ, range_obj, DATA_TYPE_DATAPTR) return NULL;
-	range_obj->data.ptr = rangep = (range_p) pr_malloc(sizeof(range_t));
+	range_obj->body->data.ptr = rangep = (range_p) pr_malloc(sizeof(range_t));
 	rangep->size  = sizeof(range_t);
 	rangep->value = start;
 	rangep->stop  = stop;
@@ -970,7 +970,7 @@
 	obj_p res;
 	range_p rangep;
 	BIN_CONTENT_CHK(RangeGen);
-	rangep = self->data.ptr;
+	rangep = self->body->data.ptr;
 	if ( (rangep->step > 0 && rangep->value >= rangep->stop) ||
 		 (rangep->step < 0 && rangep->value <= rangep->stop) ) {
 		raise_exception(ist, OBJ(STOP_ITERATION_EXC), NULL);
@@ -989,8 +989,8 @@
 
 obj_p new_slice_obj(isp ist, obj_p ind1, obj_p ind2, obj_p ind3) {
 	obj_p slice_obj = NEW_LIST(3);
-	pr_assert(!(slice_obj->has_attrs));
-	slice_obj->attr_proto.proto = OBJ(SLICE_PROTO);
+	pr_assert(!(slice_obj->body->has_attrs));
+	slice_obj->body->attr_proto.proto = OBJ(SLICE_PROTO);
 	if (ind1 == SLICEPARAM_EMPTY)
 		list_append_no_lock(slice_obj, OBJ(NONE));
 	else
@@ -1007,7 +1007,7 @@
 				list_append_no_lock(slice_obj,ind3);
 		}
 	}
-	slice_obj->immutable = TRUE;
+	slice_obj->body->immutable = TRUE;
 	return slice_obj;
 }
 
@@ -1074,7 +1074,7 @@
 	char *str_obj, buf[256];
 	if (self == WeakRef_OBJ) return NEW_STRING("<Prototype:WeakRef>");
 	BIN_STR_CHK(WeakRef);
-	wrp = self->data.ptr;
+	wrp = self->body->data.ptr;
 	if (wrp->exists) {
 		str_obj = as_str(ist, wrp->ref);
 		apr_snprintf(buf, sizeof(buf), "<WeakRef:%s>", str_obj);
@@ -1091,7 +1091,7 @@
 
 	BIN_EMPTY_CHK();
 	SET_TYPE_IF_EXC(WeakRef_OBJ, self, DATA_TYPE_DATAPTR) return NULL;
-	wrp = self->data.ptr = pr_malloc(sizeof(weak_ref_t));
+	wrp = self->body->data.ptr = pr_malloc(sizeof(weak_ref_t));
 	wrp->data_size	  = sizeof(weak_ref_t);
 	wrp->exists       = TRUE;
 	wrp->notify_flags = DELETE_NOTIFY;
@@ -1111,7 +1111,7 @@
 }
 
 DEF(WeakRef, ref, NULL) {
-	weak_ref_p wrp = self->data.ptr;
+	weak_ref_p wrp = self->body->data.ptr;
 	BIN_CONTENT_CHK(WeakRef);
 	if(!wrp->exists) {
 		raise_exception(ist, OBJ(INTERPRETER_EXC), "object doesn't exist anymore");
@@ -1121,14 +1121,14 @@
 }
 
 DEF(WeakRef, exists_QUES, NULL) {
-	weak_ref_p wrp = self->data.ptr;
+	weak_ref_p wrp = self->body->data.ptr;
 	BIN_CONTENT_CHK(WeakRef);
 	if (wrp->exists) return OBJ(PR_TRUE);
 	else			 return OBJ(PR_FALSE);
 }
 
 DEF(WeakRef, flags, NULL) {
-	weak_ref_p wrp = self->data.ptr;
+	weak_ref_p wrp = self->body->data.ptr;
 	BIN_CONTENT_CHK(WeakRef);
 	return NEW_INT(wrp->notify_flags);
 }
@@ -1136,7 +1136,7 @@
 DEF( WeakRef, notify, FPARM3( func,  OBJ(NODEF), 
 							  param, OBJ(NONE), 
 							  flags, NEW_INT(WRITE_NOTIFY|DELETE_NOTIFY) ) ) { 
-	weak_ref_p wrp = self->data.ptr;
+	weak_ref_p wrp = self->body->data.ptr;
 	obj_p callback_func;
 	int flags, immutable_flag;
 	BIN_CONTENT_CHK(WeakRef);
@@ -1211,7 +1211,7 @@
 			call_func(ist, NULL, on_write_func, NULL, 2, arr, NULL);
 	}
 	if (flags & DELETE_NOTIFY) {
-		weak_ref_p wrp = self->data.ptr;
+		weak_ref_p wrp = self->body->data.ptr;
 		obj_p on_delete_func  = get_attr(ist, self, sym(ist, "onDelete_"));
 		obj_p on_delete_param = get_attr(ist, self, sym(ist, "onDeleteParam_"));
 		wrp->exists = FALSE;

Modified: trunk/src/builtins-dict.c
===================================================================
--- trunk/src/builtins-dict.c	2004-07-17 08:33:55 UTC (rev 748)
+++ trunk/src/builtins-dict.c	2004-07-18 04:26:50 UTC (rev 749)
@@ -125,17 +125,17 @@
 	if (has_proto(ist, key_in, OBJ(INT_PROTO))) {
 		i32_t res;
 		long_p v;
-		if (key_in->data_type == DATA_TYPE_IMMDATA) {
-			res = long_hash(v = new_longp(key_in->data.i64));
+		if (key_in->body->data_type == DATA_TYPE_IMMDATA) {
+			res = long_hash(v = new_longp(key_in->body->data.i64));
 			pr_free(v);
 			return res;
 		}
 		else
-			return long_hash(key_in->data.ptr);
+			return long_hash(key_in->body->data.ptr);
 	}
 	hash_obj = call_func0(ist, key_in, SYM(HASH_));
 	if_exc_return 0;
-	return hash_obj->data.i32[0];
+	return hash_obj->body->data.i32[0];
 }
 
 //********************************* dict_add **********************************
@@ -152,7 +152,7 @@
 	dict = dict_d(dict_obj);
 
 	if (((dictlen(dict) * 100) / dictsize(dict)) > DICT_MAX_PERCENT_FULL)
-		dict_obj->data.ptr = dict = (void *)dict_realloc(dict);
+		dict_obj->body->data.ptr = dict = (void *)dict_realloc(dict);
 
 	for (i=hash_in; (key=((dp=dictptr(dict,i))->entry.key)); i++){
 		hash = dp->entry.hash;
@@ -427,7 +427,7 @@
 }
 
 DEF(Dict, objList_, FORM_RPARAM) {
-	if (!self->data.ptr) return parms[1];
+	if (!self->body->data.ptr) return parms[1];
 	return dict_keys_values(ist, self, 0 /*values*/);
 }
 
@@ -489,7 +489,7 @@
 		def_write_unlock(self);
 		return NULL;
 	}
-	dict = (dict_p) self->data.ptr;
+	dict = (dict_p) self->body->data.ptr;
 	for(i=hash_in; (key=((dp=dictptr(dict,i))->entry.key)); i++){
 		if ( dp->entry.hash == hash_in && ( key == key_in ||
 			 call_func(ist, key, SYM(EQ__QUES), NULL, 2, rp, NULL) == OBJ(PR_TRUE) ) ) {
@@ -610,14 +610,14 @@
 
 	BIN_CONTENT_CHK(Dict);
 	SET_TYPE_IF_EXC(DictGen_OBJ, gen_obj, DATA_TYPE_DATAPTR) return NULL;
-	gen_obj->data.ptr = list_obj = dict_keys(ist, self);
+	gen_obj->body->data.ptr = list_obj = dict_keys(ist, self);
 
 	listlen(list_obj) = 0;
 	return gen_obj;
 }
 
 DEF(DictGen, next, NULL) {
-	obj_p res, list_obj = self->data.ptr;
+	obj_p res, list_obj = self->body->data.ptr;
 
 	BIN_CONTENT_CHK(DictGen);
 	CHECK_TYPE_EXC(self, DictGen_OBJ, "DictGen");

Modified: trunk/src/builtins-file.c
===================================================================
--- trunk/src/builtins-file.c	2004-07-17 08:33:55 UTC (rev 748)
+++ trunk/src/builtins-file.c	2004-07-18 04:26:50 UTC (rev 749)
@@ -74,10 +74,10 @@
 
 typedef file_t* file_p;
 
-#define STREAM(obj)  (((file_p)((obj)->data.ptr))->stream)
-#define BUFSIZE(obj) (((file_p)((obj)->data.ptr))->bufsize)
-#define POOL(obj)    (((file_p)((obj)->data.ptr))->pool)
-#define FLAGS(obj)   (((file_p)((obj)->data.ptr))->flags)
+#define STREAM(obj)  (((file_p)((obj)->body->data.ptr))->stream)
+#define BUFSIZE(obj) (((file_p)((obj)->body->data.ptr))->bufsize)
+#define POOL(obj)    (((file_p)((obj)->body->data.ptr))->pool)
+#define FLAGS(obj)   (((file_p)((obj)->body->data.ptr))->flags)
 #define OPEN(obj)    (((obj) != File_OBJ) && STREAM(obj))
 
 MODULE_DECLARE(Dir);
@@ -142,9 +142,9 @@
 	filep->stream       = fp;
 	filep->pool         = subpool;
 	filep->flags        = flags;
-	file_obj->data.ptr  = filep;
-	file_obj->rd_access = ACC_USER1;
-	file_obj->wr_access = ACC_USER1;
+	file_obj->body->data.ptr  = filep;
+	file_obj->body->rd_access = ACC_USER1;
+	file_obj->body->wr_access = ACC_USER1;
 }
 
 //*************************** new_file_obj ************************************
@@ -186,7 +186,7 @@
 	file_p filep;
 	obj_p uperms_obj = NULL, res = OBJ(NONE);
 	i64_t count = 0;
-	filep = self->data.ptr;
+	filep = self->body->data.ptr;
 	dirpath = pr2c_strptr(ist, get_attr(ist, self, sym(ist, "path")));
 	if (dest_dir) {
 		destpath = pr2c_strptr(ist, get_attr(ist, dest_dir, sym(ist, "path")));
@@ -217,7 +217,7 @@
 						obj_p dir_obj, int_obj;
 						dir_obj = new_dir_obj(ist, filepath);  if_exc_return NULL;
 						int_obj = call_func0(ist, dir_obj, sym(ist, "size")); if_exc_return NULL;
-						count += int_obj->data.i64;
+						count += int_obj->body->data.i64;
 						del_unlock(dir_obj);
 						del_unlock(int_obj);
 					}
@@ -276,7 +276,7 @@
 	set_obj_doc(Dir_OBJ, "Directory object prototype");
 
 	MODULE_ADD_TO_BASE(Dir);
-	Dir_OBJ->unclonable = TRUE;
+	Dir_OBJ->body->unclonable = TRUE;
 }
 
 DEF(Dir, init_, FPARM1(path, NEW_STRING("."))) {
@@ -312,7 +312,7 @@
 	char* path;
 	file_p filep;
 	BIN_CONTENT_CHK(Dir);
-	filep = self->data.ptr;
+	filep = self->body->data.ptr;
 	path = pr2c_strptr(ist, get_attr(ist, self, sym(ist, "path")));
 	apr_stat(&finfo, path, APR_FINFO_MIN, filep->pool);
 	if (finfo.filetype == APR_DIR)  return OBJ(PR_TRUE);
@@ -326,7 +326,7 @@
 	file_p filep;
 	BIN_CONTENT_CHK(Dir);
 	INT_32_PARAM(1, uperms);
-	filep = self->data.ptr;
+	filep = self->body->data.ptr;
 	path = pr2c_strptr(ist, get_attr(ist, self, sym(ist, "path")));
 	aprerr = apr_dir_make_recursive(path, uperms, filep->pool);
 	IF_APR_ERR("Unable to make directory") return NULL;
@@ -339,7 +339,7 @@
 	char *temp, *tempp, *respath;
 	file_p filep;
 	BIN_CONTENT_CHK(Dir);
-	filep = self->data.ptr;
+	filep = self->body->data.ptr;
 	filepath = pr2c_strptr(ist, get_attr(ist, self, sym(ist, "path")));
 	tempp = temp = pr_malloc(strlen(filepath)+1);
 	strcpy(temp, filepath);
@@ -360,7 +360,7 @@
 	const char *rootpath, *filepath;
 	file_p filep;
 	BIN_CONTENT_CHK(Dir);
-	filep = self->data.ptr;
+	filep = self->body->data.ptr;
 	filepath = pr2c_strptr(ist, get_attr(ist, self, sym(ist, "path")));
 	aprerr = apr_filepath_root(&rootpath, &filepath, APR_FILEPATH_TRUENAME, filep->pool);
 	IF_APR_ERR("calculating root path") return NULL;
@@ -404,7 +404,7 @@
 	file_p filep;
 	BIN_CONTENT_CHK(Dir);
 	STRING_PARAM(1, name);
-	filep = self->data.ptr;
+	filep = self->body->data.ptr;
 	dirpath = pr2c_strptr(ist, get_attr(ist, self, sym(ist, "path")));
 	for (p=name; *p; p++) 
 		if (*p == '/' || *p == '\\') {
@@ -422,7 +422,7 @@
 	file_p filep;
 	BIN_CONTENT_CHK(Dir);
 	CHECK_TYPE_EXC(parms[1], Dir_OBJ, Directory);
-	filep = self->data.ptr;
+	filep = self->body->data.ptr;
 	dirpath1 = pr2c_strptr(ist, get_attr(ist,     self, sym(ist, "path")));
 	dirpath2 = pr2c_strptr(ist, get_attr(ist, parms[1], sym(ist, "path")));
 	aprerr = apr_file_rename(dirpath1, dirpath2, filep->pool);
@@ -438,7 +438,7 @@
 	BIN_CONTENT_CHK(Dir);
 	CHECK_TYPE_EXC(parms[1], Dir_OBJ, Directory);
 	INT_32_PARAM(2, uperms);
-	filep = self->data.ptr;
+	filep = self->body->data.ptr;
 	path = pr2c_strptr(ist, get_attr(ist, parms[1], sym(ist, "path")));
 	aprerr = apr_dir_make_recursive(path, uperms, filep->pool);
 	IF_APR_ERR("Unable to make directory") return NULL;
@@ -451,7 +451,7 @@
 	char* path;
 	file_p filep;
 	BIN_CONTENT_CHK(Dir);
-	filep = self->data.ptr;
+	filep = self->body->data.ptr;
 	dir_list(ist, self, -1, DLIST_DELETE, NULL, NULL, 0);
 	path = pr2c_strptr(ist, get_attr(ist, self, sym(ist, "path")));
 	aprerr = apr_dir_remove(path, filep->pool );
@@ -486,7 +486,7 @@
 	int attrs = 0, attrs_mask = 0;
 	file_p filep;
 	BIN_CONTENT_CHK(Dir);
-	filep = self->data.ptr;
+	filep = self->body->data.ptr;
 	if (parms[1] == OBJ(PR_TRUE)) { 
 		attrs |= APR_FILE_ATTR_READONLY;   attrs_mask |= APR_FILE_ATTR_READONLY;   }
 	if (parms[3] == OBJ(PR_TRUE)) { 
@@ -508,13 +508,13 @@
 	obj_p time_obj;
 	file_p filep;
 	BIN_CONTENT_CHK(Dir);
-	filep = self->data.ptr;
+	filep = self->body->data.ptr;
 	time_obj = parms[1];
 	if (time_obj == OBJ(NONE)) time_obj = new_time_obj(ist, apr_time_now());
 	CHECK_TYPE_EXC(time_obj, OBJ(DATETIME_PROTO), time);
 	path = pr2c_strptr(ist, get_attr(ist, self, sym(ist, "path")));
 	path[strlen(path)-1] = 0;
-	aprerr = apr_file_mtime_set(path, time_obj->data.i64, filep->pool);
+	aprerr = apr_file_mtime_set(path, time_obj->body->data.i64, filep->pool);
 	IF_APR_ERR("setting directory modification time") return NULL;
 	return self;
 }
@@ -524,7 +524,7 @@
 	char* path;
 	file_p filep;
 	BIN_CONTENT_CHK(Dir);
-	filep = self->data.ptr;
+	filep = self->body->data.ptr;
 	path = pr2c_strptr(ist, get_attr(ist, self, sym(ist, "path")));
 	apr_stat(&info, path, APR_FINFO_MTIME, filep->pool);
 	if ((info.valid & APR_FINFO_MTIME) == 0) {
@@ -574,7 +574,7 @@
 	apr_pool_t *subpool;
 	char* temp_dir;
 	int i;
-	if (TempDir_OBJ->data.ptr) return;
+	if (TempDir_OBJ->body->data.ptr) return;
 	aprerr = apr_pool_create(&subpool, get_pr_head_pool());
 	IF_APR_ERR("getting memory for TempFile") return;
 	aprerr = apr_temp_dir_get((const char **)&temp_dir, subpool);
@@ -589,7 +589,7 @@
 	set_obj_doc(TempDir_OBJ, "Temporary Directory object prototype");
 
 	MODULE_ADD_TO_BASE(TempDir);
-	TempDir_OBJ->unclonable = TRUE;
+	TempDir_OBJ->body->unclonable = TRUE;
 }
 
 DEF(TempDir, init_, NULL) {
@@ -615,7 +615,7 @@
 }
 
 DEF(TempDir, final_, NULL) {
-	if (self->data.ptr)
+	if (self->body->data.ptr)
 		call_func0(ist, self, sym(ist, "delete"));
 	return OBJ(NONE);
 }
@@ -629,7 +629,7 @@
 	set_obj_doc(File_OBJ, "File object prototype");
 
 	MODULE_ADD_TO_BASE(File);
-	File_OBJ->unclonable = TRUE;
+	File_OBJ->body->unclonable = TRUE;
 }
 
 DEF(File, init_, FPARM3( path,    OBJ(NODEF), 
@@ -653,7 +653,7 @@
 		SET_TYPE_IF_EXC(File_OBJ, self, DATA_TYPE_DATAPTR) return NULL;
 		set_file_obj_data(ist, self, parms[1], NULL, NULL, 0, 0);
 		read_lock(ist, self);
-		self->unclonable = TRUE;
+		self->body->unclonable = TRUE;
 		return OBJ(NONE);
 	}
 
@@ -694,7 +694,7 @@
 	SET_TYPE_IF_EXC(File_OBJ, self, DATA_TYPE_DATAPTR) return NULL;
 	set_file_obj_data(ist, self, parms[1], parms[3], f, bufsize, flags);
 	read_lock(ist, self);
-	self->unclonable = TRUE;
+	self->body->unclonable = TRUE;
 	return OBJ(NONE);
 }
 
@@ -712,7 +712,7 @@
 	char *path;
 	file_p filep;
 	BIN_CONTENT_CHK(File);
-	filep = self->data.ptr;
+	filep = self->body->data.ptr;
 	if (OPEN(self)) return OBJ(PR_TRUE);
 	path = pr2c_strptr(ist, get_attr(ist, self, sym(ist, "path")));
 	apr_stat(&finfo, path, APR_FINFO_MIN, filep->pool);
@@ -737,7 +737,7 @@
 			return NULL;
 		}
 	path = pr2c_strptr(ist, get_attr(ist, self, sym(ist, "path")));
-	filep = self->data.ptr;
+	filep = self->body->data.ptr;
 	aprerr = apr_file_rename(path, name, filep->pool);
 	IF_APR_ERR("renaming a file") return NULL;
 	return new_file_obj(ist, NEW_STRING(name), NULL, NULL, 0, 0);
@@ -754,7 +754,7 @@
 		raise_exception( ist, OBJ(IO_EXC), "attempt to move an open file");
 		return NULL;
 	}
-	filep = self->data.ptr;
+	filep = self->body->data.ptr;
 	srcfilepath = pr2c_strptr(ist, get_attr(ist, self, sym(ist, "path")));
 	filename    = pr2c_strptr(ist, get_attr(ist, self, sym(ist, "name")));
 	dstpath     = pr2c_strptr(ist, get_attr(ist, parms[1], sym(ist, "path")));
@@ -775,7 +775,7 @@
 	BIN_CONTENT_CHK(File);
 	CHECK_TYPE_EXC(parms[1], File_OBJ, File);
 	INT_32_PARAM(2, uperms);
-	filep = self->data.ptr;
+	filep = self->body->data.ptr;
 	path1 = pr2c_strptr(ist, get_attr(ist,     self, sym(ist, "path")));
 	path2 = pr2c_strptr(ist, get_attr(ist, parms[1], sym(ist, "path")));
 	aprerr = apr_file_copy(path1, path2, uperms, filep->pool);
@@ -792,7 +792,7 @@
 		raise_exception( ist, OBJ(IO_EXC), "attempt to delete an open file");
 		return NULL;
 	}
-	filep = self->data.ptr;
+	filep = self->body->data.ptr;
 	path = pr2c_strptr(ist, get_attr(ist, self, sym(ist, "path")));
 	aprerr = apr_file_remove(path, filep->pool );
 	IF_APR_ERR("deleting file") return NULL;
@@ -826,7 +826,7 @@
 	int attrs = 0, attrs_mask = 0;
 	file_p filep;
 	BIN_CONTENT_CHK(File);
-	filep = self->data.ptr;
+	filep = self->body->data.ptr;
 	if (parms[1] == OBJ(PR_TRUE)) { 
 		attrs |= APR_FILE_ATTR_READONLY;   attrs_mask |= APR_FILE_ATTR_READONLY;   }
 	if (parms[3] == OBJ(PR_TRUE)) { 
@@ -848,12 +848,12 @@
 	obj_p time_obj;
 	file_p filep;
 	BIN_CONTENT_CHK(File);
-	filep = self->data.ptr;
+	filep = self->body->data.ptr;
 	time_obj = parms[1];
 	if (time_obj == OBJ(NONE)) time_obj = new_time_obj(ist, apr_time_now());
 	CHECK_TYPE_EXC(time_obj, OBJ(DATETIME_PROTO), time);
 	path = pr2c_strptr(ist, get_attr(ist, self, sym(ist, "path")));
-	aprerr = apr_file_mtime_set(path, time_obj->data.i64, filep->pool);
+	aprerr = apr_file_mtime_set(path, time_obj->body->data.i64, filep->pool);
 	IF_APR_ERR("setting file modification time") return NULL;
 	return self;
 }
@@ -863,7 +863,7 @@
 	char* path;
 	file_p filep;
 	BIN_CONTENT_CHK(File);
-	filep = self->data.ptr;
+	filep = self->body->data.ptr;
 	path = pr2c_strptr(ist, get_attr(ist, self, sym(ist, "path")));
 	apr_stat(&info, path, APR_FINFO_MTIME, filep->pool);
 	if ((info.valid & APR_FINFO_MTIME) == 0) {
@@ -878,7 +878,7 @@
 	char* path;
 	file_p filep;
 	BIN_CONTENT_CHK(File);
-	filep = self->data.ptr;
+	filep = self->body->data.ptr;
 	path = pr2c_strptr(ist, get_attr(ist, self, sym(ist, "path")));
 	apr_stat(&info, path, APR_FINFO_SIZE, filep->pool);
 	if ((info.valid & APR_FINFO_SIZE) == 0) {
@@ -905,7 +905,7 @@
 		raise_exception(ist, OBJ(TYPE_EXC), "file is already open");
 		return NULL;
 	}
-	filep = self->data.ptr;
+	filep = self->body->data.ptr;
 	path = pr2c_strptr(ist, get_attr(ist, self, sym(ist, "path")));
 
 	if (strlen(mode) == 0) {
@@ -913,7 +913,7 @@
 		SET_TYPE_IF_EXC(File_OBJ, self, DATA_TYPE_DATAPTR) return NULL;
 		set_file_obj_data(ist, self, NEW_STRING(path), NULL, NULL, 0, 0);
 		read_lock(ist, self);
-		self->unclonable = TRUE;
+		self->body->unclonable = TRUE;
 		return OBJ(NONE);
 	}
 
@@ -1033,7 +1033,7 @@
 	byt_obj = NEW_OBJ(OBJ(BYTES_PROTO));
 	if (size < IMM_DATA_LEN) {
 		SET_TYPE_IF_EXC(OBJ(BYTES_PROTO), byt_obj, DATA_TYPE_IMMDATA) return NULL;
-		buf = byt_obj->data.bytes;
+		buf = byt_obj->body->data.bytes;
 	} else {
 		obj_str = obj_malloc(ist, OBJ(BYTES_PROTO), byt_obj, sizeof(str_t)+size+1);
 		buf = obj_str->byt;
@@ -1049,7 +1049,7 @@
 	while(aprerr != APR_EOF && (readall || total_read < size)) {
 		size_t next_read = (readall ? size : size - total_read);
 		size_t new_len   =  total_read + next_read;
-		if (byt_obj->data_type == DATA_TYPE_IMMDATA && new_len >= IMM_DATA_LEN) {
+		if (byt_obj->body->data_type == DATA_TYPE_IMMDATA && new_len >= IMM_DATA_LEN) {
 			obj_str = obj_malloc(ist, OBJ(BYTES_PROTO), byt_obj, sizeof(str_t)+new_len+1);
 			buf = obj_str->byt;
 		} else {
@@ -1065,15 +1065,15 @@
 		}
 		total_read += num_read;
 	}
-	if (byt_obj->data_type == DATA_TYPE_IMMDATA)
-		byt_obj->imm_data_len = (int) total_read;
+	if (byt_obj->body->data_type == DATA_TYPE_IMMDATA)
+		byt_obj->body->imm_data_len = (int) total_read;
 	else {
 		obj_str = obj_realloc(ist, byt_obj, sizeof(str_t)+total_read+1);
 		obj_str->size = (data_size_t) (sizeof(str_t)+total_read);
 		buf = obj_str->byt;
 	}
 	buf[total_read] = 0;
-	byt_obj->immutable = TRUE;
+	byt_obj->body->immutable = TRUE;
 	return byt_obj;
 }
 
@@ -1202,7 +1202,7 @@
 	set_obj_doc(TempFile_OBJ, "TempFile object prototype");
 
 	MODULE_ADD_TO_BASE(TempFile);
-	TempFile_OBJ->unclonable = TRUE;
+	TempFile_OBJ->body->unclonable = TRUE;
 }
 
 DEF(TempFile, init_, FPARM2( bufSize, NEW_INT(-1), delOnClose, OBJ(PR_FALSE))) {
@@ -1234,7 +1234,7 @@
 	SET_TYPE_IF_EXC(TempFile_OBJ, self, DATA_TYPE_DATAPTR) return NULL;
 	set_file_obj_data(ist, self, NEW_STRING(fullpath), NULL, fp, bufsize, flags);
 	read_lock(ist, self);
-	self->unclonable = TRUE;
+	self->body->unclonable = TRUE;
 	return OBJ(NONE);
 }
 
@@ -1255,7 +1255,7 @@
 	set_obj_doc(TextFile_OBJ, "TextFile object prototype");
 
 	MODULE_ADD_TO_BASE(TextFile);
-	TextFile_OBJ->unclonable = TRUE;
+	TextFile_OBJ->body->unclonable = TRUE;
 }
 
 DEF(TextFile, init_, FPARM5( path,		OBJ(NODEF), 
@@ -1285,7 +1285,7 @@
 		SET_TYPE_IF_EXC(TextFile_OBJ, self, DATA_TYPE_DATAPTR) return NULL;
 		set_file_obj_data(ist, self, parms[1], NULL, NULL, 0, 0);
 		read_lock(ist, self);
-		self->unclonable = TRUE;
+		self->body->unclonable = TRUE;
 		return OBJ(NONE);
 	}
 	read_lock(ist, self);
@@ -1327,7 +1327,7 @@
 	SET_TYPE_IF_EXC(TextFile_OBJ, self, DATA_TYPE_DATAPTR) return NULL;
 	set_file_obj_data(ist, self, parms[1], parms[3], f, bufsize, flags);
 	read_lock(ist, self);
-	self->unclonable = TRUE;
+	self->body->unclonable = TRUE;
 	return OBJ(NONE);
 }
 DEF(TextFile, open, FPARM4( mode,		NEW_STRING("r"),
@@ -1349,7 +1349,7 @@
 	INT_32_PARAM(4, bufsize);
 	path = pr2c_strptr(ist, get_attr(ist, self, sym(ist, "path")));
 
-	filep = self->data.ptr;
+	filep = self->body->data.ptr;
 	read_unlock(ist, self);
 	set_attr(ist, self, sym(ist, "encoding"), NEW_STRING(encoding));
 	if (magic) set_attr(ist, self, sym(ist, "magic"), OBJ(PR_TRUE));
@@ -1358,7 +1358,7 @@
 	if (strlen(mode) == 0) {
 		set_file_obj_data(ist, self, NEW_STRING(path), NULL, NULL, 0, 0);
 		read_lock(ist, self);
-		self->unclonable = TRUE;
+		self->body->unclonable = TRUE;
 		return OBJ(NONE);
 	}
 	read_lock(ist, self);
@@ -1392,7 +1392,7 @@
 	read_unlock(ist, self);
 	set_file_obj_data(ist, self, NEW_STRING(path), NEW_STRING(mode), f, bufsize, flags);
 	read_lock(ist, self);
-	self->unclonable = TRUE;
+	self->body->unclonable = TRUE;
 	return OBJ(NONE);
 }
 
@@ -1464,7 +1464,7 @@
 	str_obj = NEW_OBJ(OBJ(STRING_PROTO));
 	c2pr_bytcpy(ist, str_obj, buf, total_read, latin);
 	pr_free(buf);
-	str_obj->immutable = TRUE;
+	str_obj->body->immutable = TRUE;
 	return str_obj;
 }
 DEF(TextFile, readLine, FPARM1(size, NEW_INT(-1))) {
@@ -1526,7 +1526,7 @@
 	str_obj = NEW_OBJ(OBJ(STRING_PROTO));
 	c2pr_bytcpy(ist, str_obj, buf, total_read, latin);
 	pr_free(buf);
-	str_obj->immutable = TRUE;
+	str_obj->body->immutable = TRUE;
 	return str_obj;
 }
 
@@ -1595,7 +1595,7 @@
 		str_obj = NEW_OBJ(OBJ(STRING_PROTO));
 		c2pr_bytcpy(ist, str_obj, buf, num_read, latin);
 		pr_free(buf);
-		str_obj->immutable = TRUE;
+		str_obj->body->immutable = TRUE;
 		list_append(ist, list_obj, str_obj);
 	}
 	return list_obj;
@@ -1711,7 +1711,7 @@
 	set_obj_doc(TempTextFile_OBJ, "TempTextFile object prototype");
 
 	MODULE_ADD_TO_BASE(TempTextFile);
-	TempTextFile_OBJ->unclonable = TRUE;
+	TempTextFile_OBJ->body->unclonable = TRUE;
 }
 
 DEF( TempTextFile, init_, FPARM4( encoding,		NEW_STRING("ASCII"),
@@ -1753,7 +1753,7 @@
 	SET_TYPE_IF_EXC(TempTextFile_OBJ, self, DATA_TYPE_DATAPTR) return NULL;
 	set_file_obj_data(ist, self, NEW_STRING(fullpath), NULL, fp, bufsize, flags);
 	read_lock(ist, self);
-	self->unclonable = TRUE;
+	self->body->unclonable = TRUE;
 	return OBJ(NONE);
 }
 
@@ -1775,7 +1775,7 @@
 		return NULL;
 	}
 	SET_TYPE_IF_EXC(TextFileGen_OBJ, new_obj, DATA_TYPE_EXTPTR) return NULL;
-	new_obj->data.ptr = self;
+	new_obj->body->data.ptr = self;
 	return new_obj;
 }
 
@@ -1784,11 +1784,11 @@
 	set_obj_doc(TextFileGen_OBJ, "TextFileGen object prototype");
 
 	MODULE_ADD_TO_BASE(TextFileGen);
-	TextFileGen_OBJ->unclonable = TRUE;
+	TextFileGen_OBJ->body->unclonable = TRUE;
 }
 
 DEF(TextFileGen, next, NULL) {
-	obj_p res, file_obj = self->data.ptr;
+	obj_p res, file_obj = self->body->data.ptr;
 	if (!OPEN(file_obj)) {
 		raise_exception(ist, OBJ(STOP_ITERATION_EXC), NULL);
 		return NULL;
@@ -1826,7 +1826,7 @@
 	set_file_obj_data(ist, StdIn_OBJ, NEW_STRING("stdIn"), NEW_STRING("r"), 
 						   fp, 0, APR_READ);
 	set_attr(ist, StdIn_OBJ, sym(ist, "encoding"), NEW_STRING("ASCII"));
-	StdIn_OBJ->unclonable = TRUE;
+	StdIn_OBJ->body->unclonable = TRUE;
 
 	StdOut_OBJ = NEW_OBJ(TextFile_OBJ);
 	set_obj_doc(StdOut_OBJ, "stdOut unique object");
@@ -1836,7 +1836,7 @@
 	set_file_obj_data(ist, StdOut_OBJ, NEW_STRING("stdOut"), NEW_STRING("w"), 
 						   fp, 0, APR_WRITE);
 	set_attr(ist, StdOut_OBJ, sym(ist, "encoding"), NEW_STRING("ASCII"));
-	StdOut_OBJ->unclonable = TRUE;
+	StdOut_OBJ->body->unclonable = TRUE;
 
 	StdErr_OBJ = NEW_OBJ(TextFile_OBJ);
 	set_obj_doc(StdErr_OBJ, "stdErr unique object");
@@ -1846,7 +1846,7 @@
 	set_file_obj_data(ist, StdErr_OBJ, NEW_STRING("stdErr"), NEW_STRING("w"), 
 						   fp, 0, APR_WRITE);
 	set_attr(ist, StdErr_OBJ, sym(ist, "encoding"), NEW_STRING("ASCII"));
-	StdErr_OBJ->unclonable = TRUE;
+	StdErr_OBJ->body->unclonable = TRUE;
 
 	set_attr(ist, OBJ(SYS), sym(ist, "stdIn"),  StdIn_OBJ);
 	set_attr(ist, OBJ(SYS), sym(ist, "stdOut"), StdOut_OBJ);
Modified: trunk/src/builtins-float.c
===================================================================
--- trunk/src/builtins-float.c	2004-07-17 08:33:55 UTC (rev 748)
+++ trunk/src/builtins-float.c	2004-07-18 04:26:50 UTC (rev 749)
@@ -69,16 +69,16 @@
 #define	FLOAT_DATA_SIZE		8
 
 #define is_Float(objid)		(has_proto(ist, objid, Float_OBJ))
-#define Float_value(objid)	(objid->data.f64)
+#define Float_value(objid)	(objid->body->data.f64)
 MODULE_DECLARE(Float);
 
 //********************************* new_float_obj *****************************
 obj_p new_float_obj(isp ist, double num){
 	obj_p obj = NEW_OBJ(Float_OBJ);
 	SET_TYPE_IF_EXC(Float_OBJ, obj, DATA_TYPE_IMMDATA) return NULL;
-	obj->imm_data_len = 8;
-	obj->data.f64 = num;
-	obj->immutable = TRUE;
+	obj->body->imm_data_len = 8;
+	obj->body->data.f64 = num;
+	obj->body->immutable = TRUE;
 	return obj;
 }
 
@@ -97,12 +97,12 @@
 	set_attr(ist, OBJ(OBJECT), sym(ist, "Imaginary"), OBJ(IMAG_PROTO));
 
 	SET_TYPE_IF_EXC(Float_OBJ, Float_OBJ, DATA_TYPE_IMMDATA) return;
-	Float_OBJ->imm_data_len = IMM_DATA_LEN;
-	Float_OBJ->data.f64     = 0.0;
+	Float_OBJ->body->imm_data_len = IMM_DATA_LEN;
+	Float_OBJ->body->data.f64     = 0.0;
 
-	//Imag_OBJ->data_type    = DATA_TYPE_IMMDATA;
-	//Imag_OBJ->imm_data_len = IMM_DATA_LEN;
-	//Imag_OBJ->data.f64     = 0.0;
+	//Imag_OBJ->body->data_type    = DATA_TYPE_IMMDATA;
+	//Imag_OBJ->body->imm_data_len = IMM_DATA_LEN;
+	//Imag_OBJ->body->data.f64     = 0.0;
 }
 
 DEF(Float, init_, FORM_STAR_PARAM) { 
@@ -111,8 +111,8 @@
 	if (list_len(ist, parms[1]))
 		FLOAT__PARAM(0, f);
 	SET_TYPE_IF_EXC(Float_OBJ, self, DATA_TYPE_IMMDATA) return NULL;
-	self->imm_data_len = IMM_DATA_LEN;
-	self->data.f64     = f;
+	self->body->imm_data_len = IMM_DATA_LEN;
+	self->body->data.f64     = f;
 	return OBJ(NONE);
 }
 
@@ -157,7 +157,7 @@
 	if (is_Float(other)) float_other = Float_value(other);
 	else {
 		if (has_proto(ist, other, OBJ(INT_PROTO)))
-			float_other = (double)other->data.i64;
+			float_other = (double)other->body->data.i64;
 		else {
 			if (covers(other, self))
 				return call_func1(ist, other, SYM(ADD_), self);
@@ -175,7 +175,7 @@
 	if (is_Float(other)) float_other = Float_value(other);
 	else {
 		if (has_proto(ist, other, OBJ(INT_PROTO)))
-			float_other = (double)other->data.i64;
+			float_other = (double)other->body->data.i64;
 		else {
 			if (covers(other, self))
 				return call_func1(ist, other, SYM(RDIV_), self);
@@ -197,7 +197,7 @@
 	if (is_Float(other)) float_other = Float_value(other);
 	else {
 		if (has_proto(ist, other, OBJ(INT_PROTO)))
-			float_other = (double)other->data.i64;
+			float_other = (double)other->body->data.i64;
 		else {
 			raise_exception(ist, OBJ(TYPE_EXC), "Float cannot be divided into this object");
 			return NULL;
@@ -217,7 +217,7 @@
 	if (is_Float(other)) float_other = Float_value(other);
 	else {
 		if (has_proto(ist, other, OBJ(INT_PROTO)))
-			float_other = (double)other->data.i64;
+			float_other = (double)other->body->data.i64;
 		else {
 			if (covers(other, self))
 				return call_func1(ist, other, SYM(MUL_), self);
@@ -235,7 +235,7 @@
 	if (is_Float(other)) float_other = Float_value(other);
 	else {
 		if (has_proto(ist, other, OBJ(INT_PROTO)))
-			float_other = (double)other->data.i64;
+			float_other = (double)other->body->data.i64;
 		else {
 			if (covers(other, self))
 				return call_func1(ist, other, SYM(RSUB_), self);
@@ -252,7 +252,7 @@
 	if (is_Float(other)) float_other = Float_value(other);
 	else {
 		if (has_proto(ist, other, OBJ(INT_PROTO)))
-			float_other = (double)other->data.i64;
+			float_other = (double)other->body->data.i64;
 		else {
 			raise_exception(ist, OBJ(TYPE_EXC), "this object cannot be subtracted from a float");
 			return NULL;
@@ -268,7 +268,7 @@
 	if (is_Float(other)) float_other = Float_value(other);
 	else {
 		if (has_proto(ist, other, OBJ(INT_PROTO)))
-			float_other = (double)other->data.i64;
+			float_other = (double)other->body->data.i64;
 		else {
 			if (covers(other, self))
 				return call_func1(ist, other, SYM(RPOW_), self);
@@ -286,7 +286,7 @@
 	if (is_Float(other)) float_other = Float_value(other);
 	else {
 		if (has_proto(ist, other, OBJ(INT_PROTO)))
-			float_other = (double)other->data.i64;
+			float_other = (double)other->body->data.i64;
 		else {
 			raise_exception(ist, OBJ(TYPE_EXC), "this object cannot be in a pow function with a float");
 			return NULL;
@@ -303,7 +303,7 @@
 	if (is_Float(other)) float_other = Float_value(other);
 	else {
 		if (has_proto(ist, other, OBJ(INT_PROTO)))
-			float_other = (double)other->data.i64;
+			float_other = (double)other->body->data.i64;
 		else {
 			if (covers(other, self))
 				return call_func1(ist, other, SYM(RCMP_), self);
@@ -326,7 +326,7 @@
 	if (is_Float(other)) float_other = Float_value(other);
 	else {
 		if (has_proto(ist, other, OBJ(INT_PROTO)))
-			float_other = (double)other->data.i64;
+			float_other = (double)other->body->data.i64;
 		else {
 			raise_exception(ist, OBJ(TYPE_EXC), "this object cannot compared to a float");
 			return NULL;
@@ -347,7 +347,7 @@
 	if (is_Float(other)) float_other = Float_value(other);
 	else {
 		if (has_proto(ist, other, OBJ(INT_PROTO)))
-			float_other = (double)other->data.i64;
+			float_other = (double)other->body->data.i64;
 		else {
 			if (covers(other, self))
 				return call_func1(ist, other, SYM(EQ__QUES), self);
@@ -397,9 +397,9 @@
 DEF(Float, coerce_, FORM_RPARAM) {
 	BIN_CONTENT_CHK(Float);
 	if (has_proto(ist, parms[1], OBJ(INT_PROTO)))
-		return NEW_FLOAT((double)(parms[1]->data.i64));
+		return NEW_FLOAT((double)(parms[1]->body->data.i64));
 	else if (has_proto(ist, parms[1], Float_OBJ))
-		return NEW_FLOAT(parms[1]->data.f64);
+		return NEW_FLOAT(parms[1]->body->data.f64);
 	else
 		raise_exception(ist, OBJ(TYPE_EXC), "This object cannot be coerced to a Float");
 	return NULL;

Modified: trunk/src/builtins-int.c
===================================================================
--- trunk/src/builtins-int.c	2004-07-17 08:33:55 UTC (rev 748)
+++ trunk/src/builtins-int.c	2004-07-18 04:26:50 UTC (rev 749)
@@ -102,13 +102,13 @@
 
 typedef digit*  digit_p;
 
-#define long_size(obj)		(((long_p)((obj)->data.ptr))->size)
-#define long_dsize(obj)		(((long_p)((obj)->data.ptr))->dsize)
-#define long_digitp(obj)	(((long_p)((obj)->data.ptr))->digit)
+#define long_size(obj)		(((long_p)((obj)->body->data.ptr))->size)
+#define long_dsize(obj)		(((long_p)((obj)->body->data.ptr))->dsize)
+#define long_digitp(obj)	(((long_p)((obj)->body->data.ptr))->digit)
 
 #define int_sign(obj)													\
-	( obj->data_type == DATA_TYPE_IMMDATA ?								\
-		(obj->data.i64   == 0 ? 0 : (obj->data.i64   < 0 ? -1 : 1)) :	\
+	( obj->body->data_type == DATA_TYPE_IMMDATA ?								\
+		(obj->body->data.i64   == 0 ? 0 : (obj->body->data.i64   < 0 ? -1 : 1)) :	\
 		(long_dsize(obj) == 0 ? 0 : (long_dsize(obj) < 0 ? -1 : 1)) )	\
 
 #define SIGCHECK(x)			if (0) x
@@ -142,9 +142,9 @@
 obj_p new_int_obj(isp ist, i64_t num){
 	obj_p obj = NEW_OBJ(OBJ(INT_PROTO));
 	SET_TYPE_IF_EXC(OBJ(INT_PROTO), obj, DATA_TYPE_IMMDATA) return NULL;
-	obj->imm_data_len = 8;
-	obj->data.i64 = num;
-	obj->immutable = TRUE;
+	obj->body->imm_data_len = 8;
+	obj->body->data.i64 = num;
+	obj->body->immutable = TRUE;
 	return obj;
 }
 
@@ -157,16 +157,16 @@
 	obj            = NEW_OBJ(Int_OBJ);
 
 	SET_TYPE_IF_EXC(Int_OBJ, obj, DATA_TYPE_DATAPTR) return NULL;
-	obj->data.ptr  = pr_malloc(len);
-	memcpy(obj->data.ptr, longp, len);
+	obj->body->data.ptr  = pr_malloc(len);
+	memcpy(obj->body->data.ptr, longp, len);
 	long_size(obj) = len;
-	obj->immutable = TRUE;
+	obj->body->immutable = TRUE;
 	return obj;
 }
 
 int int_is_zero(obj_p obj) {
-	if (obj->data_type  == DATA_TYPE_IMMDATA)
-		return (obj->data.i64 == 0);
+	if (obj->body->data_type  == DATA_TYPE_IMMDATA)
+		return (obj->body->data.i64 == 0);
 	else
 		return (long_dsize(obj) == 0);
 }
@@ -2015,7 +2015,7 @@
 }
 
 i32_t int2i32t(isp ist, obj_p self) {
-	if (self->data_type == DATA_TYPE_NONE) {					
+	if (self->body->data_type == DATA_TYPE_NONE) {					
 		raise_exception(ist, OBJ(INTERNAL_EXC),					
 			"object has no binary data, expected Integer");	
 		return 0; }											
@@ -2023,20 +2023,20 @@
 		raise_exception(ist, OBJ(INTERNAL_EXC),					
 			"object has wrong binary data, expected Integer");	
 		return 0; }											
-	if (self->data_type == DATA_TYPE_IMMDATA) {
-		if ( self->data.i64 >  ((i64_t) 0x7fffffff) || 
-			 self->data.i64 < -((i64_t) 0x80000000) ) {
+	if (self->body->data_type == DATA_TYPE_IMMDATA) {
+		if ( self->body->data.i64 >  ((i64_t) 0x7fffffff) || 
+			 self->body->data.i64 < -((i64_t) 0x80000000) ) {
 			raise_exception(ist, OBJ(OVERFLOW_EXC),					
 						         "integer too large to convert");	
 			return 0;											
 		}
-		return (i32_t) self->data.i64;
+		return (i32_t) self->body->data.i64;
 	} else
-		return longp2int32(ist, self->data.ptr);
+		return longp2int32(ist, self->body->data.ptr);
 }
 
 i64_t int2i64t(isp ist, obj_p self) {
-	if (self->data_type == DATA_TYPE_NONE) {					
+	if (self->body->data_type == DATA_TYPE_NONE) {					
 		raise_exception(ist, OBJ(INTERNAL_EXC),					
 			"object has no binary data, expected Integer");	
 		return 0; }											
@@ -2044,10 +2044,10 @@
 		raise_exception(ist, OBJ(INTERNAL_EXC),					
 			"object has wrong binary data, expected Integer");	
 		return 0; }											
-	if (self->data_type == DATA_TYPE_IMMDATA)
-		return self->data.i64;
+	if (self->body->data_type == DATA_TYPE_IMMDATA)
+		return self->body->data.i64;
 	else
-		return longp2int64(ist, self->data.ptr);
+		return longp2int64(ist, self->body->data.ptr);
 }
 
 obj_p chr_ch3(isp ist, obj_p self) {
@@ -2069,7 +2069,7 @@
 
 #define	INT_DATA_SIZE		8
 #define is_Int(objid)		(has_proto(ist, objid, Int_OBJ))
-#define int_imm_value(objid)	(objid->data.i64)
+#define int_imm_value(objid)	(objid->body->data.i64)
 
 static obj_p SYM_LIMIT;	
 
@@ -2081,8 +2081,8 @@
 	MODULE_SET_DOC(Int, "integer object prototype");
 	set_obj_id(Int_OBJ, *, Int);
 	SET_TYPE_IF_EXC(Int_OBJ, Int_OBJ, DATA_TYPE_IMMDATA) return;
-	Int_OBJ->imm_data_len = IMM_DATA_LEN;
-	Int_OBJ->data.i64   = 0;
+	Int_OBJ->body->imm_data_len = IMM_DATA_LEN;
+	Int_OBJ->body->data.i64   = 0;
 
 	/* Dependent objects */
 	OBJ(ZERO_INT)		= NEW_INT(0);
@@ -2099,17 +2099,17 @@
 		return NULL;
 	} else {
 		SET_TYPE_IF_EXC(Int_OBJ, self, DATA_TYPE_IMMDATA) return NULL;
-		self->imm_data_len = 8;
-		self->data.i64 = 0;
+		self->body->imm_data_len = 8;
+		self->body->data.i64 = 0;
 		return OBJ(NONE);
 	}
-	if (i->data_type == DATA_TYPE_IMMDATA) {
+	if (i->body->data_type == DATA_TYPE_IMMDATA) {
 		SET_TYPE_IF_EXC(Int_OBJ, self, DATA_TYPE_IMMDATA) return NULL;
-		self->imm_data_len = 8;
-		self->data.i64 = i->data.i64;
+		self->body->imm_data_len = 8;
+		self->body->data.i64 = i->body->data.i64;
 	} else {
 		SET_TYPE_IF_EXC(Int_OBJ, self, DATA_TYPE_DATAPTR) return NULL;
-		self->data.ptr  = copy_longp(i->data.ptr, 0);
+		self->body->data.ptr  = copy_longp(i->body->data.ptr, 0);
 	}
 	return OBJ(NONE);
 }
@@ -2163,7 +2163,7 @@
 	hd1_flag = (base != 10 && hdr_flag);
 	if (chr_flag) {
 		self_str = chr_ch3(ist, self);
-	} else if (self->data_type == DATA_TYPE_IMMDATA) {
+	} else if (self->body->data_type == DATA_TYPE_IMMDATA) {
 		char str[32], *p, *s=str+1;
 		i64_t val = int2i64t(ist, self);
 		neg_flag = (val < 0);
@@ -2189,7 +2189,7 @@
 	} else {	
 		if (hdr_flag && base != 10 && long_dsize(self) < 0) {
 			long_p one;
-			num = copy_longp(self->data.ptr, 0);
+			num = copy_longp(self->body->data.ptr, 0);
 got_num:
 			one = (long_p)new_longp(1);
 			num = (long_p)long_add(num, one);
@@ -2201,7 +2201,7 @@
 			for (i = 0; i < -num->dsize; i++)
 				num->digit[i] ^= 0xffff;
 		} else 
-			num = self->data.ptr;
+			num = self->body->data.ptr;
 		self_str = long_format(num, base, heX_flag);
 		pr_free(num);
 	}
@@ -2299,7 +2299,7 @@
 
 DEF(Int, bool__QUES, NULL) {
 	BIN_CONTENT_CHK(Int);
-	if (self->data_type == DATA_TYPE_IMMDATA) {
+	if (self->body->data_type == DATA_TYPE_IMMDATA) {
 		if (int_imm_value(self)) return OBJ(PR_TRUE);
 		else				 return OBJ(PR_FALSE);
 	} else {
@@ -2312,18 +2312,18 @@
 	long_p v;
 	obj_p res;
 	BIN_CONTENT_CHK(Int);
-	if (self->data_type == DATA_TYPE_IMMDATA) {
+	if (self->body->data_type == DATA_TYPE_IMMDATA) {
 		res = new_hash_obj(ist, long_hash(v = new_longp(int_imm_value(self))));
 		pr_free(v);
 		return res;
 	}
 	else
-		return new_hash_obj(ist, long_hash(self->data.ptr));
+		return new_hash_obj(ist, long_hash(self->body->data.ptr));
 }
 
 DEF(Int, abs_, NULL){
 	BIN_CONTENT_CHK(Int);
-	if (self->data_type == DATA_TYPE_IMMDATA)
+	if (self->body->data_type == DATA_TYPE_IMMDATA)
 		return NEW_INT(abs(int_imm_value(self)));
 	else {
 		obj_p res = copy_object(ist, self);
@@ -2334,7 +2334,7 @@
 
 DEF(Int, neg_, NULL){
 	BIN_CONTENT_CHK(Int);
-	if (self->data_type == DATA_TYPE_IMMDATA)
+	if (self->body->data_type == DATA_TYPE_IMMDATA)
 		return NEW_INT( - int_imm_value(self) );
 	else {
 		obj_p res = copy_object(ist, self);
@@ -2362,21 +2362,21 @@
 	}
 	siv = int_imm_value(self);
 	oiv = int_imm_value(other);
-	if ( self->data_type  == DATA_TYPE_IMMDATA &&  
-		 other->data_type == DATA_TYPE_IMMDATA &&
+	if ( self->body->data_type  == DATA_TYPE_IMMDATA &&  
+		 other->body->data_type == DATA_TYPE_IMMDATA &&
 		 (siv < MAX64 || oiv < MAX64)          &&
 		 (siv > MIN64 || oiv > MIN64)          )
 		return NEW_INT(siv+oiv);
 	else {
 		long_p a, b;
-		if (self->data_type  == DATA_TYPE_IMMDATA)
+		if (self->body->data_type  == DATA_TYPE_IMMDATA)
 			a = new_longp(siv);
 		else
-			a = self->data.ptr;
-		if (other->data_type  == DATA_TYPE_IMMDATA)
+			a = self->body->data.ptr;
+		if (other->body->data_type  == DATA_TYPE_IMMDATA)
 			b = new_longp(oiv);
 		else
-			b = other->data.ptr;
+			b = other->body->data.ptr;
 		return new_int_long_obj(ist, long_add(a,b));
 	}
 }
@@ -2407,8 +2407,8 @@
 		raise_exception(ist, OBJ(TYPE_EXC), "Integer cannot be floor divided by this object");
 		return OBJ(NONE);
 	}
-	if ( self->data_type  == DATA_TYPE_IMMDATA &&  
-		 other->data_type == DATA_TYPE_IMMDATA ) {
+	if ( self->body->data_type  == DATA_TYPE_IMMDATA &&  
+		 other->body->data_type == DATA_TYPE_IMMDATA ) {
 		if (int_imm_value(other) == 0) {
 			raise_exception(ist, OBJ(DIVIDEZERO_EXC), NULL);
 			return NULL;
@@ -2416,14 +2416,14 @@
 		return NEW_INT(int_imm_value(self) / int_imm_value(other));
 	} else {
 		long_p a, b;
-		if (self->data_type  == DATA_TYPE_IMMDATA)
-			a = new_longp(self->data.i64);
+		if (self->body->data_type  == DATA_TYPE_IMMDATA)
+			a = new_longp(self->body->data.i64);
 		else
-			a = self->data.ptr;
-		if (other->data_type  == DATA_TYPE_IMMDATA)
-			b = new_longp(other->data.i64);
+			a = self->body->data.ptr;
+		if (other->body->data_type  == DATA_TYPE_IMMDATA)
+			b = new_longp(other->body->data.i64);
 		else
-			b = other->data.ptr;
+			b = other->body->data.ptr;
 		return new_int_long_obj(ist, long_div(a,b));
 	}
 }
@@ -2437,8 +2437,8 @@
 		raise_exception(ist, OBJ(TYPE_EXC), "Integer cannot be modded by this object");
 		return OBJ(NONE);
 	}
-	if ( self->data_type  == DATA_TYPE_IMMDATA &&  
-		 other->data_type == DATA_TYPE_IMMDATA ) {
+	if ( self->body->data_type  == DATA_TYPE_IMMDATA &&  
+		 other->body->data_type == DATA_TYPE_IMMDATA ) {
 		if (int_imm_value(other) == 0) {
 			raise_exception(ist, OBJ(DIVIDEZERO_EXC), "modulo by zero");
 			return NULL;
@@ -2446,14 +2446,14 @@
 		return NEW_INT(int_imm_value(self) % int_imm_value(other));
 	} else {
 		long_p a, b;
-		if (self->data_type  == DATA_TYPE_IMMDATA)
-			a = new_longp(self->data.i64);
+		if (self->body->data_type  == DATA_TYPE_IMMDATA)
+			a = new_longp(self->body->data.i64);
 		else
-			a = self->data.ptr;
-		if (other->data_type  == DATA_TYPE_IMMDATA)
-			b = new_longp(other->data.i64);
+			a = self->body->data.ptr;
+		if (other->body->data_type  == DATA_TYPE_IMMDATA)
+			b = new_longp(other->body->data.i64);
 		else
-			b = other->data.ptr;
+			b = other->body->data.ptr;
 		return new_int_long_obj(ist, long_mod(ist, a,b));
 	}
 }
@@ -2472,20 +2472,20 @@
 	}
 	siv = int_imm_value(self);
 	oiv = int_imm_value(other);
-	if ( self->data_type  == DATA_TYPE_IMMDATA &&  
-		 other->data_type == DATA_TYPE_IMMDATA &&
+	if ( self->body->data_type  == DATA_TYPE_IMMDATA &&  
+		 other->body->data_type == DATA_TYPE_IMMDATA &&
 		 siv < MAX32 && oiv < MAX32 && siv > MIN32 && oiv > MIN32 )
 		return NEW_INT(siv*oiv);
 	else {
 		long_p a, b;
-		if (self->data_type  == DATA_TYPE_IMMDATA)
+		if (self->body->data_type  == DATA_TYPE_IMMDATA)
 			a = new_longp(siv);
 		else
-			a = self->data.ptr;
-		if (other->data_type  == DATA_TYPE_IMMDATA)
+			a = self->body->data.ptr;
+		if (other->body->data_type  == DATA_TYPE_IMMDATA)
 			b = new_longp(oiv);
 		else
-			b = other->data.ptr;
+			b = other->body->data.ptr;
 		return new_int_long_obj(ist, long_mul(a,b));
 	}
 }
@@ -2504,20 +2504,20 @@
 	}
 	siv = int_imm_value(self);
 	oiv = int_imm_value(other);
-	if ( self->data_type  == DATA_TYPE_IMMDATA &&  
-		 other->data_type == DATA_TYPE_IMMDATA &&
+	if ( self->body->data_type  == DATA_TYPE_IMMDATA &&  
+		 other->body->data_type == DATA_TYPE_IMMDATA &&
 		 siv < MAX64 && oiv < MAX64 && siv > MIN64 && oiv > MIN64 )
 		return NEW_INT(siv-oiv);
 	else {
 		long_p a, b;
-		if (self->data_type  == DATA_TYPE_IMMDATA)
+		if (self->body->data_type  == DATA_TYPE_IMMDATA)
 			a = new_longp(siv);
 		else
-			a = self->data.ptr;
-		if (other->data_type  == DATA_TYPE_IMMDATA)
+			a = self->body->data.ptr;
+		if (other->body->data_type  == DATA_TYPE_IMMDATA)
 			b = new_longp(oiv);
 		else
-			b = other->data.ptr;
+			b = other->body->data.ptr;
 		return new_int_long_obj(ist, long_sub(a,b));
 	}
 }
@@ -2537,14 +2537,14 @@
 	}
 	if (!iso) return NEW_INT(1);
 
-	if (self->data_type  == DATA_TYPE_IMMDATA)
-		a = new_longp(self->data.i64);
+	if (self->body->data_type  == DATA_TYPE_IMMDATA)
+		a = new_longp(self->body->data.i64);
 	else
-		a = self->data.ptr;
-	if (other->data_type  == DATA_TYPE_IMMDATA)
-		b = new_longp(other->data.i64);
+		a = self->body->data.ptr;
+	if (other->body->data_type  == DATA_TYPE_IMMDATA)
+		b = new_longp(other->body->data.i64);
 	else
-		b = other->data.ptr;
+		b = other->body->data.ptr;
 	return new_int_long_obj(ist, long_pow(ist, a, b, NULL));
 }
 
@@ -2561,8 +2561,8 @@
 		raise_exception(ist, OBJ(TYPE_EXC), "This object cannot be compared to an Integer");
 		return OBJ(NONE);
 	}
-	if ( self->data_type  == DATA_TYPE_IMMDATA &&  
-		 other->data_type == DATA_TYPE_IMMDATA ) {
+	if ( self->body->data_type  == DATA_TYPE_IMMDATA &&  
+		 other->body->data_type == DATA_TYPE_IMMDATA ) {
 		if (int_imm_value(self) == int_imm_value(other))
 			return NEW_INT(0);
 		else if (int_imm_value(self) > int_imm_value(other))
@@ -2571,14 +2571,14 @@
 			return NEW_INT(-1);
 	} else {
 		long_p a, b;
-		if (self->data_type  == DATA_TYPE_IMMDATA)
-			a = new_longp(self->data.i64);
+		if (self->body->data_type  == DATA_TYPE_IMMDATA)
+			a = new_longp(self->body->data.i64);
 		else
-			a = self->data.ptr;
-		if (other->data_type  == DATA_TYPE_IMMDATA)
-			b = new_longp(other->data.i64);
+			a = self->body->data.ptr;
+		if (other->body->data_type  == DATA_TYPE_IMMDATA)
+			b = new_longp(other->body->data.i64);
 		else
-			b = other->data.ptr;
+			b = other->body->data.ptr;
 		return NEW_INT(long_compare(a,b));
 	}
 }
@@ -2598,30 +2598,30 @@
 		if (c) return call_func1(ist, other, SYM(EQ__QUES), self);
 		return OBJ(PR_FALSE);
 	}
-	if ( self->data_type  == DATA_TYPE_IMMDATA &&  
-		 other->data_type == DATA_TYPE_IMMDATA ) {
+	if ( self->body->data_type  == DATA_TYPE_IMMDATA &&  
+		 other->body->data_type == DATA_TYPE_IMMDATA ) {
 		if (int_imm_value(self) == int_imm_value(other)) return OBJ(PR_TRUE);
 		else                                             return OBJ(PR_FALSE);
 	} else {
 		long_p a, b;
-		if (self->data_type  == DATA_TYPE_IMMDATA)
-			a = new_longp(self->data.i64);
+		if (self->body->data_type  == DATA_TYPE_IMMDATA)
+			a = new_longp(self->body->data.i64);
 		else
-			a = self->data.ptr;
-		if (other->data_type  == DATA_TYPE_IMMDATA)
-			b = new_longp(other->data.i64);
+			a = self->body->data.ptr;
+		if (other->body->data_type  == DATA_TYPE_IMMDATA)
+			b = new_longp(other->body->data.i64);
 		else
-			b = other->data.ptr;
+			b = other->body->data.ptr;
 		if (long_compare(a,b)) return OBJ(PR_FALSE);
 		else                   return OBJ(PR_TRUE);
 	}
 }
 DEF(Int, invert_, NULL){
 	BIN_CONTENT_CHK(Int);
-	if ( self->data_type  == DATA_TYPE_IMMDATA)
+	if ( self->body->data_type  == DATA_TYPE_IMMDATA)
 		return NEW_INT( ~ int_imm_value(self) );
 	else
-		return new_int_long_obj(ist, long_invert(ist, self->data.ptr));
+		return new_int_long_obj(ist, long_invert(ist, self->body->data.ptr));
 }
 
 DEF(Int, xor_, FORM_RPARAM) {
@@ -2631,19 +2631,19 @@
 		raise_exception(ist, OBJ(TYPE_EXC), "object cannot be xor'd with an Integer");
 		return OBJ(NONE);
 	}
-	if ( self->data_type  == DATA_TYPE_IMMDATA &&  
-		 other->data_type == DATA_TYPE_IMMDATA ) {
+	if ( self->body->data_type  == DATA_TYPE_IMMDATA &&  
+		 other->body->data_type == DATA_TYPE_IMMDATA ) {
 		return NEW_INT(int_imm_value(self) ^ int_imm_value(other));
 	} else {
 		long_p a, b;
-		if (self->data_type  == DATA_TYPE_IMMDATA)
-			a = new_longp(self->data.i64);
+		if (self->body->data_type  == DATA_TYPE_IMMDATA)
+			a = new_longp(self->body->data.i64);
 		else
-			a = self->data.ptr;
-		if (other->data_type  == DATA_TYPE_IMMDATA)
-			b = new_longp(other->data.i64);
+			a = self->body->data.ptr;
+		if (other->body->data_type  == DATA_TYPE_IMMDATA)
+			b = new_longp(other->body->data.i64);
 		else
-			b = other->data.ptr;
+			b = other->body->data.ptr;
 		return new_int_long_obj(ist, long_xor(ist, a, b));
 	}
 }
@@ -2655,19 +2655,19 @@
 		raise_exception(ist, OBJ(TYPE_EXC), "object cannot be and'd with an Integer");
 		return OBJ(NONE);
 	}
-	if ( self->data_type  == DATA_TYPE_IMMDATA &&  
-		 other->data_type == DATA_TYPE_IMMDATA ) {
+	if ( self->body->data_type  == DATA_TYPE_IMMDATA &&  
+		 other->body->data_type == DATA_TYPE_IMMDATA ) {
 		return NEW_INT(int_imm_value(self) & int_imm_value(other));
 	} else {
 		long_p a, b;
-		if (self->data_type  == DATA_TYPE_IMMDATA)
-			a = new_longp(self->data.i64);
+		if (self->body->data_type  == DATA_TYPE_IMMDATA)
+			a = new_longp(self->body->data.i64);
 		else
-			a = self->data.ptr;
-		if (other->data_type  == DATA_TYPE_IMMDATA)
-			b = new_longp(other->data.i64);
+			a = self->body->data.ptr;
+		if (other->body->data_type  == DATA_TYPE_IMMDATA)
+			b = new_longp(other->body->data.i64);
 		else
-			b = other->data.ptr;
+			b = other->body->data.ptr;
 		return new_int_long_obj(ist, long_and(ist, a, b));
 	}
 }
@@ -2679,19 +2679,19 @@
 		raise_exception(ist, OBJ(TYPE_EXC), "object cannot be or'd with an Integer");
 		return OBJ(NONE);
 	}
-	if ( self->data_type  == DATA_TYPE_IMMDATA &&  
-		 other->data_type == DATA_TYPE_IMMDATA ) {
+	if ( self->body->data_type  == DATA_TYPE_IMMDATA &&  
+		 other->body->data_type == DATA_TYPE_IMMDATA ) {
 		return NEW_INT(int_imm_value(self) | int_imm_value(other));
 	} else {
 		long_p a, b;
-		if (self->data_type  == DATA_TYPE_IMMDATA)
-			a = new_longp(self->data.i64);
+		if (self->body->data_type  == DATA_TYPE_IMMDATA)
+			a = new_longp(self->body->data.i64);
 		else
-			a = self->data.ptr;
-		if (other->data_type  == DATA_TYPE_IMMDATA)
-			b = new_longp(other->data.i64);
+			a = self->body->data.ptr;
+		if (other->body->data_type  == DATA_TYPE_IMMDATA)
+			b = new_longp(other->body->data.i64);
 		else
-			b = other->data.ptr;
+			b = other->body->data.ptr;
 		return new_int_long_obj(ist, long_or(ist, a, b));
 	}
 }
@@ -2706,20 +2706,20 @@
 	}
 	siv = int_imm_value(self);
 	oiv = int_imm_value(other);
-	if ( self->data_type  == DATA_TYPE_IMMDATA &&  
-		 other->data_type == DATA_TYPE_IMMDATA &&
+	if ( self->body->data_type  == DATA_TYPE_IMMDATA &&  
+		 other->body->data_type == DATA_TYPE_IMMDATA &&
 		 siv < MAX32 &&  siv > MIN32 && oiv > -32 )
 		return NEW_INT(int_imm_value(self) >> int_imm_value(other));
 	else {
 		long_p a, b;
-		if (self->data_type  == DATA_TYPE_IMMDATA)
-			a = new_longp(self->data.i64);
+		if (self->body->data_type  == DATA_TYPE_IMMDATA)
+			a = new_longp(self->body->data.i64);
 		else
-			a = self->data.ptr;
-		if (other->data_type  == DATA_TYPE_IMMDATA)
-			b = new_longp(other->data.i64);
+			a = self->body->data.ptr;
+		if (other->body->data_type  == DATA_TYPE_IMMDATA)
+			b = new_longp(other->body->data.i64);
 		else
-			b = other->data.ptr;
+			b = other->body->data.ptr;
 		return new_int_long_obj(ist, long_rshift(ist, a, b));
 	}
 }
@@ -2734,20 +2734,20 @@
 	}
 	siv = int_imm_value(self);
 	oiv = int_imm_value(other);
-	if ( self->data_type  == DATA_TYPE_IMMDATA &&  
-		 other->data_type == DATA_TYPE_IMMDATA &&
+	if ( self->body->data_type  == DATA_TYPE_IMMDATA &&  
+		 other->body->data_type == DATA_TYPE_IMMDATA &&
 		 siv < MAX32 &&  siv > MIN32 && oiv < 32 )
 		return NEW_INT(int_imm_value(self) << int_imm_value(other));
 	else {
 		long_p a, b;
-		if (self->data_type  == DATA_TYPE_IMMDATA)
-			a = new_longp(self->data.i64);
+		if (self->body->data_type  == DATA_TYPE_IMMDATA)
+			a = new_longp(self->body->data.i64);
 		else
-			a = self->data.ptr;
-		if (other->data_type  == DATA_TYPE_IMMDATA)
-			b = new_longp(other->data.i64);
+			a = self->body->data.ptr;
+		if (other->body->data_type  == DATA_TYPE_IMMDATA)
+			b = new_longp(other->body->data.i64);
 		else
-			b = other->data.ptr;
+			b = other->body->data.ptr;
 		return new_int_long_obj(ist, long_lshift(ist, a, b));
 	}
 }
@@ -2755,8 +2755,8 @@
 DEF(Int, iter_, NULL) {
 	obj_p gen_obj = NEW_INT(0);
 	BIN_CONTENT_CHK(Int);
-	gen_obj->immutable = FALSE;
-	gen_obj->attr_proto.proto = IntGen_OBJ;
+	gen_obj->body->immutable = FALSE;
+	gen_obj->body->attr_proto.proto = IntGen_OBJ;
 	set_attr(ist, gen_obj, SYM_LIMIT, self);
 	return gen_obj;
 }
@@ -2777,10 +2777,10 @@
 	obj_p limit, tmp, res;
 	BIN_CONTENT_CHK(IntGen);
 	if ( !(limit=get_attr(ist, self, SYM_LIMIT)) ||
-		 (  self->data_type == DATA_TYPE_IMMDATA && 
-		   limit->data_type == DATA_TYPE_IMMDATA ?
-			 (self->data.i64 == limit->data.i64) :
-			 !(call_func1(ist, self, SYM(CMP_), limit)->data.i64) ) ) {
+		 (  self->body->data_type == DATA_TYPE_IMMDATA && 
+		   limit->body->data_type == DATA_TYPE_IMMDATA ?
+			 (self->body->data.i64 == limit->body->data.i64) :
+			 !(call_func1(ist, self, SYM(CMP_), limit)->body->data.i64) ) ) {
 		if (limit) {
 			read_unlock(ist, self);
 			del_attr(ist, self, SYM_LIMIT);
@@ -2789,11 +2789,11 @@
 		raise_exception(ist, OBJ(STOP_ITERATION_EXC), NULL);
 		return NULL;
 	}
-	if (self->data_type == DATA_TYPE_IMMDATA)
-		res = NEW_INT(self->data.i64);
+	if (self->body->data_type == DATA_TYPE_IMMDATA)
+		res = NEW_INT(self->body->data.i64);
 	else
-		res = new_int_long_obj(ist, self->data.ptr);
-	if (self->data_type == DATA_TYPE_IMMDATA) {
+		res = new_int_long_obj(ist, self->body->data.ptr);
+	if (self->body->data_type == DATA_TYPE_IMMDATA) {
 		def_write_lock(self);
 		int_imm_value(self)++;
 		def_write_unlock(self);

Modified: trunk/src/builtins-list.c
===================================================================
--- trunk/src/builtins-list.c	2004-07-17 08:33:55 UTC (rev 748)
+++ trunk/src/builtins-list.c	2004-07-18 04:26:50 UTC (rev 749)
@@ -85,7 +85,7 @@
 //********************************* new_list_obj ******************************
 obj_p new_list_obj(isp ist, size_t initial_size){
 	obj_p list_obj = NEW_OBJ(OBJ(LIST_PROTO));
-	list_p lstp = list_obj->data.ptr = 
+	list_p lstp = list_obj->body->data.ptr = 
 		      pr_malloc(list_sizeof(max(initial_size,2)));
 	SET_TYPE_IF_EXC(OBJ(TUPLE_PROTO), list_obj, DATA_TYPE_DATAPTR) return NULL;
 	lstpsetsize(lstp, max(initial_size,2));
@@ -96,7 +96,7 @@
 //********************************* init_list_data ****************************
 void init_list_data(isp ist, obj_p obj, int initial_size) {
 	list_p lstp;
-	lstp = obj->data.ptr = 
+	lstp = obj->body->data.ptr = 
 			pr_malloc(list_sizeof(max(initial_size, 2)));
 	SET_TYPE_IF_EXC(OBJ(LIST_PROTO), obj, DATA_TYPE_DATAPTR) return;
 	lstpsetsize(lstp, max(initial_size, 2));
@@ -112,10 +112,10 @@
 	llen = listlen(list_obj);
 	size = list_sizeof(llen);
 	res = copy_object(ist, list_obj);
-	res->data.ptr = list_ptr = pr_malloc(size);
+	res->body->data.ptr = list_ptr = pr_malloc(size);
 	lstpsetsize(list_ptr, llen);
 	lstplen(list_ptr)  = llen;
-	memcpy( list_ptr->item, ((list_p)(list_obj->data.ptr))->item, 
+	memcpy( list_ptr->item, ((list_p)(list_obj->body->data.ptr))->item, 
 		                                  size-sizeof(list_hdr_t) );
 	read_unlock(ist, list_obj);
 	return res;
@@ -125,7 +125,7 @@
 size_t list_len(isp ist, obj_p list_obj){
 	size_t len;
 	rdlock_rtrn(list_obj) 0;
-	if (list_obj->data.ptr)
+	if (list_obj->body->data.ptr)
 		len = listlen(list_obj);
 	else
 		len = 0;
@@ -160,12 +160,12 @@
 obj_p list_append(isp ist, obj_p list_obj, obj_p item){
 	list_p lstp;
 	wrlock_rtrn(list_obj) NULL;
-	lstp = list_obj->data.ptr;
+	lstp = list_obj->body->data.ptr;
 	if(lstplen(lstp) == lstpsize(lstp)) {
 		int size = max(lstpsize(lstp), 1) * LIST_GROWTH_FACTOR;
 		lstpsetsize(lstp, size);
 		lstp = pr_realloc(lstp, list_sizeof(lstpsize(lstp)));
-		list_obj->data.ptr = lstp;
+		list_obj->body->data.ptr = lstp;
 	}
 	listitem(list_obj, listlen(list_obj)++) = item;
 	write_unlock(ist, list_obj);
@@ -175,11 +175,11 @@
 //********************************* list_append_no_lock ***********************
 obj_p list_append_no_lock(obj_p list_obj, obj_p item){
 	list_p lstp;
-	lstp = list_obj->data.ptr;
+	lstp = list_obj->body->data.ptr;
 	if(lstplen(lstp) == lstpsize(lstp)) {
 		lstpsetsize(lstp, lstpsize(lstp) * LIST_GROWTH_FACTOR);
 		lstp = pr_realloc(lstp, list_sizeof(lstpsize(lstp)));
-		list_obj->data.ptr = lstp;
+		list_obj->body->data.ptr = lstp;
 	}
 	listitem(list_obj, listlen(list_obj)++) = item;
 	return list_obj;
@@ -276,13 +276,13 @@
 		arr[3] = b;
 		res = call_func(ist, NULL, cmp_func, NULL, 4, arr, NULL);
 		if_exc_return 0;
-		return (res->data.i64 < 0);
+		return (res->body->data.i64 < 0);
 	}
 	arr[0] = OBJ(NOKEY);
 	arr[1] = b;
 	res = call_func(ist, a, SYM(CMP_), NULL, 2, arr, NULL);
 	if_exc_return 0;
-	return (res->data.i64 < 0);
+	return (res->body->data.i64 < 0);
 }
 
 int obj_eq(obj_p a, obj_p b, isp ist, obj_p cmp_func) {
@@ -294,7 +294,7 @@
 		arr[3] = b;
 		res = call_func(ist, NULL, cmp_func, NULL, 4, arr, NULL);
 		if_exc_return 0;
-		return (res->data.i64 == 0);
+		return (res->body->data.i64 == 0);
 	}
 	arr[0] = OBJ(NOKEY);
 	arr[1] = b;
@@ -338,7 +338,7 @@
 	set_attr(ist, OBJ(OBJECT), sym(ist, "List"), List_OBJ);
 
 	SET_TYPE_IF_EXC(List_OBJ, List_OBJ, DATA_TYPE_DATAPTR) return;
-	lstp = List_OBJ->data.ptr = pr_malloc(list_sizeof(2));
+	lstp = List_OBJ->body->data.ptr = pr_malloc(list_sizeof(2));
 	lstpsetsize(lstp, 2);
 	lstplen(lstp)  = 0;
 }
@@ -352,7 +352,7 @@
 			def_write_lock(self);
 			SET_TYPE_IF_EXC(List_OBJ, self, DATA_TYPE_DATAPTR) {
 				def_write_unlock(self); return NULL; }
-			lstp = self->data.ptr = pr_malloc(list_sizeof(2));
+			lstp = self->body->data.ptr = pr_malloc(list_sizeof(2));
 			lstpsetsize(lstp, 2);
 			lstplen(lstp)  = 0;
 			def_write_unlock(self);
@@ -414,7 +414,7 @@
 			def_write_unlock(self); 
 			return NULL;
 		}
-		index1 = (int)(slice_item1->data.i64);
+		index1 = (int)(slice_item1->body->data.i64);
 		if (index1 < 0) index1 += self_len;						
 		if (index1 < 0 || index1 >= self_len) {			
 			raise_exception(ist, OBJ(INDEX_EXC), "Index (%"APR_INT64_T_FMT") out of range",
@@ -444,7 +444,7 @@
 				def_write_unlock(self);
 				return NULL;
 			}
-			index3 = (int)(slice_item3->data.i64);
+			index3 = (int)(slice_item3->body->data.i64);
 			if (index3 == 0) {
 				raise_exception(ist, OBJ(INDEX_EXC), "slice step cannot be zero");
 				def_write_unlock(self);
@@ -461,7 +461,7 @@
 			def_write_unlock(self);
 			return NULL;
 		}
-		index2 = (int)(slice_item2->data.i64);
+		index2 = (int)(slice_item2->body->data.i64);
 		if (index2 < 0) index2 += self_len;						
 		if (index2 < 0 || index2 > self_len) {			
 			raise_exception(ist, OBJ(INDEX_EXC), "Second index (%"APR_INT64_T_FMT") out of range",
@@ -497,12 +497,12 @@
 		listlen(self) = (size_t) new_len;
 		if (new_len+1 > listsize(self)) {
 			listsetsize(self, new_len + 1);
-			self->data.ptr = 
-				pr_realloc(self->data.ptr, list_sizeof(listsize(self)));
+			self->body->data.ptr = 
+				pr_realloc(self->body->data.ptr, list_sizeof(listsize(self)));
 		}
 		if (exp_len != val_len && index2 != self_len)
-			memmove( &(((list_p)self->data.ptr)->item[index1+val_len]),
-					 &(((list_p)self->data.ptr)->item[index2]),
+			memmove( &(((list_p)self->body->data.ptr)->item[index1+val_len]),
+					 &(((list_p)self->body->data.ptr)->item[index2]),
 					 (self_len - (size_t) index2) * sizeof(obj_p) );
 		for(i = index1, j=0; j < (int) val_len; i++, j++)
 			listitem(self, i) = seq_item(ist, value, j);
@@ -539,7 +539,7 @@
 			def_write_unlock(self);
 			return NULL;
 		}
-		index1 = (int)(slice_item1->data.i64);
+		index1 = (int)(slice_item1->body->data.i64);
 		if (index1 < 0) index1 += self_len;						
 		if (index1 < 0 || index1 >= self_len) {			
 			raise_exception(ist, OBJ(INDEX_EXC), "Index (%"APR_INT64_T_FMT") out of range",
@@ -549,8 +549,8 @@
 		}
 		if (slice_len == 1) {
 			if (index1 != self_len-1)
-				memmove( &(((list_p)self->data.ptr)->item[index1]),
-					     &(((list_p)self->data.ptr)->item[index1+1]),
+				memmove( &(((list_p)self->body->data.ptr)->item[index1]),
+					     &(((list_p)self->body->data.ptr)->item[index1+1]),
 						 (self_len-1 - (size_t)index1) * sizeof(obj_p) );
 			listlen(self)--;
 			def_write_unlock(self);
@@ -566,7 +566,7 @@
 				def_write_unlock(self);
 				return NULL;
 			}
-			index3 = (int)(slice_item3->data.i64);
+			index3 = (int)(slice_item3->body->data.i64);
 			if (index3 == 0) {
 				raise_exception(ist, OBJ(INDEX_EXC), "slice step cannot be zero");
 				def_write_unlock(self);
@@ -583,7 +583,7 @@
 			def_write_unlock(self);
 			return NULL;
 		}
-		index2 = (int)(slice_item2->data.i64);
+		index2 = (int)(slice_item2->body->data.i64);
 		if (index2 < 0) index2 += self_len;						
 		if (index2 < 0 || index2 > self_len) {			
 			raise_exception(ist, OBJ(INDEX_EXC), "Second index (%"APR_INT64_T_FMT") out of range",
@@ -605,22 +605,22 @@
 		if (index3 > 0) {
 			for(i = index1, j=0; i < index2; i += index3, j++)
 				if (i != self_len-1)
-					memmove( &(((list_p)self->data.ptr)->item[i-j]),
-							 &(((list_p)self->data.ptr)->item[i-j+1]),
+					memmove( &(((list_p)self->body->data.ptr)->item[i-j]),
+							 &(((list_p)self->body->data.ptr)->item[i-j+1]),
 								(self_len - 1 - (size_t)i) * sizeof(obj_p) );
 		} else {
 			for(i = index1, j=0; i > index2; i += index3, j++)
 				if (i != self_len-1)
-					memmove( &(((list_p)self->data.ptr)->item[i]),
-							 &(((list_p)self->data.ptr)->item[i+1]),
+					memmove( &(((list_p)self->body->data.ptr)->item[i]),
+							 &(((list_p)self->body->data.ptr)->item[i+1]),
 								(self_len - 1 - (size_t)i) * sizeof(obj_p) );
 		}
 	} else {
 		new_len = index1 + ((i64_t)self_len - index2);
 		listlen(self) = (size_t) new_len;
 		if (exp_len != 0 && index2 != self_len)
-			memmove( &(((list_p)self->data.ptr)->item[index1]),
-					 &(((list_p)self->data.ptr)->item[index2]),
+			memmove( &(((list_p)self->body->data.ptr)->item[index1]),
+					 &(((list_p)self->body->data.ptr)->item[index2]),
 					 (self_len - (size_t)index2) * sizeof(obj_p) );
 		def_write_unlock(self);
 		return NULL;
@@ -657,19 +657,19 @@
 
 DEF(List, mul_, FORM_RPARAM){
 	obj_p res;
-	list_p lstp, selfp = (list_p)(self->data.ptr);
+	list_p lstp, selfp = (list_p)(self->body->data.ptr);
 	int i, size, times, len = (int) list_len(ist, self);
 	BIN_CONTENT_CHK(List);
 	if (!has_proto(ist, parms[1], OBJ(INT_PROTO))) {
 		raise_exception(ist, OBJ(TYPE_EXC), "multiply times parameter must be an integer");
 		return NULL;
 	}
-	times = (int)parms[1]->data.i64;
+	times = (int)parms[1]->body->data.i64;
 	size  = len*times;
 	if(times == 0) return NEW_LIST(0);
 	if(times == 1) return self;
 	res = NEW_OBJ(List_OBJ);
-	lstp = res->data.ptr = pr_malloc(list_sizeof(size));
+	lstp = res->body->data.ptr = pr_malloc(list_sizeof(size));
 	if(!lstp) {
 		raise_exception(ist, OBJ(OUTOFMEMORY_EXC), "memory allocation failed for list multiplication");
 		return NULL;
@@ -683,14 +683,14 @@
 }
 
 DEF(List, imul_, FORM_RPARAM){
-	list_p lstp, selfp = (list_p)(self->data.ptr);
+	list_p lstp, selfp = (list_p)(self->body->data.ptr);
 	int i, size, times, len = (int) list_len(ist, self);
 	BIN_CONTENT_CHK(List);
 	if (!has_proto(ist, parms[1], OBJ(INT_PROTO))) {
 		raise_exception(ist, OBJ(TYPE_EXC), "multiply times parameter must be an integer");
 		return NULL;
 	}
-	times = (int)parms[1]->data.i64;
+	times = (int)parms[1]->body->data.i64;
 	size  = len*times;
 	if(times == 0) { read_unlock(ist, self); list_clear(ist, self); read_lock(ist, self); return self; }
 	if(times == 1) return self;
@@ -704,8 +704,8 @@
 	for(i=0; i < times; i++)
 		memcpy(&(lstp->item[i*len]), selfp->item, len*sizeof(obj_p));
 	def_write_lock(self);
-	pr_free(self->data.ptr);
-	self->data.ptr = lstp;
+	pr_free(self->body->data.ptr);
+	self->body->data.ptr = lstp;
 	def_write_unlock(self);
 	return self;
 }
@@ -714,11 +714,11 @@
 	list_p lstp;
 	BIN_CONTENT_CHK(List);
 	def_write_lock(self);
-	lstp = self->data.ptr;
+	lstp = self->body->data.ptr;
 	if(lstplen(lstp) == lstpsize(lstp)) {
 		lstpsetsize(lstp, lstpsize(lstp) * LIST_GROWTH_FACTOR);
 		lstp = pr_realloc(lstp, list_sizeof(lstpsize(lstp)));
-		self->data.ptr = lstp;
+		self->body->data.ptr = lstp;
 	}
 	listitem(self, listlen(self)++) = parms[1];
 	def_write_unlock(self);
@@ -734,14 +734,14 @@
 		raise_exception(ist, OBJ(TYPE_EXC), "extend parameter must be a tuple or list");
 		return NULL;
 	}
-	selfp     = self->data.ptr;
+	selfp     = self->body->data.ptr;
 	self_len  = lstplen(selfp);
-	otherp    = parms[1]->data.ptr;
+	otherp    = parms[1]->body->data.ptr;
 	other_len = lstplen(otherp);
 	if(self_len+other_len > lstpsize(selfp)) {
 		lstpsetsize(selfp, (self_len+other_len) * LIST_GROWTH_FACTOR);
 		selfp = pr_realloc(selfp, list_sizeof(lstpsize(selfp)));
-		self->data.ptr = selfp;
+		self->body->data.ptr = selfp;
 	}
 	memcpy( selfp->item+self_len, otherp->item, other_len*sizeof(obj_p));
 	lstplen(selfp) = self_len+other_len;
@@ -759,8 +759,8 @@
 		return NULL;
 	}
 	def_write_lock(self);
-	index = (int)parms[1]->data.i64;
-	selfp    = self->data.ptr;
+	index = (int)parms[1]->body->data.i64;
+	selfp    = self->body->data.ptr;
 	self_len = lstplen(selfp);
 	if (index < 0 || index > self_len) {
 		raise_exception(ist, OBJ(INDEX_EXC), "index (i) parameter out of range");
@@ -770,7 +770,7 @@
 	if(lstplen(selfp) == lstpsize(selfp)) {
 		lstpsetsize(selfp, lstpsize(selfp) * LIST_GROWTH_FACTOR);
 		selfp = pr_realloc(selfp, list_sizeof(lstpsize(selfp)));
-		self->data.ptr = selfp;
+		self->body->data.ptr = selfp;
 	}
 	if (index < self_len)
 		memmove( selfp->item+index+1, selfp->item+index, 
@@ -787,7 +787,7 @@
 	list_p selfp;
 	BIN_CONTENT_CHK(List);
 	def_write_lock(self);
-	selfp    = self->data.ptr;
+	selfp    = self->body->data.ptr;
 	self_len = lstplen(selfp);
 	for (i=0; i < self_len; i++) {
 		if (call_func1(ist, listitem(self, i), SYM(EQ__QUES), parms[1]) == OBJ(PR_TRUE)) break;
@@ -817,12 +817,12 @@
 		return NULL;
 	}
 	def_write_lock(self);
-	selfp    = self->data.ptr;
+	selfp    = self->body->data.ptr;
 	self_len = lstplen(selfp);
 	if (parms[1] == OBJ(NONE))
 		index = self_len-1;
 	else
-		index = (int)(parms[1]->data.i64);
+		index = (int)(parms[1]->body->data.i64);
 	if (index < 0 || index > self_len-1) {
 		raise_exception(ist, OBJ(INDEX_EXC), "index (i) parameter out of range");
 		def_write_unlock(self);
@@ -843,7 +843,7 @@
 	obj_p *p1, *p2;
 	BIN_CONTENT_CHK(List);
 	def_write_lock(self);
-	selfp    = self->data.ptr;
+	selfp    = self->body->data.ptr;
 	self_len = lstplen(selfp);
 	p1 = selfp->item;
 	p2 = selfp->item+self_len-1;
@@ -865,7 +865,7 @@
 	BIN_CONTENT_CHK(List);
 	if (parms[1] != OBJ(NONE))
 		CHECK_TYPE_EXC(self, OBJ(FUNC_PROTO), "function");
-	selfp = self->data.ptr;
+	selfp = self->body->data.ptr;
 	self_len = (int) lstplen(selfp);
 	a = selfp->item;
 	quicksort(a, 0, self_len-1, ist, parms[1]);

Modified: trunk/src/builtins-protolist.c
===================================================================
--- trunk/src/builtins-protolist.c	2004-07-17 08:33:55 UTC (rev 748)
+++ trunk/src/builtins-protolist.c	2004-07-18 04:26:50 UTC (rev 749)
@@ -70,7 +70,7 @@
 obj_p new_protolist_obj(isp ist, obj_p obj) {
 	obj_p self = new_object(ist, ProtoList_OBJ);
 	SET_TYPE_IF_EXC(ProtoList_OBJ, self, DATA_TYPE_EXTPTR) return NULL;
-	self->data.ptr  = obj;
+	self->body->data.ptr  = obj;
 	set_unclonable(self);
 	return self;
 }
@@ -109,15 +109,15 @@
 	set_obj_id(ProtoList_OBJ, *, ProtoList);
 	set_attr(ist, OBJ(OBJECT), sym(ist, "ProtoList"), ProtoList_OBJ);
 
-	ProtoList_OBJ->data_type = DATA_TYPE_EXTPTR;
-	ProtoList_OBJ->data.ptr = OBJ(OBJECT);
+	ProtoList_OBJ->body->data_type = DATA_TYPE_EXTPTR;
+	ProtoList_OBJ->body->data.ptr = OBJ(OBJECT);
 	set_unclonable(ProtoList_OBJ);
 }
 
 DEF(ProtoList, init_, FORM_RPARAM) {
 	BIN_EMPTY_CHK();
 	SET_TYPE_IF_EXC(ProtoList_OBJ, self, DATA_TYPE_EXTPTR) return NULL;
-	self->data.ptr = parms[1];
+	self->body->data.ptr = parms[1];
 	set_unclonable(self);
 	return OBJ(NONE);
 }
@@ -125,14 +125,14 @@
 DEF(ProtoList, str_, NULL) {
 	obj_p res, list;
 	BIN_STR_CHK(ProtoList);
-	res = call_func0(ist, list = protos2list(ist, self->data.ptr), SYM(STR_));
+	res = call_func0(ist, list = protos2list(ist, self->body->data.ptr), SYM(STR_));
 	del_unlock(list);
 	return res;
 }
 DEF(ProtoList, eq__QUES, FORM_RPARAM) { 
 	obj_p res, list;
 	BIN_CONTENT_CHK(ProtoList);
-	res = call_func1(ist, list = protos2list(ist, self->data.ptr), 
+	res = call_func1(ist, list = protos2list(ist, self->body->data.ptr), 
 		                  sym(ist, "eq__QUES"), parms[1]);
 	del_unlock(list);
 	return res;
@@ -141,7 +141,7 @@
 DEF(ProtoList, getItem_, FORM_RPARAM) {
 	obj_p res, list;
 	BIN_CONTENT_CHK(ProtoList);
-	res = call_func1(ist, list = protos2list(ist, self->data.ptr), 
+	res = call_func1(ist, list = protos2list(ist, self->body->data.ptr), 
 		                  sym(ist, "getItem_"), parms[1]);
 	del_unlock(list);
 	return res;
@@ -150,9 +150,9 @@
 DEF(ProtoList, setItem_, FORM_PARAM2) {
 	obj_p list;
 	BIN_CONTENT_CHK(ProtoList);
-	call_func2(ist, list = protos2list(ist, self->data.ptr), 
+	call_func2(ist, list = protos2list(ist, self->body->data.ptr), 
 	                sym(ist, "setItem_"), parms[1], parms[3]);
-	list2protos(ist, list, self->data.ptr);
+	list2protos(ist, list, self->body->data.ptr);
 	del_unlock(list);
 	return NULL;
 }
@@ -160,9 +160,9 @@
 DEF(ProtoList, delItem_, FORM_RPARAM) {
 	obj_p list;
 	BIN_CONTENT_CHK(ProtoList);
-	call_func1(ist, list = protos2list(ist, self->data.ptr), 
+	call_func1(ist, list = protos2list(ist, self->body->data.ptr), 
 	                sym(ist, "delItem_"), parms[1]);
-	list2protos(ist, list, self->data.ptr);
+	list2protos(ist, list, self->body->data.ptr);
 	del_unlock(list);
 	return NULL;
 }
@@ -170,9 +170,9 @@
 DEF(ProtoList, append_BANG, FORM_RPARAM) {
 	obj_p list;
 	BIN_CONTENT_CHK(ProtoList);
-	call_func1(ist, list = protos2list(ist, self->data.ptr), 
+	call_func1(ist, list = protos2list(ist, self->body->data.ptr), 
 	                sym(ist, "append_BANG"), parms[1]);
-	list2protos(ist, list, self->data.ptr);
+	list2protos(ist, list, self->body->data.ptr);
 	del_unlock(list);
 	return NULL;
 }
@@ -180,9 +180,9 @@
 DEF(ProtoList, insert_BANG, FORM_PARAM2) {
 	obj_p list;
 	BIN_CONTENT_CHK(ProtoList);
-	call_func2(ist, list = protos2list(ist, self->data.ptr), 
+	call_func2(ist, list = protos2list(ist, self->body->data.ptr), 
 	                sym(ist, "insert_BANG"), parms[1], parms[3]);
-	list2protos(ist, list, self->data.ptr);
+	list2protos(ist, list, self->body->data.ptr);
 	del_unlock(list);
 	return NULL;
 }
@@ -190,9 +190,9 @@
 DEF(ProtoList, remove_BANG, FORM_RPARAM) {
 	obj_p list;
 	BIN_CONTENT_CHK(ProtoList);
-	call_func1(ist, list = protos2list(ist, self->data.ptr), 
+	call_func1(ist, list = protos2list(ist, self->body->data.ptr), 
 	                sym(ist, "remove_BANG"), parms[1]);
-	list2protos(ist, list, self->data.ptr);
+	list2protos(ist, list, self->body->data.ptr);
 	del_unlock(list);
 	return NULL;
 }
@@ -200,7 +200,7 @@
 DEF(ProtoList, rIn__QUES, FORM_RPARAM) {
 	obj_p res, list;
 	BIN_CONTENT_CHK(ProtoList);
-	res = call_func1(ist, list = protos2list(ist, self->data.ptr), 
+	res = call_func1(ist, list = protos2list(ist, self->body->data.ptr), 
 		                  sym(ist, "rIn__QUES"), parms[1]);
 	del_unlock(list);
 	return res;
@@ -209,7 +209,7 @@
 DEF(ProtoList, rNotIn__QUES, FORM_RPARAM) {
 	obj_p res, list;
 	BIN_CONTENT_CHK(ProtoList);
-	res = call_func1(ist, list = protos2list(ist, self->data.ptr), 
+	res = call_func1(ist, list = protos2list(ist, self->body->data.ptr), 
 		                  sym(ist, "rNotIn__QUES"), parms[1]);
 	del_unlock(list);
 	return res;
@@ -217,7 +217,7 @@
 
 DEF(ProtoList, len_, NULL) {
 	BIN_CONTENT_CHK(ProtoList);
-	return NEW_INT(proto_len(ist, self->data.ptr));
+	return NEW_INT(proto_len(ist, self->body->data.ptr));
 }
 
 DEF(ProtoList, objList_, FORM_RPARAM) {
Modified: trunk/src/builtins-string.c
===================================================================
--- trunk/src/builtins-string.c	2004-07-17 08:33:55 UTC (rev 748)
+++ trunk/src/builtins-string.c	2004-07-18 04:26:50 UTC (rev 749)
@@ -130,8 +130,8 @@
 
 	if (size <= IMM_DATA_LEN) {
 		SET_TYPE_IF_EXC(OBJ(STRING_PROTO), obj, DATA_TYPE_IMMDATA) return;
-		obj->imm_data_len = (int) size;
-		ch3p = obj->data.str;
+		obj->body->imm_data_len = (int) size;
+		ch3p = obj->body->data.str;
 	} else {
 		obj_str = obj_malloc(ist, OBJ(STRING_PROTO), obj, sizeof(str_t)+size); if_exc_return;
 		obj_str->size = sizeof(str_t)+size;
@@ -142,7 +142,7 @@
 		ch3p->b1 = 0;
 		ch3p->b2 = 0;
 	}
-	obj->immutable = TRUE;
+	obj->body->immutable = TRUE;
 }
 
 //********************************* pr2pr_strcpy *******************************
@@ -153,8 +153,8 @@
 
 	if (size <= IMM_DATA_LEN) {
 		SET_TYPE_IF_EXC(OBJ(STRING_PROTO), obj, DATA_TYPE_IMMDATA) return;
-		obj->imm_data_len = (int) size;
-		ch3p = obj->data.str;
+		obj->body->imm_data_len = (int) size;
+		ch3p = obj->body->data.str;
 	} else {
 		obj_str = obj_malloc(ist, OBJ(STRING_PROTO), obj, sizeof(str_t)+size); if_exc_return;
 		obj_str->size = sizeof(str_t)+size;
@@ -165,7 +165,7 @@
 		ch3p->b1 = str->b1;
 		ch3p->b2 = str->b2;
 	}
-	obj->immutable = TRUE;
+	obj->body->immutable = TRUE;
 }
 
 //********************************* c2pr_bytcpy *******************************
@@ -176,8 +176,8 @@
 
 	if (size <= IMM_DATA_LEN) {
 		SET_TYPE_IF_EXC(OBJ(STRING_PROTO), obj, DATA_TYPE_IMMDATA) return;
-		obj->imm_data_len = (int) size;
-		ch3p = obj->data.str;
+		obj->body->imm_data_len = (int) size;
+		ch3p = obj->body->data.str;
 	} else {
 		obj_str = obj_malloc(ist, OBJ(STRING_PROTO), obj, sizeof(str_t)+size); if_exc_return;
 		obj_str->size = sizeof(str_t)+size;
@@ -192,7 +192,7 @@
 		ch3p->b1 = 0;
 		ch3p->b2 = 0;
 	}
-	obj->immutable = TRUE;
+	obj->body->immutable = TRUE;
 }
 
 //********************************* pr2c_strptr *******************************
@@ -204,11 +204,11 @@
 
 	if (!str_obj)
 		return "<null>";
-	if (str_obj->data_type == DATA_TYPE_IMMDATA) {
-		data_size = str_obj->imm_data_len;
-		ch3p      = str_obj->data.str;
-	} else if (str_obj->data_type == DATA_TYPE_DATAPTR) {
-		strp      = str_obj->data.ptr;
+	if (str_obj->body->data_type == DATA_TYPE_IMMDATA) {
+		data_size = str_obj->body->imm_data_len;
+		ch3p      = str_obj->body->data.str;
+	} else if (str_obj->body->data_type == DATA_TYPE_DATAPTR) {
+		strp      = str_obj->body->data.ptr;
 		data_size = strp->size - sizeof(str_t);
 		ch3p      = strp->str;
 	} else {
@@ -241,11 +241,11 @@
 		raise_exception(ist, OBJ(INTERNAL_EXC), "string object missing in pr_str2bytes");
 		return;
 	}
-	if (str_obj->data_type == DATA_TYPE_IMMDATA) {
-		data_size = str_obj->imm_data_len;
-		ch3p      = str_obj->data.str;
-	} else if (str_obj->data_type == DATA_TYPE_DATAPTR) {
-		strp      = str_obj->data.ptr;
+	if (str_obj->body->data_type == DATA_TYPE_IMMDATA) {
+		data_size = str_obj->body->imm_data_len;
+		ch3p      = str_obj->body->data.str;
+	} else if (str_obj->body->data_type == DATA_TYPE_DATAPTR) {
+		strp      = str_obj->body->data.ptr;
 		data_size = strp->size - sizeof(str_t);
 		ch3p      = strp->str;
 	} else {
@@ -348,7 +348,7 @@
 	set_obj_id(String_OBJ, *, String);
 	set_attr(ist, OBJ(OBJECT), sym(ist, "String"), String_OBJ);
 	SET_TYPE_IF_EXC(String_OBJ, String_OBJ, DATA_TYPE_IMMDATA) return;
-	String_OBJ->imm_data_len = 0;
+	String_OBJ->body->imm_data_len = 0;
 }
 
 DEF(String, init_, FORM_STAR_PARAM) {
@@ -367,11 +367,11 @@
 			s = symch(ist, obj);
 		} else if ( llen == 2 && has_proto(ist, obj, OBJ(INT_PROTO)) && 
 			        has_proto(ist, obj2 = list_item(ist, parms[1], 1), OBJ(INT_PROTO)) ) {
-			if (obj->data_type == DATA_TYPE_IMMDATA) {
-				res = long_format(new_longp(obj->data.i64), int2i32t(ist, obj2), FALSE);
+			if (obj->body->data_type == DATA_TYPE_IMMDATA) {
+				res = long_format(new_longp(obj->body->data.i64), int2i32t(ist, obj2), FALSE);
 				s = pr2c_strptr(ist, res);
 			} else {
-				res = long_format(obj->data.ptr, int2i32t(ist, obj2), FALSE);
+				res = long_format(obj->body->data.ptr, int2i32t(ist, obj2), FALSE);
 				s = pr2c_strptr(ist, res);
 			}
 		} else if (has_proto(ist, obj, OBJ(BYTES_PROTO))) {
@@ -591,10 +591,10 @@
 	for (i=0; i < argc; i++) {
 		obj_p arg_obj = list_item(ist, argv_obj, (int) i);
 		if (has_proto(ist, arg_obj, OBJ(INT_PROTO))) {
-			argv[i].arg.i64 = arg_obj->data.i64;
+			argv[i].arg.i64 = arg_obj->body->data.i64;
 			argv[i].type    = ARG_TYPE_INT;
 		} else if (has_proto(ist, arg_obj, OBJ(FLOAT_PROTO))) {
-			argv[i].arg.f64 = arg_obj->data.f64;
+			argv[i].arg.f64 = arg_obj->body->data.f64;
 			argv[i].type    = ARG_TYPE_FLOAT;
 		} else if (has_proto(ist, arg_obj, OBJ(STRING_PROTO))) {
 			argv[i].arg.str = pr2c_strptr(ist, arg_obj);
@@ -785,8 +785,8 @@
 	obj = NEW_OBJ(String_OBJ);
 	if (tlen*3 <= IMM_DATA_LEN) {
 		SET_TYPE_IF_EXC(String_OBJ, obj, DATA_TYPE_IMMDATA) return NULL;
-		obj->imm_data_len = (int) tlen*3;
-		dest_ptr = obj->data.str;
+		obj->body->imm_data_len = (int) tlen*3;
+		dest_ptr = obj->body->data.str;
 	} else {
 		obj_str = obj_malloc(ist, OBJ(STRING_PROTO), obj, sizeof(str_t)+tlen*3);
 		if(!obj_str) {
@@ -1113,7 +1113,7 @@
 	SET_TYPE_IF_EXC(StringGen_OBJ, gen_obj, DATA_TYPE_DATAPTR) return NULL;
 	len  = pr_strlen(self);
 	srcp = pr_ch3ptr(self);
-	gen_obj->data.ptr = strgenp = pr_malloc(sizeof(str_gen_t) + len*sizeof(ch3_t));
+	gen_obj->body->data.ptr = strgenp = pr_malloc(sizeof(str_gen_t) + len*sizeof(ch3_t));
 	strgenp->size = sizeof(str_gen_t) + len*sizeof(ch3_t);
 	strgenp->ptr  = dstp = strgenp->str;
 	for(i=0; i < len; i++, dstp++, srcp++) {
@@ -1129,7 +1129,7 @@
         str_gen_p strgenp;
 		BIN_CONTENT_CHK(StringGen);
         def_write_lock(self);
-		strgenp = self->data.ptr;
+		strgenp = self->body->data.ptr;
 		if (strgenp->ptr == (strgenp->str)+str_gen_len(strgenp)) {
                 raise_exception(ist, OBJ(STOP_ITERATION_EXC), NULL);
 				return NULL;

Modified: trunk/src/builtins-thread.c
===================================================================
--- trunk/src/builtins-thread.c	2004-07-17 08:33:55 UTC (rev 748)
+++ trunk/src/builtins-thread.c	2004-07-18 04:26:50 UTC (rev 749)
@@ -75,8 +75,8 @@
 	pr_thread_p thread_ptr;
 	thread_obj = NEW_OBJ(OBJ(THREAD_PROTO));
 	SET_TYPE_IF_EXC(OBJ(THREAD_PROTO), thread_obj, DATA_TYPE_DATAPTR) return;
-	thread_ptr = thread_obj->data.ptr  = pr_malloc(sizeof(pr_thread_t));
-	memset(thread_obj->data.ptr, 0, sizeof(pr_thread_t));
+	thread_ptr = thread_obj->body->data.ptr  = pr_malloc(sizeof(pr_thread_t));
+	memset(thread_obj->body->data.ptr, 0, sizeof(pr_thread_t));
 	thread_ptr->size          = sizeof(pr_thread_t);
 	thread_ptr->ist           = ist;
 	thread_ptr->apr_os_thread = apr_os_thread_current();
@@ -111,13 +111,13 @@
 		IF_APR_ERR("apr_threadattr_detach_set") return NULL;
 	}
 	if (thread_obj)
-		thread_p = thread_obj->data.ptr;
+		thread_p = thread_obj->body->data.ptr;
 	else {
 		thread_obj = NEW_OBJ(OBJ(THREAD_PROTO));
 		SET_TYPE_IF_EXC(OBJ(THREAD_PROTO), thread_obj, DATA_TYPE_DATAPTR) return NULL;
-		thread_p = thread_obj->data.ptr = pr_malloc(sizeof(pr_thread_t));
-		memset(thread_obj->data.ptr, 0, sizeof(pr_thread_t));
-		((pr_thread_p)(thread_obj->data.ptr))->size = sizeof(pr_thread_t);
+		thread_p = thread_obj->body->data.ptr = pr_malloc(sizeof(pr_thread_t));
+		memset(thread_obj->body->data.ptr, 0, sizeof(pr_thread_t));
+		((pr_thread_p)(thread_obj->body->data.ptr))->size = sizeof(pr_thread_t);
 	}
 	thread_p->ist = new_ist(acc_level);
 
@@ -142,7 +142,7 @@
 obj_p register_thread(apr_thread_t *this_thread)
 {
 	obj_p res = new_thread_object;
-	pr_thread_p thread_ptr    = res->data.ptr;
+	pr_thread_p thread_ptr    = res->body->data.ptr;
 	thread_ptr->apr_os_thread = apr_os_thread_current();
 	thread_ptr->apr_thread    = this_thread;
 	clist_append(thread_registry, res);
@@ -159,7 +159,7 @@
 	pr_lock(&thread_registry_lock);
 	for (i = 0; i < clist_len(thread_registry); i++) {
 		obj_p thread_obj = clist_item(thread_registry, i);
-		pr_thread_p thread_ptr = thread_obj->data.ptr;
+		pr_thread_p thread_ptr = thread_obj->body->data.ptr;
 		if (thread_ptr->apr_os_thread == os_thread) {
 			res = thread_ptr->apr_thread;
 			break;
@@ -179,7 +179,7 @@
 	llen = clist_len(thread_registry);
 	for (i = 0; i < llen; i++) {
 		res = clist_item(thread_registry, i);
-		if (((pr_thread_p)(res->data.ptr))->apr_os_thread == os_thread) 
+		if (((pr_thread_p)(res->body->data.ptr))->apr_os_thread == os_thread) 
 			break;
 	}
 	if (i == llen) res = NULL;
@@ -206,7 +206,7 @@
 	if_exc_return;
     memset(thread, 0, sizeof(pr_thread_t));
 	thread->size = sizeof(pr_thread_t);
-	Thread_OBJ->unclonable = TRUE;
+	Thread_OBJ->body->unclonable = TRUE;
 }
 
 
@@ -227,13 +227,13 @@
 		CHECK_TYPE_EXC(parms[5], OBJ(STRING_PROTO), "string");
 	CHECK_TYPE_EXC(parms[7], OBJ(INT_PROTO),    "integer");
 	SET_TYPE_IF_EXC(Thread_OBJ, self, DATA_TYPE_DATAPTR) return NULL;
-	self->data.ptr  = pr_malloc(sizeof(pr_thread_t));
-	memset(self->data.ptr, 0, sizeof(pr_thread_t));
-	((pr_thread_p)(self->data.ptr))->size = sizeof(pr_thread_t);
-	uthread = &(((pr_thread_p)self->data.ptr)->user_thread_data);
+	self->body->data.ptr  = pr_malloc(sizeof(pr_thread_t));
+	memset(self->body->data.ptr, 0, sizeof(pr_thread_t));
+	((pr_thread_p)(self->body->data.ptr))->size = sizeof(pr_thread_t);
+	uthread = &(((pr_thread_p)self->body->data.ptr)->user_thread_data);
 	uthread->func   = parms[1]; 
 	uthread->params = parms[3]; 
-	access_level = (int) parms[7]->data.i64;
+	access_level = (int) parms[7]->body->data.i64;
 	if (access_level == -1) access_level = ist->access;
 	if (ist->access < access_level) {
 		raise_exception(ist, OBJ(PERMISSION_EXC), 
@@ -249,7 +249,7 @@
 	set_attr(ist, self, sym(ist, "name"), name_obj);
 	new_thread_obj(ist, (apr_thread_start_t) user_thread, uthread, self, access_level);
 	read_lock(ist, self);
-	self->unclonable = TRUE;
+	self->body->unclonable = TRUE;
 	return OBJ(NONE);
 }
 
@@ -273,7 +273,7 @@
 	int new_access;
 	BIN_CONTENT_CHK(Thread);
 	CHECK_TYPE_EXC(parms[1], OBJ(INT_PROTO), "integer");
-	new_access = (int) parms[1]->data.i64;
+	new_access = (int) parms[1]->body->data.i64;
 	if (new_access > ist->access) {
 		raise_exception(ist, OBJ(PERMISSION_EXC), 
 			"attempt to raise thread access level");	
@@ -303,12 +303,12 @@
 DEF(Thread, sleep, FORM_RPARAM) {
 	BIN_CONTENT_CHK(Thread);
 	CHECK_TYPE_EXC(parms[1], OBJ(FLOAT_PROTO), "float");
-	apr_sleep((apr_interval_time_t)((parms[1]->data.f64)*1000000));
+	apr_sleep((apr_interval_time_t)((parms[1]->body->data.f64)*1000000));
 	return parms[1];
 }
 
 DEF(Thread, join, NULL) {
-	pr_thread_p thread_ptr = self->data.ptr;
+	pr_thread_p thread_ptr = self->body->data.ptr;
 	apr_status_t retval, aprerr;
 	BIN_CONTENT_CHK(Thread);
 	if (!(thread_ptr->apr_thread)) {
@@ -332,7 +332,7 @@
 	MODULE_SET_DOC(Mutex, "mutex object prototype");
 
 	set_attr(ist, OBJ(OBJECT), sym(ist,  "Mutex"), Mutex_OBJ);
-	Mutex_OBJ->unclonable = TRUE;
+	Mutex_OBJ->body->unclonable = TRUE;
 }
 
 
@@ -343,10 +343,10 @@
 	aprerr = apr_pool_create(&subpool, get_pr_head_pool());
 	IF_APR_ERR("out of memory creating mutex") return NULL;
 	SET_TYPE_IF_EXC(Mutex_OBJ, self, DATA_TYPE_DATAPTR) return NULL;
-	aprerr = apr_thread_mutex_create( (apr_thread_mutex_t**)(&self->data.ptr), 
+	aprerr = apr_thread_mutex_create( (apr_thread_mutex_t**)(&self->body->data.ptr), 
 		                               APR_THREAD_MUTEX_UNNESTED, subpool );
 	IF_APR_ERR("error creating mutex in apr_thread_mutex_create") return NULL;
-	self->unclonable = TRUE;
+	self->body->unclonable = TRUE;
 	return OBJ(NONE);
 }
 
@@ -360,7 +360,7 @@
 DEF(Mutex, lock, NULL) {
 	apr_status_t aprerr;
 	BIN_CONTENT_CHK(Mutex);
-	aprerr = apr_thread_mutex_lock((apr_thread_mutex_t*)(self->data.ptr));
+	aprerr = apr_thread_mutex_lock((apr_thread_mutex_t*)(self->body->data.ptr));
 	IF_APR_ERR("error in apr_thread_mutex_lock") return NULL;
 	return self;
 }
@@ -368,7 +368,7 @@
 DEF(Mutex, tryLock, NULL) {
 	apr_status_t aprerr;
 	BIN_CONTENT_CHK(Mutex);
-	aprerr = apr_thread_mutex_trylock((apr_thread_mutex_t*)(self->data.ptr));
+	aprerr = apr_thread_mutex_trylock((apr_thread_mutex_t*)(self->body->data.ptr));
 	if (APR_STATUS_IS_EBUSY(aprerr)) return OBJ(PR_FALSE);
 	else if (aprerr == APR_SUCCESS)	 return OBJ(PR_TRUE);
 	IF_APR_ERR("error in apr_thread_mutex_trylock") return NULL;
@@ -378,14 +378,14 @@
 DEF(Mutex, unlock, NULL) {
 	apr_status_t aprerr;
 	BIN_CONTENT_CHK(Mutex);
-	aprerr = apr_thread_mutex_unlock((apr_thread_mutex_t*)(self->data.ptr));
+	aprerr = apr_thread_mutex_unlock((apr_thread_mutex_t*)(self->body->data.ptr));
 	IF_APR_ERR("error in apr_thread_mutex_unlock") return NULL;
 	return self;
 }
 
 DEF(Mutex, final_, NULL) {
-	if (self->data.ptr)
-		apr_thread_mutex_destroy((apr_thread_mutex_t*)(self->data.ptr));
+	if (self->body->data.ptr)
+		apr_thread_mutex_destroy((apr_thread_mutex_t*)(self->body->data.ptr));
 	return OBJ(NONE);
 }
 

Modified: trunk/src/builtins-time.c
===================================================================
--- trunk/src/builtins-time.c	2004-07-17 08:33:55 UTC (rev 748)
+++ trunk/src/builtins-time.c	2004-07-18 04:26:50 UTC (rev 749)
@@ -69,9 +69,9 @@
 obj_p new_time_obj(isp ist, i64_t usecs){
 	obj_p obj = NEW_OBJ(DateTime_OBJ);
 	SET_TYPE_IF_EXC(DateTime_OBJ, obj, DATA_TYPE_IMMDATA) return NULL;
-	obj->imm_data_len = 8;
-	obj->data.i64 = usecs;
-	obj->immutable = TRUE;
+	obj->body->imm_data_len = 8;
+	obj->body->data.i64 = usecs;
+	obj->body->immutable = TRUE;
 	return obj;
 }
 
@@ -85,8 +85,8 @@
 	set_attr(ist, OBJ(OBJECT), sym(ist, "DateTime"), DateTime_OBJ);
 
 	SET_TYPE_IF_EXC(DateTime_OBJ, DateTime_OBJ, DATA_TYPE_IMMDATA) return;
-	DateTime_OBJ->imm_data_len = 8;
-	DateTime_OBJ->data.i64     = apr_time_now();
+	DateTime_OBJ->body->imm_data_len = 8;
+	DateTime_OBJ->body->data.i64     = apr_time_now();
 }
 
 DEF(DateTime, init_, FPARM8( year,        OBJ(NONE), month,  OBJ(NONE), 
@@ -113,19 +113,19 @@
 	tzinfo = parms[15];
 
 	SET_TYPE_IF_EXC(DateTime_OBJ, self, DATA_TYPE_IMMDATA) return NULL;
-	self->imm_data_len = 8;
+	self->body->imm_data_len = 8;
 	if ( !have_yr && !have_mo && !have_dy &&
 		 !have_hr && !have_mi && !have_sc && !have_us ) {
-		self->data.i64 = apr_time_now();
+		self->body->data.i64 = apr_time_now();
 		return OBJ(NONE);
 	}
 	if (  have_yr && !have_mo && !have_dy &&
 		 !have_hr && !have_mi && !have_sc && !have_us ) {
-		self->data.i64 = year;
+		self->body->data.i64 = year;
 		return OBJ(NONE);
 	}
 	if (!have_yr && !have_mo) {
-		self->data.i64 = 
+		self->body->data.i64 = 
 			(((i64_t)day)*24*60*60*1000000) + 
 		    (((i64_t)hour)*60*60*1000000) + 
 		    (((i64_t)minute)*60*1000000) + 
@@ -142,21 +142,21 @@
 	aprxt.tm_usec = (apr_int32_t) microsecond;
 	aprerr = apr_time_exp_gmt_get(&result, &aprxt);
 	IF_APR_ERR("converting time params") return NULL;
-	self->data.i64 = result;
+	self->body->data.i64 = result;
 	return OBJ(NONE);
 }
 
 DEF(DateTime, hash_, NULL) { 
 	BIN_CONTENT_CHK(DateTime);
-	return new_hash_obj(ist, self->data.i32[0]+self->data.i32[1]);
+	return new_hash_obj(ist, self->body->data.i32[0]+self->body->data.i32[1]);
 }
 
 DEF(DateTime, cmp_, FORM_RPARAM){
 	BIN_CONTENT_CHK(DateTime);
 	CHECK_TYPE_EXC(parms[1], DateTime_OBJ, DateTime);
-	if (self->data.i64 == parms[1]->data.i64)
+	if (self->body->data.i64 == parms[1]->body->data.i64)
 		return NEW_INT(0);
-	else if (self->data.i64 > parms[1]->data.i64)
+	else if (self->body->data.i64 > parms[1]->body->data.i64)
 		return NEW_INT(1);
 	else
 		return NEW_INT(-1);
@@ -165,7 +165,7 @@
 DEF(DateTime, eq__QUES, FORM_RPARAM){
 	BIN_CONTENT_CHK(DateTime);
 	CHECK_TYPE_EXC(parms[1], DateTime_OBJ, DateTime);
-	if (self->data.i64 == parms[1]->data.i64) return OBJ(PR_TRUE);
+	if (self->body->data.i64 == parms[1]->body->data.i64) return OBJ(PR_TRUE);
 	else                                      return OBJ(PR_FALSE);
 }
 
@@ -177,7 +177,7 @@
 		raise_exception(ist, OBJ(OVERFLOW_EXC), "time str_ spec not supported yet");
 		return NULL;
 	}
-	apr_rfc822_date(buf, self->data.i64);
+	apr_rfc822_date(buf, self->body->data.i64);
 	return NEW_STRING(buf);
 }
 

Modified: trunk/src/builtins-tuple.c
===================================================================
--- trunk/src/builtins-tuple.c	2004-07-17 08:33:55 UTC (rev 748)
+++ trunk/src/builtins-tuple.c	2004-07-18 04:26:50 UTC (rev 749)
@@ -67,8 +67,8 @@
 //********************************* new_tuple_obj *****************************
 obj_p new_tuple_obj(isp ist, int fixed_size) {
 	obj_p tuple_obj = NEW_LIST(fixed_size);
-	pr_assert(!(tuple_obj->has_attrs));
-	tuple_obj->attr_proto.proto = OBJ(TUPLE_PROTO);
+	pr_assert(!(tuple_obj->body->has_attrs));
+	tuple_obj->body->attr_proto.proto = OBJ(TUPLE_PROTO);
 	return tuple_obj;
 }
 
@@ -104,7 +104,7 @@
 	set_attr(ist, OBJ(OBJECT), sym(ist, "Tuple"), Tuple_OBJ);
 
 	SET_TYPE_IF_EXC(Tuple_OBJ, Tuple_OBJ, DATA_TYPE_DATAPTR) return;
-	lstp = Tuple_OBJ->data.ptr = pr_malloc(list_sizeof(2));
+	lstp = Tuple_OBJ->body->data.ptr = pr_malloc(list_sizeof(2));
 	lstpsetsize(lstp, 2);
 	lstplen(lstp)  = 0;
 }
@@ -142,7 +142,7 @@
 }
 
 DEF(Tuple, objList_, FORM_RPARAM) {
-	if (!self->data.ptr) return parms[1];
+	if (!self->body->data.ptr) return parms[1];
 	return self;
 }
 
@@ -163,8 +163,8 @@
 		self_item = list_item(ist, self, i);
 		tgt_item  = list_item(ist, tgt_list, i);
 		res = call_func1(ist, self_item, SYM(CMP_), tgt_item); if_exc_return NULL;
-		if (res->data.i64)
-			return NEW_INT(res->data.i64);
+		if (res->body->data.i64)
+			return NEW_INT(res->body->data.i64);
 	}
 	if (llen < tlen) return NEW_INT(-1);
 	if (llen > tlen) return NEW_INT(+1);
@@ -231,23 +231,23 @@
 
 DEF(Tuple, mul_, FORM_RPARAM){
 	obj_p res;
-	list_p lstp, selfp = (list_p)(self->data.ptr);
+	list_p lstp, selfp = (list_p)(self->body->data.ptr);
 	int i, total_len, times, len = (int) list_len(ist, self);
 	BIN_CONTENT_CHK(Tuple);
 	if (!has_proto(ist, parms[1], OBJ(INT_PROTO))) {
 		raise_exception(ist, OBJ(TYPE_EXC), "multiply times parameter must be an integer");
 		return NULL;
 	}
-	times = (int)parms[1]->data.i64;
+	times = (int)parms[1]->body->data.i64;
 	total_len  = len*times;
 	if(times == 0) { 
 		obj_p res = NEW_TUPLE(0);
-		res ->immutable = TRUE;
+		res ->body->immutable = TRUE;
 		return res;
 	}
 	if(times == 1) return self;
 	res = NEW_OBJ(OBJ(TUPLE_PROTO));
-	lstp = res->data.ptr = pr_malloc(list_sizeof(total_len));
+	lstp = res->body->data.ptr = pr_malloc(list_sizeof(total_len));
 	if(!lstp) {
 		raise_exception(ist, OBJ(OUTOFMEMORY_EXC), "memory allocation failed for tuple multiplication");
 		return NULL;
@@ -272,11 +272,11 @@
 	if (llen == 0) return OBJ(NONE);
 	if (llen == 1) return list_item(ist, self, 0);
 	cmp_obj = call_func1(ist, list_item(ist, self, 0), SYM(CMP_), list_item(ist, self, 1));  if_exc_return NULL;
-	if (cmp_obj->data.i64 < 0) min_item = list_item(ist, self, 0);
+	if (cmp_obj->body->data.i64 < 0) min_item = list_item(ist, self, 0);
 	else					   min_item = list_item(ist, self, 1);
 	for(i=2; i < llen; i++) {
 		cmp_obj = call_func1(ist, list_item(ist, self, i), SYM(CMP_), min_item);  if_exc_return NULL;
-		if (cmp_obj->data.i64 < 0) min_item = list_item(ist, self, i);
+		if (cmp_obj->body->data.i64 < 0) min_item = list_item(ist, self, i);
 	}
 	return min_item;
 }
@@ -288,11 +288,11 @@
 	if (llen == 0) return OBJ(NONE);
 	if (llen == 1) return list_item(ist, self, 0);
 	cmp_obj = call_func1(ist, list_item(ist, self, 0), SYM(CMP_), list_item(ist, self, 1));  if_exc_return NULL;
-	if (cmp_obj->data.i64 > 0) max_item = list_item(ist, self, 0);
+	if (cmp_obj->body->data.i64 > 0) max_item = list_item(ist, self, 0);
 	else					   max_item = list_item(ist, self, 1);
 	for(i=2; i < llen; i++) {
 		cmp_obj = call_func1(ist, list_item(ist, self, i), SYM(CMP_), max_item);  if_exc_return NULL;
-		if (cmp_obj->data.i64 > 0) max_item = list_item(ist, self, i);
+		if (cmp_obj->body->data.i64 > 0) max_item = list_item(ist, self, i);
 	}
 	return max_item;
 }
@@ -324,7 +324,7 @@
 	obj_p list_obj, gen_obj = NEW_OBJ(Tgen_OBJ);
 	BIN_CONTENT_CHK(Tuple);
 	SET_TYPE_IF_EXC(Tgen_OBJ, gen_obj, DATA_TYPE_DATAPTR) return NULL;
-	gen_obj->data.ptr = list_obj = copy_list_obj(ist, self);
+	gen_obj->body->data.ptr = list_obj = copy_list_obj(ist, self);
 	listlen(list_obj) = 0;
 	return gen_obj;
 }
@@ -339,7 +339,7 @@
 	for (i=0; i < llen; i++) {
 		hash_obj = call_func0(ist, list_item(ist, self, i), SYM(HASH_));
 		if_exc_return NULL;
-		hash += hash_obj->data.i32[0];
+		hash += hash_obj->body->data.i32[0];
 	}
 	return new_hash_obj(ist, hash);
 }
@@ -352,7 +352,7 @@
 }
 
 DEF(Tgen, next, NULL) {
-	obj_p res, list_obj = self->data.ptr;
+	obj_p res, list_obj = self->body->data.ptr;
 	size_t lsiz = listsize(list_obj);
 	size_t llen = listlen(list_obj);
 	BIN_CONTENT_CHK(Tgen);

Modified: trunk/src/dict.h
===================================================================
--- trunk/src/dict.h	2004-07-17 08:33:55 UTC (rev 748)
+++ trunk/src/dict.h	2004-07-18 04:26:50 UTC (rev 749)
@@ -81,7 +81,7 @@
 
 #define dict_sizeof(n)			(((n)+DICT_OVERHEAD) * sizeof(dict_t))
 
-#define dict_d(dict_obj)		((dict_p)((dict_obj)->data.ptr))
+#define dict_d(dict_obj)		((dict_p)((dict_obj)->body->data.ptr))
 #define dictsize_bytes(dict)	(((dict_p)(dict))[DICT_HDR_INDEX].hdr.size_bytes)
 #define dictsize(dict)			(((dict_p)(dict))[DICT_HDR_INDEX].hdr.size)
 #define dictlen(dict)			(((dict_p)(dict))[DICT_HDR_INDEX].hdr.len)

Modified: trunk/src/interp.c
===================================================================
--- trunk/src/interp.c	2004-07-17 08:33:55 UTC (rev 748)
+++ trunk/src/interp.c	2004-07-18 04:26:50 UTC (rev 749)
@@ -126,7 +126,7 @@
 obj_p new_parmptr_obj(isp ist, int ofs) {
 	obj_p new_obj = new_object(ist, OBJ(PARMPTR_PROTO));
 	SET_TYPE_IF_EXC(OBJ(PARMPTR_PROTO), new_obj, DATA_TYPE_IMMDATA) return NULL;
-	new_obj->data.i64 = ofs;
+	new_obj->body->data.i64 = ofs;
 	set_immutable(new_obj);
 	return new_obj;
 }
@@ -176,8 +176,8 @@
 obj_p new_local_obj(isp ist, obj_p symbol){
 	obj_p local_obj = NEW_OBJ(OBJ(LOCAL_PROTO));
 	SET_TYPE_IF_EXC(OBJ(LOCAL_PROTO), local_obj, DATA_TYPE_EXTPTR) return NULL;
-	local_obj->data.ptr = symbol;
-	local_obj->immutable = TRUE;
+	local_obj->body->data.ptr = symbol;
+	local_obj->body->immutable = TRUE;
 	return local_obj;
 }
 
@@ -186,11 +186,11 @@
 	int i;
 	obj_p super_obj = NEW_OBJ(OBJ(SUPER_PROTO));
 	SET_TYPE_IF_EXC(OBJ(SUPER_PROTO), super_obj, DATA_TYPE_EXTPTR) return NULL;
-	super_obj->data.ptr = symbol;
+	super_obj->body->data.ptr = symbol;
 	su(i);
 	set_attr(ist, super_obj, SYM(CONT_), container);
 	un_su(i);
-	super_obj->immutable = TRUE;
+	super_obj->body->immutable = TRUE;
 	return super_obj;
 }
 
@@ -198,8 +198,8 @@
 obj_p new_outer_obj(isp ist, obj_p symbol){
 	obj_p outer_obj = NEW_OBJ(OBJ(OUTER_PROTO));
 	SET_TYPE_IF_EXC(OBJ(OUTER_PROTO), outer_obj, DATA_TYPE_EXTPTR) return NULL;
-	outer_obj->data.ptr = symbol;
-	outer_obj->immutable = TRUE;
+	outer_obj->body->data.ptr = symbol;
+	outer_obj->body->immutable = TRUE;
 	return outer_obj;
 }
 
@@ -227,7 +227,7 @@
 		return res;
 	} else if (has_proto(ist, ref_key, OBJ(LOCAL_PROTO))) {
 		if_exc_return NULL;
-        return get_scope_attr(ist, ref_self, ref_key->data.ptr, NULL, NULL);
+        return get_scope_attr(ist, ref_self, ref_key->body->data.ptr, NULL, NULL);
 	} else if (has_proto(ist, ref_key, OBJ(SLICE_PROTO))) {
 		obj_p param[2];  
 		if_exc_return NULL;
@@ -236,9 +236,9 @@
 	} else if (has_proto(ist, ref_key, OBJ(OUTER_PROTO))) {
 		obj_p res;
 		if_exc_return NULL;
-        res = get_scope_attr(ist, ref_self, ref_key->data.ptr, NULL, ref_self);
+        res = get_scope_attr(ist, ref_self, ref_key->body->data.ptr, NULL, ref_self);
 		if (!res) {
-			raise_exception(ist, OBJ(INTERPRETER_EXC), "outer.%s not found", as_str(ist, ref_key->data.ptr));
+			raise_exception(ist, OBJ(INTERPRETER_EXC), "outer.%s not found", as_str(ist, ref_key->body->data.ptr));
 			return NULL;
 		}
 		return res;
@@ -250,14 +250,14 @@
 		obj_p res, cont = get_attr(ist, ref_key, SYM(CONT_));
 		if (!cont) {
 			raise_exception(ist, OBJ(NAME_EXC), "Container obj for attribute %s not found",
-					                             symch(ist, ref_key->data.ptr));
+					                             symch(ist, ref_key->body->data.ptr));
 			return NULL;
 		}
 		if_exc_return NULL;
-		res = get_proto_attr(ist, ref_self, ref_key->data.ptr, NULL, cont);
+		res = get_proto_attr(ist, ref_self, ref_key->body->data.ptr, NULL, cont);
 		if (!res) {
 			raise_exception(ist, OBJ(NAME_EXC), "Super attribute %s not found",
-					                             symch(ist, ref_key->data.ptr));
+					                             symch(ist, ref_key->body->data.ptr));
 		}
 		return res;
 	} else {
@@ -300,7 +300,7 @@
 		}
 		set_attr(ist, ref_self, ref_key, value);
 	} else if (has_proto(ist, ref_key, OBJ(LOCAL_PROTO))) {
-		set_attr(ist, ref_self, ref_key->data.ptr, value);
+		set_attr(ist, ref_self, ref_key->body->data.ptr, value);
 	} else if (has_proto(ist, ref_key, OBJ(SLICE_PROTO))) {
 		obj_p param[4];  
 		param[0]=OBJ(NOKEY); param[1]=ref_key;
@@ -309,13 +309,13 @@
 	} else if (has_proto(ist, ref_key, OBJ(OUTER_PROTO))) {
 		obj_p scope_obj;
 		if_exc_return;
-        get_scope_attr(ist, ref_self, ref_key->data.ptr, &scope_obj, ref_self);
+        get_scope_attr(ist, ref_self, ref_key->body->data.ptr, &scope_obj, ref_self);
 		if (!scope_obj) {
-			raise_exception(ist, OBJ(INTERPRETER_EXC), "outer.%s not found", as_str(ist, ref_key->data.ptr));
+			raise_exception(ist, OBJ(INTERPRETER_EXC), "outer.%s not found", as_str(ist, ref_key->body->data.ptr));
 			return;
 		}
 		if_exc_return;
-		set_attr(ist, scope_obj, ref_key->data.ptr, value);
+		set_attr(ist, scope_obj, ref_key->body->data.ptr, value);
 	} else if (has_proto(ist, ref_key, OBJ(INT_PROTO))) {
 		obj_p param[4];  
 		param[0]=OBJ(NOKEY); param[1]=slice1(ref_key);
@@ -325,17 +325,17 @@
 		obj_p res, proto, cont = get_attr(ist, ref_key, SYM(CONT_));
 		if (!cont) {
 			raise_exception(ist, OBJ(NAME_EXC), "Container obj for attribute %s not found",
-					                             symch(ist, ref_key->data.ptr));
+					                             symch(ist, ref_key->body->data.ptr));
 			return;
 		}
 		if_exc_return;
-		res = get_proto_attr(ist, ref_self, ref_key->data.ptr, &proto, cont);
+		res = get_proto_attr(ist, ref_self, ref_key->body->data.ptr, &proto, cont);
 		if (!res) {
 			raise_exception(ist, OBJ(NAME_EXC), "Super attribute %s not found",
-					                             symch(ist, ref_key->data.ptr));
+					                             symch(ist, ref_key->body->data.ptr));
 			return;
 		}
-		set_attr(ist, proto, ref_key->data.ptr, value);
+		set_attr(ist, proto, ref_key->body->data.ptr, value);
 	} else
 		raise_exception(ist, OBJ(INTERNAL_EXC), "Invalid reference type");
 }
@@ -368,7 +368,7 @@
 		if_exc_return;
 		del_attr(ist, ref_self, ref_key);
 	} else if (has_proto(ist, ref_key, OBJ(LOCAL_PROTO))) {
-		del_attr(ist, ref_self, ref_key->data.ptr);
+		del_attr(ist, ref_self, ref_key->body->data.ptr);
 	} else if (has_proto(ist, ref_key, OBJ(SLICE_PROTO))) {
 		obj_p param[2];  
 		param[0]=OBJ(NOKEY); param[1]=ref_key;
@@ -376,13 +376,13 @@
 	} else if (has_proto(ist, ref_key, OBJ(OUTER_PROTO))) {
 		obj_p scope_obj;
 		if_exc_return;
-        get_scope_attr(ist, ref_self, ref_key->data.ptr, &scope_obj, ref_self);
+        get_scope_attr(ist, ref_self, ref_key->body->data.ptr, &scope_obj, ref_self);
 		if (!scope_obj) {
-			raise_exception(ist, OBJ(INTERPRETER_EXC), "outer.%s not found", as_str(ist, ref_key->data.ptr));
+			raise_exception(ist, OBJ(INTERPRETER_EXC), "outer.%s not found", as_str(ist, ref_key->body->data.ptr));
 			return;
 		}
 		if_exc_return;
-		del_attr(ist, scope_obj, ref_key->data.ptr);
+		del_attr(ist, scope_obj, ref_key->body->data.ptr);
 	} else if (has_proto(ist, ref_key, OBJ(INT_PROTO))) {
 		obj_p param[2];  
 		param[0]=OBJ(NOKEY); param[1]=slice1(ref_key);
@@ -391,17 +391,17 @@
 		obj_p res, proto, cont = get_attr(ist, ref_key, SYM(CONT_));
 		if (!cont) {
 			raise_exception(ist, OBJ(NAME_EXC), "Container obj for attribute %s not found",
-					                             symch(ist, ref_key->data.ptr));
+					                             symch(ist, ref_key->body->data.ptr));
 			return;
 		}
 		if_exc_return;
-		res = get_proto_attr(ist, ref_self, ref_key->data.ptr, &proto, cont);
+		res = get_proto_attr(ist, ref_self, ref_key->body->data.ptr, &proto, cont);
 		if (!res) {
 			raise_exception(ist, OBJ(NAME_EXC), "Super attribute %s not found",
-					                             symch(ist, ref_key->data.ptr));
+					                             symch(ist, ref_key->body->data.ptr));
 			return;
 		}
-		del_attr(ist, proto, ref_key->data.ptr);
+		del_attr(ist, proto, ref_key->body->data.ptr);
 	} else
 		raise_exception(ist, OBJ(INTERNAL_EXC), "Invalid reference type");
 }
@@ -549,7 +549,7 @@
 		if (!parm) goto paramerr;
 		if (has_proto(ist, parm, OBJ(PARMPTR_PROTO))) {
 			obj_p eval_locals;
-			code_p codep = (void*)(((char*)func_obj->data.ptr)+parm->data.i64);
+			code_p codep = (void*)(((char*)func_obj->body->data.ptr)+parm->body->data.i64);
 			if (!func_obj) goto evalerr;
 			eval_locals = get_attr(ist, func_obj, SYM(PREVSCOPE_));
 			if (!eval_locals) goto evalerr;
@@ -1054,7 +1054,7 @@
 					for(i=0; i < param; i++) {
 						obj_p key = fr_stack[fr_sp+i*2+1];
 						if (has_proto(ist, key, OBJ(LOCAL_PROTO)))
-							key = key->data.ptr;
+							key = key->body->data.ptr;
 						set_attr(ist, fr_stack[fr_sp+i*2], key, list_item(ist, list, i));
 					}
 				} else {
@@ -1065,7 +1065,7 @@
 					}
 					key = fr_stack[fr_sp+1];
 					if (has_proto(ist, key, OBJ(LOCAL_PROTO)))
-						key = key->data.ptr;
+						key = key->body->data.ptr;
 					set_attr(ist, fr_stack[fr_sp], key, fr_stack[fr_sp]);
 				}
 			}	break;
@@ -1149,17 +1149,17 @@
 					apr_snprintf(dump_name, sizeof(dump_name),
 						     "!def_code_%s_%d.txt",
 						     as_str(ist, fr_stack[fr_sp+1]), cntr++);
-					dump_code(ist, func, func->data.ptr, dump_name);
+					dump_code(ist, func, func->body->data.ptr, dump_name);
 					set_attr(ist, func, SYM(NAME_), NEW_STRING(dump_name));
 				}
 #endif
 				if (op == OP_GEN) {
 					gen_p genp      = pr_malloc(sizeof(gen_t));
 					genp->frame     = NULL;
-					genp->codep     = func->data.ptr;
-					func->data.ptr  = NULL;
+					genp->codep     = func->body->data.ptr;
+					func->body->data.ptr  = NULL;
 					switch_proto(ist, func, OBJ(GEN_PROTO));
-					func->data.ptr  = genp;
+					func->body->data.ptr  = genp;
 				}
 				set_item(ist, fr_stack[fr_sp], fr_stack[fr_sp+1], func, FALSE);
 			}	break;
@@ -1305,10 +1305,10 @@
 						                            symch(ist, fr_data(1)) );
 					break;
 				}
-				if (func_obj->data_type == DATA_TYPE_EXTPTR) {
+				if (func_obj->body->data_type == DATA_TYPE_EXTPTR) {
 					obj_p res, self;
 					clist_p plist;
-					if (!func_obj->data.ptr) goto no_func_ptr;
+					if (!func_obj->body->data.ptr) goto no_func_ptr;
 					if ( !(self = fr_stack[fr_sp+1]) &&
 						 !(self = get_attr(ist, func_obj, SYM(BINDOBJ_))) &&
 						 !(self = frame->self) &&
@@ -1319,7 +1319,7 @@
 					plist = get_func_params(ist, func_obj, param*2, fr_stack+fr_sp+2);
 					IF_EXC_BREAK;
 					pre_call_lock(ist, self, plist); IF_EXC_BREAK;
-					res = ((pr_func*)(func_obj->data.ptr))
+					res = ((pr_func*)(func_obj->body->data.ptr))
 								(ist, self, 
 								(plist ? clist_len(plist) : 0), 
 								(plist ? (obj_p*)plist->items : NULL),
@@ -1333,7 +1333,7 @@
 					obj_p self;
 					frame_p new_frame;
 					IF_EXC_BREAK;
-					if (!func_obj->data.ptr) goto no_func_ptr;
+					if (!func_obj->body->data.ptr) goto no_func_ptr;
 					new_frame = get_frame_params( ist, &(frame->fparam_proc_state_idx), 
 						                               &(frame->fparam_proc_state), 
 									                   &(frame->new_locals), func_obj, param*2, fr_stack+fr_sp+2 );
@@ -1361,7 +1361,7 @@
 					switch_frame = new_frame;
 					fr_push(OBJ(NONE));
 				} else if (has_proto(ist, func_obj, OBJ(GEN_PROTO))) {
-					gen_p  genp  = func_obj->data.ptr;
+					gen_p  genp  = func_obj->body->data.ptr;
 					code_p codep = genp->codep;
 					frame_p new_frame = get_frame_params( ist, &(frame->fparam_proc_state_idx), 
 													   &(frame->fparam_proc_state), 
@@ -1432,7 +1432,7 @@
 				if (dump_module_code) dump_code_key = key;
 #endif			
 				if (has_proto(ist, key, OBJ(LOCAL_PROTO))) {
-					key = key->data.ptr;
+					key = key->body->data.ptr;
 				}
 				set_attr(ist, fr_stack[fr_sp], key, new_obj); IF_EXC_BREAK;
 				fr_push(new_obj);
@@ -1452,7 +1452,7 @@
 					else
 						apr_snprintf( dump_name, sizeof(dump_name),
 									"!with_code_%d.txt", with_num++ );
-					dump_code(ist, func, func->data.ptr, dump_name);
+					dump_code(ist, func, func->body->data.ptr, dump_name);
 					set_attr(ist, func, SYM(NAME_), NEW_STRING(dump_name));
 				}
 #else
@@ -1479,7 +1479,7 @@
 				}
 				if (has_proto(ist, name_obj, OBJ(SUPER_PROTO))) {
 					obj_p cont = get_attr(ist, name_obj, SYM(CONT_));
-					name_obj = name_obj->data.ptr;
+					name_obj = name_obj->body->data.ptr;
 					if (!cont) {
 						raise_exception( ist, OBJ(INTERNAL_EXC), "container not found for attribute %s", 
 							                                      symch(ist, name_obj) );
@@ -1489,12 +1489,12 @@
 					goto got_func;
 				}
 				if (has_proto(ist, name_obj, OBJ(LOCAL_PROTO))) {
-					name_obj = name_obj->data.ptr;
+					name_obj = name_obj->body->data.ptr;
 			 		func_obj = get_scope_attr(ist, fr_stack[fr_sp], name_obj, NULL, NULL);
 					goto got_func;
 				}
 				if (has_proto(ist, name_obj, OBJ(OUTER_PROTO))) {
-					name_obj = name_obj->data.ptr;
+					name_obj = name_obj->body->data.ptr;
 			 		func_obj = get_scope_attr(ist, fr_stack[fr_sp], name_obj, NULL, fr_stack[fr_sp]);
 					goto got_func;
 				}
@@ -1503,7 +1503,7 @@
 					break;
 				}
 				if (fr_stack[fr_sp+1] == SYM(NEXT) && has_proto(ist, fr_stack[fr_sp], OBJ(GEN_PROTO))) {
-					gen_p genp = fr_stack[fr_sp]->data.ptr;
+					gen_p genp = fr_stack[fr_sp]->body->data.ptr;
 					frame_p new_frame = genp->frame;
 					if (!new_frame) {
 						raise_exception(ist, OBJ(TYPE_EXC), "iterator not initialized");
@@ -1530,10 +1530,10 @@
 							as_str(ist, fr_stack[fr_sp+1]));
 					break;
 				}
-				if (func_obj->data_type == DATA_TYPE_EXTPTR){
+				if (func_obj->body->data_type == DATA_TYPE_EXTPTR){
 					clist_p plist;
 					obj_p res, self;
-					if (!func_obj->data.ptr) goto no_func_ptr2;
+					if (!func_obj->body->data.ptr) goto no_func_ptr2;
 					plist = get_func_params(ist, func_obj, param*2, fr_stack+fr_sp+3);
 					IF_EXC_BREAK;
 					if ( !(self = fr_stack[fr_sp+2]) &&
@@ -1547,7 +1547,7 @@
 					IF_EXC_BREAK;
 					pre_call_lock(ist, self, plist);  IF_EXC_BREAK;
 					pr_assert(sizeof(obj_p) == sizeof(clist_item_t));
-					res = ((pr_func*)(func_obj->data.ptr))
+					res = ((pr_func*)(func_obj->body->data.ptr))
 								(ist, self, 
 								(plist ? clist_len(plist) : 0), 
 								(plist ? (obj_p*)plist->items : NULL),
@@ -1561,7 +1561,7 @@
 					obj_p self;
 					frame_p new_frame;
 					IF_EXC_BREAK;
-					if (!func_obj->data.ptr) goto no_func_ptr2;
+					if (!func_obj->body->data.ptr) goto no_func_ptr2;
 					new_frame = get_frame_params( ist, &(frame->fparam_proc_state_idx), 
 													   &(frame->fparam_proc_state), 
 									                   &(frame->new_locals), func_obj, param*2, fr_stack+fr_sp+3);
@@ -1590,7 +1590,7 @@
 					switch_frame = new_frame;
 					fr_push(OBJ(NONE));
 				} else if (has_proto(ist, func_obj, OBJ(GEN_PROTO))) {
-					gen_p  genp  = func_obj->data.ptr;
+					gen_p  genp  = func_obj->body->data.ptr;
 					code_p codep = genp->codep;
 					frame_p new_frame;
 					IF_EXC_BREAK;
@@ -1758,7 +1758,7 @@
 				stack_lim = frame->code->max_stack_depth;
 				// free_frame(tmp_frame);  XXX
 				if (tmp_frame->gen_marker) {
-					gen_p genp = tmp_frame->gen_marker->data.ptr;
+					gen_p genp = tmp_frame->gen_marker->body->data.ptr;
 					genp->frame = NULL;
 				}
 				if (!tmp_frame->do_not_free)
@@ -1862,7 +1862,7 @@
 				pr_exit(1);
 			}
 			if (func_sym == SYM(NEXT) && has_proto(ist, self, OBJ(GEN_PROTO))) {
-					gen_p genp = self->data.ptr;
+					gen_p genp = self->body->data.ptr;
 					new_frame = genp->frame;
 					if (!new_frame) {
 						raise_exception(ist, OBJ(STOP_ITERATION_EXC), NULL);
@@ -1877,13 +1877,13 @@
 			return NULL;
 		}
 	}
-	if (func_obj->data_type == DATA_TYPE_EXTPTR) {
+	if (func_obj->body->data_type == DATA_TYPE_EXTPTR) {
 		obj_p res, aself;
 		clist_p plist = get_func_params( ist, func_obj, parm_cnt, lbl_val_arr);
 		if (! (aself = get_attr(ist, func_obj, SYM(BINDOBJ_))) )
 			aself = self;     if_exc_return 0;
 		pre_call_lock(ist, aself, plist); if (intrp_exobj) { str_chk_clr(ist, ist->frame); return NULL; }
-		res = ((pr_func*)(func_obj->data.ptr)) 
+		res = ((pr_func*)(func_obj->body->data.ptr)) 
 								(ist, aself, (plist ? clist_len(plist) : 0), 
 								(plist ? (obj_p*)plist->items : NULL), super_obj);
 		post_call_unlock(ist, aself, plist);
@@ -2118,7 +2118,7 @@
 #endif
 
 	thread_obj = register_thread(handle);
-	thread_p = thread_obj->data.ptr;
+	thread_p = thread_obj->body->data.ptr;
 	ist = thread_p->ist;
 
 	pr_lock(&start_main_lock);
@@ -2185,7 +2185,7 @@
 	obj_p new_locals, lbl_val_arr[MAX_NUM_PARAMS]; 
 	int i, parm_cnt;
 	obj_p thread_obj = register_thread(handle);
-	pr_thread_p thread_p = thread_obj->data.ptr;
+	pr_thread_p thread_p = thread_obj->body->data.ptr;
 	isp ist = thread_p->ist;
 	int idx = -1;
 	fparam_proc_state_t fps;

Modified: trunk/src/lock.c
===================================================================
--- trunk/src/lock.c	2004-07-17 08:33:55 UTC (rev 748)
+++ trunk/src/lock.c	2004-07-18 04:26:50 UTC (rev 749)
@@ -107,7 +107,7 @@
 void delete_notify(isp ist, obj_p obj){
 	int del_notify;
 	get_wrlock(obj, FALSE);
-	del_notify = obj->del_notify;
+	del_notify = obj->body->del_notify;
 	free_wrlock(obj);
 	if (del_notify) {
 		del_notify_lock();
@@ -137,9 +137,9 @@
 		set_attr(ist, obj, SYM(NOTIFYCALLBACK_), callback_list);
 done:
 	get_wrlock(obj, FALSE);
-	if (flags & READ_NOTIFY)   obj->rd_notify = TRUE;
-	if (flags & WRITE_NOTIFY)  obj->wr_notify = TRUE;
-	if (flags & DELETE_NOTIFY) obj->del_notify = TRUE;
+	if (flags & READ_NOTIFY)   obj->body->rd_notify = TRUE;
+	if (flags & WRITE_NOTIFY)  obj->body->wr_notify = TRUE;
+	if (flags & DELETE_NOTIFY) obj->body->del_notify = TRUE;
 	free_wrlock(obj);
 }
 
@@ -150,7 +150,7 @@
 	obj_p callback_list = get_attr(ist, obj, SYM(NOTIFYCALLBACK_));
 	if (!callback_list) return;
 	write_lock(ist, callback_list);
-	selfp = callback_list->data.ptr;
+	selfp = callback_list->body->data.ptr;
 	while (TRUE) {
 		llen  = (int) lstplen(selfp);
 		for (i=0; i < llen; i += 2)
@@ -167,9 +167,9 @@
 	for(i=0; i < llen; i += 2)
 		flags |= int2i32t(ist, list_item(ist, callback_list, i));
 	get_wrlock(obj, FALSE);
-	if (flags & READ_NOTIFY)   obj->rd_notify  = TRUE; else obj->rd_notify  = FALSE; 
-	if (flags & WRITE_NOTIFY)  obj->wr_notify  = TRUE; else obj->wr_notify  = FALSE;
-	if (flags & DELETE_NOTIFY) obj->del_notify = TRUE; else obj->del_notify = FALSE;
+	if (flags & READ_NOTIFY)   obj->body->rd_notify  = TRUE; else obj->body->rd_notify  = FALSE; 
+	if (flags & WRITE_NOTIFY)  obj->body->wr_notify  = TRUE; else obj->body->wr_notify  = FALSE;
+	if (flags & DELETE_NOTIFY) obj->body->del_notify = TRUE; else obj->body->del_notify = FALSE;
 	free_wrlock(obj);
 }
 
@@ -191,17 +191,17 @@
 //********************************* read_lock_try *****************************
 int read_lock_try(isp ist, obj_p obj) {
 	if (!lock((obj)->wrlock)) return FALSE;
-	if (ist->access < obj->rd_access) {
+	if (ist->access < obj->body->rd_access) {
 		raise_exception(ist, OBJ(PERMISSION_EXC), "read-try permission exception");
 		free_wrlock(obj);
 		return FALSE;
 	}
-	if (obj->rd_notify) {
+	if (obj->body->rd_notify) {
 		free_wrlock(obj);
 		notify(ist, obj, READ_NOTIFY);
 		get_wrlock(obj, NO_WAIT);
 	}
-	if (obj->immutable) {
+	if (obj->body->immutable) {
 		free_wrlock(obj);
 		return TRUE;
 	}
@@ -219,17 +219,17 @@
 //********************************* read_lock *********************************
 int read_lock(isp ist, obj_p obj) {
 	get_wrlock(obj, NO_WAIT);
-	if (ist->access < obj->rd_access) {
+	if (ist->access < obj->body->rd_access) {
 		raise_exception(ist, OBJ(PERMISSION_EXC), "read permission exception");
 		free_wrlock(obj);
 		return TRUE;
 	}
-	if (obj->rd_notify) {
+	if (obj->body->rd_notify) {
 		free_wrlock(obj);
 		notify(ist, obj, READ_NOTIFY);
 		get_wrlock(obj, NO_WAIT);
 	}
-	if (obj->immutable) {
+	if (obj->body->immutable) {
 		free_wrlock(obj);
 		return FALSE;
 	}
@@ -250,7 +250,7 @@
 void read_unlock(isp ist, obj_p obj) {
 	int	write_ready_flag;
 	get_wrlock(obj, NO_WAIT);
-	if (obj->immutable) {
+	if (obj->body->immutable) {
 		free_wrlock(obj);
 		return;
 	}
@@ -268,12 +268,12 @@
 //********************************* write_lock_try ****************************
 int write_lock_try(isp ist, obj_p obj) {
 	if (!lock((obj)->wrlock)) return FALSE;
-	if (ist->access < obj->wr_access) {
+	if (ist->access < obj->body->wr_access) {
 		raise_exception(ist, OBJ(PERMISSION_EXC), "write-try permission exception");
 		free_wrlock(obj);
 		return FALSE;
 	}
-	if (obj->immutable) {
+	if (obj->body->immutable) {
 		raise_exception(ist, OBJ(LOCK_EXC), "write_lock attempted on an immutable object");
 		free_wrlock(obj);
 		return FALSE;
@@ -289,12 +289,12 @@
 int write_lock(isp ist, obj_p obj) {
 	int sav_cnt = 0;
 	get_wrlock(obj, NO_WAIT);
-	if (ist->access < obj->wr_access) {
+	if (ist->access < obj->body->wr_access) {
 		raise_exception(ist, OBJ(PERMISSION_EXC), "write permission exception");
 		free_wrlock(obj);
 		return TRUE;
 	}
-	if (obj->immutable) {
+	if (obj->body->immutable) {
 		raise_exception(ist, OBJ(LOCK_EXC), "write_lock attempted on an immutable object");
 		free_wrlock(obj);
 		return TRUE;
@@ -323,9 +323,9 @@
 //********************************* write_unlock ******************************
 void write_unlock(isp ist, obj_p obj) {
 	int write_ready_flag, write_notify_flag;
-	if (obj->immutable) return;
+	if (obj->body->immutable) return;
 	pr_assert(obj->wrlock);
-	obj->archived = FALSE;
+	obj->body->archived = FALSE;
 	obj->state = OBJ_STATE_NEW_OR_MARKED;
 	if (mem_mgr_phase == MM_PHASE_MARKING && obj->scanned) {
 		obj->scanned = FALSE;
@@ -335,7 +335,7 @@
 		pr_unlock(&to_be_scanned_list_lock);
 	}
 	write_ready_flag  = obj->wrlock_req_cnt;
-	write_notify_flag = obj->wr_notify;
+	write_notify_flag = obj->body->wr_notify;
 	free_wrlock(obj);
 	if (write_ready_flag)  apr_thread_cond_broadcast(write_cond);
 	if (write_notify_flag) notify(ist, obj, WRITE_NOTIFY);

Modified: trunk/src/main.c
===================================================================
--- trunk/src/main.c	2004-07-17 08:33:55 UTC (rev 748)
+++ trunk/src/main.c	2004-07-18 04:26:50 UTC (rev 749)
@@ -147,7 +147,7 @@
 	main_argv_obj = get_attr(ist, sys_argv_obj, sym(ist, "argV"));
 	if (main_argv_obj && list_len(ist, main_argv_obj)) {
 		main1_thread_obj = new_thread_obj(ist, (apr_thread_start_t)main_thread, main_argv_obj, NULL, ACC_USER2);
-		main1_thread_ptr = main1_thread_obj->data.ptr;
+		main1_thread_ptr = main1_thread_obj->body->data.ptr;
 		if (cmd_line_option_i_flg) 
 			main1_thread_ptr->save_frame = TRUE;
 	}
@@ -159,7 +159,7 @@
 			obj_p thrd_argv = list_item(ist, threads, i);
 			obj_p acc_level = get_attr(ist, thrd_argv, SYM(ACCLEVEL_));  if_exc_return 0;
 			new_thread_obj( ist, (apr_thread_start_t) main_thread, thrd_argv, 
-				            NULL, (int) acc_level->data.i64 );
+				            NULL, (int) acc_level->body->data.i64 );
 		}
 	}
 	if (!disable_mem_mgr)

Modified: trunk/src/memory_mgr.c
===================================================================
--- trunk/src/memory_mgr.c	2004-07-17 08:33:55 UTC (rev 748)
+++ trunk/src/memory_mgr.c	2004-07-18 04:26:50 UTC (rev 749)
@@ -90,7 +90,7 @@
 //********************************* mm_read_lock *********************************
 int mm_read_lock(isp ist, obj_p obj) {
 	get_wrlock(obj, NO_WAIT);
-	if (obj->immutable) {
+	if (obj->body->immutable) {
 		free_wrlock(obj);
 		return FALSE;
 	}
@@ -135,7 +135,7 @@
 //********************************* mem_mgr_thread ******************************
 void *mem_mgr_thread(apr_thread_t *handle, void *dummy) {
 	obj_p thread_obj = register_thread(handle);
-	pr_thread_p thread_p = thread_obj->data.ptr;
+	pr_thread_p thread_p = thread_obj->body->data.ptr;
 	isp ist = thread_p->ist;
 	int i;
 
@@ -204,9 +204,9 @@
 				pr_assert(FALSE);
 			}
 			mm_read_lock(ist, obj);
-			if (obj->has_attrs) {
+			if (obj->body->has_attrs) {
 				int i;
-				attr_p attrs = obj->attr_proto.attrs;
+				attr_p attrs = obj->body->attr_proto.attrs;
 				for(i=ATTRS_OVERHEAD; i < ATTRS_OVERHEAD+attr_plen(attrs); i++){
 					val = attrs[i].attr.value;
 					if(val > min_obj && val != obj && !val->scanned) {
@@ -234,7 +234,7 @@
 					}
 				}
 			}
-			if (obj->data_type == DATA_TYPE_DATAPTR) {
+			if (obj->body->data_type == DATA_TYPE_DATAPTR) {
 				obj_p obj_list;
 				if (ist->exception_obj)
 					i=0;

Added: trunk/src/ob_malloc.c
===================================================================
--- trunk/src/ob_malloc.c	2004-07-17 08:33:55 UTC (rev 748)
+++ trunk/src/ob_malloc.c	2004-07-18 04:26:50 UTC (rev 749)
@@ -0,0 +1,208 @@
+/* ====================================================================
+ * The Prothon License Agreement, Version 1.1
+ *
+ * Copyright (c) 2004 Hahn Creative Applications, http://hahnca.com.
+ * All rights reserved. 
+ *
+ * 1. This LICENSE AGREEMENT is between Hahn Creative Applications ("HCA"),
+ * and the Individual or Organization ("Licensee") accessing and otherwise
+ * using Prothon software in source or binary form and its associated
+ * documentation.
+ * 
+ * 2. Subject to the terms and conditions of this License Agreement, HCA
+ * hereby grants Licensee a nonexclusive, royalty-free, world-wide license
+ * to reproduce, analyze, test, perform and/or display publicly, prepare
+ * derivative works, distribute, and otherwise use Prothon alone or in any
+ * derivative version, provided, however, that HCA's License Agreement and
+ * HCA's notice of copyright, i.e., "Copyright (c) 2004 Hahn Creative
+ * Applications; All Rights Reserved" are retained in Prothon alone or
+ * in any derivative version prepared by Licensee.
+ * 
+ * 3. In the event Licensee prepares a derivative work that is based on or
+ * incorporates Prothon or any part thereof, and wants to make the
+ * derivative work available to others as provided herein, then Licensee
+ * hereby agrees to include in any such work a brief summary of the
+ * changes made to Prothon.
+ * 
+ * 4. HCA is making Prothon available to Licensee on an "AS IS" basis.
+ * HCA MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.  BY WAY
+ * OF EXAMPLE, BUT NOT LIMITATION, HCA MAKES NO AND DISCLAIMS ANY
+ * REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY
+ * PARTICULAR PURPOSE OR THAT THE USE OF PROTHON WILL NOT INFRINGE ANY
+ * THIRD PARTY RIGHTS.
+ * 
+ * 5. HCA SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PROTHON
+ * FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A
+ * RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PROTHON, OR ANY
+ * DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
+ * 
+ * 6. This License Agreement will automatically terminate upon a material
+ * breach of its terms and conditions.
+ * 
+ * 7. Nothing in this License Agreement shall be deemed to create any
+ * relationship of agency, partnership, or joint venture between HCA and
+ * Licensee.  This License Agreement does not grant permission to use HCA
+ * trademarks or trade name in a trademark sense to endorse or promote
+ * products or services of Licensee, or any third party.
+ * 
+ * 8. By copying, installing or otherwise using Prothon, Licensee agrees
+ * to be bound by the terms and conditions of this License Agreement.
+ * ====================================================================
+ */
+
+// file: ob_malloc.c
+
+#include "object.h"
+
+#undef  uchar
+#define uchar			u8_t	/* assuming == 8 bits  */
+#undef  ushort
+#define ushort			u16_t	/* assuming >= 16 bits */
+#undef  uint
+#define uint			u32_t	/* assuming >= 16 bits */
+#undef  ulong
+#define ulong			u32_t	/* assuming >= 32 bits */
+
+
+typedef struct pool_hdr_s {
+	struct pool_hdr_s*	next;
+	struct pool_hdr_s*	prev;
+	uchar*				free;
+	u32_t				magic;
+	u16_t				count;
+	u16_t				capacity;
+	u16_t				is_body;
+} pool_hdr_t;
+
+typedef pool_hdr_t* pool_hdr_p;
+
+#undef  ROUNDUP
+#define ROUNDUP(x)		 (((x) + 3) & ~3)
+#define POOL_HDR_SIZE	 ROUNDUP(sizeof(pool_hdr_t))
+#define OBJP_SIZE		 ROUNDUP(sizeof(obj_t))
+#define OBJB_SIZE		 ROUNDUP(sizeof(objb_t))
+
+#define POOL_SIZE	     (4 * 1024)
+#define POOL_SIZE_MASK	 (POOL_SIZE - 1)
+#define ARENA_SIZE		 (256 * 1024 - POOL_SIZE)	/* 256k - 1p */
+#define ARENA_NB_POOLS	 (ARENA_SIZE / POOL_SIZE)
+
+#define POOL_MAGIC		  0x82dc3a7d
+
+DECLARE_PR_LOCK(ob_malloc_lock);
+#define LOCK()	 pr_lock(&ob_malloc_lock)
+#define UNLOCK() pr_unlock(&ob_malloc_lock)
+
+static uint  obj_size[2] = {OBJP_SIZE, OBJB_SIZE};
+static uint  arena_cnt   = 0;		        /* number of allocated arenas */
+static uint  watermark   = ARENA_NB_POOLS;	/* number of pools allocated from the current arena */
+static uchar* arenalist  = NULL;		    /* list of allocated arenas */
+static uchar* arenaproto = NULL;		    /* free space start address in current arena */
+
+static pool_hdr_p obj_inuse[4] = { (pool_hdr_p)&obj_inuse[0], (pool_hdr_p)&obj_inuse[0], 
+                                   (pool_hdr_p)&obj_inuse[2], (pool_hdr_p)&obj_inuse[2] };
+
+static pool_hdr_p freepools = NULL;
+
+uchar* ob_malloc(int is_body) {
+	uchar* res;
+	pool_hdr_p pool, next;
+	LOCK();
+	pool = obj_inuse[is_body*2];
+	if (pool->next != pool) {
+		pool->count++;
+		res = pool->free;
+		if ((pool->free = *(uchar**)res) != NULL) {
+			UNLOCK();
+			return res;
+		}
+		if (pool->count < pool->capacity) {
+			pool->free = (uchar*)pool + POOL_HDR_SIZE + pool->count * obj_size[is_body];
+			*(uchar**)(pool->free) = NULL;
+			UNLOCK();
+			return res;
+		}
+		next = pool->next;
+		pool = pool->prev;
+		next->prev = pool;
+		pool->next = next;
+		UNLOCK();
+		return res;
+	}
+	pool = freepools;
+	if (pool != NULL) {
+		freepools = pool->next;
+init_pool:
+		next = obj_inuse[is_body*2];
+		pool->next = next;
+		pool->prev = next;
+		next->next = pool;
+		next->prev = pool;
+		pool->magic = POOL_MAGIC;
+		pool->count = 1;
+		pool->is_body = is_body;
+		res = (uchar*)pool + POOL_HDR_SIZE;
+		pool->free = res + obj_size[is_body];
+		*(uchar**)(pool->free) = NULL;
+		pool->capacity = (POOL_SIZE - POOL_HDR_SIZE) / obj_size[is_body];
+		UNLOCK();
+		return res;
+	}
+	if (watermark < ARENA_NB_POOLS) {
+commit_pool:
+		watermark++;
+		pool = (pool_hdr_p )arenaproto;
+		arenaproto += POOL_SIZE;
+		goto init_pool;
+	}
+	res = malloc(ARENA_SIZE + POOL_SIZE);
+	if (res == NULL) {
+		UNLOCK();
+		return malloc(sizeof(obj_t));
+	}
+	*(uchar**)res = arenalist;
+	arenalist = res;
+	arena_cnt++;
+	watermark = 0;
+	arenaproto = res + (POOL_SIZE - ((size_t)res & POOL_SIZE_MASK));
+	goto commit_pool;
+}
+
+void ob_free(void *p) {
+	pool_hdr_p pool, next, prev;
+	size_t offset;
+	int is_body;
+
+	if (p == NULL) return;
+	offset = (size_t) p & POOL_SIZE_MASK;
+	pool = (pool_hdr_p )((uchar*)p - offset);
+	pr_assert(pool->magic == POOL_MAGIC);
+
+	LOCK();
+	if ((*(uchar**)p = pool->free) == NULL) {
+		pool->free = (uchar*)p;
+		--pool->count;
+		is_body = pool->is_body;
+		next = obj_inuse[is_body*2];
+		prev = next->prev;
+		pool->next = next;
+		pool->prev = prev;
+		next->prev = pool;
+		prev->next = pool;
+		UNLOCK();
+		return;
+	}
+	pool->free = (uchar*)p;
+	if (--pool->count != 0) {
+		UNLOCK();
+		return;
+	}
+	next = pool->next;
+	prev = pool->prev;
+	next->prev = prev;
+	prev->next = next;
+	pool->next = freepools;
+	freepools = pool;
+	UNLOCK();
+	return;
+}


Property changes on: trunk/src/ob_malloc.c
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: trunk/src/object.c
===================================================================
--- trunk/src/object.c	2004-07-17 08:33:55 UTC (rev 748)
+++ trunk/src/object.c	2004-07-18 04:26:50 UTC (rev 749)
@@ -214,7 +214,7 @@
 
 	/* Setup the core objects. Order counts here */
 	OBJ(OBJECT)             = NEW_OBJ(NULL);
-	OBJ(OBJECT)->attr_proto.proto = OBJ(OBJECT);
+	OBJ(OBJECT)->body->attr_proto.proto = OBJ(OBJECT);
 
 	OBJ(PR_FALSE)           = NEW_OBJ(NULL);
 	OBJ(PR_TRUE)            = NEW_OBJ(NULL);
@@ -286,23 +286,24 @@
 
 obj_p debug_object(obj_p obj) {
 	debug_obj = obj;
-	debug_obj_proto = obj->attr_proto.proto;
+	debug_obj_proto = obj->body->attr_proto.proto;
 	return obj;
 }
 
 //********************************* new_object ********************************
 obj_p new_object(isp ist, obj_p proto){
-	obj_p obj = pr_malloc(sizeof(obj_t));
-	if (obj == (obj_p) 0xa192f0) 
-		memset(obj, 0, sizeof(obj_t));
+	obj_p  obj  = (obj_p)  ob_malloc(0);
+	objb_p objb = (objb_p) ob_malloc(1);
 	memset(obj, 0, sizeof(obj_t));
+	memset(objb, 0, sizeof(objb_t));
+	obj->body = objb;
 	if (!proto) proto = OBJ(OBJECT);
-	obj->rd_access = ACC_GUEST;
+	obj->body->rd_access = ACC_GUEST;
 	if (ist)
-		obj->wr_access = ist->access;
+		obj->body->wr_access = ist->access;
 	else
-		obj->wr_access = ACC_SYSTEM;
-	obj->attr_proto.proto = proto;
+		obj->body->wr_access = ACC_SYSTEM;
+	obj->body->attr_proto.proto = proto;
 	lock_init(obj->wrlock);
 	obj->del_locked = TRUE;
 	pr_lock(&object_list_lock);
@@ -315,23 +316,19 @@
 //********************************* copy_object_data **************************
 // clobbers data section of dest (copy) object
 void copy_object_data(isp ist, obj_p copy, obj_p obj) {
-	int wrlock_req_cnt;
 	attr_p new_attrp, attrp;
-	wrlock_rtrn(obj);
-	if_wrlock(copy) { write_unlock(ist, obj); return; }
-	wrlock_req_cnt = copy->wrlock_req_cnt;
-	memcpy(copy, obj, sizeof(*obj)-2*sizeof(obj->next_obj));
-	copy->data = obj->data;
-	copy->wrlock_req_cnt = wrlock_req_cnt;
-	if (obj->has_attrs) {
+	rdlock_rtrn(obj);
+	if_wrlock(copy) { read_unlock(ist, obj); return; }
+	memcpy(copy->body, obj->body, sizeof(objb_t));
+	if (copy->body->has_attrs) {
 		size_t size;
-		attrp = obj->attr_proto.attrs;
+		attrp = obj->body->attr_proto.attrs;
 		size = attr_tsize(attrp)*sizeof(attr_t);
-		copy->attr_proto.attrs = new_attrp = pr_malloc(size);
+		copy->body->attr_proto.attrs = new_attrp = pr_malloc(size);
 		memcpy(new_attrp, attrp, size);
 	}
 	write_unlock(ist, copy);
-	write_unlock(ist, obj);
+	read_unlock(ist, obj);
 }
 
 //********************************* copy_object ******************************
@@ -339,21 +336,18 @@
 obj_p copy_object(isp ist, obj_p obj) {
 	obj_p copy;
 	attr_p new_attrp, attrp;
+	rdlock_rtrn(obj) NULL;
 	copy = NEW_OBJ(NULL);
-	memcpy(copy, obj, sizeof(*obj)-2*sizeof(obj->next_obj));
-	copy->data = obj->data;
-	copy->archived       = FALSE;
-	copy->del_locked     = TRUE;
-	copy->rdlock_cnt     = 0;
-	copy->wrlock_req_cnt = 0;
-	copy->wrlock		  = 0;
-	if (obj->has_attrs) {
+	memcpy(copy->body, obj->body, sizeof(objb_t));
+	copy->body->archived = FALSE;
+	if (copy->body->has_attrs) {
 		size_t size;
-		attrp = obj->attr_proto.attrs;
+		attrp = obj->body->attr_proto.attrs;
 		size = attr_tsize(attrp)*sizeof(attr_t);
-		copy->attr_proto.attrs = new_attrp = pr_malloc(size);
+		copy->body->attr_proto.attrs = new_attrp = pr_malloc(size);
 		memcpy(new_attrp, attrp, size);
 	}
+	read_unlock(ist, obj);
 	return copy;
 }
 
@@ -361,8 +355,8 @@
 void obj_set_data_owner(isp ist, obj_p obj, obj_p owner) {
 	attr_p attrp;
 	int i, numprotos, owner_set = FALSE; 
-	if (obj == owner || !obj->has_attrs) return;
-	attrp = obj->attr_proto.attrs;
+	if (obj == owner || !obj->body->has_attrs) return;
+	attrp = obj->body->attr_proto.attrs;
 	numprotos = attr_plen(attrp);
 	for (i=0; i < numprotos; i++) {
 		obj_p proto = attr_proto_item(attrp, i);
@@ -378,11 +372,11 @@
 	attr_p attrp;
 	obj_p owner = NULL;
 	int i, numprotos, res; 	
-	if (obj->data_type == DATA_TYPE_NONE) return FALSE;
+	if (obj->body->data_type == DATA_TYPE_NONE) return FALSE;
 	if (proto == obj) return TRUE;
-	if (!obj->has_attrs) owner = obj->attr_proto.proto;
+	if (!obj->body->has_attrs) owner = obj->body->attr_proto.proto;
 	else {
-		attrp = obj->attr_proto.attrs;
+		attrp = obj->body->attr_proto.attrs;
 		numprotos = attr_plen(attrp);
 		for (i=0; i < numprotos; i++)
 			if (attr_pp(attrp, i)->proto.owns_binary) {
@@ -400,24 +394,27 @@
 
 //********************************* free_object *******************************
 void free_object(obj_p obj) {
-	if (obj->has_attrs)
-		pr_free(obj->attr_proto.attrs);
-	if (obj->data_type == DATA_TYPE_DATAPTR)
-		pr_free(obj->data.ptr);
-	pr_free(obj);
+	if (obj->body->has_attrs)
+		pr_free(obj->body->attr_proto.attrs);
+	if (obj->body->data_type == DATA_TYPE_DATAPTR)
+		pr_free(obj->body->data.ptr);
+	if (obj->saved_body)
+		pr_free(obj->saved_body);
+	ob_free(obj->body);
+	ob_free(obj);
 }
 
 //********************************* set_immutable *****************************
 void set_immutable(obj_p obj){
 	get_wrlock(obj, NO_WAIT);
-	obj->immutable = TRUE; 
+	obj->body->immutable = TRUE; 
 	free_wrlock(obj);
 }
 
 //********************************* clr_immutable *****************************
 void clr_immutable(obj_p obj){
 	get_wrlock(obj, NO_WAIT);
-	obj->immutable = FALSE; 
+	obj->body->immutable = FALSE; 
 	free_wrlock(obj);
 }
 
@@ -425,7 +422,7 @@
 int is_immutable(obj_p obj) {
 	int res;
 	get_wrlock(obj, NO_WAIT);
-	res = obj->immutable;
+	res = obj->body->immutable;
 	free_wrlock(obj);
 	return res;
 }
@@ -433,14 +430,14 @@
 //********************************* set_unclonable ****************************
 void set_unclonable(obj_p obj){
 	get_wrlock(obj, NO_WAIT);
-	obj->unclonable = TRUE; 
+	obj->body->unclonable = TRUE; 
 	free_wrlock(obj);
 }
 
 //********************************* clr_unclonable ****************************
 void clr_unclonable(obj_p obj){
 	get_wrlock(obj, NO_WAIT);
-	obj->unclonable = FALSE; 
+	obj->body->unclonable = FALSE; 
 	free_wrlock(obj);
 }
 
@@ -448,7 +445,7 @@
 int is_unclonable(obj_p obj) {
 	int res;
 	get_wrlock(obj, NO_WAIT);
-	res = obj->unclonable; 
+	res = obj->body->unclonable; 
 	free_wrlock(obj);
 	return res;
 }
@@ -456,14 +453,14 @@
 //********************************* set_archived ****************************
 void set_archived(obj_p obj){
 	get_wrlock(obj, NO_WAIT);
-	obj->archived = TRUE; 
+	obj->body->archived = TRUE; 
 	free_wrlock(obj);
 }
 
 //********************************* clr_archived ****************************
 void clr_archived(obj_p obj){
 	get_wrlock(obj, NO_WAIT);
-	obj->archived = FALSE; 
+	obj->body->archived = FALSE; 
 	free_wrlock(obj);
 }
 
@@ -471,7 +468,7 @@
 int is_archived(obj_p obj) {
 	int res;
 	get_wrlock(obj, NO_WAIT);
-	res = obj->archived; 
+	res = obj->body->archived; 
 	free_wrlock(obj);
 	return res;
 }
@@ -479,14 +476,14 @@
 //********************************* set_obj_rdacc *****************************
 void set_obj_rdacc(obj_p obj, int access) {
 	get_wrlock(obj, NO_WAIT);
-	obj->rd_access = access; 
+	obj->body->rd_access = access; 
 	free_wrlock(obj);
 }
 
 //********************************* set_obj_wracc *****************************
 void set_obj_wracc(obj_p obj, int access) {
 	get_wrlock(obj, NO_WAIT);
-	obj->wr_access = access; 
+	obj->body->wr_access = access; 
 	free_wrlock(obj);
 }
 
@@ -494,7 +491,7 @@
 int get_obj_rdacc(obj_p obj) {
 	int res;
 	get_wrlock(obj, NO_WAIT);
-	res = obj->rd_access;
+	res = obj->body->rd_access;
 	free_wrlock(obj);
 	return res;
 }
@@ -503,7 +500,7 @@
 int get_obj_wracc(obj_p obj) {
 	int res;
 	get_wrlock(obj, NO_WAIT);
-	res = obj->wr_access;
+	res = obj->body->wr_access;
 	free_wrlock(obj);
 	return res;
 }
@@ -523,7 +520,7 @@
 		apr_vsnprintf(err_buf, sizeof(err_buf), format, ap);
 		va_end(ap);
 
-		exc_obj->wr_access = ACC_GUEST;
+		exc_obj->body->wr_access = ACC_GUEST;
 
 		p = err_buf + strlen(err_buf) - 1;
 		while (*p == '.' || *p == ' ' || *p == '\t') { *p = 0; p--; }
@@ -556,9 +553,9 @@
 //********************************* get_attr *******************************
 obj_p get_attr(isp ist, obj_p obj, obj_p key) {
 	rdlock_rtrn(obj) NULL;
-	if (obj->has_attrs){
-		attr_p ptr, attrs = obj->attr_proto.attrs;
-		attr_key_t i, akey, tgt = key->data.key;
+	if (obj->body->has_attrs){
+		attr_p ptr, attrs = obj->body->attr_proto.attrs;
+		attr_key_t i, akey, tgt = key->body->data.key;
 		obj_p res;
 		for(i=tgt; (akey=((ptr=attr_ap(attrs, i))->attr.key)) && (tgt!=akey); i++);
 		if (akey) {
@@ -574,9 +571,9 @@
 //********************************* del_attr *******************************
 int del_attr(isp ist, obj_p obj, obj_p key) {
 	wrlock_rtrn(obj) FALSE;
-	if (obj->has_attrs){
-		attr_p ptr, attrs = obj->attr_proto.attrs;
-		attr_key_t i, akey, tgt = key->data.key;
+	if (obj->body->has_attrs){
+		attr_p ptr, attrs = obj->body->attr_proto.attrs;
+		attr_key_t i, akey, tgt = key->body->data.key;
 		for(i=tgt; (akey=((ptr=attr_ap(attrs, i))->attr.key)) && (tgt!=akey); i++);
 		if (akey) {
 			ptr->attr.key = ENTRY_DELETED;
@@ -591,18 +588,18 @@
 
 //********************************* add_attrs *********************************
 attr_p add_attrs(obj_p obj) {
-	obj_p proto = obj->attr_proto.proto;
+	obj_p proto = obj->body->attr_proto.proto;
 	attr_p attrs = pr_malloc(ATTRS_TINIT * sizeof(attr_t));
 	memset(attrs, 0, ATTRS_TINIT * sizeof(attr_t));
 	attr_psize(attrs)= ATTRS_PINIT;
 	attr_asize(attrs)= ATTRS_AINIT;
 	attr_plen(attrs) = 1;
 	attr_proto_item(attrs, 0) = proto;
-	if (obj->data_type != DATA_TYPE_NONE)
+	if (obj->body->data_type != DATA_TYPE_NONE)
 		attr_owns_bin(attrs, 0) = TRUE;
 	attr_alen(attrs) = 0;
-	obj->attr_proto.attrs = attrs;
-	obj->has_attrs   = TRUE;
+	obj->body->attr_proto.attrs = attrs;
+	obj->body->has_attrs   = TRUE;
 	return attrs;
 }
 
@@ -633,7 +630,7 @@
 			ptr->attr.value = old_attr->attr.value;
 		}
 	}
-	obj->attr_proto.attrs = attrs;
+	obj->body->attr_proto.attrs = attrs;
 	pr_free(old_attrs);
 	return attrs;
 }
@@ -641,12 +638,12 @@
 //********************************* set_attr **********************************
 void set_attr(isp ist, obj_p obj, obj_p key, obj_p value) {
 	attr_p attrs, ptr, hole=0;
-	attr_key_t i, akey, tgt = key->data.key;
+	attr_key_t i, akey, tgt = key->body->data.key;
 	if (tgt%3 != 0)
 		ptr = NULL;
 	pr_assert((tgt%3)==0);
 	wrlock_rtrn(obj);
-	if (obj->has_attrs) attrs = obj->attr_proto.attrs;
+	if (obj->body->has_attrs) attrs = obj->body->attr_proto.attrs;
 	else				attrs = add_attrs(obj);
 	if (((attr_alen(attrs) * 100) / attr_asize(attrs)) > ATTRS_MAX_PERCENT_FULL)
 		attrs = attrs_realloc(obj, attrs);
@@ -668,8 +665,8 @@
 	int i;
 	size_t asize;
 	attr_p attrp;
-	if (!obj->has_attrs) return 0;
-	attrp = obj->attr_proto.attrs;
+	if (!obj->body->has_attrs) return 0;
+	attrp = obj->body->attr_proto.attrs;
 	asize = attr_asize(attrp);
 	for (i=0; i < (int) asize; i++) {
 		if (attr_ap(attrp,i)->attr.key > 0)
@@ -680,8 +677,8 @@
 
 //********************************* attr_next_key *****************************
 attr_key_t attr_next_key(isp ist, obj_p obj, attr_key_t key) {
-	if (obj->has_attrs){
-		attr_p attrs = obj->attr_proto.attrs;
+	if (obj->body->has_attrs){
+		attr_p attrs = obj->body->attr_proto.attrs;
 		attr_key_t i, akey, tgt = key;
 		int asize = (int) attr_asize(attrs);
 		for(i=tgt; (akey=(attr_ap(attrs, i))->attr.key) && (tgt!=akey); i++);
@@ -695,8 +692,8 @@
 
 //********************************* attr_value_by_key *************************
 obj_p attr_value_by_key(isp ist, obj_p obj, attr_key_t key) {
-	if (obj->has_attrs){
-		attr_p ptr, attrs = obj->attr_proto.attrs;
+	if (obj->body->has_attrs){
+		attr_p ptr, attrs = obj->body->attr_proto.attrs;
 		attr_key_t i, akey, tgt = key;
 		for(i=tgt; (akey=((ptr=attr_ap(attrs, i))->attr.key)) && (tgt!=akey); i++);
 		if (akey) return ptr->attr.value;
@@ -709,16 +706,16 @@
 	attr_p attrs;
 	wrlock_rtrn(obj);
 	if (!proto_owns_binary(ist, new_proto, obj)) {
-		if (obj->data_type == DATA_TYPE_DATAPTR)
-			pr_free(obj->data.ptr);
-		obj->data_type = DATA_TYPE_NONE;
+		if (obj->body->data_type == DATA_TYPE_DATAPTR)
+			pr_free(obj->body->data.ptr);
+		obj->body->data_type = DATA_TYPE_NONE;
 	}
-	if (!(obj->has_attrs)) {
-		obj->attr_proto.proto = new_proto;
+	if (!(obj->body->has_attrs)) {
+		obj->body->attr_proto.proto = new_proto;
 		write_unlock(ist, obj);
 		return;
 	}
-	attrs = obj->attr_proto.attrs;
+	attrs = obj->body->attr_proto.attrs;
 	attr_plen(attrs) = 1;
 	attr_proto_item(attrs, 0) = new_proto;
 	write_unlock(ist, obj);
@@ -730,7 +727,7 @@
 	attr_p attrs;
 	i32_t i, len;
 	wrlock_rtrn(obj) FALSE;
-	if (obj->has_attrs) attrs = obj->attr_proto.attrs;
+	if (obj->body->has_attrs) attrs = obj->body->attr_proto.attrs;
 	else				attrs = add_attrs(obj);
 	len = attr_plen(attrs);
 	for (i=0; i < len; i++)
@@ -752,11 +749,11 @@
 	attr_p attrs;
 	i32_t i, len;
 	wrlock_rtrn(obj) FALSE;
-	if (!obj->has_attrs) {
+	if (!obj->body->has_attrs) {
 		write_unlock(ist, obj);
 		return FALSE;
 	}
-	attrs = obj->attr_proto.attrs;
+	attrs = obj->body->attr_proto.attrs;
 	len = attr_plen(attrs);
 	if (len < 2)  {
 		write_unlock(ist, obj);
@@ -765,9 +762,9 @@
 	for (i=0; i < len; i++)
 		if (attr_proto_item(attrs, i) == proto) {
 			if (attr_owns_bin(attrs, i)) {
-				if (obj->data_type == DATA_TYPE_DATAPTR)
-					pr_free(obj->data.ptr);
-				obj->data_type = DATA_TYPE_NONE;
+				if (obj->body->data_type == DATA_TYPE_DATAPTR)
+					pr_free(obj->body->data.ptr);
+				obj->body->data_type = DATA_TYPE_NONE;
 			}
 			if (i != len-1) 
 				memmove(attr_pp(attrs,i),attr_pp(attrs,i+1),((len-1)-i)*sizeof(attr_t));
@@ -783,11 +780,11 @@
 int proto_len(isp ist, obj_p obj){
 	int res;
 	rdlock_rtrn(obj) 0;
-	if (!obj->has_attrs) {
+	if (!obj->body->has_attrs) {
 		read_unlock(ist, obj);
 		return 1;
 	}
-	res = attr_plen(obj->attr_proto.attrs);
+	res = attr_plen(obj->body->attr_proto.attrs);
 	read_unlock(ist, obj);
 	return res;
 }
@@ -796,10 +793,10 @@
 obj_p proto_item(isp ist, obj_p obj, int i){
 	obj_p res;
 	rdlock_rtrn(obj) NULL;
-	if (!obj->has_attrs)
-		res = obj->attr_proto.proto;
+	if (!obj->body->has_attrs)
+		res = obj->body->attr_proto.proto;
 	else
-		res = attr_proto_item(obj->attr_proto.attrs, i);
+		res = attr_proto_item(obj->body->attr_proto.attrs, i);
 	read_unlock(ist, obj);
 	return res;
 }
@@ -865,7 +862,7 @@
 
 	rdlock_rtrn(obj) 0;
 
-	if ( (!obj->has_attrs && obj->attr_proto.proto == obj_proto) ||
+	if ( (!obj->body->has_attrs && obj->body->attr_proto.proto == obj_proto) ||
 		 obj_proto == OBJ(OBJECT) ) {
 		read_unlock(ist, obj);
 		return TRUE;
@@ -1035,35 +1032,35 @@
 	if (size <= sizeof(obj_data_t)){
 		SET_TYPE_IF_EXC(proto, obj, DATA_TYPE_IMMDATA) 
 			return NULL;
-		obj->imm_data_len = (int) size;
-		return &obj->data;
+		obj->body->imm_data_len = (int) size;
+		return &obj->body->data;
 	} else {
 		SET_TYPE_IF_EXC(proto, obj, DATA_TYPE_DATAPTR) return NULL;
-		obj->data.ptr  = pr_malloc(size);
-		return obj->data.ptr;
+		obj->body->data.ptr  = pr_malloc(size);
+		return obj->body->data.ptr;
 	}
 }
 
 //********************************* obj_realloc *******************************
 void* obj_realloc(isp ist, obj_p obj, size_t size){
 	wrlock_rtrn(obj) NULL;
-	if(obj->data_type == DATA_TYPE_DATAPTR){
+	if(obj->body->data_type == DATA_TYPE_DATAPTR){
 		if(size <= sizeof(obj_data_t)){
-			char* ptr = obj->data.ptr;
-			obj->data_type = DATA_TYPE_IMMDATA;
-			obj->imm_data_len = (int) size;
-			memcpy(&obj->data, ptr, size);
+			char* ptr = obj->body->data.ptr;
+			obj->body->data_type = DATA_TYPE_IMMDATA;
+			obj->body->imm_data_len = (int) size;
+			memcpy(&obj->body->data, ptr, size);
 			pr_free(ptr);
 		} else 
-			obj->data.ptr = pr_realloc(obj->data.ptr, size);
+			obj->body->data.ptr = pr_realloc(obj->body->data.ptr, size);
 	} else {
 		if(size <= sizeof(obj_data_t))
-			obj->imm_data_len = (int) size;
+			obj->body->imm_data_len = (int) size;
 		else {
 			char* ptr = pr_malloc(size);
-			memcpy(ptr, &obj->data, obj->imm_data_len);
-			obj->data_type = DATA_TYPE_DATAPTR;
-			obj->data.ptr = ptr;
+			memcpy(ptr, &obj->body->data, obj->body->imm_data_len);
+			obj->body->data_type = DATA_TYPE_DATAPTR;
+			obj->body->data.ptr = ptr;
 		}
 	}
 	write_unlock(ist, obj);
@@ -1073,10 +1070,10 @@
 //********************************* obj_free **********************************
 void obj_free(isp ist, obj_p obj) {
 	wrlock_rtrn(obj);
-	if(obj->data_type == DATA_TYPE_DATAPTR)
-		pr_free(obj->data.ptr);
-	obj->data.ptr = NULL;
-	obj->data_type = DATA_TYPE_NONE;
+	if(obj->body->data_type == DATA_TYPE_DATAPTR)
+		pr_free(obj->body->data.ptr);
+	obj->body->data.ptr = NULL;
+	obj->body->data_type = DATA_TYPE_NONE;
 	write_unlock(ist, obj);
 }
 
@@ -1085,10 +1082,10 @@
 obj_p new_hash_obj(isp ist, i32_t num) {
 	obj_p hash_obj = NEW_OBJ(OBJ(HASH_PROTO));
 	SET_TYPE_IF_EXC(OBJ(HASH_PROTO), hash_obj, DATA_TYPE_IMMDATA) return NULL;
-	hash_obj->imm_data_len = 4;
-	hash_obj->data.i32[0] = num & HASH_MASK;
-	if (!(hash_obj->data.i32[0])) hash_obj->data.i32[0] = 1;
-	hash_obj->immutable = TRUE;
+	hash_obj->body->imm_data_len = 4;
+	hash_obj->body->data.i32[0] = num & HASH_MASK;
+	if (!(hash_obj->body->data.i32[0])) hash_obj->body->data.i32[0] = 1;
+	hash_obj->body->immutable = TRUE;
 	return hash_obj;
 }
 
@@ -1124,8 +1121,8 @@
 //********************************* new_C_func_obj ******************************
 obj_p new_C_func_obj(isp ist, pr_func* func_ptr, obj_p label_values_list) {
 	obj_p func_obj = NEW_OBJ(OBJ(FUNC_PROTO));
-	func_obj->data_type = DATA_TYPE_EXTPTR;
-	func_obj->data.ptr = func_ptr;
+	func_obj->body->data_type = DATA_TYPE_EXTPTR;
+	func_obj->body->data.ptr = func_ptr;
 	if (label_values_list)
 		set_attr(ist,  func_obj, SYM(FPARAMS_), copy_list_obj(ist, label_values_list) );
 	return func_obj;
@@ -1198,22 +1195,22 @@
 		( obj->state == OBJ_STATE_NEW_OR_MARKED ? "New/Marked" :
 		( obj->state == OBJ_STATE_UNMARKED ? "Unmarked" :
 		( obj->state == OBJ_STATE_DELETED  ? "Deleted" : "*** ERROR ***" ))));
-	if(obj->data_type != DATA_TYPE_NONE){
+	if(obj->body->data_type != DATA_TYPE_NONE){
 		ind(dep+1); fprintf(fout,"Data %s",
-		( obj->data_type == DATA_TYPE_IMMDATA   ? "immediate: " :
-		( obj->data_type == DATA_TYPE_DATAPTR   ? "pointer:   " : 
+		( obj->body->data_type == DATA_TYPE_IMMDATA   ? "immediate: " :
+		( obj->body->data_type == DATA_TYPE_DATAPTR   ? "pointer:   " : 
 		                                           "func ptr:  " )));
 	}
-	if(obj->data_type == DATA_TYPE_IMMDATA){
+	if(obj->body->data_type == DATA_TYPE_IMMDATA){
 		fprintf(fout, "%08x %08x \"%s\"\n", 
-							obj->data.i32[0], obj->data.i32[1], 
-							(char *)obj->data.str );
-	} else if(obj->data_type != DATA_TYPE_NONE){
-		fprintf(fout,"%08x\n", obj->data.i32[0]);
+							obj->body->data.i32[0], obj->body->data.i32[1], 
+							(char *)obj->body->data.str );
+	} else if(obj->body->data_type != DATA_TYPE_NONE){
+		fprintf(fout,"%08x\n", obj->body->data.i32[0]);
 	}
 	prt_flg = 1;
-	if (obj->has_attrs) {
-		attr_p attrs = obj->attr_proto.attrs;
+	if (obj->body->has_attrs) {
+		attr_p attrs = obj->body->attr_proto.attrs;
 		blnk();
 		for(i=ATTRS_OVERHEAD; i < ATTRS_OVERHEAD+attr_plen(attrs); i++){
 			obj_p val = attrs[i].attr.value;
@@ -1240,7 +1237,7 @@
 	} else if (obj != OBJ(OBJECT)) {
 		blnk();
 		ind(dep+1); fprintf(fout,"PROTO: "); prt_flg = 1;
-		dump_obj(ist, obj->attr_proto.proto, dep+1);
+		dump_obj(ist, obj->body->attr_proto.proto, dep+1);
 		if_exc_return;
 	}
 	blnk();

Modified: trunk/src/object.h
===================================================================
--- trunk/src/object.h	2004-07-17 08:33:55 UTC (rev 748)
+++ trunk/src/object.h	2004-07-18 04:26:50 UTC (rev 749)
@@ -76,6 +76,9 @@
 
 void console(isp ist);
 
+unsigned char* ob_malloc(int is_body);
+void ob_free(void *p);
+
 extern obj_p		obj_list_root;
 extern obj_p        core_object_marker;
 extern pr_lock_t	object_list_lock;

Modified: trunk/src/parser_routines.c
===================================================================
--- trunk/src/parser_routines.c	2004-07-17 08:33:55 UTC (rev 748)
+++ trunk/src/parser_routines.c	2004-07-18 04:26:50 UTC (rev 749)
@@ -1583,7 +1583,7 @@
 	if (int_obj)
 		*((double*) obj_malloc(IST, proto, obj, sizeof(double))) = (double) int2i64t(IST, int_obj);
 	else
-		*((double*) obj_malloc(IST, proto, obj, sizeof(double))) = num->data.f64;
+		*((double*) obj_malloc(IST, proto, obj, sizeof(double))) = num->body->data.f64;
 	res = new_code(param, 2, 1, 1, OP_PUSH);
 	get_loc(IST, res, num);
 	get_loc(IST, res, int_obj);

Modified: trunk/src/prlist.h
===================================================================
--- trunk/src/prlist.h	2004-07-17 08:33:55 UTC (rev 748)
+++ trunk/src/prlist.h	2004-07-18 04:26:50 UTC (rev 749)
@@ -75,8 +75,8 @@
 #define lstplen(list_ptr)		(((list_p)(list_ptr))->hdr.len)
 #define lstpitem(list_ptr,i)	(((list_p)(list_ptr))->item[i])
 
-#define listsetsize(list_obj,n) lstpsetsize((list_obj)->data.ptr, n)
-#define listsize(list_obj)		lstpsize((list_obj)->data.ptr)
-#define listlen(list_obj)		lstplen((list_obj)->data.ptr)
-#define listitem(list_obj,i)	lstpitem((list_obj)->data.ptr,i)
+#define listsetsize(list_obj,n) lstpsetsize((list_obj)->body->data.ptr, n)
+#define listsize(list_obj)		lstpsize((list_obj)->body->data.ptr)
+#define listlen(list_obj)		lstplen((list_obj)->body->data.ptr)
+#define listitem(list_obj,i)	lstpitem((list_obj)->body->data.ptr,i)
 

Modified: trunk/src/src.vcproj
===================================================================
--- trunk/src/src.vcproj	2004-07-17 08:33:55 UTC (rev 748)
+++ trunk/src/src.vcproj	2004-07-18 04:26:50 UTC (rev 749)
@@ -194,6 +194,9 @@
 				RelativePath=".\memory_mgr.c">
 			</File>
 			<File
+				RelativePath=".\ob_malloc.c">
+			</File>
+			<File
 				RelativePath=".\object.c">
 			</File>
 			<File
Modified: trunk/src/symbol.c
===================================================================
--- trunk/src/symbol.c	2004-07-17 08:33:55 UTC (rev 748)
+++ trunk/src/symbol.c	2004-07-18 04:26:50 UTC (rev 749)
@@ -264,19 +264,19 @@
 	}
 	sym = NEW_OBJ(OBJ(SYMBOL_PROTO));
 	SET_TYPE_IF_EXC(OBJ(SYMBOL_PROTO), sym, DATA_TYPE_IMMDATA) return NULL;
-	sym->imm_data_len = 4;
+	sym->body->imm_data_len = 4;
 	if (!(next_key = (next_key+3) & 0x7fffffff)) {
 		printf("Out of unique symbol keys.  Did we really use two billion?\n");
 		pr_exit(1);
 	}
-	sym->data.key = next_key;
+	sym->body->data.key = next_key;
 	symbol_tree = ins_trie(symbol_tree, s, sym);
 	if (!STRING_SYM) STRING_SYM = sym;
 	pr_unlock(&symbol_tree_lock);
 	set_attr(ist, sym, STRING_SYM, NEW_STRING(s));
-	sym->wr_access = ACC_SYSTEM;
+	sym->body->wr_access = ACC_SYSTEM;
 	su(i);
-	dict_add(ist, OBJ(SYMBOLS), NEW_INT(sym->data.key), sym);
+	dict_add(ist, OBJ(SYMBOLS), NEW_INT(sym->body->data.key), sym);
 	un_su(i);
 	pr_free(s);
 	set_immutable(sym);

Modified: trunk/src/sys.c
===================================================================
--- trunk/src/sys.c	2004-07-17 08:33:55 UTC (rev 748)
+++ trunk/src/sys.c	2004-07-18 04:26:50 UTC (rev 749)
@@ -96,7 +96,7 @@
 	if (!apr_thread) {
 		raise_exception(ist, OBJ(INTERNAL_EXC), "sys_exit: no thread to exit");
 	} else
-		apr_thread_exit(apr_thread, (int)parms[1]->data.i64);
+		apr_thread_exit(apr_thread, (int)parms[1]->body->data.i64);
 	return NULL;
 }
 
@@ -191,7 +191,7 @@
 	list_append(ist, vers_tuple, NEW_STRING(PROTHON_VERSION_NUMBER));
 	list_append(ist, vers_tuple, NEW_STRING(numonly(PROTHON_VERSION_BUILD, path)));
 	list_append(ist, vers_tuple, NEW_STRING(PROTHON_VERSION_DATE));
-	vers_tuple->immutable = TRUE;
+	vers_tuple->body->immutable = TRUE;
 	set_attr(ist, sys_module, sym(ist, "version"), vers_tuple);
 	set_attr(ist, sys_module, sym(ist, "modules"), OBJ(MODULES));
 	set_attr( ist, sys_module, sym(ist, "exit"),

Modified: trunk/src/thread.h
===================================================================
--- trunk/src/thread.h	2004-07-17 08:33:55 UTC (rev 748)
+++ trunk/src/thread.h	2004-07-18 04:26:50 UTC (rev 749)
@@ -65,9 +65,9 @@
 //extern DECLARE_PR_LOCK(thread_registry_lock);
 extern pr_lock_t thread_registry_lock;
 
-#define thread_saveframe(thread_obj) (((pr_thread_p)((thread_obj)->data.ptr))->save_frame)
-#define thread_frame(thread_obj)     (((pr_thread_p)((thread_obj)->data.ptr))->frame)
-#define thread_running(thread_obj)   (((pr_thread_p)((thread_obj)->data.ptr))->running)
+#define thread_saveframe(thread_obj) (((pr_thread_p)((thread_obj)->body->data.ptr))->save_frame)
+#define thread_frame(thread_obj)     (((pr_thread_p)((thread_obj)->body->data.ptr))->frame)
+#define thread_running(thread_obj)   (((pr_thread_p)((thread_obj)->body->data.ptr))->running)
 
 void thread_init(isp ist);
 obj_p register_thread(apr_thread_t *this_thread);