aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>1997-02-11 09:40:01 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>1997-02-11 09:40:01 -0200
commit205ee1ec84c0f0e9c2df923fdcfa29207e8e72b3 (patch)
tree1e2683e673e5fbf2230343df4faac3b252eee38c
parentb48847c5fac055f0d6120029f6fe1a50c852a8ac (diff)
downloadlua-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.c18
-rw-r--r--lua.h7
-rw-r--r--opcode.c46
-rw-r--r--opcode.h4
-rw-r--r--tree.c38
-rw-r--r--tree.h7
6 files changed, 79 insertions, 41 deletions
diff --git a/hash.c b/hash.c
index 90d81293..8565d4f2 100644
--- a/hash.c
+++ b/hash.c
@@ -3,7 +3,7 @@
3** hash manager for lua 3** hash manager for lua
4*/ 4*/
5 5
6char *rcs_hash="$Id: hash.c,v 2.31 1996/07/12 20:00:26 roberto Exp roberto $"; 6char *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
diff --git a/lua.h b/lua.h
index f19a1351..459f87c0 100644
--- a/lua.h
+++ b/lua.h
@@ -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);
63float lua_getnumber (lua_Object object); 63float lua_getnumber (lua_Object object);
64char *lua_getstring (lua_Object object); 64char *lua_getstring (lua_Object object);
65lua_CFunction lua_getcfunction (lua_Object object); 65lua_CFunction lua_getcfunction (lua_Object object);
66void *lua_getbinarydata (lua_Object object);
67int lua_getbindatasize (lua_Object object);
66void *lua_getuserdata (lua_Object object); 68void *lua_getuserdata (lua_Object object);
67 69
68void lua_pushnil (void); 70void lua_pushnil (void);
69void lua_pushnumber (float n); 71void lua_pushnumber (float n);
70void lua_pushstring (char *s); 72void lua_pushstring (char *s);
71void lua_pushcfunction (lua_CFunction fn); 73void lua_pushcfunction (lua_CFunction fn);
74void lua_pushbinarydata (void *buff, int size, int tag);
72void lua_pushusertag (void *u, int tag); 75void lua_pushusertag (void *u, int tag);
73void lua_pushobject (lua_Object object); 76void lua_pushobject (lua_Object object);
74 77
diff --git a/opcode.c b/opcode.c
index 5c03d7b5..281cf1bb 100644
--- a/opcode.c
+++ b/opcode.c
@@ -3,7 +3,7 @@
3** TecCGraf - PUC-Rio 3** TecCGraf - PUC-Rio
4*/ 4*/
5 5
6char *rcs_opcode="$Id: opcode.c,v 3.78 1996/11/22 13:08:28 roberto Exp roberto $"; 6char *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
712void *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
719int 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*/
726void *lua_getuserdata (lua_Object object) 740void *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
840void 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*/
831void lua_pushusertag (void *u, int tag) 854void 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
diff --git a/opcode.h b/opcode.h
index 1ee6bf97..dde9c11d 100644
--- a/opcode.h
+++ b/opcode.h
@@ -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)
diff --git a/tree.c b/tree.c
index 5ebdf84b..f594824f 100644
--- a/tree.c
+++ b/tree.c
@@ -3,7 +3,7 @@
3** TecCGraf - PUC-Rio 3** TecCGraf - PUC-Rio
4*/ 4*/
5 5
6char *rcs_tree="$Id: tree.c,v 1.19 1996/02/22 20:34:33 roberto Exp $"; 6char *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
29static stringtable string_root[NUM_HASHS]; 29static stringtable string_root[NUM_HASHS];
30 30
31static TaggedString EMPTY = {NOT_USED, NOT_USED, 0, 2, {0}}; 31static TaggedString EMPTY = {LUA_T_STRING, 0, NOT_USED, NOT_USED, 0, 2, {0}};
32 32
33 33
34static unsigned long hash (char *str) 34static 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
74static TaggedString *insert (char *str, stringtable *tb) 74static 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
109TaggedString *lua_createstring (char *str) 112TaggedString *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
117TaggedString *lua_createstring (char *str)
118{
119 return luaI_createuserdata(str, strlen(str)+1, LUA_T_STRING);
112} 120}
113 121
114 122
diff --git a/tree.h b/tree.h
index ebdad6e0..4f2212b4 100644
--- a/tree.h
+++ b/tree.h
@@ -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
15typedef struct TaggedString 15typedef 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
25TaggedString *lua_createstring (char *str); 27TaggedString *lua_createstring (char *str);
28TaggedString *luaI_createuserdata (char *buff, long size, int tag);
26Long lua_strcollector (void); 29Long lua_strcollector (void);
27 30
28#endif 31#endif