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