rev 587 - in trunk: . bin include/prothon modules modules/DBM modules/OS modules/Prosist modules/Re modules/SQLite src

SVN User <[email protected]> Wed, 09 Jun 2004 17:40:54 -0400
Newsgroups gmane.comp.lang.prothon.cvs
Message-ID <[email protected]>
Author: mark
Date: 2004-06-09 17:40:50 -0400 (Wed, 09 Jun 2004)
New Revision: 587

Added:
   trunk/src/builtins-bytes.c
   trunk/src/builtins-file.c
Removed:
   trunk/modules/File/
Modified:
   trunk/STATUS.txt
   trunk/bin/rel.pth
   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/prothon.sln
   trunk/src/builtins-attrdict.c
   trunk/src/builtins-core.c
   trunk/src/builtins-dict.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-tuple.c
   trunk/src/console.c
   trunk/src/dict.h
   trunk/src/init.pth
   trunk/src/interp.c
   trunk/src/main.c
   trunk/src/memory_mgr.c
   trunk/src/object.c
   trunk/src/object.h
   trunk/src/parser.h
   trunk/src/parser_routines.c
   trunk/src/prlist.h
   trunk/src/src.vcproj
   trunk/src/symbol.c
   trunk/src/sys.c
Log:
moved file to builtins, added Bytes type, String now
stored with 24-bit chars, build is very broken

Modified: trunk/STATUS.txt
===================================================================
--- trunk/STATUS.txt	2004-06-08 13:13:51 UTC (rev 586)
+++ trunk/STATUS.txt	2004-06-09 21:40:50 UTC (rev 587)
@@ -1,6 +1,10 @@
 
 ----------------------- TO-DO (highest priority first) ------------------------
 
+--- binaryObj = Bytes("Hello world", "ascii") (or "latin-1") exception to tell "latin-1"
+
+--- allow tracebacks in the constructors to exception objects or raise command
+
 --- add names to str.mod_, fix int display in str.mod_
 
 --- put in skeleton code for + _"abc"
@@ -30,6 +34,11 @@
 --- Traceback objects (stack trace of an exception), exceptions should show function names
 --- Fix error reporting mess, hide fake file names
 
+--- raise exception_object, doc_object
+--- except exception_object, tgt_obj
+
+--- concatenate adjacent strings  "abc" "def" -> "abcdef"
+
 --- allow strings to compare with symbols
 
 --- add conditional expression "if C then x else y"

Modified: trunk/bin/rel.pth
===================================================================
--- trunk/bin/rel.pth	2004-06-08 13:13:51 UTC (rev 586)
+++ trunk/bin/rel.pth	2004-06-09 21:40:50 UTC (rev 587)
@@ -20,7 +20,6 @@
 # this period adds this prothon home directory to Sys.path
 .
 
-# this imports the File module
-# (which should probably be a built-in anyway)
+# import commands would follow here
 
-import File
+#import Re
Modified: trunk/include/prothon/prothon.h
===================================================================
--- trunk/include/prothon/prothon.h	2004-06-08 13:13:51 UTC (rev 586)
+++ trunk/include/prothon/prothon.h	2004-06-09 21:40:50 UTC (rev 587)
@@ -144,6 +144,12 @@
 typedef i32_t			attr_key_t;
 typedef struct obj_s*	obj_p;
 
+typedef enum {
+	OBJ_STATE_NEW_OR_MARKED = 0,
+	OBJ_STATE_UNMARKED,
+	OBJ_STATE_DELETED
+} obj_state_t;
+
 typedef struct {
 	int			size;
 	int			len;
@@ -167,32 +173,38 @@
 
 typedef attr_t* attr_p;
 
-typedef enum {
-	OBJ_STATE_NEW_OR_MARKED = 0,
-	OBJ_STATE_UNMARKED,
-	OBJ_STATE_DELETED
-} obj_state_t;
+typedef union {
+	attr_p	attrs;
+	obj_p	proto;
+} attr_proto_t;
 
 typedef enum {
 	DATA_TYPE_NONE = 0,
 	DATA_TYPE_IMMDATA,
 	DATA_TYPE_DATAPTR,
-	DATA_TYPE_FUNCPTR
+	DATA_TYPE_EXTPTR
 } data_type_t;
 
-typedef union {
-	attr_p	attrs;
-	obj_p	proto;
-} attr_proto_t;
+typedef u32_t data_size_t;
 
-#define IMMEDIATE_DATA_LEN 8
+#define IMM_DATA_LEN 8
+#define DATA_SIZE(obj)	(*((data_size_t*)((obj)->data.ptr)))
 
+typedef struct {
+	u8_t	b0;
+	u8_t	b1;
+	u8_t	b2;
+} ch3_t;
+
+typedef ch3_t* ch3_p;
+
 typedef union {
 	attr_key_t	key;
 	double		f64;
 	i64_t		i64;
-	i32_t		i32[IMMEDIATE_DATA_LEN/4];
-	char		str[IMMEDIATE_DATA_LEN];
+	i32_t		i32[IMM_DATA_LEN/4];
+	ch3_t		str[IMM_DATA_LEN/3];
+	u8_t		bytes[IMM_DATA_LEN];
 	void*		ptr;
 } obj_data_t;
 
@@ -223,13 +235,20 @@
 	obj_p			next_obj;
 } obj_t;
 
-typedef struct  {
-	size_t	len;
-	char	str[];
-} pr_str_t;
+typedef struct {
+	data_size_t	len;
+	u8_t		byt[];
+} byt_t;
 
-typedef pr_str_t* pr_str_p;
+typedef byt_t* byt_p;
 
+typedef struct {
+	data_size_t	size;
+	ch3_t		str[];
+} str_t;
+
+typedef str_t* str_p;
+
 typedef struct frame_t* frame_p;
 typedef struct interp_state_s* isp;
 
@@ -241,6 +260,7 @@
 typedef user_thread_t* user_thread_p;
 
 typedef struct {
+	data_size_t			size;
 	apr_os_thread_t		apr_os_thread;
 	apr_thread_t*		apr_thread;
 	isp					ist;
@@ -256,9 +276,9 @@
 typedef u16_t digit;
 
 typedef struct {
-	u32_t	size;
-	i32_t	dsize;
-	digit	digit[];
+	data_size_t	size;
+	i32_t		dsize;
+	digit		digit[];
 } long_t;
 
 typedef long_t* long_p;
@@ -282,11 +302,11 @@
  
 // prototype objects used as protos for basic "types"
 	INT_PROTO,			// 4 Int
-	LONG_PROTO,			// 5 Long
-	FLOAT_PROTO,		// 6 Float
-	IMAG_PROTO,			// 7 Imaginary
-	SYMBOL_PROTO,		// 8 Symbol
-	SEQ_PROTO,			// 9
+	FLOAT_PROTO,		// 5 Float
+	IMAG_PROTO,			// 6 Imaginary
+	SYMBOL_PROTO,		// 7 Symbol
+	SEQ_PROTO,			// 8 Sequence
+	BYTES_PROTO,		// 9 Bytes
 	STRING_PROTO,		// 10 String
 	TUPLE_PROTO,		// 11 Tuple
 	LIST_PROTO,			// 12 List
@@ -297,7 +317,7 @@
 	SLICE_PROTO,		// 17 Slice
 	LOCAL_PROTO,		// 18 
 	OUTER_PROTO,		// 19 
-	SUPER_PROTO,			// 20
+	SUPER_PROTO,		// 20
 	GEN_PROTO,			// 21 
 	THREAD_PROTO,		// 22 Thread
 	MUTEX_PROTO,		// 23 Mutex
@@ -428,7 +448,6 @@
 	SETITEM_,
 	DELITEM_,
 	OBJLIST_,
-	CDATALEN_,
 	DEL_,
 	LEN,
 	MAX,
@@ -649,8 +668,12 @@
 obj_p new_float_obj(isp ist, double num);
 #define NEW_FLOAT(num) new_float_obj(ist, num)
 
+// NEW_BYTES_OBJ: Create a new bytes object from a data buffer.
+obj_p new_bytes_obj(isp ist, const u8_t* buffer, size_t len);
+#define NEW_BYTES(buf, len) new_bytes_obj(ist, buf, len)
+
 // NEW_STRING_OBJ: Create a new string object from a C string.
-obj_p new_string_obj(isp ist, const char* string);
+obj_p new_string_obj(isp ist, char* string);
 #define NEW_STRING(string)  new_string_obj(ist, string)
 
 // NEW_STRING_OBJ_N: Create a new string object from a C string of N chars long.
@@ -660,22 +683,17 @@
 
 // SET_STRING_DATA: Change an existing object's data to string data
 // clobbers any esisting data pointer
-void set_string_data(isp ist, obj_p obj, char* p, size_t len);
+void c2pr_strcpy(isp ist, obj_p obj, char* p, size_t len);
 
-// PR_STRPTR: macro to retreive string object as a C string
-// warning, string objects may contain null chars so C string result may be short
-// This corresponds to dptr member of apr_datum_t.
-#define pr_strptr(str_obj)																		\
-(                                !(str_obj) ?                                   NULL :			\
-  (str_obj)->data_type == DATA_TYPE_IMMDATA ?             (str_obj)->data.str        :			\
- ((str_obj)->data_type == DATA_TYPE_DATAPTR ? ((pr_str_p)((str_obj)->data.ptr))->str : NULL) )
+// PR_STRPTR: retreive string object as a C string
+char* pr2c_strptr(isp ist, obj_p str_obj);
 
 // PR_STRLEN: macro to retreive string length of a string object
 // warning, string objects may contain null chars that this length ignores
 // This corresponds to dsize member of apr_datum_t.
-#define pr_strlen(str_obj)																		\
-	( ((str_obj)->data_type == DATA_TYPE_IMMDATA) ?    (size_t)((str_obj)->imm_data_len)   :	\
-	 (((str_obj)->data_type == DATA_TYPE_DATAPTR) ? ((pr_str_p)((str_obj)->data.ptr))->len : 0 ) )
+#define pr_strlen(str_obj)																		    \
+	( ((str_obj)->data_type == DATA_TYPE_IMMDATA) ? (((size_t)((str_obj)->imm_data_len))/3):		\
+	 (((str_obj)->data_type == DATA_TYPE_DATAPTR) ? ((DATA_SIZE(str_obj)-sizeof(str_t))/3) : 0 ) )
 
 // NEW_LIST_OBJ: Create a new list object with a given initial size
 obj_p new_list_obj(isp ist, size_t initial_size);
@@ -717,7 +735,6 @@
 obj_p list_append(isp ist, obj_p list, obj_p item);
 
 // LIST_LEN: Get length of list
-
 size_t list_len(isp ist, obj_p list);
 
 // LIST_CLEAR: Set length of list to zero
@@ -962,7 +979,7 @@
 		raise_exception(ist, OBJ(TYPE_EXC),									\
 				"expected a string in parameter " #index);					\
 		return NULL;														\
-	} (var) = pr_strptr((index > 0 ? parms[((index)-1)*2+1] : list_item(ist, parms[1], -index))); }
+	} (var) = pr2c_strptr(ist, (index > 0 ? parms[((index)-1)*2+1] : list_item(ist, parms[1], -index))); }
 	
 
 #define FUNC___PARAM(index, var)	/* obj_p var; */						\
@@ -989,7 +1006,7 @@
 				"expected a string in parameter " #index);					\
 		return NULL;														\
 	}																		\
-	(var).dptr  = pr_strptr((index > 0 ? parms[((index)-1)*2+1] : list_item(ist, parms[1], -index)));	\
+	(var).dptr  = pr2c_strptr(ist, (index > 0 ? parms[((index)-1)*2+1] : list_item(ist, parms[1], -index)));	\
 	(var).dsize = pr_strlen((index > 0 ? parms[((index)-1)*2+1] : list_item(ist, parms[1], -index))); }
 
 #define SEQ_NS_PARAM(index, var)	/* obj_p var; */						\
@@ -1003,8 +1020,8 @@
 
 
 #define SEQ_OR_PARAM(index, var)	/* obj_p var; */						\
-	if ( has_proto(ist, ITEM, OBJ(STRING_PROTO)) ||					\
-		!has_proto(ist, ITEM, OBJ(SEQ_PROTO))) {						\
+	if ( has_proto(ist, ITEM, OBJ(STRING_PROTO)) ||					        \
+		!has_proto(ist, ITEM, OBJ(SEQ_PROTO))) {						    \
 		list = NEW_LIST(1);													\
 		list_append(ist, list, ITEM);										\
 		(var) = list;														\
@@ -1064,7 +1081,7 @@
 
 // AS_STR: Call str_ function on any object
 // Get C string representation of any object by calling str_ function on it.
-#define as_str(ist, obj) pr_strptr(call_func0((ist), (obj), SYM(STR_)))
+#define as_str(ist, obj) pr2c_strptr(ist, call_func0((ist), (obj), SYM(STR_)))
 
 // COVERS: Macro to determine if a type can be coerced to another type
 // Returns true if data type of o1 can represent all data that type of o2 can
@@ -1122,13 +1139,19 @@
 void* obj_realloc(isp ist, obj_p obj, size_t size);
 void  obj_free   (isp ist, obj_p obj);
 
-// OBJ_DATA_P: returns the C ptr to the data area for an object.
-#define obj_data_p(obj)															\
-	(                                 !obj ?   NULL            :				\
+// 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_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 ) ) )
 
+
 //************************** OBJECT LOCKING ***********************************
 // Prothon allows multiple threads to run at once and even multiple interpreters.
 // Data is shared at the object level.  There is only one set of objects that

Modified: trunk/include/prothon/prothon_dll.h
===================================================================
--- trunk/include/prothon/prothon_dll.h	2004-06-08 13:13:51 UTC (rev 586)
+++ trunk/include/prothon/prothon_dll.h	2004-06-09 21:40:50 UTC (rev 587)
@@ -90,9 +90,9 @@
 	obj_p		(*new_hash_obj)(isp ist, i32_t num);
 	obj_p		(*new_int_obj)(isp ist, i64_t num);
 	obj_p		(*new_float_obj)(isp ist, double num);
-	obj_p		(*new_string_obj)(isp ist, const char* string);
+	obj_p		(*new_string_obj)(isp ist, char* string);
 	obj_p		(*new_string_n_obj)(isp ist, char* string, size_t n);
-	void		(*set_string_data)(isp ist, obj_p obj, char* p, size_t len);
+	void		(*c2pr_strcpy)(isp ist, obj_p obj, char* p, size_t len);
 	obj_p		(*new_tuple_obj)(isp ist, int fixed_size);
 	obj_p		(*new_list_obj)(isp ist, size_t initial_size);
 	void		(*init_list_data)(isp ist, obj_p obj, int initial_size);
@@ -125,6 +125,7 @@
 	void		(*dump)(isp ist, char* dumpfilename, obj_p obj);
 	i32_t		(*int2i32t)(isp ist, obj_p self);
 	i64_t		(*int2i64t)(isp ist, obj_p self);
+	char*		(*pr2c_strptr)(isp ist, obj_p str_obj);
 
 	void*		(*pr_malloc)(size_t nbytes);
 	void*		(*pr_realloc)(void *p, size_t nbytes);
@@ -290,7 +291,7 @@
 #define new_float_obj		(*services->new_float_obj)
 #define new_string_obj		(*services->new_string_obj)
 #define new_string_n_obj	(*services->new_string_n_obj)
-#define set_string_data		(*services->set_string_data)
+#define c2pr_strcpy		(*services->c2pr_strcpy)
 #define new_tuple_obj		(*services->new_tuple_obj)
 #define new_list_obj		(*services->new_list_obj)
 #define init_list_data		(*services->init_list_data)
@@ -349,6 +350,7 @@
 #define dump		 		(*services->dump)
 #define int2i64t		 	(*services->int2i64t)
 #define int2i32t	 		(*services->int2i32t)
+#define pr2c_strptr	 		(*services->pr2c_strptr)
 
 #endif // OBJECT_H
 

Modified: trunk/modules/DBM/DBM.c
===================================================================
--- trunk/modules/DBM/DBM.c	2004-06-08 13:13:51 UTC (rev 586)
+++ trunk/modules/DBM/DBM.c	2004-06-09 21:40:50 UTC (rev 587)
@@ -116,7 +116,7 @@
 	apr_pool_t* pool;
 	obj_p res;
 	char *name, *type;
-	const char *used1, *used2;
+	char *used1, *used2;
 
 	BIN_CONTENT_CHK(DB);
 
Modified: trunk/modules/OS/OS.c
===================================================================
--- trunk/modules/OS/OS.c	2004-06-08 13:13:51 UTC (rev 586)
+++ trunk/modules/OS/OS.c	2004-06-09 21:40:50 UTC (rev 587)
@@ -74,7 +74,7 @@
 		set_obj_doc(ist->exception_obj, "object is not of type string");
 		return NULL;										
 	}
-	return NEW_INT(system(pr_strptr(parms[1])));
+	return NEW_INT(system(pr2c_strptr(ist, parms[1])));
 }
 
 MAIN_MODULE_INIT(OS)

Modified: trunk/modules/Prosist/Prosist.c
===================================================================
--- trunk/modules/Prosist/Prosist.c	2004-06-08 13:13:51 UTC (rev 586)
+++ trunk/modules/Prosist/Prosist.c	2004-06-09 21:40:50 UTC (rev 587)
@@ -329,7 +329,7 @@
 	}
 	if (has_proto(ist, proxy_obj, OBJ(STRING_PROTO))) {
 		ADD_CHR('s');
-		ADD_MEM(pr_strptr(proxy_obj), (int) pr_strlen(proxy_obj));
+		ADD_MEM(pr2c_strptr(ist, proxy_obj), (int) pr_strlen(proxy_obj));
 	} else if (has_proto(ist, proxy_obj, OBJ(TUPLE_PROTO))) {
 		int llen = (int) list_len(ist, proxy_obj);
 		ADD_CHR('l');
@@ -432,8 +432,8 @@
 		ADD_BUF_START();
 		ADD_NUM(id); 
 		ADD_BUF_TO_DATUM(key);
-		s1 = pr_strptr(list_item(ist, id_tuple, 0));
-		s2 = pr_strptr(list_item(ist, id_tuple, 1));
+		s1 = pr2c_strptr(ist, list_item(ist, id_tuple, 0));
+		s2 = pr2c_strptr(ist, list_item(ist, id_tuple, 1));
 		slen = strlen(s1)+strlen(s2)+2;
 		ADD_BUF_START();
 		ADD_CHR('`');
@@ -631,7 +631,7 @@
 				memcpy(&(obj->data), p+1, sizeof(obj->data));
 				goto done;
 			case 's':
-				set_string_data(ist, obj, p+1, end-(p+1));
+				c2pr_strcpy(ist, obj, p+1, end-(p+1));
 				goto done;
 			case '`':
 				del_unlock(obj);

Modified: trunk/modules/Re/Re.c
===================================================================
--- trunk/modules/Re/Re.c	2004-06-08 13:13:51 UTC (rev 586)
+++ trunk/modules/Re/Re.c	2004-06-09 21:40:50 UTC (rev 587)
@@ -408,7 +408,7 @@
 	set_attr(ist, match_obj, sym(ist, "lastindex"),	lastindex_obj);
 	arr[0] = 0; arr[1] = match_obj;
 	if (!repl_is_func) 
-		repl  = pr_strptr(parms[1]);
+		repl  = pr2c_strptr(ist, parms[1]);
 	m = pr_malloc((ngrps+1)*sizeof(regmatch_t));
 	m[0].rm_so = -1; m[0].rm_eo = 0;
 	last_split = 0;
@@ -457,7 +457,7 @@
 					raise_exception(ist, OBJ(TYPE_EXC), "repl callback function must return a string");
 					return NULL;
 				}
-				repl = pr_strptr(repl_obj);
+				repl = pr2c_strptr(ist, repl_obj);
 			}
 		}
 		p1 = repl;
@@ -569,7 +569,7 @@
 	s_lim = s + size;
 	p2 = s;
 	orig_s_obj = get_attr(ist, self, sym(ist, "string")); if_exc_return NULL;
