aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/gopkg.in/olebedev/go-duktape.v3/timers.go
diff options
context:
space:
mode:
authorPéter Szilágyi <peterke@gmail.com>2017-12-21 19:56:11 +0800
committerGitHub <noreply@github.com>2017-12-21 19:56:11 +0800
commit5258785c81959109138ebeca613f12c277188abc (patch)
treeb3d21fc2f38927841f44541a3717b69f5a3c5ec1 /vendor/gopkg.in/olebedev/go-duktape.v3/timers.go
parent1a5425779b026587e36f5d21a6e50efe17cc6a9d (diff)
downloadgo-tangerine-5258785c81959109138ebeca613f12c277188abc.tar
go-tangerine-5258785c81959109138ebeca613f12c277188abc.tar.gz
go-tangerine-5258785c81959109138ebeca613f12c277188abc.tar.bz2
go-tangerine-5258785c81959109138ebeca613f12c277188abc.tar.lz
go-tangerine-5258785c81959109138ebeca613f12c277188abc.tar.xz
go-tangerine-5258785c81959109138ebeca613f12c277188abc.tar.zst
go-tangerine-5258785c81959109138ebeca613f12c277188abc.zip
cmd, core, eth/tracers: support fancier js tracing (#15516)
* cmd, core, eth/tracers: support fancier js tracing * eth, internal/web3ext: rework trace API, concurrency, chain tracing * eth/tracers: add three more JavaScript tracers * eth/tracers, vendor: swap ottovm to duktape for tracing * core, eth, internal: finalize call tracer and needed extras * eth, tests: prestate tracer, call test suite, rewinding * vendor: fix windows builds for tracer js engine * vendor: temporary duktape fix * eth/tracers: fix up 4byte and evmdis tracer * vendor: pull in latest duktape with my upstream fixes * eth: fix some review comments * eth: rename rewind to reexec to make it more obvious * core/vm: terminate tracing using defers
Diffstat (limited to 'vendor/gopkg.in/olebedev/go-duktape.v3/timers.go')
-rw-r--r--vendor/gopkg.in/olebedev/go-duktape.v3/timers.go136
1 files changed, 136 insertions, 0 deletions
diff --git a/vendor/gopkg.in/olebedev/go-duktape.v3/timers.go b/vendor/gopkg.in/olebedev/go-duktape.v3/timers.go
new file mode 100644
index 000000000..e12ee1f2e
--- /dev/null
+++ b/vendor/gopkg.in/olebedev/go-duktape.v3/timers.go
@@ -0,0 +1,136 @@
+package duktape
+
+import (
+ "errors"
+ "fmt"
+ "time"
+)
+
+// DefineTimers defines `setTimeout`, `clearTimeout`, `setInterval`,
+// `clearInterval` into global context.
+func (d *Context) PushTimers() error {
+ d.PushGlobalStash()
+ // check if timers already exists
+ if !d.HasPropString(-1, "timers") {
+ d.PushObject()
+ d.PutPropString(-2, "timers") // stash -> [ timers:{} ]
+ d.Pop()
+
+ d.PushGlobalGoFunction("setTimeout", setTimeout)
+ d.PushGlobalGoFunction("setInterval", setInterval)
+ d.PushGlobalGoFunction("clearTimeout", clearTimeout)
+ d.PushGlobalGoFunction("clearInterval", clearTimeout)
+ return nil
+ } else {
+ d.Pop()
+ return errors.New("Timers are already defined")
+ }
+}
+
+func (d *Context) FlushTimers() {
+ d.PushGlobalStash()
+ d.PushObject()
+ d.PutPropString(-2, "timers") // stash -> [ timers:{} ]
+ d.Pop()
+}
+
+func setTimeout(c *Context) int {
+ id := c.pushTimer(0)
+ timeout := c.ToNumber(1)
+ if timeout < 1 {
+ timeout = 1
+ }
+ go func(id float64) {
+ <-time.After(time.Duration(timeout) * time.Millisecond)
+ c.Lock()
+ defer c.Unlock()
+ if c.duk_context == nil {
+ fmt.Println("[duktape] Warning!\nsetTimeout invokes callback after the context was destroyed.")
+ return
+ }
+
+ // check if timer still exists
+ c.putTimer(id)
+ if c.GetType(-1).IsObject() {
+ c.Pcall(0 /* nargs */)
+ }
+ c.dropTimer(id)
+ }(id)
+ c.PushNumber(id)
+ return 1
+}
+
+func clearTimeout(c *Context) int {
+ if c.GetType(0).IsNumber() {
+ c.dropTimer(c.GetNumber(0))
+ c.Pop()
+ }
+ return 0
+}
+
+func setInterval(c *Context) int {
+ id := c.pushTimer(0)
+ timeout := c.ToNumber(1)
+ if timeout < 1 {
+ timeout = 1
+ }
+ go func(id float64) {
+ ticker := time.NewTicker(time.Duration(timeout) * time.Millisecond)
+ for _ = range ticker.C {
+ c.Lock()
+ // check if duktape context exists
+ if c.duk_context == nil {
+ c.dropTimer(id)
+ c.Pop()
+ ticker.Stop()
+ fmt.Println("[duktape] Warning!\nsetInterval invokes callback after the context was destroyed.")
+ c.Unlock()
+ continue
+ }
+
+ // check if timer still exists
+ c.putTimer(id)
+ if c.GetType(-1).IsObject() {
+ c.Pcall(0 /* nargs */)
+ c.Pop()
+ } else {
+ c.dropTimer(id)
+ c.Pop()
+ ticker.Stop()
+ }
+ c.Unlock()
+ }
+ }(id)
+ c.PushNumber(id)
+ return 1
+}
+
+func (d *Context) pushTimer(index int) float64 {
+ id := d.timerIndex.get()
+
+ d.PushGlobalStash()
+ d.GetPropString(-1, "timers")
+ d.PushNumber(id)
+ d.Dup(index)
+ d.PutProp(-3)
+ d.Pop2()
+
+ return id
+}
+
+func (d *Context) dropTimer(id float64) {
+ d.PushGlobalStash()
+ d.GetPropString(-1, "timers")
+ d.PushNumber(id)
+ d.DelProp(-2)
+ d.Pop2()
+}
+
+func (d *Context) putTimer(id float64) {
+ d.PushGlobalStash() // stash -> [ ..., timers: { <id>: { func: true } } ]
+ d.GetPropString(-1, "timers") // stash -> [ ..., timers: { <id>: { func: true } } }, { <id>: { func: true } ]
+ d.PushNumber(id)
+ d.GetProp(-2) // stash -> [ ..., timers: { <id>: { func: true } } }, { <id>: { func: true }, { func: true } ]
+ d.Replace(-3)
+ d.Pop()
+}