使用Java實現JS指令碼引擎
專案地址
https://github.com/GitHub-Laz...
- 支援解析js指令碼生成語法樹
- 支援執行完整js指令碼
- 支援安全模式執行單行表示式
- 支援設定超時時間
打包後命令列執行
git clone https://github.com/GitHub-Laziji/js-engine.git
cd js-engine
mvn package
cd target
java -jar ./js-engine-1.0-SNAPSHOT-jar-with-dependencies.jar ./test.js
或者安裝後直接引入依賴
git clone https://github.com/GitHub-Laziji/js-engine.git
cd js-engine
mvn install
<dependency>
<groupId>org.laziji.commons</groupId>
<artifactId>js-engine</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
1. 生成語法樹 並輸出格式化程式碼
示例程式碼
class Test{
public static void main(String[] args){
Top.init();
DocNode doc = Top.compile("let a=1+2,b=3,c=\"string\",d=a*(b+c/2),func=function(){};");
System.out.println(doc);
}
}
輸出
let a = 1 + 2, b = 3, c = "string", d = a * (b + c / 2), func = function () {
}
2. 執行完整指令碼
以下示例為執行快排演算法(執行環境執行緒隔離)
示例程式碼
class Test{
/**
* function sort(arr, i, j) {
* if (i >= j) {
* return;
* }
* let p = i, q = j;
* let temp = arr[p];
* while (p < q) {
* while (p < q && arr[q] >= temp) {
* q-=1;
* }
* arr[p] = arr[q];
* while (p < q && arr[p] <= temp) {
* p+=1;
* }
* arr[q] = arr[p];
* }
* arr[q] = temp;
* sort(arr, i, q - 1);
* sort(arr, q + 1, j);
* }
*
* let arr = [234, 57, 12, 123, 346, 1234, 2];
*
* sort(arr, 0, arr.length - 1);
*/
public static void main(String[] args){
Top.init();
Top.eval("function sort(arr, i, j) {\n" +
" if (i >= j) {\n" +
" return;\n" +
" }\n" +
" let p = i, q = j;\n" +
" let temp = arr[p];\n" +
" while (p < q) {\n" +
" while (p < q && arr[q] >= temp) {\n" +
" q-=1;\n" +
" }\n" +
" arr[p] = arr[q];\n" +
" while (p < q && arr[p] <= temp) {\n" +
" p+=1;\n" +
" }\n" +
" arr[q] = arr[p];\n" +
" }\n" +
" arr[q] = temp;\n" +
" sort(arr, i, q - 1);\n" +
" sort(arr, q + 1, j);\n" +
"}\n" +
"\n" +
"let arr = [234, 57, 12, 123, 346, 1234, 2];\n" +
"\n" +
"sort(arr, 0, arr.length - 1);");
Top.loop();
System.out.println(Top.getThreadLocalTop().getMainContexts().getContexts().peek().toSimpleString());
}
}
輸出
arr: [2, 12, 57, 123, 234, 346, 1234]
sort: [object Object]
3. 執行單行表示式
該模式下只支援單行表示式 並且無法使用for、while、function、lambda、import關鍵字
示例程式碼
class Test{
public static void main(String[] args){
Top.init();
System.out.println(Top.exprEval("'hello '+(1*2*3*4)"));
}
}
輸出
hello 24
4. 設定超時時間
通過Top.getThreadLocalTop().setOvertime(100L);
設定超時時間,單位毫秒
示例程式碼
class Test{
public static void main(String[] args){
Top.init();
Top.getThreadLocalTop().setOvertime(100L);
Top.addInternalModules("sys", new SystemModuleValue());
Top.eval("import { print } from \"sys\";\n" +
"\n" +
"let i=1;\n" +
"while(true){\n" +
" print(i++);\n" +
"}");
Top.loop();
}
}
輸出
1
2
3
...
org.laziji.commons.js.exception.RunException: Run timeout.
...