@@ -11,10 +11,10 @@ use crate::{
11
11
ecmascript:: {
12
12
abstract_operations:: {
13
13
operations_on_objects:: {
14
- call, call_function, create_array_from_list, get_object_method,
14
+ call, call_function, construct , create_array_from_list, get_object_method,
15
15
try_get_object_method,
16
16
} ,
17
- testing_and_comparison:: { is_extensible, same_value} ,
17
+ testing_and_comparison:: { is_constructor , is_extensible, same_value} ,
18
18
type_conversion:: to_boolean,
19
19
} ,
20
20
builtins:: ArgumentsList ,
@@ -1322,12 +1322,71 @@ impl InternalMethods for Proxy<'_> {
1322
1322
1323
1323
fn internal_construct (
1324
1324
self ,
1325
- _agent : & mut Agent ,
1326
- _arguments_list : ArgumentsList ,
1327
- _new_target : Function ,
1328
- _gc : GcScope ,
1325
+ agent : & mut Agent ,
1326
+ arguments_list : ArgumentsList ,
1327
+ new_target : Function ,
1328
+ mut gc : GcScope < ' _ , ' _ > ,
1329
1329
) -> JsResult < Object > {
1330
- todo ! ( )
1330
+ // 1. Perform ? ValidateNonRevokedProxy(O).
1331
+ // 2. Let target be O.[[ProxyTarget]].
1332
+ // 4. Let handler be O.[[ProxyHandler]].
1333
+ // 5. Assert: handler is an Object.
1334
+ let NonRevokedProxy {
1335
+ target,
1336
+ mut handler,
1337
+ } = validate_non_revoked_proxy ( agent, self , gc. nogc ( ) ) ?;
1338
+ // 3. Assert: IsConstructor(target) is true.
1339
+ let target = is_constructor ( agent, target) . unwrap ( ) ;
1340
+ // 6. Let trap be ? GetMethod(handler, "construct").
1341
+ let trap = if let TryResult :: Continue ( trap) = try_get_object_method (
1342
+ agent,
1343
+ handler,
1344
+ BUILTIN_STRING_MEMORY . construct . into ( ) ,
1345
+ gc. nogc ( ) ,
1346
+ ) {
1347
+ trap?
1348
+ } else {
1349
+ let scoped_handler = handler. scope ( agent, gc. nogc ( ) ) ;
1350
+ let trap = get_object_method (
1351
+ agent,
1352
+ handler,
1353
+ BUILTIN_STRING_MEMORY . construct . into ( ) ,
1354
+ gc. reborrow ( ) ,
1355
+ ) ?
1356
+ . map ( Function :: unbind) ;
1357
+ let gc = gc. nogc ( ) ;
1358
+ let trap = trap. map ( |f| f. bind ( gc) ) ;
1359
+ handler = scoped_handler. get ( agent) . bind ( gc) ;
1360
+ trap
1361
+ } ;
1362
+ // 7. If trap is undefined, then
1363
+ let Some ( trap) = trap else {
1364
+ // a. Return ? Construct(target, argumentsList, newTarget).
1365
+ return construct ( agent, target, Some ( arguments_list) , Some ( new_target) , gc) ;
1366
+ } ;
1367
+ // 8. Let argArray be CreateArrayFromList(argumentsList).
1368
+ let arg_array = create_array_from_list ( agent, arguments_list. 0 , gc. nogc ( ) ) ;
1369
+ // 9. Let newObj be ? Call(trap, handler, « target, argArray, newTarget »).
1370
+ let new_obj = call_function (
1371
+ agent,
1372
+ trap. unbind ( ) ,
1373
+ handler. into_value ( ) ,
1374
+ Some ( ArgumentsList ( & [
1375
+ target. into_value ( ) ,
1376
+ arg_array. into_value ( ) ,
1377
+ new_target. into_value ( ) ,
1378
+ ] ) ) ,
1379
+ gc. reborrow ( ) ,
1380
+ ) ?;
1381
+ // 11. Return newObj.
1382
+ new_obj
1383
+ . try_into ( )
1384
+ // 10. If newObj is not an Object, throw a TypeError exception.
1385
+ . or ( Err ( agent. throw_exception_with_static_message (
1386
+ ExceptionType :: TypeError ,
1387
+ "proxy [[Construct]] must return an object" ,
1388
+ gc. nogc ( ) ,
1389
+ ) ) )
1331
1390
}
1332
1391
}
1333
1392
0 commit comments