On Sat, 9 May 2020 15:15:52 GMT, Kevin Rushforth <k...@openjdk.org> wrote:

>> ============================ test units for: compile PI+fallback
>> 
>> tests/system/src/testscriptapp2/java/mymod/myapp2/FXMLScriptDeployment2Compile_Off.java
>> ... use compile PI to set off compilation of scripts; each script code 
>> starts with "demo_02_"
>> 
>> tests/system/src/testscriptapp2/resources/mymod/myapp2/demo_02_off.fxml
>> ... set compilation for scripts off ("<?compile false?>"), therefore no 
>> script gets compiled
>> 
>> ---
>> 
>> tests/system/src/testscriptapp2/java/mymod/myapp2/FXMLScriptDeployment2Compile_Off_On.java
>> ... alternatively uses compile PI to turn compilation off and on; the script 
>> code starts alternatively with "demo_02_"
>> and "RgfPseudoCompiledScript.eval(", depending on the state set with the PI
>> tests/system/src/testscriptapp2/resources/mymod/myapp2/demo_02_off_on.fxml
>> ... starts out explicitly with "<?compile false?>" switching the state after 
>> each element containing a script
>> 
>> ---
>> 
>>  
>> tests/system/src/testscriptapp2/java/mymod/myapp2/FXMLScriptDeployment2Compile_On.java
>>  ... no compile PI given, hence compilation of scripts is on; each script 
>> code starts with
>>  "RgfPseudoCompiledScript.eval("
>>  tests/system/src/testscriptapp2/resources/mymod/myapp2/demo_02_on.fxml
>> ... no compile PI given, starts out to compile scripts by default
>> 
>> ---
>> 
>> tests/system/src/testscriptapp2/java/mymod/myapp2/FXMLScriptDeployment2Compile_On_Off.java
>> ... alternatively uses compile PI to turn compilation on and off; the script 
>> code starts alternatively with
>> "RgfPseudoCompiledScript.eval(", and "demo_02_" depending on the state set 
>> with the PI
>> tests/system/src/testscriptapp2/resources/mymod/myapp2/demo_02_on_off.fxml
>> ... starts out explicitly with "<?compile true?>" switching the state after 
>> each element containing a script (sometimes
>> using PI "<?compile?>" to test setting it to true)
>> ---
>> 
>> tests/system/src/testscriptapp2/java/mymod/myapp2/FXMLScriptDeployment2Compile_Fail_Compilation.java
>> ... although compile scripts is on, none of the scripts get compiled as they 
>> all contain the string "FAIL COMPILATION"
>> which causes RgfPseudoScriptEngineCompilable.compile(...) to throw a 
>> ScriptException causing the fallback to be used;
>> all scripts therefore start with "demo_03_"
>>  
>> tests/system/src/testscriptapp2/resources/mymod/myapp2/demo_03_fail_compile.fxml
>>  ... explicitly turns on compilation (which is on by default anyway), adds 
>> "FAIL COMPILATION" to all inline scripts and
>>  to all external scripts with the filename that starts with "demo_03_"
>
> I think the approach proposed in this PR is the best solution for this 
> enhancement. Go ahead and remove the `WIP` from
> the title, and we can proceed with the review.
> The interface and behavior change will need to be specified in the API docs. 
> This can be done by modifying the
> [Introduction to
> FXML](https://github.com/openjdk/jfx/blob/master/modules/javafx.fxml/src/main/docs/javafx/fxml/doc-files/introduction_to_fxml.html)
> document. I recommend documenting the new behavior and `<?compile>` attribute 
> somewhere in the
> [Scripting](https://github.com/openjdk/jfx/blob/master/modules/javafx.fxml/src/main/docs/javafx/fxml/doc-files/introduction_to_fxml.html#L769)
> section.  As discussed on the mailing list, this will need a CSR, which 
> should include the changes to the docs.

Suggested CSR:

Summary
=======
Have javafx.fxml.FXMLLoader compile FXML scripts before evaluating them, if the 
script engine
implements the javax.script.Compilable interface to speed up execution. In case 
compilation
throws a javax.script.ScriptException fall back to evaluating the uncompiled 
script. Allow
control of script compilation with a "compile" PI for FXML files.

Problem
=======
javafx.fxml.FXMLLoader is able to execute scripts in Java script languages
(javax.script.ScriptEngine implementations) referred to or embedded in a FXML 
file.

If a script engine implements the javax.script.Compilable interface, then such 
scripts could be
compiled and the resulting javax.script.CompiledScript could be executed 
instead using its
eval() methods.

Evaluating the javax.script.CompiledScript objects may help speed up the 
execution of script
invocations, especially for scripts defined for event attributes in FXML 
elements (e.g. like
onMouseMove) which may be repetitively invoked and evaluated.

Solution
========
Before evaluating the script code test whether the javax.script.ScriptEngine 
implements
javax.script.Compilable. If so, compile the script to a 
javax.script.CompiledScript object first
and then use its eval() method to evaluate the script, otherwise continue to 
use the
javax.script.ScriptEngine's eval() method instead. Should compilation of a 
script yield
(unexpectedly) a javax.script.ScriptException then fall back to using the
javax.script.ScriptEngine's eval() method. A new process instruction "compile" 
allows control of
the compilation of scripts ("true" sets compilation on, "false" to set 
compilation off) in FXML
files.

Specification
=============
If a javax.script.ScriptEngine implements the javax.script.Compilable 
interface, then use its
compile() method to compile the script to a javax.script.CompiledScript object 
and use its
eval() method to run the script. In the case that the compilation throws 
(unexpectedly) a
javax.script.ScriptException log a warning and fall back to using the
javax.script.ScriptEngine's eval() method instead.
To allow setting this feature off and on while processing the FXML file a 
"compile" process
instruction ("<?compile false?>" or "<?compile true?>") gets defined that 
allows to turn
compilation off and on throughout a FXML file.

-------------

PR: https://git.openjdk.java.net/jfx/pull/192

Reply via email to