diff --git a/Runtime/src/index.ts b/Runtime/src/index.ts index 74c2f880..50685863 100644 --- a/Runtime/src/index.ts +++ b/Runtime/src/index.ts @@ -148,8 +148,8 @@ export class SwiftRuntime { const argv = exports.swjs_prepare_host_function_call(argc) for (let index = 0; index < args.length; index++) { const argument = args[index] - const base = argv + 24 * index - writeValue(argument, base, base + 4, base + 8, base + 16) + const base = argv + 16 * index + writeValue(argument, base, base + 4, base + 8) } let output: any; const callback_func_ref = this.heap.retain(function (result: any) { @@ -203,7 +203,7 @@ export class SwiftRuntime { const decodeValue = ( kind: JavaScriptValueKind, - payload1: number, payload2: number, payload3: number + payload1: number, payload2: number ) => { switch (kind) { case JavaScriptValueKind.Boolean: { @@ -213,7 +213,7 @@ export class SwiftRuntime { } } case JavaScriptValueKind.Number: { - return payload3; + return payload2; } case JavaScriptValueKind.String: { return readString(payload1); @@ -237,50 +237,40 @@ export class SwiftRuntime { const writeValue = ( value: any, kind_ptr: pointer, - payload1_ptr: pointer, payload2_ptr: pointer, payload3_ptr: pointer + payload1_ptr: pointer, payload2_ptr: pointer ) => { if (value === null) { writeUint32(kind_ptr, JavaScriptValueKind.Null); - writeUint32(payload1_ptr, 0); - writeUint32(payload2_ptr, 0); return; } switch (typeof value) { case "boolean": { writeUint32(kind_ptr, JavaScriptValueKind.Boolean); writeUint32(payload1_ptr, value ? 1 : 0); - writeUint32(payload2_ptr, 0); break; } case "number": { writeUint32(kind_ptr, JavaScriptValueKind.Number); - writeUint32(payload1_ptr, 0); - writeUint32(payload2_ptr, 0); - writeFloat64(payload3_ptr, value); + writeFloat64(payload2_ptr, value); break; } case "string": { writeUint32(kind_ptr, JavaScriptValueKind.String); writeUint32(payload1_ptr, this.heap.retain(value)); - writeUint32(payload2_ptr, 0); break; } case "undefined": { writeUint32(kind_ptr, JavaScriptValueKind.Undefined); - writeUint32(payload1_ptr, 0); - writeUint32(payload2_ptr, 0); break; } case "object": { writeUint32(kind_ptr, JavaScriptValueKind.Object); writeUint32(payload1_ptr, this.heap.retain(value)); - writeUint32(payload2_ptr, 0); break; } case "function": { writeUint32(kind_ptr, JavaScriptValueKind.Function); writeUint32(payload1_ptr, this.heap.retain(value)); - writeUint32(payload2_ptr, 0); break; } default: @@ -289,17 +279,15 @@ export class SwiftRuntime { } // Note: - // `decodeValues` assumes that the size of RawJSValue is 24 - // and the alignment of it is 8 + // `decodeValues` assumes that the size of RawJSValue is 16. const decodeValues = (ptr: pointer, length: number) => { let result = [] for (let index = 0; index < length; index++) { - const base = ptr + 24 * index + const base = ptr + 16 * index const kind = readUInt32(base) const payload1 = readUInt32(base + 4) - const payload2 = readUInt32(base + 8) - const payload3 = readFloat64(base + 16) - result.push(decodeValue(kind, payload1, payload2, payload3)) + const payload2 = readFloat64(base + 8) + result.push(decodeValue(kind, payload1, payload2)) } return result } @@ -308,36 +296,36 @@ export class SwiftRuntime { swjs_set_prop: ( ref: ref, name: ref, kind: JavaScriptValueKind, - payload1: number, payload2: number, payload3: number + payload1: number, payload2: number ) => { const obj = this.heap.referenceHeap(ref); - Reflect.set(obj, readString(name), decodeValue(kind, payload1, payload2, payload3)) + Reflect.set(obj, readString(name), decodeValue(kind, payload1, payload2)) }, swjs_get_prop: ( ref: ref, name: ref, kind_ptr: pointer, - payload1_ptr: pointer, payload2_ptr: pointer, payload3_ptr: number + payload1_ptr: pointer, payload2_ptr: pointer ) => { const obj = this.heap.referenceHeap(ref); const result = Reflect.get(obj, readString(name)); - writeValue(result, kind_ptr, payload1_ptr, payload2_ptr, payload3_ptr); + writeValue(result, kind_ptr, payload1_ptr, payload2_ptr); }, swjs_set_subscript: ( ref: ref, index: number, kind: JavaScriptValueKind, - payload1: number, payload2: number, payload3: number + payload1: number, payload2: number ) => { const obj = this.heap.referenceHeap(ref); - Reflect.set(obj, index, decodeValue(kind, payload1, payload2, payload3)) + Reflect.set(obj, index, decodeValue(kind, payload1, payload2)) }, swjs_get_subscript: ( ref: ref, index: number, kind_ptr: pointer, - payload1_ptr: pointer, payload2_ptr: pointer, payload3_ptr: pointer + payload1_ptr: pointer, payload2_ptr: pointer ) => { const obj = this.heap.referenceHeap(ref); const result = Reflect.get(obj, index); - writeValue(result, kind_ptr, payload1_ptr, payload2_ptr, payload3_ptr); + writeValue(result, kind_ptr, payload1_ptr, payload2_ptr); }, swjs_encode_string: (ref: ref, bytes_ptr_result: pointer) => { const bytes = textEncoder.encode(this.heap.referenceHeap(ref)); @@ -358,22 +346,22 @@ export class SwiftRuntime { swjs_call_function: ( ref: ref, argv: pointer, argc: number, kind_ptr: pointer, - payload1_ptr: pointer, payload2_ptr: pointer, payload3_ptr: pointer + payload1_ptr: pointer, payload2_ptr: pointer ) => { const func = this.heap.referenceHeap(ref) const result = Reflect.apply(func, undefined, decodeValues(argv, argc)) - writeValue(result, kind_ptr, payload1_ptr, payload2_ptr, payload3_ptr); + writeValue(result, kind_ptr, payload1_ptr, payload2_ptr); }, swjs_call_function_with_this: ( obj_ref: ref, func_ref: ref, argv: pointer, argc: number, kind_ptr: pointer, - payload1_ptr: pointer, payload2_ptr: pointer, payload3_ptr: pointer + payload1_ptr: pointer, payload2_ptr: pointer ) => { const obj = this.heap.referenceHeap(obj_ref) const func = this.heap.referenceHeap(func_ref) const result = Reflect.apply(func, obj, decodeValues(argv, argc)) - writeValue(result, kind_ptr, payload1_ptr, payload2_ptr, payload3_ptr); + writeValue(result, kind_ptr, payload1_ptr, payload2_ptr); }, swjs_create_function: ( host_func_id: number, diff --git a/Sources/JavaScriptKit/FundamentalObjects/JSFunction.swift b/Sources/JavaScriptKit/FundamentalObjects/JSFunction.swift index 9ac11626..bd232d9a 100644 --- a/Sources/JavaScriptKit/FundamentalObjects/JSFunction.swift +++ b/Sources/JavaScriptKit/FundamentalObjects/JSFunction.swift @@ -27,11 +27,11 @@ public class JSFunction: JSObject { if let thisId = this?.id { _call_function_with_this(thisId, self.id, argv, Int32(argc), - &result.kind, &result.payload1, &result.payload2, &result.payload3) + &result.kind, &result.payload1, &result.payload2) } else { _call_function( self.id, argv, Int32(argc), - &result.kind, &result.payload1, &result.payload2, &result.payload3 + &result.kind, &result.payload1, &result.payload2 ) } return result @@ -155,6 +155,41 @@ public class JSClosure: JSFunction { } } + +// MARK: - `JSClosure` mechanism note +// +// 1. Create thunk function in JavaScript world, that has a reference +// to Swift Closure. +// ┌─────────────────────┬──────────────────────────┐ +// │ Swift side │ JavaScript side │ +// │ │ │ +// │ │ │ +// │ │ ┌──[Thunk function]──┐ │ +// │ ┌ ─ ─ ─ ─ ─│─ ─│─ ─ ─ ─ ─ ┐ │ │ +// │ ↓ │ │ │ │ │ +// │ [Swift Closure] │ │ Host Function ID │ │ +// │ │ │ │ │ +// │ │ └────────────────────┘ │ +// └─────────────────────┴──────────────────────────┘ +// +// 2. When thunk function is invoked, it calls Swift Closure via +// `_call_host_function` and callback the result through callback func +// ┌─────────────────────┬──────────────────────────┐ +// │ Swift side │ JavaScript side │ +// │ │ │ +// │ │ │ +// │ Apply ┌──[Thunk function]──┐ │ +// │ ┌ ─ ─ ─ ─ ─│─ ─│─ ─ ─ ─ ─ ┐ │ │ +// │ ↓ │ │ │ │ │ +// │ [Swift Closure] │ │ Host Function ID │ │ +// │ │ │ │ │ │ +// │ │ │ └────────────────────┘ │ +// │ │ │ ↑ │ +// │ │ Apply │ │ +// │ └─[Result]─┼───>[Callback func]─┘ │ +// │ │ │ +// └─────────────────────┴──────────────────────────┘ + @_cdecl("swjs_prepare_host_function_call") func _prepare_host_function_call(_ argc: Int32) -> UnsafeMutableRawPointer { let argumentSize = MemoryLayout.size * Int(argc) diff --git a/Sources/JavaScriptKit/FundamentalObjects/JSString.swift b/Sources/JavaScriptKit/FundamentalObjects/JSString.swift index ee334ed5..5621793d 100644 --- a/Sources/JavaScriptKit/FundamentalObjects/JSString.swift +++ b/Sources/JavaScriptKit/FundamentalObjects/JSString.swift @@ -97,7 +97,7 @@ extension JSString { func withRawJSValue(_ body: (RawJSValue) -> T) -> T { let rawValue = RawJSValue( - kind: .string, payload1: guts.jsRef, payload2: 0, payload3: 0 + kind: .string, payload1: guts.jsRef, payload2: 0 ) return body(rawValue) } diff --git a/Sources/JavaScriptKit/JSValue.swift b/Sources/JavaScriptKit/JSValue.swift index 4dc56937..696e3c61 100644 --- a/Sources/JavaScriptKit/JSValue.swift +++ b/Sources/JavaScriptKit/JSValue.swift @@ -149,13 +149,13 @@ public func getJSValue(this: JSObject, name: JSString) -> JSValue { var rawValue = RawJSValue() _get_prop(this.id, name.asInternalJSRef(), &rawValue.kind, - &rawValue.payload1, &rawValue.payload2, &rawValue.payload3) + &rawValue.payload1, &rawValue.payload2) return rawValue.jsValue() } public func setJSValue(this: JSObject, name: JSString, value: JSValue) { value.withRawJSValue { rawValue in - _set_prop(this.id, name.asInternalJSRef(), rawValue.kind, rawValue.payload1, rawValue.payload2, rawValue.payload3) + _set_prop(this.id, name.asInternalJSRef(), rawValue.kind, rawValue.payload1, rawValue.payload2) } } @@ -163,7 +163,7 @@ public func getJSValue(this: JSObject, index: Int32) -> JSValue { var rawValue = RawJSValue() _get_subscript(this.id, index, &rawValue.kind, - &rawValue.payload1, &rawValue.payload2, &rawValue.payload3) + &rawValue.payload1, &rawValue.payload2) return rawValue.jsValue() } @@ -171,7 +171,7 @@ public func setJSValue(this: JSObject, index: Int32, value: JSValue) { value.withRawJSValue { rawValue in _set_subscript(this.id, index, rawValue.kind, - rawValue.payload1, rawValue.payload2, rawValue.payload3) + rawValue.payload1, rawValue.payload2) } } diff --git a/Sources/JavaScriptKit/JSValueConvertible.swift b/Sources/JavaScriptKit/JSValueConvertible.swift index bf94ed16..63162f5f 100644 --- a/Sources/JavaScriptKit/JSValueConvertible.swift +++ b/Sources/JavaScriptKit/JSValueConvertible.swift @@ -183,7 +183,7 @@ extension RawJSValue: JSValueConvertible { case .boolean: return .boolean(payload1 != 0) case .number: - return .number(payload3) + return .number(payload2) case .string: return .string(JSString(jsRef: payload1)) case .object: @@ -194,8 +194,6 @@ extension RawJSValue: JSValueConvertible { return .undefined case .function: return .function(JSFunction(id: UInt32(payload1))) - default: - fatalError("unreachable") } } } @@ -204,38 +202,31 @@ extension JSValue { func withRawJSValue(_ body: (RawJSValue) -> T) -> T { let kind: JavaScriptValueKind let payload1: JavaScriptPayload1 - let payload2: JavaScriptPayload2 - var payload3: JavaScriptPayload3 = 0 + var payload2: JavaScriptPayload2 = 0 switch self { case let .boolean(boolValue): kind = .boolean payload1 = boolValue ? 1 : 0 - payload2 = 0 case let .number(numberValue): kind = .number payload1 = 0 - payload2 = 0 - payload3 = numberValue + payload2 = numberValue case let .string(string): return string.withRawJSValue(body) case let .object(ref): kind = .object payload1 = JavaScriptPayload1(ref.id) - payload2 = 0 case .null: kind = .null payload1 = 0 - payload2 = 0 case .undefined: kind = .undefined payload1 = 0 - payload2 = 0 case let .function(functionRef): kind = .function payload1 = JavaScriptPayload1(functionRef.id) - payload2 = 0 } - let rawValue = RawJSValue(kind: kind, payload1: payload1, payload2: payload2, payload3: payload3) + let rawValue = RawJSValue(kind: kind, payload1: payload1, payload2: payload2) return body(rawValue) } } diff --git a/Sources/JavaScriptKit/XcodeSupport.swift b/Sources/JavaScriptKit/XcodeSupport.swift index 44b95cef..3e2c24a6 100644 --- a/Sources/JavaScriptKit/XcodeSupport.swift +++ b/Sources/JavaScriptKit/XcodeSupport.swift @@ -11,32 +11,28 @@ import _CJavaScriptKit _: JavaScriptObjectRef, _: JavaScriptValueKind, _: JavaScriptPayload1, - _: JavaScriptPayload2, - _: JavaScriptPayload3 + _: JavaScriptPayload2 ) { fatalError() } func _get_prop( _: JavaScriptObjectRef, _: JavaScriptObjectRef, _: UnsafeMutablePointer!, _: UnsafeMutablePointer!, - _: UnsafeMutablePointer!, - _: UnsafeMutablePointer! + _: UnsafeMutablePointer! ) { fatalError() } func _set_subscript( _: JavaScriptObjectRef, _: Int32, _: JavaScriptValueKind, _: JavaScriptPayload1, - _: JavaScriptPayload2, - _: JavaScriptPayload3 + _: JavaScriptPayload2 ) { fatalError() } func _get_subscript( _: JavaScriptObjectRef, _: Int32, _: UnsafeMutablePointer!, _: UnsafeMutablePointer!, - _: UnsafeMutablePointer!, - _: UnsafeMutablePointer! + _: UnsafeMutablePointer! ) { fatalError() } func _encode_string( _: JavaScriptObjectRef, @@ -55,8 +51,7 @@ import _CJavaScriptKit _: UnsafePointer!, _: Int32, _: UnsafeMutablePointer!, _: UnsafeMutablePointer!, - _: UnsafeMutablePointer!, - _: UnsafeMutablePointer! + _: UnsafeMutablePointer! ) { fatalError() } func _call_function_with_this( _: JavaScriptObjectRef, @@ -64,8 +59,7 @@ import _CJavaScriptKit _: UnsafePointer!, _: Int32, _: UnsafeMutablePointer!, _: UnsafeMutablePointer!, - _: UnsafeMutablePointer!, - _: UnsafeMutablePointer! + _: UnsafeMutablePointer! ) { fatalError() } func _call_new( _: JavaScriptObjectRef, diff --git a/Sources/_CJavaScriptKit/include/_CJavaScriptKit.h b/Sources/_CJavaScriptKit/include/_CJavaScriptKit.h index 7cb4e398..c180a7e2 100644 --- a/Sources/_CJavaScriptKit/include/_CJavaScriptKit.h +++ b/Sources/_CJavaScriptKit/include/_CJavaScriptKit.h @@ -4,9 +4,14 @@ #include #include +/// `JavaScriptObjectRef` represents JavaScript object reference that is referenced by Swift side. +/// This value is an address of `SwiftRuntimeHeap`. typedef unsigned int JavaScriptObjectRef; +/// `JavaScriptHostFuncRef` represents Swift closure that is referenced by JavaScript side. +/// This value is produced by `JSClosure`. typedef unsigned int JavaScriptHostFuncRef; +/// `JavaScriptValueKind` represents the kind of JavaScript primitive value. typedef enum __attribute__((enum_extensibility(closed))) { JavaScriptValueKindInvalid = -1, JavaScriptValueKindBoolean = 0, @@ -19,97 +24,216 @@ typedef enum __attribute__((enum_extensibility(closed))) { } JavaScriptValueKind; typedef unsigned JavaScriptPayload1; -typedef unsigned JavaScriptPayload2; -typedef double JavaScriptPayload3; - +typedef double JavaScriptPayload2; + +/// `RawJSValue` is abstract representaion of JavaScript primitive value. +/// +/// For boolean value: +/// payload1: 1 or 0 +/// payload2: 0 +/// +/// For string value: +/// payload1: `JavaScriptObjectRef` of string +/// payload2: 0 +/// +/// For number value: +/// payload1: 0 +/// payload2: double number +/// +/// For object value: +/// payload1: `JavaScriptObjectRef` +/// payload2: 0 +/// For null value: +/// payload1: 0 +/// payload2: 0 +/// +/// For undefined value: +/// payload1: 0 +/// payload2: 0 +/// +/// For function value: +/// payload1: the target `JavaScriptHostFuncRef` +/// payload2: 0 +/// typedef struct { JavaScriptValueKind kind; JavaScriptPayload1 payload1; JavaScriptPayload2 payload2; - JavaScriptPayload3 payload3; } RawJSValue; #if __wasm32__ -__attribute__((__import_module__("javascript_kit"), - __import_name__("swjs_set_prop"))) extern void -_set_prop(const JavaScriptObjectRef _this, const JavaScriptObjectRef prop, - const JavaScriptValueKind kind, const JavaScriptPayload1 payload1, - const JavaScriptPayload2 payload2, const JavaScriptPayload3 payload3); +/// `_set_prop` sets a value of `_this` JavaScript object. +/// +/// @param _this The target JavaScript object to set the given value. +/// @param prop A JavaScript string object to reference a member of `_this` object. +/// @param kind A kind of JavaScript value to set the target object. +/// @param payload1 The first payload of JavaScript value to set the target object. +/// @param payload2 The second payload of JavaScript value to set the target object. __attribute__((__import_module__("javascript_kit"), - __import_name__("swjs_get_prop"))) extern void -_get_prop(const JavaScriptObjectRef _this, const JavaScriptObjectRef prop, - JavaScriptValueKind *kind, JavaScriptPayload1 *payload1, - JavaScriptPayload2 *payload2, JavaScriptPayload3 *payload3); - + __import_name__("swjs_set_prop"))) +extern void _set_prop(const JavaScriptObjectRef _this, + const JavaScriptObjectRef prop, + const JavaScriptValueKind kind, + const JavaScriptPayload1 payload1, + const JavaScriptPayload2 payload2); + +/// `_get_prop` gets a value of `_this` JavaScript object. +/// +/// @param _this The target JavaScript object to get its member value. +/// @param prop A JavaScript string object to reference a member of `_this` object. +/// @param kind A result pointer of JavaScript value kind to get. +/// @param payload1 A result pointer of first payload of JavaScript value to set the target object. +/// @param payload2 A result pointer of second payload of JavaScript value to set the target object. __attribute__((__import_module__("javascript_kit"), - __import_name__("swjs_set_subscript"))) extern void -_set_subscript(const JavaScriptObjectRef _this, const int length, - const JavaScriptValueKind kind, - const JavaScriptPayload1 payload1, - const JavaScriptPayload2 payload2, - const JavaScriptPayload3 payload3); - + __import_name__("swjs_get_prop"))) +extern void _get_prop(const JavaScriptObjectRef _this, + const JavaScriptObjectRef prop, + JavaScriptValueKind *kind, + JavaScriptPayload1 *payload1, + JavaScriptPayload2 *payload2); + +/// `_set_subscript` sets a value of `_this` JavaScript object. +/// +/// @param _this The target JavaScript object to set its member value. +/// @param index A subscript index to set value. +/// @param kind A kind of JavaScript value to set the target object. +/// @param payload1 The first payload of JavaScript value to set the target object. +/// @param payload2 The second payload of JavaScript value to set the target object. __attribute__((__import_module__("javascript_kit"), - __import_name__("swjs_get_subscript"))) extern void -_get_subscript(const JavaScriptObjectRef _this, const int length, - JavaScriptValueKind *kind, JavaScriptPayload1 *payload1, - JavaScriptPayload2 *payload2, JavaScriptPayload3 *payload3); - + __import_name__("swjs_set_subscript"))) +extern void _set_subscript(const JavaScriptObjectRef _this, + const int index, + const JavaScriptValueKind kind, + const JavaScriptPayload1 payload1, + const JavaScriptPayload2 payload2); + +/// `_get_subscript` gets a value of `_this` JavaScript object. +/// +/// @param _this The target JavaScript object to get its member value. +/// @param index A subscript index to get value. +/// @param kind A result pointer of JavaScript value kind to get. +/// @param payload1 A result pointer of first payload of JavaScript value to get the target object. +/// @param payload2 A result pointer of second payload of JavaScript value to get the target object. __attribute__((__import_module__("javascript_kit"), - __import_name__("swjs_encode_string"))) extern int -_encode_string(const JavaScriptObjectRef str_obj, JavaScriptObjectRef *bytes_ptr_result); - + __import_name__("swjs_get_subscript"))) +extern void _get_subscript(const JavaScriptObjectRef _this, + const int index, + JavaScriptValueKind *kind, + JavaScriptPayload1 *payload1, + JavaScriptPayload2 *payload2); + +/// `_encode_string` encodes the `str_obj` to bytes sequence and returns the length of bytes. +/// +/// @param str_obj A JavaScript string object ref to encode. +/// @param bytes_result A result pointer of bytes sequence representation in JavaScript. +/// This value will be used to load the actual bytes using `_load_string`. +/// @result The length of bytes sequence. This value will be used to allocate Swift side string buffer to load the actual bytes. __attribute__((__import_module__("javascript_kit"), - __import_name__("swjs_decode_string"))) extern JavaScriptObjectRef -_decode_string(const unsigned char *bytes_ptr, const int length); - + __import_name__("swjs_encode_string"))) +extern int _encode_string(const JavaScriptObjectRef str_obj, JavaScriptObjectRef *bytes_result); + +/// `_decode_string` decodes the given bytes sequence into JavaScript string object. +/// +/// @param bytes_ptr A `uint8_t` byte sequence to decode. +/// @param length The length of `bytes_ptr`. +/// @result The decoded JavaScript string object. __attribute__((__import_module__("javascript_kit"), - __import_name__("swjs_load_string"))) extern void -_load_string(const JavaScriptObjectRef ref, unsigned char *buffer); + __import_name__("swjs_decode_string"))) +extern JavaScriptObjectRef _decode_string(const unsigned char *bytes_ptr, const int length); +/// `_load_string` loads the actual bytes sequence of `bytes` into `buffer` which is a Swift side memory address. +/// +/// @param bytes A bytes sequence representation in JavaScript to load. This value should be derived from `_encode_string`. +/// @param buffer A Swift side string buffer to load the bytes. __attribute__((__import_module__("javascript_kit"), - __import_name__("swjs_call_function"))) extern void -_call_function(const JavaScriptObjectRef ref, const RawJSValue *argv, - const int argc, JavaScriptValueKind *result_kind, - JavaScriptPayload1 *result_payload1, - JavaScriptPayload2 *result_payload2, - JavaScriptPayload3 *result_payload3); - + __import_name__("swjs_load_string"))) +extern void _load_string(const JavaScriptObjectRef bytes, unsigned char *buffer); + +/// `_call_function` calls JavaScript function with given arguments list. +/// +/// @param ref The target JavaScript function to call. +/// @param argv A list of `RawJSValue` arguments to apply. +/// @param argc The length of `argv``. +/// @param result_kind A result pointer of JavaScript value kind to get. +/// @param result_payload1 A result pointer of first payload of JavaScript value to set the target object. +/// @param result_payload2 A result pointer of second payload of JavaScript value to set the target object. __attribute__((__import_module__("javascript_kit"), - __import_name__("swjs_call_function_with_this"))) extern void -_call_function_with_this(const JavaScriptObjectRef _this, - const JavaScriptObjectRef func_ref, - const RawJSValue *argv, const int argc, - JavaScriptValueKind *result_kind, - JavaScriptPayload1 *result_payload1, - JavaScriptPayload2 *result_payload2, - JavaScriptPayload3 *result_payload3); - + __import_name__("swjs_call_function"))) +extern void _call_function(const JavaScriptObjectRef ref, const RawJSValue *argv, + const int argc, JavaScriptValueKind *result_kind, + JavaScriptPayload1 *result_payload1, + JavaScriptPayload2 *result_payload2); + +/// `_call_function_with_this` calls JavaScript function with given arguments list and given `_this`. +/// +/// @param _this The value of `this` provided for the call to `func_ref`. +/// @param func_ref The target JavaScript function to call. +/// @param argv A list of `RawJSValue` arguments to apply. +/// @param argc The length of `argv``. +/// @param result_kind A result pointer of JavaScript value kind to get. +/// @param result_payload1 A result pointer of first payload of JavaScript value to set the target object. +/// @param result_payload2 A result pointer of second payload of JavaScript value to set the target object. __attribute__((__import_module__("javascript_kit"), - __import_name__("swjs_call_new"))) extern void -_call_new(const JavaScriptObjectRef ref, const RawJSValue *argv, const int argc, - JavaScriptObjectRef *result_obj); - + __import_name__("swjs_call_function_with_this"))) +extern void _call_function_with_this(const JavaScriptObjectRef _this, + const JavaScriptObjectRef func_ref, + const RawJSValue *argv, const int argc, + JavaScriptValueKind *result_kind, + JavaScriptPayload1 *result_payload1, + JavaScriptPayload2 *result_payload2); + +/// `_call_new` calls JavaScript object constructor with given arguments list. +/// +/// @param ref The target JavaScript constructor to call. +/// @param argv A list of `RawJSValue` arguments to apply. +/// @param argc The length of `argv``. +/// @param result_obj A result pointer of the constructed object. __attribute__((__import_module__("javascript_kit"), - __import_name__("swjs_instanceof"))) extern bool -_instanceof(const JavaScriptObjectRef obj, - const JavaScriptObjectRef constructor); - + __import_name__("swjs_call_new"))) +extern void _call_new(const JavaScriptObjectRef ref, + const RawJSValue *argv, const int argc, + JavaScriptObjectRef *result_obj); + +/// `_instanceof` acts like JavaScript `instanceof` operator. +/// +/// @param obj The target object to check its prototype chain. +/// @param constructor The `constructor` object to check against. +/// @result Return `true` if `constructor` appears anywhere in the prototype chain of `obj`. Return `false` if not. __attribute__((__import_module__("javascript_kit"), - __import_name__("swjs_create_function"))) extern void -_create_function(const JavaScriptHostFuncRef host_func_id, - const JavaScriptObjectRef *func_ref_ptr); - + __import_name__("swjs_instanceof"))) +extern bool _instanceof(const JavaScriptObjectRef obj, + const JavaScriptObjectRef constructor); + +/// `_create_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_release"))) extern void -_release(const JavaScriptObjectRef ref); + __import_name__("swjs_create_function"))) +extern void _create_function(const JavaScriptHostFuncRef host_func_id, + const JavaScriptObjectRef *func_ref_ptr); +/// Decrements reference count of `ref` retained by `SwiftRuntimeHeap` in JavaScript side. +/// +/// @param ref The target JavaScript object. +__attribute__((__import_module__("javascript_kit"), + __import_name__("swjs_release"))) +extern void _release(const JavaScriptObjectRef ref); + +/// Instantiate a new `TypedArray` object with given elements +/// This is used to provide an efficient way to create `TypedArray`. +/// +/// @param constructor The `TypedArray` constructor. +/// @param elements_ptr The elements pointer to initialize. They are assumed to be the same size of `constructor` elements size. +/// @param length The length of `elements_ptr` +/// @param result_obj A result pointer of the constructed object. __attribute__((__import_module__("javascript_kit"), - __import_name__("swjs_create_typed_array"))) extern void -_create_typed_array(const JavaScriptObjectRef constructor, - const void *elementsPtr, const int length, - JavaScriptObjectRef *result_obj); + __import_name__("swjs_create_typed_array"))) +extern void _create_typed_array(const JavaScriptObjectRef constructor, + const void *elements_ptr, const int length, + JavaScriptObjectRef *result_obj); #endif