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 | +}; | |