-	orig_s = pr_strptr(orig_s_obj);
+	orig_s = pr2c_strptr(ist, orig_s_obj);
 	if (unescape(ist, self, orig_s, &p1, &p2, &s, &s_lim)) return NULL;
 	res = NEW_STRING(s);
 	pr_free(s);
@@ -605,7 +605,7 @@
 		}
 	}
 	orig_s_obj = get_attr(ist, self, sym(ist, "string")); if_exc_return NULL;
-	orig_s = pr_strptr(orig_s_obj);
+	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);
@@ -632,7 +632,7 @@
 	char* orig_s;
 	obj_p orig_s_obj, res = NEW_TUPLE(ngrps);
 	orig_s_obj = get_attr(ist, self, sym(ist, "string")); if_exc_return NULL;
-	orig_s = pr_strptr(orig_s_obj);
+	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);

Modified: trunk/modules/SQLite/SQLite.c
===================================================================
--- trunk/modules/SQLite/SQLite.c	2004-06-08 13:13:51 UTC (rev 586)
+++ trunk/modules/SQLite/SQLite.c	2004-06-09 21:40:50 UTC (rev 587)
@@ -105,7 +105,7 @@
 	obj_p conn_obj;
 	char *filename, *errmsg=NULL;
 	CHECK_TYPE_EXC(parms[1], OBJ(STRING_PROTO), "string");
-	filename = pr_strptr(parms[1]);
+	filename = pr2c_strptr(ist, parms[1]);
 	conn_obj = NEW_OBJ(Connection_OBJ);
 	set_obj_doc(conn_obj, "SQLite connection");
 	conn_obj->unclonable = TRUE;
@@ -195,7 +195,7 @@
 
 	BIN_CONTENT_CHK(Cursor);
 	CHECK_TYPE_EXC(parms[1], OBJ(STRING_PROTO), "string");
-	sql = pr_strptr(parms[1]);
+	sql = pr2c_strptr(ist, parms[1]);
 	if (parms[3] != OBJ(NONE)) {
 		raise_exception(ist, Error_OBJ, "parameters not implemented yet");
 		return NULL;

Modified: trunk/prothon.sln
===================================================================
--- trunk/prothon.sln	2004-06-08 13:13:51 UTC (rev 586)
+++ trunk/prothon.sln	2004-06-09 21:40:50 UTC (rev 587)
@@ -7,10 +7,6 @@
 	ProjectSection(ProjectDependencies) = postProject
 	EndProjectSection
 EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "file", "modules\file\file.vcproj", "{84FEC2DB-F084-4C16-9442-FBA3908FCA95}"
-	ProjectSection(ProjectDependencies) = postProject
-	EndProjectSection
-EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Prosist", "modules\Prosist\Prosist.vcproj", "{ED1B9F21-0026-4156-881C-4F083129E75D}"
 	ProjectSection(ProjectDependencies) = postProject
 	EndProjectSection
@@ -41,10 +37,6 @@
 		{1B843C72-E875-45A0-BA0E-09B47B274708}.Debug.Build.0 = Debug|Win32
 		{1B843C72-E875-45A0-BA0E-09B47B274708}.Release.ActiveCfg = Release|Win32
 		{1B843C72-E875-45A0-BA0E-09B47B274708}.Release.Build.0 = Release|Win32
-		{84FEC2DB-F084-4C16-9442-FBA3908FCA95}.Debug.ActiveCfg = Debug|Win32
-		{84FEC2DB-F084-4C16-9442-FBA3908FCA95}.Debug.Build.0 = Debug|Win32
-		{84FEC2DB-F084-4C16-9442-FBA3908FCA95}.Release.ActiveCfg = Release|Win32
-		{84FEC2DB-F084-4C16-9442-FBA3908FCA95}.Release.Build.0 = Release|Win32
 		{ED1B9F21-0026-4156-881C-4F083129E75D}.Debug.ActiveCfg = Debug|Win32
 		{ED1B9F21-0026-4156-881C-4F083129E75D}.Debug.Build.0 = Debug|Win32
 		{ED1B9F21-0026-4156-881C-4F083129E75D}.Release.ActiveCfg = Release|Win32
Modified: trunk/src/builtins-attrdict.c
===================================================================
--- trunk/src/builtins-attrdict.c	2004-06-08 13:13:51 UTC (rev 586)
+++ trunk/src/builtins-attrdict.c	2004-06-09 21:40:50 UTC (rev 587)
@@ -69,7 +69,7 @@
 // ***************************** new_attrdict_obj *****************************
 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_DATAPTR) return NULL;
+	SET_TYPE_IF_EXC(AttrDict_OBJ, self, DATA_TYPE_EXTPTR) return NULL;
 	self->data.ptr  = obj;
 	set_unclonable(self);
 	return self;
