rev 672 - in trunk: include/prothon pr/test src

SVN User <[email protected]> Mon, 28 Jun 2004 04:04:43 -0400
Newsgroups gmane.comp.lang.prothon.cvs
Message-ID <[email protected]>
Author: mark
Date: 2004-06-28 04:04:40 -0400 (Mon, 28 Jun 2004)
New Revision: 672

Modified:
   trunk/include/prothon/prothon.h
   trunk/pr/test/test.pr
   trunk/src/builtins-core.c
   trunk/src/builtins-dict.c
   trunk/src/builtins-int.c
   trunk/src/interp.c
   trunk/src/lock.c
   trunk/src/lock.h
   trunk/src/memory_mgr.c
   trunk/src/object.h
Log:
weakref still not working

Modified: trunk/include/prothon/prothon.h
===================================================================
--- trunk/include/prothon/prothon.h	2004-06-28 03:33:22 UTC (rev 671)
+++ trunk/include/prothon/prothon.h	2004-06-28 08:04:40 UTC (rev 672)
@@ -521,6 +521,7 @@
 	void*		lock_stack;
 	frame_p		frame;
 	int			in_console;
+	int			notify_flags;
 	obj_p		exception_obj;
 } interp_state_t;
  

Modified: trunk/pr/test/test.pr
===================================================================
--- trunk/pr/test/test.pr	2004-06-28 03:33:22 UTC (rev 671)
+++ trunk/pr/test/test.pr	2004-06-28 08:04:40 UTC (rev 672)
@@ -1,10 +1,21 @@
 #!/usr/bin/env prothon
 
-x=6
-x
+x = 6
+weakref = WeakRef(x)
+print WeakRef
+print weakref
+print weakref.ref()
+print weakref.exists?()
+print WeakRef.READ
+print WeakRef.WRITE
+print WeakRef.DELETE
 
-try:
-    print 1//0
-except DivideByZero as e:
-    print e
+print weakref.flags()
 
+def callbk(flgs):
+	if flgs & WeakRef.READ: print 'READ'
+	if flgs & WeakRef.WRITE: print 'WRITE'
+	if flgs & WeakRef.DELETE: print 'DELETE'
+
+weakref.notify(callbk{weakref}, flags = WeakRef.READ | WeakRef.WRITE | WeakRef.DELETE)
+

Modified: trunk/src/builtins-core.c
===================================================================
--- trunk/src/builtins-core.c	2004-06-28 03:33:22 UTC (rev 671)
+++ trunk/src/builtins-core.c	2004-06-28 08:04:40 UTC (rev 672)
@@ -1031,9 +1031,9 @@
 	WeakRef_OBJ  = NEW_OBJ(NULL);
 	MODULE_ADD_TO_OBJ(WeakRef, OBJ(OBJECT), "WeakRef");
 
