Skip to content

Commit 8092333

Browse files
LiedtkeV8-internal LUCI CQ
authored andcommitted
[environment] Add <Builtin>.prototype.constructor for most builtins
See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor Change-Id: Iaa324d06653a8dfeb2cc5e48b8357f5e4d2670c2 Reviewed-on: https://chrome-internal-review.googlesource.com/c/v8/fuzzilli/+/9051196 Reviewed-by: Michael Achenbach <machenbach@google.com> Commit-Queue: Michael Achenbach <machenbach@google.com> Auto-Submit: Matthias Liedtke <mliedtke@google.com>
1 parent 7fcba01 commit 8092333

2 files changed

Lines changed: 74 additions & 29 deletions

File tree

Sources/Fuzzilli/Environment/JavaScriptEnvironment.swift

Lines changed: 72 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1326,10 +1326,18 @@ public extension ObjectGroup {
13261326
// them. Instead Fuzzilli generates GetProperty operations for them which will then be typed as
13271327
// an `ILType.unboundFunction` which knows the required receiver type (in the example `Date`),
13281328
// so Fuzzilli can generate sequences like `Date.prototype.getTime.call(new Date())`.
1329-
static func createPrototypeObjectGroup(_ receiver: ObjectGroup, excludeProperties: [String] = []) -> ObjectGroup {
1329+
static func createPrototypeObjectGroup(
1330+
_ receiver: ObjectGroup,
1331+
constructor: ILType = .object(),
1332+
excludeProperties: [String] = []) -> ObjectGroup {
13301333
let name = receiver.name + ".prototype"
13311334
var properties = Dictionary(uniqueKeysWithValues: receiver.methods.map {
13321335
($0.0, ILType.unboundFunction($0.1.first, receiver: receiver.instanceType)) })
1336+
1337+
// Each <Builtin>.prototype has a constructor property.
1338+
// In general, the following should hold true:
1339+
// <Builtin>.prototype.constructor === <Builtin>;
1340+
properties["constructor"] = constructor
13331341
// Some properties of the instance type do not come from the prototype, e.g. Iterator.next
13341342
// which comes from the Iterator protocol.
13351343
// Other properties are get accessors instead of regular functions, and error when accessed
@@ -1531,6 +1539,7 @@ public extension ObjectGroup {
15311539

15321540
// next, return and throw are part of the Iterator protocol, not Iterator.prototype.
15331541
static let jsIteratorPrototype = createPrototypeObjectGroup(jsIterator,
1542+
constructor: .jsIteratorConstructor,
15341543
excludeProperties: ["next", "return", "throw"])
15351544

15361545
static let jsIteratorConstructor = ObjectGroup(
@@ -1792,7 +1801,8 @@ public extension ObjectGroup {
17921801
]
17931802
)
17941803

1795-
static let jsPromisePrototype = createPrototypeObjectGroup(jsPromises)
1804+
static let jsPromisePrototype =
1805+
createPrototypeObjectGroup(jsPromises, constructor: .jsPromiseConstructor)
17961806

17971807
/// ObjectGroup modelling the JavaScript Promise constructor builtin
17981808
static let jsPromiseConstructor = ObjectGroup(
@@ -1867,7 +1877,7 @@ public extension ObjectGroup {
18671877
]
18681878
)
18691879

1870-
static let jsDatePrototype = createPrototypeObjectGroup(jsDate)
1880+
static let jsDatePrototype = createPrototypeObjectGroup(jsDate, constructor: .jsDateConstructor)
18711881

18721882
/// ObjectGroup modelling the JavaScript Date constructor
18731883
static let jsDateConstructor = ObjectGroup(
@@ -1934,7 +1944,8 @@ public extension ObjectGroup {
19341944
]
19351945
)
19361946

1937-
static let jsArrayBufferPrototype = createPrototypeObjectGroup(jsArrayBuffers)
1947+
static let jsArrayBufferPrototype =
1948+
createPrototypeObjectGroup(jsArrayBuffers, constructor: .jsArrayBufferConstructor)
19381949

19391950
static let jsArrayBufferConstructor = ObjectGroup(
19401951
name: "ArrayBufferConstructor",
@@ -1948,7 +1959,8 @@ public extension ObjectGroup {
19481959
]
19491960
)
19501961

1951-
static let jsSharedArrayBufferPrototype = createPrototypeObjectGroup(jsSharedArrayBuffers)
1962+
static let jsSharedArrayBufferPrototype =
1963+
createPrototypeObjectGroup(jsSharedArrayBuffers, constructor: .jsSharedArrayBufferConstructor)
19521964

19531965
static let jsSharedArrayBufferConstructor = ObjectGroup(
19541966
name: "SharedArrayBufferConstructor",
@@ -1960,7 +1972,8 @@ public extension ObjectGroup {
19601972
methods: [:]
19611973
)
19621974

1963-
static let jsStringPrototype = createPrototypeObjectGroup(jsStrings)
1975+
static let jsStringPrototype =
1976+
createPrototypeObjectGroup(jsStrings, constructor: .jsStringConstructor)
19641977

19651978
/// Object group modelling the JavaScript String constructor builtin
19661979
static let jsStringConstructor = ObjectGroup(
@@ -2208,7 +2221,8 @@ public extension ObjectGroup {
22082221
]
22092222
)
22102223

2211-
static let jsWebAssemblyGlobalPrototype = createPrototypeObjectGroup(jsWasmGlobal)
2224+
static let jsWebAssemblyGlobalPrototype =
2225+
createPrototypeObjectGroup(jsWasmGlobal, constructor: .jsWebAssemblyGlobalConstructor)
22122226

22132227
static let jsWebAssemblyGlobalConstructor = ObjectGroup(
22142228
name: "WebAssemblyGlobalConstructor",
@@ -2239,7 +2253,8 @@ public extension ObjectGroup {
22392253
methods: [:]
22402254
)
22412255

2242-
static let jsWebAssemblyMemoryPrototype = createPrototypeObjectGroup(jsWasmMemory)
2256+
static let jsWebAssemblyMemoryPrototype =
2257+
createPrototypeObjectGroup(jsWasmMemory, constructor: .jsWebAssemblyMemoryConstructor)
22432258

22442259
static let jsWebAssemblyMemoryConstructor = ObjectGroup(
22452260
name: "WebAssemblyMemoryConstructor",
@@ -2251,7 +2266,8 @@ public extension ObjectGroup {
22512266
methods: [:]
22522267
)
22532268

2254-
static let jsWebAssemblyTablePrototype = createPrototypeObjectGroup(wasmTable)
2269+
static let jsWebAssemblyTablePrototype =
2270+
createPrototypeObjectGroup(wasmTable, constructor: .jsWebAssemblyTableConstructor)
22552271

22562272
static let jsWebAssemblyTableConstructor = ObjectGroup(
22572273
name: "WebAssemblyTableConstructor",
@@ -2263,7 +2279,8 @@ public extension ObjectGroup {
22632279
methods: [:]
22642280
)
22652281

2266-
static let jsWebAssemblyTagPrototype = createPrototypeObjectGroup(jsWasmTag)
2282+
static let jsWebAssemblyTagPrototype =
2283+
createPrototypeObjectGroup(jsWasmTag, constructor: .jsWebAssemblyTagConstructor)
22672284

22682285
static let jsWebAssemblyTagConstructor = ObjectGroup(
22692286
name: "WebAssemblyTagConstructor",
@@ -2287,7 +2304,9 @@ public extension ObjectGroup {
22872304
]
22882305
)
22892306

2290-
static let jsWebAssemblyExceptionPrototype = createPrototypeObjectGroup(jsWebAssemblyException)
2307+
static let jsWebAssemblyExceptionPrototype = createPrototypeObjectGroup(
2308+
jsWebAssemblyException,
2309+
constructor: .jsWebAssemblyExceptionConstructor)
22912310

22922311
static let jsWebAssemblyExceptionConstructor = ObjectGroup(
22932312
name: "WebAssemblyExceptionConstructor",
@@ -2498,7 +2517,8 @@ public extension ObjectGroup {
24982517
]
24992518
)
25002519

2501-
static let jsTemporalInstantPrototype = createPrototypeObjectGroup(jsTemporalInstant)
2520+
static let jsTemporalInstantPrototype =
2521+
createPrototypeObjectGroup(jsTemporalInstant, constructor: .jsTemporalInstantConstructor)
25022522

25032523
/// ObjectGroup modelling the JavaScript Temporal.Instant constructor
25042524
static let jsTemporalInstantConstructor = ObjectGroup(
@@ -2547,7 +2567,8 @@ public extension ObjectGroup {
25472567
]
25482568
)
25492569

2550-
static let jsTemporalDurationPrototype = createPrototypeObjectGroup(jsTemporalDuration)
2570+
static let jsTemporalDurationPrototype =
2571+
createPrototypeObjectGroup(jsTemporalDuration, constructor: .jsTemporalDurationConstructor)
25512572

25522573
/// ObjectGroup modelling the JavaScript Temporal.Duration constructor
25532574
static let jsTemporalDurationConstructor = ObjectGroup(
@@ -2588,7 +2609,8 @@ public extension ObjectGroup {
25882609
]
25892610
)
25902611

2591-
static let jsTemporalPlainTimePrototype = createPrototypeObjectGroup(jsTemporalPlainTime)
2612+
static let jsTemporalPlainTimePrototype =
2613+
createPrototypeObjectGroup(jsTemporalPlainTime, constructor: .jsTemporalPlainTimeConstructor)
25922614

25932615
/// ObjectGroup modelling the JavaScript Temporal.PlainTime constructor
25942616
static let jsTemporalPlainTimeConstructor = ObjectGroup(
@@ -2635,7 +2657,9 @@ public extension ObjectGroup {
26352657
]
26362658
)
26372659

2638-
static let jsTemporalPlainYearMonthPrototype = createPrototypeObjectGroup(jsTemporalPlainYearMonth)
2660+
static let jsTemporalPlainYearMonthPrototype = createPrototypeObjectGroup(
2661+
jsTemporalPlainYearMonth,
2662+
constructor: .jsTemporalPlainYearMonthConstructor)
26392663

26402664
/// ObjectGroup modelling the JavaScript Temporal.PlainYearMonth constructor
26412665
static let jsTemporalPlainYearMonthConstructor = ObjectGroup(
@@ -2669,7 +2693,9 @@ public extension ObjectGroup {
26692693
]
26702694
)
26712695

2672-
static let jsTemporalPlainMonthDayPrototype = createPrototypeObjectGroup(jsTemporalPlainMonthDay)
2696+
static let jsTemporalPlainMonthDayPrototype = createPrototypeObjectGroup(
2697+
jsTemporalPlainMonthDay,
2698+
constructor: .jsTemporalPlainMonthDayConstructor)
26732699

26742700
/// ObjectGroup modelling the JavaScript Temporal.PlainMonthDay constructor.
26752701
static let jsTemporalPlainMonthDayConstructor = ObjectGroup(
@@ -2715,7 +2741,9 @@ public extension ObjectGroup {
27152741
]
27162742
)
27172743

2718-
static let jsTemporalPlainDatePrototype = createPrototypeObjectGroup(jsTemporalPlainDate)
2744+
static let jsTemporalPlainDatePrototype = createPrototypeObjectGroup(
2745+
jsTemporalPlainDate,
2746+
constructor: .jsTemporalPlainDateConstructor)
27192747

27202748
/// ObjectGroup modelling the JavaScript Temporal.PlainDate constructor
27212749
static let jsTemporalPlainDateConstructor = ObjectGroup(
@@ -2754,7 +2782,9 @@ public extension ObjectGroup {
27542782
]
27552783
)
27562784

2757-
static let jsTemporalPlainDateTimePrototype = createPrototypeObjectGroup(jsTemporalPlainDateTime)
2785+
static let jsTemporalPlainDateTimePrototype = createPrototypeObjectGroup(
2786+
jsTemporalPlainDateTime,
2787+
constructor: .jsTemporalPlainDateTimeConstructor)
27582788

27592789
/// ObjectGroup modelling the JavaScript Temporal.PlainDateTime constructor
27602790
static let jsTemporalPlainDateTimeConstructor = ObjectGroup(
@@ -2804,7 +2834,9 @@ public extension ObjectGroup {
28042834
]
28052835
)
28062836

2807-
static let jsTemporalZonedDateTimePrototype = createPrototypeObjectGroup(jsTemporalZonedDateTime)
2837+
static let jsTemporalZonedDateTimePrototype = createPrototypeObjectGroup(
2838+
jsTemporalZonedDateTime,
2839+
constructor: .jsTemporalZonedDateTimeConstructor)
28082840

28092841
/// ObjectGroup modelling the JavaScript Temporal.ZonedDateTime constructor
28102842
static let jsTemporalZonedDateTimeConstructor = ObjectGroup(
@@ -3112,7 +3144,9 @@ extension ObjectGroup {
31123144

31133145
// Exclude compare as it is a get accessor, not a property, meaning that
31143146
// Intl.Collator.prototype.compare throws unconditionally (even without calling it).
3115-
static let jsIntlCollatorPrototype = createPrototypeObjectGroup(jsIntlCollator,
3147+
static let jsIntlCollatorPrototype = createPrototypeObjectGroup(
3148+
jsIntlCollator,
3149+
constructor: .jsIntlCollatorConstructor,
31163150
excludeProperties: ["compare"])
31173151

31183152
static let jsIntlCollatorConstructor = ObjectGroup(
@@ -3159,7 +3193,9 @@ extension ObjectGroup {
31593193

31603194
// Exclude format as it is a get accessor, not a property, meaning that
31613195
// Intl.DateTimeFormat.prototype.format throws unconditionally (even without calling it).
3162-
static let jsIntlDateTimeFormatPrototype = createPrototypeObjectGroup(jsIntlDateTimeFormat,
3196+
static let jsIntlDateTimeFormatPrototype = createPrototypeObjectGroup(
3197+
jsIntlDateTimeFormat,
3198+
constructor: .jsIntlDateTimeFormatConstructor,
31633199
excludeProperties: ["format"])
31643200

31653201
static let jsIntlDateTimeFormatConstructor = ObjectGroup(
@@ -3186,7 +3222,9 @@ extension ObjectGroup {
31863222
]
31873223
)
31883224

3189-
static let jsIntlListFormatPrototype = createPrototypeObjectGroup(jsIntlListFormat)
3225+
static let jsIntlListFormatPrototype = createPrototypeObjectGroup(
3226+
jsIntlListFormat,
3227+
constructor: .jsIntlListFormatConstructor)
31903228

31913229
static let jsIntlListFormatConstructor = ObjectGroup(
31923230
name: "IntlListFormatConstructor",
@@ -3231,7 +3269,8 @@ extension ObjectGroup {
32313269
]
32323270
)
32333271

3234-
static let jsIntlLocalePrototype = createPrototypeObjectGroup(jsIntlLocale)
3272+
static let jsIntlLocalePrototype =
3273+
createPrototypeObjectGroup(jsIntlLocale, constructor: .jsIntlLocaleConstructor)
32353274

32363275
static let jsIntlLocaleConstructor = ObjectGroup(
32373276
name: "IntlLocaleConstructor",
@@ -3272,7 +3311,9 @@ extension ObjectGroup {
32723311

32733312
// Exclude format as it is a get accessor, not a property, meaning that
32743313
// Intl.NumberFormat.prototype.format throws unconditionally (even without calling it).
3275-
static let jsIntlNumberFormatPrototype = createPrototypeObjectGroup(jsIntlNumberFormat,
3314+
static let jsIntlNumberFormatPrototype = createPrototypeObjectGroup(
3315+
jsIntlNumberFormat,
3316+
constructor: .jsIntlNumberFormatConstructor,
32763317
excludeProperties: ["format"])
32773318

32783319
static let jsIntlNumberFormatConstructor = ObjectGroup(
@@ -3299,7 +3340,8 @@ extension ObjectGroup {
32993340
]
33003341
)
33013342

3302-
static let jsIntlPluralRulesPrototype = createPrototypeObjectGroup(jsIntlPluralRules)
3343+
static let jsIntlPluralRulesPrototype =
3344+
createPrototypeObjectGroup(jsIntlPluralRules, constructor: .jsIntlPluralRulesConstructor)
33033345

33043346
static let jsIntlPluralRulesConstructor = ObjectGroup(
33053347
name: "IntlPluralRulesConstructor",
@@ -3327,7 +3369,9 @@ extension ObjectGroup {
33273369
]
33283370
)
33293371

3330-
static let jsIntlRelativeTimeFormatPrototype = createPrototypeObjectGroup(jsIntlRelativeTimeFormat)
3372+
static let jsIntlRelativeTimeFormatPrototype = createPrototypeObjectGroup(
3373+
jsIntlRelativeTimeFormat,
3374+
constructor: .jsIntlRelativeTimeFormatConstructor)
33313375

33323376
static let jsIntlRelativeTimeFormatConstructor = ObjectGroup(
33333377
name: "IntlRelativeTimeFormatConstructor",
@@ -3352,7 +3396,8 @@ extension ObjectGroup {
33523396
]
33533397
)
33543398

3355-
static let jsIntlSegmenterPrototype = createPrototypeObjectGroup(jsIntlSegmenter)
3399+
static let jsIntlSegmenterPrototype =
3400+
createPrototypeObjectGroup(jsIntlSegmenter, constructor: .jsIntlSegmenterConstructor)
33563401

33573402
static let jsIntlSegmenterConstructor = ObjectGroup(
33583403
name: "IntlSegmenterConstructor",

Tests/FuzzilliTests/JSTyperTests.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1805,8 +1805,8 @@ class JSTyperTests: XCTestCase {
18051805
let realWasmTag = b.createWasmTag(parameterTypes: [.wasmi32])
18061806
XCTAssert(b.type(of: realWasmTag).Is(.object(ofGroup: "WasmTag")))
18071807
let tagPrototype = b.getProperty("prototype", of: wasmTagConstructor)
1808-
// WebAssembly.Tag.prototype doesn't have any properties or methods.
1809-
XCTAssertEqual(b.type(of: tagPrototype), .object(ofGroup: "WasmTag.prototype"))
1808+
XCTAssertEqual(b.type(of: tagPrototype),
1809+
.object(ofGroup: "WasmTag.prototype", withProperties: ["constructor"]))
18101810

18111811
let wasmExceptionConstructor = b.getProperty("Exception", of: wasm)
18121812
let wasmException = b.construct(wasmExceptionConstructor) // In theory this needs arguments.

0 commit comments

Comments
 (0)