forked from ppedemon/hava
-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathClassInit.hs
67 lines (55 loc) · 2.04 KB
/
ClassInit.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
module ClassInit(initialize) where
import List(find)
import MA
import VMStack
import VMMonad
import ClassRep
import {-# SOURCE #-} VM
{--------------------------------------------------------------------
Class initialization routines:
This is a fake initialization: any exception thrown during it
and not catched, doesn't get propagated outside the initialization
context.
Anyway, the most probable thing to happen when some init error
arises, is that your are doomed. So this is quite acceptable.
Moreover, this initialization procedure works only in a single
threaded JVM. With multiple threads accessign concurrently the
method area, we should be a lot more careful.
--------------------------------------------------------------------}
initialize :: MAIx -> VM_ ()
initialize ix =
do c <- vmgetClass ix
case getState c of
Init -> return ()
InProgress -> return ()
UnInit -> do vmsetClassState ix InProgress
case getSuper c of
N -> return ()
S s -> initialize s
primInitialize ix
vmsetClassState ix Init
vmsetClassState :: MAIx -> CStat -> VM_ ()
vmsetClassState ix st =
do c <- vmgetClass ix
vmreplaceClass ix (setState st c)
clinitMethod :: Class -> Maybe MInfo
clinitMethod c =
let ms = getStaticMethods c
in find (\m -> elemName m == "<clinit>" && elemDesc m == "()V") ms
installStack :: Stack -> VM_ Stack
installStack s = do vm <- getS
let old_s = vmgetStack vm
setS (vmsetStack vm s)
return old_s
primInitialize :: MAIx -> VM_ ()
primInitialize ix =
do c <- vmgetClass ix
case clinitMethod c of
Nothing -> return ()
Just m ->
do vm <- getS
old_s <- installStack newStack
vminvoke ix m []
vmloop
installStack old_s
return ()