rev 678 - in trunk: include/prothon modules/Re pr/test src

SVN User <[email protected]> Tue, 29 Jun 2004 18:43:05 -0400
Newsgroups gmane.comp.lang.prothon.cvs
Message-ID <[email protected]>
Author: mark
Date: 2004-06-29 18:43:01 -0400 (Tue, 29 Jun 2004)
New Revision: 678

Modified:
   trunk/include/prothon/prothon.h
   trunk/include/prothon/prothon_dll.h
   trunk/modules/Re/Re.c
   trunk/pr/test/test.pr
   trunk/src/builtins-core.c
   trunk/src/builtins-dict.c
   trunk/src/builtins-list.c
   trunk/src/interp.c
   trunk/src/lock.c
   trunk/src/memory_mgr.c
   trunk/src/object.c
   trunk/src/object.h
   trunk/src/parser_routines.c
Log:
properties finished and tested

Modified: trunk/include/prothon/prothon.h
===================================================================
--- trunk/include/prothon/prothon.h	2004-06-29 21:08:56 UTC (rev 677)
+++ trunk/include/prothon/prothon.h	2004-06-29 22:43:01 UTC (rev 678)
@@ -897,9 +897,9 @@
 // mutable sequence object such as a list or dictionary.  If you pass a super 
 // object as a key then you can access attributes of proto objects.  These are the
 // routines called by the Prothon interpreter for general access.
-obj_p get_item(isp ist, obj_p obj, obj_p key);
-void  set_item(isp ist, obj_p obj, obj_p key, obj_p value);
-void  del_item(isp ist, obj_p obj, obj_p key);
+obj_p get_item(isp ist, obj_p obj, obj_p key, int prop_flg);
+void  set_item(isp ist, obj_p obj, obj_p key, obj_p value, int prop_flg);
+void  del_item(isp ist, obj_p obj, obj_p key, int prop_flg);
 
 // NEW_SLICE_OBJ: This is the object that represents a slice of a sequence.
 // A slice is one, two, or three objects such as the two ints in x[5:9].  A slice 
@@ -1125,7 +1125,7 @@
 // NULL may be passed for lbl_val_arr and/or dyn_locals if those features aren't needed.
 // Example: "sum=x+y"  =>  sum = call_func(ist, x, sym(ist, "add_"), 2, y_arr, NULL);
 //         where y_arr =>  obj_p y_arr[2] = {NULL, y};
