-
Notifications
You must be signed in to change notification settings - Fork 2
/
share.go
94 lines (81 loc) · 2.22 KB
/
share.go
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
87
88
89
90
91
92
93
94
package data
import (
"github.com/APITeamLimited/globe-test/worker/js/common"
"github.com/dop251/goja"
)
// TODO fix it not working really well with setupData or just make it more broken
// TODO fix it working with console.log
type sharedArray struct {
arr []string
}
type wrappedSharedArray struct {
sharedArray
rt *goja.Runtime
freeze goja.Callable
isFrozen goja.Callable
parse goja.Callable
}
func (s sharedArray) wrap(rt *goja.Runtime) goja.Value {
freeze, _ := goja.AssertFunction(rt.GlobalObject().Get("Object").ToObject(rt).Get("freeze"))
isFrozen, _ := goja.AssertFunction(rt.GlobalObject().Get("Object").ToObject(rt).Get("isFrozen"))
parse, _ := goja.AssertFunction(rt.GlobalObject().Get("JSON").ToObject(rt).Get("parse"))
return rt.NewDynamicArray(wrappedSharedArray{
sharedArray: s,
rt: rt,
freeze: freeze,
isFrozen: isFrozen,
parse: parse,
})
}
func (s wrappedSharedArray) Set(index int, val goja.Value) bool {
panic(s.rt.NewTypeError("SharedArray is immutable")) // this is specifically a type error
}
func (s wrappedSharedArray) SetLen(len int) bool {
panic(s.rt.NewTypeError("SharedArray is immutable")) // this is specifically a type error
}
func (s wrappedSharedArray) Get(index int) goja.Value {
if index < 0 || index >= len(s.arr) {
return goja.Undefined()
}
val, err := s.parse(goja.Undefined(), s.rt.ToValue(s.arr[index]))
if err != nil {
common.Throw(s.rt, err)
}
err = s.deepFreeze(s.rt, val)
if err != nil {
common.Throw(s.rt, err)
}
return val
}
func (s wrappedSharedArray) Len() int {
return len(s.arr)
}
func (s wrappedSharedArray) deepFreeze(rt *goja.Runtime, val goja.Value) error {
if val != nil && goja.IsNull(val) {
return nil
}
_, err := s.freeze(goja.Undefined(), val)
if err != nil {
return err
}
o := val.ToObject(rt)
if o == nil {
return nil
}
for _, key := range o.Keys() {
prop := o.Get(key)
if prop != nil {
// isFrozen returns true for all non objects so it we don't need to check that
frozen, err := s.isFrozen(goja.Undefined(), prop)
if err != nil {
return err
}
if !frozen.ToBoolean() { // prevent cycles
if err = s.deepFreeze(rt, prop); err != nil {
return err
}
}
}
}
return nil
}