diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1997-02-11 09:40:01 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1997-02-11 09:40:01 -0200 |
commit | 205ee1ec84c0f0e9c2df923fdcfa29207e8e72b3 (patch) | |
tree | 1e2683e673e5fbf2230343df4faac3b252eee38c | |
parent | b48847c5fac055f0d6120029f6fe1a50c852a8ac (diff) | |
download | lua-205ee1ec84c0f0e9c2df923fdcfa29207e8e72b3.tar.gz lua-205ee1ec84c0f0e9c2df923fdcfa29207e8e72b3.tar.bz2 lua-205ee1ec84c0f0e9c2df923fdcfa29207e8e72b3.zip |
userdata can handle arbitrary binary data;
user tag is stored with data;
-rw-r--r-- | hash.c | 18 | ||||
-rw-r--r-- | lua.h | 7 | ||||
-rw-r--r-- | opcode.c | 46 | ||||
-rw-r--r-- | opcode.h | 4 | ||||
-rw-r--r-- | tree.c | 38 | ||||
-rw-r--r-- | tree.h | 7 |
6 files changed, 79 insertions, 41 deletions
@@ -3,7 +3,7 @@ | |||
3 | ** hash manager for lua | 3 | ** hash manager for lua |
4 | */ | 4 | */ |
5 | 5 | ||
6 | char *rcs_hash="$Id: hash.c,v 2.31 1996/07/12 20:00:26 roberto Exp roberto $"; | 6 | char *rcs_hash="$Id: hash.c,v 2.32 1996/11/18 13:48:44 roberto Exp roberto $"; |
7 | 7 | ||
8 | 8 | ||
9 | #include "mem.h" | 9 | #include "mem.h" |
@@ -50,12 +50,9 @@ static int hashindex (Hash *t, Object *ref) /* hash function */ | |||
50 | { | 50 | { |
51 | long int h; | 51 | long int h; |
52 | switch (tag(ref)) { | 52 | switch (tag(ref)) { |
53 | case LUA_T_NIL: | ||
54 | lua_error ("unexpected type to index table"); | ||
55 | h = 0; /* UNREACHEABLE */ | ||
56 | case LUA_T_NUMBER: | 53 | case LUA_T_NUMBER: |
57 | h = (long int)nvalue(ref); break; | 54 | h = (long int)nvalue(ref); break; |
58 | case LUA_T_STRING: | 55 | case LUA_T_STRING: case LUA_T_USERDATA: |
59 | h = tsvalue(ref)->hash; break; | 56 | h = tsvalue(ref)->hash; break; |
60 | case LUA_T_FUNCTION: | 57 | case LUA_T_FUNCTION: |
61 | h = (IntPoint)ref->value.tf; break; | 58 | h = (IntPoint)ref->value.tf; break; |
@@ -63,8 +60,9 @@ static int hashindex (Hash *t, Object *ref) /* hash function */ | |||
63 | h = (IntPoint)fvalue(ref); break; | 60 | h = (IntPoint)fvalue(ref); break; |
64 | case LUA_T_ARRAY: | 61 | case LUA_T_ARRAY: |
65 | h = (IntPoint)avalue(ref); break; | 62 | h = (IntPoint)avalue(ref); break; |
66 | default: /* user data */ | 63 | default: |
67 | h = (IntPoint)uvalue(ref); break; | 64 | lua_error ("unexpected type to index table"); |
65 | h = 0; /* UNREACHEABLE */ | ||
68 | } | 66 | } |
69 | if (h < 0) h = -h; | 67 | if (h < 0) h = -h; |
70 | return h%nhash(t); /* make it a valid index */ | 68 | return h%nhash(t); /* make it a valid index */ |
@@ -77,11 +75,13 @@ int lua_equalObj (Object *t1, Object *t2) | |||
77 | { | 75 | { |
78 | case LUA_T_NIL: return 1; | 76 | case LUA_T_NIL: return 1; |
79 | case LUA_T_NUMBER: return nvalue(t1) == nvalue(t2); | 77 | case LUA_T_NUMBER: return nvalue(t1) == nvalue(t2); |
80 | case LUA_T_STRING: return svalue(t1) == svalue(t2); | 78 | case LUA_T_STRING: case LUA_T_USERDATA: return svalue(t1) == svalue(t2); |
81 | case LUA_T_ARRAY: return avalue(t1) == avalue(t2); | 79 | case LUA_T_ARRAY: return avalue(t1) == avalue(t2); |
82 | case LUA_T_FUNCTION: return t1->value.tf == t2->value.tf; | 80 | case LUA_T_FUNCTION: return t1->value.tf == t2->value.tf; |
83 | case LUA_T_CFUNCTION: return fvalue(t1) == fvalue(t2); | 81 | case LUA_T_CFUNCTION: return fvalue(t1) == fvalue(t2); |
84 | default: return uvalue(t1) == uvalue(t2); | 82 | default: |
83 | lua_error("internal error at `lua_equalObj'"); | ||
84 | return 0; /* UNREACHEABLE */ | ||
85 | } | 85 | } |
86 | } | 86 | } |
87 | 87 | ||
@@ -2,14 +2,14 @@ | |||
2 | ** LUA - Linguagem para Usuarios de Aplicacao | 2 | ** LUA - Linguagem para Usuarios de Aplicacao |
3 | ** Grupo de Tecnologia em Computacao Grafica | 3 | ** Grupo de Tecnologia em Computacao Grafica |
4 | ** TeCGraf - PUC-Rio | 4 | ** TeCGraf - PUC-Rio |
5 | ** $Id: lua.h,v 3.31 1996/11/12 16:00:16 roberto Exp roberto $ | 5 | ** $Id: lua.h,v 3.32 1996/11/20 13:49:32 roberto Exp roberto $ |
6 | */ | 6 | */ |
7 | 7 | ||
8 | 8 | ||
9 | #ifndef lua_h | 9 | #ifndef lua_h |
10 | #define lua_h | 10 | #define lua_h |
11 | 11 | ||
12 | #define LUA_VERSION "Lua 2.5.1" | 12 | #define LUA_VERSION "Lua 2.?" |
13 | #define LUA_COPYRIGHT "Copyright (C) 1994-1996 TeCGraf" | 13 | #define LUA_COPYRIGHT "Copyright (C) 1994-1996 TeCGraf" |
14 | #define LUA_AUTHORS "W. Celes, R. Ierusalimschy & L. H. de Figueiredo" | 14 | #define LUA_AUTHORS "W. Celes, R. Ierusalimschy & L. H. de Figueiredo" |
15 | 15 | ||
@@ -63,12 +63,15 @@ int lua_isfunction (lua_Object object); | |||
63 | float lua_getnumber (lua_Object object); | 63 | float lua_getnumber (lua_Object object); |
64 | char *lua_getstring (lua_Object object); | 64 | char *lua_getstring (lua_Object object); |
65 | lua_CFunction lua_getcfunction (lua_Object object); | 65 | lua_CFunction lua_getcfunction (lua_Object object); |
66 | void *lua_getbinarydata (lua_Object object); | ||
67 | int lua_getbindatasize (lua_Object object); | ||
66 | void *lua_getuserdata (lua_Object object); | 68 | void *lua_getuserdata (lua_Object object); |
67 | 69 | ||
68 | void lua_pushnil (void); | 70 | void lua_pushnil (void); |
69 | void lua_pushnumber (float n); | 71 | void lua_pushnumber (float n); |
70 | void lua_pushstring (char *s); | 72 | void lua_pushstring (char *s); |
71 | void lua_pushcfunction (lua_CFunction fn); | 73 | void lua_pushcfunction (lua_CFunction fn); |
74 | void lua_pushbinarydata (void *buff, int size, int tag); | ||
72 | void lua_pushusertag (void *u, int tag); | 75 | void lua_pushusertag (void *u, int tag); |
73 | void lua_pushobject (lua_Object object); | 76 | void lua_pushobject (lua_Object object); |
74 | 77 | ||
@@ -3,7 +3,7 @@ | |||
3 | ** TecCGraf - PUC-Rio | 3 | ** TecCGraf - PUC-Rio |
4 | */ | 4 | */ |
5 | 5 | ||
6 | char *rcs_opcode="$Id: opcode.c,v 3.78 1996/11/22 13:08:28 roberto Exp roberto $"; | 6 | char *rcs_opcode="$Id: opcode.c,v 3.79 1997/01/31 14:27:11 roberto Exp roberto $"; |
7 | 7 | ||
8 | #include <setjmp.h> | 8 | #include <setjmp.h> |
9 | #include <stdio.h> | 9 | #include <stdio.h> |
@@ -709,6 +709,20 @@ char *lua_getstring (lua_Object object) | |||
709 | else return (svalue(Address(object))); | 709 | else return (svalue(Address(object))); |
710 | } | 710 | } |
711 | 711 | ||
712 | void *lua_getbinarydata (lua_Object object) | ||
713 | { | ||
714 | if (object == LUA_NOOBJECT || tag(Address(object)) != LUA_T_USERDATA) | ||
715 | lua_error("getbinarydata: object is not binary data"); | ||
716 | return svalue(Address(object)); | ||
717 | } | ||
718 | |||
719 | int lua_getbindatasize (lua_Object object) | ||
720 | { | ||
721 | if (object == LUA_NOOBJECT || tag(Address(object)) != LUA_T_USERDATA) | ||
722 | return 0; | ||
723 | else return (Address(object))->value.ts->size; | ||
724 | } | ||
725 | |||
712 | /* | 726 | /* |
713 | ** Given an object handle, return its cfuntion pointer. On error, return NULL. | 727 | ** Given an object handle, return its cfuntion pointer. On error, return NULL. |
714 | */ | 728 | */ |
@@ -725,9 +739,7 @@ lua_CFunction lua_getcfunction (lua_Object object) | |||
725 | */ | 739 | */ |
726 | void *lua_getuserdata (lua_Object object) | 740 | void *lua_getuserdata (lua_Object object) |
727 | { | 741 | { |
728 | if (object == LUA_NOOBJECT || tag(Address(object)) < LUA_T_USERDATA) | 742 | return *(void **)lua_getbinarydata(object); |
729 | return NULL; | ||
730 | else return (uvalue(Address(object))); | ||
731 | } | 743 | } |
732 | 744 | ||
733 | 745 | ||
@@ -825,15 +837,25 @@ void lua_pushcfunction (lua_CFunction fn) | |||
825 | incr_top; | 837 | incr_top; |
826 | } | 838 | } |
827 | 839 | ||
840 | void lua_pushbinarydata (void *buff, int size, int tag) | ||
841 | { | ||
842 | if (buff == NULL) | ||
843 | tag(top) = LUA_T_NIL; | ||
844 | else { | ||
845 | tsvalue(top) = luaI_createuserdata(buff, size, tag); | ||
846 | tag(top) = LUA_T_USERDATA; | ||
847 | } | ||
848 | incr_top; | ||
849 | } | ||
850 | |||
828 | /* | 851 | /* |
829 | ** Push an object (tag=userdata) to stack. | 852 | ** Push an object (tag=userdata) to stack. |
830 | */ | 853 | */ |
831 | void lua_pushusertag (void *u, int tag) | 854 | void lua_pushusertag (void *u, int tag) |
832 | { | 855 | { |
833 | if (tag < LUA_T_USERDATA) | 856 | if (tag < LUA_T_USERDATA) |
834 | lua_error("invalid tag in `lua_pushusertag'"); | 857 | lua_error("invalid tag in `lua_pushusertag'"); |
835 | tag(top) = tag; uvalue(top) = u; | 858 | lua_pushbinarydata(&u, sizeof(void *), tag); |
836 | incr_top; | ||
837 | } | 859 | } |
838 | 860 | ||
839 | /* | 861 | /* |
@@ -862,8 +884,12 @@ int lua_type (lua_Object o) | |||
862 | { | 884 | { |
863 | if (o == LUA_NOOBJECT) | 885 | if (o == LUA_NOOBJECT) |
864 | return LUA_T_NIL; | 886 | return LUA_T_NIL; |
865 | else | 887 | else { |
866 | return tag(Address(o)); | 888 | lua_Type t = tag(Address(o)); |
889 | if (t == LUA_T_USERDATA) | ||
890 | return (Address(o))->value.ts->tag; | ||
891 | else return tag(Address(o)); | ||
892 | } | ||
867 | } | 893 | } |
868 | 894 | ||
869 | 895 | ||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | ** TeCGraf - PUC-Rio | 2 | ** TeCGraf - PUC-Rio |
3 | ** $Id: opcode.h,v 3.23 1996/09/26 21:08:41 roberto Exp roberto $ | 3 | ** $Id: opcode.h,v 3.24 1996/11/01 12:46:59 roberto Exp roberto $ |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #ifndef opcode_h | 6 | #ifndef opcode_h |
@@ -102,7 +102,6 @@ typedef union | |||
102 | TaggedString *ts; | 102 | TaggedString *ts; |
103 | TFunc *tf; | 103 | TFunc *tf; |
104 | struct Hash *a; | 104 | struct Hash *a; |
105 | void *u; | ||
106 | int i; | 105 | int i; |
107 | } Value; | 106 | } Value; |
108 | 107 | ||
@@ -120,7 +119,6 @@ typedef struct Object | |||
120 | #define tsvalue(o) ((o)->value.ts) | 119 | #define tsvalue(o) ((o)->value.ts) |
121 | #define avalue(o) ((o)->value.a) | 120 | #define avalue(o) ((o)->value.a) |
122 | #define fvalue(o) ((o)->value.f) | 121 | #define fvalue(o) ((o)->value.f) |
123 | #define uvalue(o) ((o)->value.u) | ||
124 | 122 | ||
125 | /* Macros to access symbol table */ | 123 | /* Macros to access symbol table */ |
126 | #define s_object(i) (lua_table[i].object) | 124 | #define s_object(i) (lua_table[i].object) |
@@ -3,7 +3,7 @@ | |||
3 | ** TecCGraf - PUC-Rio | 3 | ** TecCGraf - PUC-Rio |
4 | */ | 4 | */ |
5 | 5 | ||
6 | char *rcs_tree="$Id: tree.c,v 1.19 1996/02/22 20:34:33 roberto Exp $"; | 6 | char *rcs_tree="$Id: tree.c,v 1.20 1996/03/14 15:56:26 roberto Exp roberto $"; |
7 | 7 | ||
8 | 8 | ||
9 | #include <string.h> | 9 | #include <string.h> |
@@ -28,14 +28,14 @@ static int initialized = 0; | |||
28 | 28 | ||
29 | static stringtable string_root[NUM_HASHS]; | 29 | static stringtable string_root[NUM_HASHS]; |
30 | 30 | ||
31 | static TaggedString EMPTY = {NOT_USED, NOT_USED, 0, 2, {0}}; | 31 | static TaggedString EMPTY = {LUA_T_STRING, 0, NOT_USED, NOT_USED, 0, 2, {0}}; |
32 | 32 | ||
33 | 33 | ||
34 | static unsigned long hash (char *str) | 34 | static unsigned long hash (char *buff, long size) |
35 | { | 35 | { |
36 | unsigned long h = 0; | 36 | unsigned long h = 0; |
37 | while (*str) | 37 | while (size--) |
38 | h = ((h<<5)-h)^(unsigned char)*(str++); | 38 | h = ((h<<5)-h)^(unsigned char)*(buff++); |
39 | return h; | 39 | return h; |
40 | } | 40 | } |
41 | 41 | ||
@@ -71,10 +71,10 @@ static void grow (stringtable *tb) | |||
71 | tb->hash = newhash; | 71 | tb->hash = newhash; |
72 | } | 72 | } |
73 | 73 | ||
74 | static TaggedString *insert (char *str, stringtable *tb) | 74 | static TaggedString *insert (char *buff, long size, int tag, stringtable *tb) |
75 | { | 75 | { |
76 | TaggedString *ts; | 76 | TaggedString *ts; |
77 | unsigned long h = hash(str); | 77 | unsigned long h = hash(buff, size); |
78 | int i; | 78 | int i; |
79 | int j = -1; | 79 | int j = -1; |
80 | if ((Long)tb->nuse*3 >= (Long)tb->size*2) | 80 | if ((Long)tb->nuse*3 >= (Long)tb->size*2) |
@@ -84,12 +84,13 @@ static TaggedString *insert (char *str, stringtable *tb) | |||
84 | grow(tb); | 84 | grow(tb); |
85 | } | 85 | } |
86 | i = h%tb->size; | 86 | i = h%tb->size; |
87 | while (tb->hash[i]) | 87 | while ((ts = tb->hash[i]) != NULL) |
88 | { | 88 | { |
89 | if (tb->hash[i] == &EMPTY) | 89 | if (ts == &EMPTY) |
90 | j = i; | 90 | j = i; |
91 | else if (strcmp(str, tb->hash[i]->str) == 0) | 91 | else if (ts->size == size && ts->tag == tag && |
92 | return tb->hash[i]; | 92 | memcmp(buff, ts->str, size) == 0) |
93 | return ts; | ||
93 | i = (i+1)%tb->size; | 94 | i = (i+1)%tb->size; |
94 | } | 95 | } |
95 | /* not found */ | 96 | /* not found */ |
@@ -98,17 +99,24 @@ static TaggedString *insert (char *str, stringtable *tb) | |||
98 | i = j; | 99 | i = j; |
99 | else | 100 | else |
100 | tb->nuse++; | 101 | tb->nuse++; |
101 | ts = tb->hash[i] = (TaggedString *)luaI_malloc(sizeof(TaggedString)+strlen(str)); | 102 | ts = tb->hash[i] = (TaggedString *)luaI_malloc(sizeof(TaggedString)+size-1); |
102 | strcpy(ts->str, str); | 103 | memcpy(ts->str, buff, size); |
104 | ts->tag = tag; | ||
105 | ts->size = size; | ||
103 | ts->marked = 0; | 106 | ts->marked = 0; |
104 | ts->hash = h; | 107 | ts->hash = h; |
105 | ts->varindex = ts->constindex = NOT_USED; | 108 | ts->varindex = ts->constindex = NOT_USED; |
106 | return ts; | 109 | return ts; |
107 | } | 110 | } |
108 | 111 | ||
109 | TaggedString *lua_createstring (char *str) | 112 | TaggedString *luaI_createuserdata (char *buff, long size, int tag) |
110 | { | 113 | { |
111 | return insert(str, &string_root[(unsigned)str[0]%NUM_HASHS]); | 114 | return insert(buff, size, tag, &string_root[(unsigned)buff[0]%NUM_HASHS]); |
115 | } | ||
116 | |||
117 | TaggedString *lua_createstring (char *str) | ||
118 | { | ||
119 | return luaI_createuserdata(str, strlen(str)+1, LUA_T_STRING); | ||
112 | } | 120 | } |
113 | 121 | ||
114 | 122 | ||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | ** tree.h | 2 | ** tree.h |
3 | ** TecCGraf - PUC-Rio | 3 | ** TecCGraf - PUC-Rio |
4 | ** $Id: tree.h,v 1.13 1996/02/14 13:35:51 roberto Exp roberto $ | 4 | ** $Id: tree.h,v 1.14 1996/02/26 17:07:49 roberto Exp roberto $ |
5 | */ | 5 | */ |
6 | 6 | ||
7 | #ifndef tree_h | 7 | #ifndef tree_h |
@@ -14,15 +14,18 @@ | |||
14 | 14 | ||
15 | typedef struct TaggedString | 15 | typedef struct TaggedString |
16 | { | 16 | { |
17 | int tag; /* if != LUA_T_STRING, this is a userdata */ | ||
18 | long size; | ||
17 | Word varindex; /* != NOT_USED if this is a symbol */ | 19 | Word varindex; /* != NOT_USED if this is a symbol */ |
18 | Word constindex; /* != NOT_USED if this is a constant */ | 20 | Word constindex; /* != NOT_USED if this is a constant */ |
19 | unsigned long hash; /* 0 if not initialized */ | 21 | unsigned long hash; /* 0 if not initialized */ |
20 | int marked; /* for garbage collection; never collect (nor change) if > 1 */ | 22 | int marked; /* for garbage collection; never collect (nor change) if > 1 */ |
21 | char str[1]; /* \0 byte already reserved */ | 23 | char str[1]; /* \0 byte already reserved; MAY BE NOT 0 TERMINATED!! */ |
22 | } TaggedString; | 24 | } TaggedString; |
23 | 25 | ||
24 | 26 | ||
25 | TaggedString *lua_createstring (char *str); | 27 | TaggedString *lua_createstring (char *str); |
28 | TaggedString *luaI_createuserdata (char *buff, long size, int tag); | ||
26 | Long lua_strcollector (void); | 29 | Long lua_strcollector (void); |
27 | 30 | ||
28 | #endif | 31 | #endif |