-obj_p call_func( isp ist, obj_p self, obj_p func_sym, 
+obj_p call_func( isp ist, obj_p cont_self, obj_p func_sym, obj_p self,
 				 int parm_cnt, obj_p* lbl_val_arr, obj_p super_obj );
 
 
@@ -1134,7 +1134,7 @@
 // CALL_FUNCn: Macros to easily call functions with zero or more params
 obj_p call_func1_f(isp ist, obj_p self, obj_p sym, obj_p parm);
 obj_p call_func2_f(isp ist, obj_p self, obj_p sym, obj_p parm1, obj_p parm2);
-#define call_func0(ist, self, sym)					call_func((ist), (self), (sym), 0, NULL, NULL)
+#define call_func0(ist, self, sym)					call_func((ist), (self), (sym), NULL, 0, NULL, NULL)
 #define call_func1(ist, self, sym, parm)			call_func1_f((ist), (self), (sym), (parm))
 #define call_func2(ist, self, sym, parm1, parm2)	call_func2_f((ist), (self), (sym), (parm1), (parm2))
 

Modified: trunk/include/prothon/prothon_dll.h
===================================================================
--- trunk/include/prothon/prothon_dll.h	2004-06-29 21:08:56 UTC (rev 677)
+++ trunk/include/prothon/prothon_dll.h	2004-06-29 22:43:01 UTC (rev 678)
@@ -105,7 +105,7 @@
 	void		(*init_list_data)(isp ist, obj_p obj, int initial_size);
 	obj_p		(*copy_list_obj)(isp ist, obj_p list_obj);
 	obj_p		(*new_C_func_obj)(isp ist, pr_func* func_ptr, obj_p form_lbl_val_list);
-	obj_p		(*call_func)( isp ist, obj_p self, obj_p func_sym, 
+	obj_p		(*call_func)( isp ist, obj_p cont_self, obj_p func_sym, obj_p self,
 		                      int parm_cnt, obj_p* lbl_val_arr, obj_p dyn_locals );
 	obj_p		(*call_func1_f)(isp ist, obj_p self, obj_p sym, obj_p parm);
 	obj_p		(*call_func2_f)(isp ist, obj_p self, obj_p sym, obj_p parm1, obj_p parm2);

Modified: trunk/modules/Re/Re.c
===================================================================
--- trunk/modules/Re/Re.c	2004-06-29 21:08:56 UTC (rev 677)
+++ trunk/modules/Re/Re.c	2004-06-29 22:43:01 UTC (rev 678)
@@ -448,7 +448,7 @@
 		lastindex_obj->data.i64 = last_index;
 		if (repl_is_func) {
 			read_unlock(ist, parms[1]);
-			repl_obj = call_func(ist, NULL, parms[1], 2, arr, NULL); 
+			repl_obj = call_func(ist, NULL, parms[1], NULL, 2, arr, NULL); 
 			read_lock(ist, parms[1]);
 			if_exc_return NULL;
 			if (repl_obj == OBJ(NONE)) repl = "";

Modified: trunk/pr/test/test.pr
===================================================================
--- trunk/pr/test/test.pr	2004-06-29 21:08:56 UTC (rev 677)
+++ trunk/pr/test/test.pr	2004-06-29 22:43:01 UTC (rev 678)
@@ -1,7 +1,18 @@
 #!/usr/bin/env prothon
 
-prop x:
-	def get_():
-		return self
+object Proto1:
+	x_ = 6
+	prop x:
+		def get_():
+			return self.x_
+		def set_(v):
+			self.x_ = v
+			return v
+		def del_():
+			print "illegal delete operation"
 
-print x
+p = Proto1()
+p.x = 3
+print p.x
+del p.x
+

Modified: trunk/src/builtins-core.c
===================================================================
--- trunk/src/builtins-core.c	2004-06-29 21:08:56 UTC (rev 677)
+++ trunk/src/builtins-core.c	2004-06-29 22:43:01 UTC (rev 678)
@@ -112,7 +112,7 @@
 	obj_p new_obj;
 	parms[0] = OBJ(PARAM_STAR);  parms[2] = OBJ(PARAM_STAR_STAR);
 	new_obj = new_object(ist, self);
-	call_func(ist, new_obj, SYM(INIT_), 4, parms, NULL);
+	call_func(ist, new_obj, SYM(INIT_), NULL, 4, parms, NULL);
 	return new_obj;
 }
 
@@ -1160,18 +1160,18 @@
 		obj_p on_read_param = get_attr(ist, self, sym(ist, "onReadParam_"));
 		if (on_read_func && on_read_param) {
 			arr[3] = on_read_param;
-			call_func(ist, NULL, on_read_func, 4, arr, NULL);
+			call_func(ist, NULL, on_read_func, NULL, 4, arr, NULL);
 		} else if (on_read_func)
-			call_func(ist, NULL, on_read_func, 2, arr, NULL);
+			call_func(ist, NULL, on_read_func, NULL, 2, arr, 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[3] = on_write_param;
-			call_func(ist, NULL, on_write_func, 4, arr, NULL);
+			call_func(ist, NULL, on_write_func, NULL, 4, arr, NULL);
 		} else if (on_write_func)
-			call_func(ist, NULL, on_write_func, 2, arr, NULL);
+			call_func(ist, NULL, on_write_func, NULL, 2, arr, NULL);
 	}
 	if (flags & DELETE_NOTIFY) {
 		weak_ref_p wrp = self->data.ptr;
@@ -1180,10 +1180,10 @@
 		wrp->exists = FALSE;
 		if (on_delete_func && on_delete_param) {
 			arr[3] = on_delete_param;
-			call_func(ist, NULL, on_delete_func, 4, arr, NULL);
+			call_func(ist, NULL, on_delete_func, NULL, 4, arr, NULL);
 			check_exceptions(ist);
 		} else if (on_delete_func) {
-			call_func(ist, NULL, on_delete_func, 2, arr, NULL);
+			call_func(ist, NULL, on_delete_func, NULL, 2, arr, NULL);
 			check_exceptions(ist);
 		}
 	}

Modified: trunk/src/builtins-dict.c
===================================================================
--- trunk/src/builtins-dict.c	2004-06-29 21:08:56 UTC (rev 677)
+++ trunk/src/builtins-dict.c	2004-06-29 22:43:01 UTC (rev 678)
@@ -158,7 +158,7 @@
 		hash = dp->entry.hash;
 		if (hash < 0) { hole = dp; continue; }
 		if ( hash == hash_in && ( key == key_in ||
-			call_func(ist, key, SYM(EQ__QUES), 2, rp, NULL) == OBJ(PR_TRUE) ) ) {
+			call_func(ist, key, SYM(EQ__QUES), NULL, 2, rp, NULL) == OBJ(PR_TRUE) ) ) {
 			match = PR_TRUE;
 			break;
 		}