-	MODULE_CONSTANT_INT(WeakRef, READ,   READ_NOTIFY)
-	MODULE_CONSTANT_INT(WeakRef, WRITE,  WRITE_NOTIFY)
-	MODULE_CONSTANT_INT(WeakRef, DELETE, DELETE_NOTIFY)
+	MODULE_CONSTANT_INT(WeakRef, READ,   READ_NOTIFY);
+	MODULE_CONSTANT_INT(WeakRef, WRITE,  WRITE_NOTIFY);
+	MODULE_CONSTANT_INT(WeakRef, DELETE, DELETE_NOTIFY);
 }
 
 DEF(WeakRef, str_, NULL) { 
@@ -1053,22 +1053,30 @@
 DEF(WeakRef, init_, FORM_RPARAM) { 
 	weak_ref_p wrp;
 	obj_p callback_func;
+	int i, immutable_flag;
 
 	BIN_EMPTY_CHK();
 	SET_TYPE_IF_EXC(WeakRef_OBJ, self, DATA_TYPE_DATAPTR) return NULL;
-	wrp               = pr_malloc(sizeof(weak_ref_t));
+	wrp = self->data.ptr = pr_malloc(sizeof(weak_ref_t));
 	wrp->data_size	  = sizeof(weak_ref_t);
 	wrp->exists       = TRUE;
 	wrp->notify_flags = DELETE_NOTIFY;
 	wrp->ref          = parms[1];
-	callback_func     = get_attr(ist, WeakRef_OBJ, sym(ist, "callback_"));
-	add_notification(ist, parms[1], callback_func, DELETE_NOTIFY);
+	callback_func     = get_attr(ist, WeakRef_OBJ, sym(ist, "callback_"));  if_exc_return NULL;
+	immutable_flag    = is_immutable(wrp->ref);
+	clr_immutable(wrp->ref);
+	su(i);
+	set_attr(ist, callback_func, SYM(BINDOBJ_), self); if_exc_return NULL;
+	un_su(i);
+	add_notification(ist, wrp->ref, callback_func, DELETE_NOTIFY);
+	if(immutable_flag) set_immutable(wrp->ref);
 	set_unclonable(self);
-	return self;
+	return OBJ(NONE);
 }
 
 DEF(WeakRef, ref, NULL) {
 	weak_ref_p wrp = self->data.ptr;
+	BIN_CONTENT_CHK(WeakRef);
 	if(!wrp->exists) {
 		raise_exception(ist, OBJ(INTERPRETER_EXC), "object doesn't exist anymore");
 		del_notify_unlock();
@@ -1078,12 +1086,14 @@
 
 DEF(WeakRef, exists_QUES, NULL) {
 	weak_ref_p wrp = self->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;
+	BIN_CONTENT_CHK(WeakRef);
 	return NEW_INT(wrp->notify_flags);
 }
 
@@ -1092,7 +1102,8 @@
 							  flags, NEW_INT(WRITE_NOTIFY|DELETE_NOTIFY) ) ) { 
 	weak_ref_p wrp = self->data.ptr;
 	obj_p callback_func;
-	int flags;
+	int flags, old_flags, new_flags, immutable_flag;
+	BIN_CONTENT_CHK(WeakRef);
 	CHECK_TYPE_EXC(parms[1], OBJ(FUNC_PROTO), function);
 	INT_32_PARAM(3, flags);
 	del_notify_lock();
@@ -1101,51 +1112,68 @@
 		del_notify_unlock();
 		return NULL;									
 	}
+	immutable_flag = is_immutable(wrp->ref);
+	clr_immutable(wrp->ref);
+	old_flags = wrp->notify_flags;
+	new_flags = old_flags | flags;
+	if (flags == 0) {
+		new_flags = DELETE_NOTIFY;
+		del_attr(ist, wrp->ref, sym(ist, "onRead_"));
+		del_attr(ist, wrp->ref, sym(ist, "onReadParam_"));
+		del_attr(ist, wrp->ref, sym(ist, "onWrite_"));
+		del_attr(ist, wrp->ref, sym(ist, "onWriteParam_"));
+		del_attr(ist, wrp->ref, sym(ist, "onDelete_"));
+		del_attr(ist, wrp->ref, sym(ist, "onDeleteParam_"));
+	}
+	read_unlock(ist, self);
 	if (flags & READ_NOTIFY) {
-		set_attr(ist, wrp->ref, sym(ist, "onRead_"), parms[3]);
+		set_attr(ist, self, sym(ist, "onRead_"), parms[1]); if_exc_return NULL;
 		if (parms[3] != OBJ(NONE))
-			set_attr(ist, wrp->ref, sym(ist, "onReadParam_"), parms[5]);
+			set_attr(ist, self, sym(ist, "onReadParam_"), parms[3]); if_exc_return NULL;
 	}
 	if (flags & WRITE_NOTIFY) {
-		set_attr(ist, wrp->ref, sym(ist, "onWrite_"), parms[3]);
+		set_attr(ist, self, sym(ist, "onWrite_"), parms[1]); if_exc_return NULL;
 		if (parms[3] != OBJ(NONE))
-			set_attr(ist, wrp->ref, sym(ist, "onWriteParam_"), parms[5]);
+			set_attr(ist, self, sym(ist, "onWriteParam_"), parms[3]); if_exc_return NULL;
 	}
 	if (flags & DELETE_NOTIFY) {
-		set_attr(ist, wrp->ref, sym(ist, "onDelete_"), parms[3]);
+		set_attr(ist, self, sym(ist, "onDelete_"), parms[1]); if_exc_return NULL;
 		if (parms[3] != OBJ(NONE))
-			set_attr(ist, wrp->ref, sym(ist, "onDeleteParam_"), parms[5]);
+			set_attr(ist, self, sym(ist, "onDeleteParam_"), parms[3]); if_exc_return NULL;
 	}
-	if (wrp->notify_flags != (wrp->notify_flags | flags)) {
-		wrp->notify_flags |= flags;
-		callback_func = get_attr(ist, WeakRef_OBJ, sym(ist, "callback_"));
-		add_notification(ist, wrp->ref, callback_func, wrp->notify_flags);
+	read_lock(ist, self);
+	if (old_flags != new_flags) {
+		wrp->notify_flags = new_flags;
+		callback_func = get_attr(ist, WeakRef_OBJ, sym(ist, "callback_")); if_exc_return NULL;
+		add_notification(ist, wrp->ref, callback_func, new_flags); if_exc_return NULL;
 	}
+	if(immutable_flag)
+		set_immutable(wrp->ref);
 	del_notify_unlock();
 	return self;
 }
 
 DEF(WeakRef, callback_, FORM_RPARAM) {
-	obj_p arr[2]; 
+	obj_p arr[4]; 
 	int flags = int2i32t(ist, parms[1]);
-	arr[0] = OBJ(NOKEY);
+	arr[0] = OBJ(NOKEY); arr[1] = parms[1]; arr[2] = OBJ(NOKEY);
 	if (flags & READ_NOTIFY) {
 		obj_p on_read_func  = get_attr(ist, self, sym(ist, "onRead_"));
 		obj_p on_read_param = get_attr(ist, self, sym(ist, "onReadParam_"));
 		if (on_read_func && on_read_param) {
-			arr[1] = on_read_param;
+			arr[3] = on_read_param;
+			call_func(ist, NULL, on_read_func, 4, arr, NULL);
+		} else if (on_read_func)
 			call_func(ist, NULL, on_read_func, 2, arr, NULL);
-		} else if (on_read_func)
-			call_func(ist, NULL, on_read_func, 0, NULL, NULL);
 	}
 	if (flags & WRITE_NOTIFY) {
 		obj_p on_write_func  = get_attr(ist, self, sym(ist, "onWrite_"));
 		obj_p on_write_param = get_attr(ist, self, sym(ist, "onWriteParam_"));
 		if (on_write_func && on_write_param) {
-			arr[1] = on_write_param;
+			arr[3] = on_write_param;
+			call_func(ist, NULL, on_write_func, 4, arr, NULL);
+		} else if (on_write_func)
 			call_func(ist, NULL, on_write_func, 2, arr, NULL);
-		} else if (on_write_func)
-			call_func(ist, NULL, on_write_func, 0, NULL, NULL);
 	}
 	if (flags & DELETE_NOTIFY) {
 		weak_ref_p wrp = self->data.ptr;
@@ -1153,11 +1181,11 @@
 		obj_p on_delete_param = get_attr(ist, self, sym(ist, "onDeleteParam_"));
 		wrp->exists = FALSE;
 		if (on_delete_func && on_delete_param) {
-			arr[1] = on_delete_param;
-			call_func(ist, NULL, on_delete_func, 2, arr, NULL);
+			arr[3] = on_delete_param;
+			call_func(ist, NULL, on_delete_func, 4, arr, NULL);
 			check_exceptions(ist);
 		} else if (on_delete_func) {
-			call_func(ist, NULL, on_delete_func, 0, NULL, NULL);
+			call_func(ist, NULL, on_delete_func, 2, arr, NULL);
 			check_exceptions(ist);
 		}
 	}

