@@ -330,19 +330,24 @@ public class JavaScriptEnvironment: ComponentBase {
330
330
331
331
registerObjectGroup ( . jsObjectConstructor)
332
332
registerObjectGroup ( . jsPromiseConstructor)
333
+ registerObjectGroup ( . jsPromisePrototype)
333
334
registerObjectGroup ( . jsArrayConstructor)
334
335
registerObjectGroup ( . jsStringConstructor)
336
+ registerObjectGroup ( . jsStringPrototype)
335
337
registerObjectGroup ( . jsSymbolConstructor)
336
338
registerObjectGroup ( . jsBigIntConstructor)
337
339
registerObjectGroup ( . jsBooleanConstructor)
338
340
registerObjectGroup ( . jsNumberConstructor)
339
341
registerObjectGroup ( . jsMathObject)
340
342
registerObjectGroup ( . jsDate)
341
343
registerObjectGroup ( . jsDateConstructor)
344
+ registerObjectGroup ( . jsDatePrototype)
342
345
registerObjectGroup ( . jsJSONObject)
343
346
registerObjectGroup ( . jsReflectObject)
344
347
registerObjectGroup ( . jsArrayBufferConstructor)
348
+ registerObjectGroup ( . jsArrayBufferPrototype)
345
349
registerObjectGroup ( . jsSharedArrayBufferConstructor)
350
+ registerObjectGroup ( . jsSharedArrayBufferPrototype)
346
351
for variant in [ " Error " , " EvalError " , " RangeError " , " ReferenceError " , " SyntaxError " , " TypeError " , " AggregateError " , " URIError " , " SuppressedError " ] {
347
352
registerObjectGroup ( . jsError( variant) )
348
353
}
@@ -885,6 +890,28 @@ public extension ILType {
885
890
static let wasmTable = ILType . object ( ofGroup: " WasmTable " , withProperties: [ " length " ] , withMethods: [ " get " , " grow " , " set " ] )
886
891
}
887
892
893
+ public extension ObjectGroup {
894
+ // Creates an object group representing a "prototype" object on a built-in, like Date.prototype.
895
+ // These objects are somewhat special in JavaScript as they describe an object which has
896
+ // methods on them for which you shall not call them with the bound this as a receiver, e.g.
897
+ // `Date.prototype.getTime()` fails as `Date.prototype` is not a `Date`.
898
+ // Therefore the methods are registered as properties, so Fuzzilli doesn't generate calls for
899
+ // them. Instead Fuzzilli generates GetProperty operations for them which will then be typed as
900
+ // an `ILType.unboundFunction` which knows the required receiver type (in the example `Date`),
901
+ // so Fuzzilli can generate sequences like `Date.prototype.getTime.call(new Date())`.
902
+ static func createPrototypeObjectGroup( _ receiver: ObjectGroup ) -> ObjectGroup {
903
+ let name = receiver. name + " .prototype "
904
+ let properties = Dictionary ( uniqueKeysWithValues: receiver. methods. map {
905
+ ( $0. 0 , ILType . unboundFunction ( $0. 1 . first, receiver: receiver. instanceType) ) } )
906
+ return ObjectGroup (
907
+ name: name,
908
+ instanceType: . object( ofGroup: name, withProperties: properties. map { $0. 0 } , withMethods: [ ] ) ,
909
+ properties: properties,
910
+ methods: [ : ]
911
+ )
912
+ }
913
+ }
914
+
888
915
// Type information for the object groups that we use to model the JavaScript runtime environment.
889
916
// The general rules here are:
890
917
// * "output" type information (properties and return values) should be as precise as possible
@@ -1259,12 +1286,14 @@ public extension ObjectGroup {
1259
1286
]
1260
1287
)
1261
1288
1289
+ static let jsPromisePrototype = createPrototypeObjectGroup ( jsPromises)
1290
+
1262
1291
/// ObjectGroup modelling the JavaScript Promise constructor builtin
1263
1292
static let jsPromiseConstructor = ObjectGroup (
1264
1293
name: " PromiseConstructor " ,
1265
1294
instanceType: . jsPromiseConstructor,
1266
1295
properties: [
1267
- " prototype " : . object ( )
1296
+ " prototype " : jsPromisePrototype . instanceType
1268
1297
] ,
1269
1298
methods: [
1270
1299
" resolve " : [ . jsAnything] => . jsPromise,
@@ -1330,12 +1359,14 @@ public extension ObjectGroup {
1330
1359
]
1331
1360
)
1332
1361
1362
+ static let jsDatePrototype = createPrototypeObjectGroup ( jsDate)
1363
+
1333
1364
/// ObjectGroup modelling the JavaScript Date constructor
1334
1365
static let jsDateConstructor = ObjectGroup (
1335
1366
name: " DateConstructor " ,
1336
1367
instanceType: . jsDateConstructor,
1337
1368
properties: [
1338
- " prototype " : . object ( )
1369
+ " prototype " : jsDatePrototype . instanceType
1339
1370
] ,
1340
1371
methods: [
1341
1372
" UTC " : [ . number, . opt( . number) , . opt( . number) , . opt( . number) , . opt( . number) , . opt( . number) , . opt( . number) ] => . jsDate,
@@ -1391,32 +1422,38 @@ public extension ObjectGroup {
1391
1422
]
1392
1423
)
1393
1424
1425
+ static let jsArrayBufferPrototype = createPrototypeObjectGroup ( jsArrayBuffers)
1426
+
1394
1427
static let jsArrayBufferConstructor = ObjectGroup (
1395
1428
name: " ArrayBufferConstructor " ,
1396
1429
instanceType: . jsArrayBufferConstructor,
1397
1430
properties: [
1398
- " prototype " : . object ( )
1431
+ " prototype " : jsArrayBufferPrototype . instanceType
1399
1432
] ,
1400
1433
methods: [
1401
1434
" isView " : [ . jsAnything] => . boolean
1402
1435
]
1403
1436
)
1404
1437
1438
+ static let jsSharedArrayBufferPrototype = createPrototypeObjectGroup ( jsSharedArrayBuffers)
1439
+
1405
1440
static let jsSharedArrayBufferConstructor = ObjectGroup (
1406
1441
name: " SharedArrayBufferConstructor " ,
1407
1442
instanceType: . jsSharedArrayBufferConstructor,
1408
1443
properties: [
1409
- " prototype " : . object ( )
1444
+ " prototype " : jsSharedArrayBufferPrototype . instanceType
1410
1445
] ,
1411
1446
methods: [ : ]
1412
1447
)
1413
1448
1449
+ static let jsStringPrototype = createPrototypeObjectGroup ( jsStrings)
1450
+
1414
1451
/// Object group modelling the JavaScript String constructor builtin
1415
1452
static let jsStringConstructor = ObjectGroup (
1416
1453
name: " StringConstructor " ,
1417
1454
instanceType: . jsStringConstructor,
1418
1455
properties: [
1419
- " prototype " : . object ( )
1456
+ " prototype " : jsStringPrototype . instanceType
1420
1457
] ,
1421
1458
methods: [
1422
1459
" fromCharCode " : [ . jsAnything... ] => . jsString,
0 commit comments