@@ -120,7 +120,7 @@
 	for (i = 0; i < llen; i += 2) {
 		obj_p key = list_item(ist, dict_list, i);
 		if (has_proto(ist, key, OBJ(STRING_PROTO)))
-			key = sym(ist, pr_strptr(key));
+			key = sym(ist, pr2c_strptr(ist, key));
 		if (!has_proto(ist, key, OBJ(SYMBOL_PROTO))) {
 			raise_exception(ist, OBJ(TYPE_EXC), "attrs_ key must be a string or symbol");
 			return;
@@ -139,14 +139,14 @@
 	set_obj_id(AttrDict_OBJ, *, AttrDict);
 	set_attr(ist, OBJ(OBJECT), sym(ist, "AttrDict"), AttrDict_OBJ);
 
-	SET_TYPE_IF_EXC(AttrDict_OBJ, AttrDict_OBJ, DATA_TYPE_DATAPTR) return;
+	SET_TYPE_IF_EXC(AttrDict_OBJ, AttrDict_OBJ, DATA_TYPE_EXTPTR) return;
 	AttrDict_OBJ->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_DATAPTR) return NULL;
+	SET_TYPE_IF_EXC(AttrDict_OBJ, self, DATA_TYPE_EXTPTR) return NULL;
 	self->data.ptr  = parms[1];
 	set_unclonable(self);
 	return OBJ(NONE);
@@ -207,7 +207,7 @@
 	if (has_proto(ist, index, OBJ(SYMBOL_PROTO)))
 		res = get_attr(ist, self->data.ptr, index);
 	else if (has_proto(ist, index, OBJ(STRING_PROTO))) {
-		res = get_attr(ist, self->data.ptr, sym(ist, pr_strptr(index)));
+		res = get_attr(ist, self->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;
@@ -224,7 +224,7 @@
 	if (has_proto(ist, index, OBJ(SYMBOL_PROTO)))
 		set_attr(ist, self->data.ptr, index, parms[3]);
 	else if (has_proto(ist, index, OBJ(STRING_PROTO))) {
-		set_attr(ist, self->data.ptr, sym(ist, pr_strptr(index)), parms[3]);
+		set_attr(ist, self->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;
@@ -241,7 +241,7 @@
 	if (has_proto(ist, index, OBJ(SYMBOL_PROTO)))
 		del_attr(ist, self->data.ptr, index);
 	else if (has_proto(ist, index, OBJ(STRING_PROTO))) {
-		del_attr(ist, self->data.ptr, sym(ist, pr_strptr(index)));
+		del_attr(ist, self->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;
Added: trunk/src/builtins-bytes.c
===================================================================
--- trunk/src/builtins-bytes.c	2004-06-08 13:13:51 UTC (rev 586)
+++ trunk/src/builtins-bytes.c	2004-06-09 21:40:50 UTC (rev 587)
@@ -0,0 +1,354 @@
+/* ====================================================================
+ * 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, dibytibute, 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, DIBYTIBUTING, 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.
+ * ====================================================================
+ */
+
+
+// builtins-bytes.c
+
+#include <prothon/prothon.h>
+#include "object.h"
+#include <prothon/prothon_dll.h>
+
+#include "pr_snprintf.h"
+
+#define is_Bytes(objid) (has_proto(ist, objid, Bytes_OBJ))
+
+MODULE_DECLARE(Bytes);
+MODULE_DECLARE(BytesGen);
+
+//********************************* new_bytes_obj ****************************
+obj_p new_bytes_obj(isp ist, const u8_t* byt, size_t len) {
+	obj_p obj;
+	byt_p obj_byt;
+	if(!byt) return NULL;
+	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;
+		if (len)
+			memcpy(obj->data.bytes, byt, len);
+	} else {
+		obj_byt = obj_malloc(ist, OBJ(BYTES_PROTO), obj, sizeof(byt_t)+len); if_exc_return NULL;
+		obj_byt->len = (data_size_t) len;
+		memcpy(&(obj_byt->byt[0]), byt, len);
+	}
+	obj->immutable = TRUE;
+	return obj;
+}
+
+//********************************* set_bytes_data ***************************
+void set_bytes_data(isp ist, obj_p obj, void* byt, size_t len) {
+	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);
+	} else {
+		obj_byt = obj_malloc(ist, OBJ(BYTES_PROTO), obj, sizeof(byt_t)+len); if_exc_return;
+		obj_byt->len = (data_size_t) len;
+		memcpy(&(obj_byt->byt[0]), byt, len);
+	}
+	obj->immutable = TRUE;
+	return;
+}
+
+//********************************* bytes_ptr *********************************
+u8_t* bytes_ptr(obj_p obj) {
+	if (obj->data_type == DATA_TYPE_IMMDATA) 
+		return obj_dataptr(obj);
+	else
+		return ((u8_t*) obj_dataptr(obj)) + sizeof(data_size_t);
+}
+
+//********************************* bytes_len *********************************
+size_t bytes_len(obj_p obj) {
+	if (obj->data_type == DATA_TYPE_IMMDATA) 
+		return obj->imm_data_len;
+	else
+		return DATA_SIZE(obj)-sizeof(data_size_t);
+}
+
+//********************************* BYTES MODULE ******************************
+
+MODULE_START(Bytes)
+{
+	Bytes_OBJ = OBJ(BYTES_PROTO);
+	MODULE_SET_DOC(Bytes, "bytes object prototype");
+	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;
+}
+
+DEF(Bytes, init_, FORM_RPARAM) {
+	char *s;
+	obj_p res = NULL;
+	BIN_EMPTY_CHK();
+	if (has_proto(ist, parms[1], OBJ(STRING_PROTO))) {
+		s = pr2c_strptr(ist, parms[1]);
+		set_bytes_data(ist, self, s, strlen(s));
+		pr_free(s);
+		return OBJ(NONE);
+	} else if (has_proto(ist, parms[1], OBJ(BYTES_PROTO))) {
+		return copy_object(ist, parms[1]);
+	} else {
+		raise_exception(ist, OBJ(TYPE_EXC), "invalid parameters");
+		return NULL;
+	}
+}
+
+DEF(Bytes, str_, NULL) {
+	char buf[32];
+	BIN_STR_CHK(Bytes);
+	apr_snprintf(buf, sizeof(buf), "<Bytes:%x>", (unsigned long) (intptr_t) self);
+	return NEW_STRING(buf);
+}
+
+DEF(Bytes, hash_, NULL) {
+	i32_t res = 0x45ced34;
+	u8_t *p, *lastp;
+	BIN_CONTENT_CHK(Bytes);
+	p = bytes_ptr(self);
+	lastp = p + bytes_len(self);
+	for(; p < lastp; p++) res += 131 * (*p);
+	return new_hash_obj(ist, res);
+}
+
+DEF(Bytes, getItem_, FORM_RPARAM) {
+	BIN_CONTENT_CHK(Bytes);
+	return get_sequence_item(ist, self, parms[1], SEQ_TYPE_BYTES);
+}
+
+DEF(Bytes, setItem_, FORM_RPARAM) {
+	raise_exception(ist, OBJ(MUTABLE_EXC), "bytes may not be modifed");
+	return NULL;
+}
+
+DEF(Bytes, delItem_, NULL) {
+	raise_exception(ist, OBJ(MUTABLE_EXC), "bytes may not be modifed");
+	return NULL;
+}
+
+DEF(Bytes, cmp, FORM_RPARAM){
+	obj_p other = parms[1];
+	size_t i, len, len1, len2;
+	u8_t *p1, *p2, str_flg = FALSE;
+
+	BIN_CONTENT_CHK(Bytes);
+	if (self == other)
+		return NEW_INT(0);
+	if (!is_Bytes(other)) {
+		if (has_proto(ist, other, OBJ(STRING_PROTO))) {
+			char* s;
+			other = new_object(ist, OBJ(BYTES_PROTO));
+			s = pr2c_strptr(ist, parms[1]); if_exc_return NULL;
+			set_bytes_data(ist, other, s, strlen(s));
+			pr_free(s);
+			str_flg = TRUE;
+		} else {
+			raise_exception(ist, OBJ(TYPE_EXC), "Cannot compare a bytes object with this object");
+			return NULL;
+		}
+	}
+	p1 = bytes_ptr(self);
+	p2 = bytes_ptr(other);
+	len1 = bytes_len(self);
+	len2 = bytes_len(other);
+	len = min(len1,len2);
+	for (i=0; i < len; i++) {
+		if (*p1 < *p2) goto neg;
+		if (*p1 > *p2) goto pos;
+	}
+	if (len1 < len2) goto neg;
+	if (len1 > len2) goto pos;
+	if (str_flg) del_unlock(other);
+	return NEW_INT(0);
+neg:
+	if (str_flg) del_unlock(other);
+	return NEW_INT(-1);
+pos:
+	if (str_flg) del_unlock(other);
+	return NEW_INT(+1);
+}
+
+DEF(Bytes, add_, FORM_RPARAM){
+	obj_p obj, other = parms[1];
+	size_t slen, olen, tlen;
+	u8_t* buf;
+
+	BIN_CONTENT_CHK(Bytes);
+	if (!is_Bytes(other)) {
+		raise_exception(ist, OBJ(TYPE_EXC), "Cannot concatenate a bytes object with this object");
+		return NULL;
+	}
+	slen = bytes_len(self); olen = bytes_len(other);
+	tlen = slen + olen;
+	buf = pr_malloc(tlen);
+	memcpy(buf,      bytes_ptr(self),  slen);
+	memcpy(buf+slen, bytes_ptr(other), olen);
+	obj = NEW_BYTES(buf, tlen);
+	pr_free(buf);
+	return obj;
+}
+
+DEF(Bytes, mul_, FORM_RPARAM){
+	obj_p obj;
+	size_t i, times, tlen, len = bytes_len(self);
+	u8_t *buf, *self_ptr;
+
+	BIN_CONTENT_CHK(Bytes);
+	INT_32_PARAM(1, times);
+	if(times == 0) return NEW_BYTES(NULL, 0);
+	if(times == 1) return self;
+	tlen = len*times;
+	buf = pr_malloc(tlen);
+	self_ptr = bytes_ptr(self);
+	for (i=0; i < times; i++)
+		memcpy(buf+(i*len), self_ptr, len);
+	obj = NEW_BYTES(buf, tlen);
+	pr_free(buf);
+	return obj;
+}
+
+DEF(Bytes, len, NULL) {
+	BIN_CONTENT_CHK(Bytes);
+	return NEW_INT(bytes_len(self));
+}
+
+DEF(Bytes, bool__QUES, NULL) {
+	BIN_CONTENT_CHK(Bytes);
+	if (bytes_len(self)) return OBJ(PR_TRUE);
+	else                 return OBJ(PR_FALSE);
+}
+
+DEF(Bytes, objList_, FORM_RPARAM) {
+	return parms[1];
+}
+
+//********************************* BYTESGEN MODULE **************************
+
+typedef struct {
+	data_size_t size;
+	u8_t*		ptr;
+} bytgen_t;
+
+typedef bytgen_t* bytgen_p;
+
+DEF(Bytes, iter_, NULL) {
+	obj_p gen_obj;
+	bytgen_p bytgenp;
+
+	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->size = DATA_SIZE(self);
+	bytgenp->ptr  = ((u8_t*)bytgenp) + sizeof(bytgen_t);
+	memcpy(bytgenp->ptr, bytes_ptr(self), bytes_len(self));
+	return gen_obj;
+}
+
+MODULE_START(BytesGen)
+{
+	BytesGen_OBJ = NEW_OBJ(NULL);
+	set_attr(ist, OBJ(OBJECT), sym(ist, "BytesGen"), BytesGen_OBJ);
+	set_obj_id(BytesGen_OBJ, *, BytesGen);
+}
+
+DEF(BytesGen, next, NULL) {
+        obj_p res = NULL;
+        bytgen_p bytgenp;
+		u8_t* limit;
+
+		BIN_CONTENT_CHK(BytesGen);
+        def_write_lock(self);
+        bytgenp = (bytgen_p)(self->data.ptr);
+		limit = ((u8_t*)(self->data.ptr)) + (bytgenp->size);
+		if (bytgenp->ptr == limit) {
+			raise_exception(ist, OBJ(STOP_ITERATION_EXC), NULL);
+			return NULL;
+		}
+		res = NEW_INT(*((bytgenp->ptr)++));
+        def_write_unlock(self);
+        return res;
+}
+
+DEF(BytesGen, objList_, FORM_RPARAM) {
+	return parms[1];
+}
+
+//********************************* MODULES INIT ******************************
+
+MAIN_MODULE_INIT(Bytes)
+{
+	MODULE_SUB_INIT(Bytes);
+	MODULE_ADD_SYM(Bytes, init_);
+	MODULE_ADD_SYM(Bytes, bool__QUES);
+	MODULE_ADD_SYM(Bytes, str_);
+	MODULE_ADD_SYM(Bytes, hash_);
+	MODULE_ADD_SYM(Bytes, cmp);
+	MODULE_ADD_SYM(Bytes, len);
+	MODULE_ADD_SYM(Bytes, getItem_);
+	MODULE_ADD_SYM(Bytes, add_);
+	MODULE_ADD_SYM(Bytes, mul_);
+	MODULE_ADD_SYM(Bytes, iter_);
+	MODULE_ADD_SYM(Bytes, setItem_);
+	MODULE_ADD_SYM(Bytes, delItem_);
+	MODULE_ADD_SYM(Bytes, objList_);
+
+	MODULE_SUB_INIT(BytesGen);
+	MODULE_ADD_SYM(BytesGen, next);
+	MODULE_ADD_SYM(BytesGen, objList_);
+	
+	set_immutable(Bytes_OBJ);
+
+	check_exceptions(ist);
+}
Modified: trunk/src/builtins-core.c
===================================================================
--- trunk/src/builtins-core.c	2004-06-08 13:13:51 UTC (rev 586)
+++ trunk/src/builtins-core.c	2004-06-09 21:40:50 UTC (rev 587)
@@ -148,25 +148,16 @@
 
 DEF(Object, copy, NULL) {
 	obj_p copy;
-	size_t cdata_size = 0;
 	if (self->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) {
-		obj_p cdata_len = call_func0(ist, self, SYM(CDATALEN_));
-		if (!cdata_len) {
-			raise_exception(ist, OBJ(INTERNAL_EXC), "fatal error: cDataLen_() call failed");
-			return NULL;
-		}
-		cdata_size = (size_t) cdata_len->data.i64;
-		del_unlock(cdata_len);
+		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 = copy_object(ist, self);
-	if (cdata_size) {
-		copy->data.ptr = pr_malloc(cdata_size);
-		memcpy(copy->data.ptr, self->data.ptr, cdata_size);
-	}
 	return copy;
 }
 
@@ -302,7 +293,7 @@
 DEF(Object, str_, NULL) {
 	char str[1024];
 	obj_p doc = get_attr(ist, self, SYM(DOC_));
-	char* p = pr_strptr(doc);
+	char* p = pr2c_strptr(ist, doc);
 	if (doc)
 		apr_snprintf(str, sizeof(str), "<Object:%lx:%s>", (unsigned long)(uintptr_t)self, p);
 	else
@@ -318,7 +309,7 @@
 	obj_p cmp_obj = call_func1(ist, self, SYM(CMP), parms[1]); 
 	if(catch_exception(ist, OBJ(FUNCNOTFOUND_EXC), NULL))
 		return OBJ(PR_FALSE);
-	if (cmp_obj && *((i64_t*)(obj_data_p(cmp_obj))) == 0)
+	if (cmp_obj && *((i64_t*)(obj_dataptr(cmp_obj))) == 0)
 		return OBJ(PR_TRUE);
 	else
 		return OBJ(PR_FALSE);
@@ -334,25 +325,25 @@
 
 DEF(Object, lt__QUES, FORM_RPARAM) {
 	obj_p cmp_obj = call_func1(ist, self, SYM(CMP), parms[1]); if_exc_return NULL;
-	if (cmp_obj && *((i64_t*)(obj_data_p(cmp_obj))) < 0)	return OBJ(PR_TRUE);
+	if (cmp_obj && *((i64_t*)(obj_dataptr(cmp_obj))) < 0)	return OBJ(PR_TRUE);
 	else											        return OBJ(PR_FALSE);
 }
 
 DEF(Object, le__QUES, FORM_RPARAM) {
 	obj_p cmp_obj = call_func1(ist, self, SYM(CMP), parms[1]); if_exc_return NULL;
-	if (cmp_obj && *((i64_t*)(obj_data_p(cmp_obj))) <= 0)	return OBJ(PR_TRUE);
+	if (cmp_obj && *((i64_t*)(obj_dataptr(cmp_obj))) <= 0)	return OBJ(PR_TRUE);
 	else											        return OBJ(PR_FALSE);
 }
 
 DEF(Object, gt__QUES, FORM_RPARAM) {
 	obj_p cmp_obj = call_func1(ist, self, SYM(CMP), parms[1]); if_exc_return NULL;
-	if (cmp_obj && *((i64_t*)(obj_data_p(cmp_obj))) > 0)	return OBJ(PR_TRUE);
+	if (cmp_obj && *((i64_t*)(obj_dataptr(cmp_obj))) > 0)	return OBJ(PR_TRUE);
 	else											        return OBJ(PR_FALSE);
 }
 
 DEF(Object, ge__QUES, FORM_RPARAM) {
 	obj_p cmp_obj = call_func1(ist, self, SYM(CMP), parms[1]); if_exc_return NULL;
-	if (cmp_obj && *((i64_t*)(obj_data_p(cmp_obj))) >= 0)	return OBJ(PR_TRUE);
+	if (cmp_obj && *((i64_t*)(obj_dataptr(cmp_obj))) >= 0)	return OBJ(PR_TRUE);
 	else											        return OBJ(PR_FALSE);
 }
 
@@ -407,7 +398,7 @@
 	obj_p str_obj = get_attr(ist, self, SYM(STRING_));
 	char buf[512];
 	BIN_STR_CHK(Symbol);
-	apr_snprintf(buf, sizeof(buf), "`%s", pr_strptr(str_obj));
+	apr_snprintf(buf, sizeof(buf), "`%s", pr2c_strptr(ist, str_obj));
 	return NEW_STRING(buf); 
 }
 
@@ -638,12 +629,16 @@
 	int i, index1 = 0, index2 = 0, index3 = 0, slice1_empty=FALSE, slice2_empty=FALSE;
 	int exp_len, self_len, slice_len = (int) list_len(ist, slice);
 	char* self_str = NULL;
+	u8_t* self_bytes = NULL;
 
 	CHECK_TYPE_EXC(self, OBJ(SEQ_PROTO), "sequence");
-
-	if (seq_type == SEQ_TYPE_STRING) {
+	
+	if (seq_type == SEQ_TYPE_BYTES) {
+		self_bytes = bytes_ptr(self);
+		self_len   = (int) bytes_len(self);
+	} else if (seq_type == SEQ_TYPE_STRING) {
+		self_str = pr2c_strptr(ist, self); if_exc_return NULL;
 		self_len = (int) pr_strlen(self);
-		self_str = pr_strptr(self);
 	} else
 		self_len = (int) list_len(ist, self);
 	slice_item1 = list_item(ist, slice,0);
@@ -652,39 +647,41 @@
 	else {
 		CHECK_TYPE_EXC(slice_item1, OBJ(INT_PROTO), "integer");
 
-		index1 = (int)(slice_item1->data.i64);
+		index1 = int2i32t(ist, slice_item1);
 		if (index1 < 0) index1 += self_len;						
 		if (index1 < 0 || index1 >= self_len) {			
 			raise_exception(ist, OBJ(INDEX_EXC), "Index (%d) out of range", index1);
 			return NULL;									
 		}
 		if (slice_len == 1) {
-			if (seq_type == SEQ_TYPE_STRING) {
+			if (seq_type == SEQ_TYPE_BYTES) {
+				return NEW_INT(*(self_bytes+index1));
+			} else if (seq_type == SEQ_TYPE_STRING) {
 				return NEW_STRINGN(self_str+index1, 1);
 			} else
 				return list_item(ist, self, index1);
 		}
 	}
 	if (slice_len == 3) {
-		slice_item3 = list_item(ist, slice,2);
+		slice_item3 = list_item(ist, slice, 2);
 		if (slice_item3 == SLICEPARAM_EMPTY || slice_item3 == OBJ(NONE)) index3 = 1;
 		else {
 			CHECK_TYPE_EXC(slice_item3, OBJ(INT_PROTO), "integer");
 
-			index3 = (int)(slice_item3->data.i64);
+			index3 = int2i32t(ist, slice_item3);
 			if (index3 == 0) {
 				raise_exception(ist, OBJ(INDEX_EXC), "Slice step cannot be zero");		
 				return NULL;
 			}
 		}
 	} else index3 = 1;
-	slice_item2 = list_item(ist, slice,1);
+	slice_item2 = list_item(ist, slice, 1);
 	if (slice_item2 == SLICEPARAM_EMPTY || slice_item2 == OBJ(NONE))
-		slice2_empty=TRUE;
+		slice2_empty = TRUE;
 	else {
 		CHECK_TYPE_EXC(slice_item2, OBJ(INT_PROTO), "integer");
 
-		index2 = (int)(slice_item2->data.i64);
+		index2 = int2i32t(ist, slice_item2);
 		if (index2 < 0) index2 += self_len;						
 		if (index2 < 0 || index2 > self_len) {			
 			raise_exception(ist, OBJ(INDEX_EXC), "Second index (%d) out of range", index2);
@@ -697,6 +694,22 @@
 		exp_len = (index2-index1+(index3-1))/index3;
 		exp_len = max(exp_len, 0);
 		switch(seq_type) {
+		case SEQ_TYPE_BYTES: {
+			int j;
+			u8_t* s = pr_malloc(exp_len);
+			for(i = index1, j=0; i < index2; i += index3, j++)
+				s[j] = self_bytes[i];
+			res = NEW_BYTES(s, j);
+			pr_free(s);
+		}   break;
+		case SEQ_TYPE_STRING: {
+			int j;
+			char* s = pr_malloc(exp_len+2);
+			for(i = index1, j=0; i < index2; i += index3, j++)
+				s[j] = self_str[i];
+			res = NEW_STRINGN(s, j);
+			pr_free(s);
+		}   break;
 		case SEQ_TYPE_TUPLE:
 			res = NEW_TUPLE(exp_len);
 			for(i = index1; i < index2; i += index3)
@@ -707,21 +720,29 @@
 			for(i = index1; i < index2; i += index3)
 				list_append(ist, res, list_item(ist, self, i));
 			break;
+		}
+	} else {
+		if (slice1_empty) index1 = self_len-1;
+		if (slice2_empty) index2 = -1;
+		exp_len = (index2-index1+(index3-1))/index3;
+		exp_len = max(exp_len, 0)+1;
+		switch(seq_type) {
+		case SEQ_TYPE_BYTES: {
+			int j;
+			u8_t* s = pr_malloc(exp_len);
+			for(i = index1, j=0; i > index2; i += index3, j++)
+				s[j] = self_str[i];
+			res = NEW_BYTES(s, j);
+			pr_free(s);
+		}   break;
 		case SEQ_TYPE_STRING: {
 			int j;
 			char* s = pr_malloc(exp_len+2);
-			for(i = index1, j=0; i < index2; i += index3, j++)
+			for(i = index1, j=0; i > index2; i += index3, j++)
 				s[j] = self_str[i];
 			res = NEW_STRINGN(s, j);
 			pr_free(s);
 		}   break;
-		}
-	} else {
-		if (slice1_empty) index1 = self_len-1;
-		if (slice2_empty) index2 = -1;
-		exp_len = (index2-index1+(index3-1))/index3;
-		exp_len = max(exp_len, 0)+1;
-		switch(seq_type) {
 		case SEQ_TYPE_TUPLE:
 			res = NEW_TUPLE(exp_len);
 			for(i = index1; i > index2; i += index3)
@@ -732,13 +753,6 @@
 			for(i = index1; i > index2; i += index3)
 				list_append(ist, res, list_item(ist, self, i));
 			break;
-		case SEQ_TYPE_STRING: {
-			int j;
-			char* s = pr_malloc(exp_len+2);
-			for(i = index1, j=0; i > index2; i += index3, j++)
-				s[j] = self_str[i];
-			res = NEW_STRINGN(s, j);
-		}   break;
 		}
 	}
 	return res;
@@ -774,7 +788,7 @@
 	}
 	self->data_type = other->data_type;
 	if (self->data_type == DATA_TYPE_DATAPTR) {
-		size = (int) (sizeof(code) + optr->len * sizeof(code_t));
+		size = DATA_SIZE(other);
 		self->data.ptr = pr_malloc(size);
 		memcpy(self->data.ptr, other->data.ptr, size);
 	} else 
@@ -792,7 +806,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_FUNCPTR)
+	if (self->data_type == DATA_TYPE_EXTPTR)
 		strcat(str, ":c");
 	if ((bobj = get_attr(ist, self, SYM(BINDOBJ_)))) {
 		strcat(str, ":bound:");
@@ -810,11 +824,6 @@
 	return self;
 }
 
-DEF(Func, cDataLen_, NULL) {
-	BIN_CONTENT_CHK(Func);
-	return NEW_INT(sizeof(code) + ((code_p)(self->data.ptr))->len * sizeof(code_t));
-}
-
 DEF(Func, objList_, FORM_RPARAM) {
 	return parms[1];
 }
@@ -907,7 +916,6 @@
 	MODULE_ADD_SYM(Func, init_);
 	MODULE_ADD_SYM(Func, str_);
 	MODULE_ADD_SYM(Func, unbind);
-	MODULE_ADD_SYM(Func, cDataLen_);
 	MODULE_ADD_SYM(Func, objList_);
 
 	check_exceptions(ist);

Modified: trunk/src/builtins-dict.c
===================================================================
--- trunk/src/builtins-dict.c	2004-06-08 13:13:51 UTC (rev 586)
+++ trunk/src/builtins-dict.c	2004-06-09 21:40:50 UTC (rev 587)
@@ -72,10 +72,12 @@
 obj_p new_dict_obj(isp ist, int initial_size){
 	obj_p dict_obj = NEW_OBJ(OBJ(DICT_PROTO));
 	dict_p dict;
-	initial_size = max(initial_size, DEFAULT_INITIAL_DICT_SIZE);
-	dict = obj_malloc(ist, OBJ(DICT_PROTO), dict_obj, (DICT_OVERHEAD+initial_size)*sizeof(dict_t)); 
-	memset(dict, 0, (DICT_OVERHEAD+initial_size)*sizeof(dict_t));
-	dictsize(dict) = initial_size;
+	int size = max(initial_size, DEFAULT_INITIAL_DICT_SIZE);
+	data_size_t data_size = dict_sizeof(size);
+	dict = obj_malloc(ist, OBJ(DICT_PROTO), dict_obj, data_size); 
+	memset(dict, 0, data_size);
+	dictsize_bytes(dict) = data_size;
+	dictsize(dict) = size;
 	return dict_obj;
 }
 
@@ -85,8 +87,10 @@
 	i32_t  i, j, hash_in, old_size = (int) dictsize(dict);
 	i32_t size = max(((int)dictsize(dict) * DICT_PAD_PERCENT_FACTOR) / 100, DEFAULT_INITIAL_DICT_SIZE);
 	i32_t len  =  (int) dictlen(dict);
-	dict = pr_malloc(dict_sizeof(size));
-	memset(dict, 0, dict_sizeof(size));
+	data_size_t data_size = dict_sizeof(size);
+	dict = pr_malloc(data_size);
+	memset(dict, 0, data_size);
+	dictsize_bytes(dict) = data_size;
 	dictsize(dict) = size;
 	dictlen(dict)  = len;
 	for(i=0; i < old_size; i++) {
@@ -190,7 +194,7 @@
 		return NULL;				
 	}
 	if (!hash_in) hash_in++;
-	dict = (dict_p) obj_data_p(dict_obj);
+	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) ) ) {
@@ -204,7 +208,7 @@
 	}
 	read_unlock(ist, dict_obj);
 	if (has_proto(ist, key_in, OBJ(STRING_PROTO))) {
-		key_in = sym(ist, pr_strptr(key_in));
+		key_in = sym(ist, pr2c_strptr(ist, key_in));
 		if (!ist->exception_obj) {
 			new_sym = TRUE;
 			goto try_again;
@@ -267,15 +271,17 @@
 MODULE_START(Dict)
 {
 	dict_p dict;
+	data_size_t dsize = dict_sizeof(DEFAULT_INITIAL_DICT_SIZE);
 
 	Dict_OBJ = OBJ(DICT_PROTO);
 	MODULE_SET_DOC(Dict, "dictionary object prototype");
 	set_obj_id(Dict_OBJ, *, Dict);
 	set_attr(ist, OBJ(OBJECT), sym(ist, "Dict"), Dict_OBJ);
 
-    dict = obj_malloc(ist, OBJ(DICT_PROTO), Dict_OBJ, (DICT_OVERHEAD+DEFAULT_INITIAL_DICT_SIZE)*sizeof(dict_t));
+    dict = obj_malloc(ist, OBJ(DICT_PROTO), Dict_OBJ, dsize);
 	if_exc_return;
-    memset(dict, 0, (DICT_OVERHEAD+DEFAULT_INITIAL_DICT_SIZE)*sizeof(dict_t));
+    memset(dict, 0, dsize);
+    dictsize_bytes(dict) = dsize;
     dictsize(dict) = DEFAULT_INITIAL_DICT_SIZE;
 }
 
@@ -289,6 +295,7 @@
 	dict_p dict;
 	obj_p list, dict_in;
 	int i, llen, size;
+	data_size_t dsize;
 
     BIN_EMPTY_OR_NOT_CHK(Dict);
 	llen = (int) list_len(ist, parms[1]);
@@ -299,9 +306,11 @@
 		return NULL;
 	} else
 		dict_in = parms[3];
-	size = max(DEFAULT_INITIAL_DICT_SIZE, (int) dict_len(ist, dict_in)*3);
-	dict = obj_malloc(ist, OBJ(DICT_PROTO), self, dict_sizeof(size));
-    memset(dict, 0, dict_sizeof(size));
+	size  = max(DEFAULT_INITIAL_DICT_SIZE, (int) dict_len(ist, dict_in)*3);
+	dsize = dict_sizeof(size);
+	dict  = obj_malloc(ist, OBJ(DICT_PROTO), self, dsize);
+    memset(dict, 0, dsize);
+    dictsize_bytes(dict) = dsize;
     dictsize(dict) = size;
 	list = dict_keys_values(ist, dict_in, 2 /*list*/);
 	llen = (int) list_len(ist, list);
@@ -398,12 +407,6 @@
 	return OBJ(PR_TRUE);
 }
 
-DEF(Dict, cDataLen_, NULL) {
-	BIN_CONTENT_CHK(Dict);
-	return NEW_INT(dict_size_bytes(self->data.ptr));
-}
-
-
 DEF(Dict, objList_, FORM_RPARAM) {
 	BIN_CONTENT_CHK(Dict);
 	return parms[1];
@@ -617,7 +620,6 @@
 	MODULE_ADD_SYM(Dict, iter_);
 	MODULE_ADD_SYM(Dict, toStorProxy_);
 	MODULE_ADD_SYM(Dict, objList_);
-	MODULE_ADD_SYM(Dict, cDataLen_);
 
 	MODULE_SUB_INIT(DictRestore);
 	MODULE_ADD_SYM(DictRestore, fromStorProxy_);

Added: trunk/src/builtins-file.c
===================================================================
--- trunk/src/builtins-file.c	2004-06-08 13:13:51 UTC (rev 586)
+++ trunk/src/builtins-file.c	2004-06-09 21:40:50 UTC (rev 587)
@@ -0,0 +1,748 @@
+/* ====================================================================
+ * 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.
+ * ====================================================================
+ */
+
+
+// builtins-file.c
+
+#include <prothon/prothon.h>
+#include <stdio.h>
+#include <string.h>
+#include "object.h"
+#include <prothon/prothon_dll.h>
+
+#include <apr_file_io.h>
+#include <apr_strings.h>
+
+#define MIN_BUFSIZE  65536
+
+typedef struct {
+	apr_file_t	*stream;	/* APR file reference */
+	int			bufsize;	/* Size of our buffer */
+	apr_pool_t	*pool;		/* Pool associated with this file */
+	apr_int32_t	flags;		/* APR flags */
+} pr_file_t;
+
+typedef pr_file_t* pr_file_p;
+
+#define STREAM(obj)  (((pr_file_p)((obj)->data.ptr))->stream)
+#define BUFSIZE(obj) (((pr_file_p)((obj)->data.ptr))->bufsize)
+#define POOL(obj)    (((pr_file_p)((obj)->data.ptr))->pool)
+#define FLAGS(obj)   (((pr_file_p)((obj)->data.ptr))->flags)
+#define OPEN(obj)    (((obj) != File_OBJ) && STREAM(obj))
+
+MODULE_DECLARE(File);
+
+static void set_file_obj(obj_p file_obj, obj_p filename, obj_p mode,
+			     apr_file_t *fp, int bufsize,
+			     apr_int32_t flags)
+{
+	apr_pool_t *subpool = apr_file_pool_get(fp);
+	pr_file_p filep;
+
+	set_attr(ist, file_obj, sym(ist, "name"), filename);
+	set_attr(ist, file_obj, sym(ist, "mode"), mode);
+
+	filep = pr_malloc(sizeof(*filep));
+
+	if (bufsize < MIN_BUFSIZE)
+		bufsize = MIN_BUFSIZE;
+
+	filep->bufsize = bufsize;
+	filep->stream  = fp;
+	filep->pool = subpool;
+	filep->flags = flags;
+	SET_TYPE_IF_EXC(File_OBJ, file_obj, DATA_TYPE_DATAPTR) return;
+	file_obj->data.ptr  = filep;
+	file_obj->rd_access = ACC_USER1;
+	file_obj->wr_access = ACC_USER1;
+}
+
+
+static obj_p new_file_object(obj_p filename, obj_p mode,
+			     apr_file_t *fp, int bufsize,
+			     apr_int32_t flags)
+{
+	obj_p file_obj;
+
+	file_obj = NEW_OBJ(File_OBJ);
+	set_file_obj(file_obj, filename, mode, fp, bufsize, flags);
+	return file_obj;
+}
+
+MODULE_START(File)
+{
+	File_OBJ = NEW_OBJ(NULL);
+	set_obj_doc(File_OBJ, "File object prototype");
+
+	MODULE_ADD_TO_BASE(File);
+	File_OBJ->unclonable = TRUE;
+}
+
+DEF(File, init_, FPARM3( path,    NULL, 
+	                     mode,    NEW_STRING("r"),
+                         bufsize, NEW_INT(-1)   ) ) {
+	apr_file_t *f;
+	apr_status_t aprerr;
+	apr_pool_t *subpool;
+	apr_int32_t flags = 0;
+	char err_buf[1024];
+	char *path, *mode;
+	int bufsize;
+	
+	BIN_EMPTY_CHK();
+	STRING_PARAM(1, path);
+	STRING_PARAM(2, mode);
+	INT_32_PARAM(3, bufsize);
+
+	if ((mode[0] != 'r' && mode[0] != 'w' && mode[0] != 'a') ||
+	    (mode[1] != '+' && mode[1] != '\0')) {
+		raise_exception(ist, OBJ(TYPE_EXC), "File mode `%s' is not valid", mode);
+		return NULL;
+	}
+
+	if (mode[0] == 'r') {
+		flags = APR_READ;
+		if (mode[1] == '+')
+			flags |= APR_WRITE;
+	} else if (mode[0] == 'w') {
+		flags = APR_WRITE | APR_CREATE | APR_TRUNCATE;
+		if (mode[1] == '+')
+			flags |= APR_READ;
+	} else if (mode[0] == 'a') {
+		flags = APR_WRITE | APR_CREATE | APR_APPEND;
+		if (mode[1] == '+')
+			flags |= APR_READ;
+	}
+
+	aprerr = apr_pool_create(&subpool, get_pr_head_pool());
+	if (aprerr != APR_SUCCESS) {
+		raise_exception(ist, OBJ(OUTOFMEMORY_EXC), "Out of memory opening files");
+		return NULL;
+	}
+
+	aprerr = apr_file_open(&f, path, flags, APR_OS_DEFAULT, subpool);
+	if (aprerr != APR_SUCCESS) {
+		raise_exception(ist, OBJ(IOEXCEPTION), "Unable to open path %s: %s",
+				path, apr_strerror(aprerr, err_buf, sizeof(err_buf)));
+		apr_pool_destroy(subpool);
+		return NULL;
+	}
+
+	/* set_file_obj() modified the object, and thus calls write_lock.
+	 * We need to unlock in order to avoid a deadlock */
+	read_unlock(ist, self);
+	set_file_obj(self, parms[1], parms[3], f, bufsize, flags);
+	read_lock(ist, self);
+	self->unclonable = TRUE;
+	return OBJ(NONE);
+}
+
+DEF(File, objList_, FORM_RPARAM) {
+	return parms[1];
+}
+
+DEF(File, close, NULL) {
+	BIN_CONTENT_CHK(File);
+	if (OPEN(self)) {
+		apr_file_close(STREAM(self));
+		STREAM(self) = NULL;
+		apr_pool_destroy(POOL(self));
+	}
+	return OBJ(NONE);
+}
+
+DEF(File, closed_QUES, NULL) { 
+	BIN_CONTENT_CHK(File);
+	if (!has_proto(ist, self, File_OBJ)) {
+		raise_exception(ist, OBJ(TYPE_EXC), "closed can only be called on a File object");
+		return NULL;
+	}
+	if (OPEN(self)) return OBJ(PR_FALSE);
+	else			return OBJ(PR_TRUE);
+}
+
+DEF(File, flush, NULL) { 
+	BIN_CONTENT_CHK(File);
+	if (!has_proto(ist, self, File_OBJ)) {
+		raise_exception(ist, OBJ(TYPE_EXC), "flush can only be called on a File object");
+		return NULL;
+	}
+	if (!OPEN(self)) {
+		raise_exception(ist, OBJ(IOEXCEPTION), "flush called on closed file");
+		return NULL;
+	}
+	if (apr_file_flush(STREAM(self)) == APR_SUCCESS) {
+		raise_exception(ist, OBJ(IOEXCEPTION), "flushing file");
+		return NULL;
+	}
+	return OBJ(NONE);
+}
+#if 0
+DEF(File, fileNo, NULL) { 
+	BIN_CONTENT_CHK(File);
+	if (!has_proto(ist, self, File_OBJ)) {
+		raise_exception(ist, OBJ(TYPE_EXC), "fileNo can only be called on a File object");
+		return NULL;
+	}
+	if (!OPEN(self)) {
+		raise_exception(ist, OBJ(IOEXCEPTION), "fileNo called on closed file");
+		return NULL;
+	}
+	return NEW_INT(_fileno(STREAM(self)));
+}
+
+DEF(File, isATty_QUES, NULL) { 
+	BIN_CONTENT_CHK(File);
+	if (!OPEN(self)) {
+		raise_exception(ist, OBJ(IOEXCEPTION), "isatty called on closed stream");
+		return NULL;
+	}
+	if (_isatty(_fileno(STREAM(self))))  return OBJ(PR_TRUE); 
+	else						return OBJ(PR_FALSE); 
+}
+#endif
+DEF(File, read, FPARM1(size, NEW_INT(-1))) {
+	int readall = FALSE;
+	size_t size, total_read=0, num_read;
+	obj_p byt_obj;
+	byt_p obj_str;
+	u8_t* buf;
+	apr_status_t aprerr;
+	char err_buf[1024];
+	i64_t size_in;
+
+	BIN_CONTENT_CHK(File);
+	INT_64_PARAM(1, size_in);
+
+	if (!has_proto(ist, self, File_OBJ)) {
+		raise_exception(ist, OBJ(TYPE_EXC), "read can only be called on a File object");
+		return NULL;
+	}
+	if (!OPEN(self)) {
+		raise_exception(ist, OBJ(IOEXCEPTION), "read called on closed file");
+		return NULL;
+	}
+	if (!(FLAGS(self) & APR_READ)) {
+		raise_exception(ist, OBJ(IOEXCEPTION), "read called on file opened without read perms");
+		return NULL;
+	}
+	if (!size_in) return NEW_BYTES(NULL, 0);
+	if (size_in < 0) {
+		readall = TRUE;
+		size = BUFSIZE(self);
+	} else
+		size = (size_t) size_in;
+	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;
+	} else {
+		obj_str = obj_malloc(ist, OBJ(BYTES_PROTO), byt_obj, sizeof(str_t)+size+1);
+		buf = obj_str->byt;
+	}
+	num_read = size;
+	aprerr = apr_file_read(STREAM(self), buf, &num_read);
+	if (aprerr != APR_SUCCESS && aprerr != APR_EOF) {
+		raise_exception(ist, OBJ(IOEXCEPTION), "%s",
+				apr_strerror(aprerr, err_buf, sizeof(err_buf)));
+		return NULL;
+	}
+	total_read += num_read;
+	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) {
+			obj_str = obj_malloc(ist, OBJ(BYTES_PROTO), byt_obj, sizeof(str_t)+new_len+1);
+			buf = obj_str->byt;
+		} else {
+			obj_str = obj_realloc(ist, byt_obj, sizeof(str_t)+new_len+1);
+			buf = obj_str->byt;
+		}
+		num_read = next_read;
+		aprerr = apr_file_read(STREAM(self), buf + total_read, &num_read);
+		if (aprerr != APR_SUCCESS && aprerr != APR_EOF) {
+			raise_exception(ist, OBJ(IOEXCEPTION), "%s",
+					apr_strerror(aprerr, err_buf, sizeof(err_buf)));
+			return NULL;
+		}
+		total_read += num_read;
+	}
+	if (byt_obj->data_type == DATA_TYPE_IMMDATA)
+		byt_obj->imm_data_len = (int) total_read;
+	else {
+		obj_str = obj_realloc(ist, byt_obj, sizeof(str_t)+total_read+1);
+		obj_str->len = (data_size_t) total_read;
+		buf = obj_str->byt;
+	}
+	buf[total_read] = 0;
+	byt_obj->immutable = TRUE;
+	return byt_obj;
+}
+
+DEF(File, readLine, FPARM1(size, NEW_INT(-1))) {
+	int readall = FALSE;
+	size_t size, total_read;
+	obj_p byt_obj;
+	byt_p obj_str;
+	u8_t* buf;
+	apr_status_t aprerr;
+	char err_buf[1024];
+	i64_t  size_in;
+
+	BIN_CONTENT_CHK(File);
+	INT_64_PARAM(1, size_in);
+
+	if (!has_proto(ist, self, File_OBJ)) {
+		raise_exception(ist, OBJ(TYPE_EXC), "readLine can only be called on a File object");
+		return NULL;
+	}
+	if (!OPEN(self)) {
+		raise_exception(ist, OBJ(IOEXCEPTION), "readLine called on closed file");
+		return NULL;
+	}
+	if (!(FLAGS(self) & APR_READ)) {
+		raise_exception(ist, OBJ(IOEXCEPTION), "readLine called on file opened without read perms");
+		return NULL;
+	}
+	if (!size_in) return NEW_BYTES(NULL, 0);
+	if (size_in < 0) {
+		readall = TRUE;
+		size = BUFSIZE(self);
+	} else
+		size = (size_t) size_in;
+	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;
+	} else {
+		obj_str = obj_malloc(ist, OBJ(BYTES_PROTO), byt_obj, sizeof(str_t)+size+1);
+		buf = obj_str->byt;
+	}
+	aprerr = apr_file_gets(buf, (int)(size + 1), STREAM(self));
+	if (aprerr != APR_SUCCESS && aprerr != APR_EOF) {
+		raise_exception(ist, OBJ(IOEXCEPTION), "%s",
+				apr_strerror(aprerr, err_buf, sizeof(err_buf)));
+		return NULL;
+	}
+	total_read = strlen(buf);
+	while (aprerr != APR_EOF && buf[total_read-1] != '\n' && (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) {
+			obj_str = obj_malloc(ist, OBJ(BYTES_PROTO), byt_obj, sizeof(str_t)+new_len+1);
+			buf = obj_str->byt;
+		} else {
+			obj_str = obj_realloc(ist, byt_obj, sizeof(str_t)+new_len+1);
+			buf = obj_str->byt;
+		}
+		aprerr = apr_file_gets(buf + total_read, (int)(next_read + 1), STREAM(self));
+		if (aprerr != APR_SUCCESS && aprerr != APR_EOF) {
+			raise_exception(ist, OBJ(IOEXCEPTION), "%s",
+					apr_strerror(aprerr, err_buf, sizeof(err_buf)));
+			return NULL;
+		}
+		total_read = strlen(buf);
+	}
+	if (byt_obj->data_type == DATA_TYPE_IMMDATA)
+		byt_obj->imm_data_len = (int) total_read;
+	else {
+		obj_str = obj_realloc(ist, byt_obj, sizeof(str_t)+total_read+1);
+		buf = obj_str->byt;
+		obj_str->len = (data_size_t) total_read;
+	}
+	buf[total_read] = 0;
+	byt_obj->immutable = TRUE;
+	return byt_obj;
+}
+
+DEF(File, readLines, FPARM1(size, NEW_INT(-1))) {
+	int readall = FALSE;
+	size_t size, total_read=0, num_read;
+	obj_p byt_obj, list_obj;
+	byt_p obj_str;
+	u8_t* buf;
+	apr_status_t aprerr;
+	char err_buf[1024];
+	i64_t  size_in;
+
+	BIN_CONTENT_CHK(File);
+	INT_64_PARAM(1, size_in);
+
+	if (!has_proto(ist, self, File_OBJ)) {
+		raise_exception(ist, OBJ(TYPE_EXC), "readLines can only be called on a File object");
+		return NULL;
+	}
+	if (!OPEN(self)) {
+		raise_exception(ist, OBJ(IOEXCEPTION), "readLines called on closed file");
+		return NULL;
+	}
+        if (!(FLAGS(self) & APR_READ)) {
+                raise_exception(ist, OBJ(IOEXCEPTION), "readLines called on file opened without read perms");
+                return NULL;
+        }
+	if (!size_in) return NEW_BYTES(NULL, 0);
+	if (size_in < 0) {
+		readall = TRUE;
+		size = BUFSIZE(self);
+	} else
+		size = (size_t) size_in;
+	list_obj = NEW_LIST(10);
+	aprerr = 0;
+	while (aprerr != APR_EOF && (readall || total_read < size)) {
+		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;
+		} else {
+			obj_str = obj_malloc(ist, OBJ(BYTES_PROTO), byt_obj, sizeof(str_t)+size+1);
+			buf = obj_str->byt;
+		}
+		aprerr = apr_file_gets(buf, (int)(size - total_read + 1), STREAM(self));
+		if (aprerr != APR_SUCCESS && aprerr != APR_EOF) {
+			raise_exception(ist, OBJ(IOEXCEPTION), "%s",
+					apr_strerror(aprerr,
+					err_buf, sizeof(err_buf)));
+			return NULL;
+		}
+		total_read += num_read = strlen(buf);
+		while ( aprerr != APR_EOF && buf[num_read-1] != '\n' &&
+				                   (readall || total_read < size) ) {
+			size_t next_read = (readall ? size : size - total_read);
+			size_t new_len = num_read + next_read;
+			if (byt_obj->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 {
+				obj_str = obj_realloc(ist, byt_obj, sizeof(str_t)+new_len+1);
+				buf = obj_str->byt;
+			}
+			aprerr = apr_file_gets(buf + num_read, (int)(next_read + 1), STREAM(self));
+			if (aprerr != APR_SUCCESS && aprerr != APR_EOF) {
+				raise_exception(ist, OBJ(IOEXCEPTION), "%s",
+						apr_strerror(aprerr,
+						err_buf, sizeof(err_buf)));
+				return NULL;
+			}
+			total_read += num_read = strlen(buf);
+		}
+		if (byt_obj->data_type == DATA_TYPE_IMMDATA)
+			byt_obj->imm_data_len = (int) num_read;
+		else {
+			obj_str = obj_realloc(ist, byt_obj, sizeof(str_t)+num_read+1);
+			buf = obj_str->byt;
+			obj_str->len = (data_size_t) num_read;
+		}
+		buf[num_read] = 0;
+		byt_obj->immutable = TRUE;
+		list_append(ist, list_obj, byt_obj);
+	}
+	return list_obj;
+}
+
+DEF(File, seek, FPARM2( pos, NULL,
+                        how, NEW_INT(0) ) ) {
+	apr_off_t pos;
+	apr_seek_where_t origin;
+	apr_status_t aprerr;
+	char err_buf[1024];
+	i64_t pos_in, how;
+
+	BIN_CONTENT_CHK(File);
+	INT_64_PARAM(1, pos_in);
+	INT_64_PARAM(2, how);
+
+	if (!has_proto(ist, self, File_OBJ)) {
+		raise_exception(ist, OBJ(TYPE_EXC), "seek can only be called on a File object");
+		return NULL;
+	}
+	if (!OPEN(self)) {
+		raise_exception(ist, OBJ(IOEXCEPTION), "seek called on closed file");
+		return NULL;
+	}
+	pos = (apr_off_t)pos_in;
+	switch(how) {
+		case 0: origin = APR_SET; break;
+		case 1: origin = APR_CUR; break;
+		case 2: origin = APR_END; break;
+		default :
+			raise_exception(ist, OBJ(TYPE_EXC), "file seek how parameter must be 0, 1, or 2");
+			return NULL;
+	}
+
+	aprerr = apr_file_seek(STREAM(self), origin, &pos);
+	if (aprerr != APR_SUCCESS) {
+		raise_exception(ist, OBJ(IOEXCEPTION), "%s",
+				apr_strerror(aprerr, err_buf, sizeof(err_buf)));
+		return NULL;
+	}
+	return OBJ(NONE);
+}
+#if 0
+DEF(File, tell, NULL) {
+	BIN_CONTENT_CHK(File);
+	if (!OPEN(self)) {
+		raise_exception(ist, OBJ(IOEXCEPTION), "tell called on closed file");
+		return NULL;
+	}
+	return NEW_INT(ftell(STREAM(self)));
+}
+#endif
+DEF(File, truncate, FPARM1(size, NULL)) {
+	apr_status_t aprerr;
+	char err_buf[1024];
+	apr_off_t size;
+	i64_t size_in;
+
+	BIN_CONTENT_CHK(File);
+	INT_64_PARAM(1, size_in);
+
+	if (!has_proto(ist, self, File_OBJ)) {
+		raise_exception(ist, OBJ(TYPE_EXC), "truncate can only be called on a File object");
+		return NULL;
+	}
+	if (!OPEN(self)) {
+		raise_exception(ist, OBJ(IOEXCEPTION), "truncate called on closed file");
+		return NULL;
+	}
+
+	/* XXX Need a way to check for upper bounds portably. This can be
+	 * different on 64-bit systems, or systems which support LFS */
+	if (size_in < 0) {
+		raise_exception(ist, OBJ(TYPE_EXC), "file truncate size value out of range");
+		return NULL;
+	}
+	size = (apr_off_t)(size_in);
+
+	aprerr = apr_file_trunc(STREAM(self), size);
+	if(aprerr != APR_SUCCESS) {
+		raise_exception(ist, OBJ(IOEXCEPTION), "%s",
+				apr_strerror(aprerr, err_buf, sizeof(err_buf)));
+		return NULL;
+	}
+	return OBJ(NONE);
+}
+
+DEF(File, write, FPARM1(str, NULL)) {
+	apr_size_t size;
+	apr_status_t aprerr;
+	char err_buf[1024];
+	char* str;
+
+	BIN_CONTENT_CHK(File);
+	STRING_PARAM(1, str);
+	size = pr_strlen(parms[1]);
+
+	if (!has_proto(ist, self, File_OBJ)) {
+		raise_exception(ist, OBJ(TYPE_EXC), "write can only be called from a File object");
+		return NULL;
+	}
+	if (!OPEN(self)) {
+		raise_exception(ist, OBJ(IOEXCEPTION), "write called on closed file");
+		return NULL;
+	}
+	if (!(FLAGS(self) & APR_WRITE)) {
+		raise_exception(ist, OBJ(IOEXCEPTION), "write called on file opened without write perms");
+		return NULL;
+	}
+
+	aprerr = apr_file_write(STREAM(self), str, &size);
+	if (aprerr != APR_SUCCESS) {
+		raise_exception(ist, OBJ(IOEXCEPTION), "%s",
+				apr_strerror(aprerr, err_buf, sizeof(err_buf)));
+		return NULL;
+	}
+	return parms[1];
+}
+
+DEF(File, writeLines, FPARM1(lst, NULL)) {
+	char* str;
+	apr_size_t size;
+	apr_status_t aprerr;
+	char err_buf[1024];
+
+	if (!has_proto(ist, parms[1], OBJ(SEQ_PROTO)) && !has_proto(ist, parms[1], OBJ(BYTES_PROTO))) {
+		raise_exception(ist, OBJ(TYPE_EXC), "file writeLines parameter must be a sequence or a string");
+		return NULL;
+	}
+	if (!has_proto(ist, self, File_OBJ)) {
+		raise_exception(ist, OBJ(TYPE_EXC), "writeLines can only be called on a File object");
+		return NULL;
+	}
+	if (!OPEN(self)) {
+		raise_exception(ist, OBJ(IOEXCEPTION), "write called on closed file");
+		return NULL;
+	}
+	if (!(FLAGS(self) & APR_WRITE)) {
+		raise_exception(ist, OBJ(IOEXCEPTION), "writeLines called on file opened without write perms");
+		return NULL;
+	}
+	if (has_proto(ist, parms[1], OBJ(BYTES_PROTO))) {
+		str  = pr2c_strptr(ist, parms[1]);
+		size = pr_strlen(parms[1]);
+		aprerr = apr_file_write(STREAM(self), str, &size);
+		if (aprerr != APR_SUCCESS) {
+			raise_exception(ist, OBJ(IOEXCEPTION), "%s",
+					apr_strerror(aprerr, err_buf, sizeof(err_buf)));
+			return NULL;
+		}
+	} else {
+		int i, llen = (int) list_len(ist, parms[1]);
+		for(i = 0; i < llen; i++) {
+			obj_p item = list_item(ist, parms[1], i);
+			if (!has_proto(ist, item, OBJ(BYTES_PROTO))) {
+				raise_exception(ist, OBJ(TYPE_EXC), "file writeLines lst item must be a string");
+				return NULL;
+			}
+			str  = pr2c_strptr(ist, item);
+			size = pr_strlen(item);
+			aprerr = apr_file_write(STREAM(self), str, &size);
+			if (aprerr != APR_SUCCESS) {
+				raise_exception(ist, OBJ(IOEXCEPTION), "%s",
+						apr_strerror(aprerr, err_buf, sizeof(err_buf)));
+				return NULL;
+			}
+		}
+	}
+	return parms[1];
+}
+
+DEF(File, setStdOut, FORM_RPARAM) {
+	int i;
+	if (!has_proto(ist, parms[1], File_OBJ)) {
+		raise_exception(ist, OBJ(TYPE_EXC), "stdout can only be assigned to a file object");
+		return NULL;
+	}
+	su(i);  read_unlock(ist, self);
+	set_attr(ist, self, sym(ist, "stdout"), parms[1]);
+	un_su(i); read_lock(ist, self);
+	return parms[1];
+}
+
+
+#define __STDIN		0
+#define __STDOUT	1
+#define __STDERR	2
+
+static obj_p __open_std_file(int type, apr_pool_t *subpool)
+{
+	obj_p mode, file;
+	apr_file_t *fp;
+	apr_status_t aprerr;
+	apr_int32_t flags;
+
+	switch (type) {
+		case __STDIN:
+			aprerr = apr_file_open_stdin(&fp, subpool);
+			mode = NEW_STRING("r");
+			file = NEW_STRING("<stdin>");
+			flags = APR_READ;
+			break;
+
+		case __STDOUT:
+			aprerr = apr_file_open_stdout(&fp, subpool);
+			file = NEW_STRING("<stdout>");
+			mode = NEW_STRING("w");
+			flags = APR_WRITE;
+			break;
+
+		case __STDERR:
+			aprerr = apr_file_open_stderr(&fp, subpool);
+			file = NEW_STRING("<stderr>");
+			mode = NEW_STRING("w");
+			flags = APR_WRITE;
+			break;
+
+		default:
+			return NULL; /* XXX something stupid, do an error */
+	}
+
+	if (aprerr != APR_SUCCESS)
+		return NULL;
+
+	return new_file_object(file, mode, fp, MIN_BUFSIZE, flags);
+}
+
+MAIN_MODULE_INIT(File) {
+	apr_pool_t *std_pool;
+	apr_status_t aprerr;
+	obj_p file_obj;
+
+	MODULE_SUB_INIT(File);
+	MODULE_ADD_SYM(File, init_);
+	MODULE_ADD_SYM(File, read);
+	MODULE_ADD_SYM(File, readLine);
+	MODULE_ADD_SYM(File, readLines);
+	MODULE_ADD_SYM(File, write);
+	MODULE_ADD_SYM(File, writeLines);
+	MODULE_ADD_SYM(File, flush);
+	MODULE_ADD_SYM(File, seek);
+	MODULE_ADD_SYM(File, truncate);
+	MODULE_ADD_SYM(File, close);
+	MODULE_ADD_SYM(File, closed_QUES);
+	MODULE_ADD_SYM(File, setStdOut);
+	MODULE_ADD_SYM(File, objList_);
+
+	/* Create base file objects for std{in,out,err} */
+	aprerr = apr_pool_create(&std_pool, get_pr_head_pool());
+	/* Need some kind of error return! */
+	if (aprerr != APR_SUCCESS)
+		return;
+
+	if ((file_obj = __open_std_file(__STDIN, std_pool)))
+		set_attr(ist, File_OBJ, sym(ist, "stdin"), file_obj);
+	if ((file_obj = __open_std_file(__STDOUT, std_pool)))
+		set_attr(ist, File_OBJ, sym(ist, "stdout"), file_obj);
+	if ((file_obj = __open_std_file(__STDERR, std_pool)))
+		set_attr(ist, File_OBJ, sym(ist, "stderr"), file_obj);
+
+	check_exceptions(ist);
+}
Modified: trunk/src/builtins-float.c
===================================================================
--- trunk/src/builtins-float.c	2004-06-08 13:13:51 UTC (rev 586)
+++ trunk/src/builtins-float.c	2004-06-09 21:40:50 UTC (rev 587)
@@ -97,11 +97,11 @@
 	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 = IMMEDIATE_DATA_LEN;
