1616 *
1717 * @author Ronald Brill
1818 */
19- final class NativeProxy extends ScriptableObject implements Function {
19+ class NativeProxy extends ScriptableObject {
2020 private static final long serialVersionUID = 6676871870513494844L ;
2121
2222 private static final String PROXY_TAG = "Proxy" ;
@@ -102,41 +102,6 @@ public String getClassName() {
102102 return target .getClassName ();
103103 }
104104
105- /**
106- * see <a
107- * href="https://262.ecma-international.org/12.0/#sec-proxy-object-internal-methods-and-internal-slots-construct-argumentslist-newtarget">10.5.13
108- * [[Construct]] (argumentsList, newTarget)</a>
109- */
110- @ Override
111- public Scriptable construct (Context cx , Scriptable scope , Object [] args ) {
112- /*
113- * 1. Let handler be O.[[ProxyHandler]].
114- * 2. If handler is null, throw a TypeError exception.
115- * 3. Assert: Type(handler) is Object.
116- * 4. Let target be O.[[ProxyTarget]].
117- * 5. Assert: IsConstructor(target) is true.
118- * 6. Let trap be ? GetMethod(handler, "construct").
119- * 7. If trap is undefined, then
120- * a. Return ? Construct(target, argumentsList, newTarget).
121- * 8. Let argArray be ! CreateArrayFromList(argumentsList).
122- * 9. Let newObj be ? Call(trap, handler, « target, argArray, newTarget »).
123- * 10. If Type(newObj) is not Object, throw a TypeError exception.
124- * 11. Return newObj.
125- */
126- ScriptableObject target = getTargetThrowIfRevoked ();
127-
128- Function trap = getTrap (TRAP_CONSTRUCT );
129- if (trap != null ) {
130- Object result = callTrap (trap , new Object [] {target , args , this });
131- if (!(result instanceof Scriptable ) || ScriptRuntime .isSymbol (result )) {
132- throw ScriptRuntime .typeError ("Constructor trap has to return a scriptable." );
133- }
134- return (ScriptableObject ) result ;
135- }
136-
137- return ((Constructable ) target ).construct (cx , scope , args );
138- }
139-
140105 /**
141106 * <a
142107 * href="https://262.ecma-international.org/12.0/#sec-proxy-object-internal-methods-and-internal-slots-hasproperty-p">10.5.7
@@ -1259,47 +1224,6 @@ public void setPrototype(Scriptable prototype) {
12591224 target .setPrototype (prototype );
12601225 }
12611226
1262- /**
1263- * see <a
1264- * href="https://262.ecma-international.org/12.0/#sec-proxy-object-internal-methods-and-internal-slots-call-thisargument-argumentslist">10.5.12
1265- * [[Call]] (thisArgument, argumentsList)</a>
1266- */
1267- @ Override
1268- public Object call (Context cx , Scriptable scope , Scriptable thisObj , Object [] args ) {
1269- /*
1270- * 1. Let handler be O.[[ProxyHandler]].
1271- * 2. If handler is null, throw a TypeError exception.
1272- * 3. Assert: Type(handler) is Object.
1273- * 4. Let target be O.[[ProxyTarget]].
1274- * 5. Let trap be ? GetMethod(handler, "apply").
1275- * 6. If trap is undefined, then
1276- * a. Return ? Call(target, thisArgument, argumentsList).
1277- * 7. Let argArray be ! CreateArrayFromList(argumentsList).
1278- * 8. Return ? Call(trap, handler, « target, thisArgument, argArray »).
1279- */
1280- ScriptableObject target = getTargetThrowIfRevoked ();
1281-
1282- Scriptable argumentsList = cx .newArray (scope , args );
1283-
1284- Function trap = getTrap (TRAP_APPLY );
1285- if (trap != null ) {
1286- return callTrap (trap , new Object [] {target , thisObj , argumentsList });
1287- }
1288-
1289- return ScriptRuntime .applyOrCall (
1290- true , cx , scope , target , new Object [] {thisObj , argumentsList });
1291- }
1292-
1293- @ Override
1294- public Scriptable getDeclarationScope () {
1295- ScriptableObject target = getTargetThrowIfRevoked ();
1296- if (target instanceof Function ) {
1297- return ((Function ) target ).getDeclarationScope ();
1298- }
1299- Kit .codeBug ();
1300- return null ;
1301- }
1302-
13031227 private static NativeProxy constructor (Context cx , Scriptable scope , Object [] args ) {
13041228 if (args .length < 2 ) {
13051229 throw ScriptRuntime .typeErrorById (
@@ -1311,7 +1235,13 @@ private static NativeProxy constructor(Context cx, Scriptable scope, Object[] ar
13111235 ScriptableObject target = ensureScriptableObjectButNotSymbol (args [0 ]);
13121236 ScriptableObject handler = ensureScriptableObjectButNotSymbol (args [1 ]);
13131237
1314- NativeProxy proxy = new NativeProxy (target , handler );
1238+ NativeProxy proxy ;
1239+ if (target instanceof Function ) {
1240+ proxy = new NativeProxyFunction (target , handler );
1241+ } else {
1242+ proxy = new NativeProxy (target , handler );
1243+ }
1244+
13151245 proxy .setPrototypeDirect (ScriptableObject .getClassPrototype (scope , PROXY_TAG ));
13161246 proxy .setParentScope (scope );
13171247 return proxy ;
@@ -1332,7 +1262,7 @@ private static Object revocable(
13321262 return revocable ;
13331263 }
13341264
1335- private Function getTrap (String trapName ) {
1265+ protected final Function getTrap (String trapName ) {
13361266 Object handlerProp = ScriptableObject .getProperty (handlerObj , trapName );
13371267 if (Scriptable .NOT_FOUND == handlerProp ) {
13381268 return null ;
@@ -1347,7 +1277,7 @@ private Function getTrap(String trapName) {
13471277 return (Function ) handlerProp ;
13481278 }
13491279
1350- private Object callTrap (Function trap , Object [] args ) {
1280+ protected final Object callTrap (Function trap , Object [] args ) {
13511281 return trap .call (Context .getContext (), trap .getDeclarationScope (), handlerObj , args );
13521282 }
13531283
@@ -1357,4 +1287,87 @@ ScriptableObject getTargetThrowIfRevoked() {
13571287 }
13581288 return targetObj ;
13591289 }
1290+
1291+ static class NativeProxyFunction extends NativeProxy implements Function {
1292+
1293+ NativeProxyFunction (ScriptableObject target , Scriptable handler ) {
1294+ super (target , handler );
1295+ }
1296+
1297+ /**
1298+ * see <a href=
1299+ * "https://262.ecma-international.org/12.0/#sec-proxy-object-internal-methods-and-internal-slots-construct-argumentslist-newtarget">10.5.13
1300+ * [[Construct]] (argumentsList, newTarget)</a>
1301+ */
1302+ @ Override
1303+ public Scriptable construct (Context cx , Scriptable scope , Object [] args ) {
1304+ /*
1305+ * 1. Let handler be O.[[ProxyHandler]].
1306+ * 2. If handler is null, throw a TypeError exception.
1307+ * 3. Assert: Type(handler) is Object.
1308+ * 4. Let target be O.[[ProxyTarget]].
1309+ * 5. Assert: IsConstructor(target) is true.
1310+ * 6. Let trap be ? GetMethod(handler, "construct").
1311+ * 7. If trap is undefined, then
1312+ * a. Return ? Construct(target, argumentsList, newTarget).
1313+ * 8. Let argArray be ! CreateArrayFromList(argumentsList).
1314+ * 9. Let newObj be ? Call(trap, handler, « target, argArray, newTarget »).
1315+ * 10. If Type(newObj) is not Object, throw a TypeError exception.
1316+ * 11. Return newObj.
1317+ */
1318+ ScriptableObject target = getTargetThrowIfRevoked ();
1319+
1320+ Function trap = getTrap (TRAP_CONSTRUCT );
1321+ if (trap != null ) {
1322+ Object result = callTrap (trap , new Object [] {target , args , this });
1323+ if (!(result instanceof Scriptable ) || ScriptRuntime .isSymbol (result )) {
1324+ throw ScriptRuntime .typeError ("Constructor trap has to return a scriptable." );
1325+ }
1326+ return (ScriptableObject ) result ;
1327+ }
1328+
1329+ return ((Constructable ) target ).construct (cx , scope , args );
1330+ }
1331+
1332+ /**
1333+ * see <a href=
1334+ * "https://262.ecma-international.org/12.0/#sec-proxy-object-internal-methods-and-internal-slots-call-thisargument-argumentslist">10.5.12
1335+ * [[Call]] (thisArgument, argumentsList)</a>
1336+ */
1337+ @ Override
1338+ public Object call (Context cx , Scriptable scope , Scriptable thisObj , Object [] args ) {
1339+ /*
1340+ * 1. Let handler be O.[[ProxyHandler]].
1341+ * 2. If handler is null, throw a TypeError exception.
1342+ * 3. Assert: Type(handler) is Object.
1343+ * 4. Let target be O.[[ProxyTarget]].
1344+ * 5. Let trap be ? GetMethod(handler, "apply").
1345+ * 6. If trap is undefined, then
1346+ * a. Return ? Call(target, thisArgument, argumentsList).
1347+ * 7. Let argArray be ! CreateArrayFromList(argumentsList).
1348+ * 8. Return ? Call(trap, handler, « target, thisArgument, argArray »).
1349+ */
1350+ ScriptableObject target = getTargetThrowIfRevoked ();
1351+
1352+ Scriptable argumentsList = cx .newArray (scope , args );
1353+
1354+ Function trap = getTrap (TRAP_APPLY );
1355+ if (trap != null ) {
1356+ return callTrap (trap , new Object [] {target , thisObj , argumentsList });
1357+ }
1358+
1359+ return ScriptRuntime .applyOrCall (
1360+ true , cx , scope , target , new Object [] {thisObj , argumentsList });
1361+ }
1362+
1363+ @ Override
1364+ public Scriptable getDeclarationScope () {
1365+ ScriptableObject target = getTargetThrowIfRevoked ();
1366+ if (target instanceof Function ) {
1367+ return ((Function ) target ).getDeclarationScope ();
1368+ }
1369+ Kit .codeBug ();
1370+ return null ;
1371+ }
1372+ }
13601373}
0 commit comments