-
Notifications
You must be signed in to change notification settings - Fork 84
Server mode #522
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Server mode #522
Changes from 14 commits
Commits
Show all changes
25 commits
Select commit
Hold shift + click to select a range
9619582
Install jsonrpc
keremc 9dfb12d
Create server mode option
keremc ae7c296
Handle JSON-RPC requests
keremc ae65798
Add command to change configuration
keremc ebe306c
Get messages
keremc ca0e384
Add analysis command
keremc 87b2a05
Make the second argument of config a JSON object
keremc 3fbbd5a
Generate change_info with compareCilFiles
keremc def09e0
Add exp_eval command
keremc e7e2161
Clear message table on reset
keremc 193ce44
Workaround for primitive arguments
keremc 71f92bc
Use record type as analyze argument
keremc 0a0aa47
Consistency
keremc c5abce9
Add jsonrpc to lock file
keremc 178e615
Rename Serialize.solver_data to server_solver_data
keremc 5e10188
Use JSON-RPC nomenclature for types
keremc 69ed30f
Use Stream.iter
keremc 3cfb6d9
Don't catch all exceptions
keremc 2c56eef
Merge remote-tracking branch 'origin/master' into server
keremc e6c4a65
Make server a string option
keremc 2c0becb
Use socket for server mode
keremc 50fad93
Split server into multiple options
keremc 481cbde
Merge remote-tracking branch 'origin/master' into server
keremc 6f1a42f
Don't serialize analysis data in server mode
keremc 1b7ef8b
Document future work in comments
keremc File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or 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 hidden or 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 hidden or 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 hidden or 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 hidden or 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 hidden or 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 hidden or 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 hidden or 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 hidden or 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,155 @@ | ||
| open Batteries | ||
| open Jsonrpc | ||
|
|
||
| type t = { | ||
| file: Cil.file; | ||
| do_analyze: Analyses.increment_data -> Cil.file -> unit; | ||
| } | ||
|
|
||
| module type Command = sig | ||
| val name: string | ||
|
|
||
| type args | ||
| type result | ||
|
|
||
| val args_of_yojson: Yojson.Safe.t -> args Ppx_deriving_yojson_runtime.error_or | ||
keremc marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| val result_to_yojson: result -> Yojson.Safe.t | ||
|
|
||
| val process: args -> t -> result | ||
| end | ||
|
|
||
| module Registry = struct | ||
| type t = (string, (module Command)) Hashtbl.t | ||
| let make () : t = Hashtbl.create 32 | ||
| let register (reg: t) (module R : Command) = Hashtbl.add reg R.name (module R) | ||
| end | ||
|
|
||
| let registry = Registry.make () | ||
|
|
||
| let handle_exn id exn = | ||
| Response.Error.(make Code.InternalError (Printexc.to_string exn) () |> Response.error id) | ||
|
|
||
| module ParamParser (C : Command) = struct | ||
| let parse params = | ||
| let args = | ||
| params | ||
| |> Option.map_default Message.Structured.to_json `Null | ||
| |> C.args_of_yojson | ||
| in | ||
| match args with | ||
| | Ok args -> Ok args | ||
| | Error err -> | ||
| (* This is a hack to handle cases where C.args is primitive type like int or string. *) | ||
| match params with | ||
| | Some `List [param] -> ( | ||
| match C.args_of_yojson param with | ||
| | Ok arg -> Ok arg | ||
| | _ -> Error err) | ||
| | _ -> Error err | ||
sim642 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| end | ||
|
|
||
| let handle_request (serv: t) (message: Message.either) (id: Id.t) = | ||
| let cmd = Hashtbl.find_option registry message.method_ in | ||
| let response = match cmd with | ||
| | Some (module C) -> | ||
| let module Parser = ParamParser (C) in ( | ||
| match Parser.parse message.params with | ||
| | Ok args -> ( | ||
| try | ||
| C.process args serv | ||
| |> C.result_to_yojson | ||
| |> Response.ok id | ||
| with exn -> handle_exn id exn) | ||
| | Error s -> Response.Error.(make Code.InvalidParams s () |> Response.error id)) | ||
| | _ -> Response.Error.(make Code.MethodNotFound message.method_ () |> Response.error id) | ||
| in | ||
| Response.yojson_of_t response |> Yojson.Safe.to_string |> print_endline | ||
sim642 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| let serve serv = | ||
| let chan = IO.to_input_channel stdin in | ||
sim642 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| let stream = Yojson.Safe.linestream_from_channel chan in | ||
| while not (Stream.is_empty stream) do | ||
| let line = Stream.next stream in | ||
keremc marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| match line with | ||
| | `Json json -> ( | ||
| try | ||
| let message = Message.either_of_yojson json in | ||
| match message.id with | ||
| | Some id -> handle_request serv message id | ||
| | _ -> () (* We just ignore notifications for now. *) | ||
| with exn -> prerr_endline (Printexc.to_string exn)) | ||
sim642 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| | `Exn exn -> prerr_endline (Printexc.to_string exn) | ||
| done | ||
|
|
||
| let make file do_analyze : t = { file; do_analyze } | ||
|
|
||
| let start file do_analyze = | ||
| GobConfig.set_bool "incremental.save" true; | ||
| serve (make file do_analyze) | ||
|
|
||
| let analyze ?(reset=false) { file; do_analyze } = | ||
| if reset then ( | ||
| Serialize.solver_data := None; | ||
| Messages.Table.(MH.clear messages_table); | ||
| Messages.Table.messages_list := []); | ||
| let increment_data, fresh = match !Serialize.solver_data with | ||
| | Some solver_data -> | ||
| let changes = CompareCIL.compareCilFiles file file in | ||
| let old_data = Some { Analyses.cil_file = file; solver_data } in | ||
| { Analyses.changes; old_data; new_file = file }, false | ||
| | _ -> Analyses.empty_increment_data file, true | ||
| in | ||
| GobConfig.set_bool "incremental.load" (not fresh); | ||
| do_analyze increment_data file; | ||
| GobConfig.set_bool "incremental.load" true | ||
|
|
||
| let () = | ||
| let register = Registry.register registry in | ||
|
|
||
| register (module struct | ||
| let name = "analyze" | ||
| type args = { reset: bool [@default false] } [@@deriving of_yojson] | ||
| type result = unit [@@deriving to_yojson] | ||
| let process { reset } serve = analyze serve ~reset | ||
| end); | ||
sim642 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| register (module struct | ||
| let name = "config" | ||
| type args = string * Yojson.Safe.t [@@deriving of_yojson] | ||
| type result = unit [@@deriving to_yojson] | ||
| let process (conf, json) _ = GobConfig.set_auto conf (Yojson.Safe.to_string json) | ||
| end); | ||
|
|
||
| register (module struct | ||
| let name = "merge_config" | ||
| type args = Yojson.Safe.t [@@deriving of_yojson] | ||
| type result = unit [@@deriving to_yojson] | ||
| let process json _ = GobConfig.merge json | ||
| end); | ||
|
|
||
| register (module struct | ||
| let name = "messages" | ||
| type args = unit [@@deriving of_yojson] | ||
| type result = Messages.Message.t list [@@deriving to_yojson] | ||
| let process () _ = !Messages.Table.messages_list | ||
| end); | ||
|
|
||
| register (module struct | ||
| let name = "exp_eval" | ||
| type args = ExpressionEvaluation.query [@@deriving of_yojson] | ||
| type result = | ||
| ((string * CilType.Location.t * string * int) * bool option) list [@@deriving to_yojson] | ||
| let process query serv = | ||
| GobConfig.set_auto "trans.activated[+]" "'expeval'"; | ||
| ExpressionEvaluation.gv_query := Some query; | ||
| analyze serv; | ||
| GobConfig.set_auto "trans.activated[-]" "'expeval'"; | ||
| !ExpressionEvaluation.gv_results | ||
| end); | ||
|
|
||
sim642 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| register (module struct | ||
| let name = "ping" | ||
| type args = unit [@@deriving of_yojson] | ||
| type result = [`Pong] [@@deriving to_yojson] | ||
| let process () _ = `Pong | ||
| end) | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.