From 2aec6c5df289df5fa2638b6145cf288669707c24 Mon Sep 17 00:00:00 2001 From: David Konsumer Date: Sat, 14 Sep 2024 17:15:55 -0700 Subject: [PATCH] starting work on assemblyscript example --- cart/as/.gitignore | 4 ++ cart/as/README.md | 5 +++ cart/as/asconfig.json | 16 ++++++++ cart/as/null0.ts | 19 ++++++++++ cart/as/package-lock.json | 57 ++++++++++++++++++++++++++++ cart/as/package.json | 20 ++++++++++ cart/as/src/assets/notnullgames.ogg | Bin 0 -> 12955 bytes cart/as/src/index.ts | 9 +++++ cart/as/src/tsconfig.json | 6 +++ null0_api/src/null0_api_wamr.h | 5 +-- 10 files changed, 138 insertions(+), 3 deletions(-) create mode 100644 cart/as/.gitignore create mode 100644 cart/as/README.md create mode 100644 cart/as/asconfig.json create mode 100644 cart/as/null0.ts create mode 100644 cart/as/package-lock.json create mode 100644 cart/as/package.json create mode 100755 cart/as/src/assets/notnullgames.ogg create mode 100644 cart/as/src/index.ts create mode 100644 cart/as/src/tsconfig.json diff --git a/cart/as/.gitignore b/cart/as/.gitignore new file mode 100644 index 0000000..1a25504 --- /dev/null +++ b/cart/as/.gitignore @@ -0,0 +1,4 @@ +.DS_Store +node_modules +build +*.log diff --git a/cart/as/README.md b/cart/as/README.md new file mode 100644 index 0000000..4040be8 --- /dev/null +++ b/cart/as/README.md @@ -0,0 +1,5 @@ +This is an example null0 cart written in [assemblyscript](https://www.assemblyscript.org/). + +## TODO + +- look into [better build](https://github.com/notnullgames/null0-ideas/blob/main/projects/assemblyscript/tools/build.mjs) diff --git a/cart/as/asconfig.json b/cart/as/asconfig.json new file mode 100644 index 0000000..b72c80b --- /dev/null +++ b/cart/as/asconfig.json @@ -0,0 +1,16 @@ +{ + "targets": { + "release": { + "outFile": "build/main.wasm", + "textFile": "build/main.wat", + "sourceMap": true, + "optimizeLevel": 3, + "shrinkLevel": 0, + "converge": false, + "noAssert": false + } + }, + "options": { + "bindings": "esm" + } +} diff --git a/cart/as/null0.ts b/cart/as/null0.ts new file mode 100644 index 0000000..2c5e7ec --- /dev/null +++ b/cart/as/null0.ts @@ -0,0 +1,19 @@ +// log a string +@external("null0", "trace") +declare function _null0_real_trace(text: ArrayBuffer): void + +// these are called by language +// https://www.assemblyscript.org/concepts.html#special-imports +// TODO: would WASI help with these? + +export function _null0_trace(message: String): void { + _null0_real_trace(String.UTF8.encode(message, true)); +} + +export function _null0_abort(message: String, fileName: String, line: u32, column: u32): void { + _null0_real_trace(String.UTF8.encode("ABORT: " + message, true)); +} + +export function _null0_seed(): f64 { + return 1.0; +} diff --git a/cart/as/package-lock.json b/cart/as/package-lock.json new file mode 100644 index 0000000..eddbf24 --- /dev/null +++ b/cart/as/package-lock.json @@ -0,0 +1,57 @@ +{ + "name": "@null0/example-as", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@null0/example-as", + "version": "0.0.0", + "license": "MIT", + "devDependencies": { + "assemblyscript": "^0.27.29" + } + }, + "node_modules/assemblyscript": { + "version": "0.27.29", + "resolved": "https://registry.npmjs.org/assemblyscript/-/assemblyscript-0.27.29.tgz", + "integrity": "sha512-pH6udb7aE2F0t6cTh+0uCepmucykhMnAmm7k0kkAU3SY7LvpIngEBZWM6p5VCguu4EpmKGwEuZpZbEXzJ/frHQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "binaryen": "116.0.0-nightly.20240114", + "long": "^5.2.1" + }, + "bin": { + "asc": "bin/asc.js", + "asinit": "bin/asinit.js" + }, + "engines": { + "node": ">=16", + "npm": ">=7" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/assemblyscript" + } + }, + "node_modules/binaryen": { + "version": "116.0.0-nightly.20240114", + "resolved": "https://registry.npmjs.org/binaryen/-/binaryen-116.0.0-nightly.20240114.tgz", + "integrity": "sha512-0GZrojJnuhoe+hiwji7QFaL3tBlJoA+KFUN7ouYSDGZLSo9CKM8swQX8n/UcbR0d1VuZKU+nhogNzv423JEu5A==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "wasm-opt": "bin/wasm-opt", + "wasm2js": "bin/wasm2js" + } + }, + "node_modules/long": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", + "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==", + "dev": true, + "license": "Apache-2.0" + } + } +} diff --git a/cart/as/package.json b/cart/as/package.json new file mode 100644 index 0000000..94e4a87 --- /dev/null +++ b/cart/as/package.json @@ -0,0 +1,20 @@ +{ + "name": "@null0/example-as", + "version": "0.0.0", + "scripts": { + "build": "asc src/index.ts --target release --use trace=_null0_trace --use abort=_null0_abort --use seed=_null0_seed --lib ./null0.ts && mkdir -p build/cart/assets && cp build/main.wasm build/cart && cp src/assets/* build/cart/assets && cd build/cart && zip -r ../example.null0 .", + "start": "../../build/host/null0 ./build/example.null0", + "prestart": "npm run build" + }, + "license": "MIT", + "devDependencies": { + "assemblyscript": "^0.27.29" + }, + "type": "module", + "exports": { + ".": { + "import": "./build/release.js", + "types": "./build/release.d.ts" + } + } +} diff --git a/cart/as/src/assets/notnullgames.ogg b/cart/as/src/assets/notnullgames.ogg new file mode 100755 index 0000000000000000000000000000000000000000..3217a6c629d107fa12fe57df41049d8f8e759ee4 GIT binary patch literal 12955 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