1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192 |
- using System;
- using Jint.Collections;
- using Jint.Native.Function;
- using Jint.Native.Object;
- using Jint.Runtime;
- using Jint.Runtime.Descriptors;
- using Jint.Runtime.Interop;
- namespace Jint.Native.Proxy
- {
- public sealed class ProxyConstructor : FunctionInstance, IConstructor
- {
- private static readonly JsString _name = new JsString("Proxy");
- private ProxyConstructor(Engine engine)
- : base(engine, _name, strict: false)
- {
- }
- public static ProxyConstructor CreateProxyConstructor(Engine engine)
- {
- var obj = new ProxyConstructor(engine);
- obj._length = new PropertyDescriptor(2, PropertyFlag.Configurable);
- return obj;
- }
- public override JsValue Call(JsValue thisObject, JsValue[] arguments)
- {
- return ExceptionHelper.ThrowTypeError<JsValue>(_engine, "Constructor Proxy requires 'new'");
- }
- /// <summary>
- /// https://www.ecma-international.org/ecma-262/6.0/index.html#sec-proxy-object-internal-methods-and-internal-slots-construct-argumentslist-newtarget
- /// </summary>
- public ObjectInstance Construct(JsValue[] arguments, JsValue newTarget)
- {
- var target = arguments.At(0);
- var handler = arguments.At(1);
- if (!target.IsObject() || !handler.IsObject())
- {
- return ExceptionHelper.ThrowTypeError<ObjectInstance>(_engine, "Cannot create proxy with a non-object as target or handler");
- }
- return Construct(target.AsObject(), handler.AsObject());
- }
- protected override void Initialize()
- {
- _properties = new StringDictionarySlim<PropertyDescriptor>(3)
- {
- ["revocable"] = new PropertyDescriptor(new ClrFunctionInstance(_engine, "revocable", Revocable, 2, PropertyFlag.Configurable), true, true, true)
- };
- }
- protected override ObjectInstance GetPrototypeOf()
- {
- return _engine.Function.Prototype;
- }
- public ProxyInstance Construct(ObjectInstance target, ObjectInstance handler)
- {
- if (target is ProxyInstance targetProxy && targetProxy._handler is null)
- {
- ExceptionHelper.ThrowTypeError(_engine);
- }
- if (handler is ProxyInstance handlerProxy && handlerProxy._handler is null)
- {
- ExceptionHelper.ThrowTypeError(_engine);
- }
- var instance = new ProxyInstance(Engine, target, handler);
- return instance;
- }
- private JsValue Revocable(JsValue thisObject, JsValue[] arguments)
- {
- var p = _engine.Proxy.Construct(arguments, Undefined);
- var result = _engine.Object.Construct(ArrayExt.Empty<JsValue>());
- result.DefineOwnProperty("revoke", new PropertyDescriptor(new ClrFunctionInstance(_engine, name: null, Revoke, 0, PropertyFlag.Configurable), PropertyFlag.ConfigurableEnumerableWritable));
- result.DefineOwnProperty("proxy", new PropertyDescriptor(Construct(arguments, thisObject), PropertyFlag.ConfigurableEnumerableWritable));
- return result;
- }
- private JsValue Revoke(JsValue thisObject, JsValue[] arguments)
- {
- var o = thisObject.AsObject();
- var proxy = (ProxyInstance) o.Get("proxy");
- proxy._handler = null;
- proxy._target = null;
- return Undefined;
- }
- }
- }
|