1 package goja
2
3 import (
4 "github.com/dop251/goja/unistring"
5 )
6
7 type nativeProxyHandler struct {
8 handler *ProxyTrapConfig
9 }
10
11 func (h *nativeProxyHandler) getPrototypeOf(target *Object) (Value, bool) {
12 if trap := h.handler.GetPrototypeOf; trap != nil {
13 return trap(target), true
14 }
15 return nil, false
16 }
17
18 func (h *nativeProxyHandler) setPrototypeOf(target *Object, proto *Object) (bool, bool) {
19 if trap := h.handler.SetPrototypeOf; trap != nil {
20 return trap(target, proto), true
21 }
22 return false, false
23 }
24
25 func (h *nativeProxyHandler) isExtensible(target *Object) (bool, bool) {
26 if trap := h.handler.IsExtensible; trap != nil {
27 return trap(target), true
28 }
29 return false, false
30 }
31
32 func (h *nativeProxyHandler) preventExtensions(target *Object) (bool, bool) {
33 if trap := h.handler.PreventExtensions; trap != nil {
34 return trap(target), true
35 }
36 return false, false
37 }
38
39 func (h *nativeProxyHandler) getOwnPropertyDescriptorStr(target *Object, prop unistring.String) (Value, bool) {
40 if trap := h.handler.GetOwnPropertyDescriptorIdx; trap != nil {
41 if idx, ok := strToInt(prop); ok {
42 desc := trap(target, idx)
43 return desc.toValue(target.runtime), true
44 }
45 }
46 if trap := h.handler.GetOwnPropertyDescriptor; trap != nil {
47 desc := trap(target, prop.String())
48 return desc.toValue(target.runtime), true
49 }
50 return nil, false
51 }
52
53 func (h *nativeProxyHandler) getOwnPropertyDescriptorIdx(target *Object, prop valueInt) (Value, bool) {
54 if trap := h.handler.GetOwnPropertyDescriptorIdx; trap != nil {
55 desc := trap(target, toIntStrict(int64(prop)))
56 return desc.toValue(target.runtime), true
57 }
58 if trap := h.handler.GetOwnPropertyDescriptor; trap != nil {
59 desc := trap(target, prop.String())
60 return desc.toValue(target.runtime), true
61 }
62 return nil, false
63 }
64
65 func (h *nativeProxyHandler) getOwnPropertyDescriptorSym(target *Object, prop *Symbol) (Value, bool) {
66 if trap := h.handler.GetOwnPropertyDescriptorSym; trap != nil {
67 desc := trap(target, prop)
68 return desc.toValue(target.runtime), true
69 }
70 return nil, false
71 }
72
73 func (h *nativeProxyHandler) definePropertyStr(target *Object, prop unistring.String, desc PropertyDescriptor) (bool, bool) {
74 if trap := h.handler.DefinePropertyIdx; trap != nil {
75 if idx, ok := strToInt(prop); ok {
76 return trap(target, idx, desc), true
77 }
78 }
79 if trap := h.handler.DefineProperty; trap != nil {
80 return trap(target, prop.String(), desc), true
81 }
82 return false, false
83 }
84
85 func (h *nativeProxyHandler) definePropertyIdx(target *Object, prop valueInt, desc PropertyDescriptor) (bool, bool) {
86 if trap := h.handler.DefinePropertyIdx; trap != nil {
87 return trap(target, toIntStrict(int64(prop)), desc), true
88 }
89 if trap := h.handler.DefineProperty; trap != nil {
90 return trap(target, prop.String(), desc), true
91 }
92 return false, false
93 }
94
95 func (h *nativeProxyHandler) definePropertySym(target *Object, prop *Symbol, desc PropertyDescriptor) (bool, bool) {
96 if trap := h.handler.DefinePropertySym; trap != nil {
97 return trap(target, prop, desc), true
98 }
99 return false, false
100 }
101
102 func (h *nativeProxyHandler) hasStr(target *Object, prop unistring.String) (bool, bool) {
103 if trap := h.handler.HasIdx; trap != nil {
104 if idx, ok := strToInt(prop); ok {
105 return trap(target, idx), true
106 }
107 }
108 if trap := h.handler.Has; trap != nil {
109 return trap(target, prop.String()), true
110 }
111 return false, false
112 }
113
114 func (h *nativeProxyHandler) hasIdx(target *Object, prop valueInt) (bool, bool) {
115 if trap := h.handler.HasIdx; trap != nil {
116 return trap(target, toIntStrict(int64(prop))), true
117 }
118 if trap := h.handler.Has; trap != nil {
119 return trap(target, prop.String()), true
120 }
121 return false, false
122 }
123
124 func (h *nativeProxyHandler) hasSym(target *Object, prop *Symbol) (bool, bool) {
125 if trap := h.handler.HasSym; trap != nil {
126 return trap(target, prop), true
127 }
128 return false, false
129 }
130
131 func (h *nativeProxyHandler) getStr(target *Object, prop unistring.String, receiver Value) (Value, bool) {
132 if trap := h.handler.GetIdx; trap != nil {
133 if idx, ok := strToInt(prop); ok {
134 return trap(target, idx, receiver), true
135 }
136 }
137 if trap := h.handler.Get; trap != nil {
138 return trap(target, prop.String(), receiver), true
139 }
140 return nil, false
141 }
142
143 func (h *nativeProxyHandler) getIdx(target *Object, prop valueInt, receiver Value) (Value, bool) {
144 if trap := h.handler.GetIdx; trap != nil {
145 return trap(target, toIntStrict(int64(prop)), receiver), true
146 }
147 if trap := h.handler.Get; trap != nil {
148 return trap(target, prop.String(), receiver), true
149 }
150 return nil, false
151 }
152
153 func (h *nativeProxyHandler) getSym(target *Object, prop *Symbol, receiver Value) (Value, bool) {
154 if trap := h.handler.GetSym; trap != nil {
155 return trap(target, prop, receiver), true
156 }
157 return nil, false
158 }
159
160 func (h *nativeProxyHandler) setStr(target *Object, prop unistring.String, value Value, receiver Value) (bool, bool) {
161 if trap := h.handler.SetIdx; trap != nil {
162 if idx, ok := strToInt(prop); ok {
163 return trap(target, idx, value, receiver), true
164 }
165 }
166 if trap := h.handler.Set; trap != nil {
167 return trap(target, prop.String(), value, receiver), true
168 }
169 return false, false
170 }
171
172 func (h *nativeProxyHandler) setIdx(target *Object, prop valueInt, value Value, receiver Value) (bool, bool) {
173 if trap := h.handler.SetIdx; trap != nil {
174 return trap(target, toIntStrict(int64(prop)), value, receiver), true
175 }
176 if trap := h.handler.Set; trap != nil {
177 return trap(target, prop.String(), value, receiver), true
178 }
179 return false, false
180 }
181
182 func (h *nativeProxyHandler) setSym(target *Object, prop *Symbol, value Value, receiver Value) (bool, bool) {
183 if trap := h.handler.SetSym; trap != nil {
184 return trap(target, prop, value, receiver), true
185 }
186 return false, false
187 }
188
189 func (h *nativeProxyHandler) deleteStr(target *Object, prop unistring.String) (bool, bool) {
190 if trap := h.handler.DeletePropertyIdx; trap != nil {
191 if idx, ok := strToInt(prop); ok {
192 return trap(target, idx), true
193 }
194 }
195 if trap := h.handler.DeleteProperty; trap != nil {
196 return trap(target, prop.String()), true
197 }
198 return false, false
199 }
200
201 func (h *nativeProxyHandler) deleteIdx(target *Object, prop valueInt) (bool, bool) {
202 if trap := h.handler.DeletePropertyIdx; trap != nil {
203 return trap(target, toIntStrict(int64(prop))), true
204 }
205 if trap := h.handler.DeleteProperty; trap != nil {
206 return trap(target, prop.String()), true
207 }
208 return false, false
209 }
210
211 func (h *nativeProxyHandler) deleteSym(target *Object, prop *Symbol) (bool, bool) {
212 if trap := h.handler.DeletePropertySym; trap != nil {
213 return trap(target, prop), true
214 }
215 return false, false
216 }
217
218 func (h *nativeProxyHandler) ownKeys(target *Object) (*Object, bool) {
219 if trap := h.handler.OwnKeys; trap != nil {
220 return trap(target), true
221 }
222 return nil, false
223 }
224
225 func (h *nativeProxyHandler) apply(target *Object, this Value, args []Value) (Value, bool) {
226 if trap := h.handler.Apply; trap != nil {
227 return trap(target, this, args), true
228 }
229 return nil, false
230 }
231
232 func (h *nativeProxyHandler) construct(target *Object, args []Value, newTarget *Object) (Value, bool) {
233 if trap := h.handler.Construct; trap != nil {
234 return trap(target, args, newTarget), true
235 }
236 return nil, false
237 }
238
239 func (h *nativeProxyHandler) toObject(runtime *Runtime) *Object {
240 return runtime.ToValue(h.handler).ToObject(runtime)
241 }
242
243 func (r *Runtime) newNativeProxyHandler(nativeHandler *ProxyTrapConfig) proxyHandler {
244 return &nativeProxyHandler{handler: nativeHandler}
245 }
246
247
248
249
250
251
252
253
254
255
256 type ProxyTrapConfig struct {
257
258 GetPrototypeOf func(target *Object) (prototype *Object)
259
260
261 SetPrototypeOf func(target *Object, prototype *Object) (success bool)
262
263
264 IsExtensible func(target *Object) (success bool)
265
266
267 PreventExtensions func(target *Object) (success bool)
268
269
270 GetOwnPropertyDescriptor func(target *Object, prop string) (propertyDescriptor PropertyDescriptor)
271
272
273 GetOwnPropertyDescriptorIdx func(target *Object, prop int) (propertyDescriptor PropertyDescriptor)
274
275
276 GetOwnPropertyDescriptorSym func(target *Object, prop *Symbol) (propertyDescriptor PropertyDescriptor)
277
278
279 DefineProperty func(target *Object, key string, propertyDescriptor PropertyDescriptor) (success bool)
280
281
282 DefinePropertyIdx func(target *Object, key int, propertyDescriptor PropertyDescriptor) (success bool)
283
284
285 DefinePropertySym func(target *Object, key *Symbol, propertyDescriptor PropertyDescriptor) (success bool)
286
287
288 Has func(target *Object, property string) (available bool)
289
290
291 HasIdx func(target *Object, property int) (available bool)
292
293
294 HasSym func(target *Object, property *Symbol) (available bool)
295
296
297 Get func(target *Object, property string, receiver Value) (value Value)
298
299
300 GetIdx func(target *Object, property int, receiver Value) (value Value)
301
302
303 GetSym func(target *Object, property *Symbol, receiver Value) (value Value)
304
305
306 Set func(target *Object, property string, value Value, receiver Value) (success bool)
307
308
309 SetIdx func(target *Object, property int, value Value, receiver Value) (success bool)
310
311
312 SetSym func(target *Object, property *Symbol, value Value, receiver Value) (success bool)
313
314
315 DeleteProperty func(target *Object, property string) (success bool)
316
317
318 DeletePropertyIdx func(target *Object, property int) (success bool)
319
320
321 DeletePropertySym func(target *Object, property *Symbol) (success bool)
322
323
324 OwnKeys func(target *Object) (object *Object)
325
326
327 Apply func(target *Object, this Value, argumentsList []Value) (value Value)
328
329
330 Construct func(target *Object, argumentsList []Value, newTarget *Object) (value *Object)
331 }
332
333 func (r *Runtime) newProxy(args []Value, proto *Object) *Object {
334 if len(args) >= 2 {
335 if target, ok := args[0].(*Object); ok {
336 if proxyHandler, ok := args[1].(*Object); ok {
337 return r.newProxyObject(target, proxyHandler, proto).val
338 }
339 }
340 }
341 panic(r.NewTypeError("Cannot create proxy with a non-object as target or handler"))
342 }
343
344 func (r *Runtime) builtin_newProxy(args []Value, newTarget *Object) *Object {
345 if newTarget == nil {
346 panic(r.needNew("Proxy"))
347 }
348 return r.newProxy(args, r.getPrototypeFromCtor(newTarget, r.getProxy(), r.global.ObjectPrototype))
349 }
350
351 func (r *Runtime) NewProxy(target *Object, nativeHandler *ProxyTrapConfig) Proxy {
352 if p, ok := target.self.(*proxyObject); ok {
353 if p.handler == nil {
354 panic(r.NewTypeError("Cannot create proxy with a revoked proxy as target"))
355 }
356 }
357 handler := r.newNativeProxyHandler(nativeHandler)
358 proxy := r._newProxyObject(target, handler, nil)
359 return Proxy{proxy: proxy}
360 }
361
362 func (r *Runtime) builtin_proxy_revocable(call FunctionCall) Value {
363 if len(call.Arguments) >= 2 {
364 if target, ok := call.Argument(0).(*Object); ok {
365 if proxyHandler, ok := call.Argument(1).(*Object); ok {
366 proxy := r.newProxyObject(target, proxyHandler, nil)
367 revoke := r.newNativeFunc(func(FunctionCall) Value {
368 proxy.revoke()
369 return _undefined
370 }, "", 0)
371 ret := r.NewObject()
372 ret.self._putProp("proxy", proxy.val, true, true, true)
373 ret.self._putProp("revoke", revoke, true, true, true)
374 return ret
375 }
376 }
377 }
378 panic(r.NewTypeError("Cannot create proxy with a non-object as target or handler"))
379 }
380
381 func (r *Runtime) createProxy(val *Object) objectImpl {
382 o := r.newNativeConstructOnly(val, r.builtin_newProxy, nil, "Proxy", 2)
383
384 o._putProp("revocable", r.newNativeFunc(r.builtin_proxy_revocable, "revocable", 2), true, false, true)
385 return o
386 }
387
388 func (r *Runtime) getProxy() *Object {
389 ret := r.global.Proxy
390 if ret == nil {
391 ret = &Object{runtime: r}
392 r.global.Proxy = ret
393 r.createProxy(ret)
394 }
395 return ret
396 }
397
View as plain text