History

Added another (currently unchecked) module, updated TODO

Dmitry Kabak (userdima committed 13 years ago

Commit 11b71951 parent 87f5efe3 files · +483 −1Browse files

Showing the changes to java (2 of 3 files). Show all

Unified · Split

2 files
  1. java/pkg/java/lang/Thread_L.b +455 −0
  2. java/pkg/java/lang/Thread_L.m +21 −0
java/pkg/java/lang/Thread_L.b+455−0
@@ -0,0 +1,455 @@
1implement Thread_L;
2
3# javal v1.3 generated file: edit with care
4
5include "jni.m";
6 jni : JNI;
7 ClassModule,
8 JString,
9 JArray,
10 JArrayI,
11 JArrayC,
12 JArrayB,
13 JArrayS,
14 JArrayJ,
15 JArrayF,
16 JArrayD,
17 JArrayZ,
18 JArrayJObject,
19 JArrayJClass,
20 JArrayJString,
21 JClass,
22 JThread,
23 JObject : import jni;
24
25#>> extra pre includes here
26
27#<<
28
29include "Thread_L.m";
30
31#>> extra post includes here
32
33sys : Sys;
34jldr : JavaClassLoader;
35cast : Cast;
36
37# following used for calling Thread.run()
38threadclass : JNI->ClassData; #class data for java.lang.Thread
39thread_run_idx : int; #method index for Thread.run()
40thread_exit_idx : int; #method index for Thread.exit()
41
42# some imports
43ThreadData : import jldr;
44
45#<<
46
47init( jni_p : JNI )
48{
49 # save java native inteface mod instance
50 jni = jni_p;
51 #>>extra initialization here
52
53 sys = jni->sys;
54 jldr = jni->jldr;
55 cast = jni->CastMod();
56
57 threadclass = jni->FindClass( "java.lang.Thread" );
58 if ( threadclass == nil )
59 jni->InitError( "Thread_L.init(): could not get thread class" );
60
61 Class : import jldr;
62 thread_run_idx = threadclass.findvmethod( "run", "()V" );
63 if ( thread_run_idx == -1 )
64 jni->InitError( "Thread_L.init(): could not locate Thread.run()" );
65
66 #thread_exit_idx = threadclass.findvmethod( "exit", "()V" );
67 #if ( exit_idx == -1 )
68 # jni->InitError( "Thread_L.init(): could not locate Thread.exit()" );
69 #<<
70}
71
72currentThread_rThread( ) : JThread
73{#>>
74 e := ref Sys->Exception;
75 if ( sys->rescue("*",e) == Sys->HANDLER )
76 {
77 # get the java thread object assocciated
78 # with this thread. it is stored in the
79 # class loader's thread structure.
80 thd_obj := jldr->getthreaddata().this;
81 if ( thd_obj != nil )
82 return( cast->JObjToJThd(thd_obj) );
83 sys->unrescue();
84 }
85 else
86 sys->rescued(Sys->ONCE, nil);
87
88
89 # either we could not find the thread data
90 # or no "Thread" object was stored in it
91 # either way we are in bad shape
92 jni->FatalError( "could not get thread object" );
93
94 return(nil);
95}#<<
96
97yield_V( )
98{#>>
99 jni->sys->sleep(0);
100}#<<
101
102sleep_J_V( p0 : big)
103{#>>
104 millis := int p0;
105
106 if ( millis < 1 )
107 {
108 if ( millis == 0 )
109 {
110 # just yield thread
111 jni->sys->sleep(0);
112 return;
113 }
114
115 # bad sleep value
116 jni->ThrowException( "java.lang.IllegalArgumentException", "timeout value is negative" );
117 }
118 jldr->sleep( millis );
119}#<<
120
121start_V( this : JThread)
122{#>>
123 thdobj := cast->JThdToJObj(this);
124
125 # grab the lock on the thread object to ensure
126 # no state is changed while we are starting the
127 # thread.
128# jni->MonitorEnter( thdobj );
129
130 if ( (this.stillborn == byte 0) && (this.PrivateInfo == nil) )
131 {
132 # spawn a limbo fct as the java
133 # thread's starting point.
134 ok := chan of int;
135 spawn javathreadinit( this, ok );
136
137 # wait for thread to init then we can
138 # continue. Note we hold a lock and
139 # the thread will change some state
140 # and notify us before the java run()
141 # method is invoked. The purpose is to
142 # allow for state information to be updated
143 # while we have the lock.
144 status := <- ok;
145
146 #status == 0 is an err
147 # == 1 is ok
148
149 if ( status == 0 )
150 {
151 this.stillborn = byte 1;
152 this.PrivateInfo = nil;
153 }
154
155 }
156# jni->MonitorExit( thdobj );
157}#<<
158
159isInterrupted_Z_Z( this : JThread, p0 : int) : int
160{#>>
161 old_flag := int this.was_interrupted;
162
163 if ( old_flag )
164 this.was_interrupted = byte p0;
165 return( old_flag );
166}#<<
167
168isAlive_Z( this : JThread) : int
169{#>>
170 thd := this.PrivateInfo;
171 if ( (this.stillborn == byte 0) && (thd != nil) )
172 {
173 # JLS does not require that we actually determine
174 # the "os" thread is alive, just that the object
175 # state indicates it is
176 return( JNI->TRUE );
177 }
178
179 # looks like thread is not alive
180 return( jni->FALSE );
181}#<<
182
183countStackFrames_I( this : JThread) : int
184{#>>
185 junk := this;
186 # need to do some /prog work
187 return( 0 );
188}#<<
189
190setPriority0_I_V( this : JThread, p0 : int)
191{#>>
192 # just save the priority, a dis thread
193 # has no priority
194 this.priority = p0;
195}#<<
196
197stop0_rObject_V( this : JThread, p0 : JObject)
198{#>>
199 # the calling thread is attempting to throw an
200 # exception at "this" thread (i.e. the one represented
201 # by this thread object. make sure that thread at least
202 # appears to be running and throw the exceptio at it
203
204 thd := this.PrivateInfo;
205 stillborn := this.stillborn;
206
207 # prevent a start or re-start
208 this.stillborn = byte 1;
209
210 if ( (stillborn == byte 0) && (thd != nil) )
211 {
212 # throw the exception (p0) at the thread
213 jldr->stop( thd, p0 );
214 }
215
216}#<<
217
218suspend0_V( this : JThread)
219{#>>
220 # the calling thread wants to suspend
221 # the "this" thread.
222 thd := this.PrivateInfo;
223 if ( (this.stillborn == byte 0) && (thd != nil) )
224 jldr->suspend( thd );
225
226}#<<
227
228resume0_V( this : JThread)
229{#>>
230 # the calling thread wants to resume
231 # the "this" thread.
232 thd := this.PrivateInfo;
233 if ( (this.stillborn == byte 0) && (thd != nil) )
234 jldr->resume( thd );
235}#<<
236
237interrupt0_V( this : JThread)
238{#>>
239 # the calling thread wants to interrupt
240 # the "this" thread.
241 thd := this.PrivateInfo;
242 if ( (this.stillborn == byte 0) && (thd != nil) )
243 jldr->interrupt( thd );
244}#<<
245
246lowinit_rThread_V( p0 : JThread)
247{#>>
248 # this fct is called once during the static init of the
249 # java.lang.Thread object. 'p0' is the "root thread" object
250 # which must be associated witht the Dis thread which is
251 # calling this fuction -- i.e. associate the 'p0' java thread
252 # object with the current Dis thread. 'p1' is the same thread
253 # object, just with the type JObject which allows us to store
254 # it off in the JavaClassLoader->ThreadData structure associated
255 # with the calling Dis thread.
256
257 # since this is the root thread make a root thread group by
258 # creating an instance of ThreadGroup and calling its private
259 # default constructor.
260 thd_grp_cl := jni->FindClass( "java.lang.ThreadGroup" );
261 if ( thd_grp_cl == nil )
262 jni->FatalError( "could not obtain ThreadGroup class" );
263
264 thd_grp := jni->NewObject( thd_grp_cl );
265 if ( thd_grp == nil )
266 jni->FatalError( "could not created root threadgroup" );
267 p0.group = thd_grp;
268
269 # get the ThreadData structure for the calling thread
270 thd := jldr->getthreaddata();
271 thd.this = cast->JThdToJObj(p0); # save java object in thread data
272 p0.PrivateInfo = thd; # save thread data in java object
273
274}#<<
275
276
277
278
279
280##### private functions used by the Thread_L module
281
282#
283# this function is the first function of all java
284# threads, except for the first thread which is
285# controlled by the JavaClassLoader module.
286#
287# jthd : the Java thread object associated with this
288# Dis thread.
289#
290# ok : use this channel to notify "spawner" that
291# we are under-way. send 0==fail; 1==ok
292#
293javathreadinit( jthd : JNI->JThread, ok : chan of int )
294{
295 # create a JavaClassLoader->ThreadData structure
296 # and "register" it with the class loader.
297
298 thd := jldr->getthreaddata();
299
300 if ( thd.this != nil )
301 {
302 # this should be nil, else the java thread
303 # already is set for this Dis thread and we
304 # are in some screwed-up state.
305 ok <-= 0;
306 return;
307 }
308
309 # now fill in the java thread obj (after
310 # the putthreaddata so any init is not affected
311 thdobj := cast->JThdToJObj( jthd );
312 thd.this = thdobj;
313
314 # now save the ThreadData in the java object in order
315 # to allow a lookup from the other diretion
316 jthd.PrivateInfo = thd;
317
318 # set our daemon thread status
319 if ( jthd.daemon == JNI->BTRUE )
320 jldr->daemonize();
321
322 # notify spawner we are under-way
323 ok <- = 1;
324
325 # we need to catch any exceptions in order
326 # to clean up the thread object's state
327 ee := ref Sys->Exception;
328 if ( sys->rescue( "*", ee ) == Sys->HANDLER )
329 {
330
331 # call Thread.run() or Runnable.run()
332 Run( jthd, thdobj );
333
334 # call Thread.exit()
335 (mod,idx) := jni->FindMethod( threadclass, "exit", "()V", JNI->METH_PRIVATE );
336 jni->jassist->mcall1( mod, idx, thdobj );
337 sys->unrescue();
338 }
339 else
340 {
341 # clear exception
342 sys->rescued( Sys->ONCE, nil );
343
344 # thread threw an unhandled exception so
345 # call the ThreadGroup.uncaughtException()
346 # method.
347 UncaughtException( jthd, thdobj, ee );
348 }
349
350 # java thread clean up
351
352 jni->jldr->monitorenter( thdobj ); ##LOCK thread object
353 {
354
355 jthd.stillborn = byte 1; # prevent re-run
356
357 # notify ALL "waiters" (which includes any Thread.join()'s)
358 jni->jldr->monitornotify( thdobj, 1 );
359 }
360 jni->jldr->monitorexit( thdobj ); ##UNLOCK thread object
361
362 # clean up thread structures
363 jldr->delthreaddata();
364 thd.this = nil;
365 jthd.PrivateInfo = nil;
366}
367
368
369#
370# if the thread object contains a "registered" Runnable
371# object then execute that Runnable's run() method, else
372# execute the Thread's run() method (which should be
373# overridden.
374#
375Run( jthd : JNI->JThread, thdobj : JObject )
376{
377 Class : import jldr;
378 class : JNI->ClassData;
379 run_idx := thread_run_idx; #default to Thread.run()
380 obj := thdobj; #this obj for run() call
381
382 if ( jthd.target != nil )
383 {
384 # the thread has a registered Runnable
385 # object, find its run() method
386 class = jni->GetObjectClassData( jthd.target );
387 run_idx = class.findvmethod( "run", "()V" );
388 if ( run_idx == -1 )
389 return;
390 obj = jthd.target; #set 'this' to the runnable obj
391 }
392 else
393 {
394 # use the thread object's run()
395 class = jni->GetObjectClassData(thdobj);
396 }
397
398 run_method := class.virtualmethods[run_idx];
399
400 # do the run()
401 jni->jassist->mcall1( run_method.class.mod, run_method.field.value, obj );
402}
403
404#
405# If the thread's ThreadGroup is a subclass of java.lang.ThreadGroup
406# then invoke that class'es "uncaughtException" method. This
407# method is called whenever a thread does not handle an exception.
408# The method is passed an instance of the Thread along with the
409# "throwable" (i.e. exception).
410#
411UncaughtException( jthd : JThread, thdobj : JObject, ee : ref Sys->Exception )
412{
413 tgrp_cl := jni->GetObjectClassData( jthd.group );
414
415 #
416 # if the thread group is the default thread group
417 # class, then we will handle the excepition here
418 # which is to simply do nothing.
419 #
420 if ( tgrp_cl.name != "java/lang/ThreadGroup" )
421 {
422 # call method, protected against exceptions
423 # since we must still clean-up the thread
424 eee := ref Sys->Exception;
425 if ( sys->rescue( "*", eee ) == Sys->HANDLER )
426 {
427 # find the uncaughtException method for the thd-grp
428 (mod,idx) := jni->FindMethod( tgrp_cl, "uncaughtException",
429 "(Ljava.lang.Thread;Ljava.lang.Throwable;)V",
430 JNI->METH_VIRTUAL );
431 if ( mod != nil )
432 {
433 # call the uncaughException handler
434 Value : import jni;
435 args := array[] of
436 {
437 ref Value.TObject(thdobj), #the thread
438 ref Value.TObject(jldr->culprit(ee)) #the exception
439 };
440
441 # do the call
442 ##LATER nil := jni->LowCall( mod, idx, jthd.group, args );
443 }
444 sys->unrescue();
445 }
446 else
447 {
448 # if we get an exception here just return
449 # and let the thread finish cleanup.
450 sys->rescued( Sys->ONCE, nil );
451 }
452 }
453
454}
455
java/pkg/java/lang/Thread_L.m+21−0
@@ -0,0 +1,21 @@
1# javal v1.3 generated file: edit with care
2
3Thread_L : module
4{
5
6 init : fn( jni_p : JNI );
7 currentThread_rThread : fn( ) : JThread;
8 yield_V : fn( );
9 sleep_J_V : fn( p0 : big);
10 start_V : fn( this : JThread);
11 isInterrupted_Z_Z : fn( this : JThread, p0 : int) : int;
12 isAlive_Z : fn( this : JThread) : int;
13 countStackFrames_I : fn( this : JThread) : int;
14 setPriority0_I_V : fn( this : JThread, p0 : int);
15 stop0_rObject_V : fn( this : JThread, p0 : JObject);
16 suspend0_V : fn( this : JThread);
17 resume0_V : fn( this : JThread);
18 interrupt0_V : fn( this : JThread);
19 lowinit_rThread_V : fn( p0 : JThread);
20
21};