Skip to content

Commit c72bd55

Browse files
authored
Merge pull request #1 from skiptools/jsc-react-native-community
Switch to build provided by react-native-community maven group
2 parents d0062fc + 159b060 commit c72bd55

File tree

5 files changed

+91
-168
lines changed

5 files changed

+91
-168
lines changed

Package.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ let package = Package(
1111
dependencies: [
1212
.package(url: "https://source.skip.tools/skip.git", from: "1.0.4"),
1313
.package(url: "https://source.skip.tools/skip-foundation.git", from: "1.0.0"),
14-
.package(url: "https://source.skip.tools/skip-ffi.git", "0.0.0"..<"2.0.0"),
14+
.package(url: "https://source.skip.tools/skip-ffi.git", from: "1.0.0"),
1515
],
1616
targets: [
1717
.target(name: "SkipScript", dependencies: [

Sources/SkipScript/JSContext.swift

Lines changed: 23 additions & 14 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
@@ -1164,9 +1172,10 @@ final class JavaScriptCoreLibrary : com.sun.jna.Library {
11641172
let isAndroid = System.getProperty("java.vm.vendor") == "The Android Project"
11651173
// on Android we use the embedded libjsc.so; on macOS host, use the system JavaScriptCore
11661174
let jscName = isAndroid ? "jsc" : "JavaScriptCore"
1167-
//return com.sun.jna.Native.load(jscName, javaClass(JavaScriptCoreLibrary.self))
1175+
if isAndroid {
1176+
System.loadLibrary("c++_shared") // io.github.react-native-community:jsc-android-intl requires this, provided in com.facebook.fbjni:fbjni
1177+
}
11681178
com.sun.jna.Native.register((JavaScriptCoreLibrary.self as kotlin.reflect.KClass).java, jscName)
1169-
11701179
#endif
11711180
}
11721181
}

Sources/SkipScript/Skip/skip.yml

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,29 @@
44
# package: 'skip.script'
55

66
# the blocks to add to the settings.gradle.kts
7-
settings:
8-
contents:
9-
- block: 'dependencyResolutionManagement'
10-
contents:
11-
- block: 'repositories'
12-
contents:
13-
# this is where the android-jsc libraries are hosted
14-
- 'maven("https://maven.skip.tools")'
7+
# only needed for the https://maven.skip.tools build…
8+
#settings:
9+
# contents:
10+
# - block: 'dependencyResolutionManagement'
11+
# contents:
12+
# - block: 'repositories'
13+
# contents:
14+
# # this is where the android-jsc libraries are hosted
15+
# - 'maven("https://maven.skip.tools")'
1516

1617
# the blocks to add to the build.gradle.kts
1718
build:
1819
contents:
1920
- block: 'dependencies'
2021
contents:
21-
- 'implementation("org.webkit:android-jsc-cppruntime:r245459@aar")'
22+
# JSC is now on Maven central (https://github.com/facebook/react-native/pull/47972): https://repo1.maven.org/maven2/io/github/react-native-community/jsc-android/2026004.0.1/
23+
- 'implementation("io.github.react-native-community:jsc-android-intl:2026004.0.1")'
24+
- 'implementation("com.facebook.fbjni:fbjni:0.7.0")' # needed for libc++_shared.so, else no symbol "_ZNSt6__ndk122__libcpp_verbose_abortEPKcz"
25+
26+
# non-international version
27+
#- 'implementation("io.github.react-native-community:jsc-android:2026004.0.1")'
28+
29+
#- 'implementation("org.webkit:android-jsc-cppruntime:r245459@aar")'
2230
# the -intl variant is bigger (24M vs. 13M), but it is needed for locale support
2331
#- 'implementation("org.webkit:android-jsc-intl:r245459@aar")'
24-
- 'implementation("org.webkit:android-jsc:r245459@aar")'
32+
#- 'implementation("org.webkit:android-jsc:r245459@aar")'

Tests/SkipScriptTests/JSContextTests.swift

Lines changed: 6 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -84,14 +84,11 @@ 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())
9390
XCTAssertEqual("65.4", ctx.evaluateScript("new Intl.NumberFormat('en-IN', { maximumSignificantDigits: 3 }).format(65.4321)")?.toString())
94-
XCTAssertEqual("٦٥٫٤٣٢١", ctx.evaluateScript("new Intl.NumberFormat('ar-AR', { maximumSignificantDigits: 6 }).format(65.432123456789)")?.toString())
91+
//XCTAssertEqual("٦٥٫٤٣٢١", ctx.evaluateScript("new Intl.NumberFormat('ar-AR', { maximumSignificantDigits: 6 }).format(65.432123456789)")?.toString())
9592

9693
let yen = "new Intl.NumberFormat('ja-JP', { style: 'currency', currency: 'JPY' }).format(45.678)"
9794
// these seem to be different values because they use combining marks differently
@@ -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)