771ec540673f4dda2ab69f6f942ee78d412b30cb
[cacao.git] / src / native / native.c
1 /****************************** native.c ***************************************
2
3         Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
4
5         See file COPYRIGHT for information on usage and disclaimer of warranties
6
7         Enth"alt die Tabellen f"ur die native-methods.
8         Die vom Headerfile-Generator erzeugten -.hh - Dateien werden hier
9         eingebunden, und ebenso alle C-Funktionen, mit denen diese
10         Methoden implementiert werden.
11
12         Authors: Reinhard Grafl      EMAIL: cacao@complang.tuwien.ac.at
13
14         Last Change: 1996/11/14
15
16 *******************************************************************************/
17
18 #include <unistd.h>
19 #include <time.h>
20
21
22 #include "global.h"
23 #include "native.h"
24
25 #include "builtin.h"
26 #include "nativetypes.hh"
27 #include "asmpart.h"
28 #include "tables.h"
29 #include "loader.h"
30
31
32 java_objectheader* exceptionptr = NULL;
33
34
35
36 static char *classpath;
37
38
39 /******************** die f"r die native-Methoden n"otigen Systemklassen *****/
40
41 static classinfo *class_java_lang_Class;
42 static classinfo *class_java_lang_Cloneable;
43 static classinfo *class_java_lang_CloneNotSupportedException;
44 static classinfo *class_java_lang_Double;
45 static classinfo *class_java_lang_Float;
46 static classinfo *class_java_io_IOException;
47 static classinfo *class_java_lang_ClassNotFoundException;
48 static classinfo *class_java_lang_InstantiationException;
49
50
51
52 /************************** alle Funktionen einbinden ************************/ 
53
54 #include "nat/lang.c"
55 #include "nat/io.c"
56 #include "nat/util.c"
57
58
59 /********************** Tabellen f"ur die Methoden ***************************/
60
61 static struct nativeref {
62         char *classname;
63         char *methodname;
64         char *descriptor;
65         bool isstatic;
66         functionptr func;
67 } nativetable [] = {
68
69 #include "nativetable.hh"
70
71 };
72
73
74 #define NATIVETABLESIZE  (sizeof(nativetable)/sizeof(struct nativeref))
75
76 static struct nativecompref {
77         unicode *classname;
78         unicode *methodname;
79         unicode *descriptor;
80         bool isstatic;
81         functionptr func;
82         } nativecomptable [NATIVETABLESIZE];
83
84 static bool nativecompdone = false;
85
86
87 /*********************** Funktion: native_loadclasses **************************
88
89         L"adt alle Klassen, die die native Methoden zus"atzlich ben"otigen 
90
91 *******************************************************************************/
92
93 void native_loadclasses()
94 {
95         class_java_lang_Cloneable = 
96                 loader_load ( unicode_new_char ("java/lang/Cloneable") );
97         class_java_lang_CloneNotSupportedException = 
98                 loader_load ( unicode_new_char ("java/lang/CloneNotSupportedException") );
99         class_java_lang_Class =
100                 loader_load ( unicode_new_char ("java/lang/Class") );
101         class_java_lang_Double =
102                 loader_load ( unicode_new_char ("java/lang/Double") );
103         class_java_lang_Float =
104                 loader_load ( unicode_new_char ("java/lang/Float") );
105         class_java_io_IOException = 
106                 loader_load ( unicode_new_char ("java/io/IOException") );
107         class_java_lang_ClassNotFoundException =
108                 loader_load ( unicode_new_char ("java/lang/ClassNotFoundException") );
109         class_java_lang_InstantiationException=
110                 loader_load ( unicode_new_char ("java/lang/InstantiationException") );
111         
112 }
113
114 /********************* Funktion: native_setclasspath ***************************/
115  
116 void native_setclasspath (char *path)
117 {
118         classpath = path;
119 }
120
121
122 /*********************** Funktion: native_findfunction ************************
123
124         Sucht in der Tabelle die passende Methode (muss mit Klassennamen,
125         Methodennamen, Descriptor und 'static'-Status "ubereinstimmen),
126         und gibt den Funktionszeiger darauf zur"uck.
127         Return: Funktionszeiger oder NULL  (wenn es keine solche Methode gibt)
128
129         Anmerkung: Zu Beschleunigung des Suchens werden die als C-Strings
130            vorliegenden Namen/Descriptors in entsprechende unicode-Symbole
131            umgewandelt (beim ersten Aufruf dieser Funktion).
132
133 *******************************************************************************/
134
135 functionptr native_findfunction (unicode *cname, unicode *mname, 
136                                  unicode *desc, bool isstatic)
137 {
138         u4 i;
139         struct nativecompref *n;
140
141         isstatic = isstatic ? true : false;
142
143         if (!nativecompdone) {
144                 for (i=0; i<NATIVETABLESIZE; i++) {
145                         nativecomptable[i].classname   = 
146                                         unicode_new_char(nativetable[i].classname);
147                         nativecomptable[i].methodname  = 
148                                         unicode_new_char(nativetable[i].methodname);
149                         nativecomptable[i].descriptor  = 
150                                         unicode_new_char(nativetable[i].descriptor);
151                         nativecomptable[i].isstatic    = 
152                                         nativetable[i].isstatic;
153                         nativecomptable[i].func        = 
154                                         nativetable[i].func;
155                         }
156                 nativecompdone = true;
157                 }
158
159         for (i=0; i<NATIVETABLESIZE; i++) {
160                 n = &(nativecomptable[i]);
161
162                 if (cname==n->classname && mname==n->methodname &&
163                     desc==n->descriptor && isstatic==n->isstatic)  return n->func;
164                 }
165
166         return NULL;
167 }
168
169
170 /********************** Funktion: javastring_new *****************************
171
172         Legt ein neues Objekt vom Typ java/lang/String an, und tr"agt als Text
173         das "ubergebene unicode-Symbol ein. 
174         Return: Zeiger auf den String, oder NULL (wenn Speicher aus)
175
176 *****************************************************************************/
177
178 java_objectheader *javastring_new (unicode *text)
179 {
180         u4 i;
181         java_lang_String *s;
182         java_chararray *a;
183         
184         s = (java_lang_String*) builtin_new (class_java_lang_String);
185         a = builtin_newarray_char (text->length);
186
187         if ( (!a) || (!s) ) return NULL;
188
189         for (i=0; i<text->length; i++) a->data[i] = text->text[i];
190         s -> value = a;
191         s -> offset = 0;
192         s -> count = text->length;
193
194         return (java_objectheader*) s;
195 }
196
197
198 /********************** Funktion: javastring_new_char ************************
199
200         Legt ein neues Objekt vom Typ java/lang/String an, und tr"agt als Text
201         den "ubergebenen C-String ein. 
202         Return: Zeiger auf den String, oder NULL (wenn Speicher aus)
203
204 *****************************************************************************/
205
206 java_objectheader *javastring_new_char (char *text)
207 {
208         u4 i;
209         u4 len = strlen(text);
210         java_lang_String *s;
211         java_chararray *a;
212         
213         s = (java_lang_String*) builtin_new (class_java_lang_String);
214         a = builtin_newarray_char (len);
215
216         if ( (!a) || (!s) ) return NULL;
217
218         for (i=0; i<len; i++) a->data[i] = text[i];
219         s -> value = a;
220         s -> offset = 0;
221         s -> count = len;
222
223         return (java_objectheader*) s;
224 }
225
226
227 /************************* Funktion: javastring_tochar *****************************
228
229         Macht aus einem java-string einen C-String, und liefert den Zeiger
230         darauf zur"uck. 
231         Achtung: Beim n"achsten Aufruf der Funktion wird der vorige String 
232         "uberschrieben
233         
234 ***********************************************************************************/
235
236 #define MAXSTRINGSIZE 1000
237 char stringbuffer[MAXSTRINGSIZE];
238
239 char *javastring_tochar (java_objectheader *so) 
240 {
241         java_lang_String *s = (java_lang_String*) so;
242         java_chararray *a;
243         u4 i;
244         
245         if (!s) return "";
246         a = s->value;
247         if (!a) return "";
248         if (s->count > MAXSTRINGSIZE) return "";
249         for (i=0; i<s->count; i++) stringbuffer[i] = a->data[s->offset+i];
250         stringbuffer[i] = '\0';
251         return stringbuffer;
252 }
253
254
255 /******************** Funktion: native_new_and_init *************************
256
257         Legt ein neues Objekt einer Klasse am Heap an, und ruft automatisch
258         die Initialisierungsmethode auf.
259         Return: Der Zeiger auf das Objekt, oder NULL, wenn kein Speicher
260                         mehr frei ist.
261                         
262 *****************************************************************************/
263
264 java_objectheader *native_new_and_init (classinfo *c)
265 {
266         methodinfo *m;
267         java_objectheader *o = builtin_new (c);
268
269         if (!o) return NULL;
270         
271         m = class_findmethod (c, 
272                               unicode_new_char ("<init>"), 
273                               unicode_new_char ("()V"));
274         if (!m) {
275                 log_text ("warning: class has no instance-initializer:");
276                 unicode_sprint (logtext, c->name);
277                 dolog();
278                 return o;
279                 }
280
281         asm_calljavamethod (m, o,NULL,NULL,NULL);
282         return o;
283 }
284
285
286 /********************* Funktion: literalstring_new ****************************
287
288         erzeugt einen Java-String mit dem angegebenen Text, allerdings nicht
289         auf dem HEAP, sondern in einem anderen Speicherbereich (der String
290         muss dann sp"ater explizit wieder freigegeben werden).
291         Alle Strings, die auf diese Art erzeugt werden, werden in einer
292         gemeinsamen Struktur gespeichert (n"amlich auch "uber die
293         Unicode-Hashtabelle), sodass identische Strings auch wirklich den
294         gleichen Zeiger liefern.
295         
296 ******************************************************************************/
297
298 java_objectheader *literalstring_new (unicode *text)
299 {
300         u4 i;
301         java_lang_String *s;
302         java_chararray *a;
303
304         if (text->string) return text->string;
305         
306         a = lit_mem_alloc (sizeof(java_chararray) + sizeof(u2)*(text->length-1) );
307         a -> header.objheader.vftbl = class_array -> vftbl;
308         a -> header.size = text->length;
309         a -> header.arraytype = ARRAYTYPE_CHAR;
310         for (i=0; i<text->length; i++) a->data[i] = text->text[i];
311
312         s = LNEW (java_lang_String);
313         s -> header.vftbl = class_java_lang_String -> vftbl;
314         s -> value = a;
315         s -> offset = 0;
316         s -> count = text->length;
317
318         unicode_setstringlink (text, (java_objectheader*) s);
319         return (java_objectheader*) s;
320 }
321
322
323 /********************** Funktion: literalstring_free **************************
324
325         L"oscht einen Java-String wieder aus dem Speicher (wird zu Systemende
326         vom Hashtabellen-Verwalter aufgerufen)
327
328 ******************************************************************************/
329
330 void literalstring_free (java_objectheader* sobj)
331 {
332         java_lang_String *s = (java_lang_String*) sobj;
333         java_chararray *a = s->value;
334         
335         LFREE (s, java_lang_String);
336         LFREE (a, sizeof(java_chararray) + sizeof(u2)*(a->header.size-1));
337 }
338
339
340