rev 433 - in trunk: . include/prothon modules/DBM modules/File modules/Prosist src

SVN User <[email protected]> Fri, 30 Apr 2004 20:22:30 -0400
Newsgroups gmane.comp.lang.prothon.cvs
Message-ID <[email protected]>
Author: mark
Date: 2004-04-30 20:22:27 -0400 (Fri, 30 Apr 2004)
New Revision: 433

Modified:
   trunk/STATUS.txt
   trunk/include/prothon/prothon.h
   trunk/include/prothon/prothon_dll.h
   trunk/modules/DBM/DBM.c
   trunk/modules/File/File.c
   trunk/modules/Prosist/Prosist.c
   trunk/src/builtins-dict.c
   trunk/src/builtins-float.c
   trunk/src/builtins-int.c
   trunk/src/builtins-list.c
   trunk/src/builtins-string.c
   trunk/src/builtins-thread.c
   trunk/src/builtins-tuple.c
   trunk/src/memory_mgr.c
   trunk/src/object.c
   trunk/src/object.h
   trunk/src/parser_routines.c
Log:
added binary data registration and checking,
used new BIN_CHK on Int and String

Modified: trunk/STATUS.txt
===================================================================
--- trunk/STATUS.txt	2004-04-30 06:02:08 UTC (rev 432)
+++ trunk/STATUS.txt	2004-05-01 00:22:27 UTC (rev 433)
@@ -7,7 +7,7 @@
 
 --- How do we add "properties", "descriptors"?
 
---- binary space registering in object
+--- binary space registering in object (1-double use of data, 2-wrong use of data)
 
 --- Add missing string functions
 

Modified: trunk/include/prothon/prothon.h
===================================================================
--- trunk/include/prothon/prothon.h	2004-04-30 06:02:08 UTC (rev 432)
+++ trunk/include/prothon/prothon.h	2004-05-01 00:22:27 UTC (rev 433)
@@ -125,13 +125,24 @@
 typedef struct obj_s*	obj_p;
 
 typedef struct {
+	int			size;
+	int			len;
+} attr_proto_hdr_t;
+
+typedef struct {
+	int			owns_binary;
+	obj_p		proto;
+} proto_entry_t;
+
+typedef struct {
 	attr_key_t	key;
 	obj_p		value;
 } attr_entry_t;
 
 typedef union {
-	i32_t 			num;
-	attr_entry_t 	attr;
+	attr_proto_hdr_t	hdr;
+	proto_entry_t		proto;
+	attr_entry_t 		attr;
 } attr_t;
 
 typedef attr_t* attr_p;
@@ -458,6 +469,17 @@
 // Clobbers binary data in dest object (copy)
 void copy_object_data(isp ist, obj_p copy, obj_p obj);
 
+// SET_TYPE_IF_EXC: Set data type field and throw exception if already set
+#define SET_TYPE_IF_EXC(obj, type)															\
+	if ((obj)->data_type != DATA_TYPE_NONE)													\
+		raise_exception(ist, OBJ(INTERNAL_EXC), "object binary data overwrite attempt");	\
+	else																					\
+		(obj)->data_type = (type);															\
+	if (ist->exception_obj)
+
+// OBJ_DATA_OWNER: Return owner prototype of binary data in obj
+obj_p obj_data_owner(obj_p obj);
+ 
 // GET_ATTR: Find attr in object that matches a key and return the attr value.
 // Searches object for attr with key that matches the given key symbol object.
 // If no attr is found with a matching key, then NULL is returned.
@@ -1015,7 +1037,7 @@
 // WARNING: obj_malloc does not internally lock the object it is modifying.  This is 
 // because it is usually used on a new object.  If you use it on a public object, be
 // sure to write_lock the object before calling obj_malloc.
-void* obj_malloc (obj_p obj, size_t size);
+void* obj_malloc (isp ist, obj_p obj, size_t size);
 void* obj_realloc(isp ist, obj_p obj, size_t size);
 void  obj_free   (isp ist, obj_p obj);
 

Modified: trunk/include/prothon/prothon_dll.h
===================================================================
--- trunk/include/prothon/prothon_dll.h	2004-04-30 06:02:08 UTC (rev 432)
+++ trunk/include/prothon/prothon_dll.h	2004-05-01 00:22:27 UTC (rev 433)
@@ -104,6 +104,7 @@
 	obj_p   	(*sym)(isp ist, char* symbol);
 	obj_p		(*new_object)(isp ist, obj_p proto);
 	void		(*copy_object_data)(isp ist, obj_p copy, obj_p obj);
+	obj_p		(*obj_data_owner)(obj_p obj);
 	void		(*set_obj_doc_f)(isp ist, obj_p obj, char* str);
 	obj_p	    (*dict_keys_values)(isp ist, obj_p dict_obj, int key_flg);
 	obj_p		(*check_exceptions)(isp ist);
@@ -124,7 +125,7 @@
 	void*		(*pr_realloc)(void *p, size_t nbytes);
 	void		(*pr_free)(void *p);
 
-	void*		(*obj_malloc) (obj_p obj, size_t size);
+	void*		(*obj_malloc) (isp ist, obj_p obj, size_t size);
 	void*		(*obj_realloc)(isp ist, obj_p obj, size_t size);
 	void		(*obj_free)   (isp ist, obj_p obj);
 
@@ -172,6 +173,11 @@
 static obj_p slf##func(isp ist, obj_p self, int pcnt,		\
 		       obj_p* parms, obj_p dlocals)
 
+#define BIN_CHK(slf)											\
+	if (obj_data_owner(self) != slf##_OBJ) {					\
+		raise_exception(ist, OBJ(INTERNAL_EXC),					\
+			"object has wrong binary data, expected %s", #slf);	\
+		return NULL; }
 
 #define MAIN_MODULE_INIT(name)									\
 static void name##_module_install(void);						\
@@ -264,6 +270,7 @@
 #define raise_exception		(*services->raise_exception)
 #define new_object			(*services->new_object)
 #define copy_object_data	(*services->copy_object_data)
+#define obj_data_owner		(*services->obj_data_owner)
 #define set_obj_doc_f		(*services->set_obj_doc_f)
 #define pr_malloc			(*services->pr_malloc)
 #define pr_realloc			(*services->pr_realloc)

Modified: trunk/modules/DBM/DBM.c
===================================================================
--- trunk/modules/DBM/DBM.c	2004-04-30 06:02:08 UTC (rev 432)
+++ trunk/modules/DBM/DBM.c	2004-05-01 00:22:27 UTC (rev 433)
@@ -168,7 +168,7 @@
 	set_attr(ist, self, sym(ist, "uperm"), parms[7]);
 	read_lock(ist, self);
 
-	self->data_type = DATA_TYPE_DATAPTR;
+	SET_TYPE_IF_EXC(self, DATA_TYPE_DATAPTR) return NULL;
 	self->data.ptr  = db;
 
 	return OBJ(NONE);
Modified: trunk/modules/File/File.c
===================================================================
--- trunk/modules/File/File.c	2004-04-30 06:02:08 UTC (rev 432)
+++ trunk/modules/File/File.c	2004-05-01 00:22:27 UTC (rev 433)
@@ -98,7 +98,7 @@
 	filep->stream  = fp;
 	filep->pool = subpool;
 	filep->flags = flags;
-	file_obj->data_type = DATA_TYPE_DATAPTR;
+	SET_TYPE_IF_EXC(file_obj, DATA_TYPE_DATAPTR) return;
 	file_obj->data.ptr  = filep;
 	file_obj->rd_access = ACC_USER1;
 	file_obj->wr_access = ACC_USER1;
@@ -277,7 +277,7 @@
 		str_obj->data_type = DATA_TYPE_IMMDATA;
 		buf = str_obj->data.str;
 	} else {
-		obj_str = obj_malloc(str_obj, sizeof(pr_str_t)+size+1);
+		obj_str = obj_malloc(ist, str_obj, sizeof(pr_str_t)+size+1);
 		buf = obj_str->str;
 	}
 	num_read = size;
@@ -292,7 +292,7 @@
 		size_t next_read = (readall ? size : size - total_read);
 		size_t new_len   =  total_read + next_read;
 		if (str_obj->data_type == DATA_TYPE_IMMDATA && new_len >= IMMEDIATE_DATA_LEN) {
-			obj_str = obj_malloc(str_obj, sizeof(pr_str_t)+new_len+1);
+			obj_str = obj_malloc(ist, str_obj, sizeof(pr_str_t)+new_len+1);
 			buf = obj_str->str;
 		} else {
 			obj_str = obj_realloc(ist, str_obj, sizeof(pr_str_t)+new_len+1);
@@ -354,7 +354,7 @@
 		str_obj->data_type    = DATA_TYPE_IMMDATA;
 		buf = str_obj->data.str;
 	} else {
-		obj_str = obj_malloc(str_obj, sizeof(pr_str_t)+size+1);
+		obj_str = obj_malloc(ist, str_obj, sizeof(pr_str_t)+size+1);
 		buf = obj_str->str;
 	}
 	aprerr = apr_file_gets(buf, (int)(size + 1), STREAM(self));
@@ -368,7 +368,7 @@
 		size_t next_read = (readall ? size : size - total_read);
 		size_t new_len = total_read + next_read;
 		if (str_obj->data_type == DATA_TYPE_IMMDATA && new_len >= IMMEDIATE_DATA_LEN) {
-			obj_str = obj_malloc(str_obj, sizeof(pr_str_t)+new_len+1);
+			obj_str = obj_malloc(ist, str_obj, sizeof(pr_str_t)+new_len+1);
 			buf = obj_str->str;
 		} else {
 			obj_str = obj_realloc(ist, str_obj, sizeof(pr_str_t)+new_len+1);
@@ -432,7 +432,7 @@
 			str_obj->data_type = DATA_TYPE_IMMDATA;
 			buf = str_obj->data.str;
 		} else {
-			obj_str = obj_malloc(str_obj, sizeof(pr_str_t)+size+1);
+			obj_str = obj_malloc(ist, str_obj, sizeof(pr_str_t)+size+1);
 			buf = obj_str->str;
 		}
 		aprerr = apr_file_gets(buf, (int)(size - total_read + 1), STREAM(self));
@@ -448,7 +448,7 @@
 			size_t next_read = (readall ? size : size - total_read);
 			size_t new_len = num_read + next_read;
 			if (str_obj->data_type == DATA_TYPE_IMMDATA && new_len >= IMMEDIATE_DATA_LEN) {
-				obj_str = obj_malloc(str_obj, sizeof(pr_str_t)+new_len+1);
+				obj_str = obj_malloc(ist, str_obj, sizeof(pr_str_t)+new_len+1);
 				buf = obj_str->str;
 			} else {
 				obj_str = obj_realloc(ist, str_obj, sizeof(pr_str_t)+new_len+1);

Modified: trunk/modules/Prosist/Prosist.c
===================================================================
--- trunk/modules/Prosist/Prosist.c	2004-04-30 06:02:08 UTC (rev 432)
+++ trunk/modules/Prosist/Prosist.c	2004-05-01 00:22:27 UTC (rev 433)
@@ -954,7 +954,7 @@
 	aprerr = apr_dbm_open_ex(&db, "SDBM", name, mode, uperm, cntxt);  
 	IF_APR_ERR("opening Prosist database") return NULL;
 
-	self->data_type		= DATA_TYPE_DATAPTR;
+	SET_TYPE_IF_EXC(self, DATA_TYPE_DATAPTR) return NULL;
 	self->data.ptr		= psrecp = pr_malloc(sizeof(psrec_t));
 	psrecp->db			= db;
 	psrecp->pool		= cntxt;

Modified: trunk/src/builtins-dict.c
===================================================================
--- trunk/src/builtins-dict.c	2004-04-30 06:02:08 UTC (rev 432)
+++ trunk/src/builtins-dict.c	2004-05-01 00:22:27 UTC (rev 433)
@@ -73,7 +73,7 @@
 	obj_p dict_obj = NEW_OBJ(OBJ(DICT_PROTO));
 	dict_p dict;
 	initial_size = max(initial_size, DEFAULT_INITIAL_DICT_SIZE);
-	dict = obj_malloc(dict_obj, (DICT_OVERHEAD+initial_size)*sizeof(dict_t));
+	dict = obj_malloc(ist, dict_obj, (DICT_OVERHEAD+initial_size)*sizeof(dict_t)); 
 	memset(dict, 0, (DICT_OVERHEAD+initial_size)*sizeof(dict_t));
 	dictsize(dict) = initial_size;
 	return dict_obj;
@@ -261,8 +261,8 @@
 	set_obj_id(Dict_OBJ, *, Dict);
 	set_attr(ist, OBJ(OBJECT), sym(ist, "Dict"), Dict_OBJ);
 
-	Dict_OBJ->data_type = DATA_TYPE_DATAPTR;
-    dict = obj_malloc(Dict_OBJ, (DICT_OVERHEAD+DEFAULT_INITIAL_DICT_SIZE)*sizeof(dict_t));
+    dict = obj_malloc(ist, Dict_OBJ, (DICT_OVERHEAD+DEFAULT_INITIAL_DICT_SIZE)*sizeof(dict_t));
+	if_exc_return;
     memset(dict, 0, (DICT_OVERHEAD+DEFAULT_INITIAL_DICT_SIZE)*sizeof(dict_t));
     dictsize(dict) = DEFAULT_INITIAL_DICT_SIZE;
 }
@@ -277,9 +277,9 @@
 	dict_p dict;
 	obj_p list;
 	int i, llen, size = max(DEFAULT_INITIAL_DICT_SIZE, (int) dict_len(ist, parms[1])*3);