+	Float_OBJ->imm_data_len = IMM_DATA_LEN;
 	Float_OBJ->data.f64     = 0.0;
 
 	//Imag_OBJ->data_type    = DATA_TYPE_IMMDATA;
-	//Imag_OBJ->imm_data_len = IMMEDIATE_DATA_LEN;
+	//Imag_OBJ->imm_data_len = IMM_DATA_LEN;
 	//Imag_OBJ->data.f64     = 0.0;
 }
 
@@ -111,7 +111,7 @@
 	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 = IMMEDIATE_DATA_LEN;
+	self->imm_data_len = IMM_DATA_LEN;
 	self->data.f64     = f;
 	return OBJ(NONE);
 }

Modified: trunk/src/builtins-int.c
===================================================================
--- trunk/src/builtins-int.c	2004-06-08 13:13:51 UTC (rev 586)
+++ trunk/src/builtins-int.c	2004-06-09 21:40:50 UTC (rev 587)
@@ -562,7 +562,7 @@
 	str = new_string_n_obj(ist, "", i);
 	if (str == NULL)
 		return NULL;
-	p = pr_strptr(str) + i;
+	p = pr2c_strptr(ist, str) + i;
     if (addL)
         *--p = 'L';
 	if (a->dsize < 0)
@@ -587,7 +587,7 @@
 			do {
 				char cdigit = (char)(accum & (base - 1));
 				cdigit += (cdigit < 10) ? '0' : 'A'-10;
-				pr_assert(p > pr_strptr(str));
+				pr_assert(p > pr2c_strptr(ist, str));
 				*--p = cdigit;
 				accumbits -= basebits;
 				accum >>= basebits;
@@ -639,7 +639,7 @@
 			do {
 				digit nextrem = (digit)(rem / base);
 				char c = (char)(rem - nextrem * base);
-				pr_assert(p > pr_strptr(str));
+				pr_assert(p > pr2c_strptr(ist, str));
 				c += (c < 10) ? '0' : 'A'-10;
 				*--p = c;
 				rem = nextrem;
@@ -668,13 +668,13 @@
 	}
 	if (sign)
 		*--p = sign;
-	if (p != pr_strptr(str)) {
-		char *q = pr_strptr(str);
+	if (p != pr2c_strptr(ist, str)) {
+		char *q = pr2c_strptr(ist, str);
 		pr_assert(p > q);
 		do {
 		} while ((*q++ = *p++) != '\0');
 	}
-	return NEW_STRING(pr_strptr(str));
+	return NEW_STRING(pr2c_strptr(ist, str));
 }
 
 /* *str points to the first digit in a string of base base digits. base
@@ -2025,7 +2025,7 @@
 	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 = IMMEDIATE_DATA_LEN;
+	Int_OBJ->imm_data_len = IMM_DATA_LEN;
 	Int_OBJ->data.i64   = 0;
 
 	/* Dependent objects */
@@ -2570,10 +2570,6 @@
 	return res;
 }
 
-DEF(Int, cDataLen_, NULL) {
-	BIN_CONTENT_CHK(Int);
-	return NEW_INT(sizeof(long_t) + long_size(self) * sizeof(digit));
-}
 DEF(Int, objList_, FORM_RPARAM) {
 	return parms[1];
 }
@@ -2607,7 +2603,6 @@
 	MODULE_ADD_SYM(Int, rShift_);
 	MODULE_ADD_SYM(Int, lShift_);
 	MODULE_ADD_SYM(Int, iter_);
-	MODULE_ADD_SYM(Int, cDataLen_);
 	MODULE_ADD_SYM(Int, objList_);
 
 	MODULE_SUB_INIT(IntGen);

Modified: trunk/src/builtins-list.c
===================================================================
--- trunk/src/builtins-list.c	2004-06-08 13:13:51 UTC (rev 586)
+++ trunk/src/builtins-list.c	2004-06-09 21:40:50 UTC (rev 587)
@@ -68,14 +68,14 @@
 
 static int seq_len(isp ist, obj_p seq) {
 	if (has_proto(ist, seq, OBJ(STRING_PROTO)))
-		return (int) strlen(pr_strptr(seq));
+		return (int) strlen(pr2c_strptr(ist, seq));
 	else return (int) list_len(ist, seq);
 }
 
 static obj_p seq_item(isp ist, obj_p seq, int i) {
 	char s[2];
 	if (has_proto(ist, seq, OBJ(STRING_PROTO))) {
-		s[0] = pr_strptr(seq)[i];
+		s[0] = pr2c_strptr(ist, seq)[i];
 		s[1] = 0;
 		return NEW_STRING(s); 
 	} else
@@ -88,7 +88,7 @@
 	list_p lstp = list_obj->data.ptr = 
 		      pr_malloc(list_sizeof(max(initial_size,2)));
 	SET_TYPE_IF_EXC(List_OBJ, list_obj, DATA_TYPE_DATAPTR) return NULL;
-	lstpsize(lstp) = max(initial_size,2);
+	lstpsetsize(lstp, max(initial_size,2));
 	lstplen(lstp)  = 0;
 	return list_obj;
 }
@@ -99,7 +99,7 @@
 	lstp = obj->data.ptr = 
 			pr_malloc(list_sizeof(max(initial_size, 2)));
 	SET_TYPE_IF_EXC(OBJ(LIST_PROTO), obj, DATA_TYPE_DATAPTR) return;
-	lstpsize(lstp) = max(initial_size, 2);
+	lstpsetsize(lstp, max(initial_size, 2));
 	lstplen(lstp)  = 0;
 }
 
@@ -113,7 +113,7 @@
 	size = list_sizeof(llen);
 	res = copy_object(ist, list_obj);
 	res->data.ptr = list_ptr = pr_malloc(size);
-	lstpsize(list_ptr) = llen;
+	lstpsetsize(list_ptr, llen);
 	lstplen(list_ptr)  = llen;
 	memcpy( list_ptr->item, ((list_p)(list_obj->data.ptr))->item, 
 		                                  size-sizeof(list_hdr_t) );
@@ -162,7 +162,7 @@
 	wrlock_rtrn(list_obj) NULL;
 	lstp = list_obj->data.ptr;
 	if(lstplen(lstp) == lstpsize(lstp)) {
-		lstpsize(lstp) *= LIST_GROWTH_FACTOR;
+		lstpsetsize(lstp, lstpsize(lstp) * LIST_GROWTH_FACTOR);
 		lstp = pr_realloc(lstp, list_sizeof(lstpsize(lstp)));
 		list_obj->data.ptr = lstp;
 	}
@@ -176,7 +176,7 @@
 	list_p lstp;
 	lstp = list_obj->data.ptr;
 	if(lstplen(lstp) == lstpsize(lstp)) {
-		lstpsize(lstp) *= LIST_GROWTH_FACTOR;
+		lstpsetsize(lstp, lstpsize(lstp) * LIST_GROWTH_FACTOR);
 		lstp = pr_realloc(lstp, list_sizeof(lstpsize(lstp)));
 		list_obj->data.ptr = lstp;
 	}
@@ -308,7 +308,7 @@
 
 	SET_TYPE_IF_EXC(List_OBJ, List_OBJ, DATA_TYPE_DATAPTR) return;
 	lstp = List_OBJ->data.ptr = pr_malloc(list_sizeof(2));
-	lstpsize(lstp) = 2;
+	lstpsetsize(lstp, 2);
 	lstplen(lstp)  = 0;
 }
 
@@ -432,7 +432,7 @@
 		new_len = index1 + (i64_t) val_len + ((i64_t)self_len - index2);
 		listlen(self) = (size_t) new_len;
 		if (new_len+1 > listsize(self)) {
-			listsize(self) = (size_t) new_len + 1;
+			listsetsize(self, new_len + 1);
 			self->data.ptr = 
 				pr_realloc(self->data.ptr, list_sizeof(listsize(self)));
 		}
@@ -588,7 +588,7 @@
 		return NULL;
 	}
 	SET_TYPE_IF_EXC(List_OBJ, res, DATA_TYPE_DATAPTR) return NULL;
-	lstpsize(lstp) = size;
+	lstpsetsize(lstp, size);
 	lstplen(lstp)  = size;
 	for(i=0; i < times; i++)
 		memcpy(&(lstp->item[i*len]), selfp->item, len*sizeof(obj_p));
@@ -601,7 +601,7 @@
 	def_write_lock(self);
 	lstp = self->data.ptr;
 	if(lstplen(lstp) == lstpsize(lstp)) {
-		lstpsize(lstp) *= LIST_GROWTH_FACTOR;
+		lstpsetsize(lstp, lstpsize(lstp) * LIST_GROWTH_FACTOR);
 		lstp = pr_realloc(lstp, list_sizeof(lstpsize(lstp)));
 		self->data.ptr = lstp;
 	}
@@ -624,7 +624,7 @@
 	otherp    = parms[1]->data.ptr;
 	other_len = lstplen(otherp);
 	if(self_len+other_len > lstpsize(selfp)) {
-		lstpsize(selfp) = (self_len+other_len) * LIST_GROWTH_FACTOR;
+		lstpsetsize(selfp, (self_len+other_len) * LIST_GROWTH_FACTOR);
 		selfp = pr_realloc(selfp, list_sizeof(lstpsize(selfp)));
 		self->data.ptr = selfp;
 	}
@@ -653,7 +653,7 @@
 		return NULL;
 	}
 	if(lstplen(selfp) == lstpsize(selfp)) {
-		lstpsize(selfp) *= LIST_GROWTH_FACTOR;
+		lstpsetsize(selfp, lstpsize(selfp) * LIST_GROWTH_FACTOR);
 		selfp = pr_realloc(selfp, list_sizeof(lstpsize(selfp)));
 		self->data.ptr = selfp;
 	}

Modified: trunk/src/builtins-protolist.c
===================================================================
--- trunk/src/builtins-protolist.c	2004-06-08 13:13:51 UTC (rev 586)
+++ trunk/src/builtins-protolist.c	2004-06-09 21:40:50 UTC (rev 587)
@@ -69,7 +69,7 @@
 // ***************************** new_protolist_obj ****************************
 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_DATAPTR) return NULL;
+	SET_TYPE_IF_EXC(ProtoList_OBJ, self, DATA_TYPE_EXTPTR) return NULL;
 	self->data.ptr  = obj;
 	set_unclonable(self);
 	return self;
@@ -109,14 +109,14 @@
 	set_obj_id(ProtoList_OBJ, *, ProtoList);
 	set_attr(ist, OBJ(OBJECT), sym(ist, "ProtoList"), ProtoList_OBJ);
 
-	ProtoList_OBJ->data_type = DATA_TYPE_DATAPTR;
+	ProtoList_OBJ->data_type = DATA_TYPE_EXTPTR;
 	ProtoList_OBJ->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_DATAPTR) return NULL;
+	SET_TYPE_IF_EXC(ProtoList_OBJ, self, DATA_TYPE_EXTPTR) return NULL;
 	self->data.ptr = parms[1];
 	set_unclonable(self);
 	return OBJ(NONE);
Modified: trunk/src/builtins-string.c
===================================================================
--- trunk/src/builtins-string.c	2004-06-08 13:13:51 UTC (rev 586)
+++ trunk/src/builtins-string.c	2004-06-09 21:40:50 UTC (rev 587)
@@ -75,78 +75,93 @@
 //********************************* new_string_obj ****************************
 // this cannot be used with binary data, for C strings only
 // for binary data with embedded nulls use NEW_STRINGN()
-obj_p new_string_obj(isp ist, const char* str){
+obj_p new_string_obj(isp ist, char* str) {
 	obj_p obj;
-	pr_str_p obj_str;
-	size_t len;
 	if(!str) return NULL;
-	len = strlen(str);
 	obj = NEW_OBJ(OBJ(STRING_PROTO));
-	if (len < IMMEDIATE_DATA_LEN) {
-		SET_TYPE_IF_EXC(OBJ(STRING_PROTO), obj, DATA_TYPE_IMMDATA) return NULL;
-		obj->imm_data_len = (int) len;
-		strcpy(obj->data.str, str);
-	} else {
-		obj_str = obj_malloc(ist, OBJ(STRING_PROTO), obj, sizeof(pr_str_t)+len+1); if_exc_return NULL;
-		obj_str->len = len;
-		strcpy(&(obj_str->str[0]), str);
-	}
-	obj->immutable = TRUE;
+	c2pr_strcpy(ist, obj, str, strlen(str));
 	return obj;
 }
 
 //********************************* new_string_n_obj **************************
 obj_p new_string_n_obj(isp ist, char* str, size_t len) {
 	obj_p obj;
-	pr_str_p obj_str;
 	if(!str) return NULL;
 	obj = NEW_OBJ(OBJ(STRING_PROTO));
-	if (len < IMMEDIATE_DATA_LEN) {
-		SET_TYPE_IF_EXC(OBJ(STRING_PROTO), obj, DATA_TYPE_IMMDATA) return NULL;
-		obj->imm_data_len = (int) len;
-		memcpy(obj->data.str, str, len);
-		obj->data.str[len] = 0;
-	} else {
-		obj_str = obj_malloc(ist, OBJ(STRING_PROTO), obj, sizeof(pr_str_t)+len+1);
-		obj_str->len = len;
-		memcpy(&(obj_str->str[0]), str, len);
-		obj_str->str[len] = 0;
-	}
+	c2pr_strcpy(ist, obj, str, len);
 	obj->immutable = TRUE;
 	return obj;
 }
 
-//********************************* set_string_data ***************************
-void set_string_data(isp ist, obj_p obj, char* p, size_t len) {
-	pr_str_p obj_str;
-	if (len < 8) {
+//********************************* c2pr_strcpy *******************************
+void c2pr_strcpy(isp ist, obj_p obj, char* str, data_size_t len) {
+	str_p obj_str;
+	ch3_p ch3p;
+	data_size_t i, size = len*3;
+
+	if (size <= IMM_DATA_LEN) {
 		SET_TYPE_IF_EXC(OBJ(STRING_PROTO), obj, DATA_TYPE_IMMDATA) return;
-		obj->imm_data_len = (u8_t) len;
-		memcpy(obj->data.str, p, len);
-		obj->data.str[len]  = 0;
+		obj->imm_data_len = (int) size;
+		ch3p = obj->data.str;
 	} else {
-		obj_str = obj->data.ptr = obj_malloc(ist, OBJ(STRING_PROTO), obj, sizeof(pr_str_t)+len+1);
-		obj_str->len = len;
-		memcpy(&(obj_str->str[0]), p, len);
-		obj_str->str[len] = 0;
+		obj_str = obj_malloc(ist, OBJ(STRING_PROTO), obj, sizeof(str_t)+size); if_exc_return;
+		obj_str->size = sizeof(str_t)+size;
+		ch3p = obj_str->str;
 	}
+	for (i=0; i < len; i++, str++, ch3p++) {
+		ch3p->b0 = *str;
+		ch3p->b1 = 0;
+		ch3p->b2 = 0;
+	}
 	obj->immutable = TRUE;
 }
 
+//********************************* pr2c_strptr *******************************
+char* pr2c_strptr(isp ist, obj_p str_obj) {
+	str_p strp;
+	ch3_p ch3p;
+	data_size_t i, data_size, len;
+	char* res;
+
+	if (!str_obj) {
+		raise_exception(ist, OBJ(VALUE_EXC), "string object missing");
+		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;
+		data_size = strp->size - sizeof(str_t);
+		ch3p      = strp->str;
+	} else {
+		raise_exception(ist, OBJ(VALUE_EXC), "string object uninitialized");
+		return NULL;
+	}
+	len = data_size/3;
+	res = pr_malloc(len+1);
+	for (i=0; i < len; i++) {
+		res[i] = (char) ch3p[i].b0;
+		if (!ch3p[i].b0 || ch3p[i].b0 > 127 || ch3p[i].b1 || ch3p[i].b2) {
+			raise_exception(ist, OBJ(VALUE_EXC), "string has non-ascii value");
+			return NULL;
+		}
+	}
+	res[i] = 0;
+	return res;
+}
 //********************************* changeCase ********************************
 // Generic case-changer function.
 #define AT_WORD_START -1
-static obj_p changeCase(isp ist,obj_p self,int (*changer)(int), size_t howMany) {
+static obj_p changeCase(isp ist,obj_p self, int (*changer)(int), size_t howMany) {
 	size_t str_len = pr_strlen(self), ii = 0;
 	char *src_ptr, *dest_ptr = 0;
-	obj_p obj;
 	int atStart = 1;
 
-	obj = copy_object(ist, self);
-	dest_ptr  = pr_strptr(obj);
+	dest_ptr = pr2c_strptr(ist, self);
 
 	// Change the copy.
-	src_ptr = pr_strptr(self);
+	src_ptr  = pr2c_strptr(ist, self);
 	for (ii=0; ii<str_len; ++ii) {
 		if (howMany == AT_WORD_START) {
 			if (atStart)
@@ -157,7 +172,7 @@
 				dest_ptr[ii] = (char)(*changer)(src_ptr[ii]);
 		}
 	}
-	return obj;
+	return NEW_STRING(dest_ptr);
 }
 
 //********************************* bin_strstr ********************************
@@ -203,7 +218,6 @@
 	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->data.str[0]  = 0;
 }
 
 DEF(String, init_, FORM_STAR_PARAM) {
@@ -220,14 +234,14 @@
 		obj_p obj2, obj = list_item(ist, parms[1], 0);
 		if (llen == 1 && has_proto(ist, obj, OBJ(SYMBOL_PROTO))) {
 			s = symch(ist, obj);
-		} else if ( llen == 2 && has_proto(ist,      obj, OBJ(INT_PROTO)) && 
+		} 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);
-				s = pr_strptr(res);
+				s = pr2c_strptr(ist, res);
 			} else {
 				res = long_format(obj->data.ptr, int2i32t(ist, obj2), FALSE);
-				s = pr_strptr(res);
+				s = pr2c_strptr(ist, res);
 			}
 		} else if (llen == 1) {
 			s = as_str(ist, obj);
@@ -237,7 +251,7 @@
 		}
 	} else
 		s = "";
