Summary: As per title. Reviewed By: skcho Differential Revision: D22411395 fbshipit-source-id: 699502382master
parent
cbfb9612e5
commit
d35807223b
@ -0,0 +1,97 @@
|
|||||||
|
(*
|
||||||
|
* Copyright (c) 2009-2013, Monoidics ltd.
|
||||||
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
*)
|
||||||
|
|
||||||
|
open! IStd
|
||||||
|
open Javalib_pack
|
||||||
|
module L = Logging
|
||||||
|
|
||||||
|
let javalib_get_class = Utils.suppress_stderr2 Javalib.get_class
|
||||||
|
|
||||||
|
type callee_status = Translated | Missing of JBasics.class_name * JBasics.method_signature
|
||||||
|
|
||||||
|
type classmap = JCode.jcode Javalib.interface_or_class JBasics.ClassMap.t
|
||||||
|
|
||||||
|
(** We store for each classname the location of its declaration. This map is filled during
|
||||||
|
JFrontend.compute_source_icfg and then it is used in JTransType.get_class_struct_typ before we
|
||||||
|
lose access to program. At the end, the information seats in each Struct.t (stored in Tenv.t) *)
|
||||||
|
type java_location_map = Location.t JBasics.ClassMap.t
|
||||||
|
|
||||||
|
type t =
|
||||||
|
{ classpath_channel: Javalib.class_path
|
||||||
|
; mutable classmap: classmap
|
||||||
|
; mutable java_location_map: java_location_map
|
||||||
|
; callees: callee_status Procname.Hash.t }
|
||||||
|
|
||||||
|
let get_classmap program = program.classmap
|
||||||
|
|
||||||
|
let set_java_location program cn loc =
|
||||||
|
program.java_location_map <- JBasics.ClassMap.add cn loc program.java_location_map
|
||||||
|
|
||||||
|
|
||||||
|
let get_java_location program cn =
|
||||||
|
try Some (JBasics.ClassMap.find cn program.java_location_map) with Caml.Not_found -> None
|
||||||
|
|
||||||
|
|
||||||
|
let mem_classmap cn program = JBasics.ClassMap.mem cn program.classmap
|
||||||
|
|
||||||
|
let get_classpath_channel program = program.classpath_channel
|
||||||
|
|
||||||
|
let add_class cn jclass program =
|
||||||
|
(* [prefix] must be a fresh class name *)
|
||||||
|
let prefix = JBasics.cn_name cn ^ Config.java_lambda_marker_infix in
|
||||||
|
(* we rewrite each class to replace invokedynamic (closure construction)
|
||||||
|
with equivalent old-style Java code that implements a suitable Java interface *)
|
||||||
|
let rewritten_jclass, new_classes = Javalib.remove_invokedynamics jclass ~prefix in
|
||||||
|
program.classmap <- JBasics.ClassMap.add cn rewritten_jclass program.classmap ;
|
||||||
|
(* the rewrite will generate new classes and we add them to the program *)
|
||||||
|
JBasics.ClassMap.iter
|
||||||
|
(fun cn jcl -> program.classmap <- JBasics.ClassMap.add cn jcl program.classmap)
|
||||||
|
new_classes ;
|
||||||
|
rewritten_jclass
|
||||||
|
|
||||||
|
|
||||||
|
let set_callee_translated program pname = Procname.Hash.replace program.callees pname Translated
|
||||||
|
|
||||||
|
let add_missing_callee program pname cn ms =
|
||||||
|
if not (Procname.Hash.mem program.callees pname) then
|
||||||
|
Procname.Hash.add program.callees pname (Missing (cn, ms))
|
||||||
|
|
||||||
|
|
||||||
|
let iter_missing_callees program ~f =
|
||||||
|
let select proc_name = function Translated -> () | Missing (cn, ms) -> f proc_name cn ms in
|
||||||
|
Procname.Hash.iter select program.callees
|
||||||
|
|
||||||
|
|
||||||
|
let cleanup program = Javalib.close_class_path program.classpath_channel
|
||||||
|
|
||||||
|
let lookup_node cn program =
|
||||||
|
try Some (JBasics.ClassMap.find cn (get_classmap program))
|
||||||
|
with Caml.Not_found -> (
|
||||||
|
try
|
||||||
|
let jclass = javalib_get_class (get_classpath_channel program) cn in
|
||||||
|
Some (add_class cn jclass program)
|
||||||
|
with
|
||||||
|
| JBasics.No_class_found _ ->
|
||||||
|
(* TODO T28155039 Figure out when and what to log *)
|
||||||
|
None
|
||||||
|
| (JBasics.Class_structure_error _ | Invalid_argument _ | Failure _) as exn ->
|
||||||
|
L.internal_error "ERROR: %s@." (Exn.to_string exn) ;
|
||||||
|
None )
|
||||||
|
|
||||||
|
|
||||||
|
let load_program ~classpath classes =
|
||||||
|
L.(debug Capture Medium) "loading program ... %!" ;
|
||||||
|
let program =
|
||||||
|
{ classpath_channel= Javalib.class_path classpath
|
||||||
|
; classmap= JBasics.ClassMap.empty
|
||||||
|
; java_location_map= JBasics.ClassMap.empty
|
||||||
|
; callees= Procname.Hash.create 128 }
|
||||||
|
in
|
||||||
|
JBasics.ClassSet.iter (fun cn -> ignore (lookup_node cn program)) classes ;
|
||||||
|
L.(debug Capture Medium) "done@." ;
|
||||||
|
program
|
@ -0,0 +1,39 @@
|
|||||||
|
(*
|
||||||
|
* Copyright (c) 2009-2013, Monoidics ltd.
|
||||||
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
*)
|
||||||
|
|
||||||
|
open! IStd
|
||||||
|
open Javalib_pack
|
||||||
|
|
||||||
|
type classmap = JCode.jcode Javalib.interface_or_class JBasics.ClassMap.t
|
||||||
|
|
||||||
|
type t
|
||||||
|
|
||||||
|
val get_classmap : t -> classmap
|
||||||
|
|
||||||
|
val set_java_location : t -> JBasics.class_name -> Location.t -> unit
|
||||||
|
|
||||||
|
val get_java_location : t -> JBasics.class_name -> Location.t option
|
||||||
|
|
||||||
|
val mem_classmap : JBasics.class_name -> t -> bool
|
||||||
|
|
||||||
|
val cleanup : t -> unit
|
||||||
|
|
||||||
|
val load_program : classpath:string -> JBasics.ClassSet.t -> t
|
||||||
|
(** load a java program *)
|
||||||
|
|
||||||
|
val lookup_node : JBasics.class_name -> t -> JCode.jcode Javalib.interface_or_class option
|
||||||
|
(** retrieve a Java node from the classname *)
|
||||||
|
|
||||||
|
val add_missing_callee : t -> Procname.t -> JBasics.class_name -> JBasics.method_signature -> unit
|
||||||
|
(** add the class name of method signature to the list of callees *)
|
||||||
|
|
||||||
|
val set_callee_translated : t -> Procname.t -> unit
|
||||||
|
(** set that the CFG for the procedure has been created *)
|
||||||
|
|
||||||
|
val iter_missing_callees :
|
||||||
|
t -> f:(Procname.t -> JBasics.class_name -> JBasics.method_signature -> unit) -> unit
|
Loading…
Reference in new issue