aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <jarred@jarredsumner.com> 2021-05-07 20:19:32 -0700
committerGravatar Jarred Sumner <jarred@jarredsumner.com> 2021-05-07 20:19:32 -0700
commit12615602144288b3123f352e5d586714bc01b4dc (patch)
tree5278fee0e74b7b123c37940d53dd37078a296c19
parentcaa747ba717e28791089d2db22ee9300f11b4d25 (diff)
downloadbun-12615602144288b3123f352e5d586714bc01b4dc.tar.gz
bun-12615602144288b3123f352e5d586714bc01b4dc.tar.zst
bun-12615602144288b3123f352e5d586714bc01b4dc.zip
This _sort of_ works
Former-commit-id: 8c4917fe60ad049789aea96018363997e9f20e8f
-rw-r--r--.gitignore4
-rw-r--r--build.zig76
-rw-r--r--src/api/demo/lib/api.ts141
-rw-r--r--src/api/demo/package.json2
-rw-r--r--src/api/demo/pnpm-lock.yaml8
-rw-r--r--src/api/schema.js401
-rw-r--r--src/api/schema.zig1
-rw-r--r--src/global.zig35
-rw-r--r--src/js_printer.zig11
-rw-r--r--src/main_wasm.zig66
10 files changed, 464 insertions, 281 deletions
diff --git a/.gitignore b/.gitignore
index bd1fdb867..b8e503f95 100644
--- a/.gitignore
+++ b/.gitignore
@@ -14,4 +14,6 @@ dist
*.log
*.out.js
/package-lock.json
-build \ No newline at end of file
+build
+*.wat
+zig-out \ No newline at end of file
diff --git a/build.zig b/build.zig
index 46b73a090..5981d7b70 100644
--- a/build.zig
+++ b/build.zig
@@ -14,28 +14,81 @@ pub fn build(b: *std.build.Builder) void {
var cwd_buf = [_]u8{0} ** 4096;
var cwd = std.os.getcwd(&cwd_buf) catch unreachable;
var exe: *std.build.LibExeObjStep = undefined;
+
+ std.debug.print("Build Mode: {s}\n", .{@tagName(mode)});
+
if (target.getOsTag() == .wasi) {
+ std.debug.print("Build OS: Wasi\n", .{});
exe.enable_wasmtime = true;
exe = b.addExecutable("esdev", "src/main_wasi.zig");
+ exe.is_dynamic = true;
+ if (mode == std.builtin.Mode.Debug) {
+ exe.setOutputDir("build/bin/debug");
+ } else {
+ exe.setOutputDir("build/bin");
+ }
} else if (target.getCpuArch().isWasm()) {
- exe = b.addExecutable("esdev", "src/main_wasm.zig");
+ std.debug.print("Build OS: WASM\n", .{});
+ // exe = b.addExecutable(
+ // "esdev",
+ // "src/main_wasm.zig",
+ // );
+ // exe.is_linking_libc = false;
+ // exe.is_dynamic = true;
+ var lib = b.addExecutable("esdev", "src/main_wasm.zig");
+
+ // exe.want_lto = true;
+ // exe.linkLibrary(lib);
if (mode == std.builtin.Mode.Debug) {
- exe.setOutputDir("build/wasm/debug");
+ // exception_handling
+ var features = target.getCpuFeatures();
+ features.addFeature(2);
+ target.updateCpuFeatures(&features);
+ lib.setOutputDir("build/wasm/debug");
} else {
- exe.setOutputDir("build/wasm");
+ // lib.strip = true;
+ lib.setOutputDir("build/wasm");
+ }
+
+ lib.want_lto = true;
+ b.install_path = lib.getOutputPath();
+
+ std.debug.print("Build Destination: {s}\n", .{lib.getOutputPath()});
+
+ b.default_step.dependOn(&lib.step);
+ b.verbose_link = true;
+ lib.setTarget(target);
+ lib.setBuildMode(mode);
+
+ std.fs.deleteTreeAbsolute(std.fs.path.join(std.heap.page_allocator, &.{ cwd, lib.getOutputPath() }) catch unreachable) catch {};
+ var install = b.getInstallStep();
+ lib.strip = false;
+ lib.install();
+
+ const run_cmd = lib.run();
+ run_cmd.step.dependOn(b.getInstallStep());
+ if (b.args) |args| {
+ run_cmd.addArgs(args);
}
+
+ const run_step = b.step("run", "Run the app");
+ run_step.dependOn(&run_cmd.step);
+
+ return;
} else {
+ std.debug.print("Build OS: Native\n", .{});
exe = b.addExecutable("esdev", "src/main.zig");
exe.linkLibC();
- }
- if (mode == std.builtin.Mode.Debug) {
- exe.setOutputDir("build/bin/debug");
- } else {
- exe.setOutputDir("build/bin");
+ if (mode == std.builtin.Mode.Debug) {
+ exe.setOutputDir("build/bin/debug");
+ } else {
+ exe.setOutputDir("build/bin");
+ }
}
+ std.debug.print("Build Destination: {s}\n", .{exe.getOutputPath()});
var walker = std.fs.walkPath(std.heap.page_allocator, cwd) catch unreachable;
if (std.builtin.is_test) {
while (walker.next() catch unreachable) |entry| {
@@ -47,10 +100,13 @@ pub fn build(b: *std.build.Builder) void {
}
exe.setTarget(target);
exe.setBuildMode(mode);
+ b.install_path = exe.getOutputPath();
- std.fs.deleteTreeAbsolute(exe.getOutputPath()) catch unreachable;
+ std.fs.deleteTreeAbsolute(std.fs.path.join(std.heap.page_allocator, &.{ cwd, exe.getOutputPath() }) catch unreachable) catch {};
+ if (!target.getCpuArch().isWasm()) {
+ exe.addLibPath("/usr/local/lib");
+ }
- exe.addLibPath("/usr/local/lib");
exe.install();
const run_cmd = exe.run();
diff --git a/src/api/demo/lib/api.ts b/src/api/demo/lib/api.ts
index 1619e2c46..9f07939c0 100644
--- a/src/api/demo/lib/api.ts
+++ b/src/api/demo/lib/api.ts
@@ -2,7 +2,7 @@ import * as Schema from "../../schema";
import { ByteBuffer } from "peechy";
export interface WebAssemblyModule {
- init(starting_memory: number): number;
+ init(): number;
transform(a: number): number;
malloc(a: number): number;
calloc(a: number): number;
@@ -15,6 +15,10 @@ const wasm_imports_sym: symbol | string =
? "wasm_imports"
: Symbol("wasm_imports");
+const ptr_converter = new ArrayBuffer(8);
+const ptr_float = new Float64Array(ptr_converter);
+const slice = new Uint32Array(ptr_converter);
+
export class ESDev {
static has_initialized = false;
static wasm_source: WebAssembly.WebAssemblyInstantiatedSource = null;
@@ -22,49 +26,142 @@ export class ESDev {
return ESDev.wasm_source.instance.exports as any;
}
static get memory() {
- return ESDev.wasm_exports.memory as WebAssembly.Memory;
+ return ESDev[wasm_imports_sym].memory as WebAssembly.Memory;
}
+
static memory_array: Uint8Array;
static _decoder: TextDecoder;
- static _wasmPtrLenToString(ptr: number, len: number) {
+ static _wasmPtrToSlice(offset: number) {
+ if (ESDev.memory_array.buffer !== ESDev.memory.buffer) {
+ ESDev.memory_array = new Uint8Array(ESDev.memory.buffer);
+ }
+ ptr_float[0] = offset;
+ return ESDev.memory_array.subarray(slice[0], slice[0] + slice[1]);
+ }
+
+ static _wasmPtrLenToString(slice: number) {
if (!ESDev._decoder) {
- ESDev._decoder = new TextDecoder();
+ ESDev._decoder = new TextDecoder("utf8");
}
- const region = ESDev.memory_array.subarray(ptr, ptr + len + 1);
+
+ const region = this._wasmPtrToSlice(slice);
+
return ESDev._decoder.decode(region);
}
// We don't want people to be calling these manually
static [wasm_imports_sym] = {
- console_log(ptr: number, len: number) {
- console.log(ESDev._wasmPtrLenToString(ptr, len));
+ console_log(slice: number) {
+ console.log(ESDev._wasmPtrLenToString(slice));
},
- console_error(ptr: number, len: number) {
- console.error(ESDev._wasmPtrLenToString(ptr, len));
+ console_error(slice: number) {
+ console.error(ESDev._wasmPtrLenToString(slice));
},
- console_warn(ptr: number, len: number) {
- console.warn(ESDev._wasmPtrLenToString(ptr, len));
+ console_warn(slice: number) {
+ console.warn(ESDev._wasmPtrLenToString(slice));
},
- console_info(ptr: number, len: number) {
- console.info(ESDev._wasmPtrLenToString(ptr, len));
+ console_info(slice: number) {
+ console.info(ESDev._wasmPtrLenToString(slice));
},
+ memory: null,
+ // __indirect_function_table: new WebAssembly.Table({
+ // initial: 0,
+ // element: "anyfunc",
+ // }),
+ // __stack_pointer: new WebAssembly.Global({
+ // mutable: true,
+ // value: "i32",
+ // }),
+ // __multi3(one: number, two: number) {
+ // return Math.imul(one | 0, two | 0);
+ // },
+ // fmod(one: number, two: number) {
+ // return one % two;
+ // },
+ // memset(ptr: number, value: number, len: number) {
+ // ESDev.memory_array.fill(value, ptr, ptr + len);
+ // },
+ // memcpy(ptr: number, value: number, len: number) {
+ // ESDev.memory_array.copyWithin(ptr, value, value + len);
+ // },
+ // // These functions convert a to an unsigned long long, rounding toward zero. Negative values all become zero.
+ // __fixunsdfti(a: number) {
+ // return Math.floor(a);
+ // },
+ // // These functions return the remainder of the unsigned division of a and b.
+ // __umodti3(a: number, b: number) {
+ // return (a | 0) % (b | 0);
+ // },
+ // // These functions return the quotient of the unsigned division of a and b.
+ // __udivti3(a: number, b: number) {
+ // return (a | 0) / (b | 0);
+ // },
+ // // These functions return the result of shifting a left by b bits.
+ // __ashlti3(a: number, b: number) {
+ // return (a | 0) >> (b | 0);
+ // },
+ // /* Returns: convert a to a double, rounding toward even. */
+ // __floatuntidf(a: number) {
+ // const mod = a % 2;
+ // if (mod === 0) {
+ // return Math.ceil(a);
+ // } else if (mod === 1) {
+ // return Math.floor(a);
+ // }
+ // },
};
static async init(url) {
+ if (ESDev.has_initialized) {
+ return;
+ }
+
+ try {
+ ESDev[wasm_imports_sym].memory = new WebAssembly.Memory({
+ initial: 1500,
+ // shared: typeof SharedArrayBuffer !== "undefined",
+ maximum: typeof SharedArrayBuffer !== "undefined" ? 5000 : undefined,
+ });
+ } catch {
+ try {
+ ESDev[wasm_imports_sym].memory = new WebAssembly.Memory({
+ initial: 750,
+ // shared: typeof SharedArrayBuffer !== "undefined",
+ maximum: typeof SharedArrayBuffer !== "undefined" ? 5000 : undefined,
+ });
+ } catch {
+ try {
+ ESDev[wasm_imports_sym].memory = new WebAssembly.Memory({
+ initial: 375,
+ // shared: typeof SharedArrayBuffer !== "undefined",
+ maximum:
+ typeof SharedArrayBuffer !== "undefined" ? 5000 : undefined,
+ });
+ } catch {
+ ESDev[wasm_imports_sym].memory = new WebAssembly.Memory({
+ initial: 125,
+ // shared: typeof SharedArrayBuffer !== "undefined",
+ maximum:
+ typeof SharedArrayBuffer !== "undefined" ? 5000 : undefined,
+ });
+ }
+ }
+ }
+
ESDev.wasm_source = await globalThis.WebAssembly.instantiateStreaming(
fetch(url),
{ env: ESDev[wasm_imports_sym] }
);
+ ESDev.memory_array = new Uint8Array(ESDev.memory.buffer);
- const res = ESDev.wasm_exports.init(1500);
+ const res = ESDev.wasm_exports.init();
if (res < 0) {
throw `[ESDev] Failed to initialize WASM module: code ${res}`;
} else {
console.log("WASM loaded.");
}
- ESDev.memory_array = new Uint8Array(ESDev.memory.buffer);
ESDev.has_initialized = true;
}
@@ -74,6 +171,10 @@ export class ESDev {
throw "Please run await ESDev.init(wasm_url) before using this.";
}
+ if (process.env.NODE_ENV === "development") {
+ console.time("[ESDev] Transform " + file_name);
+ }
+
const bb = new ByteBuffer(
new Uint8Array(content.length + file_name.length)
);
@@ -89,12 +190,16 @@ export class ESDev {
const data = bb.toUint8Array();
const ptr = ESDev.wasm_exports.malloc(data.byteLength);
- ESDev.memory_array.set(data, ptr);
- debugger;
+ this._wasmPtrToSlice(ptr).set(data);
const resp_ptr = ESDev.wasm_exports.transform(ptr);
- var _bb = new ByteBuffer(ESDev.memory_array.subarray(resp_ptr));
+ var _bb = new ByteBuffer(this._wasmPtrToSlice(resp_ptr));
const response = Schema.decodeTransformResponse(_bb);
ESDev.wasm_exports.free(resp_ptr);
+
+ if (process.env.NODE_ENV === "development") {
+ console.timeEnd("[ESDev] Transform " + file_name);
+ }
+ ESDev.wasm_exports.free(resp_ptr);
return response;
}
}
diff --git a/src/api/demo/package.json b/src/api/demo/package.json
index 8576b2bc9..588f0165f 100644
--- a/src/api/demo/package.json
+++ b/src/api/demo/package.json
@@ -9,7 +9,7 @@
},
"dependencies": {
"next": "10.2.0",
- "peechy": "0.4.0",
+ "peechy": "0.4.1",
"react": "17.0.2",
"react-dom": "17.0.2"
}
diff --git a/src/api/demo/pnpm-lock.yaml b/src/api/demo/pnpm-lock.yaml
index 3e6b4c6cc..36eb423fa 100644
--- a/src/api/demo/pnpm-lock.yaml
+++ b/src/api/demo/pnpm-lock.yaml
@@ -2,13 +2,13 @@ lockfileVersion: 5.3
specifiers:
next: 10.2.0
- peechy: 0.4.0
+ peechy: 0.4.1
react: 17.0.2
react-dom: 17.0.2
dependencies:
next: 10.2.0_react-dom@17.0.2+react@17.0.2
- peechy: 0.4.0
+ peechy: 0.4.1
react: 17.0.2
react-dom: 17.0.2_react@17.0.2
@@ -1327,8 +1327,8 @@ packages:
sha.js: 2.4.11
dev: false
- /peechy/0.4.0:
- resolution: {integrity: sha512-dIOZl4mEZGN91WYxrBv1/QOA/R6tNf10FFo4rrCSPfPGPz3gzsvkrXIT8K46XBBlZbSNYS4xUJZ6TZMrptcJIA==}
+ /peechy/0.4.1:
+ resolution: {integrity: sha512-IWelrwiGJRd3EmIvF0DcDQdJldy2QzPXY5fU42AAkqCQoMo+mX7lQIilMwLmPX3RjPfQY9Bv3pK9K8iSi2HlWA==}
hasBin: true
dependencies:
change-case: 4.1.2
diff --git a/src/api/schema.js b/src/api/schema.js
index 55c4bc040..2a695a33c 100644
--- a/src/api/schema.js
+++ b/src/api/schema.js
@@ -1,46 +1,46 @@
const Loader = {
- 1: 1,
- 2: 2,
- 3: 3,
- 4: 4,
- 5: 5,
- 6: 6,
- 7: 7,
- jsx: 1,
- js: 2,
- ts: 3,
- tsx: 4,
- css: 5,
- file: 6,
- json: 7,
+ "1": 1,
+ "2": 2,
+ "3": 3,
+ "4": 4,
+ "5": 5,
+ "6": 6,
+ "7": 7,
+ "jsx": 1,
+ "js": 2,
+ "ts": 3,
+ "tsx": 4,
+ "css": 5,
+ "file": 6,
+ "json": 7
};
const LoaderKeys = {
- 1: "jsx",
- 2: "js",
- 3: "ts",
- 4: "tsx",
- 5: "css",
- 6: "file",
- 7: "json",
- jsx: "jsx",
- js: "js",
- ts: "ts",
- tsx: "tsx",
- css: "css",
- file: "file",
- json: "json",
+ "1": "jsx",
+ "2": "js",
+ "3": "ts",
+ "4": "tsx",
+ "5": "css",
+ "6": "file",
+ "7": "json",
+ "jsx": "jsx",
+ "js": "js",
+ "ts": "ts",
+ "tsx": "tsx",
+ "css": "css",
+ "file": "file",
+ "json": "json"
};
const JSXRuntime = {
- 1: 1,
- 2: 2,
- automatic: 1,
- classic: 2,
+ "1": 1,
+ "2": 2,
+ "automatic": 1,
+ "classic": 2
};
const JSXRuntimeKeys = {
- 1: "automatic",
- 2: "classic",
- automatic: "automatic",
- classic: "classic",
+ "1": "automatic",
+ "2": "classic",
+ "automatic": "automatic",
+ "classic": "classic"
};
function decodeJSX(bb) {
@@ -53,92 +53,86 @@ function decodeJSX(bb) {
result["import_source"] = bb.readString();
result["react_fast_refresh"] = !!bb.readByte();
var length = bb.readVarUint();
- var values = (result["loader_keys"] = Array(length));
+ var values = result["loader_keys"] = Array(length);
for (var i = 0; i < length; i++) values[i] = bb.readString();
var length = bb.readVarUint();
- var values = (result["loader_values"] = Array(length));
+ var values = result["loader_values"] = Array(length);
for (var i = 0; i < length; i++) values[i] = Loader[bb.readByte()];
return result;
}
function encodeJSX(message, bb) {
+
var value = message["factory"];
if (value != null) {
bb.writeString(value);
} else {
- throw new Error('Missing required field "factory"');
+ throw new Error("Missing required field \"factory\"");
}
var value = message["runtime"];
if (value != null) {
var encoded = JSXRuntime[value];
- if (encoded === void 0)
- throw new Error(
- "Invalid value " + JSON.stringify(value) + ' for enum "JSXRuntime"'
- );
- bb.writeByte(encoded);
+if (encoded === void 0) throw new Error("Invalid value " + JSON.stringify(value) + " for enum \"JSXRuntime\"");
+bb.writeByte(encoded);
} else {
- throw new Error('Missing required field "runtime"');
+ throw new Error("Missing required field \"runtime\"");
}
var value = message["fragment"];
if (value != null) {
bb.writeString(value);
} else {
- throw new Error('Missing required field "fragment"');
+ throw new Error("Missing required field \"fragment\"");
}
var value = message["production"];
if (value != null) {
bb.writeByte(value);
} else {
- throw new Error('Missing required field "production"');
+ throw new Error("Missing required field \"production\"");
}
var value = message["import_source"];
if (value != null) {
bb.writeString(value);
} else {
- throw new Error('Missing required field "import_source"');
+ throw new Error("Missing required field \"import_source\"");
}
var value = message["react_fast_refresh"];
if (value != null) {
bb.writeByte(value);
} else {
- throw new Error('Missing required field "react_fast_refresh"');
+ throw new Error("Missing required field \"react_fast_refresh\"");
}
var value = message["loader_keys"];
if (value != null) {
- var values = value,
- n = values.length;
+ var values = value, n = values.length;
bb.writeVarUint(n);
for (var i = 0; i < n; i++) {
value = values[i];
bb.writeString(value);
}
} else {
- throw new Error('Missing required field "loader_keys"');
+ throw new Error("Missing required field \"loader_keys\"");
}
var value = message["loader_values"];
if (value != null) {
- var values = value,
- n = values.length;
+ var values = value, n = values.length;
bb.writeVarUint(n);
for (var i = 0; i < n; i++) {
value = values[i];
var encoded = Loader[value];
- if (encoded === void 0)
- throw new Error(
- "Invalid value " + JSON.stringify(value) + ' for enum "Loader"'
- );
- bb.writeByte(encoded);
+if (encoded === void 0) throw new Error("Invalid value " + JSON.stringify(value) + " for enum \"Loader\"");
+bb.writeByte(encoded);
}
} else {
- throw new Error('Missing required field "loader_values"');
+ throw new Error("Missing required field \"loader_values\"");
}
+
}
function decodeTransformOptions(bb) {
@@ -148,61 +142,61 @@ function decodeTransformOptions(bb) {
result["ts"] = !!bb.readByte();
result["base_path"] = bb.readString();
var length = bb.readVarUint();
- var values = (result["define_keys"] = Array(length));
+ var values = result["define_keys"] = Array(length);
for (var i = 0; i < length; i++) values[i] = bb.readString();
var length = bb.readVarUint();
- var values = (result["define_values"] = Array(length));
+ var values = result["define_values"] = Array(length);
for (var i = 0; i < length; i++) values[i] = bb.readString();
return result;
}
function encodeTransformOptions(message, bb) {
+
var value = message["jsx"];
if (value != null) {
encodeJSX(value, bb);
} else {
- throw new Error('Missing required field "jsx"');
+ throw new Error("Missing required field \"jsx\"");
}
var value = message["ts"];
if (value != null) {
bb.writeByte(value);
} else {
- throw new Error('Missing required field "ts"');
+ throw new Error("Missing required field \"ts\"");
}
var value = message["base_path"];
if (value != null) {
bb.writeString(value);
} else {
- throw new Error('Missing required field "base_path"');
+ throw new Error("Missing required field \"base_path\"");
}
var value = message["define_keys"];
if (value != null) {
- var values = value,
- n = values.length;
+ var values = value, n = values.length;
bb.writeVarUint(n);
for (var i = 0; i < n; i++) {
value = values[i];
bb.writeString(value);
}
} else {
- throw new Error('Missing required field "define_keys"');
+ throw new Error("Missing required field \"define_keys\"");
}
var value = message["define_values"];
if (value != null) {
- var values = value,
- n = values.length;
+ var values = value, n = values.length;
bb.writeVarUint(n);
for (var i = 0; i < n; i++) {
value = values[i];
bb.writeString(value);
}
} else {
- throw new Error('Missing required field "define_values"');
+ throw new Error("Missing required field \"define_values\"");
}
+
}
function decodeFileHandle(bb) {
@@ -215,26 +209,28 @@ function decodeFileHandle(bb) {
}
function encodeFileHandle(message, bb) {
+
var value = message["path"];
if (value != null) {
bb.writeString(value);
} else {
- throw new Error('Missing required field "path"');
+ throw new Error("Missing required field \"path\"");
}
var value = message["size"];
if (value != null) {
bb.writeVarUint(value);
} else {
- throw new Error('Missing required field "size"');
+ throw new Error("Missing required field \"size\"");
}
var value = message["fd"];
if (value != null) {
bb.writeVarUint(value);
} else {
- throw new Error('Missing required field "fd"');
+ throw new Error("Missing required field \"fd\"");
}
+
}
function decodeTransform(bb) {
@@ -242,36 +238,37 @@ function decodeTransform(bb) {
while (true) {
switch (bb.readByte()) {
- case 0:
- return result;
+ case 0:
+ return result;
- case 1:
- result["handle"] = decodeFileHandle(bb);
- break;
+ case 1:
+ result["handle"] = decodeFileHandle(bb);
+ break;
- case 2:
- result["path"] = bb.readString();
- break;
+ case 2:
+ result["path"] = bb.readString();
+ break;
- case 3:
- result["contents"] = bb.readString();
- break;
+ case 3:
+ result["contents"] = bb.readString();
+ break;
- case 4:
- result["loader"] = Loader[bb.readByte()];
- break;
+ case 4:
+ result["loader"] = Loader[bb.readByte()];
+ break;
- case 5:
- result["options"] = decodeTransformOptions(bb);
- break;
+ case 5:
+ result["options"] = decodeTransformOptions(bb);
+ break;
- default:
- throw new Error("Attempted to parse invalid message");
+ default:
+ throw new Error("Attempted to parse invalid message");
}
}
}
function encodeTransform(message, bb) {
+
var value = message["handle"];
if (value != null) {
bb.writeByte(1);
@@ -294,11 +291,8 @@ function encodeTransform(message, bb) {
if (value != null) {
bb.writeByte(4);
var encoded = Loader[value];
- if (encoded === void 0)
- throw new Error(
- "Invalid value " + JSON.stringify(value) + ' for enum "Loader"'
- );
- bb.writeByte(encoded);
+if (encoded === void 0) throw new Error("Invalid value " + JSON.stringify(value) + " for enum \"Loader\"");
+bb.writeByte(encoded);
}
var value = message["options"];
@@ -307,18 +301,19 @@ function encodeTransform(message, bb) {
encodeTransformOptions(value, bb);
}
bb.writeByte(0);
+
}
const TransformResponseStatus = {
- 1: 1,
- 2: 2,
- success: 1,
- fail: 2,
+ "1": 1,
+ "2": 2,
+ "success": 1,
+ "fail": 2
};
const TransformResponseStatusKeys = {
- 1: "success",
- 2: "fail",
- success: "success",
- fail: "fail",
+ "1": "success",
+ "2": "fail",
+ "success": "success",
+ "fail": "fail"
};
function decodeOutputFile(bb) {
@@ -330,19 +325,21 @@ function decodeOutputFile(bb) {
}
function encodeOutputFile(message, bb) {
+
var value = message["data"];
if (value != null) {
- bb.writeByteArray(value);
+ bb.writeByteArray(value);
} else {
- throw new Error('Missing required field "data"');
+ throw new Error("Missing required field \"data\"");
}
var value = message["path"];
if (value != null) {
bb.writeString(value);
} else {
- throw new Error('Missing required field "path"');
+ throw new Error("Missing required field \"path\"");
}
+
}
function decodeTransformResponse(bb) {
@@ -350,74 +347,69 @@ function decodeTransformResponse(bb) {
result["status"] = TransformResponseStatus[bb.readVarUint()];
var length = bb.readVarUint();
- var values = (result["files"] = Array(length));
+ var values = result["files"] = Array(length);
for (var i = 0; i < length; i++) values[i] = decodeOutputFile(bb);
var length = bb.readVarUint();
- var values = (result["errors"] = Array(length));
+ var values = result["errors"] = Array(length);
for (var i = 0; i < length; i++) values[i] = decodeMessage(bb);
return result;
}
function encodeTransformResponse(message, bb) {
+
var value = message["status"];
if (value != null) {
var encoded = TransformResponseStatus[value];
- if (encoded === void 0)
- throw new Error(
- "Invalid value " +
- JSON.stringify(value) +
- ' for enum "TransformResponseStatus"'
- );
- bb.writeVarUint(encoded);
+if (encoded === void 0) throw new Error("Invalid value " + JSON.stringify(value) + " for enum \"TransformResponseStatus\"");
+bb.writeVarUint(encoded);
} else {
- throw new Error('Missing required field "status"');
+ throw new Error("Missing required field \"status\"");
}
var value = message["files"];
if (value != null) {
- var values = value,
- n = values.length;
+ var values = value, n = values.length;
bb.writeVarUint(n);
for (var i = 0; i < n; i++) {
value = values[i];
encodeOutputFile(value, bb);
}
} else {
- throw new Error('Missing required field "files"');
+ throw new Error("Missing required field \"files\"");
}
var value = message["errors"];
if (value != null) {
- var values = value,
- n = values.length;
+ var values = value, n = values.length;
bb.writeVarUint(n);
for (var i = 0; i < n; i++) {
value = values[i];
encodeMessage(value, bb);
}
} else {
- throw new Error('Missing required field "errors"');
+ throw new Error("Missing required field \"errors\"");
}
+
}
const MessageKind = {
- 1: 1,
- 2: 2,
- 3: 3,
- 4: 4,
- err: 1,
- warn: 2,
- note: 3,
- debug: 4,
+ "1": 1,
+ "2": 2,
+ "3": 3,
+ "4": 4,
+ "err": 1,
+ "warn": 2,
+ "note": 3,
+ "debug": 4
};
const MessageKindKeys = {
- 1: "err",
- 2: "warn",
- 3: "note",
- 4: "debug",
- err: "err",
- warn: "warn",
- note: "note",
- debug: "debug",
+ "1": "err",
+ "2": "warn",
+ "3": "note",
+ "4": "debug",
+ "err": "err",
+ "warn": "warn",
+ "note": "note",
+ "debug": "debug"
};
function decodeLocation(bb) {
@@ -434,54 +426,56 @@ function decodeLocation(bb) {
}
function encodeLocation(message, bb) {
+
var value = message["file"];
if (value != null) {
bb.writeString(value);
} else {
- throw new Error('Missing required field "file"');
+ throw new Error("Missing required field \"file\"");
}
var value = message["namespace"];
if (value != null) {
bb.writeString(value);
} else {
- throw new Error('Missing required field "namespace"');
+ throw new Error("Missing required field \"namespace\"");
}
var value = message["line"];
if (value != null) {
bb.writeInt32(value);
} else {
- throw new Error('Missing required field "line"');
+ throw new Error("Missing required field \"line\"");
}
var value = message["column"];
if (value != null) {
bb.writeInt32(value);
} else {
- throw new Error('Missing required field "column"');
+ throw new Error("Missing required field \"column\"");
}
var value = message["line_text"];
if (value != null) {
bb.writeString(value);
} else {
- throw new Error('Missing required field "line_text"');
+ throw new Error("Missing required field \"line_text\"");
}
var value = message["suggestion"];
if (value != null) {
bb.writeString(value);
} else {
- throw new Error('Missing required field "suggestion"');
+ throw new Error("Missing required field \"suggestion\"");
}
var value = message["offset"];
if (value != null) {
bb.writeVarUint(value);
} else {
- throw new Error('Missing required field "offset"');
+ throw new Error("Missing required field \"offset\"");
}
+
}
function decodeMessageData(bb) {
@@ -489,24 +483,25 @@ function decodeMessageData(bb) {
while (true) {
switch (bb.readByte()) {
- case 0:
- return result;
+ case 0:
+ return result;
- case 1:
- result["text"] = bb.readString();
- break;
+ case 1:
+ result["text"] = bb.readString();
+ break;
- case 2:
- result["location"] = decodeLocation(bb);
- break;
+ case 2:
+ result["location"] = decodeLocation(bb);
+ break;
- default:
- throw new Error("Attempted to parse invalid message");
+ default:
+ throw new Error("Attempted to parse invalid message");
}
}
}
function encodeMessageData(message, bb) {
+
var value = message["text"];
if (value != null) {
bb.writeByte(1);
@@ -519,6 +514,7 @@ function encodeMessageData(message, bb) {
encodeLocation(value, bb);
}
bb.writeByte(0);
+
}
function decodeMessage(bb) {
@@ -527,43 +523,41 @@ function decodeMessage(bb) {
result["kind"] = MessageKind[bb.readVarUint()];
result["data"] = decodeMessageData(bb);
var length = bb.readVarUint();
- var values = (result["notes"] = Array(length));
+ var values = result["notes"] = Array(length);
for (var i = 0; i < length; i++) values[i] = decodeMessageData(bb);
return result;
}
function encodeMessage(message, bb) {
+
var value = message["kind"];
if (value != null) {
var encoded = MessageKind[value];
- if (encoded === void 0)
- throw new Error(
- "Invalid value " + JSON.stringify(value) + ' for enum "MessageKind"'
- );
- bb.writeVarUint(encoded);
+if (encoded === void 0) throw new Error("Invalid value " + JSON.stringify(value) + " for enum \"MessageKind\"");
+bb.writeVarUint(encoded);
} else {
- throw new Error('Missing required field "kind"');
+ throw new Error("Missing required field \"kind\"");
}
var value = message["data"];
if (value != null) {
encodeMessageData(value, bb);
} else {
- throw new Error('Missing required field "data"');
+ throw new Error("Missing required field \"data\"");
}
var value = message["notes"];
if (value != null) {
- var values = value,
- n = values.length;
+ var values = value, n = values.length;
bb.writeVarUint(n);
for (var i = 0; i < n; i++) {
value = values[i];
encodeMessageData(value, bb);
}
} else {
- throw new Error('Missing required field "notes"');
+ throw new Error("Missing required field \"notes\"");
}
+
}
function decodeLog(bb) {
@@ -572,65 +566,66 @@ function decodeLog(bb) {
result["warnings"] = bb.readUint32();
result["errors"] = bb.readUint32();
var length = bb.readVarUint();
- var values = (result["msgs"] = Array(length));
+ var values = result["msgs"] = Array(length);
for (var i = 0; i < length; i++) values[i] = decodeMessage(bb);
return result;
}
function encodeLog(message, bb) {
+
var value = message["warnings"];
if (value != null) {
bb.writeUint32(value);
} else {
- throw new Error('Missing required field "warnings"');
+ throw new Error("Missing required field \"warnings\"");
}
var value = message["errors"];
if (value != null) {
bb.writeUint32(value);
} else {
- throw new Error('Missing required field "errors"');
+ throw new Error("Missing required field \"errors\"");
}
var value = message["msgs"];
if (value != null) {
- var values = value,
- n = values.length;
+ var values = value, n = values.length;
bb.writeVarUint(n);
for (var i = 0; i < n; i++) {
value = values[i];
encodeMessage(value, bb);
}
} else {
- throw new Error('Missing required field "msgs"');
+ throw new Error("Missing required field \"msgs\"");
}
+
}
-export { Loader };
-export { LoaderKeys };
-export { JSXRuntime };
-export { JSXRuntimeKeys };
-export { decodeJSX };
-export { encodeJSX };
-export { decodeTransformOptions };
-export { encodeTransformOptions };
-export { decodeFileHandle };
-export { encodeFileHandle };
-export { decodeTransform };
-export { encodeTransform };
-export { TransformResponseStatus };
-export { TransformResponseStatusKeys };
-export { decodeOutputFile };
-export { encodeOutputFile };
-export { decodeTransformResponse };
-export { encodeTransformResponse };
-export { MessageKind };
-export { MessageKindKeys };
-export { decodeLocation };
-export { encodeLocation };
-export { decodeMessageData };
-export { encodeMessageData };
-export { decodeMessage };
-export { encodeMessage };
-export { decodeLog };
-export { encodeLog };
+export { Loader }
+export { LoaderKeys }
+export { JSXRuntime }
+export { JSXRuntimeKeys }
+export { decodeJSX }
+export { encodeJSX }
+export { decodeTransformOptions }
+export { encodeTransformOptions }
+export { decodeFileHandle }
+export { encodeFileHandle }
+export { decodeTransform }
+export { encodeTransform }
+export { TransformResponseStatus }
+export { TransformResponseStatusKeys }
+export { decodeOutputFile }
+export { encodeOutputFile }
+export { decodeTransformResponse }
+export { encodeTransformResponse }
+export { MessageKind }
+export { MessageKindKeys }
+export { decodeLocation }
+export { encodeLocation }
+export { decodeMessageData }
+export { encodeMessageData }
+export { decodeMessage }
+export { encodeMessage }
+export { decodeLog }
+export { encodeLog } \ No newline at end of file
diff --git a/src/api/schema.zig b/src/api/schema.zig
index d34e501a3..c10e5b5a3 100644
--- a/src/api/schema.zig
+++ b/src/api/schema.zig
@@ -442,6 +442,7 @@ pub fn update(result: *OutputFile, allocator: *std.mem.Allocator, reader: anytyp
pub fn encode(result: *const @This(), writer: anytype) anyerror!void {
+ try writer.writeIntNative(u32, @intCast(u32, result.data.len));
try writer.writeAll(result.data);
try writer.writeIntNative(u32, @intCast(u32, result.path.len));
diff --git a/src/global.zig b/src/global.zig
index eb7fcfec5..9ac540311 100644
--- a/src/global.zig
+++ b/src/global.zig
@@ -1,11 +1,13 @@
const std = @import("std");
pub usingnamespace @import("strings.zig");
+pub const isWasm = comptime std.Target.current.isWasm();
+
pub const Output = struct {
var source: *Source = undefined;
pub const Source = struct {
const StreamType = comptime {
- if (std.builtin.target.isWasm()) {
+ if (isWasm) {
return std.io.FixedBufferStream([]u8);
} else {
return std.fs.File;
@@ -28,22 +30,33 @@ pub const Output = struct {
}
};
- pub fn print(comptime fmt: string, args: anytype) void {
- if (comptime std.builtin.target.isWasm()) {
- source.stream.pos = 0;
+ pub fn printErrorable(comptime fmt: string, args: anytype) !void {
+ if (isWasm) {
+ try source.stream.seekTo(0);
+ try source.stream.writer().print(fmt, args);
+ const root = @import("root");
+ root.console_log(root.Uint8Array.fromSlice(source.out_buffer[0..source.stream.pos]));
+ } else {
std.fmt.format(source.stream.writer(), fmt, args) catch unreachable;
+ }
+ }
+
+ pub fn print(comptime fmt: string, args: anytype) void {
+ if (isWasm) {
+ source.stream.seekTo(0) catch return;
+ source.stream.writer().print(fmt, args) catch return;
const root = @import("root");
- // root.console_log(@ptrToInt(&source.out_buffer), source.stream.pos);
+ root.console_log(root.Uint8Array.fromSlice(source.out_buffer[0..source.stream.pos]));
} else {
std.fmt.format(source.stream.writer(), fmt, args) catch unreachable;
}
}
pub fn printError(comptime fmt: string, args: anytype) void {
- if (comptime std.builtin.target.isWasm()) {
- source.error_stream.pos = 0;
- std.fmt.format(source.error_stream.writer(), fmt, args) catch unreachable;
+ if (isWasm) {
+ source.error_stream.seekTo(0) catch return;
+ source.error_stream.writer().print(fmt, args) catch unreachable;
const root = @import("root");
- // root.console_error(@ptrToInt(&source.err_buffer), source.error_stream.pos);
+ root.console_error(root.Uint8Array.fromSlice(source.err_buffer[0..source.error_stream.pos]));
} else {
std.fmt.format(source.error_stream.writer(), fmt, args) catch unreachable;
}
@@ -52,8 +65,8 @@ pub const Output = struct {
pub const Global = struct {
pub fn panic(comptime fmt: string, args: anytype) noreturn {
- if (comptime std.builtin.target.isWasm()) {
- Output.printError(fmt, args);
+ if (isWasm) {
+ Output.print(fmt, args);
@panic(fmt);
} else {
std.debug.panic(fmt, args);
diff --git a/src/js_printer.zig b/src/js_printer.zig
index 80304c982..1ed418e47 100644
--- a/src/js_printer.zig
+++ b/src/js_printer.zig
@@ -771,15 +771,8 @@ pub fn NewPrinter(comptime ascii_only: bool) type {
pub fn printQuotedUTF8(p: *Printer, str: string, allow_backtick: bool) void {
const quote = p.bestQuoteCharForString(str, allow_backtick);
p.print(quote);
- // fast path: small strings get a stack allocation
- if (str.len < 128) {
- var buf = [128]u16{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
- const bufEnd = strings.toUTF16Buf(str, &buf);
- p.printQuotedUTF16(buf[0..bufEnd], quote);
- } else {
- // slow path: big strings get a heap allocation
- p.printQuotedUTF16(strings.toUTF16Alloc(str, p.allocator) catch unreachable, quote);
- }
+ // I don't think this will work...
+ p.print(str);
p.print(quote);
}
diff --git a/src/main_wasm.zig b/src/main_wasm.zig
index 03360b165..49f7d36c5 100644
--- a/src/main_wasm.zig
+++ b/src/main_wasm.zig
@@ -71,20 +71,23 @@ pub const Api = struct {
options: *Schema.TransformOptions = &default_options,
files: std.ArrayList(string),
log: logger.Log,
+ defines: ?*Define = null,
pub fn transform(self: *Api, request: Schema.Transform) !Schema.TransformResponse {
const opts = try options.TransformOptions.initUncached(alloc.dynamic, request.path.?, request.contents.?);
var source = logger.Source.initFile(opts.entry_point, alloc.dynamic);
var ast: js_ast.Ast = undefined;
- var raw_defines = RawDefines.init(alloc.static);
- try raw_defines.put("process.env.NODE_ENV", "\"development\"");
-
- var user_defines = try DefineData.from_input(raw_defines, &self.log, alloc.static);
- var define = try Define.init(
- alloc.static,
- user_defines,
- );
+ if (self.defines == null) {
+ var raw_defines = RawDefines.init(alloc.static);
+ try raw_defines.put("process.env.NODE_ENV", "\"development\"");
+
+ var user_defines = try DefineData.from_input(raw_defines, &self.log, alloc.static);
+ self.defines = try Define.init(
+ alloc.static,
+ user_defines,
+ );
+ }
switch (opts.loader) {
.json => {
@@ -101,7 +104,7 @@ pub const Api = struct {
ast = js_ast.Ast.initTest(&([_]js_ast.Part{part}));
},
.jsx, .tsx, .ts, .js => {
- var parser = try js_parser.Parser.init(opts, &self.log, &source, define, alloc.dynamic);
+ var parser = try js_parser.Parser.init(opts, &self.log, &source, self.defines.?, alloc.dynamic);
var res = try parser.parse();
ast = res.ast;
},
@@ -136,19 +139,20 @@ pub const Api = struct {
}
};
-pub extern fn console_log(ptr: usize, len: usize) void;
-pub extern fn console_error(ptr: usize, len: usize) void;
-pub extern fn console_warn(ptr: usize, len: usize) void;
-pub extern fn console_info(ptr: usize, len: usize) void;
+pub extern fn console_log(abi: Uint8Array.Abi) void;
+pub extern fn console_error(abi: Uint8Array.Abi) void;
+pub extern fn console_warn(abi: Uint8Array.Abi) void;
+pub extern fn console_info(abi: Uint8Array.Abi) void;
-const Gpa = std.heap.GeneralPurposeAllocator(.{});
-var gpa = Gpa{};
pub const Exports = struct {
- fn init(amount_to_grow: usize) callconv(.C) i32 {
- const res = @wasmMemoryGrow(0, amount_to_grow);
+ fn init() callconv(.C) i32 {
+ // const res = @wasmMemoryGrow(0, amount_to_grow);
if (alloc.needs_setup) {
- alloc.setup(&gpa.allocator) catch return -1;
- _ = MainPanicHandler.init(&api.?.log);
+ alloc.setup(zee.ZeeAllocDefaults.wasm_allocator) catch return -1;
+ // const Gpa = std.heap.GeneralPurposeAllocator(.{});
+ // var gpa = Gpa{};
+ // var allocator = &gpa.allocator;
+ // alloc.setup(allocator) catch return -1;
var out_buffer = alloc.static.alloc(u8, 2048) catch return -1;
var err_buffer = alloc.static.alloc(u8, 2048) catch return -1;
var output = alloc.static.create(Output.Source) catch return -1;
@@ -166,8 +170,15 @@ pub const Exports = struct {
var _api = alloc.static.create(Api) catch return -1;
_api.* = Api{ .files = std.ArrayList(string).init(alloc.dynamic), .log = logger.Log.init(alloc.dynamic) };
api = _api;
- // Output.print("Initialized.", .{});
- return res;
+ Output.printErrorable("Initialized.", .{}) catch |err| {
+ var name = alloc.static.alloc(u8, @errorName(err).len) catch unreachable;
+ std.mem.copy(u8, name, @errorName(err));
+ console_error(Uint8Array.fromSlice(name));
+ };
+
+ _ = MainPanicHandler.init(&api.?.log);
+
+ return 1;
}
fn transform(abi: Uint8Array.Abi) callconv(.C) Uint8Array.Abi {
@@ -219,6 +230,8 @@ pub const Exports = struct {
}
};
+var api: ?*Api = null;
+
comptime {
@export(Exports.init, .{ .name = "init", .linkage = .Strong });
@export(Exports.transform, .{ .name = "transform", .linkage = .Strong });
@@ -228,6 +241,11 @@ comptime {
@export(Exports.free, .{ .name = "free", .linkage = .Strong });
}
-var api: ?*Api = null;
-
-pub fn main() anyerror!void {}
+pub fn main() anyerror!void {
+ std.mem.doNotOptimizeAway(Exports.init);
+ std.mem.doNotOptimizeAway(Exports.transform);
+ std.mem.doNotOptimizeAway(Exports.malloc);
+ std.mem.doNotOptimizeAway(Exports.calloc);
+ std.mem.doNotOptimizeAway(Exports.realloc);
+ std.mem.doNotOptimizeAway(Exports.free);
+}