From 0c6c6bb24b517e9ad65efd7b465ba48608700e1b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr>
Date: Fri, 26 Jul 2024 10:47:50 +0200
Subject: [PATCH] [Eva] Moves flamegraph request from values_request to
 general_requests.

---
 ivette/src/frama-c/plugins/eva/Flamegraph.tsx |   2 +-
 .../frama-c/plugins/eva/api/general/index.ts  | 141 ++++++++++++++++++
 .../frama-c/plugins/eva/api/values/index.ts   | 141 ------------------
 src/plugins/eva/api/general_requests.ml       |  95 ++++++++++++
 src/plugins/eva/api/values_request.ml         |  95 ------------
 5 files changed, 237 insertions(+), 237 deletions(-)

diff --git a/ivette/src/frama-c/plugins/eva/Flamegraph.tsx b/ivette/src/frama-c/plugins/eva/Flamegraph.tsx
index ad08c4da315..41f01b1f881 100644
--- a/ivette/src/frama-c/plugins/eva/Flamegraph.tsx
+++ b/ivette/src/frama-c/plugins/eva/Flamegraph.tsx
@@ -25,7 +25,7 @@ import { IconButton } from 'dome/controls/buttons';
 import * as Ivette from 'ivette';
 import * as Ast from 'frama-c/kernel/api/ast';
 import * as States from 'frama-c/states';
-import * as Eva from 'frama-c/plugins/eva/api/values';
+import * as Eva from 'frama-c/plugins/eva/api/general';
 import { FlameGraph } from 'react-flame-graph';
 import AutoSizer, { Size } from 'react-virtualized-auto-sizer';
 import { EvaReady, EvaStatus } from './components/AnalysisStatus';
diff --git a/ivette/src/frama-c/plugins/eva/api/general/index.ts b/ivette/src/frama-c/plugins/eva/api/general/index.ts
index c37d5121b0b..ce5eb30dbab 100644
--- a/ivette/src/frama-c/plugins/eva/api/general/index.ts
+++ b/ivette/src/frama-c/plugins/eva/api/general/index.ts
@@ -760,4 +760,145 @@ export const getStates: Server.GetRequest<
   [ string, string, string ][]
   >= getStates_internal;
 
+/** Kernel function stack identifier */
+export type kfstack = Json.index<'#kfstack'>;
+
+/** Decoder for `kfstack` */
+export const jKfstack: Json.Decoder<kfstack> =
+  Json.jIndex<'#kfstack'>('#kfstack');
+
+/** Natural order for `kfstack` */
+export const byKfstack: Compare.Order<kfstack> = Compare.number;
+
+/** Default value for `kfstack` */
+export const kfstackDefault: kfstack =
+  Json.jIndex<'#kfstack'>('#kfstack')(-1);
+
+/** Kernel function list infos */
+export type calllink = { callee: decl, caller?: decl };
+
+/** Decoder for `calllink` */
+export const jCalllink: Json.Decoder<calllink> =
+  Json.jObject({ callee: jDecl, caller: Json.jOption(jDecl),});
+
+/** Natural order for `calllink` */
+export const byCalllink: Compare.Order<calllink> =
+  Compare.byFields
+    <{ callee: decl, caller?: decl }>({
+    callee: byDecl,
+    caller: Compare.defined(byDecl),
+  });
+
+/** Default value for `calllink` */
+export const calllinkDefault: calllink =
+  { callee: declDefault, caller: undefined };
+
+/** Data for array rows [`evaFlamegraph`](#evaflamegraph)  */
+export interface evaFlamegraphData {
+  /** Entry identifier. */
+  key: Json.key<'#evaFlamegraph'>;
+  /** Caller list identifier */
+  stack: kfstack;
+  /** Computation time for the kernel function stack */
+  time: number;
+  /** Kernel function description */
+  title: string;
+  /** Function name */
+  name: string;
+  /** Function list */
+  funlist: string;
+  /** Kernel function key */
+  kfkey: string;
+}
+
+/** Decoder for `evaFlamegraphData` */
+export const jEvaFlamegraphData: Json.Decoder<evaFlamegraphData> =
+  Json.jObject({
+    key: Json.jKey<'#evaFlamegraph'>('#evaFlamegraph'),
+    stack: jKfstack,
+    time: Json.jNumber,
+    title: Json.jString,
+    name: Json.jString,
+    funlist: Json.jString,
+    kfkey: Json.jString,
+  });
+
+/** Natural order for `evaFlamegraphData` */
+export const byEvaFlamegraphData: Compare.Order<evaFlamegraphData> =
+  Compare.byFields
+    <{ key: Json.key<'#evaFlamegraph'>, stack: kfstack, time: number,
+       title: string, name: string, funlist: string, kfkey: string }>({
+    key: Compare.string,
+    stack: byKfstack,
+    time: Compare.number,
+    title: Compare.string,
+    name: Compare.string,
+    funlist: Compare.string,
+    kfkey: Compare.string,
+  });
+
+/** Signal for array [`evaFlamegraph`](#evaflamegraph)  */
+export const signalEvaFlamegraph: Server.Signal = {
+  name: 'plugins.eva.general.signalEvaFlamegraph',
+};
+
+const reloadEvaFlamegraph_internal: Server.GetRequest<null,null> = {
+  kind: Server.RqKind.GET,
+  name: 'plugins.eva.general.reloadEvaFlamegraph',
+  input: Json.jNull,
+  output: Json.jNull,
+  fallback: null,
+  signals: [],
+};
+/** Force full reload for array [`evaFlamegraph`](#evaflamegraph)  */
+export const reloadEvaFlamegraph: Server.GetRequest<null,null>= reloadEvaFlamegraph_internal;
+
+const fetchEvaFlamegraph_internal: Server.GetRequest<
+  number,
+  { reload: boolean, removed: Json.key<'#evaFlamegraph'>[],
+    updated: evaFlamegraphData[], pending: number }
+  > = {
+  kind: Server.RqKind.GET,
+  name: 'plugins.eva.general.fetchEvaFlamegraph',
+  input: Json.jNumber,
+  output: Json.jObject({
+            reload: Json.jBoolean,
+            removed: Json.jArray(
+                       Json.jKey<'#evaFlamegraph'>('#evaFlamegraph')),
+            updated: Json.jArray(jEvaFlamegraphData),
+            pending: Json.jNumber,
+          }),
+  fallback: { reload: false, removed: [], updated: [], pending: 0 },
+  signals: [],
+};
+/** Data fetcher for array [`evaFlamegraph`](#evaflamegraph)  */
+export const fetchEvaFlamegraph: Server.GetRequest<
+  number,
+  { reload: boolean, removed: Json.key<'#evaFlamegraph'>[],
+    updated: evaFlamegraphData[], pending: number }
+  >= fetchEvaFlamegraph_internal;
+
+const evaFlamegraph_internal: State.Array<
+  Json.key<'#evaFlamegraph'>,
+  evaFlamegraphData
+  > = {
+  name: 'plugins.eva.general.evaFlamegraph',
+  getkey: ((d:evaFlamegraphData) => d.key),
+  signal: signalEvaFlamegraph,
+  fetch: fetchEvaFlamegraph,
+  reload: reloadEvaFlamegraph,
+  order: byEvaFlamegraphData,
+};
+/** Data for Eva flamegraph */
+export const evaFlamegraph: State.Array<
+  Json.key<'#evaFlamegraph'>,
+  evaFlamegraphData
+  > = evaFlamegraph_internal;
+
+/** Default value for `evaFlamegraphData` */
+export const evaFlamegraphDataDefault: evaFlamegraphData =
+  { key: Json.jKey<'#evaFlamegraph'>('#evaFlamegraph')(''),
+    stack: kfstackDefault, time: 0, title: '', name: '', funlist: '',
+    kfkey: '' };
+
 /* ------------------------------------- */
diff --git a/ivette/src/frama-c/plugins/eva/api/values/index.ts b/ivette/src/frama-c/plugins/eva/api/values/index.ts
index c0cf380694f..e5dfbd41bb7 100644
--- a/ivette/src/frama-c/plugins/eva/api/values/index.ts
+++ b/ivette/src/frama-c/plugins/eva/api/values/index.ts
@@ -232,145 +232,4 @@ export const getValues: Server.GetRequest<
     vElse?: evaluation }
   >= getValues_internal;
 
-/** Kernel function stack identifier */
-export type kfstack = Json.index<'#kfstack'>;
-
-/** Decoder for `kfstack` */
-export const jKfstack: Json.Decoder<kfstack> =
-  Json.jIndex<'#kfstack'>('#kfstack');
-
-/** Natural order for `kfstack` */
-export const byKfstack: Compare.Order<kfstack> = Compare.number;
-
-/** Default value for `kfstack` */
-export const kfstackDefault: kfstack =
-  Json.jIndex<'#kfstack'>('#kfstack')(-1);
-
-/** Kernel function list infos */
-export type calllink = { callee: decl, caller?: decl };
-
-/** Decoder for `calllink` */
-export const jCalllink: Json.Decoder<calllink> =
-  Json.jObject({ callee: jDecl, caller: Json.jOption(jDecl),});
-
-/** Natural order for `calllink` */
-export const byCalllink: Compare.Order<calllink> =
-  Compare.byFields
-    <{ callee: decl, caller?: decl }>({
-    callee: byDecl,
-    caller: Compare.defined(byDecl),
-  });
-
-/** Default value for `calllink` */
-export const calllinkDefault: calllink =
-  { callee: declDefault, caller: undefined };
-
-/** Data for array rows [`evaFlamegraph`](#evaflamegraph)  */
-export interface evaFlamegraphData {
-  /** Entry identifier. */
-  key: Json.key<'#evaFlamegraph'>;
-  /** Caller list identifier */
-  stack: kfstack;
-  /** Computation time for the kernel function stack */
-  time: number;
-  /** Kernel function description */
-  title: string;
-  /** Function name */
-  name: string;
-  /** Function list */
-  funlist: string;
-  /** Kernel function key */
-  kfkey: string;
-}
-
-/** Decoder for `evaFlamegraphData` */
-export const jEvaFlamegraphData: Json.Decoder<evaFlamegraphData> =
-  Json.jObject({
-    key: Json.jKey<'#evaFlamegraph'>('#evaFlamegraph'),
-    stack: jKfstack,
-    time: Json.jNumber,
-    title: Json.jString,
-    name: Json.jString,
-    funlist: Json.jString,
-    kfkey: Json.jString,
-  });
-
-/** Natural order for `evaFlamegraphData` */
-export const byEvaFlamegraphData: Compare.Order<evaFlamegraphData> =
-  Compare.byFields
-    <{ key: Json.key<'#evaFlamegraph'>, stack: kfstack, time: number,
-       title: string, name: string, funlist: string, kfkey: string }>({
-    key: Compare.string,
-    stack: byKfstack,
-    time: Compare.number,
-    title: Compare.string,
-    name: Compare.string,
-    funlist: Compare.string,
-    kfkey: Compare.string,
-  });
-
-/** Signal for array [`evaFlamegraph`](#evaflamegraph)  */
-export const signalEvaFlamegraph: Server.Signal = {
-  name: 'plugins.eva.values.signalEvaFlamegraph',
-};
-
-const reloadEvaFlamegraph_internal: Server.GetRequest<null,null> = {
-  kind: Server.RqKind.GET,
-  name: 'plugins.eva.values.reloadEvaFlamegraph',
-  input: Json.jNull,
-  output: Json.jNull,
-  fallback: null,
-  signals: [],
-};
-/** Force full reload for array [`evaFlamegraph`](#evaflamegraph)  */
-export const reloadEvaFlamegraph: Server.GetRequest<null,null>= reloadEvaFlamegraph_internal;
-
-const fetchEvaFlamegraph_internal: Server.GetRequest<
-  number,
-  { reload: boolean, removed: Json.key<'#evaFlamegraph'>[],
-    updated: evaFlamegraphData[], pending: number }
-  > = {
-  kind: Server.RqKind.GET,
-  name: 'plugins.eva.values.fetchEvaFlamegraph',
-  input: Json.jNumber,
-  output: Json.jObject({
-            reload: Json.jBoolean,
-            removed: Json.jArray(
-                       Json.jKey<'#evaFlamegraph'>('#evaFlamegraph')),
-            updated: Json.jArray(jEvaFlamegraphData),
-            pending: Json.jNumber,
-          }),
-  fallback: { reload: false, removed: [], updated: [], pending: 0 },
-  signals: [],
-};
-/** Data fetcher for array [`evaFlamegraph`](#evaflamegraph)  */
-export const fetchEvaFlamegraph: Server.GetRequest<
-  number,
-  { reload: boolean, removed: Json.key<'#evaFlamegraph'>[],
-    updated: evaFlamegraphData[], pending: number }
-  >= fetchEvaFlamegraph_internal;
-
-const evaFlamegraph_internal: State.Array<
-  Json.key<'#evaFlamegraph'>,
-  evaFlamegraphData
-  > = {
-  name: 'plugins.eva.values.evaFlamegraph',
-  getkey: ((d:evaFlamegraphData) => d.key),
-  signal: signalEvaFlamegraph,
-  fetch: fetchEvaFlamegraph,
-  reload: reloadEvaFlamegraph,
-  order: byEvaFlamegraphData,
-};
-/** Data for Eva flamegraph */
-export const evaFlamegraph: State.Array<
-  Json.key<'#evaFlamegraph'>,
-  evaFlamegraphData
-  > = evaFlamegraph_internal;
-
-/** Default value for `evaFlamegraphData` */
-export const evaFlamegraphDataDefault: evaFlamegraphData =
-  { key: Json.jKey<'#evaFlamegraph'>('#evaFlamegraph')(''),
-    stack: kfstackDefault, time: 0, title: '', name: '', funlist: '',
-    kfkey: '' };
-
 /* ------------------------------------- */
