Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 32 additions & 19 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,36 +1,48 @@
FROM node:lts-slim as node

WORKDIR /build

ARG FONTAWESOME_TOKEN
COPY package*.json ./
RUN echo "@fortawesome:registry=https://npm.fontawesome.com/\n//npm.fontawesome.com/:_authToken=${FONTAWESOME_TOKEN}" > ./.npmrc \
&& npm ci \
&& rm -f ./.npmrc

COPY webpack.*.js ./
COPY Public ./Public/
RUN npx webpack --config webpack.prod.js


FROM swiftlang/swift:nightly-main-focal as swift
RUN export DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true \
&& apt-get -q update && apt-get -q dist-upgrade -y \
&& apt-get install -y --no-install-recommends libsqlite3-dev \
&& apt-get install -y --no-install-recommends libsqlite3-dev curl \
&& rm -rf /var/lib/apt/lists/*

RUN set -e; \
SWIFT_PLATFORM_SUFFIX="ubuntu20.04_x86_64.tar.gz" \
SWIFTWASM_TAG=swift-wasm-5.7-SNAPSHOT-2022-06-25-a \
SWIFTWASM_BIN_URL="https://github.com/swiftwasm/swift/releases/download/$SWIFTWASM_TAG/$SWIFTWASM_TAG-$SWIFT_PLATFORM_SUFFIX" \
&& export DEBIAN_FRONTEND=noninteractive \
&& curl -fsSL "$SWIFTWASM_BIN_URL" -o swiftwasm.tar.gz \
&& mkdir -p /opt/swiftwasm \
&& tar -xzf swiftwasm.tar.gz --directory /opt/swiftwasm --strip-components=1 \
&& chmod -R o+r /opt/swiftwasm/usr/lib/swift \
&& rm -rf swiftwasm.tar.gz

WORKDIR /build
COPY --from=node /build /build
COPY ./Package.* ./
RUN swift package resolve

COPY . .
RUN swift build -c release -Xswiftc -enable-testing
RUN SWIFTWASM_TOOLCHAIN=/opt/swiftwasm ./Scripts/build-wasm.sh

WORKDIR /staging
RUN cp "$(swift build --package-path /build -c release --show-bin-path)/Run" ./ \
&& mv /build/Public ./Public && chmod -R a-w ./Public \
&& mv /build/.build ./.build && chmod -R a-w ./.build
&& cp -R /build/.build ./.build && chmod -R a-w ./.build

FROM node:lts-slim as node

WORKDIR /build

ARG FONTAWESOME_TOKEN
COPY package*.json ./
RUN echo "@fortawesome:registry=https://npm.fontawesome.com/\n//npm.fontawesome.com/:_authToken=${FONTAWESOME_TOKEN}" > ./.npmrc \
&& npm ci \
&& rm -f ./.npmrc

COPY webpack.*.js ./
COPY Public ./Public/
COPY --from=swift /staging/.build/wasm .build/wasm
RUN npx webpack --config webpack.prod.js



FROM swiftlang/swift:nightly-main-focal
Expand All @@ -40,10 +52,11 @@ RUN export DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true \

WORKDIR /app
COPY --from=swift --chown=vapor:vapor /staging /app
COPY --from=node /build/Public/dist /app/Public/dist

USER vapor:vapor
EXPOSE 8080

ENTRYPOINT ["./Run"]
CMD ["serve", "--env", "production", "--hostname", "0.0.0.0", "--port", "8080"]


3 changes: 1 addition & 2 deletions Package.resolved

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ let package = Package(
.macOS(.v12)
],
dependencies: [
.package(url: "https://github.com/apple/swift-experimental-string-processing.git", branch: "main"),
.package(url: "https://github.com/apple/swift-experimental-string-processing.git", branch: "cff565f296580bbb966bb7e35b65e9a8e184abbb"),
.package(url: "https://github.com/apple/swift-syntax", branch: "main"),
.package(url: "https://github.com/vapor/vapor.git", from: "4.65.0"),
.package(url: "https://github.com/vapor/leaf.git", from: "4.2.0"),
Expand Down
4 changes: 2 additions & 2 deletions Public/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { MatchInfoView } from "./views/match_info_view";

import { DSLHighlighter } from "./views/dsl_highlighter";

import { Runner } from "./runner";
import { WasmRunner } from "./wasm_runner";

export class App {
constructor() {
Expand Down Expand Up @@ -81,7 +81,7 @@ export class App {
this.onDSLEditorChange();
});

this.runner = new Runner();
this.runner = new WasmRunner();
this.runner.onready = this.onRunnerReady.bind(this);
this.runner.onresponse = this.onRunnerResponse.bind(this);

Expand Down
120 changes: 120 additions & 0 deletions Public/js/wasm_runner.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
"use strict";

import { Runner } from "./runner";
import { WASI } from "@wasmer/wasi";
import { WasmFs } from "@wasmer/wasmfs";

class WASICommand {
constructor(wasmModule) {
this.wasmModule = wasmModule;
}

static async load(wasmFile) {
const response = await fetch(wasmFile)
if (WebAssembly.compileStreaming) {
const wasmModule = await WebAssembly.compileStreaming(response);
return new WASICommand(wasmModule);
} else {
const bytes = await response.arrayBuffer();
const wasmModule = await WebAssembly.compile(bytes);
return new WASICommand(wasmModule);
}
}

async exec(args) {
const wasmFs = new WasmFs();
let stdout = "";
let stderr = "";
const originalWriteSync = wasmFs.fs.writeSync;
wasmFs.fs.writeSync = (fd, buffer, offset, length, position) => {
const text = new TextDecoder("utf-8").decode(buffer);
switch (fd) {
case 1:
stdout += text;
break;
case 2:
stderr += text;
console.error(text);
break;
}
return originalWriteSync(fd, buffer, offset, length, position);
};

const wrapWASI = (wasiObject) => {
// PATCH: @wasmer-js/wasi@0.x forgets to call `refreshMemory` in `clock_res_get`,
// See also https://github.com/swiftwasm/carton/blob/2c5cf34e0cbb6a4807445ef62a8404bac40314b1/entrypoint/common.js#L135-L145
const original_clock_res_get = wasiObject.wasiImport["clock_res_get"];

wasiObject.wasiImport["clock_res_get"] = (clockId, resolution) => {
wasiObject.refreshMemory();
return original_clock_res_get(clockId, resolution);
};
return wasiObject.wasiImport;
};
const wasi = new WASI({
args: ["main.wasm", ...args],
bindings: {
...WASI.defaultBindings,
fs: wasmFs.fs,
},
});
const instance = await WebAssembly.instantiate(this.wasmModule, {
wasi_snapshot_preview1: wrapWASI(wasi),
});
wasi.start(instance);
return { stdout, stderr };
}
}

export class WasmRunner extends Runner {
constructor() {
super();

this.locallyAvailableMethods = {
"parseDSL": {
command: WASICommand.load("./DSLParser.wasm"),
async run(request, command) {
const { stdout, stderr } = await command.exec([request.pattern])
return { method: request.method, result: stdout, error: stderr };
}
},
"convertToDSL": {
command: WASICommand.load("./DSLConverter.wasm"),
async run(request, command) {
const { stdout, stderr } = await command.exec([request.pattern])
return { method: request.method, result: stdout, error: stderr };
}
},
"match": {
command: WASICommand.load("./Matcher.wasm"),
async run(request, command) {
const { stdout, stderr } = await command.exec([request.pattern, request.text, request.matchOptions.join(",")])
return { method: request.method, result: stdout, error: stderr };
}
},
"parseExpression": {
command: WASICommand.load("./ExpressionParser.wasm"),
async run(request, command) {
const { stdout, stderr } = await command.exec([request.pattern, request.matchOptions.join(",")])
return { method: request.method, result: stdout, error: stderr };
}
},
}
}
async run(request) {
if (this.locallyAvailableMethods[request.method]) {
try {
const method = this.locallyAvailableMethods[request.method];
const command = await method.command;
const response = await method.run(request, command);
console.log(response);
this.onresponse(response);
} catch (e) {
console.warn(`Error while running ${request.method} on local. Retry on backend:`, e);
super.run(request);
}
return;
}
super.run(request);
}
}
19 changes: 19 additions & 0 deletions Scripts/build-wasm.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
set -eu

SWIFTWASM_TOOLCHAIN="${SWIFTWASM_TOOLCHAIN:?"Install SwiftWasm toolchain snapshot https://github.com/swiftwasm/swift/releases/tag/swift-wasm-5.7-SNAPSHOT-2022-06-25-a"}"

for product in "DSLParser" "DSLConverter" "Matcher" "ExpressionParser"; do
echo "Building ${product} for WebAssembly..."
# WORKAROUND: --disable-dead-strip is required to avoid using --gc-sections in linking
# since wasm-ld doesn't support retaining dynamically referenced data segment yet
# See also:
# * https://github.com/llvm/llvm-project/issues/55839
# * https://github.com/apple/swift-package-manager/pull/4135
$SWIFTWASM_TOOLCHAIN/usr/bin/swift build \
--triple wasm32-unknown-wasi \
--scratch-path .build/wasm \
--configuration release \
-Xswiftc -enable-testing \
--disable-dead-strip \
--product "$product"
done
Loading