Skip to content

Commit d2e8277

Browse files
committed
fix all webidl tests
1 parent b7f4467 commit d2e8277

File tree

16 files changed

+70
-432
lines changed

16 files changed

+70
-432
lines changed

src/node/internal/internal_inspect.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3023,6 +3023,18 @@ export function formatLog(
30233023

30243024
function isBuiltinPrototype(proto: unknown) {
30253025
if (proto === null) return true;
3026+
// JSG resource type prototypes carry the kResourceTypeInspect symbol.
3027+
// These are not "built-in" in the JS-engine sense even though their
3028+
// constructors are own properties of globalThis (per Web IDL). The
3029+
// prototype walk must continue through them to collect accessor
3030+
// properties (e.g. Blob.prototype.size).
3031+
if (
3032+
typeof proto === 'object' &&
3033+
proto !== null &&
3034+
internal.kResourceTypeInspect in (proto as Record<PropertyKey, unknown>)
3035+
) {
3036+
return false;
3037+
}
30263038
const descriptor = Object.getOwnPropertyDescriptor(proto, 'constructor');
30273039
return (
30283040
descriptor !== undefined &&

src/workerd/api/global-scope.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -619,6 +619,12 @@ class ServiceWorkerGlobalScope: public WorkerGlobalScope {
619619

620620
JSG_NESTED_TYPE(DOMException);
621621
JSG_NESTED_TYPE(WorkerGlobalScope);
622+
if (flags.getSpecCompliantPropertyAttributes()) {
623+
// EventTarget is also declared on WorkerGlobalScope, but V8's
624+
// FunctionTemplate::Inherit() does not propagate instance-template
625+
// properties. Redeclare here so it becomes an own property of globalThis.
626+
JSG_NESTED_TYPE(EventTarget);
627+
}
622628

623629
JSG_METHOD(btoa);
624630
JSG_METHOD(atob);

src/workerd/io/compatibility-date.capnp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1463,13 +1463,18 @@ struct CompatibilityFlags @0x8f8c1b68151b6cef {
14631463
$compatEnableFlag("spec_compliant_property_attributes")
14641464
$compatDisableFlag("no_spec_compliant_property_attributes")
14651465
$experimental;
1466-
# Fixes several Web IDL compliance issues on constructor, method, getter,
1467-
# and setter property attributes:
1466+
# Fixes several Web IDL compliance issues on property attributes:
14681467
# - Constructor .length reflects the number of required arguments instead
14691468
# of always being 0.
14701469
# - Method and static method .length reflects the number of required
14711470
# arguments instead of always being 0.
14721471
# - Getter .length is explicitly 0 and setter .length is 1.
14731472
# - Getter .name is "get <name>" and setter .name is "set <name>" per the
14741473
# Web IDL spec, instead of empty strings.
1474+
# - Constants gain DontDelete (non-configurable) on both the constructor
1475+
# and prototype, matching { writable: false, enumerable: true,
1476+
# configurable: false } per Web IDL.
1477+
# - Interface objects (nested types) become own properties of globalThis
1478+
# with { writable: true, enumerable: false, configurable: true }, instead
1479+
# of being inherited from the prototype chain.
14751480
}

src/workerd/jsg/resource.h

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1542,8 +1542,13 @@ struct ResourceTypeBuilder {
15421542
auto v8Name = v8StrIntern(isolate, name);
15431543
auto v8Value = typeWrapper.wrap(isolate, kj::none, kj::mv(value));
15441544

1545-
constructor->Set(v8Name, v8Value, v8::PropertyAttribute::ReadOnly);
1546-
constructor->PrototypeTemplate()->Set(v8Name, v8Value, v8::PropertyAttribute::ReadOnly);
1545+
// Per Web IDL, constants are {writable: false, enumerable: true, configurable: false}.
1546+
const auto attrs = getSpecCompliantPropertyAttributes(isolate)
1547+
? static_cast<v8::PropertyAttribute>(
1548+
v8::PropertyAttribute::ReadOnly | v8::PropertyAttribute::DontDelete)
1549+
: v8::PropertyAttribute::ReadOnly;
1550+
constructor->Set(v8Name, v8Value, attrs);
1551+
constructor->PrototypeTemplate()->Set(v8Name, v8Value, attrs);
15471552
}
15481553

15491554
template <const char* name, typename Getter, Getter getter>
@@ -1604,7 +1609,28 @@ struct ResourceTypeBuilder {
16041609
static_assert(
16051610
hasGetTemplate, "Type must be listed in JSG_DECLARE_ISOLATE_TYPE to be declared nested.");
16061611

1607-
prototype->Set(isolate, name, typeWrapper.getTemplate(isolate, static_cast<Type*>(nullptr)));
1612+
auto tmpl = typeWrapper.getTemplate(isolate, static_cast<Type*>(nullptr));
1613+
1614+
// Always install on the prototype so that types declared on parent classes are
1615+
// inherited through FunctionTemplate::Inherit().
1616+
prototype->Set(isolate, name, tmpl);
1617+
1618+
if constexpr (isContext) {
1619+
if (getSpecCompliantPropertyAttributes(isolate)) {
1620+
// Per Web IDL, [Exposed] interface objects must be own properties of the global
1621+
// object with { writable: true, enumerable: false, configurable: true }. When
1622+
// building the global scope (isContext == true), also install on the instance
1623+
// template so that they become own properties of globalThis.
1624+
//
1625+
// NOTE: V8's FunctionTemplate::Inherit() does NOT propagate instance-template
1626+
// properties to child types. This means nested types declared on a parent
1627+
// context type (e.g. WorkerGlobalScope) won't automatically appear as own
1628+
// properties of the child (e.g. ServiceWorkerGlobalScope). To keep things
1629+
// simple, the leaf context type must declare all its nested types directly -
1630+
// don't rely on inheriting nested types from parent context classes.
1631+
instance->Set(isolate, name, tmpl, v8::PropertyAttribute::DontEnum);
1632+
}
1633+
}
16081634
}
16091635

16101636
inline void registerTypeScriptRoot() { /* only needed for RTTI */ }

src/wpt/WebCryptoAPI-test.ts

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -210,32 +210,10 @@ export default {
210210
comment:
211211
'IDL tests fail because Workers exposes globals differently than browsers (not as own properties of self)',
212212
expectedFailures: [
213-
'Crypto interface: existence and properties of interface object',
214-
'Crypto interface object length',
215-
'Crypto interface object name',
216-
'Crypto interface: existence and properties of interface prototype object',
217-
'Crypto interface: existence and properties of interface prototype object\'s "constructor" property',
218-
"Crypto interface: existence and properties of interface prototype object's @@unscopables property",
219-
'Crypto interface: attribute subtle',
220-
'Crypto interface: operation getRandomValues(ArrayBufferView)',
221-
'Crypto interface: operation randomUUID()',
222-
'Crypto must be primary interface of crypto',
223-
'CryptoKey interface: existence and properties of interface object',
224-
'CryptoKey interface object length',
225-
'CryptoKey interface object name',
226-
'CryptoKey interface: existence and properties of interface prototype object',
227-
'CryptoKey interface: existence and properties of interface prototype object\'s "constructor" property',
228-
"CryptoKey interface: existence and properties of interface prototype object's @@unscopables property",
229213
'CryptoKey interface: attribute type',
230214
'CryptoKey interface: attribute extractable',
231215
'CryptoKey interface: attribute algorithm',
232216
'CryptoKey interface: attribute usages',
233-
'SubtleCrypto interface: existence and properties of interface object',
234-
'SubtleCrypto interface object length',
235-
'SubtleCrypto interface object name',
236-
'SubtleCrypto interface: existence and properties of interface prototype object',
237-
'SubtleCrypto interface: existence and properties of interface prototype object\'s "constructor" property',
238-
"SubtleCrypto interface: existence and properties of interface prototype object's @@unscopables property",
239217
'SubtleCrypto interface: operation encrypt(AlgorithmIdentifier, CryptoKey, BufferSource)',
240218
'SubtleCrypto interface: operation decrypt(AlgorithmIdentifier, CryptoKey, BufferSource)',
241219
'SubtleCrypto interface: operation sign(AlgorithmIdentifier, CryptoKey, BufferSource)',
@@ -248,7 +226,6 @@ export default {
248226
'SubtleCrypto interface: operation exportKey(KeyFormat, CryptoKey)',
249227
'SubtleCrypto interface: operation wrapKey(KeyFormat, CryptoKey, CryptoKey, AlgorithmIdentifier)',
250228
'SubtleCrypto interface: operation unwrapKey(KeyFormat, BufferSource, CryptoKey, AlgorithmIdentifier, AlgorithmIdentifier, boolean, sequence<KeyUsage>)',
251-
'SubtleCrypto must be primary interface of crypto.subtle',
252229
'Window interface: attribute crypto',
253230
],
254231
},

src/wpt/compression-test.ts

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -91,22 +91,10 @@ export default {
9191
},
9292
'idlharness.https.any.js': {
9393
comment:
94-
'Workers expose globals differently than browsers - these interface tests fail',
94+
'Workers expose globals differently than browsers - readable/writable attribute tests still fail',
9595
expectedFailures: [
96-
'CompressionStream interface: existence and properties of interface object',
97-
'CompressionStream interface object length',
98-
'CompressionStream interface object name',
9996
'CompressionStream interface: existence and properties of interface prototype object',
100-
'CompressionStream interface: existence and properties of interface prototype object\'s "constructor" property',
101-
"CompressionStream interface: existence and properties of interface prototype object's @@unscopables property",
102-
'CompressionStream must be primary interface of new CompressionStream("deflate")',
103-
'DecompressionStream interface: existence and properties of interface object',
104-
'DecompressionStream interface object length',
105-
'DecompressionStream interface object name',
10697
'DecompressionStream interface: existence and properties of interface prototype object',
107-
'DecompressionStream interface: existence and properties of interface prototype object\'s "constructor" property',
108-
"DecompressionStream interface: existence and properties of interface prototype object's @@unscopables property",
109-
'DecompressionStream must be primary interface of new DecompressionStream("deflate")',
11098
],
11199
},
112100
'third_party/pako/pako_inflate.min.js': {},

src/wpt/encoding-test.ts

Lines changed: 1 addition & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -31,45 +31,10 @@ export default {
3131
},
3232
'idlharness.any.js': {
3333
comment:
34-
'Workers expose globals differently than browsers - these interface tests fail',
34+
'Workers expose globals differently than browsers - readable/writable attribute tests still fail',
3535
expectedFailures: [
36-
'TextDecoder interface: existence and properties of interface object',
37-
'TextDecoder interface object length',
38-
'TextDecoder interface object name',
39-
'TextDecoder interface: existence and properties of interface prototype object',
40-
'TextDecoder interface: existence and properties of interface prototype object\'s "constructor" property',
41-
"TextDecoder interface: existence and properties of interface prototype object's @@unscopables property",
42-
'TextDecoder interface: operation decode(optional AllowSharedBufferSource, optional TextDecodeOptions)',
43-
'TextDecoder interface: attribute encoding',
44-
'TextDecoder interface: attribute fatal',
45-
'TextDecoder interface: attribute ignoreBOM',
46-
'TextDecoder must be primary interface of new TextDecoder()',
47-
'TextEncoder interface: existence and properties of interface object',
48-
'TextEncoder interface object length',
49-
'TextEncoder interface object name',
50-
'TextEncoder interface: existence and properties of interface prototype object',
51-
'TextEncoder interface: existence and properties of interface prototype object\'s "constructor" property',
52-
"TextEncoder interface: existence and properties of interface prototype object's @@unscopables property",
53-
'TextEncoder interface: operation encode(optional USVString)',
54-
'TextEncoder interface: operation encodeInto(USVString, Uint8Array)',
55-
'TextEncoder interface: attribute encoding',
56-
'TextEncoder must be primary interface of new TextEncoder()',
57-
'TextDecoderStream interface: existence and properties of interface object',
58-
'TextDecoderStream interface object length',
59-
'TextDecoderStream interface object name',
6036
'TextDecoderStream interface: existence and properties of interface prototype object',
61-
'TextDecoderStream interface: existence and properties of interface prototype object\'s "constructor" property',
62-
"TextDecoderStream interface: existence and properties of interface prototype object's @@unscopables property",
63-
'TextDecoderStream interface: attribute encoding',
64-
'TextDecoderStream interface: attribute fatal',
65-
'TextDecoderStream interface: attribute ignoreBOM',
66-
'TextEncoderStream interface: existence and properties of interface object',
67-
'TextEncoderStream interface object length',
68-
'TextEncoderStream interface object name',
6937
'TextEncoderStream interface: existence and properties of interface prototype object',
70-
'TextEncoderStream interface: existence and properties of interface prototype object\'s "constructor" property',
71-
"TextEncoderStream interface: existence and properties of interface prototype object's @@unscopables property",
72-
'TextEncoderStream interface: attribute encoding',
7338
],
7439
},
7540
'iso-2022-jp-decoder.any.js': {},

src/wpt/fetch/api-test.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,6 @@ export default {
410410
expectedFailures: [
411411
// Headers interface tests
412412
/^Headers interface/,
413-
/^Headers must be primary interface/,
414413
// Request interface tests
415414
/^Request interface/,
416415
// Response interface tests

src/wpt/fs-test.ts

Lines changed: 1 addition & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -185,41 +185,18 @@ export default {
185185
},
186186
'idlharness.https.any.js': {
187187
comment:
188-
'Workers expose globals differently than browsers - these interface tests fail',
188+
'Remaining IDL failures: prototype chain issues, operation .length mismatches',
189189
expectedFailures: [
190-
'FileSystemHandle interface: existence and properties of interface object',
191-
'FileSystemHandle interface object length',
192-
'FileSystemHandle interface object name',
193-
'FileSystemHandle interface: existence and properties of interface prototype object',
194-
'FileSystemHandle interface: existence and properties of interface prototype object\'s "constructor" property',
195-
"FileSystemHandle interface: existence and properties of interface prototype object's @@unscopables property",
196-
'FileSystemHandle interface: attribute kind',
197-
'FileSystemHandle interface: attribute name',
198190
'FileSystemHandle interface: operation isSameEntry(FileSystemHandle)',
199191
'FileSystemFileHandle interface: existence and properties of interface object',
200-
'FileSystemFileHandle interface object length',
201-
'FileSystemFileHandle interface object name',
202-
'FileSystemFileHandle interface: existence and properties of interface prototype object',
203-
'FileSystemFileHandle interface: existence and properties of interface prototype object\'s "constructor" property',
204-
"FileSystemFileHandle interface: existence and properties of interface prototype object's @@unscopables property",
205192
'FileSystemFileHandle interface: operation getFile()',
206193
'FileSystemFileHandle interface: operation createWritable(optional FileSystemCreateWritableOptions)',
207194
'FileSystemDirectoryHandle interface: existence and properties of interface object',
208-
'FileSystemDirectoryHandle interface object length',
209-
'FileSystemDirectoryHandle interface object name',
210-
'FileSystemDirectoryHandle interface: existence and properties of interface prototype object',
211-
'FileSystemDirectoryHandle interface: existence and properties of interface prototype object\'s "constructor" property',
212-
"FileSystemDirectoryHandle interface: existence and properties of interface prototype object's @@unscopables property",
213195
'FileSystemDirectoryHandle interface: operation getFileHandle(USVString, optional FileSystemGetFileOptions)',
214196
'FileSystemDirectoryHandle interface: operation getDirectoryHandle(USVString, optional FileSystemGetDirectoryOptions)',
215197
'FileSystemDirectoryHandle interface: operation removeEntry(USVString, optional FileSystemRemoveOptions)',
216198
'FileSystemDirectoryHandle interface: operation resolve(FileSystemHandle)',
217199
'FileSystemWritableFileStream interface: existence and properties of interface object',
218-
'FileSystemWritableFileStream interface object length',
219-
'FileSystemWritableFileStream interface object name',
220-
'FileSystemWritableFileStream interface: existence and properties of interface prototype object',
221-
'FileSystemWritableFileStream interface: existence and properties of interface prototype object\'s "constructor" property',
222-
"FileSystemWritableFileStream interface: existence and properties of interface prototype object's @@unscopables property",
223200
'FileSystemWritableFileStream interface: operation write(FileSystemWriteChunkType)',
224201
'FileSystemWritableFileStream interface: operation seek(unsigned long long)',
225202
'FileSystemWritableFileStream interface: operation truncate(unsigned long long)',

src/wpt/harness/globals.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,6 @@ import { getBindingPath } from './common';
2929
// @ts-expect-error We're just exposing enough stuff for the tests to pass; it's not a perfect match
3030
globalThis.self = globalThis;
3131

32-
// WPT tests use self.URL which requires URL to be an own property of globalThis
33-
globalThis.URL = URL;
34-
3532
// Some WPT tests reference addEventListener at the top level during file evaluation.
3633
// workerd doesn't have addEventListener on the global (it uses module exports instead),
3734
// so we provide a no-op stub to allow test files to load without throwing.

0 commit comments

Comments
 (0)