-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathPerlCompiledScript.java
More file actions
86 lines (77 loc) · 3.11 KB
/
PerlCompiledScript.java
File metadata and controls
86 lines (77 loc) · 3.11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
package org.perlonjava.app.scriptengine;
import org.perlonjava.runtime.runtimetypes.RuntimeArray;
import org.perlonjava.runtime.runtimetypes.RuntimeCode;
import org.perlonjava.runtime.runtimetypes.RuntimeContextType;
import org.perlonjava.runtime.runtimetypes.RuntimeList;
import javax.script.CompiledScript;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptException;
import java.lang.invoke.MethodHandle;
/**
* PerlCompiledScript represents a pre-compiled Perl script that can be executed multiple times.
* <p>
* This class implements the CompiledScript interface from JSR 223, allowing Perl code to be
* compiled once and executed many times, which significantly improves performance when the same
* script needs to be run repeatedly.
* <p>
* The compiled code is stored as a generated class instance and invoked via MethodHandle to
* avoid ClassLoader issues.
*/
public class PerlCompiledScript extends CompiledScript {
private final PerlScriptEngine engine;
private final Object compiledInstance; // Compiled code instance
private final MethodHandle invoker; // MethodHandle to invoke apply()
/**
* Creates a new PerlCompiledScript.
*
* @param engine The script engine that compiled this script
* @param compiledInstance The compiled code instance
* @throws Exception if MethodHandle creation fails
*/
public PerlCompiledScript(PerlScriptEngine engine, Object compiledInstance) throws Exception {
this.engine = engine;
this.compiledInstance = compiledInstance;
// Create MethodHandle for apply() method
Class<?> instanceClass = compiledInstance.getClass();
this.invoker = RuntimeCode.lookup.findVirtual(instanceClass, "apply", RuntimeCode.methodType);
}
/**
* Executes the compiled script.
*
* @param context The script context (bindings, readers, writers)
* @return The result of script execution
* @throws ScriptException if execution fails
*/
@Override
public Object eval(ScriptContext context) throws ScriptException {
try {
// Execute the compiled code with empty arguments via MethodHandle
RuntimeArray args = new RuntimeArray();
RuntimeList result = (RuntimeList) invoker.invoke(compiledInstance, args, RuntimeContextType.SCALAR);
return result != null ? result.toString() : null;
} catch (Throwable t) {
ScriptException scriptException = new ScriptException("Error executing compiled Perl script: " + t.getMessage());
scriptException.initCause(t);
throw scriptException;
}
}
/**
* Returns the script engine that created this compiled script.
*
* @return The PerlScriptEngine instance
*/
@Override
public ScriptEngine getEngine() {
return engine;
}
/**
* Gets the underlying compiled code instance.
* This can be useful for advanced use cases.
*
* @return The compiled code instance
*/
public Object getCompiledInstance() {
return compiledInstance;
}
}