Explorar el Código

add Rt Scheduler.

ZRY hace 1 año
padre
commit
ee8f8f2b8a

+ 1 - 1
docs/engine/README.md

@@ -41,7 +41,7 @@ JSVM即JS解释器,JSEnv提供暴露到JS运行时环境可以调用的各类
 ### 示例
 
 请前往`example\cmd`查看示例。该示例包含一个简单的可以运行的引擎代码,
-以及一个babel工程,将新版本ECMAScript转换到该引擎支持的ECMScript 5。
+以及一个webpack工程,将新版本ECMAScript转换到该引擎支持的ECMScript 5。
 
 在`example`目录使用`make`完成编译。
 

+ 35 - 14
docs/js/README.md

@@ -5,39 +5,60 @@
 ### main.js基本结构
 
 ```javascript
-var main = {
+module.exports = {
     setup: function (){
-        
+
     },
     loop: function (){
-        
+
     },
     cleanup: function (){
-        
+
     }
-};
-main
+}
 ```
 
+### JS API Reference
+
+每个内置Rt包的API参考参见各`Rt.<RtName>.<Locale>.md`.
+
+#### module
+
+对全局对象的引用。
+
+#### lsrt() -> string[]
+
+返回一个字符串列表,列出所有注册的Rt实例的名称。
+
 ## en-US
 
-### Basic index.js structure
+### Basic main.js structure
 
 ```javascript
-var main = {
+module.exports = {
     setup: function (){
-        
+
     },
     loop: function (){
-        
+
     },
     cleanup: function (){
-        
+
     }
-};
-main
+}
 ```
 
 ### JS API Reference
 
-See `Rt.<RtName>.<Locale>.md`.
+
+For each Rt Package, See `Rt.<RtName>.<Locale>.md`.
+
+#### module
+
+A reference to global object.
+
+#### lsrt()
+
+return name list of registed Rt package.
+
+

+ 17 - 2
docs/js/Rt.Runtime.zh-CN.md

@@ -6,7 +6,9 @@
 
 ## API Reference
 
-### quit()
+### quit(...)
+
+为了确保退出容易执行成功,它接受任何类型参数。
 
 当该函数被调用时,向解释器发送一个Interrupt,将会结束当前解释器实例的运行。
 
@@ -14,4 +16,17 @@
 `Err_JSVMAbortByInterruit`,由go这侧程序决定接下来的行为。
 
 若在`loop`中调用,则主循环退出,`RunLoop`函数返回`nil`,不会返回错误。
-(因为除非受到Interrup,主循环是会不断进行的,所以此时调用quit视为一种正常的退出行为)
+(因为除非受到Interrup,主循环是会不断进行的,所以此时调用quit视为一种正常的退出行为)
+
+### sleep(int64 timeMs)
+
+睡眠,单位为毫秒,将被转化为int64,故需传入符合范围的整数。
+
+### getScope() -> string
+
+获取当前执行的scope,返回值可能为以下值:
+
+* `load`
+* `setup`
+* `loop`
+* `cleanup`

+ 9 - 1
example/cmd/go.mod

@@ -3,12 +3,20 @@ module git.swzry.com/ProjectNagae/NagaeJSVM/example/cmd
 go 1.19
 
 require (
+	git.swzry.com/ProjectNagae/NagaeJSVM/ngjsvm v0.0.0-20230420233959-5ee38c55ac10
 	git.swzry.com/zry/GoHiedaLogger/hiedabke_console v0.0.0-20230124221017-3a7a6ec97a0d
 	git.swzry.com/zry/GoHiedaLogger/hiedalog v0.0.0-20230124221017-3a7a6ec97a0d
+	git.swzry.com/zry/go-lazy-quiter v0.0.0-20230314224806-9477d49516ef
+	github.com/oklog/run v1.1.0
 	github.com/spf13/afero v1.9.5
 )
 
 require (
+	github.com/dlclark/regexp2 v1.9.0 // indirect
+	github.com/dop251/goja v0.0.0-20230402114112-623f9dda9079 // indirect
+	github.com/dop251/goja_nodejs v0.0.0-20230322100729-2550c7b6c124 // indirect
+	github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect
+	github.com/google/pprof v0.0.0-20230406165453-00490a63f317 // indirect
 	github.com/ttacon/chalk v0.0.0-20160626202418-22c06c80ed31 // indirect
-	golang.org/x/text v0.3.7 // indirect
+	golang.org/x/text v0.9.0 // indirect
 )

+ 52 - 1
example/cmd/go.sum

@@ -36,21 +36,41 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RX
 cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
 cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo=
 dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
