File: NOTES

package info (click to toggle)
bock 0.20.2.1
  • links: PTS
  • area: main
  • in suites: woody
  • size: 1,228 kB
  • ctags: 1,370
  • sloc: ansic: 7,367; java: 5,553; yacc: 963; lex: 392; makefile: 243; sh: 90; perl: 42
file content (175 lines) | stat: -rw-r--r-- 7,395 bytes parent folder | download | duplicates (3)
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
A few notes to myself...

----------------------------------------------------------------------

typedecl:

  public, abstract, final and interface are meaningful.

  protected is used as a scratch flag to tell whether the type has been
  processed on this run through.

  native is used to indicate that there aren't any non-overriding,
  non-static methods in the type.

----------------------------------------------------------------------

Names in the C output file are of the form "Java<kind>_<id>", where
<kind> = ia*  Instance structure tag (number of 'a's = level of array nesting)
              <id> = <package>_<class>
       = m    Class jump-struct tag
              <id> = <package>_<class>
       = mia* Instantiation of class jump-struct
              <id> = <package>_<class>
       = sf   Class field
              <id> = <package>_<class>_<fieldname>
       = coa* Prefabricated class object
              <id> = <package>_<class>
       = c    Constructor
              <id> = <package>_<class>__<argtypes>
       = si   Static initialiser
              <id> = <package>_<class>
       =      (nothing) Class or instance method
              <id> = <package>_<class>_<methodname>__<argtypes>

Arrays are supported by one of each of these shared between all arrays:
  Javama      Array jump-struct tag
  Javamia     Instantiation of array jump-struct
  Javaa_clone Clone method for array classes

Actually, that isn't true; because the jump-struct contains a pointer
to the class object, we must instantiate the jump-struct once per array
type.  All array types use Javam_java_lang_Object as the type of their
jump-struct, because they don't have any methods specific to themselves.
So, Javam_java_lang_Object is the jump-struct tag for all array types,
but the instantiations are Javamia_pkg_Class, Javamiabool, etc.

Also:
  Java(m)i(a*)bool, Java(m)i(a*)byte, ...
              Instance structure tag / jump-struct instantiation for
              arrays with primitive element type

<argtypes> follows the form used in the .class file format, escaped as
per JNI.

----------------------------------------------------------------------

The 'this' argument to each instance method is of type java.lang.Object,
so as not to unnecessarily complicate the implementation of interfaces.

Narrowing reference conversions are just a struct member access:
  struct typea { ... } *vara;
  struct typeb { struct typea super; ... } *varb;

  ...

  vara = &(varb->super)

Widening reference conversions involve some complex and nonstandard,
but hopefully fairly portable, pointer arithmetic.  We assume that all
other type sizes and offsets can be represented in units of sizeof(char).

  ... check that the widening is valid ...
  varb = (struct typeb *) (((char *) vara)
                           - ( ( (char *) &(((struct typeb *) 0)->super) )
                               - (char *) 0) );

In practice, this will be equivalent to a simple cast between pointer
types.  If there's padding at the beginning of the struct, though,
the above code should correctly offset the new pointer to take this
into account.

When adding garbage collection, it will probably be necessary to revert
to using plain casts between pointer types, and adding code to the C
initialisation section to check that there is no padding at the start
of any struct.

[Additional: I recently discovered that the C standard prohibits a
 compiler from placing padding at the start of a struct, or reordering
 a struct's members.  This means that it should be perfectly all right
 to revert to using plain casts without any additional checks.]

----------------------------------------------------------------------

The parse tree undergoes a fair bit of processing.  Here's some
documentation on the stmt and expr parts of the tree:

struct stmt contains:
  tag: says what kind of statement this is
  var: for variable declarations, the type, the names declared, and the
       corresponding initialisers.
  expr: an expression, or list of expressions
  stmt[1234]: sub-statements
  catch: for a try statement, a list of catchclauses
  rest: the next statement in the block

The statements in a block are chained in the correct order through their
'rest' pointers.  This is in contrast to all the other linked lists in the
tree, which are, as a rule, built in reverse order and not subsequently
fixed up.

Tags are:
  Localvar: 'var' indicates what variables are defined
  If: if 'expr' is true, execute 'stmt1', otherwise execute 'stmt2'
  While: while 'expr' is true, execute 'stmt1'
  For: execute 'stmt1' first, then, while 'expr' is true, execute the
       block 'stmt3', then the update statement 'stmt2'.  'stmt1' and
       'stmt2' are NO LONGER in reverse execution order!
  Block: execute the block 'stmt1'
  Empty: No-op
  Exprstmt: evaluate 'expr'
  Switch: evaluate 'expr', then jump to the appropriate Case in 'stmt1'
  Case: 'expr' is the label
  Default: no content
  Do: execute 'stmt1' until 'expr' is false
  Break, Cont: no content
  Return: return from method.  If 'expr' != null, return its value.
  Throw: throws 'expr'
  Try: execute block 'stmt1', handle exceptions using 'catch' clauses,
       if any, then execute finaliser 'stmt2'.

struct expr contains:
  tag: says what kind of expr this is
  exp[123]: subexpressions of ths expression
  type: this expression's type
  name: 
  integ: 
  str: 
  rest: the next expression in a list

Tags are:
  Prim: unused
  NullString: the value of 'exp1', unless it is null, in which case "null".
  Localacc: access local variable 'str'
  This, Nulllit: no data
  Intlit, Longlit, Boollit, Charlit: literal value 'integ'
  Stringlit: literal value 'str', or string pool index 'integ'
  Floatlit, Doublit: literal; value not currently stored.
  New: create a new object of type 'type'.  If it's an array, the
       dimension exprs are 'exp1'.  Otherwise, the constructor args are
       'exp2'.
  Primfield: access the field named by 'str' in expression 'exp1'
  Meth: call method 'str' of 'exp1', with arguments 'exp2'.  'integ' is
        0 for instance methods, 1 for static methods.
  Super: call superclass method named 'str' with arguments 'exp2' if
         'integ' is 0, otherwise access superclass field 'str'
  Array: index by 'exp2' into array 'exp1'
  Name: any ExpressionName is initially parsed to this type of expr,
        the ExpressionName being placed in 'name'.  A later stage of
        processing turns most ExpressionNames into other kinds of exprs;
        the only ones being left as Names are TypeNames.
  Postinc, Postdec: 'exp1' ++ --
  Plus, Minus, Preinc, Predec, Comp, Not: + - ++ -- ~ ! 'exp1'
  Cast: convert 'exp1' to type 'type'
  Mult, Div, Rem, Add, Sub, Lshift, Rshift, Urshift, Lt, Gt, Leq, Geq: 
        'exp1' * / % + - << >> >>> < > <= >= 'exp2'
  Inst: 'exp1' instanceof 'type'.  The name from 'type' is stashed in
        'name' when the type decorator fills in 'type'.
  Eq, Neq, And, Xor, Or, Condand, Condor: relational operators:
        'exp1' == != & ^ | && || 'exp2'
  Cond: exp1 ? exp2 : exp3
  Assign: evaluate 'exp2' then assign the result to 'exp1'
  Multass, Divass, Remass, Addass, Subass, Lshiftass, Rshiftass,
    Urshiftass, Andass, Xorass, Orass: same, but combined with an operator
  Arrayinit: create an array from the list of expressions 'exp1', whose
    length is `integ'.