| author | wenzelm |
| Wed, 20 May 2020 20:45:43 +0200 | |
| changeset 71849 | 265bbad3d6af |
| parent 71673 | src/Pure/System/invoke_scala.scala@88dfbc382a3d |
| child 71850 | f640380aaf86 |
| permissions | -rw-r--r-- |
| 71849 | 1 |
/* Title: Pure/System/scala.scala |
|
43744
2c7e1565b4a3
some support to invoke Scala methods under program control;
wenzelm
parents:
diff
changeset
|
2 |
Author: Makarius |
|
2c7e1565b4a3
some support to invoke Scala methods under program control;
wenzelm
parents:
diff
changeset
|
3 |
|
| 71849 | 4 |
Support for Scala at runtime. |
|
43744
2c7e1565b4a3
some support to invoke Scala methods under program control;
wenzelm
parents:
diff
changeset
|
5 |
*/ |
|
2c7e1565b4a3
some support to invoke Scala methods under program control;
wenzelm
parents:
diff
changeset
|
6 |
|
|
2c7e1565b4a3
some support to invoke Scala methods under program control;
wenzelm
parents:
diff
changeset
|
7 |
package isabelle |
|
2c7e1565b4a3
some support to invoke Scala methods under program control;
wenzelm
parents:
diff
changeset
|
8 |
|
|
2c7e1565b4a3
some support to invoke Scala methods under program control;
wenzelm
parents:
diff
changeset
|
9 |
|
|
43751
8c7f69f1825b
proper InvocationTargetException.getCause for indirect exceptions;
wenzelm
parents:
43748
diff
changeset
|
10 |
import java.lang.reflect.{Method, Modifier, InvocationTargetException}
|
|
56730
e723f041b6d0
tuned signature -- separate pool for JFuture tasks, which can be canceled;
wenzelm
parents:
56667
diff
changeset
|
11 |
|
| 43748 | 12 |
import scala.util.matching.Regex |
|
43744
2c7e1565b4a3
some support to invoke Scala methods under program control;
wenzelm
parents:
diff
changeset
|
13 |
|
|
2c7e1565b4a3
some support to invoke Scala methods under program control;
wenzelm
parents:
diff
changeset
|
14 |
|
| 71849 | 15 |
object Scala |
|
43744
2c7e1565b4a3
some support to invoke Scala methods under program control;
wenzelm
parents:
diff
changeset
|
16 |
{
|
| 71849 | 17 |
/** invoke JVM method via Isabelle/Scala **/ |
18 |
||
| 43748 | 19 |
/* method reflection */ |
20 |
||
21 |
private val Ext = new Regex("(.*)\\.([^.]*)")
|
|
|
43744
2c7e1565b4a3
some support to invoke Scala methods under program control;
wenzelm
parents:
diff
changeset
|
22 |
private val STRING = Class.forName("java.lang.String")
|
|
2c7e1565b4a3
some support to invoke Scala methods under program control;
wenzelm
parents:
diff
changeset
|
23 |
|
| 43748 | 24 |
private def get_method(name: String): String => String = |
25 |
name match {
|
|
26 |
case Ext(class_name, method_name) => |
|
27 |
val m = |
|
28 |
try { Class.forName(class_name).getMethod(method_name, STRING) }
|
|
29 |
catch {
|
|
|
43751
8c7f69f1825b
proper InvocationTargetException.getCause for indirect exceptions;
wenzelm
parents:
43748
diff
changeset
|
30 |
case _: ClassNotFoundException | _: NoSuchMethodException => |
|
8c7f69f1825b
proper InvocationTargetException.getCause for indirect exceptions;
wenzelm
parents:
43748
diff
changeset
|
31 |
error("No such method: " + quote(name))
|
| 43748 | 32 |
} |
33 |
if (!Modifier.isStatic(m.getModifiers)) error("Not at static method: " + m.toString)
|
|
|
43751
8c7f69f1825b
proper InvocationTargetException.getCause for indirect exceptions;
wenzelm
parents:
43748
diff
changeset
|
34 |
if (m.getReturnType != STRING) error("Bad method return type: " + m.toString)
|
| 43748 | 35 |
|
|
43751
8c7f69f1825b
proper InvocationTargetException.getCause for indirect exceptions;
wenzelm
parents:
43748
diff
changeset
|
36 |
(arg: String) => {
|
|
8c7f69f1825b
proper InvocationTargetException.getCause for indirect exceptions;
wenzelm
parents:
43748
diff
changeset
|
37 |
try { m.invoke(null, arg).asInstanceOf[String] }
|
|
8c7f69f1825b
proper InvocationTargetException.getCause for indirect exceptions;
wenzelm
parents:
43748
diff
changeset
|
38 |
catch {
|
|
8c7f69f1825b
proper InvocationTargetException.getCause for indirect exceptions;
wenzelm
parents:
43748
diff
changeset
|
39 |
case e: InvocationTargetException if e.getCause != null => |
|
8c7f69f1825b
proper InvocationTargetException.getCause for indirect exceptions;
wenzelm
parents:
43748
diff
changeset
|
40 |
throw e.getCause |
|
8c7f69f1825b
proper InvocationTargetException.getCause for indirect exceptions;
wenzelm
parents:
43748
diff
changeset
|
41 |
} |
|
8c7f69f1825b
proper InvocationTargetException.getCause for indirect exceptions;
wenzelm
parents:
43748
diff
changeset
|
42 |
} |
| 43748 | 43 |
case _ => error("Malformed method name: " + quote(name))
|
44 |
} |
|
45 |
||
46 |
||
47 |
/* method invocation */ |
|
48 |
||
49 |
object Tag extends Enumeration |
|
|
43744
2c7e1565b4a3
some support to invoke Scala methods under program control;
wenzelm
parents:
diff
changeset
|
50 |
{
|
| 65638 | 51 |
val NULL, OK, ERROR, FAIL, INTERRUPT = Value |
| 43748 | 52 |
} |
|
43744
2c7e1565b4a3
some support to invoke Scala methods under program control;
wenzelm
parents:
diff
changeset
|
53 |
|
| 43748 | 54 |
def method(name: String, arg: String): (Tag.Value, String) = |
55 |
Exn.capture { get_method(name) } match {
|
|
56 |
case Exn.Res(f) => |
|
57 |
Exn.capture { f(arg) } match {
|
|
58 |
case Exn.Res(null) => (Tag.NULL, "") |
|
59 |
case Exn.Res(res) => (Tag.OK, res) |
|
|
56667
65e84b0ef974
more abstract Exn.Interrupt and POSIX return code;
wenzelm
parents:
56387
diff
changeset
|
60 |
case Exn.Exn(Exn.Interrupt()) => (Tag.INTERRUPT, "") |
| 44158 | 61 |
case Exn.Exn(e) => (Tag.ERROR, Exn.message(e)) |
| 43748 | 62 |
} |
| 44158 | 63 |
case Exn.Exn(e) => (Tag.FAIL, Exn.message(e)) |
| 43748 | 64 |
} |
|
43744
2c7e1565b4a3
some support to invoke Scala methods under program control;
wenzelm
parents:
diff
changeset
|
65 |
} |
|
52111
1fd184eaa310
explicit management of Session.Protocol_Handlers, with protocol state and functions;
wenzelm
parents:
49470
diff
changeset
|
66 |
|
|
1fd184eaa310
explicit management of Session.Protocol_Handlers, with protocol state and functions;
wenzelm
parents:
49470
diff
changeset
|
67 |
|
|
1fd184eaa310
explicit management of Session.Protocol_Handlers, with protocol state and functions;
wenzelm
parents:
49470
diff
changeset
|
68 |
/* protocol handler */ |
|
1fd184eaa310
explicit management of Session.Protocol_Handlers, with protocol state and functions;
wenzelm
parents:
49470
diff
changeset
|
69 |
|
| 71849 | 70 |
class Scala extends Session.Protocol_Handler |
|
52111
1fd184eaa310
explicit management of Session.Protocol_Handlers, with protocol state and functions;
wenzelm
parents:
49470
diff
changeset
|
71 |
{
|
| 65219 | 72 |
private var session: Session = null |
| 61561 | 73 |
private var futures = Map.empty[String, Future[Unit]] |
|
52111
1fd184eaa310
explicit management of Session.Protocol_Handlers, with protocol state and functions;
wenzelm
parents:
49470
diff
changeset
|
74 |
|
| 65219 | 75 |
override def init(init_session: Session): Unit = |
76 |
synchronized { session = init_session }
|
|
77 |
||
| 65220 | 78 |
override def exit(): Unit = synchronized |
79 |
{
|
|
80 |
for ((id, future) <- futures) cancel(id, future) |
|
81 |
futures = Map.empty |
|
82 |
} |
|
83 |
||
| 71849 | 84 |
private def fulfill(id: String, tag: Scala.Tag.Value, res: String): Unit = |
| 56387 | 85 |
synchronized |
86 |
{
|
|
87 |
if (futures.isDefinedAt(id)) {
|
|
| 71849 | 88 |
session.protocol_command("Scala.fulfill", id, tag.id.toString, res)
|
| 56387 | 89 |
futures -= id |
90 |
} |
|
|
52111
1fd184eaa310
explicit management of Session.Protocol_Handlers, with protocol state and functions;
wenzelm
parents:
49470
diff
changeset
|
91 |
} |
|
1fd184eaa310
explicit management of Session.Protocol_Handlers, with protocol state and functions;
wenzelm
parents:
49470
diff
changeset
|
92 |
|
| 65219 | 93 |
private def cancel(id: String, future: Future[Unit]) |
|
52111
1fd184eaa310
explicit management of Session.Protocol_Handlers, with protocol state and functions;
wenzelm
parents:
49470
diff
changeset
|
94 |
{
|
| 61561 | 95 |
future.cancel |
| 71849 | 96 |
fulfill(id, Scala.Tag.INTERRUPT, "") |
|
52111
1fd184eaa310
explicit management of Session.Protocol_Handlers, with protocol state and functions;
wenzelm
parents:
49470
diff
changeset
|
97 |
} |
|
1fd184eaa310
explicit management of Session.Protocol_Handlers, with protocol state and functions;
wenzelm
parents:
49470
diff
changeset
|
98 |
|
| 65219 | 99 |
private def invoke_scala(msg: Prover.Protocol_Output): Boolean = synchronized |
|
52111
1fd184eaa310
explicit management of Session.Protocol_Handlers, with protocol state and functions;
wenzelm
parents:
49470
diff
changeset
|
100 |
{
|
|
54442
c39972ddd672
more specific Protocol_Output: empty message.body, main content via bytes/text;
wenzelm
parents:
52582
diff
changeset
|
101 |
msg.properties match {
|
|
52111
1fd184eaa310
explicit management of Session.Protocol_Handlers, with protocol state and functions;
wenzelm
parents:
49470
diff
changeset
|
102 |
case Markup.Invoke_Scala(name, id) => |
|
1fd184eaa310
explicit management of Session.Protocol_Handlers, with protocol state and functions;
wenzelm
parents:
49470
diff
changeset
|
103 |
futures += (id -> |
| 61561 | 104 |
Future.fork {
|
| 71849 | 105 |
val (tag, result) = Scala.method(name, msg.text) |
| 65219 | 106 |
fulfill(id, tag, result) |
|
56730
e723f041b6d0
tuned signature -- separate pool for JFuture tasks, which can be canceled;
wenzelm
parents:
56667
diff
changeset
|
107 |
}) |
|
52111
1fd184eaa310
explicit management of Session.Protocol_Handlers, with protocol state and functions;
wenzelm
parents:
49470
diff
changeset
|
108 |
true |
|
1fd184eaa310
explicit management of Session.Protocol_Handlers, with protocol state and functions;
wenzelm
parents:
49470
diff
changeset
|
109 |
case _ => false |
|
1fd184eaa310
explicit management of Session.Protocol_Handlers, with protocol state and functions;
wenzelm
parents:
49470
diff
changeset
|
110 |
} |
|
1fd184eaa310
explicit management of Session.Protocol_Handlers, with protocol state and functions;
wenzelm
parents:
49470
diff
changeset
|
111 |
} |
|
1fd184eaa310
explicit management of Session.Protocol_Handlers, with protocol state and functions;
wenzelm
parents:
49470
diff
changeset
|
112 |
|
| 65219 | 113 |
private def cancel_scala(msg: Prover.Protocol_Output): Boolean = synchronized |
|
52111
1fd184eaa310
explicit management of Session.Protocol_Handlers, with protocol state and functions;
wenzelm
parents:
49470
diff
changeset
|
114 |
{
|
|
54442
c39972ddd672
more specific Protocol_Output: empty message.body, main content via bytes/text;
wenzelm
parents:
52582
diff
changeset
|
115 |
msg.properties match {
|
|
52111
1fd184eaa310
explicit management of Session.Protocol_Handlers, with protocol state and functions;
wenzelm
parents:
49470
diff
changeset
|
116 |
case Markup.Cancel_Scala(id) => |
|
1fd184eaa310
explicit management of Session.Protocol_Handlers, with protocol state and functions;
wenzelm
parents:
49470
diff
changeset
|
117 |
futures.get(id) match {
|
| 65219 | 118 |
case Some(future) => cancel(id, future) |
|
52111
1fd184eaa310
explicit management of Session.Protocol_Handlers, with protocol state and functions;
wenzelm
parents:
49470
diff
changeset
|
119 |
case None => |
|
1fd184eaa310
explicit management of Session.Protocol_Handlers, with protocol state and functions;
wenzelm
parents:
49470
diff
changeset
|
120 |
} |
|
1fd184eaa310
explicit management of Session.Protocol_Handlers, with protocol state and functions;
wenzelm
parents:
49470
diff
changeset
|
121 |
true |
|
1fd184eaa310
explicit management of Session.Protocol_Handlers, with protocol state and functions;
wenzelm
parents:
49470
diff
changeset
|
122 |
case _ => false |
|
1fd184eaa310
explicit management of Session.Protocol_Handlers, with protocol state and functions;
wenzelm
parents:
49470
diff
changeset
|
123 |
} |
|
1fd184eaa310
explicit management of Session.Protocol_Handlers, with protocol state and functions;
wenzelm
parents:
49470
diff
changeset
|
124 |
} |
|
1fd184eaa310
explicit management of Session.Protocol_Handlers, with protocol state and functions;
wenzelm
parents:
49470
diff
changeset
|
125 |
|
| 65219 | 126 |
val functions = |
127 |
List( |
|
| 71673 | 128 |
Markup.Invoke_Scala.name -> invoke_scala, |
129 |
Markup.Cancel_Scala.name -> cancel_scala) |
|
|
52111
1fd184eaa310
explicit management of Session.Protocol_Handlers, with protocol state and functions;
wenzelm
parents:
49470
diff
changeset
|
130 |
} |