rev 129 - in trunk: include/prothon modules/File modules/Re modules/String modules/Tuple pr src
SVN User <[email protected]>
| Newsgroups | gmane.comp.lang.prothon.cvs |
|---|---|
| Message-ID | <[email protected]> |
Author: mark
Date: 2004-03-25 23:27:31 -0500 (Thu, 25 Mar 2004)
New Revision: 129
Removed:
trunk/include/prothon/prstring.h
Modified:
trunk/include/prothon/prothon.h
trunk/modules/File/File.c
trunk/modules/Re/Re.c
trunk/modules/String/String.c
trunk/modules/Tuple/Tuple.c
trunk/pr/re_test.pr
trunk/src/builtins.c
trunk/src/console.c
trunk/src/interp.c
trunk/src/lock.c
trunk/src/lock.h
trunk/src/memory_mgr.c
trunk/src/object.c
trunk/src/parser_routines.c
trunk/src/symbol.c
trunk/src/sys.c
Log:
fixed string object so it can hold binary data
(embedded null chars), added unmutable bit to object
which disables all write locking and turns read locking
into no-ops for efficiency, speeded up write locking
Modified: trunk/include/prothon/prothon.h
===================================================================
--- trunk/include/prothon/prothon.h 2004-03-26 00:27:20 UTC (rev 128)
+++ trunk/include/prothon/prothon.h 2004-03-26 04:27:31 UTC (rev 129)
@@ -139,19 +139,22 @@
obj_p proto;
} attr_proto_t;
+#define IMMEDIATE_DATA_LEN 8
+
typedef union {
- attr_key_t key;
+ attr_key_t key;
double f64;
i64_t i64;
- i32_t i32[2];
- char byte[8];
+ i32_t i32[IMMEDIATE_DATA_LEN/4];
+ char str[IMMEDIATE_DATA_LEN];
void* ptr;
} obj_data_t;
typedef struct obj_s {
- obj_type_t data_type :4;
u8_t imm_data_len :4;
+ obj_type_t data_type :3;
obj_state_t state :3;
+ u8_t unmutable :1;
u8_t del_locked :1;
u8_t scanned :1;
u8_t has_attrs :1;
@@ -160,11 +163,18 @@
u8_t rdlock_cnt;
u8_t wrlock_req_cnt;
apr_uint32_t wrlock;
- attr_proto_t attr_proto;
+ attr_proto_t attr_proto;
obj_data_t data;
obj_p next_obj;
} obj_t;
+typedef struct {
+ size_t len;
+ char str[];
+} pr_str_t;
+
+typedef pr_str_t* pr_str_p;
+
//************************* MALLOC FUNCTIONS **********************************
// These behave identical to the standard OS functions, but on segments smaller
// than 64 bytes are much faster than most OS implementations. See prmalloc.c.
@@ -664,9 +674,9 @@
// see Int.c for example of usage
#define DEF(slf, func, fparam_list) \
static obj_p slf##func(isp ist, obj_p self, int pcnt, obj_p* parms, obj_p dlocals); \
- static void slf##func##init(void) { \
+ static void slf##func##init(void) { \
set_attr(ist, slf, sym(ist, #func), new_func_obj(ist, slf##func, fparam_list)); \
- } \
+ } \
static obj_p slf##func(isp ist, obj_p self, int pcnt, obj_p* parms, obj_p dlocals)
// FORM_RPARAM: convenience macro for single formal right parameter
@@ -712,12 +722,12 @@
// CALL_FUNCn: Macros to easily call functions with zero or one param
obj_p call_func1_f(isp ist, obj_p self, obj_p sym, obj_p parm);
-#define call_func0(ist, self, sym) call_func(ist, self, sym, 0, NULL, NULL)
-#define call_func1(ist, self, sym, parm) call_func1_f(ist, self, sym, parm)
+#define call_func0(ist, self, sym) call_func((ist), (self), (sym), 0, NULL, NULL)
+#define call_func1(ist, self, sym, parm) call_func1_f((ist), (self), (sym), (parm))
-// STR: Call __str__ function on any object
-// Get string representation of any object by calling __str__ function on it.
-#define str(ist, obj) ((char*)obj_data_p(call_func0(ist, (obj), SYM(__STR__))))
+// 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) strch(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
@@ -725,7 +735,7 @@
// int type. Covering a value does not mean that some precision will not be lost.
// This test determines when coercion is allowed. It is up to the prototype
// objects to decide which objects they cover by offering the __covers__ function.
-#define covers(o1, o2) (call_func1(ist, (o1), SYM(__COVERS__), (o2)) == OBJ(TRUE))
+#define covers(o1, o2) (call_func1((ist), (o1), SYM(__COVERS__), (o2)) == OBJ(TRUE))
//********************************* EXCEPTIONS ******************************************
// Exceptions are raised by calling raise_exception(ist, proto, doc). Proto is a proto
@@ -769,15 +779,25 @@
void obj_free (isp ist, obj_p obj);
// OBJ_DATA_P: returns the C ptr to the data area for an object.
-// Example: A string object accesses it's C string this way: ((char*)obj_data_p(str_obj))
#define obj_data_p(obj) \
( !obj ? NULL : \
( (obj)->data_type == OBJ_TYPE_IMMDATA ? &((obj)->data) : \
( (obj)->data_type == OBJ_TYPE_DATAPTR ? (obj)->data.ptr : NULL ) ) )
-// strch: Convenience macro to access C string in string object
-#define strch(str_obj) ((char*)obj_data_p(str_obj))
+// STRCH: macro to retreive string object as a C string
+// warning, string objects may contain null chars so C string result may be short
+#define strch(str_obj) \
+( !(str_obj) ? NULL : \
+ (str_obj)->data_type == OBJ_TYPE_IMMDATA ? (str_obj)->data.str : \
+ ((str_obj)->data_type == OBJ_TYPE_DATAPTR ? ((pr_str_p)((str_obj)->data.ptr))->str : NULL) )
+// pr_strlen: macro to retreive string length of a string object
+// warning, string objects may contain null chars that this length ignores
+#define pr_strlen(str_obj) \
+ ( ((str_obj)->data_type == OBJ_TYPE_IMMDATA) ? (size_t)((str_obj)->imm_data_len) : \
+ (((str_obj)->data_type == OBJ_TYPE_DATAPTR) ? ((pr_str_p)((str_obj)->data.ptr))->len : 0 ) )
+
+
//************************** 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
Deleted: trunk/include/prothon/prstring.h
===================================================================
--- trunk/include/prothon/prstring.h 2004-03-26 00:27:20 UTC (rev 128)
+++ trunk/include/prothon/prstring.h 2004-03-26 04:27:31 UTC (rev 129)
@@ -1,71 +0,0 @@
-/* ====================================================================
- * The Prothon License Agreement, Version 1.0
- *
- * Copyright (c) 2004 Mark C. Hahn <[email protected]>. All rights
- * reserved.
- *
- * 1. This LICENSE AGREEMENT is between Mark C. Hahn ("MCH"), 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, MCH
- * 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 MCH's License Agreement and
- * MCH's notice of copyright, i.e., "Copyright (c) 2004 Mark C. Hahn; 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. MCH is making Prothon available to Licensee on an "AS IS" basis.
- * MCH MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY
- * OF EXAMPLE, BUT NOT LIMITATION, MCH 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. MCH 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 MCH and
- * Licensee. This License Agreement does not grant permission to use MCH
- * 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.
- * ====================================================================
- */
-
-
-// prString.h
-
-typedef union {
- i64_t len;
- char byte[];
-} str_t;
-
-typedef str_t* str_p;
-
-strlen(str_obj) \
- ( ((str_obj)->data_type == OBJ_TYPE_IMMDATA) ? (i64_t)((str_obj)->imm_data_len) : \
- (((str_obj)->data_type == OBJ_TYPE_DATAPTR) ? ((str_p)((str_obj)->data.ptr))->len : 0 : 0) )
-
-stritem(str_obj, i) \
-( ((str_obj)->data_type == OBJ_TYPE_IMMDATA) ? (str_obj)->data.byte[i] : \
- (((str_obj)->data_type == OBJ_TYPE_DATAPTR) ? ((str_p)((str_obj)->data.ptr))->byte[i] : 0 : 0) )
-
-
Modified: trunk/modules/File/File.c
===================================================================
--- trunk/modules/File/File.c 2004-03-26 00:27:20 UTC (rev 128)
+++ trunk/modules/File/File.c 2004-03-26 04:27:31 UTC (rev 129)
@@ -204,9 +204,10 @@
#endif
DEF(FILE_PROTO, read, list2( sym(ist, "size"), new_int_obj(-1))) {
int readall = FALSE;
- i64_t size;
- size_t total_read=0, num_read;
+ i64_t size_in;
+ size_t size, total_read=0, num_read;
obj_p str_obj;
+ pr_str_p obj_str;
char* buf;
apr_status_t aprerr;
char err_buf[1024];
@@ -219,49 +220,64 @@
raise_exception(ist, OBJ(IOEXCEPTION), "read called on closed file");
return NULL;
}
- size = parms[1]->data.i64;
- if (!size) return new_string_obj("");
- if (size < 0) {
+ size_in = parms[1]->data.i64;
+ if (!size_in) return new_string_obj("");
+ if (size_in < 0) {
readall = TRUE;
size = BUFSIZE(self);
+ } else
+ size = (size_t) size_in;
+ str_obj = new_object(OBJ(STRING_PROTO));
+ if (size < IMMEDIATE_DATA_LEN) {
+ str_obj->data_type = OBJ_TYPE_IMMDATA;
+ buf = str_obj->data.str;
+ } else {
+ obj_str = obj_malloc(str_obj, sizeof(pr_str_t)+size+1);
+ buf = obj_str->str;
}
- str_obj = new_object(OBJ(STRING_PROTO));
- buf = obj_malloc(str_obj, (size_t) size+1);
-
- num_read = (size_t) size;
+ num_read = size;
aprerr = apr_file_read(STREAM(self), buf, &num_read);
if (aprerr != APR_SUCCESS && aprerr != APR_EOF) {
raise_exception(ist, OBJ(IOEXCEPTION), 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_t) size : (size_t) size - total_read);
-
- buf = obj_realloc(ist, str_obj, (total_read + next_read + 1));
+ size_t next_read = (readall ? size : size - total_read);
+ size_t new_len = total_read + next_read;
+ if (str_obj->data_type == OBJ_TYPE_IMMDATA && new_len >= IMMEDIATE_DATA_LEN) {
+ obj_str = obj_malloc(str_obj, sizeof(pr_str_t)+new_len+1);
+ buf = obj_str->str;
+ } else {
+ obj_str = obj_realloc(ist, str_obj, sizeof(pr_str_t)+new_len+1);
+ buf = obj_str->str;
+ }
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), apr_strerror(aprerr, err_buf,
- sizeof(err_buf)));
+ raise_exception(ist, OBJ(IOEXCEPTION), apr_strerror(aprerr, err_buf, sizeof(err_buf)));
return NULL;
}
total_read += num_read;
}
-
- buf = obj_realloc(ist, str_obj, (size_t)(total_read+1));
+ if (str_obj->data_type == OBJ_TYPE_IMMDATA)
+ str_obj->imm_data_len = (int) total_read;
+ else {
+ obj_str = obj_realloc(ist, str_obj, sizeof(pr_str_t)+total_read+1);
+ obj_str->len = total_read;
+ buf = obj_str->str;
+ }
buf[total_read] = 0;
-
+ str_obj->unmutable = TRUE;
return str_obj;
}
DEF(FILE_PROTO, readline, list2( sym(ist, "size"), new_int_obj(-1))) {
int readall = FALSE;
- i64_t size;
- size_t total_read;
+ i64_t size_in;
+ size_t size, total_read;
obj_p str_obj;
+ pr_str_p obj_str;
char* buf;
apr_status_t aprerr;
char err_buf[1024];
@@ -274,41 +290,62 @@
raise_exception(ist, OBJ(IOEXCEPTION), "readline called on closed file");
return NULL;
}
- size = (size_t)(parms[1]->data.i64);
- if (!size) return new_string_obj("");
- if (size < 0) {
+ size_in = parms[1]->data.i64;
+ if (!size_in) return new_string_obj("");
+ if (size_in < 0) {
readall = TRUE;
size = BUFSIZE(self);
+ } else
+ size = (size_t) size_in;
+ str_obj = new_object(OBJ(STRING_PROTO));
+ if (size < IMMEDIATE_DATA_LEN) {
+ str_obj->data_type = OBJ_TYPE_IMMDATA;
+ buf = str_obj->data.str;
+ } else {
+ obj_str = obj_malloc(str_obj, sizeof(pr_str_t)+size+1);
+ buf = obj_str->str;
}
- str_obj = new_object(OBJ(STRING_PROTO));
- buf = obj_malloc(str_obj, (size_t) size + 1);
aprerr = apr_file_gets(buf, (int)(size + 1), STREAM(self));
if (aprerr != APR_SUCCESS && aprerr != APR_EOF) {
raise_exception(ist, OBJ(IOEXCEPTION), 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_t) size : (size_t) size - total_read);
- buf = obj_realloc(ist, str_obj, (size_t)(total_read+next_read+1));
+ 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 (str_obj->data_type == OBJ_TYPE_IMMDATA && new_len >= IMMEDIATE_DATA_LEN) {
+ obj_str = obj_malloc(str_obj, sizeof(pr_str_t)+new_len+1);
+ buf = obj_str->str;
+ } else {
+ obj_str = obj_realloc(ist, str_obj, sizeof(pr_str_t)+new_len+1);
+ buf = obj_str->str;
+ }
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), apr_strerror(aprerr, err_buf,
- sizeof(err_buf)));
+ raise_exception(ist, OBJ(IOEXCEPTION), apr_strerror(aprerr, err_buf, sizeof(err_buf)));
return NULL;
}
total_read = strlen(buf);
}
- obj_realloc(ist, str_obj, (size_t)(total_read+1));
+ if (str_obj->data_type == OBJ_TYPE_IMMDATA)
+ str_obj->imm_data_len = (int) total_read;
+ else {
+ obj_str = obj_realloc(ist, str_obj, sizeof(pr_str_t)+total_read+1);
+ buf = obj_str->str;
+ obj_str->len = total_read;
+ }
+ buf[total_read] = 0;
+ str_obj->unmutable = TRUE;
return str_obj;
}
DEF(FILE_PROTO, readlines, list2( sym(ist, "size"), new_int_obj(-1))) {
int readall = FALSE;
- i64_t size;
- size_t total_read=0, num_read;
+ i64_t size_in;
+ size_t size, total_read=0, num_read;
obj_p str_obj, list_obj;
+ pr_str_p obj_str;
char* buf;
apr_status_t aprerr;
char err_buf[1024];
@@ -321,17 +358,24 @@
raise_exception(ist, OBJ(IOEXCEPTION), "readlines called on closed file");
return NULL;
}
- size = (parms[1]->data.i64);
- if (!size) return new_string_obj("");
- if (size < 0) {
+ size_in = parms[1]->data.i64;
+ if (!size_in) return new_string_obj("");
+ if (size_in < 0) {
readall = TRUE;
size = BUFSIZE(self);
- }
+ } else
+ size = (size_t) size_in;
list_obj = new_list_obj(10);
aprerr = 0;
while (aprerr != APR_EOF && (readall || total_read < size)) {
str_obj = new_object(OBJ(STRING_PROTO));
- buf = obj_malloc(str_obj, (size_t) size + 1);
+ if (size < IMMEDIATE_DATA_LEN) {
+ str_obj->data_type = OBJ_TYPE_IMMDATA;
+ buf = str_obj->data.str;
+ } else {
+ obj_str = obj_malloc(str_obj, sizeof(pr_str_t)+size+1);
+ buf = obj_str->str;
+ }
aprerr = apr_file_gets(buf, (int)(size - total_read + 1), STREAM(self));
if (aprerr != APR_SUCCESS && aprerr != APR_EOF) {
raise_exception(ist, OBJ(IOEXCEPTION), apr_strerror(aprerr,
@@ -341,8 +385,15 @@
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_t) size : (size_t) size - total_read);
- buf = obj_realloc(ist, str_obj, total_read + next_read + 1);
+ size_t next_read = (readall ? size : size - total_read);
+ size_t new_len = num_read + next_read;
+ if (str_obj->data_type == OBJ_TYPE_IMMDATA && new_len >= IMMEDIATE_DATA_LEN) {
+ obj_str = obj_malloc(str_obj, sizeof(pr_str_t)+new_len+1);
+ buf = obj_str->str;
+ } else {
+ obj_str = obj_realloc(ist, str_obj, sizeof(pr_str_t)+new_len+1);
+ buf = obj_str->str;
+ }
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), apr_strerror(aprerr,
@@ -351,7 +402,15 @@
}
total_read += num_read = strlen(buf);
}
- obj_realloc(ist, str_obj, (size_t)(num_read+1));
+ if (str_obj->data_type == OBJ_TYPE_IMMDATA)
+ str_obj->imm_data_len = (int) num_read;
+ else {
+ obj_str = obj_realloc(ist, str_obj, sizeof(pr_str_t)+num_read+1);
+ buf = obj_str->str;
+ obj_str->len = num_read;
+ }
+ buf[num_read] = 0;
+ str_obj->unmutable = TRUE;
list_append(ist, list_obj, str_obj);
}
return list_obj;
@@ -447,8 +506,8 @@
return NULL;
}
- str = strch(parms[1]);
- size = strlen(str);
+ str = strch(parms[1]);
+ size = pr_strlen(parms[1]);
aprerr = apr_file_write(STREAM(self), str, &size);
if (aprerr != APR_SUCCESS) {
@@ -474,8 +533,8 @@
}
if (has_proto(ist, parms[1], OBJ(STRING_PROTO))) {
- str = strch(parms[1]);
- size = strlen(str);
+ str = strch(parms[1]);
+ size = pr_strlen(parms[1]);
aprerr = apr_file_write(STREAM(self), str, &size);
if (aprerr != APR_SUCCESS) {
raise_exception(ist, OBJ(IOEXCEPTION),
@@ -490,8 +549,8 @@
raise_exception(ist, OBJ(TYPE_EXC), "file writelines lst item must be a string");
return NULL;
}
- str = strch(item);
- size = strlen(str);
+ str = strch(item);
+ size = pr_strlen(item);
aprerr = apr_file_write(STREAM(self), str, &size);
if (aprerr != APR_SUCCESS) {
raise_exception(ist, OBJ(IOEXCEPTION),
Modified: trunk/modules/Re/Re.c
===================================================================
--- trunk/modules/Re/Re.c 2004-03-26 00:27:20 UTC (rev 128)
+++ trunk/modules/Re/Re.c 2004-03-26 04:27:31 UTC (rev 129)
@@ -157,6 +157,7 @@
else list_append(ist, tuple_obj, new_string_obj_n(s+sp,ep-sp));
}
list_append(ist, res, tuple_obj);
+ tuple_obj->unmutable = TRUE;
}
}
pr_free(m);
@@ -525,6 +526,7 @@
res = new_tuple_obj(2);
list_append(ist, res, list_item(ist, self, 2*grp ));
list_append(ist, res, list_item(ist, self, 2*grp+1));
+ res->unmutable = TRUE;
return res;
}
@@ -596,6 +598,7 @@
if (sp == -1) list_append(ist, res, OBJ(NONE));
else list_append(ist, res, new_string_obj_n(orig_s+sp, ep-sp));
}
+ res->unmutable = TRUE;
return res;
}
}
@@ -612,6 +615,7 @@
if (sp == -1) list_append(ist, res, parms[1]);
else list_append(ist, res, new_string_obj_n(orig_s+sp, ep-sp));
}
+ res->unmutable = TRUE;
return res;
}
Modified: trunk/modules/String/String.c
===================================================================
--- trunk/modules/String/String.c 2004-03-26 00:27:20 UTC (rev 128)
+++ trunk/modules/String/String.c 2004-03-26 04:27:31 UTC (rev 129)
@@ -81,20 +81,34 @@
}
DEF(STR_PROTO_OBJ, __add__, FORM_RPARAM){
- obj_p res, other = parms[1];
- char *r,*s,*o;
+ obj_p obj, other = parms[1];
+ pr_str_p obj_str;
+ size_t slen, olen, tlen;
if (!is_String(other)) other = call_func0(ist, other, SYM(__STR__));
- r = pr_malloc(strlen(s=strch(self))+strlen(o=strch(other))+1);
- strcpy(r, s); strcat(r, o);
- res = new_string_obj(r);
- pr_free(r);
- return res;
+ slen = pr_strlen(self); olen = pr_strlen(other);
+ tlen = slen + olen;
+ obj = new_object(OBJ(STRING_PROTO));
+ if (tlen < IMMEDIATE_DATA_LEN) {
+ obj->data_type = OBJ_TYPE_IMMDATA;
+ obj->imm_data_len = (int) tlen;
+ memcpy(&(obj->data.str[0]), strch(self), slen);
+ memcpy(&(obj->data.str[slen]), strch(other), olen);
+ obj->data.str[tlen] = 0;
+ } else {
+ obj_str = obj_malloc(obj, sizeof(pr_str_t)+tlen+1);
+ obj_str->len = tlen;
+ memcpy(&(obj_str->str[0]), strch(self), slen);
+ memcpy(&(obj_str->str[slen]), strch(other), olen);
+ obj_str->str[tlen] = 0;
+ }
+ obj->unmutable = TRUE;
+ return obj;
}
DEF(STR_PROTO_OBJ, __mul__, FORM_RPARAM){
- obj_p res;
- char *res_str, *self_str = strch(self);
- size_t i, times, len = strlen(self_str);
+ obj_p obj;
+ pr_str_p obj_str;
+ size_t i, times, tlen, len = pr_strlen(self);
if (!has_proto(ist, parms[1], OBJ(INT_PROTO))) {
raise_exception(ist, OBJ(TYPE_EXC), "multiply times parameter must be an integer");
return NULL;
@@ -102,16 +116,27 @@
times = (size_t) parms[1]->data.i64;
if(times == 0) return new_string_obj("");
if(times == 1) return self;
- res = new_string_obj("");
- res_str = obj_malloc(res, len*times+1);
- if(!res_str) {
- raise_exception(ist, OBJ(OUTOFMEMORY_EXC), "memory allocation failed for string multiplication");
- return NULL;
+ tlen = len*times+1;
+ obj = new_object(OBJ(STRING_PROTO));
+ if (tlen < IMMEDIATE_DATA_LEN) {
+ obj->data_type = OBJ_TYPE_IMMDATA;
+ obj->imm_data_len = (int) tlen;
+ for(i=0; i < times; i++)
+ memcpy(obj->data.str+i*len, strch(self), len);
+ obj->data.str[tlen] = 0;
+ } else {
+ obj_str = obj_malloc(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, strch(self), len);
+ obj_str->str[tlen] = 0;
}
- for(i=0; i < times; i++)
- memcpy(res_str+i*len, self_str, len);
- res_str[len*times] = 0;
- return res;
+ obj->unmutable = TRUE;
+ return obj;
}
DEF(STR_PROTO_OBJ, __gen__, NULL) {
@@ -144,30 +169,56 @@
}
DEF(STR_PROTO_OBJ, join, FORM_RPARAM) {
- char *s, *self_s, *item_s;
- obj_p res, list;
+ char *self_str, *dest_ptr;
+ pr_str_p obj_str;
+ obj_p obj, list, str_list;
int i, llen;
+ size_t ofs, self_len, tlen;
if (!has_proto(ist, parms[1], OBJ(LIST_PROTO))) {
raise_exception(ist, OBJ(TYPE_EXC), "join function parameter must be a list");
return NULL;
}
list = parms[1];
llen = list_len(ist, parms[1]);
- self_s = strch(self);
- s = pr_malloc(1); s[0] = 0;
+ if (!llen) return new_string_obj("");
+ str_list = new_list_obj(llen);
+ self_str = strch(self);
+ self_len = pr_strlen(self);
+ tlen = 0;
for (i=0; i < llen; i++) {
- item_s = str(ist, list_item(ist, list, i)); if_exc_return NULL;
+ obj_p str_obj = call_func0(ist, list_item(ist, list, i), SYM(__STR__)); if_exc_return NULL;
+ list_append(ist, str_list, str_obj);
+ tlen += pr_strlen(str_obj);
+ if (i != llen-1) tlen += self_len;
+ }
+ obj = new_object(OBJ(STRING_PROTO));
+ if (tlen < IMMEDIATE_DATA_LEN) {
+ obj->data_type = OBJ_TYPE_IMMDATA;
+ obj->imm_data_len = (int) tlen;
+ dest_ptr = obj->data.str;
+ } else {
+ obj_str = obj_malloc(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;
+ dest_ptr = obj_str->str;
+ }
+ for(i=0, ofs=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, strch(str_obj), str_len);
+ ofs += str_len;
if (i != llen-1) {
- s = pr_realloc(s, strlen(s)+strlen(item_s)+strlen(self_s)+1);
- strcat(s, item_s); strcat(s, self_s);
- } else {
- s = pr_realloc(s, strlen(s)+strlen(item_s)+1);
- strcat(s, item_s);
+ memcpy(dest_ptr+ofs, self_str, self_len);
+ ofs += self_len;
}
}
- res = new_string_obj(s);
- pr_free(s);
- return res;
+ dest_ptr[tlen] = 0;
+ obj->unmutable = TRUE;
+ del_unlock(ist, str_list);
+ return obj;
}
DEF(STR_PROTO_OBJ, __in__, FORM_RPARAM) {
@@ -185,7 +236,7 @@
}
DEF(STR_PROTO_OBJ, len, NULL) {
- return new_int_obj(strlen(strch(self)));
+ return new_int_obj(pr_strlen(self));
}
install_module(){
Modified: trunk/modules/Tuple/Tuple.c
===================================================================
--- trunk/modules/Tuple/Tuple.c 2004-03-26 00:27:20 UTC (rev 128)
+++ trunk/modules/Tuple/Tuple.c 2004-03-26 04:27:31 UTC (rev 129)
@@ -106,7 +106,11 @@
}
times = (int)parms[1]->data.i64;
size = len*times;
- if(times == 0) return new_tuple_obj(0);
+ if(times == 0) {
+ obj_p res = new_tuple_obj(0);
+ res ->unmutable = TRUE;
+ return res;
+ }
if(times == 1) return self;
res = new_object(OBJ(TUPLE_PROTO));
lstp = res->data.ptr = pr_malloc((LIST_OVERHEAD+size)*sizeof(list_t));
Modified: trunk/pr/re_test.pr
===================================================================
--- trunk/pr/re_test.pr 2004-03-26 00:27:20 UTC (rev 128)
+++ trunk/pr/re_test.pr 2004-03-26 04:27:31 UTC (rev 129)
@@ -2,7 +2,9 @@
def findall(r,s):
result=[]
- def foundone(mo): &result.append!(mo.group())
+ def foundone(mo):
+ &result.append!(mo.group())
+ return ''
r.sub(foundone, s)
return result
Modified: trunk/src/builtins.c
===================================================================
--- trunk/src/builtins.c 2004-03-26 00:27:20 UTC (rev 128)
+++ trunk/src/builtins.c 2004-03-26 04:27:31 UTC (rev 129)
@@ -217,7 +217,7 @@
DEF(EXCEPTION_OBJ, __init__, FORM_STAR_PARAM) {
obj_p res;
if (list_len(ist, parms[1]) > 0)
- raise_exception(ist, self, str(ist, list_item(ist, parms[1], 0)));
+ raise_exception(ist, self, as_str(ist, list_item(ist, parms[1], 0)));
else
raise_exception(ist, self, NULL);
res = ist->exception_obj;
@@ -258,7 +258,7 @@
for (i=0; i < len; i++) {
char* item_str;
obj_p item = list_item(ist, self,i);
- if ((uintptr_t)item > 10) item_str = str(ist, item);
+ if ((uintptr_t)item > 10) item_str = as_str(ist, item);
else {
sprintf(msg, "<objptr:%lx>", (unsigned long)(uintptr_t)item);
item_str = msg;
@@ -284,8 +284,8 @@
int exp_len, self_len, slice_len = list_len(ist, slice);
char* self_str = NULL;
if (seq_type == SEQ_TYPE_STRING) {
+ self_len = (int) pr_strlen(self);
self_str = strch(self);
- self_len = (int)strlen(self_str);
} else
self_len = list_len(ist, self);
slice_item1 = list_item(ist, slice,0);
@@ -306,8 +306,7 @@
}
if (slice_len == 1) {
if (seq_type == SEQ_TYPE_STRING) {
- char s[2]; s[0] = self_str[index1]; s[1] = 0;
- return new_string_obj(s);
+ return new_string_obj_n(self_str+index1, 1);
} else
return list_item(ist, self, index1);
}
@@ -365,8 +364,7 @@
char* s = pr_malloc(exp_len+2);
for(i = index1, j=0; i < index2; i += index3, j++)
s[j] = self_str[i];
- s[j]=0;
- res = new_string_obj(s);
+ res = new_string_obj_n(s, j);
pr_free(s);
} break;
}
@@ -391,8 +389,7 @@
char* s = pr_malloc(exp_len+2);
for(i = index1, j=0; i > index2; i += index3, j++)
s[j] = self_str[i];
- s[j]=0;
- res = new_string_obj(s);
+ res = new_string_obj_n(s, j);
} break;
}
}
@@ -408,7 +405,7 @@
DEF(STRING_OBJ, __hash__, NULL) {
i32_t res = 0x9a7c5e3;
- char* p;
+ char *p;
for(p=strch(self); *p; p++) res += 131 * (*p);
return new_hash_obj(res);
}
@@ -695,8 +692,8 @@
obj_p vals = dict_values(ist, self);
strcpy(res, "{");
for (i=0; i < len; i++) {
- char* str1 = str(ist, list_item(ist, keys,i));
- char* str2 = str(ist, list_item(ist, vals,i));
+ char* str1 = as_str(ist, list_item(ist, keys,i));
+ char* str2 = as_str(ist, list_item(ist, vals,i));
res = pr_realloc(res, strlen(res)+strlen(str1)+1+strlen(str2)+( i != len-1 ? 3 : 2));
strcat(res, str1);
strcat(res, ":");
@@ -729,7 +726,7 @@
}
if (!(res = dict_item(ist, self, list_item(ist, parms[1],0)))) {
char msg[1024];
- sprintf(msg, "no entry found with key: %s", str(ist, list_item(ist, parms[1],0)));
+ sprintf(msg, "no entry found with key: %s", as_str(ist, list_item(ist, parms[1],0)));
raise_exception(ist, OBJ(INDEX_EXC), msg);
return NULL;
}
Modified: trunk/src/console.c
===================================================================
--- trunk/src/console.c 2004-03-26 00:27:20 UTC (rev 128)
+++ trunk/src/console.c 2004-03-26 04:27:31 UTC (rev 129)
@@ -226,7 +226,7 @@
ist->frame = NULL;
} else {
if (res && res != OBJ(NONE)) {
- char* res_str = str(ist, res);
+ char* res_str = as_str(ist, res);
if (res_str[strlen(res_str)-1] == '\n')
printf("%s", res_str);
else
Modified: trunk/src/interp.c
===================================================================
--- trunk/src/interp.c 2004-03-26 00:27:20 UTC (rev 128)
+++ trunk/src/interp.c 2004-03-26 04:27:31 UTC (rev 129)
@@ -871,7 +871,7 @@
if (intrp_exobj) break;
if (!func_obj) {
char str[1024];
- sprintf(str, "Function %s not found", str(ist, fr_stack[fr_sp+1]));
+ sprintf(str, "Function %s not found", as_str(ist, fr_stack[fr_sp+1]));
raise_exception(ist, OBJ(FUNCNOTFOUND_EXC), str);
break;
}
@@ -923,7 +923,7 @@
goto call_get_func;
}
}
- sprintf(str, "Function not found: \"%s\"", str(ist, fr_stack[fr_sp+1]));
+ sprintf(str, "Function not found: \"%s\"", as_str(ist, fr_stack[fr_sp+1]));
raise_exception(ist, OBJ(FUNCNOTFOUND_EXC), str);
}
} break;
@@ -993,7 +993,7 @@
if (fr_stack[fr_sp+i]) {
obj_p str_obj = call_func0(ist, fr_stack[fr_sp+i], SYM(__STR__));
if (intrp_exobj) break;
- printf("%s ", (char *)obj_data_p(str_obj));
+ printf("%s ", strch(str_obj));
} else if (i == param-1) goto endcase;
printf("\n");
} break;
@@ -1091,7 +1091,7 @@
func_obj = get_proto_attr(ist, self, func_sym, NULL); if_exc_return NULL;
if (!func_obj) {
char err_str[1024];
- sprintf(err_str, "Function not found: \"%s\"", str(ist, func_sym));
+ sprintf(err_str, "Function not found: \"%s\"", as_str(ist, func_sym));
if (!ist) {
printf("Internal error with exceptions disabled: %s", err_str);
pr_exit(1);
@@ -1178,9 +1178,9 @@
has_proto(ist, exc, OBJ(EXCEPTION)) ) {
obj_p doc = get_attr(ist, exc, SYM(__DOC__));
if (doc && exc != orig_excobj)
- printf("%s, ", (char *)obj_data_p(doc));
+ printf("%s, ", strch(doc));
else if (doc)
- printf("%s.\n\n", (char *)obj_data_p(doc));
+ printf("%s.\n\n", strch(doc));
}
}
return orig_excobj;
Modified: trunk/src/lock.c
===================================================================
--- trunk/src/lock.c 2004-03-26 00:27:20 UTC (rev 128)
+++ trunk/src/lock.c 2004-03-26 04:27:31 UTC (rev 129)
@@ -63,8 +63,6 @@
#include "lock.h"
#define lockstack ((clist_p)(ist->lock_stack))
-#define NO_WAIT 0
-#define WAIT 1
apr_thread_cond_t *obj_wrlock_cond;
apr_thread_mutex_t *obj_wrlock_mutex;
@@ -92,6 +90,10 @@
//********************************* read_lock_try *****************************
int read_lock_try(isp ist, obj_p obj) {
if (!lock((obj)->wrlock)) return FALSE;
+ if (obj->unmutable) {
+ free_obj_wrlock(obj);
+ return TRUE;
+ }
if (obj->wrlock_req_cnt) {
free_obj_wrlock(obj);
return FALSE;
@@ -106,6 +108,10 @@
//********************************* read_lock *********************************
void read_lock(isp ist, obj_p obj) {
get_wrlock(obj, NO_WAIT);
+ if (obj->unmutable) {
+ free_obj_wrlock(obj);
+ return;
+ }
if (obj->wrlock_req_cnt && !clist_in(lockstack, obj)) {
while(obj->wrlock_req_cnt) {
free_obj_wrlock(obj);
@@ -123,6 +129,10 @@
void read_unlock(isp ist, obj_p obj) {
int write_ready_flag;
get_wrlock(obj, NO_WAIT);
+ if (obj->unmutable) {
+ free_obj_wrlock(obj);
+ return;
+ }
write_ready_flag = !(--(obj->rdlock_cnt)) && obj->wrlock_req_cnt;
free_obj_wrlock(obj);
if (write_ready_flag) apr_thread_cond_broadcast(write_cond);
@@ -137,6 +147,11 @@
//********************************* write_lock_try ****************************
int write_lock_try(isp ist, obj_p obj) {
if (!lock((obj)->wrlock)) return FALSE;
+ if (obj->unmutable) {
+ raise_exception(ist, OBJ(LOCK_EXC), "write_lock attempted on an unmutable object");
+ free_obj_wrlock(obj);
+ return FALSE;
+ }
if (obj->rdlock_cnt || obj->wrlock_req_cnt) {
free_obj_wrlock(obj);
return FALSE;
@@ -149,26 +164,35 @@
void write_lock(isp ist, obj_p obj) {
int sav_cnt = 0;
get_wrlock(obj, NO_WAIT);
- if(clist_in(lockstack, obj)) {
- raise_exception(ist, OBJ(LOCK_EXC), "write_lock performed on a read_locked object");
- obj->rdlock_cnt -= sav_cnt = clist_in_cnt(lockstack, obj);
- }
- apr_thread_mutex_lock(write_mutex);
- while (obj->rdlock_cnt) {
- obj->wrlock_req_cnt++;
+ if (obj->unmutable) {
+ raise_exception(ist, OBJ(LOCK_EXC), "write_lock attempted on an unmutable object");
+ // something should be done to stop code from actually modifying object XXX
free_obj_wrlock(obj);
- apr_thread_cond_timedwait(write_cond, write_mutex, PAUSE_MS*1000);
- get_wrlock(obj, NO_WAIT);
- obj->wrlock_req_cnt--;
+ return;
}
- apr_thread_mutex_unlock(write_mutex);
- obj->rdlock_cnt += sav_cnt;
+ if(obj->rdlock_cnt) {
+ if(clist_in(lockstack, obj)) {
+ raise_exception(ist, OBJ(LOCK_EXC), "write_lock performed on a read_locked object");
+ obj->rdlock_cnt -= sav_cnt = clist_in_cnt(lockstack, obj);
+ }
+ apr_thread_mutex_lock(write_mutex);
+ while (obj->rdlock_cnt) {
+ obj->wrlock_req_cnt++;
+ free_obj_wrlock(obj);
+ apr_thread_cond_timedwait(write_cond, write_mutex, PAUSE_MS*1000);
+ get_wrlock(obj, NO_WAIT);
+ obj->wrlock_req_cnt--;
+ }
+ apr_thread_mutex_unlock(write_mutex);
+ obj->rdlock_cnt += sav_cnt;
+ }
obj->long_wrlock = TRUE;
}
//********************************* write_unlock ******************************
void write_unlock(isp ist, obj_p obj) {
int write_ready_flag;
+ if (obj->unmutable) return;
assert(obj->wrlock);
obj->long_wrlock = FALSE;
obj->archived = FALSE;
Modified: trunk/src/lock.h
===================================================================
--- trunk/src/lock.h 2004-03-26 00:27:20 UTC (rev 128)
+++ trunk/src/lock.h 2004-03-26 04:27:31 UTC (rev 129)
@@ -98,4 +98,11 @@
if (obj_wrlock_waiting) \
apr_thread_cond_broadcast(obj_wrlock_cond)
+#define NO_WAIT 0
+#define WAIT 1
+
+void get_wrlock(obj_p obj, int force_wait);
+
#endif // #ifndef LOCK_H
+
+
Modified: trunk/src/memory_mgr.c
===================================================================
--- trunk/src/memory_mgr.c 2004-03-26 00:27:20 UTC (rev 128)
+++ trunk/src/memory_mgr.c 2004-03-26 04:27:31 UTC (rev 129)
@@ -56,6 +56,7 @@
#include "object.h"
#include "interp.h"
#include "memory_mgr.h"
+#include "lock.h"
#ifdef WIN32
#include <windows.h>
@@ -83,6 +84,22 @@
i64_t hi_mem_boundary;
i64_t lo_mem_boundary;
+//********************************* mm_write_lock ********************************
+void mm_write_lock(isp ist, obj_p obj) {
+ get_wrlock(obj, NO_WAIT);
+ if(obj->rdlock_cnt) {
+ apr_thread_mutex_lock(write_mutex);
+ while (obj->rdlock_cnt) {
+ obj->wrlock_req_cnt++;
+ free_obj_wrlock(obj);
+ apr_thread_cond_timedwait(write_cond, write_mutex, PAUSE_MS*1000);
+ get_wrlock(obj, NO_WAIT);
+ obj->wrlock_req_cnt--;
+ }
+ apr_thread_mutex_unlock(write_mutex);
+ }
+ obj->long_wrlock = TRUE;
+}
//********************************* mm_write_unlock ***************************
void mm_write_unlock(obj_p obj) {
@@ -128,7 +145,7 @@
obj=obj_list_root;
pr_unlock(&object_list_lock);
while(obj) {
- write_lock(ist, obj);
+ mm_write_lock(ist, obj);
obj->state = OBJ_STATE_UNMARKED;
obj->scanned = FALSE;
mm_write_unlock(obj);
@@ -146,7 +163,7 @@
mem_mgr_phase = MM_PHASE_MARKING;
obj = OBJ(ROOT_GLOBALS);
to_be_scanned_list = new_clist(1000);
- write_lock(ist, obj);
+ mm_write_lock(ist, obj);
obj->state = OBJ_STATE_NEW_OR_MARKED;
obj->scanned = TRUE;
mm_write_unlock(obj);
@@ -161,7 +178,7 @@
for(i=ATTRS_OVERHEAD; i < ATTRS_OVERHEAD+attr_blen(attrs); i++){
val = attrs[i].attr.value;
if(val > min_obj && val != obj && !val->scanned) {
- write_lock(ist, val);
+ mm_write_lock(ist, val);
val->state = OBJ_STATE_NEW_OR_MARKED;
val->scanned = TRUE;
mm_write_unlock(val);
@@ -175,7 +192,7 @@
if ( attrs[i].attr.key > 0 &&
(val = attrs[i].attr.value) > min_obj &&
val != obj && !val->scanned ) {
- write_lock(ist, val);
+ mm_write_lock(ist, val);
val->state = OBJ_STATE_NEW_OR_MARKED;
val->scanned = TRUE;
mm_write_unlock(val);
@@ -187,7 +204,7 @@
}
if (obj->data_type == OBJ_TYPE_DATAPTR) {
obj_p obj_list;
- write_lock(ist, mm_obj_list);
+ mm_write_lock(ist, mm_obj_list);
listlen(mm_obj_list) = 0;
write_unlock(ist, mm_obj_list);
obj_list = call_func(ist, obj, SYM(__OBJLIST__), 2, mm_obj_act_param, NULL);
@@ -202,7 +219,7 @@
for(i=0; i < llen; i++) {
obj_p val = listitem(obj_list, i);
if (val > min_obj && val != obj && !val->scanned) {
- write_lock(ist, val);
+ mm_write_lock(ist, val);
val->state = OBJ_STATE_NEW_OR_MARKED;
val->scanned = TRUE;
mm_write_unlock(val);
@@ -254,7 +271,7 @@
if (obj->state != OBJ_STATE_NEW_OR_MARKED && !obj->del_locked) {
call_func(ist, obj, SYM(__DEL__), 0, NULL, NULL);
ist->exception_obj = 0;
- write_lock(ist, obj);
+ mm_write_lock(ist, obj);
obj->state = OBJ_STATE_DELETED;
pr_lock(&object_list_lock);
if (last_obj)
Modified: trunk/src/object.c
===================================================================
--- trunk/src/object.c 2004-03-26 00:27:20 UTC (rev 128)
+++ trunk/src/object.c 2004-03-26 04:27:31 UTC (rev 129)
@@ -704,11 +704,12 @@
if (size <= sizeof(obj_data_t)){
obj->data_type = OBJ_TYPE_IMMDATA;
obj->imm_data_len = (int) size;
+ return &obj->data;
} else {
obj->data_type = OBJ_TYPE_DATAPTR;
obj->data.ptr = pr_malloc(size);
+ return obj->data.ptr;
}
- return obj_data_p(obj);
}
//********************************* obj_realloc *******************************
@@ -753,6 +754,7 @@
obj->data_type = OBJ_TYPE_IMMDATA;
obj->imm_data_len = 8;
obj->data.i64 = num;
+ obj->unmutable = TRUE;
return obj;
}
@@ -762,29 +764,51 @@
obj->data_type = OBJ_TYPE_IMMDATA;
obj->imm_data_len = 8;
obj->data.f64 = num;
+ obj->unmutable = TRUE;
return obj;
}
//********************************* new_string_obj ****************************
+// this cannot be used with binary data, for C strings only
+// for binary data with embedded nulls use new_string_obj_n()
obj_p new_string_obj(char* str){
obj_p obj;
- char* obj_str;
+ pr_str_p obj_str;
+ size_t len;
if(!str) return NULL;
+ len = strlen(str);
obj = new_object(OBJ(STRING_PROTO));
- obj_str = obj_malloc(obj, strlen(str) + 1);
- strcpy(obj_str, str);
+ if (len < IMMEDIATE_DATA_LEN) {
+ obj->data_type = OBJ_TYPE_IMMDATA;
+ obj->imm_data_len = (int) len;
+ strcpy(obj->data.str, str);
+ } else {
+ obj_str = obj_malloc(obj, sizeof(pr_str_t)+len+1);
+ obj_str->len = len;
+ strcpy(&(obj_str->str[0]), str);
+ }
+ obj->unmutable = TRUE;
return obj;
}
-//********************************* new_string_obj ****************************
-obj_p new_string_obj_n(char* str, size_t n){
+//********************************* new_string_obj_n ****************************
+obj_p new_string_obj_n(char* str, size_t len){
obj_p obj;
- char* obj_str;
+ pr_str_p obj_str;
if(!str) return NULL;
obj = new_object(OBJ(STRING_PROTO));
- obj_str = obj_malloc(obj, n+1);
- strncpy(obj_str, str, n);
- obj_str[n] = 0;
+ if (len < IMMEDIATE_DATA_LEN) {
+ obj->data_type = OBJ_TYPE_IMMDATA;
+ obj->imm_data_len = (int) len;
+ memcpy(obj->data.str, str, len);
+ obj->data.str[len] = 0;
+ } else {
+ obj_str = obj_malloc(obj, sizeof(pr_str_t)+len+1);
+ obj_str->len = len;
+ memcpy(&(obj_str->str[0]), str, len);
+ obj_str->str[len] = 0;
+ }
+ obj->unmutable = TRUE;
return obj;
}
@@ -795,6 +819,7 @@
hash_obj->imm_data_len = 4;
hash_obj->data.i32[0] = num & HASH_MASK;
if (!(hash_obj->data.i32[0])) hash_obj->data.i32[0] = 1;
+ hash_obj->unmutable = TRUE;
return hash_obj;
}
@@ -906,6 +931,7 @@
list_append_no_lock(slice_obj,ind3);
}
}
+ slice_obj->unmutable = TRUE;
return slice_obj;
}
@@ -914,6 +940,7 @@
obj_p super_obj = new_object(OBJ(SUPER_PROTO));
super_obj->data_type = OBJ_TYPE_DATAPTR;
super_obj->data.ptr = symbol;
+ super_obj->unmutable = TRUE;
return super_obj;
}
@@ -1200,7 +1227,7 @@
obj_p doc;
doc = get_attr(ist, obj, SYM(__DOC__));
if (doc) {fprintf(fout,"obj(%lx) doc: %s\n", (unsigned long)(uintptr_t)obj, strch(doc)); prt_flg = 1;}
- else {fprintf(fout,"%s\n",str(ist, obj)); 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)
return;
@@ -1218,7 +1245,7 @@
if(obj->data_type == OBJ_TYPE_IMMDATA){
fprintf(fout, "%08x %08x \"%s\"\n",
obj->data.i32[0], obj->data.i32[1],
- obj->data.byte );
+ obj->data.str );
} else if(obj->data_type != OBJ_TYPE_NONE){
fprintf(fout,"%08x\n", obj->data.i32[0]);
}
Modified: trunk/src/parser_routines.c
===================================================================
--- trunk/src/parser_routines.c 2004-03-26 00:27:20 UTC (rev 128)
+++ trunk/src/parser_routines.c 2004-03-26 04:27:31 UTC (rev 129)
@@ -1062,10 +1062,22 @@
}
code* string_to_obj(void* param, char* str, int long_flag){
code* p = new_code(param, 2, 1, 1, OP_PUSH);
+ pr_str_p obj_str;
+ size_t len = strlen(str);
obj_p obj = new_object(
(long_flag == NEW_LONG? OBJ(LONG_PROTO) : OBJ(STRING_PROTO)) );
- char* obj_str = obj_malloc(obj, strlen(str) + 1);
- strcpy(obj_str, str);
+ if (len < IMMEDIATE_DATA_LEN) {
+ obj->data_type = OBJ_TYPE_IMMDATA;
+ obj->imm_data_len = (int) len;
+ memcpy(obj->data.str, str, len);
+ obj->data.str[len] = 0;
+ } else {
+ obj_str = obj_malloc(obj, sizeof(pr_str_t)+len+1);
+ obj_str->len = len;
+ memcpy(&(obj_str->str[0]), str, len);
+ obj_str->str[len] = 0;
+ }
+ obj->unmutable = TRUE;
p->code_data[0].bytecode.param = 2;
p->code_data[1].data = obj;
add_to_const_list(param, obj);
Modified: trunk/src/symbol.c
===================================================================
--- trunk/src/symbol.c 2004-03-26 00:27:20 UTC (rev 128)
+++ trunk/src/symbol.c 2004-03-26 04:27:31 UTC (rev 129)
@@ -244,7 +244,10 @@
obj_p s_obj;
if (sym_obj) {
s_obj = get_attr(ist, sym_obj, SYM(__STRING__));
- if (s_obj) return strch(s_obj);
+ if (s_obj) {
+ char* tmp = strch(s_obj);
+ return tmp;
+ }
}
return NULL;
}
Modified: trunk/src/sys.c
===================================================================
--- trunk/src/sys.c 2004-03-26 00:27:20 UTC (rev 128)
+++ trunk/src/sys.c 2004-03-26 04:27:31 UTC (rev 129)
@@ -180,6 +180,7 @@
list_append(ist, vers_tuple, new_string_obj(PROTHON_VERSION_NUMBER));
list_append(ist, vers_tuple, new_string_obj(numonly(PROTHON_VERSION_BUILD, path)));
list_append(ist, vers_tuple, new_string_obj(PROTHON_VERSION_DATE));
+ vers_tuple->unmutable = TRUE;
set_attr(ist, sys_module, sym(ist, "version"), vers_tuple);
set_attr(ist, sys_module, sym(ist, "maxint"), new_int_obj(MAX_INT_VAL));
set_attr(ist, sys_module, sym(ist, "modules"), OBJ(MODULES));
_______________________________________________
Prothon-commits mailing list
[email protected]
http://lists.prothon.org/mailman/listinfo/prothon-commits