| author | blanchet | 
| Fri, 06 Feb 2015 19:17:17 +0100 | |
| changeset 59486 | 2025a17bb20f | 
| parent 56333 | 38f1422ef473 | 
| child 62505 | 9e2a65912111 | 
| permissions | -rw-r--r-- | 
| 43748 | 1 | (* Title: Pure/System/invoke_scala.ML | 
| 2 | Author: Makarius | |
| 3 | ||
| 49173 
fa01a202399c
eliminated potentially confusing terminology of Scala "layer";
 wenzelm parents: 
46774diff
changeset | 4 | JVM method invocation service via Isabelle/Scala. | 
| 43748 | 5 | *) | 
| 6 | ||
| 7 | signature INVOKE_SCALA = | |
| 8 | sig | |
| 43749 | 9 | val method: string -> string -> string | 
| 10 | val promise_method: string -> string -> string future | |
| 52111 
1fd184eaa310
explicit management of Session.Protocol_Handlers, with protocol state and functions;
 wenzelm parents: 
50682diff
changeset | 11 | exception Null | 
| 43748 | 12 | end; | 
| 13 | ||
| 14 | structure Invoke_Scala: INVOKE_SCALA = | |
| 15 | struct | |
| 16 | ||
| 52111 
1fd184eaa310
explicit management of Session.Protocol_Handlers, with protocol state and functions;
 wenzelm parents: 
50682diff
changeset | 17 | val _ = Session.protocol_handler "isabelle.Invoke_Scala"; | 
| 43749 | 18 | |
| 19 | ||
| 43748 | 20 | (* pending promises *) | 
| 21 | ||
| 52537 | 22 | val new_id = string_of_int o Counter.make (); | 
| 43748 | 23 | |
| 24 | val promises = | |
| 25 | Synchronized.var "Invoke_Scala.promises" (Symtab.empty: string future Symtab.table); | |
| 26 | ||
| 27 | ||
| 28 | (* method invocation *) | |
| 29 | ||
| 43749 | 30 | fun promise_method name arg = | 
| 43748 | 31 | let | 
| 32 | val id = new_id (); | |
| 56333 
38f1422ef473
support bulk messages consisting of small string segments, which are more healthy to the Poly/ML RTS and might prevent spurious GC crashes such as MTGCProcessMarkPointers::ScanAddressesInObject;
 wenzelm parents: 
52537diff
changeset | 33 | fun abort () = Output.protocol_message (Markup.cancel_scala id) []; | 
| 44298 
b8f8488704e2
Future.promise: explicit abort operation (like uninterruptible future job);
 wenzelm parents: 
43761diff
changeset | 34 | val promise = Future.promise abort : string future; | 
| 43748 | 35 | val _ = Synchronized.change promises (Symtab.update (id, promise)); | 
| 56333 
38f1422ef473
support bulk messages consisting of small string segments, which are more healthy to the Poly/ML RTS and might prevent spurious GC crashes such as MTGCProcessMarkPointers::ScanAddressesInObject;
 wenzelm parents: 
52537diff
changeset | 36 | val _ = Output.protocol_message (Markup.invoke_scala name id) [arg]; | 
| 43748 | 37 | in promise end; | 
| 38 | ||
| 43749 | 39 | fun method name arg = Future.join (promise_method name arg); | 
| 40 | ||
| 43748 | 41 | |
| 52111 
1fd184eaa310
explicit management of Session.Protocol_Handlers, with protocol state and functions;
 wenzelm parents: 
50682diff
changeset | 42 | (* fulfill *) | 
| 43748 | 43 | |
| 52111 
1fd184eaa310
explicit management of Session.Protocol_Handlers, with protocol state and functions;
 wenzelm parents: 
50682diff
changeset | 44 | exception Null; | 
| 
1fd184eaa310
explicit management of Session.Protocol_Handlers, with protocol state and functions;
 wenzelm parents: 
50682diff
changeset | 45 | |
| 
1fd184eaa310
explicit management of Session.Protocol_Handlers, with protocol state and functions;
 wenzelm parents: 
50682diff
changeset | 46 | fun fulfill id tag res = | 
| 43748 | 47 | let | 
| 48 | val result = | |
| 49 | (case tag of | |
| 50 | "0" => Exn.Exn Null | |
| 43761 
e72ba84ae58f
tuned signature -- corresponding to Scala version;
 wenzelm parents: 
43749diff
changeset | 51 | | "1" => Exn.Res res | 
| 43748 | 52 | | "2" => Exn.Exn (ERROR res) | 
| 53 | | "3" => Exn.Exn (Fail res) | |
| 49470 | 54 | | "4" => Exn.Exn Exn.Interrupt | 
| 43748 | 55 | | _ => raise Fail "Bad tag"); | 
| 56 | val promise = | |
| 57 | Synchronized.change_result promises | |
| 58 | (fn tab => (the (Symtab.lookup tab id), Symtab.delete id tab)); | |
| 59 | val _ = Future.fulfill_result promise result; | |
| 60 | in () end; | |
| 61 | ||
| 52111 
1fd184eaa310
explicit management of Session.Protocol_Handlers, with protocol state and functions;
 wenzelm parents: 
50682diff
changeset | 62 | val _ = | 
| 
1fd184eaa310
explicit management of Session.Protocol_Handlers, with protocol state and functions;
 wenzelm parents: 
50682diff
changeset | 63 | Isabelle_Process.protocol_command "Invoke_Scala.fulfill" | 
| 
1fd184eaa310
explicit management of Session.Protocol_Handlers, with protocol state and functions;
 wenzelm parents: 
50682diff
changeset | 64 | (fn [id, tag, res] => | 
| 
1fd184eaa310
explicit management of Session.Protocol_Handlers, with protocol state and functions;
 wenzelm parents: 
50682diff
changeset | 65 | fulfill id tag res | 
| 
1fd184eaa310
explicit management of Session.Protocol_Handlers, with protocol state and functions;
 wenzelm parents: 
50682diff
changeset | 66 | handle exn => if Exn.is_interrupt exn then () else reraise exn); | 
| 
1fd184eaa310
explicit management of Session.Protocol_Handlers, with protocol state and functions;
 wenzelm parents: 
50682diff
changeset | 67 | |
| 43748 | 68 | end; | 
| 69 |