-	set_string_data(ist, self, s, strlen(s));
+	c2pr_strcpy(ist, self, s, strlen(s));
 	if (res) del_unlock(res);
 	return OBJ(NONE);
 }
@@ -249,9 +263,10 @@
 
 DEF(String, hash_, NULL) {
 	i32_t res = 0x9a7c5e3;
-	char *p;
+	char *p,*p2;
 	BIN_CONTENT_CHK(String);
-	for(p=pr_strptr(self); *p; p++) res += 131 * (*p);
+	for(p2=p=pr2c_strptr(ist, self); *p; p++) res += 131 * (*p);
+	pr_free(p2);
 	return new_hash_obj(ist, res);
 }
 
@@ -279,39 +294,32 @@
 		raise_exception(ist, OBJ(TYPE_EXC), "Cannot compare a string and non-string");
 		return NULL;
 	}
-	return NEW_INT(strcmp(pr_strptr(self), pr_strptr(other)));
+	return NEW_INT(strcmp(pr2c_strptr(ist, self), pr2c_strptr(ist, other)));
 }
 
 DEF(String, add_, FORM_RPARAM){
-	obj_p obj, other = parms[1];
-	pr_str_p obj_str;
+	obj_p res, other = parms[1];
 	size_t slen, olen, tlen;
+	char* buf;
+
 	BIN_CONTENT_CHK(String);
 	if (!is_String(other)) other = call_func0(ist, other, SYM(STR_));
 	slen = pr_strlen(self); olen = pr_strlen(other);
 	tlen = slen + olen;
-	obj = NEW_OBJ(String_OBJ);
-	if (tlen < IMMEDIATE_DATA_LEN) {
-		SET_TYPE_IF_EXC(String_OBJ, obj, DATA_TYPE_IMMDATA) return NULL;
-		obj->imm_data_len = (int) tlen;
-		memcpy(&(obj->data.str[0]),    pr_strptr(self),  slen);
-		memcpy(&(obj->data.str[slen]), pr_strptr(other), olen);
-		obj->data.str[tlen] = 0;
-	} else {
-		obj_str = obj_malloc(ist, OBJ(STRING_PROTO), 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);
-		obj_str->str[tlen] = 0;
-	}
-	obj->immutable = TRUE;
-	return obj;
+	buf = pr_malloc(tlen+1);
+	memcpy(buf,      pr2c_strptr(ist, self),  slen);
+	memcpy(buf+slen, pr2c_strptr(ist, other), olen);
+	buf[tlen] = 0;
+	res = NEW_STRINGN(buf, tlen);
+	pr_free(buf);
+	return res;
 }
 
 DEF(String, mul_, FORM_RPARAM){
-	obj_p obj;
-	pr_str_p obj_str;
+	obj_p res;
 	size_t i, times, tlen, len = pr_strlen(self);
+	char *buf, *self_strptr;
+
 	BIN_CONTENT_CHK(String);
 	if (!has_proto(ist, parms[1], OBJ(INT_PROTO))) {
 		raise_exception(ist, OBJ(TYPE_EXC), "multiply times parameter must be an integer");
@@ -321,34 +329,21 @@
 	if(times == 0) return NEW_STRING("");
 	if(times == 1) return self;
 	tlen = len*times;
-	obj = NEW_OBJ(String_OBJ);
-	if (tlen < IMMEDIATE_DATA_LEN-1) {
-		SET_TYPE_IF_EXC(String_OBJ, obj, DATA_TYPE_IMMDATA) return NULL;
-		obj->imm_data_len = (int) tlen;
-		for(i=0; i < times; i++)
-			memcpy(obj->data.str+i*len, pr_strptr(self), len);
-		obj->data.str[tlen] = 0;
-	} else {
-		obj_str = obj_malloc(ist, String_OBJ, obj, sizeof(pr_str_t)+tlen+1);
-		if(!obj_str) {
-			raise_exception(ist, OBJ(OUTOFMEMORY_EXC), "memory allocation failed for string multiplication");
-			return NULL;
-		}
-		obj_str->len = tlen;
-		for(i=0; i < times; i++)
-			memcpy(obj_str->str+i*len, pr_strptr(self), len);
-		obj_str->str[tlen] = 0;
-	}
-	obj->immutable = TRUE;
-	return obj;
+	buf = pr_malloc(tlen+1);
+	self_strptr = pr2c_strptr(ist, self);
+	for(i=0; i < times; i++)
+		memcpy(buf+(i*len), self_strptr, len);
+	buf[tlen] = 0;
+	res = NEW_STRINGN(buf, tlen);
+	pr_free(buf);
+	return res;
 }
 
-
 DEF(String, mod_, FORM_RPARAM) {
 	obj_p			res, argv_obj = parms[1];
 	size_t			i, argc;
 	pr_arg_p		argv;
-	char			*fmt_str = pr_strptr(self), *buf;
+	char			*fmt_str = pr2c_strptr(ist, self), *buf;
 	apr_status_t	aprerr;
 
 	BIN_CONTENT_CHK(String);
@@ -368,7 +363,7 @@
 			argv[i].arg.f64 = arg_obj->data.f64;
 			argv[i].type    = ARG_TYPE_FLOAT;
 		} else if (has_proto(ist, arg_obj, OBJ(STRING_PROTO))) {
-			argv[i].arg.str = pr_strptr(arg_obj);
+			argv[i].arg.str = pr2c_strptr(ist, arg_obj);
 			argv[i].type    = ARG_TYPE_STRING;
 		} else {
 			raise_exception(ist, OBJ(TYPE_EXC), "invalid type for string (%%) format");
@@ -388,16 +383,25 @@
 }
 
 DEF(String, ord, NULL) {
+	ch3_p ch3p;
 	BIN_CONTENT_CHK(String);
-	return NEW_INT((int)(*pr_strptr(self)));
+	if (!pr_strlen(self)) {
+		raise_exception(ist, OBJ(VALUE_EXC), "ord not valid on empty string");
+		return NULL;
+	}
+	ch3p = ((str_p)self->data.ptr)->str;
+	return NEW_INT(ch3p->b0+((ch3p->b1+(ch3p->b2*256))*256));
 }
 
 DEF(String, join, FORM_RPARAM) {
-	char *self_str, *dest_ptr;
-	pr_str_p obj_str;
+	char *self_str;
+	str_p obj_str;
 	obj_p obj, list, str_list;
 	int i, llen;
-	size_t ofs, self_len, tlen;
+	u32_t j;
+	size_t self_len, tlen;
+	ch3_p dest_ptr;
+
 	BIN_CONTENT_CHK(String);
 	if (!has_proto(ist, parms[1], OBJ(LIST_PROTO))) {
 		raise_exception(ist, OBJ(TYPE_EXC), "join function parameter must be a list");
@@ -407,7 +411,7 @@
 	llen = (int) list_len(ist, parms[1]);
 	if (!llen) return NEW_STRING("");
 	str_list = NEW_LIST(llen);
-	self_str = pr_strptr(self);
+	self_str = pr2c_strptr(ist, self);
 	self_len = pr_strlen(self);
 	tlen = 0;
 	for (i=0; i < llen; i++) {
@@ -417,30 +421,37 @@
 		if (i != llen-1) tlen += self_len;
 	}
 	obj = NEW_OBJ(String_OBJ);
-	if (tlen < IMMEDIATE_DATA_LEN) {
+	if (tlen*3 <= IMM_DATA_LEN) {
 		SET_TYPE_IF_EXC(String_OBJ, obj, DATA_TYPE_IMMDATA) return NULL;
-		obj->imm_data_len = (int) tlen;
+		obj->imm_data_len = (int) tlen*3;
 		dest_ptr = obj->data.str;
 	} else {
-		obj_str = obj_malloc(ist, OBJ(STRING_PROTO), obj, sizeof(pr_str_t)+tlen+1);
+		obj_str = obj_malloc(ist, OBJ(STRING_PROTO), obj, sizeof(str_t)+tlen*3);
 		if(!obj_str) {
 			raise_exception(ist, OBJ(OUTOFMEMORY_EXC), "memory allocation failed for string join");
 			return NULL;
 		}
-		obj_str->len = tlen;
+		obj_str->size = (data_size_t)(sizeof(str_t)+tlen*3);
 		dest_ptr = obj_str->str;
 	}
-	for(i=0, ofs=0; i < llen; i++) {
+	for(i=0; i < llen; i++) {
 		obj_p  str_obj = list_item(ist, str_list, i);
 		size_t str_len = pr_strlen(str_obj);
-		memcpy(dest_ptr+ofs, pr_strptr(str_obj), str_len);
-		ofs += str_len;
+		char* src_ptr = pr2c_strptr(ist, str_obj);
+		for (j=0; j < str_len; j++, src_ptr++, dest_ptr++) {
+			dest_ptr->b0 = *src_ptr;
+			dest_ptr->b1 = 0;
+			dest_ptr->b2 = 0;
+		}
 		if (i != llen-1) {
-			memcpy(dest_ptr+ofs, self_str, self_len);
-			ofs += self_len;
+			src_ptr = self_str;
+			for (j=0; j < self_len; j++, src_ptr++, dest_ptr++) {
+				dest_ptr->b0 = *src_ptr;
+				dest_ptr->b1 = 0;
+				dest_ptr->b2 = 0;
+			}
 		}
 	}
-	dest_ptr[tlen] = 0;
 	set_immutable(obj);
 	del_unlock(str_list);
 	return obj;
@@ -450,7 +461,7 @@
 	BIN_CONTENT_CHK(String);
 	if (!has_proto(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);
+	if (strstr(pr2c_strptr(ist, parms[1]), pr2c_strptr(ist, self))) return OBJ(PR_TRUE);
 	else						              return OBJ(PR_FALSE);
 }
 
@@ -458,7 +469,7 @@
 	BIN_CONTENT_CHK(String);
 	if (!has_proto(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);
+	if (strstr(pr2c_strptr(ist, parms[1]), pr2c_strptr(ist, self))) return OBJ(PR_FALSE);
 	else						              return OBJ(PR_TRUE);
 }
 
@@ -514,14 +525,14 @@
 		start = (size_t)int_imm_value(parms[3]);
 	}
 
-	find_ptr = pr_strptr(parms[1]);
+	find_ptr = pr2c_strptr(ist, parms[1]);
 	find_len = pr_strlen(parms[1]);
 	if (find_len<1) {
 		return new_int_obj(ist,0);
 	}
-	found = bin_strstr(pr_strptr(self)+int_imm_value(parms[3]),str_len,find_ptr,find_len);
+	found = bin_strstr(pr2c_strptr(ist, self)+int_imm_value(parms[3]),str_len,find_ptr,find_len);
 	if (found) {
-		result = new_int_obj(ist,found-pr_strptr(self));
+		result = new_int_obj(ist,found-pr2c_strptr(ist, self));
 	} else {
 		result = new_int_obj(ist,0);
 	}
@@ -534,9 +545,9 @@
 	size_t find_len = 0;
 	size_t repl_len = 0;
 	size_t result_len = str_len;
-	char* dest_ptr = 0;
+	char *buf, *dest_ptr = 0;
 	obj_p obj=0;
-	pr_str_p obj_str = 0;
+	str_p obj_str = 0;
 	char* src_ptr = 0;
 	char* find_ptr = 0;
 	char* repl_ptr = 0;
@@ -562,41 +573,26 @@
 		return NULL;
 	}
 	repl_len = pr_strlen(parms[3]);
-	src_ptr = pr_strptr(self);
-	find_ptr = pr_strptr(parms[1]);
-	repl_ptr = pr_strptr(parms[3]);
+	src_ptr  = pr2c_strptr(ist, self);
+	find_ptr = pr2c_strptr(ist, parms[1]);
+	repl_ptr = pr2c_strptr(ist, parms[3]);
 
 	// This is perhaps not as efficient as it could be.
 
 	// Find the length of the result string.
 	temp_len = str_len;
-	a_match = bin_strstr(src_ptr,temp_len,find_ptr,find_len);
+	a_match = bin_strstr(src_ptr, temp_len, find_ptr, find_len);
 	while (a_match) {
 		result_len -= find_len;
 		result_len += repl_len;
 		a_match += find_len; // Skip the matching text.
 		temp_len = str_len - (a_match - src_ptr);
-		a_match = bin_strstr(a_match,temp_len,find_ptr,find_len);
+		a_match = bin_strstr(a_match, temp_len, find_ptr, find_len);
 	}
 
 	// Create the copy.
-	// Create the copy.
-	obj = NEW_OBJ(String_OBJ);
-	if (result_len < IMMEDIATE_DATA_LEN-1) {
-		SET_TYPE_IF_EXC(String_OBJ, obj, DATA_TYPE_IMMDATA) return NULL;
-		obj->imm_data_len = (int) result_len;
-		dest_ptr = obj->data.str;
-		dest_ptr[result_len]=0;
-	} else {
-		obj_str = obj_malloc(ist, OBJ(STRING_PROTO), obj, sizeof(pr_str_t)+result_len+1);
-		if(!obj_str) {
-			raise_exception(ist, OBJ(OUTOFMEMORY_EXC), "memory allocation failed for string.replace");
-			return NULL;
-		}
-		obj_str->len = result_len;
-		dest_ptr = obj_str->str;
-		dest_ptr[result_len]=0;
-	}
+	dest_ptr = buf = pr_malloc(sizeof(str_t) + result_len + 1);
+	dest_ptr[result_len] = 0;
 
 	// Fill the replaced copy.
 	temp_len = str_len;
@@ -623,15 +619,15 @@
 	if (where_ptr<src_ptr+str_len) {
 		memcpy(dest_ptr,where_ptr,(src_ptr+str_len)-where_ptr);
 	}
-	return obj;
+	return NEW_STRINGN(buf, result_len);
 }
 
 DEF(String, expandTabs, FPARM1( nSpaces, NEW_INT(8) )) {
 	obj_p result;	
 	BIN_CONTENT_CHK(String);
 	{
-		obj_p tab = new_string_obj(ist,"\t");
-		obj_p tspace = new_string_obj(ist," ");
+		obj_p tab = new_string_obj(ist, "\t");
+		obj_p tspace = new_string_obj(ist, " ");
 		obj_p mul_args[]= {NULL, parms[1]};
 		obj_p spcs = Stringmul_(ist,tspace,2,mul_args,0);
 		obj_p repl_args[] = {NULL, tab, NULL, spcs};
@@ -648,7 +644,7 @@
 // we're dealing with null-terminated text strings.
 //===============================
 DEF(String, lStrip, NULL) {
-	char* cstr = pr_strptr(self);
+	char* cstr = pr2c_strptr(ist, self);
 
 	BIN_CONTENT_CHK(String);
 
@@ -657,12 +653,12 @@
 	}
 	
 	// Create the copy.
-	return new_string_obj(ist,cstr);
+	return new_string_obj(ist, cstr);
 }
 
 DEF(String, rStrip, NULL) {
 	// Count whitespace at the end.
-	char* cstr = pr_strptr(self)+pr_strlen(self)-1;
+	char* cstr = pr2c_strptr(ist, self)+pr_strlen(self)-1;
 	size_t result_len = 0;
 
 	BIN_CONTENT_CHK(String);
@@ -670,14 +666,14 @@
 	while (isspace(*cstr)) {
 		--cstr;
 	}
-	result_len = cstr-pr_strptr(self)+1;
+	result_len = cstr-pr2c_strptr(ist, self)+1;
 	
 	// Create the copy.
-	return new_string_n_obj(ist,pr_strptr(self),result_len);
+	return new_string_n_obj(ist,pr2c_strptr(ist, self),result_len);
 }
 
 DEF(String, strip, NULL) {
-	char *cstr2, *cstr = pr_strptr(self);
+	char *cstr2, *cstr = pr2c_strptr(ist, self);
 	size_t result_len;
 
 	BIN_CONTENT_CHK(String);
@@ -687,7 +683,7 @@
 	}
 	
 	// Count whitespace at the end.
-	cstr2 = pr_strptr(self)+pr_strlen(self)-1;
+	cstr2 = pr2c_strptr(ist, self)+pr_strlen(self)-1;
 	result_len = 0;
 	while (isspace(*cstr2)) {
 		--cstr2;
@@ -719,9 +715,9 @@
 		raise_exception(ist, OBJ(TYPE_EXC), "split: empty separator");
 		return NULL;
 	}
-	src_ptr = pr_strptr(self);
+	src_ptr = pr2c_strptr(ist, self);
 	where_ptr = src_ptr;
-	find_ptr = pr_strptr(parms[1]);
+	find_ptr = pr2c_strptr(ist, parms[1]);
 
 	temp_len = str_len;
 	a_match = bin_strstr(src_ptr,temp_len,find_ptr,find_len);
@@ -748,17 +744,11 @@
 	BIN_CONTENT_CHK(String);
 	gen_obj = NEW_OBJ(StringGen_OBJ);
 	SET_TYPE_IF_EXC(StringGen_OBJ, gen_obj, DATA_TYPE_DATAPTR) return NULL;
-	gen_obj->data.ptr = pr_strptr(self);
+	gen_obj->data.ptr = pr2c_strptr(ist, self);
 	set_attr(ist, gen_obj, sym(ist, "savedString"), self);
 	return gen_obj;
 }
 
-
-DEF(String, cDataLen_, NULL) {
-	BIN_CONTENT_CHK(String);
-	return NEW_INT(sizeof(pr_str_t) + pr_strlen(self) + 1);
-}
-
 DEF(String, objList_, FORM_RPARAM) {
 	return parms[1];
 }
@@ -828,7 +818,6 @@
 	MODULE_ADD_SYM(String, setItem_);
 	MODULE_ADD_SYM(String, delItem_);
 	MODULE_ADD_SYM(String, objList_);
-	MODULE_ADD_SYM(String, cDataLen_);
 
 	MODULE_SUB_INIT(StringGen);
 	MODULE_ADD_SYM(StringGen, next);

Modified: trunk/src/builtins-thread.c
===================================================================
--- trunk/src/builtins-thread.c	2004-06-08 13:13:51 UTC (rev 586)
+++ trunk/src/builtins-thread.c	2004-06-09 21:40:50 UTC (rev 587)
@@ -77,6 +77,7 @@
 	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->size          = sizeof(pr_thread_t);
 	thread_ptr->ist           = ist;
 	thread_ptr->apr_os_thread = apr_os_thread_current();
 	thread_ptr->running		  = TRUE;
@@ -116,6 +117,7 @@
 		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->ist = new_ist(acc_level);
 
@@ -203,6 +205,7 @@
     thread = obj_malloc(ist, Thread_OBJ, Thread_OBJ, sizeof(pr_thread_t));
 	if_exc_return;
     memset(thread, 0, sizeof(pr_thread_t));
+	thread->size = sizeof(pr_thread_t);
 	Thread_OBJ->unclonable = TRUE;
 }
 
@@ -226,6 +229,7 @@
 	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);
 	uthread->func   = parms[1]; 
 	uthread->params = parms[3]; 
