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 @@
1+implement Thread_L;
2+
3+# javal v1.3 generated file: edit with care
4+
5+include "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+
29+include "Thread_L.m";
30+
31+#>> extra post includes here
32+
33+sys : Sys;
34+jldr : JavaClassLoader;
35+cast : Cast;
36+
37+# following used for calling Thread.run()
38+threadclass : JNI->ClassData; #class data for java.lang.Thread
39+thread_run_idx : int; #method index for Thread.run()
40+thread_exit_idx : int; #method index for Thread.exit()
41+
42+# some imports
43+ThreadData : import jldr;
44+
45+#<<
46+
47+init( 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+
72+currentThread_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+
97+yield_V( )
98+{#>>
99+ jni->sys->sleep(0);
100+}#<<
101+
102+sleep_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+
121+start_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+
159+isInterrupted_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+
168+isAlive_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+
183+countStackFrames_I( this : JThread) : int
184+{#>>
185+ junk := this;
186+ # need to do some /prog work
187+ return( 0 );
188+}#<<
189+
190+setPriority0_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+
197+stop0_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+
218+suspend0_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+
228+resume0_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+
237+interrupt0_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+
246+lowinit_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+#
293+javathreadinit( 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+#
375+Run( 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+#
411+UncaughtException( 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+
3+Thread_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+};