+git.swzry.com/ProjectNagae/NagaeJSVM/ngjsvm v0.0.0-20230420233959-5ee38c55ac10 h1:ctiyc6tDOyKyL7A4h+vryv+NpgiEKc6dnQz9CS4zaEI=
+git.swzry.com/ProjectNagae/NagaeJSVM/ngjsvm v0.0.0-20230420233959-5ee38c55ac10/go.mod h1:i7bofpnkVR/wuMXbiq12KOPfpG/lp9OCjz5zDB/dO9A=
 git.swzry.com/zry/GoHiedaLogger/hiedabke_console v0.0.0-20230124221017-3a7a6ec97a0d h1:KP1no0UMetYZlzL9Jb6aCqA/99BGsN60hwP0JA4YqU8=
 git.swzry.com/zry/GoHiedaLogger/hiedabke_console v0.0.0-20230124221017-3a7a6ec97a0d/go.mod h1:QKGs1+W8+y6/RMTSaAv6LwJnY9/7zaGs38IbwmYlFbo=
 git.swzry.com/zry/GoHiedaLogger/hiedalog v0.0.0-20230124221017-3a7a6ec97a0d h1:Op3+BKhQiMKQnUz892FWFyIFG4OUC7cc3oawFVzJfT0=
 git.swzry.com/zry/GoHiedaLogger/hiedalog v0.0.0-20230124221017-3a7a6ec97a0d/go.mod h1:NMU7558kNXCUuK0qKYQMtYK/kn2lhwelnij295H3pdU=
+git.swzry.com/zry/go-lazy-quiter v0.0.0-20230314224806-9477d49516ef h1:nUXmES3nWAIvcbTYCXSM9d3T2WyUUM+iCXYt6YKprPg=
+git.swzry.com/zry/go-lazy-quiter v0.0.0-20230314224806-9477d49516ef/go.mod h1:eZ9m10j5Jyx/ss9rR+njRozBr+3pn6vnLGZdSqZrGSE=
 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
 github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
 github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
+github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY=
 github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
+github.com/chzyer/readline v1.5.0/go.mod h1:x22KAscuvRqlLoK9CsoYsmxoXZMMFVyOl86cAH8qUic=
 github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
+github.com/chzyer/test v0.0.0-20210722231415-061457976a23/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
 github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
 github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
 github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
 github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
+github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
+github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
+github.com/dlclark/regexp2 v1.9.0 h1:pTK/l/3qYIKaRXuHnEnIf7Y5NxfRPfpb7dis6/gdlVI=
+github.com/dlclark/regexp2 v1.9.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
+github.com/dop251/goja v0.0.0-20211022113120-dc8c55024d06/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk=
+github.com/dop251/goja v0.0.0-20221118162653-d4bf6fde1b86/go.mod h1:yRkwfj0CBpOGre+TwBsqPV0IH0Pk73e4PXJOeNDboGs=
+github.com/dop251/goja v0.0.0-20230402114112-623f9dda9079 h1:xkbJGxVnk5sM8/LXeTKaBOfAZrI+iqvIPyH8oK1c6CQ=
+github.com/dop251/goja v0.0.0-20230402114112-623f9dda9079/go.mod h1:QMWlm50DNe14hD7t24KEqZuUdC9sOTy8W6XbCU1mlw4=
+github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y=
+github.com/dop251/goja_nodejs v0.0.0-20211022123610-8dd9abb0616d/go.mod h1:DngW8aVqWbuLRMHItjPUyqdj+HWPvnQe8V8y1nDpIbM=
+github.com/dop251/goja_nodejs v0.0.0-20230322100729-2550c7b6c124 h1:QDuDMgEkC/lnmvk0d/fZfcUUml18uUbS9TY5QtbdFhs=
+github.com/dop251/goja_nodejs v0.0.0-20230322100729-2550c7b6c124/go.mod h1:0tlktQL7yHfYEtjcRGi/eiOkbDR5XF7gyFFvbC5//E0=
 github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
 github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
 github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
@@ -60,6 +80,8 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7
 github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
+github.com/go-sourcemap/sourcemap v2.1.3+incompatible h1:W1iEw64niKVGogNgBN3ePyLFfuisuzeidWPMPWmECqU=
+github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg=
 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
 github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
 github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
@@ -109,6 +131,9 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf
 github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
 github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
 github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
+github.com/google/pprof v0.0.0-20230207041349-798e818bf904/go.mod h1:uglQLonpP8qtYCYyzA+8c/9qtqgA3qsXGYqCPKARAFg=
+github.com/google/pprof v0.0.0-20230406165453-00490a63f317 h1:hFhpt7CTmR3DX+b4R19ydQFtofxT0Sv3QsKNMVQYTMQ=
+github.com/google/pprof v0.0.0-20230406165453-00490a63f317/go.mod h1:79YE0hCXdHag9sBkw2o+N/YnZtTkXi0UT9Nnixa5eYk=
 github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
 github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