@@ -254,7 +258,7 @@
 	char name[80];
 	BIN_STR_CHK(Thread);
 	if ((name_obj = get_attr(ist, self, sym(ist, "name"))))
-		apr_snprintf(name, sizeof(name), "<Thread:%s>", pr_strptr(name_obj));
+		apr_snprintf(name, sizeof(name), "<Thread:%s>", pr2c_strptr(ist, name_obj));
 	else 
 		apr_snprintf(name, sizeof(name), "<Thread:%lx>", (unsigned long)(uintptr_t)self);
 	return NEW_STRING(name);

Modified: trunk/src/builtins-tuple.c
===================================================================
--- trunk/src/builtins-tuple.c	2004-06-08 13:13:51 UTC (rev 586)
+++ trunk/src/builtins-tuple.c	2004-06-09 21:40:50 UTC (rev 587)
@@ -89,7 +89,7 @@
 
 	SET_TYPE_IF_EXC(Tuple_OBJ, Tuple_OBJ, DATA_TYPE_DATAPTR) return;
 	lstp = Tuple_OBJ->data.ptr = pr_malloc(list_sizeof(2));
-	lstpsize(lstp) = 2;
+	lstpsetsize(lstp, 2);
 	lstplen(lstp)  = 0;
 }
 
@@ -236,7 +236,7 @@
 		return NULL;
 	}
 	SET_TYPE_IF_EXC(Tuple_OBJ, res, DATA_TYPE_DATAPTR) return NULL;
-	lstpsize(lstp) = size;
+	lstpsetsize(lstp, size);
 	lstplen(lstp)  = size;
 	for(i=0; i < times; i++)
 		memcpy(lstp->item+(i*len), selfp->item, len*sizeof(obj_p));
@@ -303,10 +303,6 @@
 	return NULL;
 }
 
-DEF(Tuple, cDataLen_, NULL) {
-	return NEW_INT(list_sizeof(listsize(self)));
-}
-
 DEF(Tuple, iter_, NULL) {
 	obj_p list_obj, gen_obj = NEW_OBJ(Tgen_OBJ);
 	BIN_CONTENT_CHK(Tuple);
@@ -376,7 +372,6 @@
 	MODULE_ADD_SYM(Tuple, setItem_);
 	MODULE_ADD_SYM(Tuple, delItem_);
 	MODULE_ADD_SYM(Tuple, objList_);
-	MODULE_ADD_SYM(Tuple, cDataLen_);	
 
 	MODULE_SUB_INIT(Tgen);
 	MODULE_ADD_SYM(Tgen, next);

Modified: trunk/src/console.c
===================================================================
--- trunk/src/console.c	2004-06-08 13:13:51 UTC (rev 586)
+++ trunk/src/console.c	2004-06-09 21:40:50 UTC (rev 587)
@@ -89,14 +89,14 @@
 	obj_p prompt;
 	if (!sys) sys = get_attr(ist, OBJ(OBJECT), sym(ist, "Sys"));
 	prompt = get_attr(ist, sys, sym(ist, "ps1"));
-	return pr_strptr(prompt);
+	return pr2c_strptr(ist, prompt);
 }
 
 char* ps2(isp ist){
 	obj_p prompt;
 	if (!sys) sys = get_attr(ist, OBJ(OBJECT), sym(ist, "Sys"));
 	prompt = get_attr(ist, sys, sym(ist, "ps2"));
-	return pr_strptr(prompt);
+	return pr2c_strptr(ist, prompt);
 }
 
 int get_src(isp ist) {

Modified: trunk/src/dict.h
===================================================================
--- trunk/src/dict.h	2004-06-08 13:13:51 UTC (rev 586)
+++ trunk/src/dict.h	2004-06-09 21:40:50 UTC (rev 587)
@@ -58,8 +58,9 @@
 #define DICT_PAD_PERCENT_FACTOR		300
 
 typedef struct {
-	size_t	size;
-	size_t	len;
+	data_size_t		size_bytes;
+	size_t			size;
+	size_t			len;
 } dict_hdr_t;
 
 typedef struct {
@@ -75,16 +76,17 @@
 
 typedef dict_t*  dict_p;
 
+#define DICT_HDR_INDEX			0
+#define DICT_OVERHEAD			1
+
 #define dict_sizeof(n)			(((n)+DICT_OVERHEAD) * sizeof(dict_t))
-#define dict_size_bytes(dict)	(dict_sizeof(dictsize(dict)))
 
-#define DICT_HDR_INDEX		0
-#define DICT_OVERHEAD		1
-#define dict_d(dict_obj)	((dict_p)((dict_obj)->data.ptr))
-#define dictsize(dict)		(((dict_p)(dict))[DICT_HDR_INDEX].hdr.size)
-#define dictlen(dict)		(((dict_p)(dict))[DICT_HDR_INDEX].hdr.len)
-#define dictptr(dict, i)	( ((dict_p)(dict)) + DICT_OVERHEAD + ((i)%dictsize(dict)) )
-#define dicthash(dict,i)	(dictptr(((dict_p)(dict)),i)->entry.hash)
-#define dictkey(dict, i)	(dictptr(((dict_p)(dict)),i)->entry.key)
-#define dictitem(dict,i)	(dictptr(((dict_p)(dict)),i)->entry.value)
+#define dict_d(dict_obj)		((dict_p)((dict_obj)->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)
+#define dictptr(dict, i)		( ((dict_p)(dict)) + DICT_OVERHEAD + ((i)%dictsize(dict)) )
+#define dicthash(dict,i)		(dictptr(((dict_p)(dict)),i)->entry.hash)
+#define dictkey(dict, i)		(dictptr(((dict_p)(dict)),i)->entry.key)
+#define dictitem(dict,i)		(dictptr(((dict_p)(dict)),i)->entry.value)
 

Modified: trunk/src/init.pth
===================================================================
--- trunk/src/init.pth	2004-06-08 13:13:51 UTC (rev 586)
+++ trunk/src/init.pth	2004-06-09 21:40:50 UTC (rev 587)
@@ -5,7 +5,6 @@
 
 # these are added to Sys.path
 
-c:\prothon\modules\file\debug
 c:\prothon\modules\re\debug
 c:\prothon\modules\prosist\debug
 c:\prothon\modules\SQLite\debug
@@ -14,5 +13,5 @@
 
 # this is executed before Main as module PthMod1
 
-import File
+#import Re
 
Modified: trunk/src/interp.c
===================================================================
--- trunk/src/interp.c	2004-06-08 13:13:51 UTC (rev 586)
+++ trunk/src/interp.c	2004-06-09 21:40:50 UTC (rev 587)
@@ -108,7 +108,7 @@
 	code_p code = NULL;
 	size_t flen;
 	if (code_in)       code = code_in;
-	else if (func_obj) code = obj_data_p(func_obj);
+	else if (func_obj) code = obj_dataptr(func_obj);
 	flen = sizeof(frame_t) + ( code ? (code->max_stack_depth+STACK_PADDING) * sizeof(obj_p) : 0 );
 	frame = pr_malloc(flen);
 	memset(frame, 0, flen);
@@ -143,7 +143,7 @@
 //********************************* new_local_obj *****************************
 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_DATAPTR) return NULL;
+	SET_TYPE_IF_EXC(OBJ(LOCAL_PROTO), local_obj, DATA_TYPE_EXTPTR) return NULL;
 	local_obj->data.ptr = symbol;
 	local_obj->immutable = TRUE;
 	return local_obj;
@@ -153,7 +153,7 @@
 obj_p new_super_obj(isp ist, obj_p container, obj_p symbol) {
 	int i;
 	obj_p super_obj = NEW_OBJ(OBJ(SUPER_PROTO));
-	SET_TYPE_IF_EXC(OBJ(SUPER_PROTO), super_obj, DATA_TYPE_DATAPTR) return NULL;
+	SET_TYPE_IF_EXC(OBJ(SUPER_PROTO), super_obj, DATA_TYPE_EXTPTR) return NULL;
 	super_obj->data.ptr = symbol;
 	su(i);
 	set_attr(ist, super_obj, SYM(CONT_), container);
@@ -165,7 +165,7 @@
 //********************************* new_outer_obj *****************************
 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_DATAPTR) return NULL;
+	SET_TYPE_IF_EXC(OBJ(OUTER_PROTO), outer_obj, DATA_TYPE_EXTPTR) return NULL;
 	outer_obj->data.ptr = symbol;
 	outer_obj->immutable = TRUE;
 	return outer_obj;
@@ -626,13 +626,13 @@
 
 	for (i = 0; i < llen; i++) {
 		apr_snprintf(full_path, sizeof(full_path), "%s/%s/init_.pr",
-				pr_strptr(list_item(ist, path_list, i)),
+				pr2c_strptr(ist, list_item(ist, path_list, i)),
 				symch(ist, fr_data(pkg_depth)));
 
 		if (apr_stat(&finfo, full_path, APR_FINFO_TYPE, get_pr_head_pool()) ==
 		    APR_SUCCESS && finfo.filetype == APR_REG) {
 			apr_snprintf(pkg_path, sizeof(pkg_path), "%s/%s",
-				     pr_strptr(list_item(ist, path_list, i)),
+				     pr2c_strptr(ist, list_item(ist, path_list, i)),
 				     symch(ist, fr_data(pkg_depth)));
 
 			if (alias && pkg_depth < param-1)
@@ -703,7 +703,7 @@
 			alias = module_symbol;
 
 		for (i = 0; i < llen; i++) {
-			apr_cpystrn(full_path, pr_strptr(list_item(ist, path_list, i)),
+			apr_cpystrn(full_path, pr2c_strptr(ist, list_item(ist, path_list, i)),
 				    sizeof(full_path));
 
 			if (load_dll_module(ist, full_path, module_name, dest_module, alias))
@@ -722,7 +722,7 @@
 	} else {
 		for(i = 0; i < llen; i++) {
 			apr_snprintf(full_path, sizeof(full_path), "%s/%s.pr",
-				     pr_strptr(list_item(ist, path_list, i)),
+				     pr2c_strptr(ist, list_item(ist, path_list, i)),
 				     module_name);
 			if (load_module(ist, module_symbol, frame->locals, dest_module,
 					alias, full_path, ": a module", NULL, NULL ))
@@ -976,6 +976,7 @@
 						raise_exception( ist, OBJ(INTERPRETER_EXC), "attribute %s not found", 
 																	as_str(ist, key) );
 						break;
+						dump(ist, "!dump-obj.txt", OBJ(OBJECT));
 					}
 					fr_push(att);
 				}
@@ -1048,7 +1049,7 @@
 				if (fparams_len) {
 					obj_p fparams_obj = NEW_LIST(fparams_len);
 					pr_assert(sizeof(obj_p) == sizeof(obj_p));
-					memcpy( ((list_p)(obj_data_p(fparams_obj)))->item, 
+					memcpy( ((list_p)(obj_dataptr(fparams_obj)))->item, 
 							fr_stack+fr_sp+2, fparams_len*sizeof(obj_p) );
 					listlen(fparams_obj) = fparams_len;
 					set_attr(ist, func,    SYM(FPARAMS_),  fparams_obj);
@@ -1157,7 +1158,7 @@
 					raise_exception(ist, OBJ(TYPE_EXC), "Exec parameter must be a string");
 					break;
 				}
-				state = parse_file_or_string(ist, NULL, pr_strptr(str_obj));
+				state = parse_file_or_string(ist, NULL, pr2c_strptr(ist, str_obj));
 				if (!state || !(code = (state->parse_results))) break;
 				new_frame = create_frame( ist, frame->self, frame->syn_locals, frame->dyn_locals, 
 					                           frame->locals, NULL, code, "execString" );
@@ -1190,7 +1191,7 @@
 			case OP_OBJCALL: {
 				fr_sp -= 2+2*param;
 				func_obj = fr_stack[fr_sp];
-				if (func_obj->data_type == DATA_TYPE_FUNCPTR) {
+				if (func_obj->data_type == DATA_TYPE_EXTPTR) {
 					obj_p res, self;
 					clist_p plist;
 					if (!func_obj->data.ptr) goto no_func_ptr;
@@ -1379,7 +1380,7 @@
 							as_str(ist, fr_stack[fr_sp+1]));
 					break;
 				}
-				if (func_obj->data_type == DATA_TYPE_FUNCPTR){
+				if (func_obj->data_type == DATA_TYPE_EXTPTR){
 					clist_p plist;
 					obj_p res, self;
 					if (!func_obj->data.ptr) goto no_func_ptr2;
@@ -1487,7 +1488,7 @@
 					if (fr_stack[fr_sp+i]) {  // NOT STACKLESS XXX
 						obj_p str_obj = call_func0(ist, fr_stack[fr_sp+i], SYM(STR_));
 						IF_EXC_BREAK;
-						printf("%s ", pr_strptr(str_obj));
+						printf("%s ", pr2c_strptr(ist, str_obj));
 					} else if (i == param-1) goto endcase;
 				printf("\n");
 			}   break;
@@ -1689,7 +1690,7 @@
 			return NULL;
 		}
 	}
-	if (func_obj->data_type == DATA_TYPE_FUNCPTR) {
+	if (func_obj->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_))) )
@@ -1761,9 +1762,9 @@
 	if ((fstk_obj = get_attr(ist, orig_excobj, sym(ist, "frame_stack")))) {
 		for (i = (int) list_len(ist, fstk_obj) - 3; i >= 0; i -= 3) {
 			printf( "--- File: %s, line: %"APR_INT64_T_FMT", char: %"APR_INT64_T_FMT"\n",
-				pr_strptr(list_item(ist, fstk_obj, i  )), 
-				*((i64_t *)obj_data_p(list_item(ist, fstk_obj, i+1))), 
-				*((i64_t *)obj_data_p(list_item(ist, fstk_obj, i+2))) );
+				pr2c_strptr(ist, list_item(ist, fstk_obj, i  )), 
+				*((i64_t *)obj_dataptr(list_item(ist, fstk_obj, i+1))), 
+				*((i64_t *)obj_dataptr(list_item(ist, fstk_obj, i+2))) );
 		}
 	}
 
@@ -1775,9 +1776,9 @@
 				obj_p doc = get_attr(ist, exc, SYM(DOC_));
 
 				if (doc && exc != orig_excobj)
-					printf("%s, ", pr_strptr(doc));
+					printf("%s, ", pr2c_strptr(ist, doc));
 				else if (doc)
-					printf("%s.\n\n", pr_strptr(doc));
+					printf("%s.\n\n", pr2c_strptr(ist, doc));
 			}
 		}
 	}
@@ -1906,7 +1907,7 @@
 	int i, main_index=0;
 	obj_p main_sym, module, thread_obj;
 	pr_thread_p thread_p;
-	char* filename = pr_strptr(list_item(ist, (obj_p)argv, 0));
+	char* filename = pr2c_strptr(ist, list_item(ist, (obj_p)argv, 0));
 
 #ifdef DEBUG_THREADS
 	if (debug_threads) printf("Starting a main thread\n");

Modified: trunk/src/main.c
===================================================================
--- trunk/src/main.c	2004-06-08 13:13:51 UTC (rev 586)
+++ trunk/src/main.c	2004-06-09 21:40:50 UTC (rev 587)
@@ -125,7 +125,7 @@
 #endif
 
 	if ((code_str_obj = get_attr(ist, sys_argv_obj, sym(ist, "code")))) {
-		exec_string(ist, pr_strptr(code_str_obj), FALSE, NULL);
+		exec_string(ist, pr2c_strptr(ist, code_str_obj), FALSE, NULL);
 		check_exceptions(ist);
 	}
 	cmd_line_option_i_flg = (int)(intptr_t) get_attr(ist, sys_argv_obj, sym(ist, "i"));

Modified: trunk/src/memory_mgr.c
===================================================================
--- trunk/src/memory_mgr.c	2004-06-08 13:13:51 UTC (rev 586)
+++ trunk/src/memory_mgr.c	2004-06-09 21:40:50 UTC (rev 587)
@@ -211,7 +211,7 @@
 					dump(ist, "mm-ist-dump.txt", ist->exception_obj);
 					pr_exit(1);
 					printf("         exception: %s\n",
-						pr_strptr(get_attr(ist, ist->exception_obj, SYM(DOC_))));
+						pr2c_strptr(ist, get_attr(ist, ist->exception_obj, SYM(DOC_))));
 					ist->exception_obj = 0;
 				} else if (obj_list) {
 					int i, llen = (int) list_len(ist, obj_list);

Modified: trunk/src/object.c
===================================================================
--- trunk/src/object.c	2004-06-08 13:13:51 UTC (rev 586)
+++ trunk/src/object.c	2004-06-09 21:40:50 UTC (rev 587)
@@ -141,7 +141,7 @@
 	dll_services.new_float_obj	  = new_float_obj;	
 	dll_services.new_string_obj	  = new_string_obj;	
 	dll_services.new_string_n_obj = new_string_n_obj;	
-	dll_services.set_string_data  = set_string_data;	
+	dll_services.c2pr_strcpy  = c2pr_strcpy;	
 	dll_services.new_tuple_obj	  = new_tuple_obj;	
 	dll_services.new_list_obj	  = new_list_obj;
 	dll_services.init_list_data	  = init_list_data;
@@ -202,6 +202,7 @@
 	dll_services.dump			   = dump;		 
 	dll_services.int2i32t		   = int2i32t;		 
 	dll_services.int2i64t		   = int2i64t;		 
+	dll_services.pr2c_strptr	   = pr2c_strptr;		 
 	dll_services.proto_owns_binary = proto_owns_binary;		 
 	dll_services.obj_set_data_owner	= obj_set_data_owner;		 
 
@@ -230,6 +231,7 @@
 	OBJ(FUNC_PROTO)         = NEW_OBJ(NULL);
 	OBJ(GEN_PROTO)          = NEW_OBJ(NULL);
 	OBJ(INT_PROTO)          = NEW_OBJ(NULL);
+	OBJ(BYTES_PROTO)        = NEW_OBJ(OBJ(SEQ_PROTO));
 	OBJ(STRING_PROTO)       = NEW_OBJ(OBJ(SEQ_PROTO));
 	OBJ(DICT_PROTO)         = NEW_OBJ(NULL);
 	OBJ(METHOD_PROTO)       = NEW_OBJ(OBJ(FUNC_PROTO));
@@ -244,6 +246,8 @@
 	BUILTIN_LOAD(Core);
 	BUILTIN_LOAD(Dict);
 	BUILTIN_LOAD(AttrDict);
+	BUILTIN_LOAD(Bytes);
+	BUILTIN_LOAD(File);
 	BUILTIN_LOAD(Float);
 	BUILTIN_LOAD(Int);
 	BUILTIN_LOAD(List);
@@ -347,9 +351,7 @@
 	attr_p attrp;
 	obj_p owner = NULL;
 	int i, numprotos, res; 	
-	if ( obj->data_type != DATA_TYPE_IMMDATA &&
-		 obj->data_type != DATA_TYPE_DATAPTR )
-		return FALSE;
+	if (obj->data_type == DATA_TYPE_NONE) return FALSE;
 	if (proto == obj) return TRUE;
 	if (!obj->has_attrs) owner = obj->attr_proto.proto;
 	else {
@@ -569,8 +571,7 @@
 	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 )
+	if (obj->data_type != DATA_TYPE_NONE)
 		attr_owns_bin(attrs, 0) = TRUE;
 	attr_alen(attrs) = 0;
 	obj->attr_proto.attrs = attrs;
@@ -1039,7 +1040,7 @@
 		}
 	}
 	write_unlock(ist, obj);
-	return obj_data_p(obj);
+	return obj_dataptr(obj);
 }
 
 //********************************* obj_free **********************************
