Skip to content

Commit b78f3ca

Browse files
Merge pull request #265 from swiftwasm/katei/embedded-followup
Follow-up adjustment for Embedded support
2 parents 459d1e9 + c326ebf commit b78f3ca

File tree

9 files changed

+69
-55
lines changed

9 files changed

+69
-55
lines changed

.github/workflows/test.yml

+16
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,19 @@ jobs:
8686
- run: swift build
8787
env:
8888
DEVELOPER_DIR: /Applications/${{ matrix.xcode }}.app/Contents/Developer/
89+
90+
embedded-build:
91+
name: Build for embedded target
92+
runs-on: ubuntu-22.04
93+
strategy:
94+
matrix:
95+
entry:
96+
- os: ubuntu-22.04
97+
toolchain: DEVELOPMENT-SNAPSHOT-2024-09-25-a
98+
steps:
99+
- uses: actions/checkout@v4
100+
- uses: ./.github/actions/install-swift
101+
with:
102+
swift-dir: development/ubuntu2204
103+
swift-version: swift-${{ matrix.entry.toolchain }}
104+
- run: ./Examples/Embedded/build.sh

Examples/Embedded/Package.swift

+19-2
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,31 @@ let package = Package(
66
name: "Embedded",
77
dependencies: [
88
.package(name: "JavaScriptKit", path: "../../"),
9-
.package(url: "https://github.com/swifweb/EmbeddedFoundation", branch: "0.1.0")
9+
.package(url: "https://github.com/swiftwasm/swift-dlmalloc", branch: "0.1.0")
1010
],
1111
targets: [
1212
.executableTarget(
1313
name: "EmbeddedApp",
1414
dependencies: [
1515
"JavaScriptKit",
16-
.product(name: "Foundation", package: "EmbeddedFoundation")
16+
.product(name: "dlmalloc", package: "swift-dlmalloc")
17+
],
18+
cSettings: [
19+
.unsafeFlags(["-fdeclspec"])
20+
],
21+
swiftSettings: [
22+
.enableExperimentalFeature("Embedded"),
23+
.enableExperimentalFeature("Extern"),
24+
.unsafeFlags([
25+
"-Xfrontend", "-gnone",
26+
"-Xfrontend", "-disable-stack-protector",
27+
]),
28+
],
29+
linkerSettings: [
30+
.unsafeFlags([
31+
"-Xclang-linker", "-nostdlib",
32+
"-Xlinker", "--no-entry"
33+
])
1734
]
1835
)
1936
]

Examples/Embedded/Sources/EmbeddedApp/_thingsThatShouldNotBeNeeded.swift

+5-9
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,9 @@ func strlen(_ s: UnsafePointer<Int8>) -> Int {
1717
return p - s
1818
}
1919

20-
// TODO: why do I need this? and surely this is not ideal... figure this out, or at least have this come from a C lib
21-
@_cdecl("memmove")
22-
func memmove(_ dest: UnsafeMutableRawPointer, _ src: UnsafeRawPointer, _ n: Int) -> UnsafeMutableRawPointer {
23-
let d = dest.assumingMemoryBound(to: UInt8.self)
24-
let s = src.assumingMemoryBound(to: UInt8.self)
25-
for i in 0..<n {
26-
d[i] = s[i]
20+
@_cdecl("arc4random_buf")
21+
public func arc4random_buf(_ buffer: UnsafeMutableRawPointer, _ size: Int) {
22+
for i in 0..<size {
23+
buffer.storeBytes(of: UInt8.random(in: 0...255), toByteOffset: i, as: UInt8.self)
2724
}
28-
return dest
29-
}
25+
}

Examples/Embedded/build.sh

+4-6
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1-
EXPERIMENTAL_EMBEDDED_WASM=true swift build -c release --product EmbeddedApp \
1+
#!/bin/bash
2+
package_dir="$(cd "$(dirname "$0")" && pwd)"
3+
JAVASCRIPTKIT_EXPERIMENTAL_EMBEDDED_WASM=true swift build --package-path "$package_dir" -c release --product EmbeddedApp \
24
--triple wasm32-unknown-none-wasm \
35
-Xswiftc -enable-experimental-feature -Xswiftc Embedded \
46
-Xswiftc -enable-experimental-feature -Xswiftc Extern \
5-
-Xswiftc -wmo -Xswiftc -disable-cmo \
6-
-Xswiftc -Xfrontend -Xswiftc -gnone \
7-
-Xswiftc -Xfrontend -Xswiftc -disable-stack-protector \
8-
-Xswiftc -cxx-interoperability-mode=default \
97
-Xcc -D__Embedded -Xcc -fdeclspec \
108
-Xlinker --export-if-defined=__main_argc_argv \
119
-Xlinker --export-if-defined=swjs_call_host_function \
12-
-Xswiftc -Xclang-linker -Xswiftc -mexec-model=reactor
10+
-Xswiftc -Xclang-linker -Xswiftc -mexec-model=reactor

Package.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import PackageDescription
44
import Foundation
55

66
// NOTE: needed for embedded customizations, ideally this will not be necessary at all in the future, or can be replaced with traits
7-
let shouldBuildForEmbedded = ProcessInfo.processInfo.environment["EXPERIMENTAL_EMBEDDED_WASM"].flatMap(Bool.init) ?? false
7+
let shouldBuildForEmbedded = ProcessInfo.processInfo.environment["JAVASCRIPTKIT_EXPERIMENTAL_EMBEDDED_WASM"].flatMap(Bool.init) ?? false
88

99
let package = Package(
1010
name: "JavaScriptKit",

Sources/JavaScriptKit/ConstructibleFromJSValue.swift

+8-4
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ extension SignedInteger where Self: ConstructibleFromJSValue {
4040
/// If the value is too large to fit in the `Self` type, `nil` is returned.
4141
///
4242
/// - Parameter bigInt: The `JSBigIntExtended` to decode
43-
public init?(exactly bigInt: JSBigIntExtended) {
43+
public init?(exactly bigInt: some JSBigIntExtended) {
4444
self.init(exactly: bigInt.int64Value)
4545
}
4646

@@ -49,7 +49,7 @@ extension SignedInteger where Self: ConstructibleFromJSValue {
4949
/// Crash if the value is too large to fit in the `Self` type.
5050
///
5151
/// - Parameter bigInt: The `JSBigIntExtended` to decode
52-
public init(_ bigInt: JSBigIntExtended) {
52+
public init(_ bigInt: some JSBigIntExtended) {
5353
self.init(bigInt.int64Value)
5454
}
5555

@@ -68,9 +68,11 @@ extension SignedInteger where Self: ConstructibleFromJSValue {
6868
if let number = value.number {
6969
return Self(exactly: number.rounded(.towardZero))
7070
}
71+
#if !hasFeature(Embedded)
7172
if let bigInt = value.bigInt as? JSBigIntExtended {
7273
return Self(exactly: bigInt)
7374
}
75+
#endif
7476
return nil
7577
}
7678
}
@@ -87,7 +89,7 @@ extension UnsignedInteger where Self: ConstructibleFromJSValue {
8789
/// Returns `nil` if the value is negative or too large to fit in the `Self` type.
8890
///
8991
/// - Parameter bigInt: The `JSBigIntExtended` to decode
90-
public init?(exactly bigInt: JSBigIntExtended) {
92+
public init?(exactly bigInt: some JSBigIntExtended) {
9193
self.init(exactly: bigInt.uInt64Value)
9294
}
9395

@@ -96,7 +98,7 @@ extension UnsignedInteger where Self: ConstructibleFromJSValue {
9698
/// Crash if the value is negative or too large to fit in the `Self` type.
9799
///
98100
/// - Parameter bigInt: The `JSBigIntExtended` to decode
99-
public init(_ bigInt: JSBigIntExtended) {
101+
public init(_ bigInt: some JSBigIntExtended) {
100102
self.init(bigInt.uInt64Value)
101103
}
102104

@@ -114,9 +116,11 @@ extension UnsignedInteger where Self: ConstructibleFromJSValue {
114116
if let number = value.number {
115117
return Self(exactly: number.rounded(.towardZero))
116118
}
119+
#if !hasFeature(Embedded)
117120
if let bigInt = value.bigInt as? JSBigIntExtended {
118121
return Self(exactly: bigInt)
119122
}
123+
#endif
120124
return nil
121125
}
122126
}

Sources/JavaScriptKit/FundamentalObjects/JSFunction.swift

+7-17
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ public class JSFunction: JSObject, _JSFunctionProtocol {
136136
id, argv, Int32(argc),
137137
&payload1, &payload2
138138
)
139-
let kindAndFlags = valueKindAndFlagsFromBits(resultBitPattern)
139+
let kindAndFlags = JavaScriptValueKindAndFlags(bitPattern: resultBitPattern)
140140
assert(!kindAndFlags.isException)
141141
let result = RawJSValue(kind: kindAndFlags.kind, payload1: payload1, payload2: payload2)
142142
return result
@@ -153,7 +153,7 @@ public class JSFunction: JSObject, _JSFunctionProtocol {
153153
id, argv, Int32(argc),
154154
&payload1, &payload2
155155
)
156-
let kindAndFlags = valueKindAndFlagsFromBits(resultBitPattern)
156+
let kindAndFlags = JavaScriptValueKindAndFlags(bitPattern: resultBitPattern)
157157
#if !hasFeature(Embedded)
158158
assert(!kindAndFlags.isException)
159159
#endif
@@ -241,25 +241,15 @@ public extension _JSFunctionProtocol {
241241
new(arguments: [arg0.jsValue, arg1.jsValue, arg2.jsValue, arg3.jsValue, arg4.jsValue, arg5.jsValue, arg6.jsValue])
242242
}
243243
}
244+
#endif
244245

245-
// C bit fields seem to not work with Embedded
246-
// in "normal mode" this is defined as a C struct
247-
private struct JavaScriptValueKindAndFlags {
248-
let errorBit: UInt32 = 1 << 32
246+
internal struct JavaScriptValueKindAndFlags {
247+
static var errorBit: UInt32 { 1 << 31 }
249248
let kind: JavaScriptValueKind
250249
let isException: Bool
251250

252251
init(bitPattern: UInt32) {
253-
self.kind = JavaScriptValueKind(rawValue: bitPattern & ~errorBit)!
254-
self.isException = (bitPattern & errorBit) != 0
252+
self.kind = JavaScriptValueKind(rawValue: bitPattern & ~Self.errorBit)!
253+
self.isException = (bitPattern & Self.errorBit) != 0
255254
}
256255
}
257-
#endif
258-
259-
private func valueKindAndFlagsFromBits(_ bits: UInt32) -> JavaScriptValueKindAndFlags {
260-
#if hasFeature(Embedded)
261-
JavaScriptValueKindAndFlags(bitPattern: bits)
262-
#else
263-
unsafeBitCast(bits, to: JavaScriptValueKindAndFlags.self)
264-
#endif
265-
}

Sources/JavaScriptKit/FundamentalObjects/JSThrowingFunction.swift

+7-6
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,14 @@ public class JSThrowingFunction {
4242
let argv = bufferPointer.baseAddress
4343
let argc = bufferPointer.count
4444

45-
var exceptionKind = JavaScriptValueKindAndFlags()
45+
var exceptionRawKind = JavaScriptRawValueKindAndFlags()
4646
var exceptionPayload1 = JavaScriptPayload1()
4747
var exceptionPayload2 = JavaScriptPayload2()
4848
let resultObj = swjs_call_throwing_new(
4949
self.base.id, argv, Int32(argc),
50-
&exceptionKind, &exceptionPayload1, &exceptionPayload2
50+
&exceptionRawKind, &exceptionPayload1, &exceptionPayload2
5151
)
52+
let exceptionKind = JavaScriptValueKindAndFlags(bitPattern: exceptionRawKind)
5253
if exceptionKind.isException {
5354
let exception = RawJSValue(kind: exceptionKind.kind, payload1: exceptionPayload1, payload2: exceptionPayload2)
5455
return .failure(exception.jsValue)
@@ -70,21 +71,21 @@ private func invokeJSFunction(_ jsFunc: JSFunction, arguments: [ConvertibleToJSV
7071
rawValues.withUnsafeBufferPointer { bufferPointer -> (JSValue, Bool) in
7172
let argv = bufferPointer.baseAddress
7273
let argc = bufferPointer.count
73-
var kindAndFlags = JavaScriptValueKindAndFlags()
74+
let kindAndFlags: JavaScriptValueKindAndFlags
7475
var payload1 = JavaScriptPayload1()
7576
var payload2 = JavaScriptPayload2()
7677
if let thisId = this?.id {
7778
let resultBitPattern = swjs_call_function_with_this(
7879
thisId, id, argv, Int32(argc),
7980
&payload1, &payload2
8081
)
81-
kindAndFlags = unsafeBitCast(resultBitPattern, to: JavaScriptValueKindAndFlags.self)
82+
kindAndFlags = JavaScriptValueKindAndFlags(bitPattern: resultBitPattern)
8283
} else {
8384
let resultBitPattern = swjs_call_function(
8485
id, argv, Int32(argc),
8586
&payload1, &payload2
8687
)
87-
kindAndFlags = unsafeBitCast(resultBitPattern, to: JavaScriptValueKindAndFlags.self)
88+
kindAndFlags = JavaScriptValueKindAndFlags(bitPattern: resultBitPattern)
8889
}
8990
let result = RawJSValue(kind: kindAndFlags.kind, payload1: payload1, payload2: payload2)
9091
return (result.jsValue, kindAndFlags.isException)
@@ -95,4 +96,4 @@ private func invokeJSFunction(_ jsFunc: JSFunction, arguments: [ConvertibleToJSV
9596
}
9697
return result
9798
}
98-
#endif
99+
#endif

Sources/_CJavaScriptKit/include/_CJavaScriptKit.h

+2-10
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,7 @@ typedef enum __attribute__((enum_extensibility(closed))) {
2929
JavaScriptValueKindBigInt = 8,
3030
} JavaScriptValueKind;
3131

32-
#if __Embedded
33-
// something about the bit field widths is not working with embedded
34-
typedef unsigned short JavaScriptValueKindAndFlags;
35-
#else
36-
typedef struct {
37-
JavaScriptValueKind kind: 31;
38-
bool isException: 1;
39-
} JavaScriptValueKindAndFlags;
40-
#endif
32+
typedef uint32_t JavaScriptRawValueKindAndFlags;
4133

4234
typedef unsigned JavaScriptPayload1;
4335
typedef double JavaScriptPayload2;
@@ -253,7 +245,7 @@ IMPORT_JS_FUNCTION(swjs_call_new, JavaScriptObjectRef, (const JavaScriptObjectRe
253245
IMPORT_JS_FUNCTION(swjs_call_throwing_new, JavaScriptObjectRef, (const JavaScriptObjectRef ref,
254246
const RawJSValue *argv,
255247
const int argc,
256-
JavaScriptValueKindAndFlags *exception_kind,
248+
JavaScriptRawValueKindAndFlags *exception_kind,
257249
JavaScriptPayload1 *exception_payload1,
258250
JavaScriptPayload2 *exception_payload2))
259251

0 commit comments

Comments
 (0)