Skip to content

Commit 2bebc0e

Browse files
author
Nicolas Barré
authored
Java 9 compatibility (#9)
* Java 9 changes - ConstantModule - ConstantPackage - Tested successfully with openjdk11 (all modules) * Stackmap format - reverting to low level format for correctness - fixes class loading bug after unparsing * Bugfix in JParseSignature - correcting stupid bug with classes starting by 'L' which where not in a package the correction is just one line deletion in jParseSignature.ml * JFile - sep is now a char instead of a string of length 1 * Permissive - if JBasics.get_permissive() is true, we allow a class that is neither a module nor Object to have no superclass * More java tests for invokedynamic instruction
1 parent 33cffee commit 2bebc0e

34 files changed

+346
-171
lines changed

.travis-setup.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ then
66
sudo apt-get update
77
sudo apt-get install opam
88
else
9-
brew install opam ocaml camlp4
9+
brew install opam ocaml camlp4
1010
export OCAML_VERSION="system"
1111
fi
1212

.travis.sh

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
echo "Working on branch" $TRAVIS_BRANCH
22

3-
OPAM_DEPENDS="ocamlfind camlzip extlib camomile"
3+
OPAM_DEPENDS="ocamlfind camlzip extlib"
44

5+
opam switch create $OCAML_VERSION
56
opam switch $OCAML_VERSION
67
eval `opam config env`
78

.travis.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@ matrix:
1010
dist: trusty
1111
sudo: required
1212
env :
13-
- OCAML_VERSION=4.02.3
13+
- OCAML_VERSION=4.07.0
1414
- os: linux
1515
dist: trusty
1616
sudo: required
1717
env :
18-
- OCAML_VERSION=4.07.0
18+
- OCAML_VERSION=4.08.0
1919
- os: osx
2020

2121
notifications:

javalib.opam

+1-2
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,12 @@ build: [
1414
install: [make "install"]
1515
remove: ["ocamlfind" "remove" "javalib"]
1616
depends: [
17-
"ocaml" {>= "4.02"}
17+
"ocaml" {>= "4.04"}
1818
"conf-which" {build}
1919
"ocamlfind" {build}
2020
"camlzip" {>= "1.05"}
2121
"camlp4"
2222
"extlib"
23-
"camomile"
2423
]
2524

2625
synopsis: "Javalib is a library written in OCaml with the aim to provide a high level representation of Java .class files"

src/jBasics.ml

+10-1
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,8 @@ type constant =
163163
| ConstInvokeDynamic of bootstrap_method_index * method_signature
164164
| ConstNameAndType of string * descriptor
165165
| ConstStringUTF8 of string
166+
| ConstModule of string
167+
| ConstPackage of string
166168
| ConstUnusable
167169

168170
(* Stackmap type. *)
@@ -177,7 +179,14 @@ type verification_type =
177179
| VObject of object_type
178180
| VUninitialized of int (* creation point *)
179181

180-
type stackmap = (int * verification_type list * verification_type list)
182+
type stackmap_frame =
183+
| SameFrame of int
184+
| SameLocals of int * verification_type
185+
| SameLocalsExtended of int * int * verification_type
186+
| ChopFrame of int * int
187+
| SameFrameExtended of int * int
188+
| AppendFrame of int * int * verification_type list
189+
| FullFrame of int * int * verification_type list * verification_type list
181190

182191
type version = {major :int; minor:int;}
183192

src/jBasics.mli

+10-1
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,8 @@ type constant =
325325
| ConstInvokeDynamic of bootstrap_method_index * method_signature
326326
| ConstNameAndType of string * descriptor
327327
| ConstStringUTF8 of string
328+
| ConstModule of string
329+
| ConstPackage of string
328330
| ConstUnusable
329331

330332
(** {1 Stackmaps} *)
@@ -342,7 +344,14 @@ type verification_type =
342344
| VUninitialized of int (** creation point *)
343345

344346
(** Stackmap type. *)
345-
type stackmap = (int* verification_type list * verification_type list)
347+
type stackmap_frame =
348+
| SameFrame of int
349+
| SameLocals of int * verification_type
350+
| SameLocalsExtended of int * int * verification_type
351+
| ChopFrame of int * int
352+
| SameFrameExtended of int * int
353+
| AppendFrame of int * int * verification_type list
354+
| FullFrame of int * int * verification_type list * verification_type list
346355

347356
(** {1 Errors} *)
348357

src/jClassLow.mli

+2-11
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,7 @@ type class_flag = [
219219
| `AccEnum
220220
| `AccInterface
221221
| `AccSuper
222+
| `AccModule
222223
]
223224

224225
type access_flag = [
@@ -238,19 +239,9 @@ type access_flag = [
238239
| `AccVarArgs
239240
| `AccAnnotation
240241
| `AccEnum
242+
| `AccModule
241243
]
242244

243-
244-
(** DFr : Addition for 1.6 stackmap. *)
245-
type stackmap_frame =
246-
| SameFrame of int
247-
| SameLocals of int * verification_type
248-
| SameLocalsExtended of int * int * verification_type
249-
| ChopFrame of int * int
250-
| SameFrameExtended of int * int
251-
| AppendFrame of int * int * verification_type list
252-
| FullFrame of int * int * verification_type list * verification_type list
253-
254245
type mp_flags = [ `AccFinal | `AccSynthetic | `AccMandated | `AccRFU of int ]
255246

256247
type method_parameters = {

src/jCode.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ type jcode = {
163163
c_line_number_table : (int * int) list option;
164164
c_local_variable_table : (int * int * string * value_type * int) list option;
165165
c_local_variable_type_table : (int * int * string * JSignature.fieldTypeSignature * int) list option;
166-
c_stack_map : stackmap list option;
166+
c_stack_map : stackmap_frame list option;
167167
c_attributes : (string * string) list;
168168
}
169169

src/jCode.mli

+1-1
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ type jcode = {
200200
(** (start_pc, length, name, type, index) *)
201201
c_local_variable_type_table : (int * int * string * JSignature.fieldTypeSignature * int) list option;
202202
(** LocalVariableTable for generics, described in the JVM Spec se8, §4.7.14 *)
203-
c_stack_map : stackmap list option;
203+
c_stack_map : stackmap_frame list option;
204204
c_attributes : (string * string) list;
205205
}
206206

src/jDumpBasics.ml

+30-5
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,8 @@ let rec dump_constant ch = function
174174
JLib.IO.printf ch "invoke-dynamic : %d %s"
175175
bmi
176176
(ms_name ms)
177+
| ConstModule s -> JLib.IO.printf ch "module %s" s
178+
| ConstPackage s -> JLib.IO.printf ch "package %s" s
177179

178180
let dump_bootstrap_argument ch = function
179181
| `String s -> dump_constant ch (ConstString s)
@@ -216,11 +218,34 @@ let dump_verification_type = function
216218
| VObject c -> sprintf "Object %s" (object_value_signature c)
217219
| VUninitialized off -> sprintf "Uninitialized %d" off
218220

219-
let dump_stackmap ch (offset,locals,stack) =
220-
JLib.IO.printf ch "\n offset=%d,\n locals=[" offset;
221-
List.iter (fun t -> JLib.IO.printf ch "\n %s" (dump_verification_type t)) locals;
222-
JLib.IO.printf ch "],\n stack=[";
223-
List.iter (fun t -> JLib.IO.printf ch "\n %s" (dump_verification_type t)) stack
221+
(* let dump_stackmap ch (offset,locals,stack) =
222+
* JLib.IO.printf ch "\n offset=%d,\n locals=[" offset;
223+
* List.iter (fun t -> JLib.IO.printf ch "\n %s" (dump_verification_type t)) locals;
224+
* JLib.IO.printf ch "],\n stack=[";
225+
* List.iter (fun t -> JLib.IO.printf ch "\n %s" (dump_verification_type t)) stack *)
226+
227+
let dump_stackmap ch frame =
228+
match frame with
229+
| SameFrame k -> JLib.IO.printf ch "SameFrame(tag:%d)\n" k
230+
| SameLocals (k,vtype) ->
231+
JLib.IO.printf ch "SameLocals(tag:%d,%s)\n" k (dump_verification_type vtype)
232+
| SameLocalsExtended (k,i,vtype) ->
233+
JLib.IO.printf ch "SameLocalsExtended(tag:%d,%d,%s)\n"
234+
k i (dump_verification_type vtype)
235+
| ChopFrame (k,i) ->
236+
JLib.IO.printf ch "ChopFrame(tag:%d,%d)\n" k i
237+
| SameFrameExtended (k,i) ->
238+
JLib.IO.printf ch "SameFrameExtended(tag:%d,%d)\n" k i
239+
| AppendFrame (k,i,vtypes) ->
240+
let svtypes = String.concat "," (List.map dump_verification_type vtypes) in
241+
JLib.IO.printf ch "AppendFrame(tag:%d,%d,%s)\n" k i svtypes
242+
| FullFrame (k,offset,locals,stack) ->
243+
JLib.IO.printf ch "FullFrame(tag:%d," k;
244+
JLib.IO.printf ch "\n offset=%d,\n locals=[" offset;
245+
List.iter (fun t -> JLib.IO.printf ch "\n %s" (dump_verification_type t)) locals;
246+
JLib.IO.printf ch "],\n stack=[";
247+
List.iter (fun t -> JLib.IO.printf ch "\n %s" (dump_verification_type t)) stack;
248+
JLib.IO.nwrite_string ch ")\n"
224249

225250
open JCode
226251

src/jDumpBasics.mli

+1-1
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ val dump_constantpool : 'a JLib.IO.output -> constant array -> unit
105105
val dump_verification_type : verification_type -> string
106106

107107
val dump_stackmap :
108-
'a JLib.IO.output -> stackmap -> unit
108+
'a JLib.IO.output -> stackmap_frame -> unit
109109
(** [dump_stackmap ch sm] prints on [ch] the stackmap [sm]. *)
110110

111111
val dump_exc : 'a JLib.IO.output -> 'b -> JCode.exception_handler -> unit

src/jDumpLow.ml

+2-19
Original file line numberDiff line numberDiff line change
@@ -198,30 +198,13 @@ let access_flags = function
198198
| `AccBridge -> "bridge"
199199
| `AccSuper -> "`AccSuper"
200200
| `AccSynthetic -> "synthetic"
201+
| `AccModule -> "module"
201202
| `AccRFU i -> Printf.sprintf "rfu 0x%X" i
202203
) flags) ^ " "
203204

204205
let string_nwrite ch s = JLib.IO.nwrite_string ch s
205206

206-
let dump_java6_stackmap ch frame =
207-
match frame with
208-
| SameFrame k -> JLib.IO.printf ch "SameFrame(tag:%d)\n" k
209-
| SameLocals (k,vtype) ->
210-
JLib.IO.printf ch "SameLocals(tag:%d,%s)\n" k (dump_verification_type vtype)
211-
| SameLocalsExtended (k,i,vtype) ->
212-
JLib.IO.printf ch "SameLocalsExtended(tag:%d,%d,%s)\n"
213-
k i (dump_verification_type vtype)
214-
| ChopFrame (k,i) ->
215-
JLib.IO.printf ch "ChopFrame(tag:%d,%d)\n" k i
216-
| SameFrameExtended (k,i) ->
217-
JLib.IO.printf ch "SameFrameExtended(tag:%d,%d)\n" k i
218-
| AppendFrame (k,i,vtypes) ->
219-
let svtypes = String.concat "," (List.map dump_verification_type vtypes) in
220-
JLib.IO.printf ch "AppendFrame(tag:%d,%d,%s)\n" k i svtypes
221-
| FullFrame (k,offset,locals,stack) ->
222-
JLib.IO.printf ch "FullFrame(tag:%d," k;
223-
dump_stackmap ch (offset,locals,stack);
224-
string_nwrite ch ")\n"
207+
let dump_java6_stackmap ch frame = dump_stackmap ch frame
225208

226209
let dump_inner_classes ch icl =
227210
List.iter

src/jFile.ml

+4-4
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ open JClassLow
2727
let sep =
2828
match Sys.os_type with
2929
| "Unix"
30-
| "Cygwin" -> ":"
31-
| "Win32" -> ";"
30+
| "Cygwin" -> ':'
31+
| "Win32" -> ';'
3232
| _ -> assert false
3333

3434
let replace_dot =
@@ -75,14 +75,14 @@ let open_path s =
7575
type directories = string list
7676

7777
let make_directories dirs =
78-
match JLib.String.nsplit dirs sep with
78+
match String.split_on_char sep dirs with
7979
| [] -> [Filename.current_dir_name]
8080
| cp ->
8181
List.filter is_dir cp
8282

8383
let class_path cp =
8484
let cp_list =
85-
match JLib.String.nsplit cp sep with
85+
match String.split_on_char sep cp with
8686
| [] -> [Filename.current_dir_name]
8787
| cp -> cp
8888
in

src/jFile.mli

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ type class_path
2929

3030
(** [sep] is the class path separator. It contains a colon (:) under
3131
Unix and Cygwin and a semi-colon (;) under Windows (or MinGW). *)
32-
val sep : string
32+
val sep : char
3333

3434
(** [class_path cp] opens a class path from the list [cp] of
3535
directories and jar (or zip) files separated by {!JFile.sep}. jar

src/jHigh2Low.ml

+1-13
Original file line numberDiff line numberDiff line change
@@ -95,19 +95,7 @@ let h2l_inner_classes = function
9595
in
9696
[AttributeInnerClasses (List.rev_map h2l_ic icl)]
9797

98-
(* This function only build full frames. We don't try to compress the stackmap
99-
information like javac. *)
100-
let h2l_stackmap_table sm : stackmap_frame list =
101-
let (_,table) =
102-
List.fold_left
103-
(fun (last,table) (pc,lv,sv) ->
104-
if (last = 0) then
105-
(pc,FullFrame(255,pc,lv,sv)::table)
106-
else
107-
let offset_delta = pc - last - 1 in
108-
(pc,FullFrame(255,offset_delta,lv,sv)::table)
109-
) (0,[]) sm in
110-
List.rev table
98+
let h2l_stackmap_table sm : stackmap_frame list = sm
11199

112100
let h2l_code2attribute consts bm_table = function
113101
| Native -> []

src/jLow2High.ml

+5-40
Original file line numberDiff line numberDiff line change
@@ -96,44 +96,7 @@ let low2high_attributes consts (al:JClassLow.attribute list) :attributes =
9696
al);
9797
}
9898

99-
let expanse_stackmap_table stackmap_table =
100-
let (_,stackmap) =
101-
List.fold_left
102-
(fun ((pc,l,_),stackmap) frame ->
103-
match frame with
104-
| SameFrame k ->
105-
let offset = pc + k + 1 in
106-
let s = (offset,l,[]) in
107-
(s,s::stackmap)
108-
| SameLocals (k,vtype) ->
109-
let offset = pc + k - 64 + 1 in
110-
let s = (offset,l,[vtype]) in
111-
(s,s::stackmap)
112-
| SameLocalsExtended (_,offset_delta,vtype) ->
113-
let offset = pc + offset_delta + 1 in
114-
let s = (offset,l,[vtype]) in
115-
(s,s::stackmap)
116-
| ChopFrame (k,offset_delta) ->
117-
let offset = pc + offset_delta + 1 in
118-
let nb_chop = 251 - k in
119-
let l_chop = List.rev
120-
(JLib.List.drop nb_chop (List.rev l)) in
121-
let s = (offset,l_chop,[]) in
122-
(s,s::stackmap)
123-
| SameFrameExtended (_,offset_delta) ->
124-
let offset = pc + offset_delta + 1 in
125-
let s = (offset,l,[]) in
126-
(s,s::stackmap)
127-
| AppendFrame (_,offset_delta,vtype_list) ->
128-
let offset = pc + offset_delta + 1 in
129-
let s = (offset,l@vtype_list,[]) in
130-
(s,s::stackmap)
131-
| FullFrame (_,offset_delta,lv,sv) ->
132-
let offset = pc + offset_delta + 1 in
133-
let s = (offset,lv,sv) in
134-
(s,s::stackmap)
135-
) ((-1,[],[]),[]) stackmap_table in
136-
List.rev stackmap
99+
let expanse_stackmap_table stackmap_table = stackmap_table
137100

138101
let low2high_code consts bootstrap_methods = function c ->
139102
{
@@ -801,8 +764,6 @@ let low2high_innerclass = function
801764
}
802765

803766
let low2high_class cl =
804-
if cl.j_super = None && cl.j_name <> JBasics.java_lang_object
805-
then raise (Class_structure_error "Only java.lang.Object is allowed not to have a super-class.");
806767
let flags = cl.j_flags in
807768
let (access,flags) = flags2access (flags :> access_flag list) in
808769
let (accsuper,flags) = get_flag `AccSuper flags in
@@ -812,6 +773,10 @@ let low2high_class cl =
812773
let (is_synthetic,flags) = get_flag `AccSynthetic flags in
813774
let (is_annotation,flags) = get_flag `AccAnnotation flags in
814775
let (is_enum,flags) = get_flag `AccEnum flags in
776+
let (is_module,flags) = get_flag `AccModule flags in
777+
if not (JBasics.get_permissive ()) &&
778+
cl.j_super = None && cl.j_name <> JBasics.java_lang_object && not is_module
779+
then raise (Class_structure_error "Only java.lang.Object is allowed not to have a super-class.");
815780
let flags =
816781
List.map
817782
(function

src/jManifest.mll

+2-2
Original file line numberDiff line numberDiff line change
@@ -69,15 +69,15 @@ and section = parse
6969
(* TODO : accept missing manifest version (for midlets) *)
7070
let sections2manifest = function
7171
| ((mv, v) :: main) :: sections
72-
when String.lowercase mv = "manifest-version" ->
72+
when String.lowercase_ascii mv = "manifest-version" ->
7373
{main_section =
7474
{manifest_version = List.map int_of_string (JLib.String.nsplit v ".");
7575
main_attributes = main};
7676
individual_sections =
7777
List.map
7878
(function
7979
| (name, v) :: attributes
80-
when String.lowercase name = "name" ->
80+
when String.lowercase_ascii name = "name" ->
8181
{name = v ; attributes = attributes}
8282
| _ -> failwith "incorrect manifest")
8383
sections}

0 commit comments

Comments
 (0)