@@ -209,7 +209,7 @@
 	dict = (dict_p) obj_dataptr(dict_obj);
 	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), 2, rp, NULL) == OBJ(PR_TRUE) ) ) {
+			 call_func(ist, key, SYM(EQ__QUES), NULL, 2, rp, NULL) == OBJ(PR_TRUE) ) ) {
 			dict_rd_chk();
 			res = dp->entry.value;
 			read_unlock(ist, dict_obj);
@@ -485,7 +485,7 @@
 	dict = (dict_p) self->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), 2, rp, NULL) == OBJ(PR_TRUE) ) ) {
+			 call_func(ist, key, SYM(EQ__QUES), NULL, 2, rp, NULL) == OBJ(PR_TRUE) ) ) {
 			dp->entry.hash = ENTRY_DELETED;
 			dictlen(dict)--;
 			def_write_unlock(self);

Modified: trunk/src/builtins-list.c
===================================================================
--- trunk/src/builtins-list.c	2004-06-29 21:08:56 UTC (rev 677)
+++ trunk/src/builtins-list.c	2004-06-29 22:43:01 UTC (rev 678)
@@ -273,13 +273,13 @@
 		arr[1] = a;
 		arr[2] = OBJ(NOKEY);
 		arr[3] = b;
-		res = call_func(ist, NULL, cmp_func, 4, arr, NULL);
+		res = call_func(ist, NULL, cmp_func, NULL, 4, arr, NULL);
 		if_exc_return 0;
 		return (res->data.i64 < 0);
 	}
 	arr[0] = OBJ(NOKEY);
 	arr[1] = b;
-	res = call_func(ist, a, SYM(CMP_), 2, arr, NULL);
+	res = call_func(ist, a, SYM(CMP_), NULL, 2, arr, NULL);
 	if_exc_return 0;
 	return (res->data.i64 < 0);
 }
@@ -291,13 +291,13 @@
 		arr[1] = a;
 		arr[2] = OBJ(NOKEY);
 		arr[3] = b;
-		res = call_func(ist, NULL, cmp_func, 4, arr, NULL);
+		res = call_func(ist, NULL, cmp_func, NULL, 4, arr, NULL);
 		if_exc_return 0;
 		return (res->data.i64 == 0);
 	}
 	arr[0] = OBJ(NOKEY);
 	arr[1] = b;
-	res = call_func(ist, a, SYM(EQ__QUES), 2, arr, NULL);
+	res = call_func(ist, a, SYM(EQ__QUES), NULL, 2, arr, NULL);
 	if_exc_return 0;
 	return (res == OBJ(PR_TRUE));
 }

