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..0ca1b455e 100644 --- a/Sources/JavaScriptKit/FundamentalObjects/JSClosure.swift +++ b/Sources/JavaScriptKit/FundamentalObjects/JSClosure.swift @@ -71,7 +71,7 @@ public class JSClosure: JSObject, JSClosureProtocol { }) } - 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) @@ -80,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 } 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 ///