Modified: trunk/src/builtins-dict.c
===================================================================
--- trunk/src/builtins-dict.c	2004-06-28 03:33:22 UTC (rev 671)
+++ trunk/src/builtins-dict.c	2004-06-28 08:04:40 UTC (rev 672)
@@ -122,6 +122,17 @@
 		raise_exception(ist, OBJ(TYPE_EXC), "dictionary keys must be immutable");
 		return 0;
 	}
+	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));
+			pr_free(v);
+			return res;
+		}
+		else
+			return long_hash(key_in->data.ptr);
+	}
 	hash_obj = call_func0(ist, key_in, SYM(HASH_));
 	if_exc_return 0;
 	return hash_obj->data.i32[0];

Modified: trunk/src/builtins-int.c
===================================================================
--- trunk/src/builtins-int.c	2004-06-28 03:33:22 UTC (rev 671)
+++ trunk/src/builtins-int.c	2004-06-28 08:04:40 UTC (rev 672)
@@ -1986,7 +1986,7 @@
 	return c;
 }
 
-static long long_hash(long_p v)
+long long_hash(long_p v)
 {
 	long x;
 	int i, sign;

Modified: trunk/src/interp.c
===================================================================
--- trunk/src/interp.c	2004-06-28 03:33:22 UTC (rev 671)
+++ trunk/src/interp.c	2004-06-28 08:04:40 UTC (rev 672)
@@ -1764,7 +1764,7 @@
 		        has_proto(ist, func_obj, OBJ(FUNC_PROTO)) ) {
 		frame_p frame, new_frame;
 		obj_p new_locals, aself; 
-		int idx;
+		int idx = -1;
 		fparam_proc_state_t fps;
 
 		if (!ist) {

Modified: trunk/src/lock.c
===================================================================
--- trunk/src/lock.c	2004-06-28 03:33:22 UTC (rev 671)
+++ trunk/src/lock.c	2004-06-28 08:04:40 UTC (rev 672)
@@ -62,8 +62,6 @@
 #include "memory_mgr.h"
 #include "lock.h"
 
-#define lockstack	((clist_p)(ist->lock_stack))
-
 apr_thread_cond_t	*obj_wrlock_cond;
 apr_thread_mutex_t	*obj_wrlock_mutex;
 apr_thread_cond_t	*write_cond;
@@ -76,14 +74,33 @@
 //********************************* notify ************************************
 void notify(isp ist, obj_p obj, int flag) {
 	int i, llen;
-	obj_p callback_list, arr[2] = {OBJ(NOKEY), NEW_INT(flag)};
+	obj_p callback_list, arr[2];
+	arr[0] = OBJ(NOKEY);
 
-	if (callback_list = get_attr(ist, obj, SYM(NOTIFYCALLBACK_))) {
-		llen = (int) list_len(ist, callback_list);
-		for (i=0; i < llen; i += 2)
-			if (int2i32t(ist, list_item(ist, callback_list, i)) & flag)
-				call_func(ist, NULL, list_item(ist, callback_list, i+1), 2, arr, NULL);
+	if (ist->notify_flags) {
+		ist->notify_flags |= flag;
+		return;
 	}
+	ist->notify_flags = flag;
+	callback_list = get_attr(ist, obj, SYM(NOTIFYCALLBACK_));
+	if (ist->exception_obj) { ist->notify_flags = 0; return; }
+	if (callback_list) {
+		while(ist->notify_flags) {
+			if (ist->notify_flags & READ_NOTIFY)        flag = READ_NOTIFY;   
+			else if (ist->notify_flags & WRITE_NOTIFY)  flag = WRITE_NOTIFY;  
+			else if (ist->notify_flags & DELETE_NOTIFY) flag = DELETE_NOTIFY;
+			arr[1] = NEW_INT(flag);
+			llen = (int) list_len(ist, callback_list);
+			for (i=0; i < llen; i += 2)
+				if (int2i32t(ist, list_item(ist, callback_list, i)) & flag) {
+					call_func(ist, NULL, list_item(ist, callback_list, i+1), 2, arr, NULL);
+					check_exceptions(ist);
+				}
+			ist->notify_flags &= ~flag;
+			del_unlock(arr[1]);
+		}
+	}
+	ist->notify_flags = 0;
 }
 
 //********************************* delete_notify *****************************
@@ -180,6 +197,11 @@
 		free_wrlock(obj);
 		return FALSE;
 	}
+	if (obj->rd_notify) {
+		free_wrlock(obj);
+		notify(ist, obj, READ_NOTIFY);
+		get_wrlock(obj, NO_WAIT);
+	}
 	if (obj->immutable) {
 		free_wrlock(obj);
 		return TRUE;
@@ -191,7 +213,6 @@
 	clist_push(lockstack, obj);
 	obj->rdlock_cnt++;
 	obj->state = OBJ_STATE_NEW_OR_MARKED;
-	if (obj->rd_notify) notify(ist, obj, READ_NOTIFY);
 	free_wrlock(obj);
 	return TRUE;
 }
@@ -204,6 +225,11 @@
 		free_wrlock(obj);
 		return TRUE;
 	}
+	if (obj->rd_notify) {
+		free_wrlock(obj);
+		notify(ist, obj, READ_NOTIFY);
+		get_wrlock(obj, NO_WAIT);
+	}
 	if (obj->immutable) {
 		free_wrlock(obj);
 		return FALSE;
@@ -217,7 +243,6 @@
 	clist_push(lockstack, obj);
 	obj->rdlock_cnt++;
 	obj->state = OBJ_STATE_NEW_OR_MARKED;
-	if (obj->rd_notify) notify(ist, obj, READ_NOTIFY);
 	free_wrlock(obj);
 	return FALSE;
 }
@@ -258,7 +283,6 @@
 		free_wrlock(obj);
 		return FALSE;
 	}
