From ff093302029d9a884ff4b0a4426f0263b49b2894 Mon Sep 17 00:00:00 2001 From: Max Desiatov Date: Thu, 12 May 2022 18:10:57 +0100 Subject: [PATCH 1/4] Map `long long` IDL type to Swift `Int32` This fixes an issue with `func vertexAttribPointer(index: GLuint, size: GLint, type: GLenum, normalized: GLboolean, stride: GLsizei, offset: GLintptr)` passing `offset` value of `BigInt` type to the JS function due to `public typealias GLintptr = Int64`, which led to `can't cast BigInt to number` runtime errors. Either WebGL spec is wrong, or browsers implement it incorrectly. Rust folks had a similar issue and they went with `i32`. --- Sources/WebAPIKit/Generated.swift | 42 +++++++++---------- .../WebIDL+SwiftRepresentation.swift | 2 +- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/Sources/WebAPIKit/Generated.swift b/Sources/WebAPIKit/Generated.swift index 0ec0d64c..594b4711 100644 --- a/Sources/WebAPIKit/Generated.swift +++ b/Sources/WebAPIKit/Generated.swift @@ -1016,7 +1016,7 @@ public class AudioData: JSBridgedClass { public var duration: UInt64 @ReadonlyAttribute - public var timestamp: Int64 + public var timestamp: Int32 @inlinable public func allocationSize(options: AudioDataCopyToOptions) -> UInt32 { let this = jsObject @@ -1071,7 +1071,7 @@ public class AudioDataCopyToOptions: BridgedDictionary { } public class AudioDataInit: BridgedDictionary { - public convenience init(format: AudioSampleFormat, sampleRate: Float, numberOfFrames: UInt32, numberOfChannels: UInt32, timestamp: Int64, data: BufferSource) { + public convenience init(format: AudioSampleFormat, sampleRate: Float, numberOfFrames: UInt32, numberOfChannels: UInt32, timestamp: Int32, data: BufferSource) { let object = JSObject.global[Strings.Object].function!.new() object[Strings.format] = format.jsValue object[Strings.sampleRate] = sampleRate.jsValue @@ -1105,7 +1105,7 @@ public class AudioDataInit: BridgedDictionary { public var numberOfChannels: UInt32 @ReadWriteAttribute - public var timestamp: Int64 + public var timestamp: Int32 @ReadWriteAttribute public var data: BufferSource @@ -2336,7 +2336,7 @@ public class Blob: JSBridgedClass { @ReadonlyAttribute public var type: String - @inlinable public func slice(start: Int64? = nil, end: Int64? = nil, contentType: String? = nil) -> Self { + @inlinable public func slice(start: Int32? = nil, end: Int32? = nil, contentType: String? = nil) -> Self { let this = jsObject return this[Strings.slice].function!(this: this, arguments: [start?.jsValue ?? .undefined, end?.jsValue ?? .undefined, contentType?.jsValue ?? .undefined]).fromJSValue()! } @@ -6788,7 +6788,7 @@ public class EncodedAudioChunk: JSBridgedClass { public var type: EncodedAudioChunkType @ReadonlyAttribute - public var timestamp: Int64 + public var timestamp: Int32 @ReadonlyAttribute public var duration: UInt64? @@ -6803,7 +6803,7 @@ public class EncodedAudioChunk: JSBridgedClass { } public class EncodedAudioChunkInit: BridgedDictionary { - public convenience init(type: EncodedAudioChunkType, timestamp: Int64, duration: UInt64, data: BufferSource) { + public convenience init(type: EncodedAudioChunkType, timestamp: Int32, duration: UInt64, data: BufferSource) { let object = JSObject.global[Strings.Object].function!.new() object[Strings.type] = type.jsValue object[Strings.timestamp] = timestamp.jsValue @@ -6824,7 +6824,7 @@ public class EncodedAudioChunkInit: BridgedDictionary { public var type: EncodedAudioChunkType @ReadWriteAttribute - public var timestamp: Int64 + public var timestamp: Int32 @ReadWriteAttribute public var duration: UInt64 @@ -6888,7 +6888,7 @@ public class EncodedVideoChunk: JSBridgedClass { public var type: EncodedVideoChunkType @ReadonlyAttribute - public var timestamp: Int64 + public var timestamp: Int32 @ReadonlyAttribute public var duration: UInt64? @@ -6903,7 +6903,7 @@ public class EncodedVideoChunk: JSBridgedClass { } public class EncodedVideoChunkInit: BridgedDictionary { - public convenience init(type: EncodedVideoChunkType, timestamp: Int64, duration: UInt64, data: BufferSource) { + public convenience init(type: EncodedVideoChunkType, timestamp: Int32, duration: UInt64, data: BufferSource) { let object = JSObject.global[Strings.Object].function!.new() object[Strings.type] = type.jsValue object[Strings.timestamp] = timestamp.jsValue @@ -6924,7 +6924,7 @@ public class EncodedVideoChunkInit: BridgedDictionary { public var type: EncodedVideoChunkType @ReadWriteAttribute - public var timestamp: Int64 + public var timestamp: Int32 @ReadWriteAttribute public var duration: UInt64 @@ -7461,7 +7461,7 @@ public class File: Blob { public var name: String @ReadonlyAttribute - public var lastModified: Int64 + public var lastModified: Int32 } public class FileList: JSBridgedClass { @@ -7483,7 +7483,7 @@ public class FileList: JSBridgedClass { } public class FilePropertyBag: BridgedDictionary { - public convenience init(lastModified: Int64) { + public convenience init(lastModified: Int32) { let object = JSObject.global[Strings.Object].function!.new() object[Strings.lastModified] = lastModified.jsValue self.init(unsafelyWrapping: object) @@ -7495,7 +7495,7 @@ public class FilePropertyBag: BridgedDictionary { } @ReadWriteAttribute - public var lastModified: Int64 + public var lastModified: Int32 } public class FileReader: EventTarget { @@ -21238,15 +21238,15 @@ public typealias GLbyte = Int8 public typealias GLshort = Int16 public typealias GLint = Int32 public typealias GLsizei = Int32 -public typealias GLintptr = Int64 -public typealias GLsizeiptr = Int64 +public typealias GLintptr = Int32 +public typealias GLsizeiptr = Int32 public typealias GLubyte = UInt8 public typealias GLushort = UInt16 public typealias GLuint = UInt32 public typealias GLfloat = Float public typealias GLclampf = Float -public typealias GLint64 = Int64 +public typealias GLint64 = Int32 public typealias GLuint64 = UInt64 public typealias GPUBufferUsageFlags = UInt32 @@ -22213,7 +22213,7 @@ public class VideoFrame: JSBridgedClass { public var duration: UInt64? @ReadonlyAttribute - public var timestamp: Int64? + public var timestamp: Int32? @ReadonlyAttribute public var colorSpace: VideoColorSpace @@ -22247,7 +22247,7 @@ public class VideoFrame: JSBridgedClass { } public class VideoFrameBufferInit: BridgedDictionary { - public convenience init(format: VideoPixelFormat, codedWidth: UInt32, codedHeight: UInt32, timestamp: Int64, duration: UInt64, layout: [PlaneLayout], visibleRect: DOMRectInit, displayWidth: UInt32, displayHeight: UInt32, colorSpace: VideoColorSpaceInit) { + public convenience init(format: VideoPixelFormat, codedWidth: UInt32, codedHeight: UInt32, timestamp: Int32, duration: UInt64, layout: [PlaneLayout], visibleRect: DOMRectInit, displayWidth: UInt32, displayHeight: UInt32, colorSpace: VideoColorSpaceInit) { let object = JSObject.global[Strings.Object].function!.new() object[Strings.format] = format.jsValue object[Strings.codedWidth] = codedWidth.jsValue @@ -22286,7 +22286,7 @@ public class VideoFrameBufferInit: BridgedDictionary { public var codedHeight: UInt32 @ReadWriteAttribute - public var timestamp: Int64 + public var timestamp: Int32 @ReadWriteAttribute public var duration: UInt64 @@ -22329,7 +22329,7 @@ public class VideoFrameCopyToOptions: BridgedDictionary { } public class VideoFrameInit: BridgedDictionary { - public convenience init(duration: UInt64, timestamp: Int64, alpha: AlphaOption, visibleRect: DOMRectInit, displayWidth: UInt32, displayHeight: UInt32) { + public convenience init(duration: UInt64, timestamp: Int32, alpha: AlphaOption, visibleRect: DOMRectInit, displayWidth: UInt32, displayHeight: UInt32) { let object = JSObject.global[Strings.Object].function!.new() object[Strings.duration] = duration.jsValue object[Strings.timestamp] = timestamp.jsValue @@ -22354,7 +22354,7 @@ public class VideoFrameInit: BridgedDictionary { public var duration: UInt64 @ReadWriteAttribute - public var timestamp: Int64 + public var timestamp: Int32 @ReadWriteAttribute public var alpha: AlphaOption diff --git a/Sources/WebIDLToSwift/WebIDL+SwiftRepresentation.swift b/Sources/WebIDLToSwift/WebIDL+SwiftRepresentation.swift index 0a5c4005..9d97f6fb 100644 --- a/Sources/WebIDLToSwift/WebIDL+SwiftRepresentation.swift +++ b/Sources/WebIDLToSwift/WebIDL+SwiftRepresentation.swift @@ -541,7 +541,7 @@ extension IDLType: SwiftRepresentable { "byte": "Int8", "short": "Int16", "long": "Int32", - "long long": "Int64", + "long long": "Int32", "Function": "JSFunction", "bigint": "__UNSUPPORTED_BIGINT__", ] From 90de29e4478ce11b943f1ccc061d97b67e7ac056 Mon Sep 17 00:00:00 2001 From: Max Desiatov Date: Thu, 12 May 2022 20:51:53 +0100 Subject: [PATCH 2/4] Declare `GLintptr` typealias manually --- Sources/WebAPIKit/Generated.swift | 1 - Sources/WebAPIKit/Support.swift | 3 ++- Sources/WebIDLToSwift/MergeDeclarations.swift | 2 ++ Sources/WebIDLToSwift/WebIDL+SwiftRepresentation.swift | 3 ++- 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Sources/WebAPIKit/Generated.swift b/Sources/WebAPIKit/Generated.swift index 594b4711..b420e97b 100644 --- a/Sources/WebAPIKit/Generated.swift +++ b/Sources/WebAPIKit/Generated.swift @@ -21238,7 +21238,6 @@ public typealias GLbyte = Int8 public typealias GLshort = Int16 public typealias GLint = Int32 public typealias GLsizei = Int32 -public typealias GLintptr = Int32 public typealias GLsizeiptr = Int32 public typealias GLubyte = UInt8 public typealias GLushort = UInt16 diff --git a/Sources/WebAPIKit/Support.swift b/Sources/WebAPIKit/Support.swift index df39886f..a4c1aa5e 100644 --- a/Sources/WebAPIKit/Support.swift +++ b/Sources/WebAPIKit/Support.swift @@ -1,5 +1,5 @@ -import JavaScriptKit @_exported import ECMAScript +import JavaScriptKit /* TODO: fix this */ public typealias __UNSUPPORTED_BIGINT__ = JSValue @@ -22,3 +22,4 @@ public typealias HTMLOrSVGImageElement = HTMLImageElement public typealias HTMLOrSVGScriptElement = HTMLScriptElement public typealias BodyInit = XMLHttpRequestBodyInit public typealias CustomElementConstructor = JSFunction +public typealias GLintptr = Int32 diff --git a/Sources/WebIDLToSwift/MergeDeclarations.swift b/Sources/WebIDLToSwift/MergeDeclarations.swift index 991c11ef..b5ff2a63 100644 --- a/Sources/WebIDLToSwift/MergeDeclarations.swift +++ b/Sources/WebIDLToSwift/MergeDeclarations.swift @@ -7,6 +7,8 @@ enum DeclarationMerger { "CustomElementConstructor", "ArrayBufferView", "RotationMatrixType", + // Mapped to `Int32` manually. + "GLintptr", ] static let validExposures: Set = ["Window"] diff --git a/Sources/WebIDLToSwift/WebIDL+SwiftRepresentation.swift b/Sources/WebIDLToSwift/WebIDL+SwiftRepresentation.swift index 9d97f6fb..ed3a8090 100644 --- a/Sources/WebIDLToSwift/WebIDL+SwiftRepresentation.swift +++ b/Sources/WebIDLToSwift/WebIDL+SwiftRepresentation.swift @@ -541,7 +541,8 @@ extension IDLType: SwiftRepresentable { "byte": "Int8", "short": "Int16", "long": "Int32", - "long long": "Int32", + // FIXME: this maps to BigInt when bridged to JS, which most probably leads to issues. + "long long": "Int64", "Function": "JSFunction", "bigint": "__UNSUPPORTED_BIGINT__", ] From dda1e7b2a50c57930a88b9c1b3b72c54680af18d Mon Sep 17 00:00:00 2001 From: Max Desiatov Date: Thu, 12 May 2022 20:57:02 +0100 Subject: [PATCH 3/4] Revert untested `Int32` changes --- Sources/WebAPIKit/Generated.swift | 40 +++++++++++++++---------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/Sources/WebAPIKit/Generated.swift b/Sources/WebAPIKit/Generated.swift index b420e97b..0363d116 100644 --- a/Sources/WebAPIKit/Generated.swift +++ b/Sources/WebAPIKit/Generated.swift @@ -1016,7 +1016,7 @@ public class AudioData: JSBridgedClass { public var duration: UInt64 @ReadonlyAttribute - public var timestamp: Int32 + public var timestamp: Int64 @inlinable public func allocationSize(options: AudioDataCopyToOptions) -> UInt32 { let this = jsObject @@ -1071,7 +1071,7 @@ public class AudioDataCopyToOptions: BridgedDictionary { } public class AudioDataInit: BridgedDictionary { - public convenience init(format: AudioSampleFormat, sampleRate: Float, numberOfFrames: UInt32, numberOfChannels: UInt32, timestamp: Int32, data: BufferSource) { + public convenience init(format: AudioSampleFormat, sampleRate: Float, numberOfFrames: UInt32, numberOfChannels: UInt32, timestamp: Int64, data: BufferSource) { let object = JSObject.global[Strings.Object].function!.new() object[Strings.format] = format.jsValue object[Strings.sampleRate] = sampleRate.jsValue @@ -1105,7 +1105,7 @@ public class AudioDataInit: BridgedDictionary { public var numberOfChannels: UInt32 @ReadWriteAttribute - public var timestamp: Int32 + public var timestamp: Int64 @ReadWriteAttribute public var data: BufferSource @@ -2336,7 +2336,7 @@ public class Blob: JSBridgedClass { @ReadonlyAttribute public var type: String - @inlinable public func slice(start: Int32? = nil, end: Int32? = nil, contentType: String? = nil) -> Self { + @inlinable public func slice(start: Int64? = nil, end: Int64? = nil, contentType: String? = nil) -> Self { let this = jsObject return this[Strings.slice].function!(this: this, arguments: [start?.jsValue ?? .undefined, end?.jsValue ?? .undefined, contentType?.jsValue ?? .undefined]).fromJSValue()! } @@ -6788,7 +6788,7 @@ public class EncodedAudioChunk: JSBridgedClass { public var type: EncodedAudioChunkType @ReadonlyAttribute - public var timestamp: Int32 + public var timestamp: Int64 @ReadonlyAttribute public var duration: UInt64? @@ -6803,7 +6803,7 @@ public class EncodedAudioChunk: JSBridgedClass { } public class EncodedAudioChunkInit: BridgedDictionary { - public convenience init(type: EncodedAudioChunkType, timestamp: Int32, duration: UInt64, data: BufferSource) { + public convenience init(type: EncodedAudioChunkType, timestamp: Int64, duration: UInt64, data: BufferSource) { let object = JSObject.global[Strings.Object].function!.new() object[Strings.type] = type.jsValue object[Strings.timestamp] = timestamp.jsValue @@ -6824,7 +6824,7 @@ public class EncodedAudioChunkInit: BridgedDictionary { public var type: EncodedAudioChunkType @ReadWriteAttribute - public var timestamp: Int32 + public var timestamp: Int64 @ReadWriteAttribute public var duration: UInt64 @@ -6888,7 +6888,7 @@ public class EncodedVideoChunk: JSBridgedClass { public var type: EncodedVideoChunkType @ReadonlyAttribute - public var timestamp: Int32 + public var timestamp: Int64 @ReadonlyAttribute public var duration: UInt64? @@ -6903,7 +6903,7 @@ public class EncodedVideoChunk: JSBridgedClass { } public class EncodedVideoChunkInit: BridgedDictionary { - public convenience init(type: EncodedVideoChunkType, timestamp: Int32, duration: UInt64, data: BufferSource) { + public convenience init(type: EncodedVideoChunkType, timestamp: Int64, duration: UInt64, data: BufferSource) { let object = JSObject.global[Strings.Object].function!.new() object[Strings.type] = type.jsValue object[Strings.timestamp] = timestamp.jsValue @@ -6924,7 +6924,7 @@ public class EncodedVideoChunkInit: BridgedDictionary { public var type: EncodedVideoChunkType @ReadWriteAttribute - public var timestamp: Int32 + public var timestamp: Int64 @ReadWriteAttribute public var duration: UInt64 @@ -7461,7 +7461,7 @@ public class File: Blob { public var name: String @ReadonlyAttribute - public var lastModified: Int32 + public var lastModified: Int64 } public class FileList: JSBridgedClass { @@ -7483,7 +7483,7 @@ public class FileList: JSBridgedClass { } public class FilePropertyBag: BridgedDictionary { - public convenience init(lastModified: Int32) { + public convenience init(lastModified: Int64) { let object = JSObject.global[Strings.Object].function!.new() object[Strings.lastModified] = lastModified.jsValue self.init(unsafelyWrapping: object) @@ -7495,7 +7495,7 @@ public class FilePropertyBag: BridgedDictionary { } @ReadWriteAttribute - public var lastModified: Int32 + public var lastModified: Int64 } public class FileReader: EventTarget { @@ -21238,14 +21238,14 @@ public typealias GLbyte = Int8 public typealias GLshort = Int16 public typealias GLint = Int32 public typealias GLsizei = Int32 -public typealias GLsizeiptr = Int32 +public typealias GLsizeiptr = Int64 public typealias GLubyte = UInt8 public typealias GLushort = UInt16 public typealias GLuint = UInt32 public typealias GLfloat = Float public typealias GLclampf = Float -public typealias GLint64 = Int32 +public typealias GLint64 = Int64 public typealias GLuint64 = UInt64 public typealias GPUBufferUsageFlags = UInt32 @@ -22212,7 +22212,7 @@ public class VideoFrame: JSBridgedClass { public var duration: UInt64? @ReadonlyAttribute - public var timestamp: Int32? + public var timestamp: Int64? @ReadonlyAttribute public var colorSpace: VideoColorSpace @@ -22246,7 +22246,7 @@ public class VideoFrame: JSBridgedClass { } public class VideoFrameBufferInit: BridgedDictionary { - public convenience init(format: VideoPixelFormat, codedWidth: UInt32, codedHeight: UInt32, timestamp: Int32, duration: UInt64, layout: [PlaneLayout], visibleRect: DOMRectInit, displayWidth: UInt32, displayHeight: UInt32, colorSpace: VideoColorSpaceInit) { + public convenience init(format: VideoPixelFormat, codedWidth: UInt32, codedHeight: UInt32, timestamp: Int64, duration: UInt64, layout: [PlaneLayout], visibleRect: DOMRectInit, displayWidth: UInt32, displayHeight: UInt32, colorSpace: VideoColorSpaceInit) { let object = JSObject.global[Strings.Object].function!.new() object[Strings.format] = format.jsValue object[Strings.codedWidth] = codedWidth.jsValue @@ -22285,7 +22285,7 @@ public class VideoFrameBufferInit: BridgedDictionary { public var codedHeight: UInt32 @ReadWriteAttribute - public var timestamp: Int32 + public var timestamp: Int64 @ReadWriteAttribute public var duration: UInt64 @@ -22328,7 +22328,7 @@ public class VideoFrameCopyToOptions: BridgedDictionary { } public class VideoFrameInit: BridgedDictionary { - public convenience init(duration: UInt64, timestamp: Int32, alpha: AlphaOption, visibleRect: DOMRectInit, displayWidth: UInt32, displayHeight: UInt32) { + public convenience init(duration: UInt64, timestamp: Int64, alpha: AlphaOption, visibleRect: DOMRectInit, displayWidth: UInt32, displayHeight: UInt32) { let object = JSObject.global[Strings.Object].function!.new() object[Strings.duration] = duration.jsValue object[Strings.timestamp] = timestamp.jsValue @@ -22353,7 +22353,7 @@ public class VideoFrameInit: BridgedDictionary { public var duration: UInt64 @ReadWriteAttribute - public var timestamp: Int32 + public var timestamp: Int64 @ReadWriteAttribute public var alpha: AlphaOption From 3a150350f02a839a5fbbcfd0a98399edf8d26abd Mon Sep 17 00:00:00 2001 From: Max Desiatov Date: Thu, 12 May 2022 20:58:23 +0100 Subject: [PATCH 4/4] Expand `GLintptr` comment --- Sources/WebIDLToSwift/MergeDeclarations.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Sources/WebIDLToSwift/MergeDeclarations.swift b/Sources/WebIDLToSwift/MergeDeclarations.swift index b5ff2a63..7902f6ed 100644 --- a/Sources/WebIDLToSwift/MergeDeclarations.swift +++ b/Sources/WebIDLToSwift/MergeDeclarations.swift @@ -7,7 +7,8 @@ enum DeclarationMerger { "CustomElementConstructor", "ArrayBufferView", "RotationMatrixType", - // Mapped to `Int32` manually. + // Mapped to `Int32` manually. This can't be represented as `Int64` due to `BigInt` representation on JS side, + // but as a pointer it can't be represented as floating point number either. "GLintptr", ] static let validExposures: Set = ["Window"]