-
-	self->data_type = DATA_TYPE_DATAPTR;
-    dict = obj_malloc(self, dict_sizeof(size));
+	
+	SET_TYPE_IF_EXC(self, DATA_TYPE_DATAPTR) return NULL;
+    dict = obj_malloc(ist, self, dict_sizeof(size));
     memset(dict, 0, dict_sizeof(size));
     dictsize(dict) = size;
 	list = dict_keys_values(ist, parms[1], 2 /*list*/);

Modified: trunk/src/builtins-float.c
===================================================================
--- trunk/src/builtins-float.c	2004-04-30 06:02:08 UTC (rev 432)
+++ trunk/src/builtins-float.c	2004-05-01 00:22:27 UTC (rev 433)
@@ -112,7 +112,7 @@
 	double f = 0.0;
 	if (list_len(ist, parms[1]))
 		FLOAT__PARAM(0, f);
-	self->data_type    = DATA_TYPE_IMMDATA;
+	SET_TYPE_IF_EXC(self, DATA_TYPE_IMMDATA) return NULL;
 	self->imm_data_len = IMMEDIATE_DATA_LEN;
 	self->data.f64     = f;
 	return OBJ(NONE);

Modified: trunk/src/builtins-int.c
===================================================================
--- trunk/src/builtins-int.c	2004-04-30 06:02:08 UTC (rev 432)
+++ trunk/src/builtins-int.c	2004-05-01 00:22:27 UTC (rev 433)
@@ -112,7 +112,7 @@
 	i64_t i = 0;
 	if (list_len(ist, parms[1]))
 		INT_64_PARAM(0,i);
-	self->data_type    = DATA_TYPE_IMMDATA;
+	SET_TYPE_IF_EXC(self, DATA_TYPE_IMMDATA) return NULL;
 	self->imm_data_len = IMMEDIATE_DATA_LEN;
 	self->data.i64     = i;
 	return OBJ(NONE);