Modified: trunk/src/interp.c
===================================================================
--- trunk/src/interp.c	2004-06-29 21:08:56 UTC (rev 677)
+++ trunk/src/interp.c	2004-06-29 22:43:01 UTC (rev 678)
@@ -182,8 +182,9 @@
 }
 
 //********************************* get_item ******************************
-obj_p get_item(isp ist, obj_p ref_self, obj_p ref_key){
-	if (get_attr(ist, ref_self, SYM(GET_))) {
+obj_p get_item(isp ist, obj_p ref_self, obj_p ref_key, int prop_flg){
+	if (prop_flg && get_proto_attr(ist, ref_self, SYM(GET_), NULL, NULL)) {
+		return call_func1(ist, ref_self, SYM(GET_), ref_key);
 	}
 	if (has_proto(ist, ref_key, OBJ(SYMBOL_PROTO))) {
 		obj_p res;
@@ -193,6 +194,13 @@
 			raise_exception(ist, OBJ(NAME_EXC), "Attribute %s not found",
 					symch(ist, ref_key));
 		}
+		if (prop_flg && has_proto(ist, res, OBJ(PROP_PROTO))) {
+			if (get_proto_attr(ist, res, SYM(GET_), NULL, NULL)) {
+				return call_func(ist, res, SYM(GET_), ref_self, 0, NULL, NULL);
+			}
+			raise_exception(ist, OBJ(TYPE_EXC), "read attempt on a property with no get_ method");
+			return NULL;
+		}
 		return res;
 	} else if (has_proto(ist, ref_key, OBJ(LOCAL_PROTO))) {
 		if_exc_return NULL;
@@ -201,7 +209,7 @@
 		obj_p param[2];  
 		if_exc_return NULL;
 		param[0]=OBJ(NOKEY); param[1]=ref_key;
-        return call_func(ist, ref_self, SYM(GETITEM_), 2, param, 0);
+        return call_func(ist, ref_self, SYM(GETITEM_), NULL, 2, param, 0);
 	} else if (has_proto(ist, ref_key, OBJ(OUTER_PROTO))) {
 		obj_p res;
 		if_exc_return NULL;
@@ -214,7 +222,7 @@
 	} else if (has_proto(ist, ref_key, OBJ(INT_PROTO))) {
 		obj_p param[2];  
 		param[0]=OBJ(NOKEY); param[1]=slice1(ref_key);
-        return call_func(ist, ref_self, SYM(GETITEM_), 2, param, 0);
+        return call_func(ist, ref_self, SYM(GETITEM_), NULL, 2, param, 0);
 	} else if (has_proto(ist, ref_key, OBJ(SUPER_PROTO))) {
 		obj_p res, cont = get_attr(ist, ref_key, SYM(CONT_));
 		if (!cont) {
@@ -236,7 +244,11 @@
 }
 
 //********************************* set_item ******************************
-void set_item(isp ist, obj_p ref_self, obj_p ref_key, obj_p value){
+void set_item(isp ist, obj_p ref_self, obj_p ref_key, obj_p value, int prop_flg){
+	if (prop_flg && get_proto_attr(ist, ref_self, SYM(SET_), NULL, NULL)) {
+		call_func2(ist, ref_self, SYM(SET_), ref_key, value);
+		return;
+	}
 	if (ref_key == SYM(ATTRS_)) {
 		if (!has_proto(ist, value, OBJ(DICT_PROTO))) {
 			raise_exception(ist, OBJ(TYPE_EXC), "attempt to replace attrs_ with non-dictionary");
@@ -250,7 +262,19 @@
 		}
 		list2protos(ist, value, ref_self);
 	} else if (has_proto(ist, ref_key, OBJ(SYMBOL_PROTO))) {
-		if_exc_return;
+		if (prop_flg) {
+			obj_p res = get_proto_attr(ist, ref_self, ref_key, NULL, NULL);
+			if_exc_return;
+			if (res && has_proto(ist, res, OBJ(PROP_PROTO))) {
+				if (get_proto_attr(ist, res, SYM(SET_), NULL, NULL)) {
+					obj_p arr[2]; arr[0] = OBJ(NOKEY); arr[1] = value;
+					call_func(ist, res, SYM(SET_), ref_self, 2, arr, NULL);
+					return;
+				}
+				raise_exception(ist, OBJ(TYPE_EXC), "write attempt on a property with no set_ method");
+				return;
+			}
+		}
 		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);
@@ -258,7 +282,7 @@
 		obj_p param[4];  
 		param[0]=OBJ(NOKEY); param[1]=ref_key;
 		param[2]=OBJ(NOKEY); param[3]=value;
-        call_func(ist, ref_self, SYM(SETITEM_), 4, param, 0);
+        call_func(ist, ref_self, SYM(SETITEM_), NULL, 4, param, 0);
 	} else if (has_proto(ist, ref_key, OBJ(OUTER_PROTO))) {
 		obj_p scope_obj;
 		if_exc_return;
@@ -273,7 +297,7 @@
 		obj_p param[4];  
 		param[0]=OBJ(NOKEY); param[1]=slice1(ref_key);
 		param[2]=OBJ(NOKEY); param[3]=value;
-        call_func(ist, ref_self, SYM(SETITEM_), 4, param, 0);
+        call_func(ist, ref_self, SYM(SETITEM_), NULL, 4, param, 0);
 	} else if (has_proto(ist, ref_key, OBJ(SUPER_PROTO))) {
 		obj_p res, proto, cont = get_attr(ist, ref_key, SYM(CONT_));
 		if (!cont) {
@@ -294,7 +318,11 @@
 }
 
 //********************************* del_item ***********************************
-void del_item(isp ist, obj_p ref_self, obj_p ref_key){
+void del_item(isp ist, obj_p ref_self, obj_p ref_key, int prop_flg){
+	if (prop_flg && get_proto_attr(ist, ref_self, SYM(DEL_), NULL, NULL)) {
+		call_func1(ist, ref_self, SYM(DEL_), ref_key);
+		return;
+	}
 	if (ref_key == SYM(ATTRS_)) {
 		raise_exception(ist, OBJ(TYPE_EXC), "attempt to del attrs_");
 		return;
@@ -302,6 +330,18 @@
 		raise_exception(ist, OBJ(TYPE_EXC), "attempt to del protos_");
 		return;
 	} else if (has_proto(ist, ref_key, OBJ(SYMBOL_PROTO))) {
+		if (prop_flg) {
+			obj_p res = get_proto_attr(ist, ref_self, ref_key, NULL, NULL);
+			if_exc_return;
+			if (res && has_proto(ist, res, OBJ(PROP_PROTO))) {
+				if (get_proto_attr(ist, res, SYM(DEL_), NULL, NULL)) {
+					call_func(ist, res, SYM(DEL_), ref_self, 0, NULL, NULL);
+					return;
+				}
+				raise_exception(ist, OBJ(TYPE_EXC), "delete attempt on a property with no del_ method");
+				return;
+			}
+		}
 		if_exc_return;
 		del_attr(ist, ref_self, ref_key);
 	} else if (has_proto(ist, ref_key, OBJ(LOCAL_PROTO))) {
@@ -309,7 +349,7 @@
 	} else if (has_proto(ist, ref_key, OBJ(SLICE_PROTO))) {
 		obj_p param[2];  
 		param[0]=OBJ(NOKEY); param[1]=ref_key;
-        call_func(ist, ref_self, SYM(DELITEM_), 2, param, 0);
+        call_func(ist, ref_self, SYM(DELITEM_), NULL, 2, param, 0);
 	} else if (has_proto(ist, ref_key, OBJ(OUTER_PROTO))) {
 		obj_p scope_obj;
 		if_exc_return;
@@ -323,7 +363,7 @@
 	} else if (has_proto(ist, ref_key, OBJ(INT_PROTO))) {
 		obj_p param[2];  
 		param[0]=OBJ(NOKEY); param[1]=slice1(ref_key);
-        call_func(ist, ref_self, SYM(DELITEM_), 2, param, 0);
+        call_func(ist, ref_self, SYM(DELITEM_), NULL, 2, param, 0);
 	} else if (has_proto(ist, ref_key, OBJ(SUPER_PROTO))) {
 		obj_p res, proto, cont = get_attr(ist, ref_key, SYM(CONT_));
 		if (!cont) {
@@ -968,7 +1008,7 @@
 				else if (key == SYM(PROTOS_))
 					fr_push(new_protolist_obj(ist, obj));
 				else {
-					att = get_item(ist, obj, key); IF_EXC_BREAK;
+					att = get_item(ist, obj, key, TRUE); IF_EXC_BREAK;
 					if (!att) {
 						raise_exception( ist, OBJ(INTERPRETER_EXC), "attribute %s not found", 
 																	       as_str(ist, key) );
@@ -982,7 +1022,7 @@
 				sp1 = sp2 - param;
 				fr_sp = sp2;
 				for(i=0; i < param; i++, sp1++, sp2+=2)
-					set_item(ist, fr_stack[sp2], fr_stack[sp2+1], fr_stack[sp1]);
+					set_item(ist, fr_stack[sp2], fr_stack[sp2+1], fr_stack[sp1], TRUE);
 			}	break;
 			case OP_SEQ_ASSIGN: {
 				obj_p list;
@@ -1071,11 +1111,11 @@
 					switch_proto(ist, func, OBJ(GEN_PROTO));
 					func->data.ptr  = genp;
 				}
-				set_item(ist, fr_stack[fr_sp], fr_stack[fr_sp+1], func);
+				set_item(ist, fr_stack[fr_sp], fr_stack[fr_sp+1], func, FALSE);
 			}	break;
 			case OP_DEL:
 				fr_sp -= 2;
-				del_item(ist, fr_stack[fr_sp], fr_stack[fr_sp+1]);
+				del_item(ist, fr_stack[fr_sp], fr_stack[fr_sp+1], TRUE);
 				break;
 			case OP_BR:
 #ifdef TRACE_INTERPRETER
@@ -1182,7 +1222,7 @@
 				obj_p obj, bindee, bound_meth;
 				fr_sp -= 3;
 				if (!(bindee = fr_stack[fr_sp+2])) bindee = fr_stack[fr_sp];
-				obj = get_item(ist, fr_stack[fr_sp], fr_stack[fr_sp+1]); IF_EXC_BREAK;
+				obj = get_item(ist, fr_stack[fr_sp], fr_stack[fr_sp+1], TRUE); IF_EXC_BREAK;
 				bound_meth = copy_object(ist, obj);
 				su(i);
 				set_attr(ist, bound_meth, SYM(BINDOBJ_), bindee); 
@@ -1312,7 +1352,7 @@
 				if (num_protos == 0) new_obj = NEW_OBJ(NULL);
 				else {
 					obj_p psym = fr_stack[fr_sp+3];
-					obj_p proto = get_item(ist, fr_stack[fr_sp+2], psym); IF_EXC_BREAK;
+					obj_p proto = get_item(ist, fr_stack[fr_sp+2], psym, TRUE); IF_EXC_BREAK;
 					if (!proto) {
 						raise_exception(ist, OBJ(NAME_EXC), "prototype %s not found", as_str(ist, psym));
 						goto end_op_obj;
@@ -1321,7 +1361,7 @@
 				}
 				for (i=1; i < num_protos; i++) {
 					obj_p psym = fr_stack[fr_sp+(i+1)*2+1];
-					obj_p proto = get_item(ist, fr_stack[fr_sp+(i+1)*2], psym);
+					obj_p proto = get_item(ist, fr_stack[fr_sp+(i+1)*2], psym, TRUE);
 					if (ist->exception_obj) goto end_op_obj;
 					if (!proto) {
 						raise_exception(ist, OBJ(NAME_EXC), "prototype %s not found", as_str(ist, psym));
@@ -1739,15 +1779,16 @@
 }
 
 //******************************** call_func **********************************
-obj_p call_func( isp ist, obj_p self, obj_p func_sym, 
+obj_p call_func( isp ist, obj_p cont_self, obj_p func_sym, obj_p self,
 				 int parm_cnt, obj_p* lbl_val_arr, obj_p super_obj ) {
 	obj_p func_obj;
 	frame_p new_frame;
-	if (!self) {
+	if (!self) self = cont_self;
+	if (!self) self = NEW_OBJ(NULL);
+	if (!cont_self) {
 		func_obj = func_sym; 
-		self = NEW_OBJ(NULL);
 	} else {
-		func_obj = get_proto_attr(ist, self, func_sym, NULL, super_obj); if_exc_return NULL;
+		func_obj = get_proto_attr(ist, cont_self, func_sym, NULL, super_obj); if_exc_return NULL;
 		if (!func_obj) {
 			if (!ist) {
 				printf("Internal error with exceptions disabled: Function not found: \"%s\"", 
@@ -1780,7 +1821,6 @@
 		post_call_unlock(ist, aself, plist);
 		free_clist(plist);
 		if (intrp_exobj) return NULL;
-		if (!func_sym) del_unlock(self);
 		return res;
 	} else if ( func_obj != OBJ(FUNC_PROTO) && 
 		        has_proto(ist, func_obj, OBJ(FUNC_PROTO)) ) {
@@ -1791,16 +1831,13 @@
 
 		if (!ist) {
 			raise_exception(ist, OBJ(INTERNAL_EXC), "Illegal function call to Prothon function");
-			if (!func_sym) del_unlock(self);
 			return 0;
 		}
 		if (intrp_exobj) {
-			if (!func_sym) del_unlock(self);
 			return 0;
 		}
 		frame = ist->frame;
 		if (intrp_exobj) {
-			if (!func_sym) del_unlock(self);
 			return 0;
 		}
 		if (! (aself = get_attr(ist, func_obj, SYM(BINDOBJ_))) )
@@ -1818,15 +1855,11 @@
 		ist->frame = new_frame;
 		ist->frame->called_from_c = TRUE;
 		if (intrp_exobj) {
-			if (!func_sym) del_unlock(self);
 			return 0;
 		}
-		if (!func_sym) 
-			del_unlock(self);
 		return exec_loop(ist);
 	} else {
 		raise_exception(ist, OBJ(FUNCNOTFOUND_EXC), "Function not found");
-		if (!func_sym) del_unlock(self);
 		return 0;
 	}
 }

Modified: trunk/src/lock.c
===================================================================
--- trunk/src/lock.c	2004-06-29 21:08:56 UTC (rev 677)
+++ trunk/src/lock.c	2004-06-29 22:43:01 UTC (rev 678)
@@ -93,7 +93,7 @@
 			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);
+					call_func(ist, NULL, list_item(ist, callback_list, i+1), NULL, 2, arr, NULL);
 					check_exceptions(ist);
 				}
 			ist->notify_flags &= ~flag;

Modified: trunk/src/memory_mgr.c
===================================================================
--- trunk/src/memory_mgr.c	2004-06-29 21:08:56 UTC (rev 677)
+++ trunk/src/memory_mgr.c	2004-06-29 22:43:01 UTC (rev 678)
@@ -239,7 +239,7 @@
 					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);
+				obj_list = call_func(ist, obj, SYM(OBJLIST_), NULL, 2, mm_obj_act_param, NULL);
 				if (ist->exception_obj) {
 					printf("\nWarning: memory manager unable to scan object: %lx\n",
 						(unsigned long)(uintptr_t)obj);
@@ -312,7 +312,7 @@
 			obj_count++;
 			if (obj->state != OBJ_STATE_NEW_OR_MARKED && !obj->del_locked) {
 				delete_notify(ist, obj);
-				call_func(ist, obj, SYM(FINAL_), 0, NULL, NULL);
+				call_func(ist, obj, SYM(FINAL_), NULL, 0, NULL, NULL);
 				check_exceptions(ist);
 				mm_write_lock(ist, obj);
 				ist->exception_obj = 0;
@@ -352,7 +352,7 @@
 		pr_unlock(&object_list_lock); 
 		while(obj) {
 			obj_count++;
-			call_func(ist, obj, SYM(FINAL_), 0, NULL, NULL);
+			call_func(ist, obj, SYM(FINAL_), NULL, 0, NULL, NULL);
 			check_exceptions(ist);
 			pr_lock(&object_list_lock); 
 			obj = obj->next_obj;

Modified: trunk/src/object.c
===================================================================
--- trunk/src/object.c	2004-06-29 21:08:56 UTC (rev 677)
+++ trunk/src/object.c	2004-06-29 22:43:01 UTC (rev 678)
@@ -1086,7 +1086,7 @@
 	obj_p arr[2];
 	arr[0] = OBJ(NOKEY); 
 	arr[1] = parm; 
-	return call_func(ist, self, sym, 2, arr, NULL);
+	return call_func(ist, self, sym, NULL, 2, arr, NULL);
 }
 
 //********************************* call_func2_f ********************************
@@ -1094,7 +1094,7 @@
 	obj_p arr[4];
 	arr[0] = OBJ(NOKEY);  arr[1] = parm1; 
 	arr[2] = OBJ(NOKEY);  arr[3] = parm2; 
-	return call_func(ist, self, sym, 4, arr, NULL);
+	return call_func(ist, self, sym, NULL, 4, arr, NULL);
 }
 
 

Modified: trunk/src/object.h
===================================================================
--- trunk/src/object.h	2004-06-29 21:08:56 UTC (rev 677)
+++ trunk/src/object.h	2004-06-29 22:43:01 UTC (rev 678)
@@ -136,8 +136,8 @@
 extern obj_p debug_obj;
 extern obj_p debug_obj_proto;
 
-void set_item(isp ist, obj_p ref_self, obj_p ref_key, obj_p value);
-void del_item(isp ist, obj_p ref_self, obj_p ref_key);
+void set_item(isp ist, obj_p ref_self, obj_p ref_key, obj_p value, int prop_flg);
+void del_item(isp ist, obj_p ref_self, obj_p ref_key, int prop_flg);
 
 obj_p new_protolist_obj(isp ist, obj_p obj);
 obj_p new_attrdict_obj(isp ist, obj_p obj);

Modified: trunk/src/parser_routines.c
===================================================================
--- trunk/src/parser_routines.c	2004-06-29 21:08:56 UTC (rev 677)
+++ trunk/src/parser_routines.c	2004-06-29 22:43:01 UTC (rev 678)
@@ -628,9 +628,10 @@
 		calc_code(clist_item(protos, i),&len, &stack_depth, &max_stack_depth);
 	len += (label ? 2 : 3);
 	res = new_code(param, len, stack_depth, max_stack_depth, 0);
-	if (label)
+	if (label) {
 		res->code_data[k++].bytecode.opcode = OP_PUSH_LOCAL_REF;
 		res->code_data[k++].data = sym(IST, pr2c_strptr(IST, label));
+	}
 	if (ref)
 		add_code(ref, res, &k);
 	for (i=0; i < llen; i++)
@@ -643,7 +644,7 @@
 	}
 	func = new_object(IST, OBJ(FUNC_PROTO));
 	code_len = sizeof(code) + body->len * sizeof(code_t);
-	memmove(obj_malloc(IST, OBJ(FUNC_PROTO), func, code_len), body, code_len);
+	memcpy(obj_malloc(IST, OBJ(FUNC_PROTO), func, code_len), body, code_len);
 	res->code_data[k++].data = func;
 	if (!label)
 		res->code_data[k++].num  = llen;