Skip to content

Unable to call JS functions with more than 2 arguments in Embedded Swift #279

Closed
@ole

Description

@ole

When building for Embedded Swift, JSValue and JSObject don’t support JS function calls with more than 2 arguments. I noticed this when trying to call the fillRect() method on CanvasRenderingContext2D. Example:

import JavaScriptKit

let document = JSObject.global.document
let canvas = document.getElementById("canvas")
var ctx: JSValue = canvas.getContext("2d")
// 🔴 Error (in Embedded Swift only): cannot call value of non-function type 'JSValue'
_ = ctx.fillRect(20, 20, 200, 100)

The following works as a workaround but is ugly:

_ = ctx.object!.fillRect.function!(this: ctx.object!, arguments: [20, 20, 200, 100])

The reason that it doesn't work is:

  1. Embedded Swift doesn't support existentials, so the general function invocation mechanism of the form subscript(dynamicMember name: String) -> ((ConvertibleToJSValue...) -> JSValue) is not available.

  2. Both JSValue and JSObject only have concrete overloads for up to 2 function call arguments:

    #if hasFeature(Embedded)
    public extension JSValue {
        @_disfavoredOverload
        subscript(dynamicMember name: String) -> (() -> JSValue)
    
        @_disfavoredOverload
        subscript<A0: ConvertibleToJSValue>(dynamicMember name: String) -> ((A0) -> JSValue)
    
        @_disfavoredOverload
        subscript<A0: ConvertibleToJSValue, A1: ConvertibleToJSValue>(dynamicMember name: String) -> ((A0, A1) -> JSValue)
    }
    #endif

Question: Would you be interested in a PR that adds more of these concrete overloads for Embedded Swift? Or do you want to wait for variadic generics support in Embedded Swift to solve this problem "the right way"?

If it's the former, I'm willing to send the PR. In this case, up to how many arguments should I go? Is 4 enough? Or should we go up to, say, 6?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions