Skip to content

Commit 159b060

Browse files
committed
Resolve issues with function values
1 parent 8dc183f commit 159b060

File tree

3 files changed

+68
-154
lines changed

3 files changed

+68
-154
lines changed

Sources/SkipScript/JSContext.swift

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -527,12 +527,11 @@ public class JSValue {
527527

528528
let pointerSize: Int32 = com.sun.jna.Native.POINTER_SIZE
529529
let size = Int64(arguments.count * pointerSize)
530-
let argptr = arguments.count == 0 ? nil : com.sun.jna.Memory(size)
531-
//defer { argptr?.clear(size) }
530+
let args = arguments.count == 0 ? nil : com.sun.jna.Memory(size)
531+
defer { args?.clear(size) }
532532
for i in (0..<arguments.count) {
533-
argptr?.setPointer(i.toLong() * pointerSize, arguments[i].value)
533+
args!.setPointer(i.toLong() * pointerSize, arguments[i].value)
534534
}
535-
let args = com.sun.jna.ptr.PointerByReference(argptr)
536535
#endif
537536

538537
let ctx = self.context
@@ -706,6 +705,15 @@ extension JSValue {
706705
// }
707706
}
708707

708+
#if SKIP
709+
// workaround for inability to implement this as a convenience constructor due to needing local variables: In Kotlin, delegating calls to 'self' or 'super' constructors can not use local variables other than the parameters passed to this constructor
710+
public func JSValue(string value: String, in context: JSContext) -> JSValue {
711+
let str = JavaScriptCore.JSStringCreateWithUTF8CString(value)
712+
defer { JavaScriptCore.JSStringRelease(str) }
713+
return JSValue(jsValueRef: JavaScriptCore.JSValueMakeString(context.context, str), in: context)
714+
}
715+
#endif
716+
709717

710718
public struct JSCError : Error {
711719
let errorDescription: String
@@ -876,7 +884,7 @@ private final class JSFunctionCallbackImpl : JSCallbackFunction {
876884
init() {
877885
}
878886

879-
public func JSFunctionCallback(_ jsc: JSContextRef?, _ object: JSObjectRef?, _ this: JSObjectRef?, _ argumentCount: Int, _ arguments: UnsafePointer<JSValueRef?>?, _ exception: UnsafeMutablePointer<JSValueRef?>?) -> JSValueRef? {
887+
public func callback(_ jsc: JSContextRef?, _ object: JSObjectRef?, _ this: JSObjectRef?, _ argumentCount: Int, _ arguments: UnsafePointer<JSValueRef?>?, _ exception: UnsafeMutablePointer<JSValueRef?>?) -> JSValueRef? {
880888
guard let object = object,
881889
let data = JavaScriptCore.JSObjectGetPrivate(object) else {
882890
preconditionFailure("SkipScript: unable to find private object data for \(object)")
@@ -890,9 +898,9 @@ private final class JSFunctionCallbackImpl : JSCallbackFunction {
890898
return nil
891899
}
892900

893-
//let argptrs = argumentCount == 0 ? nil : arguments?.value.getPointerArray(0, argumentCount) // Crashes
894-
let args = (0..<argumentCount).map {
895-
JSValue(jsValueRef: arguments!.getPointer(0).getPointer(Int64($0 * com.sun.jna.Native.POINTER_SIZE)), in: context)
901+
let argptrs = argumentCount == 0 ? nil : arguments!.getPointerArray(0, argumentCount)
902+
let args: [JSValue] = (0..<argumentCount).map {
903+
JSValue(jsValueRef: argptrs![$0], in: context)
896904
}
897905
let this = this.map { JSValue(jsValueRef: $0, in: context) }
898906
let value: JSValue = callback(context, this, args)
@@ -919,7 +927,7 @@ private final class JSFunctionFinalizeImpl : JSCallbackFunction {
919927
init() {
920928
}
921929

922-
public func JSFunctionFinalize(_ object: JSObjectRef?) -> Void {
930+
public func callback(_ object: JSObjectRef?) -> Void {
923931
guard let object = object,
924932
let data = JavaScriptCore.JSObjectGetPrivate(object) else {
925933
preconditionFailure("SkipScript: unable to find private object data for \(object)")
@@ -957,7 +965,7 @@ private final class JSFunctionInstanceOfImpl : JSCallbackFunction {
957965
init() {
958966
}
959967

960-
public func JSFunctionInstanceOf(_ jsc: JSContextRef?, _ constructor: JSObjectRef?, _ possibleInstance: JSValueRef?, _ exception: UnsafeMutablePointer<JSValueRef?>?) -> Bool {
968+
public func callback(_ jsc: JSContextRef?, _ constructor: JSObjectRef?, _ possibleInstance: JSValueRef?, _ exception: UnsafeMutablePointer<JSValueRef?>?) -> Bool {
961969
fatalError("### TODO: JSFunctionInstanceOf")
962970
return false
963971
}
@@ -996,7 +1004,7 @@ private final class JSFunctionConstructorImpl : JSCallbackFunction {
9961004
init() {
9971005
}
9981006

999-
public func JSFunctionConstructor(_ jsc: JSContextRef?, _ object: JSObjectRef?, _ argumentCount: Int, _ arguments: UnsafePointer<JSValueRef?>?, _ exception: UnsafeMutablePointer<JSValueRef?>?) -> JSObjectRef? {
1007+
public func callback(_ jsc: JSContextRef?, _ object: JSObjectRef?, _ argumentCount: Int, _ arguments: UnsafePointer<JSValueRef?>?, _ exception: UnsafeMutablePointer<JSValueRef?>?) -> JSObjectRef? {
10001008
fatalError("### TODO: JSFunctionConstructor")
10011009
return nil
10021010
}
@@ -1150,7 +1158,7 @@ final class JavaScriptCoreLibrary : com.sun.jna.Library {
11501158
/* SKIP EXTERN */ public func JSObjectMakeFunctionWithCallback(_ ctx: JSContextRef, _ name: JSStringRef, _ callAsFunction: JSObjectCallAsFunctionCallback) -> JSObjectRef
11511159
/* SKIP EXTERN */ public func JSObjectMake(_ ctx: JSContextRef, _ jsClass: JSClassRef?, _ data: OpaqueJSValue?) -> JSObjectRef
11521160

1153-
/* SKIP EXTERN */ public func JSObjectCallAsFunction(_ ctx: JSContextRef, _ object: OpaquePointer?, _ thisObject: OpaquePointer?, _ argumentCount: Int32, _ arguments: com.sun.jna.ptr.PointerByReference?, _ exception: ExceptionPtr?) -> JSValueRef
1161+
/* SKIP EXTERN */ public func JSObjectCallAsFunction(_ ctx: JSContextRef, _ object: OpaquePointer?, _ thisObject: OpaquePointer?, _ argumentCount: Int32, _ arguments: OpaquePointer?, _ exception: ExceptionPtr?) -> JSValueRef
11541162

11551163
/* SKIP EXTERN */ public func JSClassCreate(_ cls: JSClassDefinition) -> JSClassRef
11561164
/* SKIP EXTERN */ public func JSClassRetain(_ cls: JSClassRef) -> JSClassRef

Tests/SkipScriptTests/JSContextTests.swift

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,6 @@ class JSContextTests : XCTestCase {
8484
}
8585

8686
func testIntl() throws {
87-
if isAndroid {
88-
throw XCTSkip("testIntl disabled on Android due to not using android-jsc-intl") // adds 4+ meg per/arch (i.e., 20MB+ per build)
89-
}
9087
let ctx = try XCTUnwrap(JSContext())
9188

9289
XCTAssertEqual("12,34 €", ctx.evaluateScript("new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(12.34)")?.toString())
@@ -194,10 +191,7 @@ class JSContextTests : XCTestCase {
194191
JavaScriptCore.JSValueMakeNumber(ctx, callbackResult)
195192
}
196193
#else
197-
let callbackPtr = JSCCallback()
198-
// { ctx in
199-
// JavaScriptCore.JSValueMakeNumber(ctx!!, callbackResult)
200-
// }
194+
let callbackPtr = JSCCallback()
201195
#endif
202196

203197
let callbackFunction = JavaScriptCore.JSObjectMakeFunctionWithCallback(jsc, callbackName, callbackPtr)
@@ -206,24 +200,15 @@ class JSContextTests : XCTestCase {
206200
let f = try XCTUnwrap(JavaScriptCore.JSObjectCallAsFunction(jsc, callbackFunction, nil, 0, nil, nil))
207201
XCTAssertEqual(callbackResult, JavaScriptCore.JSValueToNumber(jsc, f, nil))
208202

209-
#if !SKIP
210-
// TODO: need JSObjectSetProperty in Skip
211-
JavaScriptCore.JSObjectSetProperty(jsc, jsc, callbackName, callbackFunction, JSPropertyAttributes(kJSPropertyAttributeNone), nil)
212-
XCTAssertEqual(callbackResult.description, try eval("skip_cb()").toString())
213-
#endif
203+
if !isAndroid { // crashes on Android, passes on Robolectric
204+
JavaScriptCore.JSObjectSetProperty(jsc, jsc, callbackName, callbackFunction, JSPropertyAttributes(kJSPropertyAttributeNone), nil)
205+
XCTAssertEqual(callbackResult.description, try eval("skip_cb()").toString())
206+
}
214207
}
215208

216209
#if SKIP
217210
class JSCCallback : com.sun.jna.Callback {
218-
// let callbackBlock: (JSContextRef?) -> JSValueRef?
219-
//
220-
// init(callbackBlock: @escaping (JSContextRef?) -> JSValueRef?) {
221-
// self.callbackBlock = callbackBlock
222-
// }
223-
224-
// TODO: (ctx: JSContextRef?, function: JSObjectRef?, thisObject: JSObjectRef?, argumentCount: Int, arguments: UnsafePointer<JSValueRef?>?, exception: UnsafeMutablePointer<JSValueRef?>?)
225211
func callback(ctx: JSContextRef?, function: JSObjectRef?, thisObject: JSObjectRef?, argumentCount: Int32, arguments: UnsafeMutableRawPointer?, exception: UnsafeMutableRawPointer?) -> JSValueRef {
226-
//callbackBlock(ctx)
227212
JavaScriptCore.JSValueMakeNumber(ctx!, callbackResult)
228213
}
229214
}

0 commit comments

Comments
 (0)