-	if (obj->wr_notify) notify(ist, obj, WRITE_NOTIFY);
 	return TRUE;
 }
 
@@ -294,13 +318,12 @@
 		apr_thread_mutex_unlock(write_mutex);
 		obj->rdlock_cnt += sav_cnt;
 	}
-	if (obj->wr_notify) notify(ist, obj, WRITE_NOTIFY);
 	return FALSE;
 }
 
 //********************************* write_unlock ******************************
 void write_unlock(isp ist, obj_p obj) {
-	int write_ready_flag;
+	int write_ready_flag, write_notify_flag;
 	if (obj->immutable) return;
 	pr_assert(obj->wrlock);
 	obj->archived = FALSE;
@@ -312,9 +335,11 @@
 			clist_append(to_be_scanned_list, obj);
 		pr_unlock(&to_be_scanned_list_lock);
 	}
-	write_ready_flag = obj->wrlock_req_cnt;	
+	write_ready_flag  = obj->wrlock_req_cnt;
+	write_notify_flag = obj->wr_notify;
 	free_wrlock(obj);
-	if (write_ready_flag) apr_thread_cond_broadcast(write_cond);
+	if (write_ready_flag)  apr_thread_cond_broadcast(write_cond);
+	if (write_notify_flag) notify(ist, obj, WRITE_NOTIFY);
 }
 
 //********************************* pr_lock ********************************

