Showing the changes to java (2 of 3 files). Show all
Unified · Split
| @@ -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 | |||
| @@ -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 | }; | ||