-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
157 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
open Ast.Grammar | ||
open Structures | ||
open Auxiliary.Functions | ||
module Graph = Graph' | ||
|
||
|
||
type external_reference = ExternalReferences.t' | ||
|
||
module Analysis : AbstractAnalysis.T = struct | ||
type t = { | ||
external_refs : ExternalReferences.t; | ||
calls : ExternalReferences.t; | ||
_context : unit | ||
} | ||
|
||
(* handle external reference objects*) | ||
let create_ext_ref (module' : string) (properties : property list) : external_reference = | ||
{ _module = module'; properties = properties } | ||
|
||
let add_property (ext_ref : external_reference) (property : property) : external_reference = | ||
{ext_ref with properties = ext_ref.properties @ [property]} | ||
|
||
(* handle external calls collection *) | ||
let add_ext_call (info : t) (call : LocationSet.t) (ext_ref : external_reference) : t = | ||
ExternalReferences.T.replace info.calls call ext_ref; | ||
info | ||
|
||
|
||
(* handle external references collection *) | ||
let add_ext_ref (info : t) (loc : LocationSet.t) (ext_ref : external_reference) : t = | ||
ExternalReferences.T.replace info.external_refs loc ext_ref; | ||
info | ||
|
||
let get_ext_ref (info : t) (loc : LocationSet.t) : external_reference option = | ||
ExternalReferences.T.find_opt info.external_refs loc | ||
|
||
(* context *) | ||
let update_context (info : t) : t = info | ||
|
||
|
||
let analyse (info : t) (state : State.t) (statement : m Statement.t) : t = | ||
let eval_expr = Store.eval_expr state.store state.this in | ||
let alloc = Graph.alloc state.graph in | ||
|
||
let info = update_context info in | ||
match statement with | ||
| _, AssignFunCall {left; callee; arguments; id_call; _} -> | ||
|
||
if Identifier.get_name callee = "require" then ( | ||
(* get module name *) | ||
let module_arg = List.nth_opt arguments 0 in | ||
let module_name = match module_arg with | ||
| Some (_, Literal {value = String module_name; _}) -> | ||
if String.starts_with ~prefix:"./" module_name | ||
then String.sub module_name 2 (String.length module_name - 2) | ||
else module_name | ||
|
||
| _ -> failwith "failed to obtain require module name" | ||
in | ||
|
||
let loc = eval_expr (Identifier.to_expression left) in | ||
let external_reference = create_ext_ref module_name [] in | ||
add_ext_ref info loc external_reference) | ||
|
||
else ( | ||
(* check if callee is an external call *) | ||
let l_call = LocationSet.singleton (alloc id_call) in | ||
let callee = eval_expr (Identifier.to_expression callee) in | ||
let external_reference = get_ext_ref info callee in | ||
map_default (fun external_reference -> | ||
add_ext_call info l_call external_reference | ||
) info external_reference;) | ||
|
||
|
||
| _, AssignMetCallStatic {_object; property; id_call; _} -> | ||
(* check if object callee is an external reference *) | ||
let l_call = LocationSet.singleton (alloc id_call) in | ||
let callee = eval_expr _object in | ||
let external_reference = get_ext_ref info callee in | ||
map_default (fun external_reference -> | ||
let external_reference' = add_property external_reference property in | ||
add_ext_call info l_call external_reference' | ||
) info external_reference | ||
|
||
| _, StaticLookup {left; _object; property; _} -> | ||
(* check if object is an external reference *) | ||
let loc = eval_expr (Identifier.to_expression left) in | ||
let loc_obj = eval_expr _object in | ||
let external_reference = get_ext_ref info loc_obj in | ||
map_default (fun external_reference -> | ||
let external_reference' = add_property external_reference property in | ||
add_ext_ref info loc external_reference' | ||
) info external_reference; | ||
|
||
| _ -> info | ||
|
||
let init () : t = { | ||
external_refs = ExternalReferences.T.create 10; | ||
calls = ExternalReferences.T.create 10; | ||
_context = () | ||
} | ||
|
||
let finish (info : t) : AnalysisType.t = AnalysisType.CollectExternalCalls info.calls | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
open Structures | ||
|
||
module T = Hashtbl.Make (LocationSet) | ||
|
||
|
||
type t' = { | ||
_module : string; | ||
properties : property list | ||
} | ||
|
||
type t = t' T.t | ||
|
||
let iter : (LocationSet.t -> t' -> unit) -> t -> unit = T.iter | ||
let print (refs : t) : unit = | ||
print_endline "=======" ; | ||
iter (fun loc value -> | ||
print_endline "key : "; | ||
LocationSet.print loc; | ||
print_endline "value : "; | ||
print_endline ("{ module : " ^ value._module ^ ", \n properties : " ^ String.concat "." value.properties ^ " }"); | ||
print_endline "----------"; | ||
) refs; | ||
print_endline "=======" ; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters