mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-17 01:06:08 +03:00
Merge pull request #67 from mitchellh/wasm-shared
wasm: use shared, imported memory
This commit is contained in:
32
build.zig
32
build.zig
@ -112,16 +112,44 @@ pub fn build(b: *std.build.Builder) !void {
|
|||||||
|
|
||||||
// wasm
|
// wasm
|
||||||
{
|
{
|
||||||
|
// Build our Wasm target.
|
||||||
|
const wasm_target: std.zig.CrossTarget = .{
|
||||||
|
.cpu_arch = .wasm32,
|
||||||
|
.os_tag = .freestanding,
|
||||||
|
.cpu_model = .{ .explicit = &std.Target.wasm.cpu.mvp },
|
||||||
|
.cpu_features_add = std.Target.wasm.featureSet(&.{
|
||||||
|
// We use this to explicitly request shared memory.
|
||||||
|
.atomics,
|
||||||
|
|
||||||
|
// Not explicitly used but compiler could use them if they want.
|
||||||
|
.bulk_memory,
|
||||||
|
.reference_types,
|
||||||
|
.sign_ext,
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Whether we're using wasm shared memory. Some behaviors change.
|
||||||
|
// For now we require this but I wanted to make the code handle both
|
||||||
|
// up front.
|
||||||
|
const wasm_shared: bool = true;
|
||||||
|
exe_options.addOption(bool, "wasm_shared", wasm_shared);
|
||||||
|
|
||||||
const wasm = b.addSharedLibrary(
|
const wasm = b.addSharedLibrary(
|
||||||
"ghostty-wasm",
|
"ghostty-wasm",
|
||||||
"src/main_wasm.zig",
|
"src/main_wasm.zig",
|
||||||
.{ .unversioned = {} },
|
.{ .unversioned = {} },
|
||||||
);
|
);
|
||||||
wasm.setTarget(.{ .cpu_arch = .wasm32, .os_tag = .freestanding });
|
wasm.setTarget(wasm_target);
|
||||||
wasm.setBuildMode(mode);
|
wasm.setBuildMode(mode);
|
||||||
wasm.setOutputDir("zig-out");
|
wasm.setOutputDir("zig-out");
|
||||||
wasm.addOptions("build_options", exe_options);
|
wasm.addOptions("build_options", exe_options);
|
||||||
|
|
||||||
|
// So that we can use web workers with our wasm binary
|
||||||
|
wasm.import_memory = true;
|
||||||
|
wasm.initial_memory = 65536 * 25;
|
||||||
|
wasm.max_memory = 65536 * 65536; // Maximum number of pages in wasm32
|
||||||
|
wasm.shared_memory = wasm_shared;
|
||||||
|
|
||||||
// Stack protector adds extern requirements that we don't satisfy.
|
// Stack protector adds extern requirements that we don't satisfy.
|
||||||
wasm.stack_protector = false;
|
wasm.stack_protector = false;
|
||||||
|
|
||||||
@ -136,7 +164,7 @@ pub fn build(b: *std.build.Builder) !void {
|
|||||||
// it lets us test some basic functionality.
|
// it lets us test some basic functionality.
|
||||||
const test_step = b.step("test-wasm", "Run all tests for wasm");
|
const test_step = b.step("test-wasm", "Run all tests for wasm");
|
||||||
const main_test = b.addTest("src/main_wasm.zig");
|
const main_test = b.addTest("src/main_wasm.zig");
|
||||||
main_test.setTarget(.{ .cpu_arch = .wasm32, .os_tag = .wasi });
|
main_test.setTarget(wasm_target);
|
||||||
main_test.addOptions("build_options", exe_options);
|
main_test.addOptions("build_options", exe_options);
|
||||||
try addDeps(b, main_test, true);
|
try addDeps(b, main_test, true);
|
||||||
test_step.dependOn(&main_test.step);
|
test_step.dependOn(&main_test.step);
|
||||||
|
@ -4,9 +4,11 @@ const zjs = new ZigJS();
|
|||||||
const importObject = {
|
const importObject = {
|
||||||
module: {},
|
module: {},
|
||||||
env: {
|
env: {
|
||||||
|
memory: new WebAssembly.Memory({ initial: 25, maximum: 65536, shared: true }),
|
||||||
log: (ptr: number, len: number) => {
|
log: (ptr: number, len: number) => {
|
||||||
const view = new DataView(zjs.memory.buffer, ptr, Number(len));
|
const arr = new Uint8ClampedArray(zjs.memory.buffer, ptr, len);
|
||||||
const str = new TextDecoder('utf-8').decode(view);
|
const data = arr.slice();
|
||||||
|
const str = new TextDecoder('utf-8').decode(data);
|
||||||
console.log(str);
|
console.log(str);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -20,8 +22,8 @@ fetch(url.href).then(response =>
|
|||||||
).then(bytes =>
|
).then(bytes =>
|
||||||
WebAssembly.instantiate(bytes, importObject)
|
WebAssembly.instantiate(bytes, importObject)
|
||||||
).then(results => {
|
).then(results => {
|
||||||
|
const memory = importObject.env.memory;
|
||||||
const {
|
const {
|
||||||
memory,
|
|
||||||
malloc,
|
malloc,
|
||||||
free,
|
free,
|
||||||
face_new,
|
face_new,
|
||||||
|
@ -423,9 +423,17 @@ pub const Wasm = struct {
|
|||||||
defer mem_buf.deinit();
|
defer mem_buf.deinit();
|
||||||
|
|
||||||
// Create an array that points to our buffer
|
// Create an array that points to our buffer
|
||||||
const Uint8ClampedArray = try js.global.get(js.Object, "Uint8ClampedArray");
|
const arr = arr: {
|
||||||
defer Uint8ClampedArray.deinit();
|
const Uint8ClampedArray = try js.global.get(js.Object, "Uint8ClampedArray");
|
||||||
const arr = try Uint8ClampedArray.new(.{ mem_buf, buf.ptr, buf.len });
|
defer Uint8ClampedArray.deinit();
|
||||||
|
const arr = try Uint8ClampedArray.new(.{ mem_buf, buf.ptr, buf.len });
|
||||||
|
if (!wasm.shared_mem) break :arr arr;
|
||||||
|
|
||||||
|
// If we're sharing memory then we have to copy the data since
|
||||||
|
// we can't set ImageData directly using a SharedArrayBuffer.
|
||||||
|
defer arr.deinit();
|
||||||
|
break :arr try arr.call(js.Object, "slice", .{});
|
||||||
|
};
|
||||||
defer arr.deinit();
|
defer arr.deinit();
|
||||||
|
|
||||||
// Create the image data from our array
|
// Create the image data from our array
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
//! This file contains helpers for wasm compilation.
|
//! This file contains helpers for wasm compilation.
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const builtin = @import("builtin");
|
const builtin = @import("builtin");
|
||||||
|
const options = @import("build_options");
|
||||||
|
|
||||||
comptime {
|
comptime {
|
||||||
if (!builtin.target.isWasm()) {
|
if (!builtin.target.isWasm()) {
|
||||||
@ -8,6 +9,10 @@ comptime {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// True if we're in shared memory mode. If true, then the memory buffer
|
||||||
|
/// in JS will be backed by a SharedArrayBuffer and some behaviors change.
|
||||||
|
pub const shared_mem = options.wasm_shared;
|
||||||
|
|
||||||
/// The allocator to use in wasm environments.
|
/// The allocator to use in wasm environments.
|
||||||
///
|
///
|
||||||
/// The return values of this should NOT be sent to the host environment
|
/// The return values of this should NOT be sent to the host environment
|
||||||
|
2
vendor/zig-js
vendored
2
vendor/zig-js
vendored
@ -1 +1 @@
|
|||||||
Subproject commit 5e3a5ce776f7b424022494a830f66ace224fe7ff
|
Subproject commit c89c1965cc6bf6ede97c1b891b624ce5282853d1
|
Reference in New Issue
Block a user