@@ -118,18 +143,25 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ
 github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
 github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
 github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
+github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w=
 github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
 github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
 github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
 github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
 github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
+github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
+github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
 github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
 github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
+github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
+github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA=
+github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU=
 github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
 github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
+github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
 github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM=
 github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
@@ -142,6 +174,7 @@ github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
 github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
 go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
 go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
 go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
@@ -154,6 +187,7 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U
 golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
+golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@@ -188,6 +222,7 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
 golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -220,6 +255,8 @@ golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v
 golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
 golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
 golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
+golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -239,6 +276,7 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ
 golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -274,7 +312,13 @@ golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA=
 golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -282,8 +326,11 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
+golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
+golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
+golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
 golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -334,6 +381,7 @@ golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4f
 golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
 golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
 golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
+golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -428,8 +476,11 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj
 google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
 gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
 gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
+gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=

+ 18 - 13
example/cmd/main.go

@@ -5,6 +5,8 @@ import (
 	"git.swzry.com/ProjectNagae/NagaeJSVM/ngjsvm"
 	"git.swzry.com/zry/GoHiedaLogger/hiedabke_console"
 	"git.swzry.com/zry/GoHiedaLogger/hiedalog"
+	lazyquiter "git.swzry.com/zry/go-lazy-quiter"
+	"github.com/oklog/run"
 	"github.com/spf13/afero"
 	"os"
 	"path"
@@ -14,6 +16,7 @@ import (
 var Logger *hiedalog.HiedaLogger
 var JsFile string
 var DebugMode bool
+var LazyQuiter *lazyquiter.RunGroupQuiter
 
 func main() {
 	// Parse command line argument
@@ -68,6 +71,7 @@ func main() {
 	jsenv.AddRt("logger", &ngjsvm.JSRtLogger{
 		LogFunc: ngjsvm.JSRtLoggerLogFuncFromHiedaLogger(Logger, "js-log"),
 	})
+	jsenv.AddRt("scheduler", &ngjsvm.JSRtScheduler{})
 	jsenv.AddRt("nest_test", ngjsvm.NewJSRtNest(map[string]ngjsvm.JsRtInterface{
 		"logger1": &ngjsvm.JSRtLogger{
 			LogFunc: ngjsvm.JSRtLoggerLogFuncFromHiedaLogger(Logger, "js-sub-log1"),
@@ -85,29 +89,30 @@ func main() {
 	// Run 'setup'
 	err = engine.ExecSetup()
 	if err != nil {
-		Logger.LogPrint("main", hiedalog.DLN_ERROR, "run 'setup' failed: ", err)
+		Logger.LogPrint("main", hiedalog.DLN_ERROR, "Run 'setup' failed: ", err)
 		// will continue even if 'setup' failed.
 		// but you can end program when 'setup' failed.
 		// don't forget to do engine dispose
 	}
 
-	// Run loop
-
-	// if you have "github.com/oklog/run" you can uncomment these codes
-
-	//rg := &run.Group{}
-	//rg.Add(engine.RunLoop, engine.StopLoop)
-	//err = rg.Run()
+	// Init lazyquiter for catching `Ctrl+C`
+	LazyQuiter = lazyquiter.NewRunGroupQuiter()
+	LazyQuiter.SignalNotifyFunc = func(sig os.Signal) {
+		Logger.LogPrint("main", hiedalog.DLN_INFO, "Quit by user Ctrl+C abort.")
+	}
 
-	// or simply use this below
-	err = engine.RunLoop()
+	// Run loop
+	rg := &run.Group{}
+	rg.Add(LazyQuiter.Run, LazyQuiter.Stop)
+	rg.Add(engine.RunLoop, engine.StopLoop)
+	err = rg.Run()
 	if err != nil {
 		if err == ngjsvm.Err_JSVMAbortByInterruit {
 			// this means it exit by interrupt,
 			// for example, a 'runtime.quit()' executed in script will cause this
-			Logger.LogPrint("main", hiedalog.DLN_INFO, "js vm interrupted")
+			Logger.LogPrint("main", hiedalog.DLN_INFO, "JS VM interrupted")
 		} else {
-			Logger.LogPrint("main", hiedalog.DLN_FATAL, "run 'loop' failed: ", err)
+			Logger.LogPrint("main", hiedalog.DLN_FATAL, "Run 'loop' failed: ", err)
 			return
 		}
 	}
@@ -115,7 +120,7 @@ func main() {
 	// Run 'cleanup'
 	err = engine.ExecCleanup()
 	if err != nil {
-		Logger.LogPrint("main", hiedalog.DLN_ERROR, "run 'cleanup' failed: ", err)
+		Logger.LogPrint("main", hiedalog.DLN_ERROR, "Run 'cleanup' failed: ", err)
 	}
 
 	// because we set 'defer engine.Dispose()' so we don't need to do it.

+ 26 - 2
example/js-src/src/index.js

@@ -1,19 +1,43 @@
 import module_test from "./module_test"
 
+logger.log("current scope: ", runtime.getScope())
+
 export default {
-  counter: 20,
+  counter: 10,
+  intv: 0,
   setup(){
     logger.log("hello, this is setup function")
     logger.log("module test: a=", module_test.a, " ,b=", module_test.b)
+    logger.log("current scope: ", runtime.getScope())
+    logger.log(lsrt())
+    logger.debug()
+    logger.trace(1, 2, 3)
+    logger.info({a: 1, b: 2})
+    logger.warn({a: 1, b: 2}, ["a", "b", "c"], "d", 15.2)
+    logger.error([{a: 1, b: 2}, {}, ["c", "d"], "e", 5.6])
+    let f1 = function () {
+      logger.log("scheduler interval")
+    }
+    let f2 = function () {
+      logger.log("scheduler timeout")
+    }
+    this.intv = scheduler.setInterval(f1, 1321)
+    scheduler.setTimeout(f2, 2500)
   },
   loop(){
     this.counter--
-    logger.log("loop...")
+    logger.log("scope:", runtime.getScope(),", remain: ", this.counter)
     if(this.counter <= 0){
       runtime.quit()
     }
+    if(this.counter < 4){
+      scheduler.clearInterval(this.intv)
+    }
+    runtime.sleep(1500)
   },
   cleanup(){
+    logger.log("current scope: ", runtime.getScope())
     logger.log("clean up...")
+    scheduler.clearAll()
   },
 }

+ 2 - 1
example/js-src/webpack.config.js

@@ -14,7 +14,8 @@ module.exports = {
     },
 
   },
-  mode: 'development',
+  //mode: 'development',
+  mode: 'production',
   target: 'es5',
   devtool: false,
   plugins: [

+ 11 - 1
go.work.sum

@@ -8,8 +8,11 @@ github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ
 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802 h1:1BDTz0u9nC3//pOCMdNH+CiXJVYJh5UQNCOBG7jbELc=
 github.com/census-instrumentation/opencensus-proto v0.2.1 h1:glEXhBS5PSLLv4IXzLA5yPRVX4bilULVyxxbrfOtDAk=
 github.com/chzyer/logex v1.2.0 h1:+eqR0HfOetur4tgnC8ftU5imRnhi4te+BadWS95c5AM=
+github.com/chzyer/logex v1.2.1/go.mod h1:JLbx6lG2kDbNRFnfkgvh4eRJRPX1QCoOIWomwysCBrQ=
 github.com/chzyer/readline v1.5.0 h1:lSwwFrbNviGePhkewF1az4oLmcwqCZijQ2/Wi3BGHAI=
+github.com/chzyer/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObkaSkeBlk=
 github.com/chzyer/test v0.0.0-20210722231415-061457976a23 h1:dZ0/VyGgQdVGAss6Ju0dt5P0QltE0SFY5Woh6hbIfiQ=
+github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8=
 github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI=
 github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403 h1:cqQfy1jclcSy/FwLjemeg3SR1yaINm74aQyupQ0Bl8M=
 github.com/creack/pty v1.1.9 h1:uDmaGzcdjhF4i/plgjmEsriH11Y0o7RKapEf/LDaM3w=
@@ -18,7 +21,6 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad h1:E
 github.com/envoyproxy/protoc-gen-validate v0.1.0 h1:EQciDnbrYxy13PgWoY8AqoxGiPrpgBZ1R8UNe3ddc+A=
 github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1 h1:QbL/5oDUmRBzO9/Z7Seo6zf912W/a6Sr4Eu0G/3Jho0=
 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4 h1:WtGNWLvXpe6ZudgnXrq0barxBImvnnJoMEhXAzcbM0I=
-github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
 github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY=
 github.com/golang/mock v1.4.4 h1:l75CXGRSwbaYNpl/Z2X1XIIAMSCquvXgpVZDhwEIJsc=
 github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM=
@@ -32,6 +34,7 @@ github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+
 github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8 h1:tlyzajkF3030q6M8SvmJSemC9DTHL/xaMa18b65+JM4=
 github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
 github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2 h1:rcanfLhLDA8nozr/K289V1zcntHr3V+SHlXwzz1ZI2g=
+github.com/ianlancetaylor/demangle v0.0.0-20220517205856-0058ec4f073c/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w=
 github.com/jstemmer/go-junit-report v0.9.1 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o=
 github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg=
 github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8=
@@ -53,13 +56,20 @@ golang.org/x/image v0.0.0-20190802002840-cff245a6509b h1:+qEpEAPhDZ1o0x3tHzZTQDA
 golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5 h1:2M3HP5CCK1Si9FQhwnzYhXdG6DXeebvUHFpre8QvbyI=
 golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028 h1:4+4C/Iv2U4fMZBiMCc98MG1In4gJY5YRhtpDNeDeHWs=
 golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
+golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
 golang.org/x/net v0.0.0-20220722155237-a158d28d115b h1:PxfKdU9lEEDYjdIzOtC4qFWgkU2rGHdKlKowJSMN9h0=
+golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
 golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99 h1:5vD4XjIc0X5+kHZjx4UecYdjA6mJo+XXNoaW0EjU5Os=
 golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 h1:uVc8UZUe6tr40fFVnUP5Oj+veunVezqYl9z7DYw9xzw=
 golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s=
+golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
+golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
+golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
 golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs=
 golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU=
+golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
 golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
 google.golang.org/api v0.40.0 h1:uWrpz12dpVPn7cojP82mk02XDgTJLDPc2KbVTxrWb4A=
 google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=

+ 2 - 0
ngjsvm/go.mod

@@ -4,6 +4,7 @@ go 1.19
 
 require (
 	git.swzry.com/zry/GoHiedaLogger/hiedalog v0.0.0-20230124221017-3a7a6ec97a0d
+	github.com/GUAIK-ORG/go-snowflake v0.0.0-20200116064823-220c4260e85f
 	github.com/dop251/goja v0.0.0-20230402114112-623f9dda9079
 	github.com/dop251/goja_nodejs v0.0.0-20211022123610-8dd9abb0616d
 	github.com/spf13/afero v1.9.5
@@ -12,6 +13,7 @@ require (
 require (
 	github.com/dlclark/regexp2 v1.7.0 // indirect
 	github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect
+	github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b // indirect
 	github.com/google/pprof v0.0.0-20230207041349-798e818bf904 // indirect
 	golang.org/x/text v0.3.8 // indirect
 )

+ 3 - 0
ngjsvm/go.sum

@@ -40,6 +40,8 @@ git.swzry.com/zry/GoHiedaLogger/hiedalog v0.0.0-20230124221017-3a7a6ec97a0d h1:O
 git.swzry.com/zry/GoHiedaLogger/hiedalog v0.0.0-20230124221017-3a7a6ec97a0d/go.mod h1:NMU7558kNXCUuK0qKYQMtYK/kn2lhwelnij295H3pdU=
 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
+github.com/GUAIK-ORG/go-snowflake v0.0.0-20200116064823-220c4260e85f h1:RDkg3pyE1qGbBpRWmvSN9RNZC5nUrOaEPiEpEb8y2f0=
+github.com/GUAIK-ORG/go-snowflake v0.0.0-20200116064823-220c4260e85f/go.mod h1:zA7AF9RTfpluCfz0omI4t5KCMaWHUMicsZoMccnaT44=
 github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
 github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
 github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY=
@@ -73,6 +75,7 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2
 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
 github.com/go-sourcemap/sourcemap v2.1.3+incompatible h1:W1iEw64niKVGogNgBN3ePyLFfuisuzeidWPMPWmECqU=
 github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg=
+github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
 github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
 github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=

+ 25 - 0
ngjsvm/js_engine.go

@@ -30,6 +30,13 @@ const (
 		"please use 'module.exports = xxx' to export it."
 )
 
+const (
+	RunScopeNameLoad    = "load"
+	RunScopeNameSetup   = "setup"
+	RunScopeNameLoop    = "loop"
+	RunScopeNameCleanup = "cleanup"
+)
+
 type RuntimeRegisterFunc func(vm *JSVM) *JSEnv
 
 type JSVMConfig struct {
@@ -58,6 +65,7 @@ type JSVM struct {
 	mainProgram     *goja.Program
 	loopCtx         context.Context
 	loopCncl        context.CancelFunc
+	scopeName       string
 }
 
 func NewJSVM(cfg *JSVMConfig) *JSVM {
@@ -69,6 +77,7 @@ func NewJSVM(cfg *JSVMConfig) *JSVM {
 		runtimeEnvLogPrefix: cfg.RuntimeEnvLogPrefix,
 		useStrictMode:       cfg.UseStrictMode,
 		disposed:            false,
+		scopeName:           "",
 	}
 	vm.logger.LogPrint(vm.engineLogPrefix, hiedalog.DLN_INFO, "NagaeJSVM engine ready.")
 	return vm
@@ -127,6 +136,7 @@ func (v *JSVM) LoadScript(uri string) error {
 	}
 	v.mainProgram = prog
 	v.vm.ClearInterrupt()
+	v.scopeName = RunScopeNameLoad
 	retval, err := v.vm.RunProgram(v.mainProgram)
 	if err != nil {
 		_, ok := err.(*goja.InterruptedError)
@@ -229,6 +239,7 @@ func (v *JSVM) ExecSetup() error {
 		return Err_JSVMCallOnNilObject
 	}
 	v.vm.ClearInterrupt()
+	v.scopeName = RunScopeNameSetup
 	val, err := v.setupFunc(v.mainObj)
 	if err != nil {
 		_, ok := err.(*goja.InterruptedError)
@@ -257,6 +268,7 @@ func (v *JSVM) ExecCleanup() error {
 		return Err_JSVMCallOnNilObject
 	}
 	v.vm.ClearInterrupt()
+	v.scopeName = RunScopeNameCleanup
 	val, err := v.exitHandlerFunc(v.mainObj)
 	if err != nil {
 		_, ok := err.(*goja.InterruptedError)
@@ -311,6 +323,7 @@ func (v *JSVM) RunLoop() error {
 	v.loopCncl = cncl
 	v.loopCtx = ctx
 	v.vm.ClearInterrupt()
+	v.scopeName = RunScopeNameLoop
 RunLoopLoop:
 	for {
 		wch := make(chan error)
@@ -386,3 +399,15 @@ func (v *JSVM) EngineDispose() {
 	v.logger.LogPrint(v.engineLogPrefix, hiedalog.DLN_DEBUG, "engine deactivated.")
 	v.disposed = true
 }
+
+func (v *JSVM) GetCurrentScopeName() string {
+	return v.scopeName
+}
+
+func (v *JSVM) ThrowException(i interface{}) {
+	panic(v.vm.ToValue(i))
+}
+
+func (v *JSVM) ToValue(i interface{}) goja.Value {
+	return v.vm.ToValue(i)
+}

+ 12 - 0
ngjsvm/js_export.go

@@ -113,7 +113,19 @@ func (v *JSEnv) lsrt(call goja.FunctionCall) goja.Value {
 	return ret
 }
 
+func (v *JSEnv) GetCurrentScopeName() string {
+	return v.jsvm.GetCurrentScopeName()
+}
+
 func (v *JSEnv) prepareBasicJsEnv() {
 	_ = v.jsvm.RegisterObject("module", v.jsvm.GetGlobalObject())
 	_ = v.jsvm.RegisterObject("lsrt", v.lsrt)
 }
+
+func (v *JSEnv) ThrowException(i interface{}) {
+	v.jsvm.ThrowException(i)
+}
+
+func (v *JSEnv) ToValue(i interface{}) goja.Value {
+	return v.jsvm.ToValue(i)
+}

+ 26 - 24
ngjsvm/js_rt_logger.go

@@ -39,7 +39,11 @@ func JSRtLoggerLogFuncFromHiedaLogger(logger *hiedalog.HiedaLogger, moduleName s
 	return func(level JSRtLoggerLogLevel, info []goja.Value) {
 		a := make([]interface{}, len(info))
 		for i, v := range info {
-			a[i] = v.String()
+			if v == nil {
+				a[i] = "null"
+			} else {
+				a[i] = v.ToString()
+			}
 		}
 		logger.LogPrint(moduleName, level.MapToHiedaLogLevel(), a...)
 	}
@@ -62,7 +66,7 @@ func (j *JSRtLogger) RegisterRt(name string, env *JSEnv) (goja.Value, error) {
 	fmap := map[string]interface{}{
 		"error": j.J_error,
 		"warn":  j.J_warn,
-		"log":   j.J_log,
+		"log":   j.J_info,
 		"info":  j.J_info,
 		"trace": j.J_trace,
 		"debug": j.J_debug,
@@ -76,44 +80,42 @@ func (j *JSRtLogger) IsRegistered() bool {
 	return j.isReg
 }
 
-func (j *JSRtLogger) J_debug(v ...goja.Value) {
+func (j *JSRtLogger) J_debug(call goja.FunctionCall) goja.Value {
 	if !j.isReg {
-		return
+		return goja.Undefined()
 	}
-	j.LogFunc(JSRrLoggerLogLevelDebug, v)
+	j.LogFunc(JSRrLoggerLogLevelDebug, call.Arguments)
+	return goja.Undefined()
 }
 
-func (j *JSRtLogger) J_trace(v ...goja.Value) {
+func (j *JSRtLogger) J_trace(call goja.FunctionCall) goja.Value {
 	if !j.isReg {
-		return
+		return goja.Undefined()
 	}
-	j.LogFunc(JSRrLoggerLogLevelTrace, v)
+	j.LogFunc(JSRrLoggerLogLevelTrace, call.Arguments)
+	return goja.Undefined()
 }
 
-func (j *JSRtLogger) J_log(v ...goja.Value) {
+func (j *JSRtLogger) J_info(call goja.FunctionCall) goja.Value {
 	if !j.isReg {
-		return
+		return goja.Undefined()
 	}
-	j.LogFunc(JSRrLoggerLogLevelInfo, v)
+	j.LogFunc(JSRrLoggerLogLevelInfo, call.Arguments)
+	return goja.Undefined()
 }
 
-func (j *JSRtLogger) J_info(v ...goja.Value) {
+func (j *JSRtLogger) J_warn(call goja.FunctionCall) goja.Value {
 	if !j.isReg {
-		return
+		return goja.Undefined()
 	}
-	j.LogFunc(JSRrLoggerLogLevelInfo, v)
+	j.LogFunc(JSRrLoggerLogLevelWarn, call.Arguments)
+	return goja.Undefined()
 }
 
-func (j *JSRtLogger) J_warn(v ...goja.Value) {
+func (j *JSRtLogger) J_error(call goja.FunctionCall) goja.Value {
 	if !j.isReg {
-		return
+		return goja.Undefined()
 	}
-	j.LogFunc(JSRrLoggerLogLevelWarn, v)
-}
-
-func (j *JSRtLogger) J_error(v ...goja.Value) {
-	if !j.isReg {
-		return
-	}
-	j.LogFunc(JSRrLoggerLogLevelError, v)
+	j.LogFunc(JSRrLoggerLogLevelError, call.Arguments)
+	return goja.Undefined()
 }

+ 25 - 4
ngjsvm/js_rt_runtime.go

@@ -1,6 +1,9 @@
 package ngjsvm
 
-import "github.com/dop251/goja"
+import (
+	"github.com/dop251/goja"
+	"time"
+)
 
 type JSRtRuntime struct {
 	isReg bool
@@ -13,7 +16,9 @@ func (j *JSRtRuntime) Dispose() {
 func (j *JSRtRuntime) RegisterRt(name string, env *JSEnv) (goja.Value, error) {
 	j.env = env
 	fmap := map[string]interface{}{
-		"quit": j.J_quit,
+		"quit":     j.J_quit,
+		"sleep":    j.J_sleep,
+		"getScope": j.J_getScope,
 	}
 	obj := j.env.BuildObject(name, fmap)
 	j.isReg = true
@@ -24,9 +29,25 @@ func (j *JSRtRuntime) IsRegistered() bool {
 	return j.isReg
 }
 
-func (j *JSRtRuntime) J_quit(v ...goja.Value) {
+func (j *JSRtRuntime) J_quit(call goja.FunctionCall) goja.Value {
 	if !j.isReg {
-		return
+		return goja.Undefined()
 	}
 	j.env.JSCallQuit()
+	return goja.Undefined()
+}
+
+func (j *JSRtRuntime) J_sleep(xtime goja.Value) {
+	if !j.isReg {
+		return
+	}
+	t := xtime.ToInteger()
+	time.Sleep(time.Duration(t) * time.Millisecond)
+}
+
+func (j *JSRtRuntime) J_getScope() string {
+	if !j.isReg {
+		return ""
+	}
+	return j.env.GetCurrentScopeName()
 }

+ 190 - 0
ngjsvm/js_rt_scheduler.go

@@ -0,0 +1,190 @@
+package ngjsvm
+
+import (
+	"context"
+	"fmt"
+	"github.com/GUAIK-ORG/go-snowflake/snowflake"
+	"github.com/dop251/goja"
+	"sync"
+	"time"
+)
+
+const (
+	JSRtSchedulerExceptionFunctionNotCallable = "provided function is not callable"
+)
+
+type jsRtSchedulerTicker struct {
+	id       int64
+	ticker   *time.Ticker
+	callback func()
+	ctx      context.Context
+	cncl     context.CancelFunc
+	onlyOnce bool
+	delMet   func(tkid int64)
+}
+
+func newJsRtSchedulerTiker(
+	id int64,
+	interval time.Duration,
+	callback func(),
+	once bool,
+	delMet func(tkid int64),
+) *jsRtSchedulerTicker {
+	ctx, cncl := context.WithCancel(context.Background())
+	t := &jsRtSchedulerTicker{
+		id:       id,
+		ticker:   time.NewTicker(interval),
+		callback: callback,
+		ctx:      ctx,
+		cncl:     cncl,
+		onlyOnce: once,
+		delMet:   delMet,
+	}
+	go t.tickLoop()
+	return t
+}
+
+func (t *jsRtSchedulerTicker) tickLoop() {
+TickLoop:
+	for {
+		select {
+		case <-t.ctx.Done():
+			break TickLoop
+		case <-t.ticker.C:
+			t.callback()
+			if t.onlyOnce {
+				break TickLoop
+			}
+			t.callback()
+			break
+		}
+	}
+	t.ticker.Stop()
+	if t.delMet != nil {
+		t.delMet(t.id)
+	}
+}
+
+func (t *jsRtSchedulerTicker) Dispose() {
+	if t.ticker != nil {
+		t.ticker.Stop()
+	}
+	if t.cncl != nil {
+		t.cncl()
+		t.cncl = nil
+	}
+}
+
+type JSRtScheduler struct {
+	isReg      bool
+	env        *JSEnv
+	snowflaker *snowflake.Snowflake
+	tickers    map[int64]*jsRtSchedulerTicker
+	tickerLock sync.RWMutex
+}
+
+func (j *JSRtScheduler) clearAllTicks() {
+	j.tickerLock.Lock()
+	for k, v := range j.tickers {
+		v.Dispose()
+		delete(j.tickers, k)
+	}
+	j.tickerLock.Unlock()
+}
+
+func (j *JSRtScheduler) Dispose() {
+	j.clearAllTicks()
+}
+
+func (j *JSRtScheduler) RegisterRt(name string, env *JSEnv) (goja.Value, error) {
+	j.env = env
+	sn, err := snowflake.NewSnowflake(0, 0)
+	if err != nil {
+		return nil, fmt.Errorf("failed create snowflaker: %v", err)
+	}
+	j.snowflaker = sn
+	j.tickers = make(map[int64]*jsRtSchedulerTicker)
+	fmap := map[string]interface{}{
+		"NotCallableException": JSRtSchedulerExceptionFunctionNotCallable,
+		"setInterval":          j.J_setInterval,
+		"clearInterval":        j.J_clearInterval,
+		"setTimeout":           j.J_setTimeout,
+		"clearTimeout":         j.J_clearTimeout,
+		"clearAll":             j.J_clearAll,
+	}
+	obj := j.env.BuildObject(name, fmap)
+	j.isReg = true
+	return obj, nil
+}
+
+func (j *JSRtScheduler) IsRegistered() bool {
+	return j.isReg
+}
+
+func (j *JSRtScheduler) J_setInterval(call goja.FunctionCall) goja.Value {
+	return j.setTicker(call, false)
+}
+
+func (j *JSRtScheduler) J_clearInterval(call goja.FunctionCall) goja.Value {
+	return j.clearTick(call)
+}
+
+func (j *JSRtScheduler) J_setTimeout(call goja.FunctionCall) goja.Value {
+	return j.setTicker(call, true)
+}
+
+func (j *JSRtScheduler) J_clearTimeout(call goja.FunctionCall) goja.Value {
+	return j.clearTick(call)
+}
+
+func (j *JSRtScheduler) J_clearAll(call goja.FunctionCall) goja.Value {
+	if !j.isReg {
+		return goja.Undefined()
+	}
+	j.clearAllTicks()
+	return goja.Undefined()
+}
+
+func (j *JSRtScheduler) setTicker(call goja.FunctionCall, once bool) goja.Value {
+	if !j.isReg {
+		return goja.Undefined()
+	}
+	if fn, ok := goja.AssertFunction(call.Argument(0)); ok {
+		intvms := call.Argument(1).ToInteger()
+		var args []goja.Value
+		if len(call.Arguments) > 2 {
+			args = append(args, call.Arguments[2:]...)
+		}
+		f := func() { fn(nil, args...) }
+		intv := time.Duration(intvms) * time.Millisecond
+		tkid := j.snowflaker.NextVal()
+		tk := newJsRtSchedulerTiker(tkid, intv, f, once, j.disposeTicker)
+		j.tickerLock.Lock()
+		j.tickers[tkid] = tk
+		j.tickerLock.Unlock()
+		return j.env.ToValue(tkid)
+	} else {
+		j.env.ThrowException(JSRtSchedulerExceptionFunctionNotCallable)
+	}
+	return goja.Undefined()
+}
+
+func (j *JSRtScheduler) disposeTicker(tkid int64) {
+	j.tickerLock.Lock()
+	tk, ok := j.tickers[tkid]
+	if ok {
+		tk.Dispose()
+		delete(j.tickers, tkid)
+	}
+	j.tickerLock.Unlock()
+}
+
+func (j *JSRtScheduler) clearTick(call goja.FunctionCall) goja.Value {
+	if !j.isReg {
+		return goja.Undefined()
+	}
+	tkidRaw := call.Argument(0)
+	tkid := tkidRaw.ToInteger()
+	j.disposeTicker(tkid)
+	return goja.Undefined()
+}