@@ -125,24 +125,29 @@
 
 DEF(Int, __hash__, NULL) { 
 	i32_t i32 = (i32_t) Int_value(self);
+	BIN_CHK(Int);
 	return new_hash_obj(ist, i32);
 }
 
 DEF(Int, __abs__, NULL){
 	i64_t num = Int_value(self);
+	BIN_CHK(Int);
 	return NEW_INT(num < 0 ? -num : num);
 }
 
 DEF(Int, __neg__, NULL){
+	BIN_CHK(Int);
 	return NEW_INT( - Int_value(self) );
 }
 
 DEF(Int, __pos__, NULL){
+	BIN_CHK(Int);
 	return self;
 }
 
 DEF(Int, __add__, FORM_RPARAM){
 	obj_p other = parms[1];
+	BIN_CHK(Int);
 	if (!is_Int(other)) {
 		if (covers(other, self))
 			return call_func1(ist, other, SYM(__ADD__), self);
@@ -155,6 +160,7 @@
 DEF(Int, __div__, FORM_RPARAM){
 	obj_p res;
 	obj_p float_self, float_other, other = parms[1];
+	BIN_CHK(Int);
 	if (!is_Int(other)) {
 		if (covers(other, self))
 			return call_func1(ist, other, SYM(__RDIV__), self);
@@ -170,6 +176,7 @@
 
 DEF(Int, __floorDiv__, FORM_RPARAM){
 	obj_p other = parms[1];
+	BIN_CHK(Int);
 	if (!is_Int(other)) {
 		if (covers(other, self))
 			return call_func1(ist, other, SYM(__RFLOORDIV__), self);
@@ -185,6 +192,7 @@
 
 DEF(Int, __mod__, FORM_RPARAM) {
 	obj_p other = parms[1];
+	BIN_CHK(Int);
 	if (!is_Int(other)) {
 		if (covers(other, self))
 			return call_func1(ist, other, SYM(__RMOD__), self);
@@ -200,6 +208,7 @@
 
 DEF(Int, __mul__, FORM_RPARAM) {
 	obj_p other = parms[1];
+	BIN_CHK(Int);
 	if (!is_Int(other)) {
 		if (covers(other, self))
 			return call_func1(ist, other, SYM(__MUL__), self);
@@ -211,6 +220,7 @@
 
 DEF(Int, __sub__, FORM_RPARAM) {
 	obj_p other = parms[1];
+	BIN_CHK(Int);
 	if (!is_Int(other)) {
 		if (covers(other, self))
 			return call_func1(ist, other, SYM(__RSUB__), self);
@@ -223,6 +233,7 @@
 DEF(Int, __pow__, FORM_RPARAM){
 	obj_p res;
 	obj_p float_self, float_other, other = parms[1];
+	BIN_CHK(Int);
 	float_self  = call_func1(ist, OBJ(FLOAT_PROTO), SYM(__COERCE__), self);  if_exc_return NULL;
 	float_other = call_func1(ist, OBJ(FLOAT_PROTO), SYM(__COERCE__), other); if_exc_return NULL;
 	res = call_func1(ist, float_self, SYM(__POW__), float_other);
@@ -232,6 +243,7 @@
 
 DEF(Int, cmp, FORM_RPARAM){
 	obj_p other = parms[1];
+	BIN_CHK(Int);
 	if (!is_Int(other)) {
 		if (covers(other, self))
 			return call_func1(ist, other, SYM(__RCMP__), self);
@@ -248,6 +260,7 @@
 
 DEF(Int, __eq__QUES, FORM_RPARAM){
 	obj_p other = parms[1];
+	BIN_CHK(Int);
 	if (!is_Int(other)) {
 		int c = covers(other, self);
 		if (catch_exception(ist, OBJ(FUNCNOTFOUND_EXC), NULL)) 
@@ -259,11 +272,13 @@
 	else                                     return OBJ(PR_FALSE);
 }
 DEF(Int, __invert__, NULL){
+	BIN_CHK(Int);
 	return NEW_INT( ~ Int_value(self) );
 }
 
 DEF(Int, __xor__, FORM_RPARAM) {
 	obj_p other = parms[1];
+	BIN_CHK(Int);
 	if (!is_Int(other)) {
 		raise_exception(ist, OBJ(TYPE_EXC), "object cannot be xor'd with an Integer");
 		return OBJ(NONE);
@@ -273,6 +288,7 @@
 
 DEF(Int, __and__, FORM_RPARAM) {
 	obj_p other = parms[1];
+	BIN_CHK(Int);
 	if (!is_Int(other)) {
 		raise_exception(ist, OBJ(TYPE_EXC), "object cannot be and'd with an Integer");
 		return OBJ(NONE);
@@ -282,6 +298,7 @@
 
 DEF(Int, __or__, FORM_RPARAM) {
 	obj_p other = parms[1];
+	BIN_CHK(Int);
 	if (!is_Int(other)) {
 		raise_exception(ist, OBJ(TYPE_EXC), "object cannot be or'd with an Integer");
 		return OBJ(NONE);
@@ -291,6 +308,7 @@
 
 DEF(Int, __rShift__, FORM_RPARAM) {
 	obj_p other = parms[1];
+	BIN_CHK(Int);
 	if (!is_Int(other)) {
 		raise_exception(ist, OBJ(TYPE_EXC), "object cannot be shifted with an Integer");
 		return OBJ(NONE);
@@ -300,6 +318,7 @@
 
 DEF(Int, __lShift__, FORM_RPARAM) {
 	obj_p other = parms[1];
+	BIN_CHK(Int);
 	if (!is_Int(other)) {
 		raise_exception(ist, OBJ(TYPE_EXC), "object cannot be shifted with an Integer");
 		return OBJ(NONE);
@@ -309,12 +328,14 @@
 
 DEF(Int, __str__, NULL){
 	char str[24];
+	BIN_CHK(Int);
 	apr_snprintf(str, sizeof(str), "%"APR_INT64_T_FMT, (i64_t)Int_value(self));
 	return NEW_STRING(str);
 }
 
 DEF(Int, __iter__, NULL) {
 	obj_p gen_obj = NEW_INT(0);
+	BIN_CHK(Int);
 	gen_obj->immutable = FALSE;
 	gen_obj->attr_proto.proto = IntGen_OBJ;
 	set_attr(ist, gen_obj, SYM_LIMIT, self);
@@ -323,6 +344,7 @@
 
 DEF(Int, chr, NULL) {
 	char s[1];
+	BIN_CHK(Int);
 	s[0] = (char) Int_value(self);
 	return NEW_STRINGN(s, 1);
 }
@@ -337,6 +359,7 @@
 
 DEF(IntGen, next, NULL) {
 	obj_p limit, res;
+	BIN_CHK(IntGen);
 	if ( !(limit=get_attr(ist, self, SYM_LIMIT)) ||
 		  Int_value(self) == Int_value(limit) ) {
 		if (limit) {

Modified: trunk/src/builtins-list.c
===================================================================
--- trunk/src/builtins-list.c	2004-04-30 06:02:08 UTC (rev 432)
+++ trunk/src/builtins-list.c	2004-05-01 00:22:27 UTC (rev 433)
@@ -98,7 +98,7 @@
 	list_p lstp;
 	lstp = obj->data.ptr = 
 			pr_malloc(list_sizeof(max(initial_size, 2)));
-	obj->data_type = DATA_TYPE_DATAPTR;
+	SET_TYPE_IF_EXC(obj, DATA_TYPE_DATAPTR) return;
 	lstpsize(lstp) = max(initial_size, 2);
 	lstplen(lstp)  = 0;
 }

Modified: trunk/src/builtins-string.c
===================================================================
--- trunk/src/builtins-string.c	2004-04-30 06:02:08 UTC (rev 432)
+++ trunk/src/builtins-string.c	2004-05-01 00:22:27 UTC (rev 433)
@@ -83,7 +83,7 @@
 		obj->imm_data_len = (int) len;
 		strcpy(obj->data.str, str);
 	} else {
-		obj_str = obj_malloc(obj, sizeof(pr_str_t)+len+1);
+		obj_str = obj_malloc(ist, obj, sizeof(pr_str_t)+len+1); if_exc_return NULL;
 		obj_str->len = len;
 		strcpy(&(obj_str->str[0]), str);
 	}
@@ -103,7 +103,7 @@
 		memcpy(obj->data.str, str, len);
 		obj->data.str[len] = 0;
 	} else {
-		obj_str = obj_malloc(obj, sizeof(pr_str_t)+len+1);
+		obj_str = obj_malloc(ist, obj, sizeof(pr_str_t)+len+1);
 		obj_str->len = len;
 		memcpy(&(obj_str->str[0]), str, len);
 		obj_str->str[len] = 0;
@@ -116,13 +116,13 @@
 void set_string_data(isp ist, obj_p obj, char* p, size_t len) {
 	pr_str_p obj_str;
 	if (len < 8) {
-		obj->data_type    = DATA_TYPE_IMMDATA;
+		SET_TYPE_IF_EXC(obj, DATA_TYPE_IMMDATA) return;
 		obj->imm_data_len = (u8_t) len;
 		memcpy(obj->data.str, p, len);
 		obj->data.str[len]  = 0;
 	} else {
-		obj->data_type    = DATA_TYPE_DATAPTR;
-		obj_str = obj->data.ptr = obj_malloc(obj, sizeof(pr_str_t)+len+1);
+		SET_TYPE_IF_EXC(obj, DATA_TYPE_DATAPTR) return;
+		obj_str = obj->data.ptr = obj_malloc(ist, obj, sizeof(pr_str_t)+len+1);
 		obj_str->len = len;
 		memcpy(&(obj_str->str[0]), p, len);
 		obj_str->str[len] = 0;
@@ -158,21 +158,25 @@
 }
 
 DEF(String, __str__, NULL) {
+	BIN_CHK(String);
 	return self;
 }
 
 DEF(String, __hash__, NULL) {
 	i32_t res = 0x9a7c5e3;
 	char *p;
+	BIN_CHK(String);
 	for(p=pr_strptr(self); *p; p++) res += 131 * (*p);
 	return new_hash_obj(ist, res);
 }
 
 DEF(String, __objList__, FORM_RPARAM) {
+	BIN_CHK(String);
 	return parms[1];
 }
 
 DEF(String, __getItem__, FORM_RPARAM) {
+	BIN_CHK(String);
 	return get_sequence_item(ist, self, parms[1], SEQ_TYPE_STRING);
 }
 
@@ -188,6 +192,7 @@
 
 DEF(String, cmp, FORM_RPARAM){
 	obj_p other = parms[1];
+	BIN_CHK(String);
 	if (self == other)
 		return NEW_INT(0);
 	if (!is_String(other)) {
@@ -201,6 +206,7 @@
 	obj_p obj, other = parms[1];
 	pr_str_p obj_str;
 	size_t slen, olen, tlen;
+	BIN_CHK(String);
 	if (!is_String(other)) other = call_func0(ist, other, SYM(__STR__));
 	slen = pr_strlen(self); olen = pr_strlen(other);
 	tlen = slen + olen;
@@ -212,7 +218,7 @@
 		memcpy(&(obj->data.str[slen]), pr_strptr(other), olen);
 		obj->data.str[tlen] = 0;
 	} else {
-		obj_str = obj_malloc(obj, sizeof(pr_str_t)+tlen+1);
+		obj_str = obj_malloc(ist, obj, sizeof(pr_str_t)+tlen+1);
 		obj_str->len = tlen;
 		memcpy(&(obj_str->str[0]),    pr_strptr(self),  slen);
 		memcpy(&(obj_str->str[slen]), pr_strptr(other), olen);
@@ -226,6 +232,7 @@
 	obj_p obj;
 	pr_str_p obj_str;
 	size_t i, times, tlen, len = pr_strlen(self);
+	BIN_CHK(String);
 	if (!has_proto_QUES(ist, parms[1], OBJ(INT_PROTO))) {
 		raise_exception(ist, OBJ(TYPE_EXC), "multiply times parameter must be an integer");
 		return NULL;
@@ -242,7 +249,7 @@
 			memcpy(obj->data.str+i*len, pr_strptr(self), len);
 		obj->data.str[tlen] = 0;
 	} else {
-		obj_str = obj_malloc(obj, sizeof(pr_str_t)+tlen+1);
+		obj_str = obj_malloc(ist, obj, sizeof(pr_str_t)+tlen+1);
 		if(!obj_str) {
 			raise_exception(ist, OBJ(OUTOFMEMORY_EXC), "memory allocation failed for string multiplication");
 			return NULL;
@@ -264,6 +271,7 @@
 	char			*fmt_str = pr_strptr(self), *buf;
 	apr_status_t	aprerr;
 
+	BIN_CHK(String);
 	if ( has_proto_QUES(ist, argv_obj, OBJ(STRING_PROTO)) ||
 		!has_proto_QUES(ist, argv_obj,    OBJ(SEQ_PROTO)) ) {
 		argv_obj = NEW_LIST(1);
@@ -301,6 +309,7 @@
 
 DEF(String, __iter__, NULL) {
 	obj_p gen_obj = NEW_OBJ(StringGen_OBJ);
+	BIN_CHK(String);
 	gen_obj->data_type = DATA_TYPE_DATAPTR;
 	gen_obj->data.ptr = pr_strptr(self);
 	set_attr(ist, gen_obj, sym(ist, "saved_string"), self);
@@ -308,6 +317,7 @@
 }
 
 DEF(String, ord, NULL) {
+	BIN_CHK(String);
 	return NEW_INT((int)(*pr_strptr(self)));
 }
 
@@ -317,6 +327,7 @@
 	obj_p obj, list, str_list;
 	int i, llen;
 	size_t ofs, self_len, tlen;
+	BIN_CHK(String);
 	if (!has_proto_QUES(ist, parms[1], OBJ(LIST_PROTO))) {
 		raise_exception(ist, OBJ(TYPE_EXC), "join function parameter must be a list");
 		return NULL;
@@ -340,7 +351,7 @@
 		obj->imm_data_len = (int) tlen;
 		dest_ptr = obj->data.str;
 	} else {
-		obj_str = obj_malloc(obj, sizeof(pr_str_t)+tlen+1);
+		obj_str = obj_malloc(ist, obj, sizeof(pr_str_t)+tlen+1);
 		if(!obj_str) {
 			raise_exception(ist, OBJ(OUTOFMEMORY_EXC), "memory allocation failed for string multiplication");
 			return NULL;
@@ -365,6 +376,7 @@
 }
 
 DEF(String, __in__QUES, FORM_RPARAM) {
+	BIN_CHK(String);
 	if (!has_proto_QUES(ist, parms[1], String_OBJ))
 		return call_func1(ist, parms[1], SYM(__RIN__QUES), self);
 	if (strstr(pr_strptr(parms[1]), pr_strptr(self))) return OBJ(PR_TRUE);
@@ -372,6 +384,7 @@
 }
 
 DEF(String, __notIn__QUES, FORM_RPARAM) {
+	BIN_CHK(String);
 	if (!has_proto_QUES(ist, parms[1], String_OBJ))
 		return call_func1(ist, parms[1], SYM(__RNOTIN__QUES), self);
 	if (strstr(pr_strptr(parms[1]), pr_strptr(self))) return OBJ(PR_FALSE);
@@ -379,15 +392,18 @@
 }
 
 DEF(String, len, NULL) {
+	BIN_CHK(String);
 	return NEW_INT(pr_strlen(self));
 }
 
 DEF(String, __bool__QUES, NULL) {
+	BIN_CHK(String);
 	if (pr_strlen(self)) return OBJ(PR_TRUE);
 	else                 return OBJ(PR_FALSE);
 }
 
 DEF(String, __cDataLen__, NULL) {
+	BIN_CHK(String);
 	return NEW_INT(sizeof(pr_str_t) + pr_strlen(self) + 1);
 }
 
@@ -405,11 +421,12 @@
         int ch;
         obj_p res = NULL;
         char* res_str;
+		BIN_CHK(StringGen);
         def_write_lock(self);
         if ((ch = *((char*)self->data.ptr))) {
 				self->data.ptr = (i64_t *)(((char*)self->data.ptr) + 1);
                 res = NEW_OBJ(String_OBJ);
-                res_str = (char*)obj_malloc(res, 2);
+                res_str = (char*)obj_malloc(ist, res, 2);
                 res_str[0] = ch;
                 res_str[1] = 0;
         } else

Modified: trunk/src/builtins-thread.c
===================================================================
--- trunk/src/builtins-thread.c	2004-04-30 06:02:08 UTC (rev 432)
+++ trunk/src/builtins-thread.c	2004-05-01 00:22:27 UTC (rev 433)
@@ -74,7 +74,7 @@
 	obj_p thread_obj;
 	pr_thread_p thread_ptr;
 	thread_obj = NEW_OBJ(OBJ(THREAD_PROTO));
-	thread_obj->data_type = DATA_TYPE_DATAPTR;
+	SET_TYPE_IF_EXC(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->ist           = ist;
@@ -132,7 +132,7 @@
 
 	if (!thread_obj) {
 		thread_obj = NEW_OBJ(OBJ(THREAD_PROTO));
-		thread_obj->data_type = DATA_TYPE_DATAPTR;
+		SET_TYPE_IF_EXC(thread_obj, DATA_TYPE_DATAPTR) return NULL;
 		thread_obj->data.ptr  = pr_malloc(sizeof(pr_thread_t));
 		memset(thread_obj->data.ptr, 0, sizeof(pr_thread_t));
 	}
@@ -195,8 +195,8 @@
 	set_attr(ist,  Thread_OBJ, sym(ist,   "USER2"), NEW_INT( ACC_USER2));
 	set_attr(ist,  Thread_OBJ, sym(ist,  "SYSTEM"), NEW_INT(ACC_SYSTEM));
 
-	Thread_OBJ->data_type = DATA_TYPE_DATAPTR;
-    thread = obj_malloc(Thread_OBJ, sizeof(pr_thread_t));
+    thread = obj_malloc(ist, Thread_OBJ, sizeof(pr_thread_t));
+	if_exc_return;
     memset(thread, 0, sizeof(pr_thread_t));
 	Thread_OBJ->unclonable = TRUE;
 }
@@ -216,7 +216,7 @@
 	if (parms[5] != OBJ(NONE))
 		CHECK_TYPE_EXC(parms[5], OBJ(STRING_PROTO), "string");
 	CHECK_TYPE_EXC(parms[7], OBJ(INT_PROTO),    "integer");
-	self->data_type = DATA_TYPE_DATAPTR;
+	SET_TYPE_IF_EXC(self, DATA_TYPE_DATAPTR) return NULL;
 	self->data.ptr  = pr_malloc(sizeof(pr_thread_t));
 	memset(self->data.ptr, 0, sizeof(pr_thread_t));
 	uthread = &(((pr_thread_p)self->data.ptr)->user_thread_data);
@@ -325,7 +325,7 @@
 
 	aprerr = apr_pool_create(&subpool, get_pr_head_pool());
 	IF_APR_ERR("out of memory creating mutex") return NULL;
-	self->data_type = DATA_TYPE_DATAPTR;
+	SET_TYPE_IF_EXC(self, DATA_TYPE_DATAPTR) return NULL;
 	aprerr = apr_thread_mutex_create((apr_thread_mutex_t**)(&self->data.ptr), APR_THREAD_MUTEX_UNNESTED, subpool);
 	IF_APR_ERR("error creating mutex in apr_thread_mutex_create") return NULL;
 	self->unclonable = TRUE;

Modified: trunk/src/builtins-tuple.c
===================================================================
--- trunk/src/builtins-tuple.c	2004-04-30 06:02:08 UTC (rev 432)
+++ trunk/src/builtins-tuple.c	2004-05-01 00:22:27 UTC (rev 433)
@@ -226,7 +226,7 @@
 		raise_exception(ist, OBJ(OUTOFMEMORY_EXC), "memory allocation failed for tuple multiplication");
 		return NULL;
 	}
-	res->data_type = DATA_TYPE_DATAPTR;
+	SET_TYPE_IF_EXC(res, DATA_TYPE_DATAPTR) return NULL;
 	lstpsize(lstp) = size;
 	lstplen(lstp)  = size;
 	for(i=0; i < times; i++)

Modified: trunk/src/memory_mgr.c
===================================================================
--- trunk/src/memory_mgr.c	2004-04-30 06:02:08 UTC (rev 432)
+++ trunk/src/memory_mgr.c	2004-05-01 00:22:27 UTC (rev 433)
@@ -169,7 +169,7 @@
 			if (obj->has_attrs) {
 				int i;
 				attr_p attrs = obj->attr_proto.attrs;
-				for(i=ATTRS_OVERHEAD; i < ATTRS_OVERHEAD+attr_blen(attrs); i++){
+				for(i=ATTRS_OVERHEAD; i < ATTRS_OVERHEAD+attr_plen(attrs); i++){
 					val = attrs[i].attr.value;
 					if(val > min_obj && val != obj && !val->scanned) {
 						mm_write_lock(ist, val);
@@ -181,8 +181,8 @@
 						pr_unlock(&to_be_scanned_list_lock);
 					}
 				}
-				for( i=ATTRS_OVERHEAD+attr_bsize(attrs); 
-					 i < ATTRS_OVERHEAD+attr_bsize(attrs)+attr_asize(attrs); i++){
+				for( i=ATTRS_OVERHEAD+attr_psize(attrs); 
+					 i < ATTRS_OVERHEAD+attr_psize(attrs)+attr_asize(attrs); i++){
 					if ( attrs[i].attr.key > 0 &&
 						 (val = attrs[i].attr.value) > min_obj && 
 						  val != obj && !val->scanned ) {

Modified: trunk/src/object.c
===================================================================
--- trunk/src/object.c	2004-04-30 06:02:08 UTC (rev 432)
+++ trunk/src/object.c	2004-05-01 00:22:27 UTC (rev 433)
@@ -198,6 +198,7 @@
 	dll_services.proto_len		   = proto_len;	  
 	dll_services.proto_item		   = proto_item;		 
 	dll_services.dump			   = dump;		 
+	dll_services.obj_data_owner	   = obj_data_owner;		 
 
 	/* Setup the core objects. Order counts here */
 	OBJ(OBJECT)             = NEW_OBJ(NULL);
@@ -305,8 +306,24 @@
 	return copy;
 }
 
+//********************************* obj_data_owner ****************************
+obj_p obj_data_owner(obj_p obj) {
+	attr_p attrp;
+	int i, numprotos; 
+	if ( obj->data_type != DATA_TYPE_IMMDATA &&
+		 obj->data_type != DATA_TYPE_DATAPTR )
+		return NULL;
+	if (!obj->has_attrs) return obj->attr_proto.proto;
+	attrp = obj->attr_proto.attrs;
+	numprotos = attr_plen(attrp);
+	for (i=0; i < numprotos; i++)
+		if (attr_pp(attrp, i)->proto.owns_binary)
+			return attr_proto_item(attrp, i);
+	return NULL;
+}
+
 //********************************* free_object *******************************
-void free_object(obj_p obj){
+void free_object(obj_p obj) {
 	if (obj->has_attrs)
 		pr_free(obj->attr_proto.attrs);
 	if (obj->data_type == DATA_TYPE_DATAPTR)
@@ -418,9 +435,10 @@
 //********************************* raise_exception ***************************
 void raise_exception(isp ist, obj_p proto_obj, const char *format, ...)
 {
+	obj_p exc_obj;
 	if (!proto_obj)
 		proto_obj = OBJ(EXCEPTION);
-	ist->exception_obj = NEW_OBJ(proto_obj);
+	exc_obj = NEW_OBJ(proto_obj);
 	if (format) {
 		char *p, err_buf[512];
 		va_list ap;
@@ -429,13 +447,14 @@
 		apr_vsnprintf(err_buf, sizeof(err_buf), format, ap);
 		va_end(ap);
 
-		ist->exception_obj->wr_access = ACC_GUEST;
+		exc_obj->wr_access = ACC_GUEST;
 
 		p = err_buf + strlen(err_buf) - 1;
 		while (*p == '.' || *p == ' ' || *p == '\t') { *p = 0; p--; }
 
-		set_obj_doc(ist->exception_obj, err_buf);
+		set_obj_doc(exc_obj, err_buf);
 	}
+	ist->exception_obj = exc_obj;
 }
 
 //********************************* if_exc_return ************************************
@@ -497,15 +516,18 @@
 //********************************* add_attrs *********************************
 attr_p add_attrs(obj_p obj){
 	obj_p proto = obj->attr_proto.proto;
-	attr_p attrs = pr_malloc(ATTRS_TSIZE_INIT * sizeof(attr_t));
-	memset(attrs, 0, ATTRS_TSIZE_INIT * sizeof(attr_t));
-	attr_bsize(attrs)= ATTRS_BSIZE_INIT;
-	attr_asize(attrs)= ATTRS_ASIZE_INIT;
-	attr_blen(attrs) = 1;
-	attr_bp(attrs,0)->attr.value = 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_IMMDATA ||
+	     obj->data_type == DATA_TYPE_DATAPTR )
+		attr_owns_bin(attrs, 0) = TRUE;
 	attr_alen(attrs) = 0;
 	obj->attr_proto.attrs = attrs;
-	obj->has_attrs  	 = TRUE;
+	obj->has_attrs   = TRUE;
 	return attrs;
 }
 
@@ -513,18 +535,18 @@
 attr_p attrs_realloc(obj_p obj, attr_p attrs) {
 	attr_key_t i;
 	attr_p old_attrs = attrs;
-	i32_t  old_bsize = attr_bsize(attrs);
+	i32_t  old_bsize = attr_psize(attrs);
 	i32_t  old_asize = attr_asize(attrs);
-	i32_t bsize =  attr_blen(attrs) + ATTRS_PROTO_PADDING;
-	i32_t asize = max((attr_alen(attrs) * ATTRS_PAD_PERCENT_FACTOR) / 100, ATTRS_ASIZE_INIT);
-	i32_t blen  =  attr_blen(attrs);
+	i32_t bsize =  attr_plen(attrs) + ATTRS_PROTO_PADDING;
+	i32_t asize = max((attr_alen(attrs) * ATTRS_PAD_PERCENT_FACTOR) / 100, ATTRS_AINIT);
+	i32_t blen  =  attr_plen(attrs);
 	i32_t alen  =  attr_alen(attrs);
 	size_t tsize = (size_t)(ATTRS_OVERHEAD+bsize+asize) * sizeof(attr_t);
 	attrs = pr_malloc(tsize);
 	memset(attrs, 0, tsize);
-	attr_bsize(attrs) = bsize;
+	attr_psize(attrs) = bsize;
 	attr_asize(attrs) = asize;
-	attr_blen(attrs)  = blen;
+	attr_plen(attrs)  = blen;
 	attr_alen(attrs)  = alen;
 	memcpy(attrs+ATTRS_OVERHEAD, old_attrs+ATTRS_OVERHEAD, blen * sizeof(attr_t));
 	for (i=ATTRS_OVERHEAD+old_bsize; i < ATTRS_OVERHEAD+old_bsize+old_asize; i++){
@@ -611,14 +633,17 @@
 void switch_proto(isp ist, obj_p obj, obj_p new_proto) {
 	attr_p attrs;
 	wrlock_rtrn(obj);
+	if (obj->data_type == DATA_TYPE_DATAPTR)
+		pr_free(obj->data.ptr);
+	obj->data_type = DATA_TYPE_NONE;
 	if (!(obj->has_attrs)) {
 		obj->attr_proto.proto = new_proto;
 		write_unlock(ist, obj);
 		return;
 	}
 	attrs = obj->attr_proto.attrs;
-	attr_blen(attrs) = 1;
-	attr_bp(attrs,0)->attr.value = new_proto;
+	attr_plen(attrs) = 1;
+	attr_proto_item(attrs, 0) = new_proto;
 	write_unlock(ist, obj);
 	return;
 }
@@ -630,24 +655,24 @@
 	wrlock_rtrn(obj) FALSE;
 	if (obj->has_attrs) attrs = obj->attr_proto.attrs;
 	else				attrs = add_attrs(obj);
-	len = attr_blen(attrs);
+	len = attr_plen(attrs);
 	for (i=0; i < len; i++)
-		if (attr_bp(attrs, i)->attr.value == proto) {
+		if (attr_proto_item(attrs, i) == proto) {
 			write_unlock(ist, obj);
 			return FALSE;
 		}
-	if (len == attr_bsize(attrs)) {
+	if (len == attr_psize(attrs)) {
 		attrs = attrs_realloc(obj, attrs);
-		len = attr_blen(attrs);
+		len = attr_plen(attrs);
 	}
 	if (pos >= len) {
-		attr_bp(attrs, attr_blen(attrs)++)->attr.value = proto;
+		attr_proto_item(attrs, attr_plen(attrs)++) = proto;
 		write_unlock(ist, obj);
 		return TRUE;
 	} else if (pos < 0) pos = 0;
-	memmove(attr_bp(attrs,pos+1),attr_bp(attrs,pos),(len-pos)*sizeof(attr_t));
-	attr_bp(attrs,pos)->attr.value = proto;
-	attr_blen(attrs)++;
+	memmove(attr_pp(attrs,pos+1),attr_pp(attrs,pos),(len-pos)*sizeof(attr_t));
+	attr_proto_item(attrs, pos) = proto;
+	attr_plen(attrs)++;
 	write_unlock(ist, obj);
 	return TRUE;
 }
@@ -662,16 +687,21 @@
 		return FALSE;
 	}
 	attrs = obj->attr_proto.attrs;
-	len = attr_blen(attrs);
+	len = attr_plen(attrs);
 	if (len < 2)  {
 		write_unlock(ist, obj);
 		return FALSE;
 	}
 	for (i=0; i < len; i++)
-		if (attr_bp(attrs, i)->attr.value == proto) {
+		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 (i != len-1) 
-				memmove(attr_bp(attrs,i),attr_bp(attrs,i+1),((len-1)-i)*sizeof(attr_t));
-			attr_blen(attrs)--;
+				memmove(attr_pp(attrs,i),attr_pp(attrs,i+1),((len-1)-i)*sizeof(attr_t));
+			attr_plen(attrs)--;
 			write_unlock(ist, obj);
 			return TRUE;
 		}
@@ -687,7 +717,7 @@
 		read_unlock(ist, obj);
 		return 1;
 	}
-	res = attr_blen(obj->attr_proto.attrs);
+	res = attr_plen(obj->attr_proto.attrs);
 	read_unlock(ist, obj);
 	return res;
 }
@@ -699,7 +729,7 @@
 	if (!obj->has_attrs)
 		res = obj->attr_proto.proto;
 	else
-		res = attr_bp(obj->attr_proto.attrs, i)->attr.value;
+		res = attr_proto_item(obj->attr_proto.attrs, i);
 	read_unlock(ist, obj);
 	return res;
 }
@@ -907,13 +937,15 @@
 }
 
 //********************************* obj_alloc ***************************
-void* obj_malloc(obj_p obj, size_t size) {
+void* obj_malloc(isp ist, obj_p obj, size_t size) {
 	if (size <= sizeof(obj_data_t)){
-		obj->data_type    = DATA_TYPE_IMMDATA;
+		SET_TYPE_IF_EXC(obj, DATA_TYPE_IMMDATA) 
+			return NULL;
 		obj->imm_data_len = (int) size;
 		return &obj->data;
 	} else {
-		obj->data_type = DATA_TYPE_DATAPTR;
+		SET_TYPE_IF_EXC(obj, DATA_TYPE_DATAPTR) 
+			return NULL;
 		obj->data.ptr  = pr_malloc(size);
 		return obj->data.ptr;
 	}
@@ -1069,14 +1101,14 @@
 	if (obj->has_attrs) {
 		attr_p attrs = obj->attr_proto.attrs;
 		blnk();
-		for(i=ATTRS_OVERHEAD; i < ATTRS_OVERHEAD+attr_blen(attrs); i++){
+		for(i=ATTRS_OVERHEAD; i < ATTRS_OVERHEAD+attr_plen(attrs); i++){
 			obj_p val = attrs[i].attr.value;
 			ind(dep+1); fprintf(fout,"PROTO: "); prt_flg = 1;
 			dump_obj(ist, val, dep+1);
 			if_exc_return;
 		}
-		for( i=ATTRS_OVERHEAD+attr_bsize(attrs); 
-			 i < ATTRS_OVERHEAD+attr_bsize(attrs)+attr_asize(attrs); i++){
+		for( i=ATTRS_OVERHEAD+attr_psize(attrs); 
+			 i < ATTRS_OVERHEAD+attr_psize(attrs)+attr_asize(attrs); i++){
 			if (attrs[i].attr.key > 0) {
 				char* sstr;
 				attr_key_t key = attrs[i].attr.key;

Modified: trunk/src/object.h
===================================================================
--- trunk/src/object.h	2004-04-30 06:02:08 UTC (rev 432)
+++ trunk/src/object.h	2004-05-01 00:22:27 UTC (rev 433)
@@ -99,22 +99,22 @@
 #define ATTRS_PAD_PERCENT_FACTOR		300
 #define ATTRS_PROTO_PADDING				1
 
-#define ATTRS_BSIZE_INDEX		0
-#define ATTRS_BLEN_INDEX		1
-#define ATTRS_ASIZE_INDEX		2
-#define ATTRS_ALEN_INDEX		3
-#define ATTRS_OVERHEAD			4
-#define ATTRS_BSIZE_INIT 		(ATTRS_PROTO_PADDING+1)
-#define ATTRS_ASIZE_INIT 		8
-#define ATTRS_TSIZE_INIT		(ATTRS_OVERHEAD+ATTRS_BSIZE_INIT+ATTRS_ASIZE_INIT)
+#define ATTRS_PINDEX	0
+#define ATTRS_AINDEX	1
+#define ATTRS_OVERHEAD	2
+#define ATTRS_PINIT 	(ATTRS_PROTO_PADDING+1)
+#define ATTRS_AINIT 	8
+#define ATTRS_TINIT		(ATTRS_OVERHEAD+ATTRS_PINIT+ATTRS_AINIT)
 
-#define attr_bsize(attrp)	((*(attrp+ATTRS_BSIZE_INDEX)).num)
-#define attr_blen(attrp)	((*(attrp+ATTRS_BLEN_INDEX)).num)
-#define attr_asize(attrp)	((*(attrp+ATTRS_ASIZE_INDEX)).num)
-#define attr_alen(attrp)	((*(attrp+ATTRS_ALEN_INDEX)).num)
-#define attr_tsize(attrp)	(ATTRS_OVERHEAD+attr_bsize(attrp)+attr_asize(attrp))
-#define attr_bp(attrp,i)	((attrp)+(ATTRS_OVERHEAD+(i)))
-#define attr_ap(attrp,i)	((attrp)+(ATTRS_OVERHEAD+attr_bsize(attrp)+((i)%attr_asize(attrp))))
+#define attr_psize(attrp)	((*(attrp+ATTRS_PINDEX)).hdr.size)
+#define attr_plen(attrp)	((*(attrp+ATTRS_PINDEX)).hdr.len)
+#define attr_asize(attrp)	((*(attrp+ATTRS_AINDEX)).hdr.size)
+#define attr_alen(attrp)	((*(attrp+ATTRS_AINDEX)).hdr.len)
+#define attr_tsize(attrp)	(ATTRS_OVERHEAD+attr_psize(attrp)+attr_asize(attrp))
+#define attr_pp(attrp,i)	((attrp)+(ATTRS_OVERHEAD+(i)))
+#define attr_ap(attrp,i)	((attrp)+(ATTRS_OVERHEAD+attr_psize(attrp)+((i)%attr_asize(attrp))))
+#define attr_proto_item(attrp,i) (((attrp)+(ATTRS_OVERHEAD+(i)))->proto.proto)
+#define attr_owns_bin(attrp,i)	 (((attrp)+(ATTRS_OVERHEAD+(i)))->proto.owns_binary)
 
 #define PAUSE_MS 2
 

Modified: trunk/src/parser_routines.c
===================================================================
--- trunk/src/parser_routines.c	2004-04-30 06:02:08 UTC (rev 432)
+++ trunk/src/parser_routines.c	2004-05-01 00:22:27 UTC (rev 433)
@@ -511,7 +511,7 @@
 	res->code_data[k++].bytecode.param = 3;
 	func = new_object(IST, OBJ(FUNC_PROTO));
 	code_len = sizeof(code) + body->len * sizeof(code_t);
-	memmove(obj_malloc(func, code_len), body, code_len);
+	memmove(obj_malloc(IST, func, code_len), body, code_len);
 	res->code_data[k++].data = func;
 	res->code_data[k++].num  = llen;
 	assert(k = len);
@@ -1236,7 +1236,7 @@
 		add_code(self, res, &k);
 	func = new_object(IST, OBJ(FUNC_PROTO));
 	code_len = blen * sizeof(code_t);
-	memmove(obj_malloc(func, code_len), body, code_len);
+	memmove(obj_malloc(IST, func, code_len), body, code_len);
 	switch (flg) {
 		case DEF_FLG: opcode = OP_DEF;	  pcnt = 3; depth_dec =  2; break;
 		case GEN_FLG: opcode = OP_GEN;	  pcnt = 3; depth_dec =  2; break;
@@ -1353,7 +1353,7 @@
 code_p int_to_obj(void* param, i64_t num){
 	code_p res;
 	obj_p obj = new_object(IST, OBJ(INT_PROTO));
-	*((i64_t*) obj_malloc(obj, sizeof(i64_t))) = num;
+	*((i64_t*) obj_malloc(IST, obj, sizeof(i64_t))) = num;
 	res = new_code(param, 2, 1, 1, OP_PUSH);
 	res->code_data[0].bytecode.param = 2;
 	res->code_data[1].data = obj;
@@ -1364,7 +1364,7 @@
 	code_p res;
 	obj_p obj = new_object(IST, 
 		(imag_flag == NEW_IMAG? OBJ(IMAG_PROTO) : OBJ(FLOAT_PROTO)) );
-	*((double*) obj_malloc(obj, sizeof(double))) = num;
+	*((double*) obj_malloc(IST, obj, sizeof(double))) = num;
 	res = new_code(param, 2, 1, 1, OP_PUSH);
 	res->code_data[0].bytecode.param = 2;
 	res->code_data[1].data = obj;
@@ -1383,7 +1383,7 @@
 		memcpy(obj->data.str, str, len);
 		obj->data.str[len] = 0;
 	} else {
-		obj_str = obj_malloc(obj, sizeof(pr_str_t)+len+1);
+		obj_str = obj_malloc(IST, obj, sizeof(pr_str_t)+len+1);
 		obj_str->len = len;
 		memcpy(&(obj_str->str[0]), str, len);
 		obj_str->str[len] = 0;