Skip to content

Commit b34607b

Browse files
Support function call with this
1 parent 408a99a commit b34607b

File tree

6 files changed

+86
-4
lines changed

6 files changed

+86
-4
lines changed

Diff for: src/swift/Sources/JavaScriptKit/JSFunction.swift

+16
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,22 @@ public class JSFunctionRef: Equatable {
2828
return result.jsValue()
2929
}
3030

31+
public func apply(this: JSObjectRef, arguments: [JSValue]) -> JSValue {
32+
let result = arguments.withRawJSValues { rawValues in
33+
rawValues.withUnsafeBufferPointer { bufferPointer -> RawJSValue in
34+
let argv = bufferPointer.baseAddress
35+
let argc = bufferPointer.count
36+
var result = RawJSValue()
37+
_call_function_with_this(this.id,
38+
self.id, argv, Int32(argc),
39+
&result.kind, &result.payload1, &result.payload2
40+
)
41+
return result
42+
}
43+
}
44+
return result.jsValue()
45+
}
46+
3147
public func new(_ arguments: [JSValue]) -> JSObjectRef {
3248
return arguments.withRawJSValues { rawValues in
3349
rawValues.withUnsafeBufferPointer { bufferPointer in

Diff for: src/swift/Sources/JavaScriptKit/XcodeSupport.swift

+7
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,13 @@ func _call_function(
3939
_ result_kind: UnsafeMutablePointer<JavaScriptValueKind>!,
4040
_ result_payload1: UnsafeMutablePointer<JavaScriptPayload>!,
4141
_ result_payload2: UnsafeMutablePointer<JavaScriptPayload>!) { fatalError() }
42+
func _call_function_with_this(
43+
_ _this: JavaScriptObjectRef,
44+
_ func_ref: JavaScriptObjectRef,
45+
_ argv: UnsafePointer<RawJSValue>!, _ argc: Int32,
46+
_ result_kind: UnsafeMutablePointer<JavaScriptValueKind>!,
47+
_ result_payload1: UnsafeMutablePointer<JavaScriptPayload>!,
48+
_ result_payload2: UnsafeMutablePointer<JavaScriptPayload>!) { fatalError() }
4249
func _call_new(
4350
_ ref: JavaScriptObjectRef,
4451
_ argv: UnsafePointer<RawJSValue>!, _ argc: Int32,

Diff for: src/swift/Sources/_CJavaScriptKit/include/_CJavaScriptKit.h

+15-4
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,7 @@ __attribute__((
3434
))
3535
extern void _set_prop(
3636
const JavaScriptObjectRef _this,
37-
const char *prop,
38-
const int length,
37+
const char *prop, const int length,
3938
const JavaScriptValueKind kind,
4039
const JavaScriptPayload payload1,
4140
const JavaScriptPayload payload2
@@ -47,8 +46,7 @@ __attribute__((
4746
))
4847
extern void _get_prop(
4948
const JavaScriptObjectRef _this,
50-
const char *prop,
51-
const int length,
49+
const char *prop, const int length,
5250
JavaScriptValueKind *kind,
5351
JavaScriptPayload *payload1,
5452
JavaScriptPayload *payload2
@@ -99,6 +97,19 @@ extern void _call_function(
9997
JavaScriptPayload *result_payload2
10098
);
10199

100+
__attribute__((
101+
__import_module__("javascript_kit"),
102+
__import_name__("swjs_call_function_with_this")
103+
))
104+
extern void _call_function_with_this(
105+
const JavaScriptObjectRef _this,
106+
const JavaScriptObjectRef func_ref,
107+
const RawJSValue *argv, const int argc,
108+
JavaScriptValueKind *result_kind,
109+
JavaScriptPayload *result_payload1,
110+
JavaScriptPayload *result_payload2
111+
);
112+
102113
__attribute__((
103114
__import_module__("javascript_kit"),
104115
__import_name__("swjs_call_new")

Diff for: src/web/src/index.ts

+14
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,20 @@ export class SwiftRuntime {
281281
writeUint32(payload1_ptr, payload1);
282282
writeUint32(payload2_ptr, payload2);
283283
},
284+
swjs_call_function_with_this: (
285+
obj_ref: ref, func_ref: ref,
286+
argv: pointer, argc: number,
287+
kind_ptr: pointer,
288+
payload1_ptr: pointer, payload2_ptr: pointer
289+
) => {
290+
const obj = this._heapValues[obj_ref]
291+
const func = this._heapValues[func_ref]
292+
const result = Reflect.apply(func, obj, decodeValues(argv, argc))
293+
const { kind, payload1, payload2 } = encodeValue(result);
294+
writeUint32(kind_ptr, kind);
295+
writeUint32(payload1_ptr, payload1);
296+
writeUint32(payload2_ptr, payload2);
297+
},
284298
swjs_create_function: (
285299
host_func_id: number,
286300
func_ref_ptr: pointer,

Diff for: test/JavaScriptKitExec/Sources/JavaScriptKitExec/main.swift

+30
Original file line numberDiff line numberDiff line change
@@ -182,3 +182,33 @@ New_Object_Construction: do {
182182
} catch {
183183
print(error)
184184
}
185+
186+
Call_Function_With_This: do {
187+
188+
// ```js
189+
// global.Animal = function(name, age, isCat) {
190+
// this.name = name
191+
// this.age = age
192+
// this.bark = () => {
193+
// return isCat ? "nyan" : "wan"
194+
// }
195+
// this.isCat = isCat
196+
// this.getIsCat = function() {
197+
// return this.isCat
198+
// }
199+
// }
200+
// ```
201+
let objectConstructor = try expectFunction(getJSValue(this: .global(), name: "Animal"))
202+
let cat1 = objectConstructor.new([.string("Tama"), .number(3), .boolean(true)])
203+
let getIsCat = try expectFunction(getJSValue(this: cat1, name: "getIsCat"))
204+
205+
// Direct call without this
206+
try expectEqual(getIsCat(), .undefined)
207+
208+
// Call with this
209+
let gotIsCat = getIsCat.apply(this: cat1, arguments: [])
210+
try expectEqual(gotIsCat, .boolean(true))
211+
212+
} catch {
213+
print(error)
214+
}

Diff for: test/index.js

+4
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@ global.Animal = function(name, age, isCat) {
5050
this.bark = () => {
5151
return isCat ? "nyan" : "wan"
5252
}
53+
this.isCat = isCat
54+
this.getIsCat = function() {
55+
return this.isCat
56+
}
5357
}
5458

5559
const startWasiTask = async () => {

0 commit comments

Comments
 (0)