@@ -1096,7 +1097,7 @@
 //********************************* 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_FUNCPTR;
+	func_obj->data_type = DATA_TYPE_EXTPTR;
 	func_obj->data.ptr = func_ptr;
 	if (label_values_list)
 		set_attr(ist,  func_obj, SYM(FPARAMS_), copy_list_obj(ist, label_values_list) );
@@ -1144,7 +1145,7 @@
 	int i;
 	obj_p doc;
 	doc = get_attr(ist, obj, SYM(DOC_));
-	if (doc) {fprintf(fout,"obj(%lx) doc: %s\n", (unsigned long)(uintptr_t)obj, pr_strptr(doc)); prt_flg = 1;}
+	if (doc) {fprintf(fout,"obj(%lx) doc: %s\n", (unsigned long)(uintptr_t)obj, pr2c_strptr(ist, doc)); prt_flg = 1;}
 	else     {fprintf(fout,"%s\n",as_str(ist, obj)); prt_flg = 1;}
 	for(i=0; i < clist_len(object_list); i++)
 		if (clist_item(object_list, i) == obj)

Modified: trunk/src/object.h
===================================================================
--- trunk/src/object.h	2004-06-08 13:13:51 UTC (rev 586)
+++ trunk/src/object.h	2004-06-09 21:40:50 UTC (rev 587)
@@ -148,6 +148,8 @@
 obj_p long_format(long_p aa, int base, int addL);\
 long_p new_longp(i64_t ival);
 int int_is_zero(obj_p obj);
+u8_t* bytes_ptr(obj_p obj);
+size_t bytes_len(obj_p obj);
 
 void dict2attrs(isp ist, obj_p dict, obj_p obj);
 void list2protos(isp ist, obj_p list, obj_p obj);
@@ -173,9 +175,10 @@
 obj_p str_tuple_list(isp ist, obj_p self, char* ldelim, char* rdelim);
 obj_p get_sequence_item(isp ist, obj_p self, obj_p slice, int seq_type);
 
-#define SEQ_TYPE_STRING         0
-#define SEQ_TYPE_TUPLE          1
-#define SEQ_TYPE_LIST           2
+#define SEQ_TYPE_BYTES			0
+#define SEQ_TYPE_STRING         1
+#define SEQ_TYPE_TUPLE          2
+#define SEQ_TYPE_LIST           3
 
 
 #endif  // #define OBJECT_H

Modified: trunk/src/parser.h
===================================================================
--- trunk/src/parser.h	2004-06-08 13:13:51 UTC (rev 586)
+++ trunk/src/parser.h	2004-06-09 21:40:50 UTC (rev 587)
@@ -76,7 +76,8 @@
 typedef struct code_s* code_p;
 
 typedef struct code_s {
-	int			len;
+	data_size_t	size;
+	int     	len;
 	int 		stack_depth;
 	int 		max_stack_depth;
 	int			assign_parm_cnt;

Modified: trunk/src/parser_routines.c
===================================================================
--- trunk/src/parser_routines.c	2004-06-08 13:13:51 UTC (rev 586)
+++ trunk/src/parser_routines.c	2004-06-09 21:40:50 UTC (rev 587)
@@ -179,13 +179,14 @@
 
 //********************************* new_code **********************************
 code_p new_code(void* param, int size, int stk, int max_stk, opcode_t opcode) {
-	code_p p = pr_malloc(sizeof(code)+size*sizeof(code_t));
-	memset(p, 0, sizeof(code)+size*sizeof(code_t));
-	p->len = size;
-	p->stack_depth = stk;
+	data_size_t data_size = sizeof(code)+size*sizeof(code_t);
+	code_p p = pr_malloc(data_size);
+	memset(p, 0, data_size);
+	p->size            = data_size;
+	p->len             = size;
+	p->stack_depth     = stk;
 	p->max_stack_depth = max_stk;
-	if(size)
-		p->code_data[0].bytecode.opcode = opcode;
+	if(size) p->code_data[0].bytecode.opcode = opcode;
 	p->srcmap = new_clist(16);
 	clist_append_num(p->srcmap, 0);
 	clist_append_num(p->srcmap, ((parse_state*) param)->line);
@@ -324,16 +325,16 @@
 	return debug_retrn(__LINE__, p1);
 }
 clist_p label_to_import_path(void* param, obj_p label){
-	return new_clist_1(sym(IST, pr_strptr(label)));
+	return new_clist_1(sym(IST, pr2c_strptr(IST, label)));
 }
 clist_p append_label_to_import_path(void* param, clist_p list, obj_p label){
-	return clist_append(list, sym(IST, pr_strptr(label)));
+	return clist_append(list, sym(IST, pr2c_strptr(IST, label)));
 }
 clist_p import_path_to_import_param(void* param, clist_p list){
 	return ins_clist(new_clist_1(list), NULL, 1);	
 }
 clist_p import_path_as_label_to_import_param(void* param, clist_p list, obj_p label){
-	return ins_clist(new_clist_1(list), sym(IST, pr_strptr(label)), 1);	
+	return ins_clist(new_clist_1(list), sym(IST, pr2c_strptr(IST, label)), 1);	
 }
 clist_p new_import_param(void* param, clist_p list){
 	return new_clist_1(list);
@@ -399,31 +400,31 @@
 code_p label_to_attrref(void* param, obj_p label){
 	code_p p;
 	p = new_code(param, 2, 2, 2, OP_PUSH_LOCAL_REF);
-	p->code_data[1].data = sym(IST, (pr_strptr(label)));
+	p->code_data[1].data = sym(IST, (pr2c_strptr(IST, label)));
 	return debug_retrn(__LINE__, p);
 }
 code_p self_label_to_attrref(void* param, obj_p label){
 	code_p p;
 	p = new_code(param, 2, 2, 2, OP_PUSH_SELF_REF);
-	p->code_data[1].data = sym(IST, pr_strptr(label));
+	p->code_data[1].data = sym(IST, pr2c_strptr(IST, label));
 	return debug_retrn(__LINE__, p);
 }
 code_p super_label_to_attrref(void* param, obj_p label) {
 	code_p p;
 	p = new_code(param, 2, 2, 2, OP_PUSH_SUPER_REF);
-	p->code_data[1].data = sym(IST, pr_strptr(label));
+	p->code_data[1].data = sym(IST, pr2c_strptr(IST, label));
 	return debug_retrn(__LINE__, p);
 }
 code_p outer_label_to_attrref(void* param, obj_p label){
 	code_p p;
 	p = new_code(param, 2, 2, 2, OP_PUSH_OUTER_REF);
-	p->code_data[1].data = sym(IST, pr_strptr(label));
+	p->code_data[1].data = sym(IST, pr2c_strptr(IST, label));
 	return debug_retrn(__LINE__, p);
 }
 code_p caller_label_to_attrref(void* param, obj_p label){
 	code_p p;
 	p = new_code(param, 2, 2, 2, OP_PUSH_CALLER_REF);
-	p->code_data[1].data = sym(IST, pr_strptr(label));
+	p->code_data[1].data = sym(IST, pr2c_strptr(IST, label));
 	return debug_retrn(__LINE__, p);
 }
 code_p obj_label_to_attrref(void* param, code_p obj, obj_p label){
@@ -431,7 +432,7 @@
 	obj = pr_realloc(obj, sizeof(code)+(obj->len)*sizeof(code_t));
 	obj->code_data[obj->len-2].bytecode.opcode = OP_PUSH;
 	obj->code_data[obj->len-2].bytecode.param = 2;
-	obj->code_data[obj->len-1].data = sym(IST, pr_strptr(label));
+	obj->code_data[obj->len-1].data = sym(IST, pr2c_strptr(IST, label));
 	obj->stack_depth += 1;
 	obj->max_stack_depth = max(obj->max_stack_depth, obj->stack_depth);
 	return debug_retrn(__LINE__, obj);
@@ -570,7 +571,7 @@
 code_p label_to_formparm(void* param, obj_p label){
 	code_p res = new_code(param, 3, 2, 2, OP_PUSH);
 	res->code_data[0].bytecode.param = 3;
-	res->code_data[1].data = sym(IST, pr_strptr(label));
+	res->code_data[1].data = sym(IST, pr2c_strptr(IST, label));
 	res->code_data[2].data = PARAM_NORMAL;
 	return debug_retrn(__LINE__, res);
 }
@@ -582,7 +583,7 @@
 	memmove(expr->code_data+2, expr->code_data, ((expr->len)-2)*sizeof(code_t));
 	expr->code_data[0].bytecode.opcode = OP_PUSH;
 	expr->code_data[0].bytecode.param  = 2;
-	expr->code_data[1].data = sym(IST, pr_strptr(label));
+	expr->code_data[1].data = sym(IST, pr2c_strptr(IST, label));
 	return debug_retrn(__LINE__, expr);
 }
 code_p lbl_proto_body_to_obj(void* param, code_p ref, clist_p protos, code_p body) {
@@ -615,14 +616,14 @@
 	code_p res = new_code(param, 3, 2, 2, OP_PUSH);
 	res->code_data[0].bytecode.param = 3;
 	res->code_data[1].data = PARAM_STAR;
-	res->code_data[2].data = sym(IST, pr_strptr(label));
+	res->code_data[2].data = sym(IST, pr2c_strptr(IST, label));
 	return debug_retrn(__LINE__, res);
 }
 code_p star_star_ref_to_formparm(void* param, obj_p label){
 	code_p res = new_code(param, 3, 2, 2, OP_PUSH);
 	res->code_data[0].bytecode.param = 3;
 	res->code_data[1].data = PARAM_STAR_STAR;
-	res->code_data[2].data = sym(IST, pr_strptr(label));
+	res->code_data[2].data = sym(IST, pr2c_strptr(IST, label));
 	return debug_retrn(__LINE__, res);
 }
 code_p expr_to_sparm(void* param, code_p p1){
@@ -846,22 +847,22 @@
 
 code_p break_stmt(void* param, obj_p label){
 	code_p res = new_code(param, 2, 0, 0, OP_BREAK);
-	res->code_data[1].pstr = pr_strptr(label);
+	res->code_data[1].pstr = pr2c_strptr(IST, label);
 	return debug_retrn(__LINE__, res);
 }
 code_p continue_stmt(void* param, obj_p label){
 	code_p res = new_code(param, 2, 0, 0, OP_CONTINUE);
-	res->code_data[1].pstr = pr_strptr(label);
+	res->code_data[1].pstr = pr2c_strptr(IST, label);
 	return debug_retrn(__LINE__, res);
 }
-void patch_break_continues(obj_p label, code_p body){
+void patch_break_continues(void* param, obj_p label, code_p body) {
 	int p=0;
 	while(p < body->len){
 		int opcode = body->code_data[p].bytecode.opcode;
-		int param  = body->code_data[p].bytecode.param;
+		int parm   = body->code_data[p].bytecode.param;
 		char* pstr = body->code_data[p+1].pstr;
 		if ( (opcode == OP_BREAK || opcode == OP_CONTINUE) &&
-			 (!strcmp(pstr, "~") || !strcmp(pstr, pr_strptr(label))) ){
+			 (!strcmp(pstr, "~") || !strcmp(pstr, pr2c_strptr(IST, label))) ){
 			body->code_data[p].bytecode.opcode = OP_BR;
 			body->code_data[p].bytecode.param  = (body->len - p) +
 									(opcode == OP_CONTINUE ?  0 : 1);
@@ -870,7 +871,7 @@
 			body->code_data[p+1].bytecode.param  = 1;
 		}
 		if (opcode < OP_PARAM_WORDS_BOUNDARY)
-			p += param;
+			p += parm;
 		else if (opcode < OP_TWO_WORDS_BOUNDARY)
 			p += 2;
 		else
@@ -999,11 +1000,11 @@
 
 	for (i=1; i < llen; i++){
 		obj_p s = clist_item(forlst,i);
-		if ( !(*(pr_strptr(s)) >= 'a' && *(pr_strptr(s)) <= 'z') && ! *(pr_strptr(s)) == '_'){
-			printf("For variable not local: %s\n", pr_strptr(s));
+		if ( !(*(pr2c_strptr(IST, s)) >= 'a' && *(pr2c_strptr(IST, s)) <= 'z') && ! *(pr2c_strptr(IST, s)) == '_'){
+			printf("For variable not local: %s\n", pr2c_strptr(IST, s));
 			pr_exit(1);
 		}
-		clist_item(forlst,i) = sym(IST, pr_strptr(s));
+		clist_item(forlst,i) = sym(IST, pr2c_strptr(IST, s));
 	}
 	add_code(expr, res, k);
 	res->code_data[*k    ].bytecode.opcode = OP_PUSH;
@@ -1086,9 +1087,9 @@
 	int i, k=0, len=0, stack_depth=0, max_stack_depth=0;
 	int llen = clist_len(targets)-1, loop_loc, body_loc, els_loc, end_els_loc, end_loc;
 	code_p expr = clist_item(targets, llen);
-	patch_break_continues(clist_item(targets,0), body);
+	patch_break_continues(param, clist_item(targets,0), body);
 	for (i=1; i < llen; i++)
-		clist_item(targets, i) = sym(IST, pr_strptr((obj_p)clist_item(targets, i)));
+		clist_item(targets, i) = sym(IST, pr2c_strptr(IST, (obj_p)clist_item(targets, i)));
 	calc_code(expr, &len, &stack_depth, &max_stack_depth); 
 	len += 5;			
 	loop_loc = len;  
@@ -1228,7 +1229,7 @@
 	code *res;
 	int k=0, len=0, stack_depth=0, max_stack_depth = 6;
 	int loop_loc, body_loc, els_loc, end_loc;
-	patch_break_continues(label, body);
+	patch_break_continues(param, label, body);
 	loop_loc = len;
 	calc_code(expr, &len, &stack_depth, &max_stack_depth); 
 	len += 7;
@@ -1451,7 +1452,7 @@
 	return debug_retrn(__LINE__, word_expr_to_param(param, PARAM_NORMAL, expr));
 }
 code_p label_eq_expr_to_param(void* param, obj_p label, code_p expr){
-	return debug_retrn(__LINE__, word_expr_to_param(param, sym(IST, pr_strptr(label)), expr));
+	return debug_retrn(__LINE__, word_expr_to_param(param, sym(IST, pr2c_strptr(IST, label)), expr));
 }
 code_p star_seq_to_param(void* param, code_p expr){
 	return debug_retrn(__LINE__, word_expr_to_param(param, PARAM_STAR, expr));
@@ -1481,22 +1482,7 @@
 }
 code_p string_to_obj(void* param, obj_p str){
 	code_p p = new_code(param, 2, 1, 1, OP_PUSH);
-	pr_str_p obj_str;
-	size_t len = pr_strlen(str);
-	obj_p proto = OBJ(STRING_PROTO);
-	obj_p obj = new_object(IST, proto);
-	if (len < IMMEDIATE_DATA_LEN) {
-		obj->data_type = DATA_TYPE_IMMDATA;
-		obj->imm_data_len = (int) len;
-		memcpy(obj->data.str, pr_strptr(str), len);
-		obj->data.str[len] = 0;
-	} else {
-		obj_str = obj_malloc(IST, proto, obj, sizeof(pr_str_t)+len+1);
-		obj_str->len = len;
-		memcpy(&(obj_str->str[0]), pr_strptr(str), len);
-		obj_str->str[len] = 0;
-	}
-	obj->immutable = TRUE;
+	obj_p obj = copy_object(IST, str);
 	p->code_data[0].bytecode.param = 2;
 	p->code_data[1].data = obj;
 	add_to_const_list(param, obj);
@@ -1504,7 +1490,7 @@
 }
 code_p rquote_lbl_to_obj(void* param, obj_p label) {
 	code_p p = new_code(param, 2, 1, 1, OP_PUSH);
-	obj_p symbol = sym(IST, pr_strptr(label));
+	obj_p symbol = sym(IST, pr2c_strptr(IST, label));
 	p->code_data[0].bytecode.param = 2;
 	p->code_data[1].data = symbol;
 	add_to_const_list(param, symbol);
@@ -1576,8 +1562,8 @@
 	add_code(expr, res, &k);
 	res->code_data[k  ].bytecode.opcode = OP_PUSH;
 	res->code_data[k++].bytecode.param  = 2;
-	if (pr_strptr(label))
-		res->code_data[k++].data = sym(IST, pr_strptr(label));
+	if (label)
+		res->code_data[k++].data = sym(IST, pr2c_strptr(IST, label));
 	else
 		res->code_data[k++].data = OBJ(NONE);
 	res->code_data[k  ].bytecode.opcode = OP_EXCEPT;

Modified: trunk/src/prlist.h
===================================================================
--- trunk/src/prlist.h	2004-06-08 13:13:51 UTC (rev 586)
+++ trunk/src/prlist.h	2004-06-09 21:40:50 UTC (rev 587)
@@ -56,11 +56,11 @@
 #define DEFAULT_INITIAL_LIST_SIZE	8
 #define LIST_GROWTH_FACTOR			2
 
-#define list_sizeof(n)	(sizeof(list_hdr_t)+((n)*sizeof(obj_p)))
+#define list_sizeof(n)	((data_size_t)(sizeof(list_hdr_t)+((n)*sizeof(obj_p))))
 
 typedef struct {
-	size_t	size;
-	size_t	len;
+	data_size_t	size;
+	size_t		len;
 } list_hdr_t;
 
 typedef struct {
@@ -70,11 +70,13 @@
 
 typedef list_t* list_p;
 
-#define lstpsize(list_ptr)		(((list_p)(list_ptr))->hdr.size)
+#define lstpsetsize(list_ptr,n) ((((list_p)(list_ptr))->hdr.size)=list_sizeof(n))
+#define lstpsize(list_ptr)		(((((list_p)(list_ptr))->hdr.size)-sizeof(list_hdr_t))/sizeof(obj_t))
 #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 listlen(list_obj)		lstplen((list_obj)->data.ptr)
 #define listitem(list_obj,i)	lstpitem((list_obj)->data.ptr,i)
 

Modified: trunk/src/src.vcproj
===================================================================
--- trunk/src/src.vcproj	2004-06-08 13:13:51 UTC (rev 586)
+++ trunk/src/src.vcproj	2004-06-09 21:40:50 UTC (rev 587)
@@ -137,12 +137,18 @@
 				RelativePath=".\builtins-attrdict.c">
 			</File>
 			<File
+				RelativePath=".\builtins-bytes.c">
+			</File>
+			<File
 				RelativePath=".\builtins-core.c">
 			</File>
 			<File
 				RelativePath=".\builtins-dict.c">
 			</File>
 			<File
+				RelativePath=".\builtins-file.c">
+			</File>
+			<File
 				RelativePath=".\builtins-float.c">
 			</File>
 			<File
Modified: trunk/src/symbol.c
===================================================================
--- trunk/src/symbol.c	2004-06-08 13:13:51 UTC (rev 586)
+++ trunk/src/symbol.c	2004-06-09 21:40:50 UTC (rev 587)
@@ -141,7 +141,6 @@
 	{ "setItem_",		0 },
 	{ "delItem_",		0 },
 	{ "objList_",		0 }, // f3
-	{ "cDataLen_",		0 },
 	{ "del_",			0 },
 	{ "len",			0 },
 	{ "max",			0 },
@@ -281,7 +280,7 @@
 	if (sym_obj) {
 		s_obj = get_attr(ist, sym_obj, SYM(STRING_));
 		if (s_obj) {
-			char* tmp = pr_strptr(s_obj);
+			char* tmp = pr2c_strptr(ist, s_obj);
 			return tmp;
 		}
 	}

Modified: trunk/src/sys.c
===================================================================
--- trunk/src/sys.c	2004-06-08 13:13:51 UTC (rev 586)
+++ trunk/src/sys.c	2004-06-09 21:40:50 UTC (rev 587)
@@ -126,7 +126,7 @@
 #endif
 
 	for(i=0; i < llen; i++) {
-		char* item = pr_strptr(list_item(ist, list, i));
+		char* item = pr2c_strptr(ist, list_item(ist, list, i));
 		if (!strcmp(full_path, item))
 			return;
 	}