Modified: trunk/src/lock.h
===================================================================
--- trunk/src/lock.h	2004-06-28 03:33:22 UTC (rev 671)
+++ trunk/src/lock.h	2004-06-28 08:04:40 UTC (rev 672)
@@ -71,6 +71,8 @@
 #define lock_init(lock_var)	(apr_atomic_set32(&lock_var, 0))
 #endif
 
+#define lockstack	((clist_p)(ist->lock_stack))
+
 typedef struct {
 	int					waiting;
 	apr_uint32_t		lock;

Modified: trunk/src/memory_mgr.c
===================================================================
--- trunk/src/memory_mgr.c	2004-06-28 03:33:22 UTC (rev 671)
+++ trunk/src/memory_mgr.c	2004-06-28 08:04:40 UTC (rev 672)
@@ -87,6 +87,26 @@
 	obj->wrlock_req_cnt = 0;			
 }
 
+//********************************* mm_read_lock *********************************
+int mm_read_lock(isp ist, obj_p obj) {
+	get_wrlock(obj, NO_WAIT);
+	if (obj->immutable) {
+		free_wrlock(obj);
+		return FALSE;
+	}
+	if (obj->wrlock_req_cnt && !clist_in(lockstack, obj)) { 
+		while(obj->wrlock_req_cnt) {
+			free_wrlock(obj);
+			get_wrlock(obj, WAIT);
+		}
+	}
+	clist_push(lockstack, obj);
+	obj->rdlock_cnt++;
+	obj->state = OBJ_STATE_NEW_OR_MARKED;
+	free_wrlock(obj);
+	return FALSE;
+}
+
 //********************************* mm_write_lock *****************************
 void mm_write_lock(isp ist, obj_p obj) {
 	get_wrlock(obj, NO_WAIT);
@@ -117,6 +137,7 @@
 	obj_p thread_obj = register_thread(handle);
 	pr_thread_p thread_p = thread_obj->data.ptr;
 	isp ist = thread_p->ist;
+	int i;
 
 	obj_p mm_obj_list = NEW_LIST(100);
 	obj_p mm_obj_act_param[] = {OBJ(NOKEY), mm_obj_list}; 
@@ -169,10 +190,16 @@
 		obj->scanned = TRUE;
 		mm_write_unlock(obj);
 markscan:
+		if (ist->exception_obj)
+			i=0;
 		while(TRUE) {
 			obj_p val;
 			obj_count++;
-			read_lock(ist, obj);
+			if (ist->exception_obj)
+				i=0;
+			mm_read_lock(ist, obj);
+			if (ist->exception_obj)
+				i=0;
 			if (obj->has_attrs) {
 				int i;
 				attr_p attrs = obj->attr_proto.attrs;
@@ -205,7 +232,11 @@
 			}
 			if (obj->data_type == DATA_TYPE_DATAPTR) {
 				obj_p obj_list;
-				mm_write_lock(ist, mm_obj_list);
+				if (ist->exception_obj)
+					i=0;
+				mm_write_lock(ist, mm_obj_list); 
+				if (ist->exception_obj)
+					i=0;
 				listlen(mm_obj_list) = 0;
 				write_unlock(ist, mm_obj_list);
 				obj_list = call_func(ist, obj, SYM(OBJLIST_), 2, mm_obj_act_param, NULL);
@@ -239,6 +270,9 @@
 				}
 			}
 			read_unlock(ist, obj);
+			if (ist->exception_obj)
+				i=0;
+
 			pr_lock(&to_be_scanned_list_lock);
 			if (clist_len(to_be_scanned_list)) {
 				obj = clist_pop_dups(to_be_scanned_list);
@@ -247,6 +281,8 @@
 				pr_unlock(&to_be_scanned_list_lock);
 				break;
 			}
+			if (ist->exception_obj)
+				i=0;
 		}
 		apr_sleep(1000);
 		pr_lock(&to_be_scanned_list_lock);

Modified: trunk/src/object.h
===================================================================
--- trunk/src/object.h	2004-06-28 03:33:22 UTC (rev 671)
+++ trunk/src/object.h	2004-06-28 08:04:40 UTC (rev 672)
@@ -148,6 +148,7 @@
 long_p cstr2longp(isp ist, char *str, char **pend, int base);
 obj_p long_format(long_p aa, int base, int uppercase);
 long_p new_longp(i64_t ival);
+long long_hash(long_p v);
 int int_is_zero(obj_p obj);
 u8_t* bytes_ptr(obj_p obj);
 size_t bytes_len(obj_p obj);