diff --git a/src/plugins/eva/api/general_requests.ml b/src/plugins/eva/api/general_requests.ml
index a6ba38f5c9f..afcf9ac7c20 100644
--- a/src/plugins/eva/api/general_requests.ml
+++ b/src/plugins/eva/api/general_requests.ml
@@ -868,3 +868,98 @@ let () = Request.register ~package
           (Data.Jtriple (Data.Jstring) (Data.Jstring) (Data.Jstring)))
     ~signals:[computation_signal]
     get_states
+
+
+
+(* ----- Flamegraph --------------------------------------------------------- *)
+
+module Jkfstack :
+sig
+  include Data.S with type t = Eva_perf.KfList.t
+  val get : Eva_perf.KfList.t -> int
+end = Data.Index
+    (Eva_perf.KfList.Map)
+    (struct
+      let package = package
+      let name = "kfstack"
+      let descr = Markdown.plain "Kernel function stack identifier"
+    end)
+
+module Jkfs : Request.Output with type t = Eva_perf.KfList.t = struct
+
+  type t = Eva_perf.KfList.t
+
+  let jcalllink = Server.Data.declare ~package
+      ~name:"calllink" ~descr:(Markdown.plain "Kernel function list infos")
+      (Jrecord [
+          "callee" , Kernel_ast.Decl.jtype ;
+          "caller" , Joption Kernel_ast.Decl.jtype ;
+        ])
+
+  let jtype = Package.(Jarray jcalllink)
+
+  let jkfstack ~jcaller ~jcallee =
+    `Assoc [
+      "callee", jcallee ;
+      "caller", jcaller ;
+    ]
+
+  let to_json (cl : t) =
+    let aux (acc, jcaller) callee =
+      let jcallee = Kernel_ast.Decl.to_json (SFunction callee) in
+      jkfstack ~jcaller ~jcallee :: acc, jcallee
+    in
+    match cl with
+    | [] -> `List []
+    | entry :: r ->
+      let entry_point = Kernel_ast.Decl.to_json (SFunction entry) in
+      let l, _last_callee =
+        List.fold_left aux
+          ([`Assoc [ "callee", entry_point ]], entry_point)
+          (List.rev r)
+      in `List l
+
+end
+
+let _evaFlamegraph =
+  let model = States.model () in
+  (* This field is useful for interacting with other components,
+     eg. the currently selected callstack in EVA values *)
+  States.column model ~name:"stack"
+    ~descr:(Markdown.plain "Caller list identifier")
+    ~data:(module Jkfstack) ~get:fst ;
+  (* This field contains the computation time *)
+  States.column model ~name:"time"
+    ~descr:(Markdown.plain "Computation time for the kernel function stack")
+    ~data:(module Data.Jfloat)
+    ~get:(fun (_cs, (_start, duration)) -> duration);
+  (* This field might be useful to display tooltips on the flames *)
+  States.column model ~name:"title"
+    ~descr:(Markdown.plain "Kernel function description")
+    ~data:(module Data.Jstring)
+    ~get:(fun (cl,_) -> Pretty_utils.to_string Eva_perf.KfList.pretty cl);
+  (* This field contains the name of the function on top of the
+     kernel function stack *)
+  States.column model ~name:"name"
+    ~descr:(Markdown.plain "Function name")
+    ~data:(module Data.Jstring)
+    ~get:(fun (cl,_) -> Kernel_function.get_name (List.(hd (rev cl))));
+  (* This field contains the list of the function names *)
+  States.column model ~name:"funlist"
+    ~descr:(Markdown.plain "Function list")
+    ~data:(module Data.Jstring)
+    ~get:(fun (cl,_) ->
+        Pretty_utils.to_string (Eva_perf.KfList.pretty ~sep:":") cl);
+  (* This field contains the declaration of the function on top of the
+     kernel function stack *)
+  States.column model ~name:"kfkey"
+    ~descr:(Markdown.plain "Kernel function key")
+    ~data:(module Data.Jstring)
+    ~get:(fun (cl,_) -> Kernel_ast.Decl.index (SFunction (List.(hd (rev cl)))));
+  (* Add/remove other fields if necessary... *)
+  States.register_framac_array
+    ~package
+    ~name:"evaFlamegraph"
+    ~descr:(Markdown.plain "Data for Eva flamegraph")
+    ~key:(fun cl -> Format.sprintf "#%06d" @@ Jkfstack.get cl)
+    model (module Eva_perf.EvaFlamegraph)
diff --git a/src/plugins/eva/api/values_request.ml b/src/plugins/eva/api/values_request.ml
index 74be4f22038..401d42f4731 100644
--- a/src/plugins/eva/api/values_request.ml
+++ b/src/plugins/eva/api/values_request.ml
@@ -722,98 +722,3 @@ let () =
     end
 
 (* -------------------------------------------------------------------------- *)
-(* --- Flamegraph                                                         --- *)
-(* -------------------------------------------------------------------------- *)
-
-module Jkfstack :
-sig
-  include Data.S with type t = Eva_perf.KfList.t
-  val get : Eva_perf.KfList.t -> int
-end = Data.Index
-    (Eva_perf.KfList.Map)
-    (struct
-      let package = package
-      let name = "kfstack"
-      let descr = Md.plain "Kernel function stack identifier"
-    end)
-
-module Jkfs : Request.Output with type t = Eva_perf.KfList.t = struct
-
-  type t = Eva_perf.KfList.t
-
-  let jcalllink = Server.Data.declare ~package
-      ~name:"calllink" ~descr:(Md.plain "Kernel function list infos")
-      (Jrecord [
-          "callee" , Jdecl.jtype ;
-          "caller" , Joption Jdecl.jtype ;
-        ])
-
-  let jtype = Package.(Jarray jcalllink)
-
-  let jkfstack ~jcaller ~jcallee =
-    `Assoc [
-      "callee", jcallee ;
-      "caller", jcaller ;
-    ]
-
-  let to_json (cl : t) =
-    let aux (acc, jcaller) callee =
-      let jcallee = Jdecl.to_json (SFunction callee) in
-      jkfstack ~jcaller ~jcallee :: acc, jcallee
-    in
-    match cl with
-    | [] -> `List []
-    | entry :: r ->
-      let entry_point = Jdecl.to_json (SFunction entry) in
-      let l, _last_callee =
-        List.fold_left aux
-          ([`Assoc [ "callee", entry_point ]], entry_point)
-          (List.rev r)
-      in `List l
-
-end
-
-let _evaFlamegraph =
-  let model = States.model () in
-  (* This field is useful for interacting with other components,
-     eg. the currently selected callstack in EVA values *)
-  States.column model ~name:"stack"
-    ~descr:(Markdown.plain "Caller list identifier")
-    ~data:(module Jkfstack) ~get:fst ;
-  (* This field contains the computation time *)
-  States.column model ~name:"time"
-    ~descr:(Markdown.plain "Computation time for the kernel function stack")
-    ~data:(module Data.Jfloat)
-    ~get:(fun (_cs, (_start, duration)) -> duration);
-  (* This field might be useful to display tooltips on the flames *)
-  States.column model ~name:"title"
-    ~descr:(Markdown.plain "Kernel function description")
-    ~data:(module Data.Jstring)
-    ~get:(fun (cl,_) -> Pretty_utils.to_string Eva_perf.KfList.pretty cl);
-  (* This field contains the name of the function on top of the
-     kernel function stack *)
-  States.column model ~name:"name"
-    ~descr:(Markdown.plain "Function name")
-    ~data:(module Data.Jstring)
-    ~get:(fun (cl,_) -> Kernel_function.get_name (List.(hd (rev cl))));
-  (* This field contains the list of the function names *)
-  States.column model ~name:"funlist"
-    ~descr:(Markdown.plain "Function list")
-    ~data:(module Data.Jstring)
-    ~get:(fun (cl,_) ->
-        Pretty_utils.to_string (Eva_perf.KfList.pretty ~sep:":") cl);
-  (* This field contains the declaration of the function on top of the
-     kernel function stack *)
-  States.column model ~name:"kfkey"
-    ~descr:(Markdown.plain "Kernel function key")
-    ~data:(module Data.Jstring)
-    ~get:(fun (cl,_) -> Kernel_ast.Decl.index (SFunction (List.(hd (rev cl)))));
-  (* Add/remove other fields if necessary... *)
-  States.register_framac_array
-    ~package
-    ~name:"evaFlamegraph"
-    ~descr:(Markdown.plain "Data for Eva flamegraph")
-    ~key:(fun cl -> Format.sprintf "#%06d" @@ Jkfstack.get cl)
-    model (module Eva_perf.EvaFlamegraph)
-
-(* -------------------------------------------------------------------------- *)
-- 
GitLab