/** * Copyright (c) 2012-2016 André Bargull * Alle Rechte vorbehalten / All Rights Reserved. Use is subject to license terms. * * <https://github.com/anba/es6draft> */ package com.github.anba.es6draft.runtime.objects.reflect; import static com.github.anba.es6draft.runtime.AbstractOperations.CreateDataProperty; import static com.github.anba.es6draft.runtime.internal.Errors.newTypeError; import static com.github.anba.es6draft.runtime.internal.Properties.createProperties; import static com.github.anba.es6draft.runtime.types.Undefined.UNDEFINED; import static com.github.anba.es6draft.runtime.types.builtins.ProxyObject.ProxyCreate; import com.github.anba.es6draft.runtime.ExecutionContext; import com.github.anba.es6draft.runtime.Realm; import com.github.anba.es6draft.runtime.internal.Initializable; import com.github.anba.es6draft.runtime.internal.Messages; import com.github.anba.es6draft.runtime.internal.Properties.Attributes; import com.github.anba.es6draft.runtime.internal.Properties.Function; import com.github.anba.es6draft.runtime.internal.Properties.Prototype; import com.github.anba.es6draft.runtime.internal.Properties.Value; import com.github.anba.es6draft.runtime.internal.Ref; import com.github.anba.es6draft.runtime.types.Constructor; import com.github.anba.es6draft.runtime.types.Intrinsics; import com.github.anba.es6draft.runtime.types.Undefined; import com.github.anba.es6draft.runtime.types.builtins.BuiltinConstructor; import com.github.anba.es6draft.runtime.types.builtins.BuiltinFunction; import com.github.anba.es6draft.runtime.types.builtins.OrdinaryObject; import com.github.anba.es6draft.runtime.types.builtins.ProxyObject; /** * <h1>26 Reflection</h1><br> * <h2>26.2 Proxy Objects</h2> * <ul> * <li>26.2.1 The Proxy Constructor * <li>26.2.2 Properties of the Proxy Constructor * </ul> */ public final class ProxyConstructor extends BuiltinConstructor implements Initializable { /** * Constructs a new Proxy constructor function. * * @param realm * the realm object */ public ProxyConstructor(Realm realm) { super(realm, "Proxy", 2); } @Override public void initialize(Realm realm) { createProperties(realm, this, Properties.class); } @Override public ProxyConstructor clone() { return new ProxyConstructor(getRealm()); } /** * 26.2.1.1 Proxy (target, handler) */ @Override public ProxyObject call(ExecutionContext callerContext, Object thisValue, Object... args) { /* step 1 */ throw newTypeError(calleeContext(), Messages.Key.ProxyNew); } /** * 26.2.1.1 Proxy (target, handler) */ @Override public ProxyObject construct(ExecutionContext callerContext, Constructor newTarget, Object... args) { Object target = argument(args, 0); Object handler = argument(args, 1); /* step 1 (not applicable) */ /* step 2 */ return ProxyCreate(calleeContext(), target, handler); } /** * 26.2.2 Properties of the Proxy Constructor Function */ public enum Properties { ; @Prototype public static final Intrinsics __proto__ = Intrinsics.FunctionPrototype; @Value(name = "length", attributes = @Attributes(writable = false, enumerable = false, configurable = true)) public static final int length = 2; @Value(name = "name", attributes = @Attributes(writable = false, enumerable = false, configurable = true)) public static final String name = "Proxy"; /** * 26.2.2.1 Proxy.revocable ( target, handler ) * * @param cx * the execution context * @param thisValue * the function this-value * @param target * the proxy target object * @param handler * the proxy handler object * @return the revocable proxy */ @Function(name = "revocable", arity = 2) public static Object revocable(ExecutionContext cx, Object thisValue, Object target, Object handler) { /* steps 1-2 */ ProxyObject p = ProxyCreate(cx, target, handler); /* steps 3-4 */ ProxyRevocationFunction revoker = new ProxyRevocationFunction(cx.getRealm(), p); /* step 5 */ OrdinaryObject result = ObjectCreate(cx, Intrinsics.ObjectPrototype); /* step 6 */ CreateDataProperty(cx, result, "proxy", p); /* step 7 */ CreateDataProperty(cx, result, "revoke", revoker); /* step 8 */ return result; } } /** * <h1>26.2.2.1.1 Proxy Revocation Functions</h1> */ public static final class ProxyRevocationFunction extends BuiltinFunction { /** [[RevocableProxy]] */ private Ref<ProxyObject> revocableProxy; public ProxyRevocationFunction(Realm realm, ProxyObject revocableProxy) { this(realm, new Ref<>(revocableProxy)); createDefaultFunctionProperties(); } private ProxyRevocationFunction(Realm realm, Ref<ProxyObject> revocableProxy) { super(realm, ANONYMOUS, 0); this.revocableProxy = revocableProxy; } @Override public ProxyRevocationFunction clone() { return new ProxyRevocationFunction(getRealm(), revocableProxy); } @Override public Undefined call(ExecutionContext callerContext, Object thisValue, Object... args) { /* step 1 */ Ref<ProxyObject> p = revocableProxy; /* step 2 */ if (p == null) { return UNDEFINED; } /* step 3 */ revocableProxy = null; /* step 4 (implicit) */ ProxyObject proxy = p.get(); /* steps 5-6 */ if (proxy != null) { p.clear(); proxy.revoke(); } /* step 7 */ return UNDEFINED; } } }