Skip to content

Commit 44e62c5

Browse files
author
Nicolas Barré
authored
Java 8 compatibility
* Parsing ldc instructions taking method type and handle as arguments * Parsing/Unparsing invokestatic and invokespecial with interface methods * Removing assumption that interface methods should be abstract * Implementing MethodParameters attribute * Parsing and Unparsing of Java 8 lambdas * Better specification of the method_handle type * Gathering all constant pool elements under the same type * Documentation * Tests : compiling, parsing, unparsing and comparison of java test sources * Preparing the changelog for major version of Javalib
1 parent 9a7047a commit 44e62c5

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+1586
-1090
lines changed

.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,7 @@ src/META
99
doc/tutorial/*.pdf
1010
doc/api
1111
src/jManifest.ml
12+
tests/src/test_parser
13+
tests/src/unparser
14+
tests/.errors
15+
src/ocaml

CHANGELOG

+13-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,18 @@
1-
From 2.3.5 to 2.3.?
1+
From 2.3.5 to 3.0
22
-----------------
3+
Major changes:
4+
* Java 8 compatibility:
5+
- implementation of method handles and bootstrap methods
6+
- adding InvokeDynamic instruction
7+
- interfaces can now implement concrete methods
8+
- invokestatic and invokespecial intructions can refer to interface methods
9+
- new attribute MethodParameters
10+
311
Minor changes:
12+
* integration of ptrees inside Javalib_pack
13+
14+
TODO:
15+
* The new attributes RuntimeVisibleTypeAnnotations and RuntimeInvisibleTypeAnnotations have no high-level representation.
416

517
From 2.3.4 to 2.3.5
618
-----------------

intro.ocamldoc

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
{b {C JAVALIB_TRUNK}}
22

3-
{i {C Laurent Hubert an Tiphaine Turpin}}
3+
{i {C Nicolas Barré, Laurent Hubert and Tiphaine Turpin}}
44

5-
{i {C July 2016}}
5+
{i {C October 2018}}
66

7-
{2 {L Documentation}}
7+
{1 {L Documentation}}
88

99
{b {L User interface}}
1010

11-
The following modules consitute the user interface of Javalib. They are the only
11+
The following modules constitute the user interface of Javalib. They are the only
1212
modules you should need.
1313

1414
{!modules: Javalib JBasics JCode}
@@ -36,4 +36,4 @@ have some feedback).
3636

3737
{!indexlist}
3838

39-
{i {C Others contributors: Florent Kirchner, Nicolas Barré, Nicolas Cannasse and David Pichardie}}
39+
{i {C Others contributors: Florent Kirchner, Nicolas Cannasse and David Pichardie}}

src/Makefile

+4-3
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,10 @@ javalib_pack.cmx: $(MODULE_INTERFACES:=.cmi) $(MODULES:=.cmx)
8989
# doc
9090
doc: $(MODULE_INTERFACES:=.cmi) $(MODULES:=.ml) ../intro.ocamldoc
9191
mkdir -p $(DOCDIR)
92-
$(OCAMLDOC) $(RECODE) $(INCLUDE) -I ptrees -d $(DOCDIR) -html -stars \
93-
-colorize-code -intro ../intro.ocamldoc -t Javalib \
94-
$(MODULE_INTERFACES:=.mli)
92+
$(OCAMLDOC) $(RECODE) $(INCLUDE) -I ptrees -d $(DOCDIR) -html -stars \
93+
-css-style style.css -colorize-code -intro ../intro.ocamldoc \
94+
-t Javalib $(MODULE_INTERFACES:=.mli)
95+
cp style.css $(DOCDIR)
9596

9697
# cleaning
9798
clean:

src/jBasics.ml

+43-19
Original file line numberDiff line numberDiff line change
@@ -71,18 +71,6 @@ type java_basic_type = [
7171
| other_num
7272
]
7373

74-
type method_handle_kind = [
75-
| `GetField
76-
| `GetStatic
77-
| `PutField
78-
| `PutStatic
79-
| `InvokeVirtual
80-
| `InvokeStatic
81-
| `InvokeSpecial
82-
| `NewInvokeSpecial
83-
| `InvokeInterface
84-
]
85-
8674
(* Java object type *)
8775
type object_type =
8876
| TClass of class_name
@@ -118,29 +106,60 @@ type descriptor =
118106
| SValue of field_descriptor
119107
| SMethod of method_descriptor
120108

121-
(* Constant value. *)
122109
type jstr = string
123110
let make_jstr s = s
124111
let jstr_pp s = String.escaped s
125112
let jstr_raw s = s
126113

114+
(* Method Handle *)
115+
type jmethod_or_interface = [
116+
| `Method of class_name * method_signature
117+
| `InterfaceMethod of class_name * method_signature
118+
]
119+
120+
type method_handle = [
121+
| `GetField of class_name * field_signature
122+
| `GetStatic of class_name * field_signature
123+
| `PutField of class_name * field_signature
124+
| `PutStatic of class_name * field_signature
125+
| `InvokeVirtual of object_type * method_signature
126+
| `NewInvokeSpecial of class_name * method_signature
127+
| `InvokeStatic of jmethod_or_interface
128+
| `InvokeSpecial of jmethod_or_interface
129+
| `InvokeInterface of class_name * method_signature
130+
]
131+
132+
(* Bootstrap argument *)
133+
type bootstrap_argument = [
134+
| `String of jstr
135+
| `Class of object_type
136+
| `Int of int32
137+
| `Long of int64
138+
| `Float of float
139+
| `Double of float
140+
| `MethodHandle of method_handle
141+
| `MethodType of method_descriptor
142+
]
143+
144+
(* Bootstrap method *)
145+
type bootstrap_method = {
146+
bm_ref : method_handle;
147+
bm_args : bootstrap_argument list;
148+
}
127149

128-
type constant_value =
150+
(* Constant. *)
151+
type constant =
129152
| ConstString of jstr
130153
| ConstInt of int32
131154
| ConstFloat of float
132155
| ConstLong of int64
133156
| ConstDouble of float
134157
| ConstClass of object_type
135-
136-
(* Constant. *)
137-
type constant =
138-
| ConstValue of constant_value
139158
| ConstField of (class_name * field_signature)
140159
| ConstMethod of (object_type * method_signature)
141160
| ConstInterfaceMethod of (class_name * method_signature)
142161
| ConstMethodType of method_descriptor
143-
| ConstMethodHandle of method_handle_kind * constant
162+
| ConstMethodHandle of method_handle
144163
| ConstInvokeDynamic of bootstrap_method_index * method_signature
145164
| ConstNameAndType of string * descriptor
146165
| ConstStringUTF8 of string
@@ -318,6 +337,11 @@ let make_ms mname margs mrtype =
318337
mst.msi_next <- msi + 1;
319338
new_ms
320339

340+
let make_md md = md
341+
let md_split md = md
342+
let md_args md = fst md
343+
let md_rtype md = snd md
344+
321345
let make_fs fname fdesc =
322346
let dic = common_dictionary in
323347
let fst = dic.field_signature_table

src/jBasics.mli

+84-39
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323

2424
(** Basic elements of class files. *)
2525

26-
(** {2 Definition of basic types and descriptors.} *)
26+
(** {1 Definition of basic types and descriptors.} *)
2727

2828
(** Type representing a class name. e.g. [java.lang.Object] *)
2929
type class_name
@@ -34,6 +34,11 @@ type class_name
3434
have the same [method_signature]. *)
3535
type method_signature
3636

37+
(** Type representing a method descriptor.
38+
A method descriptor contains the types of parameters and the method
39+
return type. *)
40+
type method_descriptor
41+
3742
(** Type representing a field signature.
3843
A field signature contains the field name and the field type. *)
3944
type field_signature
@@ -92,19 +97,6 @@ type java_basic_type = [
9297
| other_num
9398
]
9499

95-
(** Method handle type. *)
96-
type method_handle_kind = [
97-
| `GetField
98-
| `GetStatic
99-
| `PutField
100-
| `PutStatic
101-
| `InvokeVirtual
102-
| `InvokeStatic
103-
| `InvokeSpecial
104-
| `NewInvokeSpecial
105-
| `InvokeInterface
106-
]
107-
108100
(** Java object type *)
109101
type object_type =
110102
| TClass of class_name
@@ -114,15 +106,18 @@ type object_type =
114106
and value_type =
115107
| TBasic of java_basic_type
116108
| TObject of object_type
117-
109+
110+
(** Abstract datatype for Java strings *)
111+
type jstr
112+
118113
(** Version number of the class file. Extract of the specification: An
119114
implementation of Java 1.k sould support class file formats of
120115
versions in the range of 45.0 through 44+k.0 inclusive. E.g. Java
121116
1.6 implementations support class file formats of versions up to
122117
50.0. *)
123118
type version = {major :int; minor:int;}
124119

125-
(** {2 Basic types manipulation.} *)
120+
(** {1 Basic types manipulation.} *)
126121

127122
(** Creating and manipulating {!class_name} values. *)
128123

@@ -185,6 +180,20 @@ val ms_compare : method_signature -> method_signature -> int
185180
(** Returns [true] if two method signatures are equal, [false] otherwise. *)
186181
val ms_equal : method_signature -> method_signature -> bool
187182

183+
(** Creating and manipulating {!method_descriptor} values. *)
184+
185+
(** Builds a [method_descriptor]. *)
186+
val make_md : value_type list * value_type option -> method_descriptor
187+
188+
(** Splits a [method_descriptor] into arguments list and return type. *)
189+
val md_split : method_descriptor -> value_type list * value_type option
190+
191+
(** Returns the [method_descriptor] arguments list. *)
192+
val md_args : method_descriptor -> value_type list
193+
194+
(** Returns the [method_descriptor] return type. *)
195+
val md_rtype : method_descriptor -> value_type option
196+
188197
(** Creating and manipulating {!field_signature} values. *)
189198

190199
(** Builds a [field_signature]. *)
@@ -236,7 +245,57 @@ val cms_compare : class_method_signature -> class_method_signature -> int
236245
(** Returns [true] if two [class_method_signature] are equal, [false] otherwise. *)
237246
val cms_equal : class_method_signature -> class_method_signature -> bool
238247

239-
(** {2 Constant pool.} *)
248+
(** Builds a [jstr]. *)
249+
val make_jstr : string -> jstr
250+
251+
(** Returns a [string] where all characters outside the ASCII printable range (32..126) are escaped. *)
252+
val jstr_pp : jstr -> string
253+
254+
(** Returns the original [string]. *)
255+
val jstr_raw : jstr -> string
256+
257+
(** {1 Bootstrap method and method handle types.} *)
258+
259+
(** Features introduced in Java 8 to implement lambdas. *)
260+
261+
type jmethod_or_interface = [
262+
| `Method of class_name * method_signature
263+
| `InterfaceMethod of class_name * method_signature
264+
]
265+
266+
(** Method handle. cf JVM Spec se8 §4.4.8. *)
267+
type method_handle = [
268+
| `GetField of class_name * field_signature
269+
| `GetStatic of class_name * field_signature
270+
| `PutField of class_name * field_signature
271+
| `PutStatic of class_name * field_signature
272+
| `InvokeVirtual of object_type * method_signature
273+
| `NewInvokeSpecial of class_name * method_signature
274+
| `InvokeStatic of jmethod_or_interface
275+
| `InvokeSpecial of jmethod_or_interface
276+
| `InvokeInterface of class_name * method_signature
277+
]
278+
279+
(** Bootstrap argument. cf JVM Spec se8 §4.7.23. *)
280+
type bootstrap_argument = [
281+
| `String of jstr
282+
| `Class of object_type
283+
| `Int of int32
284+
| `Long of int64
285+
| `Float of float
286+
| `Double of float
287+
| `MethodHandle of method_handle
288+
| `MethodType of method_descriptor
289+
]
290+
291+
(** Bootstrap method called by the [invokedynamic] instruction.
292+
cf JVM Spec se8 §4.7.23. *)
293+
type bootstrap_method = {
294+
bm_ref : method_handle;
295+
bm_args : bootstrap_argument list;
296+
}
297+
298+
(** {1 Constant pool.} *)
240299

241300
(** You should not need this for normal usage, as the
242301
parsing/unparsing functions take care of the constant pool. This
@@ -245,44 +304,30 @@ val cms_equal : class_method_signature -> class_method_signature -> bool
245304

246305
type bootstrap_method_index = int
247306

248-
(** Method descriptor. *)
249-
type method_descriptor = value_type list * value_type option
250-
251307
(** Signatures parsed from CONSTANT_NameAndType_info structures. *)
252308
type descriptor =
253309
| SValue of value_type
254310
| SMethod of method_descriptor
255311

256-
(** Abstract datatype for Java strings *)
257-
type jstr
258-
val make_jstr : string -> jstr
259-
val jstr_pp : jstr -> string
260-
val jstr_raw : jstr -> string
261-
262-
(** Constant value. *)
263-
type constant_value =
312+
(** Constant pool values. *)
313+
type constant =
264314
| ConstString of jstr
265315
| ConstInt of int32
266316
| ConstFloat of float
267317
| ConstLong of int64
268318
| ConstDouble of float
269319
| ConstClass of object_type
270-
271-
(** Constant. *)
272-
type constant =
273-
| ConstValue of constant_value
274320
| ConstField of (class_name * field_signature)
275321
| ConstMethod of (object_type * method_signature)
276322
| ConstInterfaceMethod of (class_name * method_signature)
277323
| ConstMethodType of method_descriptor
278-
| ConstMethodHandle of method_handle_kind * constant
324+
| ConstMethodHandle of method_handle
279325
| ConstInvokeDynamic of bootstrap_method_index * method_signature
280326
| ConstNameAndType of string * descriptor
281327
| ConstStringUTF8 of string
282328
| ConstUnusable
283329

284-
285-
(** {2 Stackmaps} *)
330+
(** {1 Stackmaps} *)
286331

287332
(** Verification type. *)
288333
type verification_type =
@@ -299,7 +344,7 @@ type verification_type =
299344
(** Stackmap type. *)
300345
type stackmap = (int* verification_type list * verification_type list)
301346

302-
(** {2 Errors} *)
347+
(** {1 Errors} *)
303348

304349
(** The library may throw the following exceptions, in addition to [Invalid_argument].
305350
Any other exception (in particular, an [Assert_failure])
@@ -313,7 +358,7 @@ exception No_class_found of string
313358
exception Class_structure_error of string
314359

315360

316-
(** {2 Annotations} *)
361+
(** {1 Annotations} *)
317362

318363
(** [element_value] represents a constant value, either a number, a string, a
319364
class, an enum, an array of [element_value]s or another annotation. *)
@@ -344,7 +389,7 @@ and annotation = {
344389
}
345390

346391

347-
(** {2 Containers.} *)
392+
(** {1 Containers.} *)
348393

349394
(** This module allows to build maps of elements indexed by [class_name] values. *)
350395
module ClassMap : GenericMap.GenericMapSig with type key = class_name
@@ -382,7 +427,7 @@ sig
382427
end
383428

384429

385-
(** {2 Tuning JavaLib.} *)
430+
(** {1 Tuning JavaLib.} *)
386431

387432
(** [set_permissive true] disables some checking in JavaLib. It can
388433
allow to parse some files that do not strictly comply with the

0 commit comments

Comments
 (0)