From 7824ccc05113b742f0fe50f006fb8ec326d72f9c Mon Sep 17 00:00:00 2001 From: Samuel Colbran Date: Mon, 6 Sep 2021 13:43:42 -0700 Subject: [PATCH 1/3] expose this --- Runtime/src/index.ts | 12 ++++++++++++ .../FundamentalObjects/JSClosure.swift | 14 ++++++++++++++ Sources/JavaScriptKit/XcodeSupport.swift | 4 ++++ Sources/_CJavaScriptKit/include/_CJavaScriptKit.h | 10 ++++++++++ 4 files changed, 40 insertions(+) diff --git a/Runtime/src/index.ts b/Runtime/src/index.ts index 144fed737..5090125d2 100644 --- a/Runtime/src/index.ts +++ b/Runtime/src/index.ts @@ -448,6 +448,18 @@ export class SwiftRuntime { } writeValue(result, kind_ptr, payload1_ptr, payload2_ptr, false); }, + swjs_create_this_function: ( + host_func_id: number, + func_ref_ptr: pointer + ) => { + const func_ref = this.heap.retain(function () { + return callHostFunction( + host_func_id, + [this] + Array.prototype.slice.call(arguments) + ); + }); + writeUint32(func_ref_ptr, func_ref); + }, swjs_create_function: ( host_func_id: number, func_ref_ptr: pointer diff --git a/Sources/JavaScriptKit/FundamentalObjects/JSClosure.swift b/Sources/JavaScriptKit/FundamentalObjects/JSClosure.swift index cd96dd0b5..41f844911 100644 --- a/Sources/JavaScriptKit/FundamentalObjects/JSClosure.swift +++ b/Sources/JavaScriptKit/FundamentalObjects/JSClosure.swift @@ -71,6 +71,20 @@ public class JSClosure: JSObject, JSClosureProtocol { }) } + public init(this: @escaping (JSObject, [JSValue]) -> JSValue) { + // 1. Fill `id` as zero at first to access `self` to get `ObjectIdentifier`. + super.init(id: 0) + let objectId = ObjectIdentifier(self) + let funcRef = JavaScriptHostFuncRef(bitPattern: Int32(objectId.hashValue)) + // 2. Retain the given this in static storage by `funcRef`. + sharedClosures[funcRef] = this + // 3. Create a new JavaScript function which calls the given Swift function. + var objectRef: JavaScriptObjectRef = 0 + _create_this_function(funcRef, &objectRef) + hostFuncRef = funcRef + id = objectRef + } + public init(_ body: @escaping ([JSValue]) -> JSValue) { // 1. Fill `id` as zero at first to access `self` to get `ObjectIdentifier`. super.init(id: 0) diff --git a/Sources/JavaScriptKit/XcodeSupport.swift b/Sources/JavaScriptKit/XcodeSupport.swift index 0777e911a..29077eadd 100644 --- a/Sources/JavaScriptKit/XcodeSupport.swift +++ b/Sources/JavaScriptKit/XcodeSupport.swift @@ -78,6 +78,10 @@ import _CJavaScriptKit _: JavaScriptObjectRef, _: JavaScriptObjectRef ) -> Bool { fatalError() } + func _create_this_function( + _: JavaScriptHostFuncRef, + _: UnsafePointer! + ) { fatalError() } func _create_function( _: JavaScriptHostFuncRef, _: UnsafePointer! diff --git a/Sources/_CJavaScriptKit/include/_CJavaScriptKit.h b/Sources/_CJavaScriptKit/include/_CJavaScriptKit.h index 6d383b3ea..53415cdbc 100644 --- a/Sources/_CJavaScriptKit/include/_CJavaScriptKit.h +++ b/Sources/_CJavaScriptKit/include/_CJavaScriptKit.h @@ -228,6 +228,16 @@ __attribute__((__import_module__("javascript_kit"), extern bool _instanceof(const JavaScriptObjectRef obj, const JavaScriptObjectRef constructor); +/// `_create_this_function` creates a JavaScript thunk function that calls Swift side closure. +/// See also comments on JSFunction.swift +/// +/// @param host_func_id The target Swift side function called by the created thunk function. +/// @param func_ref_ptr A result pointer of created thunk function. +__attribute__((__import_module__("javascript_kit"), + __import_name__("swjs_create_this_function"))) +extern void _create_this_function(const JavaScriptHostFuncRef host_func_id, + const JavaScriptObjectRef *func_ref_ptr); + /// `_create_function` creates a JavaScript thunk function that calls Swift side closure. /// See also comments on JSFunction.swift /// From 5ebcd23bb88598b63e9ab73e08d3544c1e2fb80d Mon Sep 17 00:00:00 2001 From: Samuel Colbran Date: Mon, 6 Sep 2021 13:45:21 -0700 Subject: [PATCH 2/3] match body code --- Sources/JavaScriptKit/FundamentalObjects/JSClosure.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/JavaScriptKit/FundamentalObjects/JSClosure.swift b/Sources/JavaScriptKit/FundamentalObjects/JSClosure.swift index 41f844911..572690ae4 100644 --- a/Sources/JavaScriptKit/FundamentalObjects/JSClosure.swift +++ b/Sources/JavaScriptKit/FundamentalObjects/JSClosure.swift @@ -71,7 +71,7 @@ public class JSClosure: JSObject, JSClosureProtocol { }) } - public init(this: @escaping (JSObject, [JSValue]) -> JSValue) { + public init(this: @escaping ([JSValue]) -> JSValue) { // 1. Fill `id` as zero at first to access `self` to get `ObjectIdentifier`. super.init(id: 0) let objectId = ObjectIdentifier(self) From 0e21d49376fee6af71fca8d6c82b9ff799583384 Mon Sep 17 00:00:00 2001 From: Samuel Colbran Date: Mon, 6 Sep 2021 13:47:53 -0700 Subject: [PATCH 3/3] remove public init(this: @escaping ([JSValue]) -> JSValue) --- .../FundamentalObjects/JSClosure.swift | 23 +++++-------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/Sources/JavaScriptKit/FundamentalObjects/JSClosure.swift b/Sources/JavaScriptKit/FundamentalObjects/JSClosure.swift index 572690ae4..0ca1b455e 100644 --- a/Sources/JavaScriptKit/FundamentalObjects/JSClosure.swift +++ b/Sources/JavaScriptKit/FundamentalObjects/JSClosure.swift @@ -71,21 +71,7 @@ public class JSClosure: JSObject, JSClosureProtocol { }) } - public init(this: @escaping ([JSValue]) -> JSValue) { - // 1. Fill `id` as zero at first to access `self` to get `ObjectIdentifier`. - super.init(id: 0) - let objectId = ObjectIdentifier(self) - let funcRef = JavaScriptHostFuncRef(bitPattern: Int32(objectId.hashValue)) - // 2. Retain the given this in static storage by `funcRef`. - sharedClosures[funcRef] = this - // 3. Create a new JavaScript function which calls the given Swift function. - var objectRef: JavaScriptObjectRef = 0 - _create_this_function(funcRef, &objectRef) - hostFuncRef = funcRef - id = objectRef - } - - public init(_ body: @escaping ([JSValue]) -> JSValue) { + public init(_ body: @escaping ([JSValue]) -> JSValue, this: Bool = false) { // 1. Fill `id` as zero at first to access `self` to get `ObjectIdentifier`. super.init(id: 0) let objectId = ObjectIdentifier(self) @@ -94,8 +80,11 @@ public class JSClosure: JSObject, JSClosureProtocol { sharedClosures[funcRef] = body // 3. Create a new JavaScript function which calls the given Swift function. var objectRef: JavaScriptObjectRef = 0 - _create_function(funcRef, &objectRef) - + if this { + _create_this_function(funcRef, &objectRef) + } else { + _create_function(funcRef, &objectRef) + } hostFuncRef = funcRef id = objectRef }