From c7941d027be068f6e563a17e882232580fe15334 Mon Sep 17 00:00:00 2001 From: nsfisis Date: Fri, 5 Sep 2025 20:12:41 +0900 Subject: feat(worker): move directory worker/ to worker/php/ --- backend/taskqueue/processor.go | 2 +- compose.local.yaml | 4 +- compose.prod.yaml | 4 +- worker/.dockerignore | 1 - worker/.gitignore | 2 - worker/Dockerfile | 82 ----------------- worker/biome.json | 30 ------ worker/exec.mjs | 85 ----------------- worker/index.mjs | 39 -------- worker/package-lock.json | 202 ----------------------------------------- worker/package.json | 17 ---- worker/php-wasm.c | 22 ----- worker/php/.dockerignore | 1 + worker/php/.gitignore | 2 + worker/php/Dockerfile | 82 +++++++++++++++++ worker/php/biome.json | 30 ++++++ worker/php/exec.mjs | 85 +++++++++++++++++ worker/php/index.mjs | 39 ++++++++ worker/php/package-lock.json | 202 +++++++++++++++++++++++++++++++++++++++++ worker/php/package.json | 17 ++++ worker/php/php-wasm.c | 22 +++++ 21 files changed, 485 insertions(+), 485 deletions(-) delete mode 100644 worker/.dockerignore delete mode 100644 worker/.gitignore delete mode 100644 worker/Dockerfile delete mode 100644 worker/biome.json delete mode 100644 worker/exec.mjs delete mode 100644 worker/index.mjs delete mode 100644 worker/package-lock.json delete mode 100644 worker/package.json delete mode 100644 worker/php-wasm.c create mode 100644 worker/php/.dockerignore create mode 100644 worker/php/.gitignore create mode 100644 worker/php/Dockerfile create mode 100644 worker/php/biome.json create mode 100644 worker/php/exec.mjs create mode 100644 worker/php/index.mjs create mode 100644 worker/php/package-lock.json create mode 100644 worker/php/package.json create mode 100644 worker/php/php-wasm.c diff --git a/backend/taskqueue/processor.go b/backend/taskqueue/processor.go index 0dfaf68..42714f5 100644 --- a/backend/taskqueue/processor.go +++ b/backend/taskqueue/processor.go @@ -39,7 +39,7 @@ func (p *processor) doProcessTaskRunTestcase( if err != nil { return nil, fmt.Errorf("json.Marshal failed: %v", err) } - req, err := http.NewRequest("POST", "http://worker:80/exec", bytes.NewBuffer(reqJSON)) + req, err := http.NewRequest("POST", "http://worker-php:80/exec", bytes.NewBuffer(reqJSON)) if err != nil { return nil, fmt.Errorf("http.NewRequest failed: %v", err) } diff --git a/compose.local.yaml b/compose.local.yaml index ed7be03..c6fdf72 100644 --- a/compose.local.yaml +++ b/compose.local.yaml @@ -49,9 +49,9 @@ services: retries: 5 restart: always - worker: + worker-php: build: - context: ./worker + context: ./worker/php expose: - 80 env_file: [.env] diff --git a/compose.prod.yaml b/compose.prod.yaml index 86d4c1c..093abca 100644 --- a/compose.prod.yaml +++ b/compose.prod.yaml @@ -71,9 +71,9 @@ services: retries: 5 restart: always - worker: + worker-php: build: - context: ./worker + context: ./worker/php expose: - 80 env_file: [.env] diff --git a/worker/.dockerignore b/worker/.dockerignore deleted file mode 100644 index 07e6e47..0000000 --- a/worker/.dockerignore +++ /dev/null @@ -1 +0,0 @@ -/node_modules diff --git a/worker/.gitignore b/worker/.gitignore deleted file mode 100644 index 89c10d6..0000000 --- a/worker/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/lib/php-wasm.* -/node_modules diff --git a/worker/Dockerfile b/worker/Dockerfile deleted file mode 100644 index 18e715b..0000000 --- a/worker/Dockerfile +++ /dev/null @@ -1,82 +0,0 @@ -FROM emscripten/emsdk:3.1.74 AS wasm-builder - -RUN git clone --depth=1 --branch=php-8.4.4 https://github.com/php/php-src - -RUN apt-get update && \ - apt-get install -y --no-install-recommends \ - autoconf \ - bison \ - pkg-config \ - re2c \ - && \ - : - -# Define ZEND_MM_ERROR=0 for suppressing munmap() errors. -RUN cd php-src && \ - ./buildconf --force && \ - emconfigure ./configure \ - --disable-all \ - --disable-mbregex \ - --disable-fiber-asm \ - --disable-cli \ - --disable-cgi \ - --disable-phpdbg \ - --enable-embed=static \ - --enable-short-tags \ - --enable-mbstring \ - --without-iconv \ - --without-libxml \ - --without-pcre-jit \ - --without-pdo-sqlite \ - --without-sqlite3 \ - && \ - EMCC_CFLAGS='-s ERROR_ON_UNDEFINED_SYMBOLS=0 -D ZEND_MM_ERROR=0' emmake make -j$(nproc) && \ - mv libs/libphp.a .. && \ - make clean && \ - git clean -fd && \ - : - -COPY php-wasm.c /src/ - -RUN cd php-src && \ - emcc \ - -c \ - -o php-wasm.o \ - -I . \ - -I TSRM \ - -I Zend \ - -I main \ - ../php-wasm.c \ - && \ - mv php-wasm.o .. && \ - make clean && \ - git clean -fd && \ - : - -RUN emcc \ - -s ENVIRONMENT=node \ - -s ERROR_ON_UNDEFINED_SYMBOLS=0 \ - -s EXPORTED_RUNTIME_METHODS='["ccall"]' \ - -s EXPORT_ES6=1 \ - -s INITIAL_MEMORY=16777216 \ - -s INVOKE_RUN=0 \ - -s MODULARIZE=1 \ - -o php-wasm.js \ - php-wasm.o \ - libphp.a \ - ; - -FROM node:22.14 - -WORKDIR /app -ENV NODE_ENV=production - -COPY --from=wasm-builder /src/php-wasm.js /src/php-wasm.wasm /app/ -COPY package.json package-lock.json /app/ - -RUN npm install - -COPY index.mjs exec.mjs /app/ - -ENTRYPOINT ["node", "index.mjs"] -EXPOSE 80 diff --git a/worker/biome.json b/worker/biome.json deleted file mode 100644 index 2eb0751..0000000 --- a/worker/biome.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json", - "vcs": { - "enabled": false, - "clientKind": "git", - "useIgnoreFile": false - }, - "files": { - "ignoreUnknown": false, - "ignore": [] - }, - "formatter": { - "enabled": true, - "indentStyle": "tab" - }, - "organizeImports": { - "enabled": true - }, - "linter": { - "enabled": true, - "rules": { - "recommended": true - } - }, - "javascript": { - "formatter": { - "quoteStyle": "double" - } - } -} diff --git a/worker/exec.mjs b/worker/exec.mjs deleted file mode 100644 index d8ca899..0000000 --- a/worker/exec.mjs +++ /dev/null @@ -1,85 +0,0 @@ -import PHPWasm from "./php-wasm.js"; - -process.once("message", async ({ code: originalCode, input }) => { - const PRELUDE = ` - define('STDIN', fopen('php://stdin', 'r')); - define('STDOUT', fopen('php://stdout', 'r')); - define('STDERR', fopen('php://stderr', 'r')); - - error_reporting(E_ALL & ~E_WARNING & ~E_NOTICE & ~E_DEPRECATED); - - `; - - // remove php tag - let code; - if (originalCode.startsWith(" { - if (stdinBuf.length <= stdinPos) { - return null; - } - return stdinBuf.readUInt8(stdinPos++); - }, - stdout: (asciiCode) => { - if (asciiCode === null) { - return; // flush - } - if (BUFFER_MAX <= stdoutPos) { - return; // ignore - } - stdoutBuf.writeUInt8( - asciiCode < 0 ? asciiCode + 256 : asciiCode, - stdoutPos++, - ); - }, - stderr: (asciiCode) => { - if (asciiCode === null) { - return; // flush - } - if (BUFFER_MAX <= stderrPos) { - return; // ignore - } - stderrBuf.writeUInt8( - asciiCode < 0 ? asciiCode + 256 : asciiCode, - stderrPos++, - ); - }, - }); - - let err; - let result; - try { - result = ccall("php_wasm_run", "number", ["string"], [code]); - } catch (e) { - err = e; - } - if (err) { - process.send({ - status: "runtime_error", - stdout: stdoutBuf.subarray(0, stdoutPos).toString(), - stderr: `${stderrBuf.subarray(0, stderrPos).toString()}\n${err.toString()}`, - }); - } else { - process.send({ - status: result === 0 ? "success" : "runtime_error", - stdout: stdoutBuf.subarray(0, stdoutPos).toString(), - stderr: stderrBuf.subarray(0, stderrPos).toString(), - }); - } -}); diff --git a/worker/index.mjs b/worker/index.mjs deleted file mode 100644 index 9950ffa..0000000 --- a/worker/index.mjs +++ /dev/null @@ -1,39 +0,0 @@ -import { fork } from "node:child_process"; -import { serve } from "@hono/node-server"; -import { Hono } from "hono"; - -const execPhp = (code, input, timeoutMsec) => { - return new Promise((resolve, _reject) => { - const proc = fork("./exec.mjs"); - - proc.send({ code, input }); - - proc.on("message", (result) => { - resolve(result); - proc.kill(); - }); - - setTimeout(() => { - resolve({ - status: "timeout", - stdout: "", - stderr: `Time Limit Exceeded: ${timeoutMsec} msec`, - }); - proc.kill(); - }, timeoutMsec); - }); -}; - -const app = new Hono(); - -app.post("/exec", async (c) => { - console.log("worker/exec"); - const { code, stdin, max_duration_ms } = await c.req.json(); - const result = await execPhp(code, stdin, max_duration_ms); - return c.json(result); -}); - -serve({ - fetch: app.fetch, - port: 80, -}); diff --git a/worker/package-lock.json b/worker/package-lock.json deleted file mode 100644 index d682e43..0000000 --- a/worker/package-lock.json +++ /dev/null @@ -1,202 +0,0 @@ -{ - "name": "iosdc-japan-2025-albatross-worker", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "iosdc-japan-2025-albatross-worker", - "dependencies": { - "@hono/node-server": "^1.13.8", - "hono": "^4.7.4" - }, - "devDependencies": { - "@biomejs/biome": "^1.9.4" - } - }, - "node_modules/@biomejs/biome": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-1.9.4.tgz", - "integrity": "sha512-1rkd7G70+o9KkTn5KLmDYXihGoTaIGO9PIIN2ZB7UJxFrWw04CZHPYiMRjYsaDvVV7hP1dYNRLxSANLaBFGpog==", - "dev": true, - "hasInstallScript": true, - "license": "MIT OR Apache-2.0", - "bin": { - "biome": "bin/biome" - }, - "engines": { - "node": ">=14.21.3" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/biome" - }, - "optionalDependencies": { - "@biomejs/cli-darwin-arm64": "1.9.4", - "@biomejs/cli-darwin-x64": "1.9.4", - "@biomejs/cli-linux-arm64": "1.9.4", - "@biomejs/cli-linux-arm64-musl": "1.9.4", - "@biomejs/cli-linux-x64": "1.9.4", - "@biomejs/cli-linux-x64-musl": "1.9.4", - "@biomejs/cli-win32-arm64": "1.9.4", - "@biomejs/cli-win32-x64": "1.9.4" - } - }, - "node_modules/@biomejs/cli-darwin-arm64": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-1.9.4.tgz", - "integrity": "sha512-bFBsPWrNvkdKrNCYeAp+xo2HecOGPAy9WyNyB/jKnnedgzl4W4Hb9ZMzYNbf8dMCGmUdSavlYHiR01QaYR58cw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT OR Apache-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=14.21.3" - } - }, - "node_modules/@biomejs/cli-darwin-x64": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-1.9.4.tgz", - "integrity": "sha512-ngYBh/+bEedqkSevPVhLP4QfVPCpb+4BBe2p7Xs32dBgs7rh9nY2AIYUL6BgLw1JVXV8GlpKmb/hNiuIxfPfZg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT OR Apache-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=14.21.3" - } - }, - "node_modules/@biomejs/cli-linux-arm64": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-1.9.4.tgz", - "integrity": "sha512-fJIW0+LYujdjUgJJuwesP4EjIBl/N/TcOX3IvIHJQNsAqvV2CHIogsmA94BPG6jZATS4Hi+xv4SkBBQSt1N4/g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT OR Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=14.21.3" - } - }, - "node_modules/@biomejs/cli-linux-arm64-musl": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-1.9.4.tgz", - "integrity": "sha512-v665Ct9WCRjGa8+kTr0CzApU0+XXtRgwmzIf1SeKSGAv+2scAlW6JR5PMFo6FzqqZ64Po79cKODKf3/AAmECqA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT OR Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=14.21.3" - } - }, - "node_modules/@biomejs/cli-linux-x64": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-1.9.4.tgz", - "integrity": "sha512-lRCJv/Vi3Vlwmbd6K+oQ0KhLHMAysN8lXoCI7XeHlxaajk06u7G+UsFSO01NAs5iYuWKmVZjmiOzJ0OJmGsMwg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT OR Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=14.21.3" - } - }, - "node_modules/@biomejs/cli-linux-x64-musl": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-1.9.4.tgz", - "integrity": "sha512-gEhi/jSBhZ2m6wjV530Yy8+fNqG8PAinM3oV7CyO+6c3CEh16Eizm21uHVsyVBEB6RIM8JHIl6AGYCv6Q6Q9Tg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT OR Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=14.21.3" - } - }, - "node_modules/@biomejs/cli-win32-arm64": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-1.9.4.tgz", - "integrity": "sha512-tlbhLk+WXZmgwoIKwHIHEBZUwxml7bRJgk0X2sPyNR3S93cdRq6XulAZRQJ17FYGGzWne0fgrXBKpl7l4M87Hg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT OR Apache-2.0", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=14.21.3" - } - }, - "node_modules/@biomejs/cli-win32-x64": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-1.9.4.tgz", - "integrity": "sha512-8Y5wMhVIPaWe6jw2H+KlEm4wP/f7EW3810ZLmDlrEEy5KvBsb9ECEfu/kMWD484ijfQ8+nIi0giMgu9g1UAuuA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT OR Apache-2.0", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=14.21.3" - } - }, - "node_modules/@hono/node-server": { - "version": "1.13.8", - "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.13.8.tgz", - "integrity": "sha512-fsn8ucecsAXUoVxrUil0m13kOEq4mkX4/4QozCqmY+HpGfKl74OYSn8JcMA8GnG0ClfdRI4/ZSeG7zhFaVg+wg==", - "license": "MIT", - "engines": { - "node": ">=18.14.1" - }, - "peerDependencies": { - "hono": "^4" - } - }, - "node_modules/hono": { - "version": "4.7.4", - "resolved": "https://registry.npmjs.org/hono/-/hono-4.7.4.tgz", - "integrity": "sha512-Pst8FuGqz3L7tFF+u9Pu70eI0xa5S3LPUmrNd5Jm8nTHze9FxLTK9Kaj5g/k4UcwuJSXTP65SyHOPLrffpcAJg==", - "license": "MIT", - "engines": { - "node": ">=16.9.0" - } - } - } -} diff --git a/worker/package.json b/worker/package.json deleted file mode 100644 index c1b0569..0000000 --- a/worker/package.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "name": "iosdc-japan-2025-albatross-worker", - "private": true, - "type": "module", - "main": "index.mjs", - "scripts": { - "check": "npm run check:biome", - "check:biome": "biome check --write" - }, - "devDependencies": { - "@biomejs/biome": "^1.9.4" - }, - "dependencies": { - "@hono/node-server": "^1.13.8", - "hono": "^4.7.4" - } -} diff --git a/worker/php-wasm.c b/worker/php-wasm.c deleted file mode 100644 index 9c71ca1..0000000 --- a/worker/php-wasm.c +++ /dev/null @@ -1,22 +0,0 @@ -#include -#include -#include -#include - -int EMSCRIPTEN_KEEPALIVE php_wasm_run(const char* code) { - zend_result result; - - int argc = 1; - char* argv[] = { "php.wasm", NULL }; - - PHP_EMBED_START_BLOCK(argc, argv); - - result = zend_eval_string_ex(code, NULL, "php.wasm code", 1); - - PHP_EMBED_END_BLOCK(); - - fflush(stdout); - fflush(stderr); - - return result == SUCCESS ? 0 : 1; -} diff --git a/worker/php/.dockerignore b/worker/php/.dockerignore new file mode 100644 index 0000000..07e6e47 --- /dev/null +++ b/worker/php/.dockerignore @@ -0,0 +1 @@ +/node_modules diff --git a/worker/php/.gitignore b/worker/php/.gitignore new file mode 100644 index 0000000..89c10d6 --- /dev/null +++ b/worker/php/.gitignore @@ -0,0 +1,2 @@ +/lib/php-wasm.* +/node_modules diff --git a/worker/php/Dockerfile b/worker/php/Dockerfile new file mode 100644 index 0000000..18e715b --- /dev/null +++ b/worker/php/Dockerfile @@ -0,0 +1,82 @@ +FROM emscripten/emsdk:3.1.74 AS wasm-builder + +RUN git clone --depth=1 --branch=php-8.4.4 https://github.com/php/php-src + +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + autoconf \ + bison \ + pkg-config \ + re2c \ + && \ + : + +# Define ZEND_MM_ERROR=0 for suppressing munmap() errors. +RUN cd php-src && \ + ./buildconf --force && \ + emconfigure ./configure \ + --disable-all \ + --disable-mbregex \ + --disable-fiber-asm \ + --disable-cli \ + --disable-cgi \ + --disable-phpdbg \ + --enable-embed=static \ + --enable-short-tags \ + --enable-mbstring \ + --without-iconv \ + --without-libxml \ + --without-pcre-jit \ + --without-pdo-sqlite \ + --without-sqlite3 \ + && \ + EMCC_CFLAGS='-s ERROR_ON_UNDEFINED_SYMBOLS=0 -D ZEND_MM_ERROR=0' emmake make -j$(nproc) && \ + mv libs/libphp.a .. && \ + make clean && \ + git clean -fd && \ + : + +COPY php-wasm.c /src/ + +RUN cd php-src && \ + emcc \ + -c \ + -o php-wasm.o \ + -I . \ + -I TSRM \ + -I Zend \ + -I main \ + ../php-wasm.c \ + && \ + mv php-wasm.o .. && \ + make clean && \ + git clean -fd && \ + : + +RUN emcc \ + -s ENVIRONMENT=node \ + -s ERROR_ON_UNDEFINED_SYMBOLS=0 \ + -s EXPORTED_RUNTIME_METHODS='["ccall"]' \ + -s EXPORT_ES6=1 \ + -s INITIAL_MEMORY=16777216 \ + -s INVOKE_RUN=0 \ + -s MODULARIZE=1 \ + -o php-wasm.js \ + php-wasm.o \ + libphp.a \ + ; + +FROM node:22.14 + +WORKDIR /app +ENV NODE_ENV=production + +COPY --from=wasm-builder /src/php-wasm.js /src/php-wasm.wasm /app/ +COPY package.json package-lock.json /app/ + +RUN npm install + +COPY index.mjs exec.mjs /app/ + +ENTRYPOINT ["node", "index.mjs"] +EXPOSE 80 diff --git a/worker/php/biome.json b/worker/php/biome.json new file mode 100644 index 0000000..2eb0751 --- /dev/null +++ b/worker/php/biome.json @@ -0,0 +1,30 @@ +{ + "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json", + "vcs": { + "enabled": false, + "clientKind": "git", + "useIgnoreFile": false + }, + "files": { + "ignoreUnknown": false, + "ignore": [] + }, + "formatter": { + "enabled": true, + "indentStyle": "tab" + }, + "organizeImports": { + "enabled": true + }, + "linter": { + "enabled": true, + "rules": { + "recommended": true + } + }, + "javascript": { + "formatter": { + "quoteStyle": "double" + } + } +} diff --git a/worker/php/exec.mjs b/worker/php/exec.mjs new file mode 100644 index 0000000..d8ca899 --- /dev/null +++ b/worker/php/exec.mjs @@ -0,0 +1,85 @@ +import PHPWasm from "./php-wasm.js"; + +process.once("message", async ({ code: originalCode, input }) => { + const PRELUDE = ` + define('STDIN', fopen('php://stdin', 'r')); + define('STDOUT', fopen('php://stdout', 'r')); + define('STDERR', fopen('php://stderr', 'r')); + + error_reporting(E_ALL & ~E_WARNING & ~E_NOTICE & ~E_DEPRECATED); + + `; + + // remove php tag + let code; + if (originalCode.startsWith(" { + if (stdinBuf.length <= stdinPos) { + return null; + } + return stdinBuf.readUInt8(stdinPos++); + }, + stdout: (asciiCode) => { + if (asciiCode === null) { + return; // flush + } + if (BUFFER_MAX <= stdoutPos) { + return; // ignore + } + stdoutBuf.writeUInt8( + asciiCode < 0 ? asciiCode + 256 : asciiCode, + stdoutPos++, + ); + }, + stderr: (asciiCode) => { + if (asciiCode === null) { + return; // flush + } + if (BUFFER_MAX <= stderrPos) { + return; // ignore + } + stderrBuf.writeUInt8( + asciiCode < 0 ? asciiCode + 256 : asciiCode, + stderrPos++, + ); + }, + }); + + let err; + let result; + try { + result = ccall("php_wasm_run", "number", ["string"], [code]); + } catch (e) { + err = e; + } + if (err) { + process.send({ + status: "runtime_error", + stdout: stdoutBuf.subarray(0, stdoutPos).toString(), + stderr: `${stderrBuf.subarray(0, stderrPos).toString()}\n${err.toString()}`, + }); + } else { + process.send({ + status: result === 0 ? "success" : "runtime_error", + stdout: stdoutBuf.subarray(0, stdoutPos).toString(), + stderr: stderrBuf.subarray(0, stderrPos).toString(), + }); + } +}); diff --git a/worker/php/index.mjs b/worker/php/index.mjs new file mode 100644 index 0000000..9950ffa --- /dev/null +++ b/worker/php/index.mjs @@ -0,0 +1,39 @@ +import { fork } from "node:child_process"; +import { serve } from "@hono/node-server"; +import { Hono } from "hono"; + +const execPhp = (code, input, timeoutMsec) => { + return new Promise((resolve, _reject) => { + const proc = fork("./exec.mjs"); + + proc.send({ code, input }); + + proc.on("message", (result) => { + resolve(result); + proc.kill(); + }); + + setTimeout(() => { + resolve({ + status: "timeout", + stdout: "", + stderr: `Time Limit Exceeded: ${timeoutMsec} msec`, + }); + proc.kill(); + }, timeoutMsec); + }); +}; + +const app = new Hono(); + +app.post("/exec", async (c) => { + console.log("worker/exec"); + const { code, stdin, max_duration_ms } = await c.req.json(); + const result = await execPhp(code, stdin, max_duration_ms); + return c.json(result); +}); + +serve({ + fetch: app.fetch, + port: 80, +}); diff --git a/worker/php/package-lock.json b/worker/php/package-lock.json new file mode 100644 index 0000000..d682e43 --- /dev/null +++ b/worker/php/package-lock.json @@ -0,0 +1,202 @@ +{ + "name": "iosdc-japan-2025-albatross-worker", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "iosdc-japan-2025-albatross-worker", + "dependencies": { + "@hono/node-server": "^1.13.8", + "hono": "^4.7.4" + }, + "devDependencies": { + "@biomejs/biome": "^1.9.4" + } + }, + "node_modules/@biomejs/biome": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-1.9.4.tgz", + "integrity": "sha512-1rkd7G70+o9KkTn5KLmDYXihGoTaIGO9PIIN2ZB7UJxFrWw04CZHPYiMRjYsaDvVV7hP1dYNRLxSANLaBFGpog==", + "dev": true, + "hasInstallScript": true, + "license": "MIT OR Apache-2.0", + "bin": { + "biome": "bin/biome" + }, + "engines": { + "node": ">=14.21.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/biome" + }, + "optionalDependencies": { + "@biomejs/cli-darwin-arm64": "1.9.4", + "@biomejs/cli-darwin-x64": "1.9.4", + "@biomejs/cli-linux-arm64": "1.9.4", + "@biomejs/cli-linux-arm64-musl": "1.9.4", + "@biomejs/cli-linux-x64": "1.9.4", + "@biomejs/cli-linux-x64-musl": "1.9.4", + "@biomejs/cli-win32-arm64": "1.9.4", + "@biomejs/cli-win32-x64": "1.9.4" + } + }, + "node_modules/@biomejs/cli-darwin-arm64": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-1.9.4.tgz", + "integrity": "sha512-bFBsPWrNvkdKrNCYeAp+xo2HecOGPAy9WyNyB/jKnnedgzl4W4Hb9ZMzYNbf8dMCGmUdSavlYHiR01QaYR58cw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-darwin-x64": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-1.9.4.tgz", + "integrity": "sha512-ngYBh/+bEedqkSevPVhLP4QfVPCpb+4BBe2p7Xs32dBgs7rh9nY2AIYUL6BgLw1JVXV8GlpKmb/hNiuIxfPfZg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-arm64": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-1.9.4.tgz", + "integrity": "sha512-fJIW0+LYujdjUgJJuwesP4EjIBl/N/TcOX3IvIHJQNsAqvV2CHIogsmA94BPG6jZATS4Hi+xv4SkBBQSt1N4/g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-arm64-musl": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-1.9.4.tgz", + "integrity": "sha512-v665Ct9WCRjGa8+kTr0CzApU0+XXtRgwmzIf1SeKSGAv+2scAlW6JR5PMFo6FzqqZ64Po79cKODKf3/AAmECqA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-x64": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-1.9.4.tgz", + "integrity": "sha512-lRCJv/Vi3Vlwmbd6K+oQ0KhLHMAysN8lXoCI7XeHlxaajk06u7G+UsFSO01NAs5iYuWKmVZjmiOzJ0OJmGsMwg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-x64-musl": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-1.9.4.tgz", + "integrity": "sha512-gEhi/jSBhZ2m6wjV530Yy8+fNqG8PAinM3oV7CyO+6c3CEh16Eizm21uHVsyVBEB6RIM8JHIl6AGYCv6Q6Q9Tg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-win32-arm64": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-1.9.4.tgz", + "integrity": "sha512-tlbhLk+WXZmgwoIKwHIHEBZUwxml7bRJgk0X2sPyNR3S93cdRq6XulAZRQJ17FYGGzWne0fgrXBKpl7l4M87Hg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-win32-x64": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-1.9.4.tgz", + "integrity": "sha512-8Y5wMhVIPaWe6jw2H+KlEm4wP/f7EW3810ZLmDlrEEy5KvBsb9ECEfu/kMWD484ijfQ8+nIi0giMgu9g1UAuuA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@hono/node-server": { + "version": "1.13.8", + "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.13.8.tgz", + "integrity": "sha512-fsn8ucecsAXUoVxrUil0m13kOEq4mkX4/4QozCqmY+HpGfKl74OYSn8JcMA8GnG0ClfdRI4/ZSeG7zhFaVg+wg==", + "license": "MIT", + "engines": { + "node": ">=18.14.1" + }, + "peerDependencies": { + "hono": "^4" + } + }, + "node_modules/hono": { + "version": "4.7.4", + "resolved": "https://registry.npmjs.org/hono/-/hono-4.7.4.tgz", + "integrity": "sha512-Pst8FuGqz3L7tFF+u9Pu70eI0xa5S3LPUmrNd5Jm8nTHze9FxLTK9Kaj5g/k4UcwuJSXTP65SyHOPLrffpcAJg==", + "license": "MIT", + "engines": { + "node": ">=16.9.0" + } + } + } +} diff --git a/worker/php/package.json b/worker/php/package.json new file mode 100644 index 0000000..c1b0569 --- /dev/null +++ b/worker/php/package.json @@ -0,0 +1,17 @@ +{ + "name": "iosdc-japan-2025-albatross-worker", + "private": true, + "type": "module", + "main": "index.mjs", + "scripts": { + "check": "npm run check:biome", + "check:biome": "biome check --write" + }, + "devDependencies": { + "@biomejs/biome": "^1.9.4" + }, + "dependencies": { + "@hono/node-server": "^1.13.8", + "hono": "^4.7.4" + } +} diff --git a/worker/php/php-wasm.c b/worker/php/php-wasm.c new file mode 100644 index 0000000..9c71ca1 --- /dev/null +++ b/worker/php/php-wasm.c @@ -0,0 +1,22 @@ +#include +#include +#include +#include + +int EMSCRIPTEN_KEEPALIVE php_wasm_run(const char* code) { + zend_result result; + + int argc = 1; + char* argv[] = { "php.wasm", NULL }; + + PHP_EMBED_START_BLOCK(argc, argv); + + result = zend_eval_string_ex(code, NULL, "php.wasm code", 1); + + PHP_EMBED_END_BLOCK(); + + fflush(stdout); + fflush(stderr); + + return result == SUCCESS ? 0 : 1; +} -- cgit v1.2.3-70-g09d2