]>
Commit | Line | Data |
---|---|---|
58eb6e7c AG |
1 | // java-interp.h - Header file for the bytecode interpreter. -*- c++ -*- |
2 | ||
fdae83ab | 3 | /* Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation |
58eb6e7c AG |
4 | |
5 | This file is part of libgcj. | |
6 | ||
7 | This software is copyrighted work licensed under the terms of the | |
8 | Libgcj License. Please consult the file "LIBGCJ_LICENSE" for | |
9 | details. */ | |
10 | ||
11 | #ifndef __JAVA_INTERP_H__ | |
12 | #define __JAVA_INTERP_H__ | |
13 | ||
58eb6e7c AG |
14 | #include <jvm.h> |
15 | #include <java-cpool.h> | |
16 | ||
17 | #ifdef INTERPRETER | |
18 | ||
19 | #pragma interface | |
20 | ||
21 | #include <java/lang/Class.h> | |
22 | #include <java/lang/ClassLoader.h> | |
58eb6e7c AG |
23 | |
24 | extern "C" { | |
25 | #include <ffi.h> | |
26 | } | |
27 | ||
28 | extern inline jboolean | |
29 | _Jv_IsInterpretedClass (jclass c) | |
30 | { | |
31 | return (c->loader != 0); | |
32 | } | |
33 | ||
34 | struct _Jv_ResolvedMethod; | |
35 | ||
58eb6e7c | 36 | void _Jv_DefineClass (jclass, jbyteArray, jint, jint); |
58eb6e7c AG |
37 | |
38 | void _Jv_InitField (jobject, jclass, int); | |
39 | void * _Jv_AllocMethodInvocation (jsize size); | |
a12fe13d TT |
40 | int _Jv_count_arguments (_Jv_Utf8Const *signature, |
41 | jboolean staticp = true); | |
42 | void _Jv_VerifyMethod (_Jv_InterpMethod *method); | |
58eb6e7c AG |
43 | |
44 | /* FIXME: this should really be defined in some more generic place */ | |
45 | #define ROUND(V, A) (((((unsigned) (V))-1) | ((A)-1))+1) | |
46 | ||
47 | /* the interpreter is written in C++, primarily because it makes it easy for | |
48 | * the entire thing to be "friend" with class Class. */ | |
49 | ||
50 | class _Jv_InterpClass; | |
51 | class _Jv_InterpMethod; | |
fdae83ab TT |
52 | |
53 | // Before a method is "compiled" we store values as the bytecode PC, | |
54 | // an int. Afterwards we store them as pointers into the prepared | |
55 | // code itself. | |
56 | union _Jv_InterpPC | |
57 | { | |
58 | int i; | |
59 | void *p; | |
60 | }; | |
58eb6e7c | 61 | |
a12fe13d TT |
62 | class _Jv_InterpException |
63 | { | |
fdae83ab TT |
64 | _Jv_InterpPC start_pc; |
65 | _Jv_InterpPC end_pc; | |
66 | _Jv_InterpPC handler_pc; | |
67 | _Jv_InterpPC handler_type; | |
58eb6e7c AG |
68 | |
69 | friend class _Jv_ClassReader; | |
70 | friend class _Jv_InterpMethod; | |
a12fe13d | 71 | friend class _Jv_BytecodeVerifier; |
58eb6e7c AG |
72 | }; |
73 | ||
f39b788a TT |
74 | // Base class for method representations. Subclasses are interpreted |
75 | // and JNI methods. | |
76 | class _Jv_MethodBase | |
77 | { | |
78 | protected: | |
79 | // The class which defined this method. | |
80 | _Jv_InterpClass *defining_class; | |
81 | ||
82 | // The method description. | |
83 | _Jv_Method *self; | |
d348bda4 TT |
84 | |
85 | // Size of raw arguments. | |
86 | _Jv_ushort args_raw_size; | |
8ade4771 TT |
87 | |
88 | public: | |
89 | _Jv_Method *get_method () | |
90 | { | |
91 | return self; | |
92 | } | |
f39b788a TT |
93 | }; |
94 | ||
facc279f TT |
95 | class _Jv_InterpMethod : public _Jv_MethodBase |
96 | { | |
58eb6e7c AG |
97 | _Jv_ushort max_stack; |
98 | _Jv_ushort max_locals; | |
99 | int code_length; | |
100 | ||
101 | _Jv_ushort exc_count; | |
58eb6e7c | 102 | |
fdae83ab TT |
103 | void *prepared; |
104 | ||
58eb6e7c AG |
105 | unsigned char* bytecode () |
106 | { | |
107 | return | |
108 | ((unsigned char*)this) | |
109 | + ROUND((sizeof (_Jv_InterpMethod) | |
110 | + exc_count*sizeof (_Jv_InterpException)), 4); | |
111 | } | |
fdae83ab | 112 | |
58eb6e7c AG |
113 | _Jv_InterpException * exceptions () |
114 | { | |
115 | return (_Jv_InterpException*) (this+1); | |
116 | } | |
117 | ||
118 | static size_t size (int exc_count, int code_length) | |
119 | { | |
120 | return | |
121 | ROUND ((sizeof (_Jv_InterpMethod) | |
122 | + (exc_count * sizeof (_Jv_InterpException))), 4) | |
123 | + code_length; | |
124 | } | |
125 | ||
126 | // return the method's invocation pointer (a stub). | |
127 | void *ncode (); | |
fdae83ab | 128 | void compile (const void * const *); |
58eb6e7c | 129 | |
7941ceab AG |
130 | static void run_normal (ffi_cif*, void*, ffi_raw*, void*); |
131 | static void run_synch_object (ffi_cif*, void*, ffi_raw*, void*); | |
132 | static void run_synch_class (ffi_cif*, void*, ffi_raw*, void*); | |
58eb6e7c | 133 | |
fdae83ab | 134 | void run (void*, ffi_raw *); |
58eb6e7c AG |
135 | |
136 | public: | |
137 | static void dump_object(jobject o); | |
138 | ||
139 | friend class _Jv_ClassReader; | |
a12fe13d | 140 | friend class _Jv_BytecodeVerifier; |
58eb6e7c AG |
141 | |
142 | friend void _Jv_PrepareClass(jclass); | |
58eb6e7c AG |
143 | }; |
144 | ||
58eb6e7c AG |
145 | class _Jv_InterpClass : public java::lang::Class |
146 | { | |
facc279f | 147 | _Jv_MethodBase **interpreted_methods; |
58eb6e7c AG |
148 | _Jv_ushort *field_initializers; |
149 | ||
150 | friend class _Jv_ClassReader; | |
151 | friend class _Jv_InterpMethod; | |
152 | friend void _Jv_PrepareClass(jclass); | |
153 | friend void _Jv_InitField (jobject, jclass, int); | |
470042c7 TT |
154 | #ifdef JV_MARKOBJ_DECL |
155 | friend JV_MARKOBJ_DECL; | |
156 | #endif | |
8ade4771 TT |
157 | |
158 | friend _Jv_MethodBase ** _Jv_GetFirstMethod (_Jv_InterpClass *klass); | |
58eb6e7c AG |
159 | }; |
160 | ||
8ade4771 TT |
161 | extern inline _Jv_MethodBase ** |
162 | _Jv_GetFirstMethod (_Jv_InterpClass *klass) | |
163 | { | |
164 | return klass->interpreted_methods; | |
165 | } | |
166 | ||
58eb6e7c AG |
167 | struct _Jv_ResolvedMethod { |
168 | jint stack_item_count; | |
169 | jint vtable_index; | |
170 | jclass klass; | |
171 | _Jv_Method* method; | |
172 | ||
173 | // a resolved method holds the cif in-line, so that _Jv_MarkObj just needs | |
174 | // to mark the resolved method to hold on to the cif. Some memory could be | |
175 | // saved by keeping a cache of cif's, since many will be the same. | |
176 | ffi_cif cif; | |
177 | ffi_type * arg_types[0]; | |
178 | }; | |
179 | ||
facc279f TT |
180 | class _Jv_JNIMethod : public _Jv_MethodBase |
181 | { | |
182 | // The underlying function. If NULL we have to look for the | |
183 | // function. | |
184 | void *function; | |
185 | ||
d348bda4 TT |
186 | // This is the CIF used by the JNI function. |
187 | ffi_cif jni_cif; | |
188 | ||
189 | // These are the argument types used by the JNI function. | |
190 | ffi_type **jni_arg_types; | |
191 | ||
facc279f TT |
192 | // This function is used when making a JNI call from the interpreter. |
193 | static void call (ffi_cif *, void *, ffi_raw *, void *); | |
194 | ||
195 | void *ncode (); | |
196 | ||
197 | friend class _Jv_ClassReader; | |
198 | friend void _Jv_PrepareClass(jclass); | |
8ade4771 TT |
199 | |
200 | public: | |
201 | // FIXME: this is ugly. | |
202 | void set_function (void *f) | |
203 | { | |
204 | function = f; | |
205 | } | |
facc279f TT |
206 | }; |
207 | ||
f39b788a TT |
208 | #endif /* INTERPRETER */ |
209 | ||
58eb6e7c | 210 | #endif /* __JAVA_INTERP_H__ */ |