forked from swiftwasm/JavaScriptKit
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathJSFunction.swift
96 lines (85 loc) · 3.41 KB
/
JSFunction.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
import _CJavaScriptKit
@dynamicCallable
public class JSFunctionRef: JSObjectRef {
@discardableResult
public func dynamicallyCall(withArguments arguments: [JSValueConvertible]) -> JSValue {
let result = arguments.withRawJSValues { rawValues -> RawJSValue in
return rawValues.withUnsafeBufferPointer { bufferPointer -> RawJSValue in
let argv = bufferPointer.baseAddress
let argc = bufferPointer.count
var result = RawJSValue()
_call_function(
self.id, argv, Int32(argc),
&result.kind, &result.payload1, &result.payload2, &result.payload3
)
return result
}
}
return result.jsValue()
}
public func apply(this: JSObjectRef, arguments: JSValueConvertible...) -> JSValue {
apply(this: this, argumentList: arguments)
}
public func apply(this: JSObjectRef, argumentList: [JSValueConvertible]) -> JSValue {
let result = argumentList.withRawJSValues { rawValues in
rawValues.withUnsafeBufferPointer { bufferPointer -> RawJSValue in
let argv = bufferPointer.baseAddress
let argc = bufferPointer.count
var result = RawJSValue()
_call_function_with_this(this.id,
self.id, argv, Int32(argc),
&result.kind, &result.payload1, &result.payload2, &result.payload3
)
return result
}
}
return result.jsValue()
}
public func new(_ arguments: JSValueConvertible...) -> JSObjectRef {
return arguments.withRawJSValues { rawValues in
rawValues.withUnsafeBufferPointer { bufferPointer in
let argv = bufferPointer.baseAddress
let argc = bufferPointer.count
var resultObj = JavaScriptObjectRef()
_call_new(
self.id, argv, Int32(argc),
&resultObj
)
return JSObjectRef(id: resultObj)
}
}
}
static var sharedFunctions: [([JSValue]) -> JSValue] = []
public static func from(_ body: @escaping ([JSValue]) -> JSValue) -> JSFunctionRef {
let id = JavaScriptHostFuncRef(sharedFunctions.count)
sharedFunctions.append(body)
var funcRef: JavaScriptObjectRef = 0
_create_function(id, &funcRef)
return JSFunctionRef(id: funcRef)
}
public override func jsValue() -> JSValue {
.function(self)
}
}
@_cdecl("swjs_prepare_host_function_call")
public func _prepare_host_function_call(_ argc: Int32) -> UnsafeMutableRawPointer {
let argumentSize = MemoryLayout<RawJSValue>.size * Int(argc)
return malloc(Int(argumentSize))!
}
@_cdecl("swjs_cleanup_host_function_call")
public func _cleanup_host_function_call(_ pointer: UnsafeMutableRawPointer) {
free(pointer)
}
@_cdecl("swjs_call_host_function")
public func _call_host_function(
_ hostFuncRef: JavaScriptHostFuncRef,
_ argv: UnsafePointer<RawJSValue>, _ argc: Int32,
_ callbackFuncRef: JavaScriptObjectRef) {
let hostFunc = JSFunctionRef.sharedFunctions[Int(hostFuncRef)]
let args = UnsafeBufferPointer(start: argv, count: Int(argc)).map {
$0.jsValue()
}
let result = hostFunc(args)
let callbackFuncRef = JSFunctionRef(id: callbackFuncRef)
_ = callbackFuncRef(result)
}