diff --git a/.c8rc.json b/.c8rc.json
new file mode 100644
index 0000000000..fde64f42b6
--- /dev/null
+++ b/.c8rc.json
@@ -0,0 +1,17 @@
+{
+ "reporter": ["html", "text"],
+ "reportsDirectory": "./coverage",
+ "src": ["src"],
+ "exclude": [
+ "std/**/*",
+ "tests/**/*",
+ "dist/**/*",
+ "bin/asinit.js",
+ "lib/**/*",
+ "scripts/**/*",
+ "src/glue/wasm/**/*",
+ "util/browser/**/*"
+ ],
+ "clean": true,
+ "exclude-after-remap": true
+}
diff --git a/.eslintignore b/.eslintignore
deleted file mode 100644
index 1f981fe5e5..0000000000
--- a/.eslintignore
+++ /dev/null
@@ -1,10 +0,0 @@
-dist/
-docs/
-lib/binaryen.js
-lib/parse/index.js
-out/
-raw/
-tests/parser/
-
-# FIXME: Tagged template literal tests with invalid escapes
-tests/compiler/templateliteral.ts
diff --git a/.eslintrc.js b/.eslintrc.js
deleted file mode 100644
index 2f5dadc521..0000000000
--- a/.eslintrc.js
+++ /dev/null
@@ -1,257 +0,0 @@
-module.exports = {
- root: true,
- parser: "@typescript-eslint/parser",
- plugins: [
- "@typescript-eslint",
- ],
- extends: [
- "eslint:recommended",
- "plugin:@typescript-eslint/eslint-recommended",
- "plugin:@typescript-eslint/recommended",
- ],
- parserOptions: {
- ecmaVersion: 2020,
- sourceType: "module",
- ecmaFeatures: {}
- },
- globals: {
- "BigInt64Array": "readonly",
- "BigUint64Array": "readonly",
- "__non_webpack_require__": "readonly"
- },
-
- // === General rules =========================================================
-
- rules: {
- // Omitted semicolons are hugely popular, yet within the compiler it makes
- // sense to be better safe than sorry.
- "semi": "error",
-
- // Our code bases uses 2 spaces for indentation, and we enforce it here so
- // files don't mix spaces, tabs or different indentation levels.
- "indent": ["error", 2, {
- "SwitchCase": 1,
- "VariableDeclarator": "first",
- "offsetTernaryExpressions": true,
- "ignoredNodes": [ // FIXME: something's odd here
- "ConditionalExpression > *",
- "ConditionalExpression > * > *",
- "ConditionalExpression > * > * > *"
- ]
- }],
-
- // This is mostly visual style, making comments look uniform.
- "spaced-comment": ["error", "always", {
- "markers": ["/"], // triple-slash
- "exceptions": ["/"] // all slashes
- }],
-
- // This tends to be annoying as it encourages developers to make everything
- // that is never reassigned a 'const', sometimes semantically incorrect so,
- // typically leading to huge diffs in follow-up PRs modifying affected code.
- "prefer-const": "off",
-
- // It is perfectly fine to declare top-level variables with `var`, yet this
- // rule doesn't provide configuration options that would help.
- "no-var": "off",
-
- // Quite often, dealing with multiple related cases at once or otherwise
- // falling through is exactly the point of using a switch.
- "no-fallthrough": "off",
-
- // Typical false-positives here are `do { ... } while (true)` statements or
- // similar, but the only option provided here is not checking any loops.
- "no-constant-condition": ["error", { checkLoops: false }],
-
- // Functions are nested in blocks occasionally, and there haven't been any
- // problems with this so far, so turning the check off.
- "no-inner-declarations": "off",
-
- // Quite common in scenarios where an iteration starts at `current = this`.
- "@typescript-eslint/no-this-alias": "off",
-
- // Disabled here, but enabled again for JavaScript files.
- "no-unused-vars": "off",
-
- // Disabled here, but enabled again for TypeScript files.
- "@typescript-eslint/no-unused-vars": "off"
- },
- overrides: [
-
- // === JavaScript rules ====================================================
-
- {
- env: {
- "browser": true,
- "amd": true,
- "node": true,
- "es6": true
- },
- files: [
- "**/*.js",
- "bin/*"
- ],
- rules: {
- // We are testing both ESM and UMD, so don't limit us.
- "@typescript-eslint/no-var-requires": "off",
-
- // This rule does not behave well in JS files.
- "@typescript-eslint/explicit-module-boundary-types": "off",
-
- // Enforcing to remove function parameters on stubs makes code less
- // maintainable, so we instead allow unused function parameters.
- "no-unused-vars": [
- "warn", {
- "vars": "local",
- "args": "none",
- "ignoreRestSiblings": false
- }
- ]
- }
- },
-
- // === TypeScript rules ====================================================
-
- {
- files: [
- "**/*.ts"
- ],
- rules: {
- // Enforcing to remove function parameters on stubs makes code less
- // maintainable, so we instead allow unused function parameters.
- "@typescript-eslint/no-unused-vars": [
- "warn", {
- "vars": "local",
- "varsIgnorePattern": "^[A-Z](?:From|To)?$", // ignore type params
- "args": "none",
- "ignoreRestSiblings": false
- }
- ]
- }
- },
-
- // === AssemblyScript rules (extends TypeScript rules) =====================
-
- {
- files: [
- "**/assembly/**/*.ts",
- "src/**/*.ts",
- "lib/parse/src/**/*.ts"
- ],
- rules: {
- // Namespaces are quite useful in AssemblyScript
- "@typescript-eslint/no-namespace": "off",
-
- // There is actually codegen difference here
- "@typescript-eslint/no-array-constructor": "off",
-
- // Sometimes it can't be avoided to add a @ts-ignore
- "@typescript-eslint/ban-ts-comment": "off",
-
- // Utilized to achieve portability in some cases
- "@typescript-eslint/no-non-null-assertion": "off",
- }
- },
-
- // === Compiler rules (extends AssemblyScript rules) =======================
-
- {
- files: [
- "src/**/*.ts",
- "std/assembly/**/*.ts"
- ],
- rules: {
- // There is an actual codegen difference here - TODO: revisit
- "no-cond-assign": "off",
-
- // Not all types can be omitted in AS yet - TODO: revisit
- "@typescript-eslint/no-inferrable-types": "off",
-
- // Used rarely to reference internals that are not user-visible
- "@typescript-eslint/triple-slash-reference": "off",
-
- // The compiler has its own `Function` class for example
- "no-shadow-restricted-names": "off",
- "@typescript-eslint/ban-types": "off"
- }
- },
-
- // === Standard Library rules (extends AssemblyScript rules) ===============
-
- {
- files: [
- "std/assembly/**/*.ts"
- ],
- rules: {
- // We are implementing with --noLib, so we shadow all the time
- "no-shadow-restricted-names": "off",
-
- // Similarly, sometimes we need the return type to be String, not string
- "@typescript-eslint/ban-types": "off"
- }
- },
-
- // === Standard Definition rules (extends TypeScript rules) ================
-
- {
- files: [
- "std/**/*.d.ts"
- ],
- rules: {
- // Often required to achieve compatibility with TypeScript
- "@typescript-eslint/no-explicit-any": "off",
-
- // Interfaces can be stubs here, i.e. not yet fully implemented
- "@typescript-eslint/no-empty-interface": "off",
-
- // Definitions make use of `object` to model rather unusual constraints
- "@typescript-eslint/ban-types": "off"
- }
- },
-
- // === Compiler Definition rules (extends TypeScript rules) ================
-
- {
- files: [
- "./index.d.ts",
- "./index.release.d.ts",
- ],
- rules: {
- // Our definitions are complicated, and all attempts to describe them
- // as modules have failed so far. As such, we re-export namespaces.
- "@typescript-eslint/no-namespace": "off",
- "@typescript-eslint/triple-slash-reference": "off"
- }
- },
-
- // === Test rules (extends TypeScript rules) ===============================
-
- {
- files: [
- "./tests/compiler/**/*.ts",
- "./lib/loader/tests/assembly/**/*.ts"
- ],
- rules: {
- // Tests typically include unusual code patterns on purpose. This is
- // very likely not an extensive list, but covers what's there so far.
- "no-empty": "off",
- "no-cond-assign": "off",
- "no-compare-neg-zero": "off",
- "no-inner-declarations": "off",
- "no-constant-condition": "off",
- "use-isnan": "off",
- "@typescript-eslint/no-namespace": "off",
- "@typescript-eslint/no-unused-vars": "off",
- "@typescript-eslint/no-empty-function": "off",
- "@typescript-eslint/no-non-null-assertion": "off",
- "@typescript-eslint/no-extra-semi": "off",
- "@typescript-eslint/no-inferrable-types": "off",
- "@typescript-eslint/ban-types": "off",
- "@typescript-eslint/triple-slash-reference": "off",
- "@typescript-eslint/ban-ts-comment": "off",
- "@typescript-eslint/no-extra-non-null-assertion": "off",
- "@typescript-eslint/no-empty-interface": "off"
- }
- },
- ]
-};
diff --git a/.gitattributes b/.gitattributes
index b817804567..219d8546ed 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,5 +1,6 @@
bin/* text eol=lf
dist/* binary
scripts/*.sh eol=lf
-lib/binaryen.js binary
tests/compiler/std/string-encoding.ts eol=lf
+src/bindings/js.ts eol=lf
+src/bindings/tsd.ts eol=lf
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
deleted file mode 100644
index 6ed9129c68..0000000000
--- a/.github/ISSUE_TEMPLATE.md
+++ /dev/null
@@ -1,4 +0,0 @@
-
diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml
new file mode 100644
index 0000000000..9919f1b62f
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug.yml
@@ -0,0 +1,33 @@
+name: Bug Report
+description: Encountered an issue? File a bug report!
+labels: [bug]
+body:
+ - type: markdown
+ attributes:
+ value: |
+ Thanks for taking the time to fill out this bug report! To get off to a good start, make sure to:
+ * Search if there is an existing issue on the topic
+ * Get familiar with the [contributing guidelines](https://github.com/AssemblyScript/assemblyscript/blob/main/CONTRIBUTING.md)
+ - type: textarea
+ id: description
+ attributes:
+ label: Bug description
+ description: What happened? What was the expected behavior?
+ validations:
+ required: true
+ - type: textarea
+ id: reproduction
+ attributes:
+ label: Steps to reproduce
+ description: |
+ How can the issue be reproduced? A minimum example is best. Tip: Use [code blocks](https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/creating-and-highlighting-code-blocks).
+ validations:
+ required: true
+ - type: input
+ id: version
+ attributes:
+ label: AssemblyScript version
+ description: "What's the AssemblyScript version used?"
+ placeholder: "vX.Y.Z"
+ validations:
+ required: true
diff --git a/.github/ISSUE_TEMPLATE/feature.yml b/.github/ISSUE_TEMPLATE/feature.yml
new file mode 100644
index 0000000000..15fa469b9c
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature.yml
@@ -0,0 +1,18 @@
+name: Feature suggestion
+description: Got a neat idea? File a feature suggestion!
+labels: [enhancement]
+body:
+ - type: markdown
+ attributes:
+ value: |
+ Thanks for taking the time to fill out this feature suggestion! To get off to a good start, make sure to:
+ * Search if there is an existing issue on the topic
+ * See if the feature is mentioned at [implementation status](https://www.assemblyscript.org/status.html)
+ * Get familiar with the [contributing guidelines](https://github.com/AssemblyScript/assemblyscript/blob/main/CONTRIBUTING.md)
+ - type: textarea
+ id: description
+ attributes:
+ label: Feature suggestion
+ description: Please describe the feature you'd like to suggest.
+ validations:
+ required: true
diff --git a/.github/ISSUE_TEMPLATE/question.yml b/.github/ISSUE_TEMPLATE/question.yml
new file mode 100644
index 0000000000..9975feabe7
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/question.yml
@@ -0,0 +1,17 @@
+name: Ask a question
+description: Wondering how to achieve something specific? Ask a question!
+labels: [question]
+body:
+ - type: markdown
+ attributes:
+ value: |
+ To get off to a good start, make sure to:
+ * Consider asking questions on our [community Discord](https://discord.gg/assemblyscript) instead
+ * Search if there is an existing issue on the topic
+ - type: textarea
+ id: description
+ attributes:
+ label: Question
+ description: What would you like to know?
+ validations:
+ required: true
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index ad286f4976..5abd484e8b 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -2,9 +2,12 @@
Thanks for submitting a pull request to AssemblyScript! Please take a moment to
review the contributing guidelines linked below, and confirm with an [x] 🙂
-->
+Fixes # .
+Changes proposed in this pull request:
⯈
⯈
⯈
-- [ ] I've read the contributing guidelines
\ No newline at end of file
+- [ ] I've read the contributing guidelines
+- [ ] I've added my name and email to the NOTICE file
diff --git a/.github/stale.yml b/.github/stale.yml
deleted file mode 100644
index 2ccd92d651..0000000000
--- a/.github/stale.yml
+++ /dev/null
@@ -1,18 +0,0 @@
-# Automatically close questions and other uncategorized issues on inactivity
-only: issues
-daysUntilStale: 30
-daysUntilClose: 7
-exemptLabels:
- - bug
- - enhancement
- - compatibility
-exemptProjects: true
-exemptMilestones: true
-exemptAssignees: true
-staleLabel: stale
-markComment: >
- This issue has been automatically marked as stale because it has not had
- recent activity. It will be closed if no further activity occurs. Thank you
- for your contributions.
-closeComment: false
-limitPerRun: 1
diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml
new file mode 100644
index 0000000000..9002e311df
--- /dev/null
+++ b/.github/workflows/pr.yml
@@ -0,0 +1,20 @@
+name: PR
+
+on:
+ pull_request:
+ types: [opened, edited, synchronize]
+
+jobs:
+ check-title:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Check PR Title Prefix
+ id: title-check
+ uses: actions/github-script@v9
+ with:
+ script: |
+ const prefs = ["feat", "fix", "breaking", "chore"];
+ const title = context.payload.pull_request.title.toLowerCase();
+ const hasValidPrefix = prefs.some(prefix => title.startsWith(`${prefix}:`));
+ if (!hasValidPrefix)
+ core.setFailed("PR title must start with 'feat:', 'fix:', 'breaking:' or 'chore:'");
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
index 0838ecfe30..269112457d 100644
--- a/.github/workflows/publish.yml
+++ b/.github/workflows/publish.yml
@@ -1,5 +1,8 @@
name: Publish
on:
+ # Note that the main branch will be used regardless of the branch chosen
+ # in the web interface.
+ workflow_dispatch:
schedule:
- cron: '0 0 * * *'
jobs:
@@ -7,18 +10,19 @@ jobs:
name: Packages
if: github.repository == 'AssemblyScript/assemblyscript'
runs-on: ubuntu-latest
+ permissions:
+ id-token: write
+ contents: write
steps:
- - uses: actions/checkout@v1
+ - uses: actions/checkout@v6
with:
- ref: master
- - uses: dcodeIO/setup-node-nvm@master
+ ref: main
+ fetch-depth: 0
+ - uses: actions/setup-node@v6
with:
node-version: current
- name: Install dependencies
- run: | # npm>=7 is currently broken: https://github.com/npm/cli/issues/1973
- npm -g install npm@6
- npm -v
- npm ci
+ run: npm ci
- name: Build packages
run: |
VERSION=$(npx aspublish --version)
@@ -45,8 +49,8 @@ jobs:
- name: Publish packages
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
run: |
+ node ./scripts/prepublish
if [ $(node -pe "require('./package.json').version") != "0.0.0" ]; then
npx aspublish
fi
@@ -59,3 +63,4 @@ jobs:
npm publish --access public
fi
cd ../..
+ node ./scripts/prepublish --reset
diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml
new file mode 100644
index 0000000000..9278bfd6aa
--- /dev/null
+++ b/.github/workflows/stale.yml
@@ -0,0 +1,22 @@
+name: Stale
+on:
+ schedule:
+ - cron: '30 23 * * *'
+jobs:
+ stale:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/stale@v10
+ with:
+ stale-issue-message: 'This issue has been automatically marked as stale because it has not had recent activity. It will be closed in one week if no further activity occurs. Thank you for your contributions!'
+ stale-issue-label: 'stale'
+ stale-pr-message: 'This PR has been automatically marked as stale because it has not had recent activity. It will be closed in one week if no further activity occurs. Thank you for your contributions!'
+ close-pr-message: 'This PR has been automatically closed due to lack of recent activity, but feel free to reopen it as long as you merge in the main branch afterwards.'
+ exempt-issue-labels: 'bug,enhancement,compatibility'
+ exempt-pr-labels: 'breaking change'
+ exempt-draft-pr: true
+ exempt-all-milestones: true
+ exempt-all-assignees: true
+ days-before-issue-stale: 60
+ days-before-pr-stale: 120
+ days-before-close: 7
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 44bbf8126f..f9d2f7db0a 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -2,157 +2,101 @@ name: Test
on:
push:
branches:
- - master
+ - main
pull_request:
+concurrency:
+ group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
+ cancel-in-progress: true
jobs:
check:
name: "Check"
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v1.0.0
- - name: "Check that author is present in the NOTICE file"
- if: github.event_name == 'pull_request'
- run: |
- AUTHOR=$(git log -1 --format="%aE")
- if [ -z "$AUTHOR" ]; then
- printf "\Cannot perform NOTICE check: Commit does not include an email address.\n" &&
- exit 1;
- elif ! grep -q "$AUTHOR" NOTICE || false; then
- printf "\nAuthor '$AUTHOR' does not appear to be listed in the NOTICE file, yet.\n" &&
- printf "Please see https://github.com/AssemblyScript/assemblyscript/blob/master/CONTRIBUTING.md\n" &&
- exit 1;
- else
- printf "\nOK: Author is present in the NOTICE file.\n";
- fi
+ - uses: actions/checkout@v6
- name: "Check that distribution files are unmodified"
if: github.event_name == 'pull_request'
run: |
if git --no-pager diff --name-only $(git rev-parse origin/${{ github.base_ref }})...${{ github.sha }} | grep -q "^dist/"; then
printf "\nThe pull request modifies distribution files, but it shouldn't.\n" &&
- printf "Please see https://github.com/AssemblyScript/assemblyscript/blob/master/CONTRIBUTING.md\n" &&
+ printf "Please see https://github.com/AssemblyScript/assemblyscript/blob/main/CONTRIBUTING.md\n" &&
exit 1;
else
printf "\nOK: Distributions files have not been modified.\n";
fi
- test:
- name: "Compiler (Linux, node ${{ matrix.node_version }})"
- runs-on: ubuntu-latest
+ compiler:
+ name: "Compiler (${{ matrix.os }}, node ${{ matrix.node_version }})"
+ runs-on: ${{ matrix.os }}-latest
needs: check
strategy:
matrix:
- node_version: ["current", "lts_latest"]
+ os: ["ubuntu", "macos", "windows"]
+ node_version: ["current", "lts/*"]
steps:
- - uses: actions/checkout@v1.0.0
- - uses: dcodeIO/setup-node-nvm@master
+ - uses: actions/checkout@v6
+ - uses: actions/setup-node@v6
with:
node-version: ${{ matrix.node_version }}
- name: Install dependencies
run: npm ci --no-audit
- - name: Clean distribution files
- run: npm run clean
- - name: Check sources
- run: npm run check
- - name: Test sources
- run: npm test
- - name: Build distribution files
- run: npm run build
- - name: Test distribution
- run: npm test
- - name: Test browser build
- run: node tests/browser-asc
- test-windows:
- name: "Compiler (Windows, node current)"
- runs-on: windows-latest
- needs: check
- steps:
- - uses: actions/checkout@v1.0.0
- - uses: dcodeIO/setup-node-nvm@master
- with:
- node-version: current
- - name: Install dependencies
- run: npm ci --no-audit
- - name: Clean distribution files
- run: npm run clean
- - name: Test sources
- run: npm test
- - name: Build distribution files
- run: npm run build
- - name: Test distribution
- run: npm test
- - name: Test browser build
- run: node tests/browser-asc
- test-macos:
- name: "Compiler (MacOS, node current)"
- runs-on: macos-latest
- needs: check
- steps:
- - uses: actions/checkout@v1.0.0
- - uses: dcodeIO/setup-node-nvm@master
- with:
- node-version: current
- - name: Install dependencies
- run: npm ci --no-audit
- - name: Clean distribution files
- run: npm run clean
- - name: Test sources
- run: npm test
- - name: Build distribution files
+ - name: Build
run: npm run build
- - name: Test distribution
+ - name: Check
+ run: npm run check
+ - name: Test
run: npm test
- - name: Test browser build
- run: node tests/browser-asc
- test-bootstrap:
- name: "Compiler (Bootstrap)"
+ bootstrap:
+ name: "Bootstrap (${{ matrix.target }})"
runs-on: ubuntu-latest
needs: check
+ strategy:
+ matrix:
+ target: ["debug", "release"]
steps:
- - uses: actions/checkout@v1.0.0
- - uses: dcodeIO/setup-node-nvm@master
+ - uses: actions/checkout@v6
+ - uses: actions/setup-node@v6
with:
node-version: current
- name: Install dependencies
run: npm ci --no-audit
- - name: Clean distribution files
- run: npm run clean
- - name: Bootstrap the compiler
- run: npm run bootstrap
- - name: Run compiler tests (untouched-bootstrap)
- run: npm run test:compiler -- --wasm out/assemblyscript.untouched-bootstrap.wasm
- - name: Run compiler tests (optimized-bootstrap)
- run: npm run test:compiler -- --wasm out/assemblyscript.optimized-bootstrap.wasm
- test-features:
+ - name: Build
+ run: npm run build
+ - name: "Bootstrap ${{ matrix.target }}"
+ run: npm run bootstrap:${{ matrix.target }}
+ - name: "Test ${{ matrix.target }}"
+ run: npm run test:compiler -- --wasm build/assemblyscript.${{ matrix.target }}-bootstrap.js
+ - name: "Compile ${{ matrix.target }} -> ${{ matrix.target == 'debug' && 'release' || 'debug' }}"
+ run: node bin/asc --config src/asconfig.json --target ${{ matrix.target == 'debug' && 'release' || 'debug' }}-bootstrap --wasm ./build/assemblyscript.${{ matrix.target }}-bootstrap.js
+ - name: "Test ${{ matrix.target == 'debug' && 'release' || 'debug' }}"
+ run: npm run test:compiler -- --wasm build/assemblyscript.${{ matrix.target == 'debug' && 'release' || 'debug' }}-bootstrap.js
+ features:
name: "Features"
runs-on: ubuntu-latest
needs: check
steps:
- - uses: actions/checkout@v1.0.0
- - uses: dcodeIO/setup-node-nvm@master
- with:
- node-mirror: https://nodejs.org/download/v8-canary/
- node-version: "node"
+ - uses: actions/checkout@v6
+ - uses: actions/setup-node@v6
- name: Install dependencies
run: npm ci --no-audit
- - name: Clean distribution files
- run: npm run clean
+ - name: Build
+ run: npm run build
- name: Test experimental features
env:
- ASC_FEATURES: mutable-globals,threads,reference-types,bigint-integration,gc
+ ASC_FEATURES: threads,reference-types,gc,exception-handling
run: |
- npm run test:compiler rt/flags features/js-bigint-integration features/reference-types features/threads std-wasi/process std-wasi/crypto
- test-runtimes:
+ npm run test:compiler features/threads features/reference-types features/gc features/exception-handling bindings/esm bindings/raw
+ runtimes:
name: "Runtimes"
runs-on: ubuntu-latest
needs: check
steps:
- - uses: actions/checkout@v1.0.0
- - uses: dcodeIO/setup-node-nvm@master
+ - uses: actions/checkout@v6
+ - uses: actions/setup-node@v6
with:
node-version: current
- name: Install dependencies
run: npm ci --no-audit
- - name: Clean distribution files
- run: npm run clean
+ - name: Build
+ run: npm run build
- name: Test default allocator
run: |
cd tests/allocators/default
@@ -165,21 +109,38 @@ jobs:
npm run build
cd ..
npm test stub
- test-loader:
+ loader:
name: "Loader"
runs-on: ubuntu-latest
needs: check
steps:
- - uses: actions/checkout@v1.0.0
- - uses: dcodeIO/setup-node-nvm@master
+ - uses: actions/checkout@v6
+ - uses: actions/setup-node@v6
with:
node-version: current
- name: Install dependencies
run: npm ci --no-audit
- - name: Clean distribution files
- run: npm run clean
+ - name: Build
+ run: npm run build
- name: Test the loader
run: |
cd lib/loader
npm run asbuild
npm run test
+ coverage:
+ name: "Coverage"
+ runs-on: ubuntu-latest
+ needs: check
+ steps:
+ - uses: actions/checkout@v6
+ - uses: actions/setup-node@v6
+ with:
+ node-version: 24
+ - name: Install dependencies
+ run: npm ci --no-audit
+ - name: Build
+ run: npm run build
+ - name: Collect coverage
+ run: npx c8 -r none -- npm test
+ - name: Output coverage summary
+ run: npx c8 report -r text-summary
diff --git a/.gitignore b/.gitignore
index 2efb8995ec..79bb9e71d8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,10 +1,18 @@
-npm-debug.*
-dist/
-docs/
node_modules/
-out/
+*debug.log
+build/
raw/
.history
*.backup
.vscode
.idea
+cli/index.generated.js
+src/diagnosticMessages.generated.ts
+coverage/
+
+dist/*.generated.d.ts
+dist/*.map
+dist/asc.js
+dist/assemblyscript.js
+dist/importmap.json
+dist/web.js
diff --git a/.npmrc b/.npmrc
new file mode 100644
index 0000000000..b6f27f1359
--- /dev/null
+++ b/.npmrc
@@ -0,0 +1 @@
+engine-strict=true
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
deleted file mode 100644
index 9cd16c0d9e..0000000000
--- a/CODE_OF_CONDUCT.md
+++ /dev/null
@@ -1,46 +0,0 @@
-# Contributor Covenant Code of Conduct
-
-## Our Pledge
-
-In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
-
-## Our Standards
-
-Examples of behavior that contributes to creating a positive environment include:
-
-* Using welcoming and inclusive language
-* Being respectful of differing viewpoints and experiences
-* Gracefully accepting constructive criticism
-* Focusing on what is best for the community
-* Showing empathy towards other community members
-
-Examples of unacceptable behavior by participants include:
-
-* The use of sexualized language or imagery and unwelcome sexual attention or advances
-* Trolling, insulting/derogatory comments, and personal or political attacks
-* Public or private harassment
-* Publishing others' private information, such as a physical or electronic address, without explicit permission
-* Other conduct which could reasonably be considered inappropriate in a professional setting
-
-## Our Responsibilities
-
-Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
-
-Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
-
-## Scope
-
-This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
-
-## Enforcement
-
-Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
-
-Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
-
-## Attribution
-
-This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [https://contributor-covenant.org/version/1/4][version]
-
-[homepage]: https://contributor-covenant.org
-[version]: https://contributor-covenant.org/version/1/4/
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index e903ed7941..57b2125939 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,12 +1,12 @@
Contributing
============
-The following is a set of guidelines for contributing to AssemblyScript and its packages, which are hosted in the [AsssemblyScript Organization](https://github.com/AssemblyScript) on GitHub. These are mostly guidelines, not rules. Use your best judgement, and feel free to proposse changes to this document in a pull request.
+The following is a set of guidelines for contributing to AssemblyScript and its packages, which are hosted in the [AsssemblyScript Organization](https://github.com/AssemblyScript) on GitHub. These are mostly guidelines, not rules. Use your best judgement, and feel free to propose changes to this document in a pull request.
Code of Conduct
---------------
-This project and everyone participating in it is governed by the [AssemblyScript Code of Conduct](CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code.
+This project and everyone participating in it is governed by the [AssemblyScript Code of Conduct](https://github.com/AssemblyScript/.github/blob/main/CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code.
Filing Issues
-------------
@@ -15,7 +15,7 @@ Bugs and enhancement suggestions are tracked as GitHub issues.
#### How Do I Submit A (Good) Bug Report?
-After you've determined which repository your bug is related to and that the issue is still present in the latest version of the master branch, create an issue on that repository and provide the following information:
+After you've determined which repository your bug is related to and that the issue is still present in the latest version of the main branch, create an issue on that repository and provide the following information:
* Use a **clear and descriptive title** for the issue to identify the problem.
* Explain which **behavior you expected** to see instead and why.
@@ -51,4 +51,15 @@ Before submitting your pull request, also make sure that the following condition
Please note that if a pull request is rather complicated, i.e. touches lots of internals, or became stale, it is not uncommon that a core contributor performs the final integration to get it done in good conscience while naming you as a co-author.
+Guidelines for **AI**-assisted Contributions
+--------------------------------------------
+
+**AI** tools are welcome as helpers, not authors. Keep these practices in mind:
+
+* Stay accountable: only submit changes you understand and can justify; be ready to explain behavior, edge cases. If an **AI** suggestion feels unclear, rewrite or drop it.
+* Keep humans in the loop: discuss non-trivial ideas early via [Issues](https://github.com/AssemblyScript/assemblyscript/issues) or [Discord](https://discord.gg/assemblyscript), especially when you are unsure about design or impact.
+* Use **AI** for acceleration, optimization and verification: treat **AI** output as a draft for code, tests, or docs; run linters/tests and review the logic **yourself**.
+* Be transparent in PRs: note briefly if **AI** was used and for what (e.g., initial draft, test scaffolding), and call out any parts where you want extra review.
+* Prefer small patches over large dumps; if you cannot confidently explain an **AI**-produced change, open a well-described issue instead.
+
Thank you!
diff --git a/NOTICE b/NOTICE
index 061349e4aa..da2cb563d4 100644
--- a/NOTICE
+++ b/NOTICE
@@ -38,6 +38,31 @@ under the licensing terms detailed in LICENSE:
* yjhmelody
* bnbarak
* Colin Eberhardt
+* Ryan Pivovar
+* Roman F. <70765447+romdotdog@users.noreply.github.com>
+* Joe Pea
+* Felipe Gasper
+* Congcong Cai
+* mooooooi
+* Yasushi Ando
+* Syed Jafri
+* Peter Hayman
+* ApsarasX
+* Adrien Zinger
+* Ruixiang Chen
+* Daniel Salvadori
+* Jairus Tanaka
+* CountBleck
+* Abdul Rauf
+* Bach Le
+* Xinquan Xu
+* Matt Johnson-Pint
+* Fabián Heredia Montiel
+* Jonas Minnberg
+* Kam Chehresa
+* Mopsgamer <79159094+Mopsgamer@users.noreply.github.com>
+* EDM115
+* Weixie Cui
Portions of this software are derived from third-party works licensed under
the following terms:
diff --git a/README.md b/README.md
index d3ad7b35bd..5df1fa3c5b 100644
--- a/README.md
+++ b/README.md
@@ -1,36 +1,52 @@
-
+
-
-
-
-
-
+
+
+
+
+
-
AssemblyScript compiles a strict variant of TypeScript (basically JavaScript with types) to WebAssembly using Binaryen. It generates lean and mean WebAssembly modules while being just an npm install away.
+
AssemblyScript compiles a variant of TypeScript (basically JavaScript with types) to WebAssembly using Binaryen. It generates lean and mean WebAssembly modules while being just an npm install away.
Most of the core team members and most contributors do this open source work in their free time. If you use AssemblyScript for a serious task or plan to do so, and you'd like us to invest more time on it, please donate to our OpenCollective. By sponsoring this project, your logo will show up below. Thank you so much for your support!
+
Most of the maintainers and contributors do this open source work in their free time. If you use AssemblyScript for a serious task or plan to do so, and you'd like us to invest more time on it, please donate to our OpenCollective. By sponsoring this project, your logo will show up below. Thank you so much for your support!
-
+
+
+## Development instructions
+
+A development environment can be set up by cloning the repository:
+
+```sh
+git clone https://github.com/AssemblyScript/assemblyscript.git
+cd assemblyscript
+npm install
+npm link
+```
+
+The link step is optional and makes the development instance available globally. The full process is documented as part of the repository:
+
+* [Compiler instructions](./src)
+* [Runtime instructions](./std/assembly/rt)
+* [Test instructions](./tests)
diff --git a/bin/asc b/bin/asc
deleted file mode 100755
index 0b08d513b4..0000000000
--- a/bin/asc
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/usr/bin/env node
-
-const tailArgs = process.argv.indexOf("--");
-if (~tailArgs) {
- require("child_process").spawnSync(
- process.argv[0],
- process.argv.slice(tailArgs + 1).concat(
- process.argv.slice(1, tailArgs)
- ),
- { stdio: "inherit" }
- );
- return;
-}
-
-try { require("source-map-support").install(); } catch (e) {}
-
-const asc = module.exports = require("../cli/asc.js");
-if (/\basc$/.test(process.argv[1])) {
- asc.ready.then(() => process.exitCode = asc.main(process.argv.slice(2)));
-}
diff --git a/bin/asc.js b/bin/asc.js
new file mode 100755
index 0000000000..8924e92340
--- /dev/null
+++ b/bin/asc.js
@@ -0,0 +1,35 @@
+#!/usr/bin/env node
+
+const [ nodePath, thisPath, ...args ] = process.argv;
+const nodeArgs = process.execArgv;
+
+const hasSourceMaps = nodeArgs.includes("--enable-source-maps");
+const posCustomArgs = args.indexOf("--");
+const isDeno = typeof Deno !== "undefined";
+
+if (isDeno) {
+ process.on = function() { /* suppress 'not implemented' message */ };
+}
+
+if ((!hasSourceMaps || ~posCustomArgs) && !isDeno) {
+ if (!hasSourceMaps) {
+ nodeArgs.push("--enable-source-maps");
+ }
+ if (~posCustomArgs) {
+ nodeArgs.push(...args.slice(posCustomArgs + 1));
+ args.length = posCustomArgs;
+ }
+ const { status, signal } = (await import("child_process")).spawnSync(
+ nodePath,
+ [...nodeArgs, thisPath, ...args],
+ { stdio: "inherit" }
+ );
+ if (status || signal) process.exitCode = 1;
+} else {
+ const apiResult = (await import("../dist/asc.js")).main(process.argv.slice(2), {
+ stdout: process.stdout,
+ stderr: process.stderr
+ });
+ const { error } = await apiResult;
+ if (error) process.exitCode = 1;
+}
diff --git a/bin/asinit b/bin/asinit
deleted file mode 100755
index 57bc75d9f0..0000000000
--- a/bin/asinit
+++ /dev/null
@@ -1,419 +0,0 @@
-#!/usr/bin/env node
-
-const fs = require("fs");
-const path = require("path");
-const colors = require("../cli/util/colors");
-const version = require("../package.json").version;
-const options = require("../cli/util/options");
-
-const npmDefaultTest = "echo \"Error: no test specified\" && exit 1";
-
-const commands = {
- "npm": {
- install: "npm install",
- run: "npm run",
- test: "npm test"
- },
- "yarn": {
- install: "yarn install",
- run: "yarn",
- test: "yarn test"
- },
- "pnpm": {
- install: "pnpm install",
- run: "pnpm run",
- test: "pnpm test"
- }
-};
-
-let pm = "npm";
-if (typeof process.env.npm_config_user_agent === "string") {
- if (/\byarn\//.test(process.env.npm_config_user_agent)) {
- pm = "yarn";
- } else if (/\bpnpm\//.test(process.env.npm_config_user_agent)) {
- pm = "pnpm";
- }
-}
-
-const asinitOptions = {
- "help": {
- "category": "General",
- "description": "Prints a help message.",
- "type": "b",
- "alias": "h"
- },
- "yes": {
- "category": "General",
- "description": "Answers all questions with their default option for non-interactive usage.",
- "type": "b",
- "alias": "y"
- }
-};
-
-const cliOptions = options.parse(process.argv.slice(2), asinitOptions);
-
-if (cliOptions.options.help || cliOptions.arguments.length === 0) printHelp();
-
-function printHelp() {
- console.log([
- "Sets up a new AssemblyScript project or updates an existing one.",
- "For example, to create a new project in the current directory:",
- "",
- " " + colors.cyan("asinit") + " .",
- ].join("\n"));
- process.exit(0);
-}
-
-const projectDir = path.resolve(cliOptions.arguments[0]);
-const compilerDir = path.join(__dirname, "..");
-const compilerVersion = require(path.join(compilerDir, "package.json")).version;
-const assemblyDir = path.join(projectDir, "assembly");
-const tsconfigFile = path.join(assemblyDir, "tsconfig.json");
-const asconfigFile = path.join(projectDir, "asconfig.json");
-let tsconfigBase = path.relative(assemblyDir, path.join(compilerDir, "std", "assembly.json"));
-if (/^(\.\.[/\\])*node_modules[/\\]assemblyscript[/\\]/.test(tsconfigBase)) {
- // Use node resolution if the compiler is a normal dependency
- tsconfigBase = "assemblyscript/std/assembly.json";
-}
-const entryFile = path.join(assemblyDir, "index.ts");
-const buildDir = path.join(projectDir, "build");
-const testsDir = path.join(projectDir, "tests");
-const gitignoreFile = path.join(buildDir, ".gitignore");
-const packageFile = path.join(projectDir, "package.json");
-const indexFile = path.join(projectDir, "index.js");
-const testsIndexFile = path.join(testsDir, "index.js");
-
-console.log([
- "Version: " + version,
- "",
- colors.white([
- "This command will make sure that the following files exist in the project",
- "directory '" + projectDir + "':"
- ].join("\n")),
- "",
- colors.cyan(" ./assembly"),
- " Directory holding the AssemblyScript sources being compiled to WebAssembly.",
- "",
- colors.cyan(" ./assembly/tsconfig.json"),
- " TypeScript configuration inheriting recommended AssemblyScript settings.",
- "",
- colors.cyan(" ./assembly/index.ts"),
- " Example entry file being compiled to WebAssembly to get you started.",
- "",
- colors.cyan(" ./build"),
- " Build artifact directory where compiled WebAssembly files are stored.",
- "",
- colors.cyan(" ./build/.gitignore"),
- " Git configuration that excludes compiled binaries from source control.",
- "",
- colors.cyan(" ./index.js"),
- " Main file loading the WebAssembly module and exporting its exports.",
- "",
- colors.cyan(" ./tests/index.js"),
- " Example test to check that your module is indeed working.",
- "",
- colors.cyan(" ./asconfig.json"),
- " Configuration file defining both a 'debug' and a 'release' target.",
- "",
- colors.cyan(" ./package.json"),
- " Package info containing the necessary commands to compile to WebAssembly.",
- "",
- "The command will try to update existing files to match the correct settings",
- "for this instance of the compiler in '" + compilerDir + "'.",
- ""
-].join("\n"));
-
-function createProject(answer) {
- if (!/^y?$/i.test(answer)) {
- process.exit(1);
- return;
- }
- console.log();
- ensureProjectDirectory();
- ensureAssemblyDirectory();
- ensureTsconfigJson();
- ensureEntryFile();
- ensureBuildDirectory();
- ensureGitignore();
- ensurePackageJson();
- ensureIndexJs();
- ensureTestsDirectory();
- ensureTestsIndexJs();
- ensureAsconfigJson();
- console.log([
- colors.green("Done!"),
- "",
- "Don't forget to install dependencies before you start:",
- "",
- colors.white(" " + commands[pm].install),
- "",
- "To edit the entry file, open '" + colors.cyan("assembly/index.ts") + "' in your editor of choice.",
- "Create as many additional files as necessary and use them as imports.",
- "",
- "To build the entry file to WebAssembly when you are ready, run:",
- "",
- colors.white(" " + commands[pm].run + " asbuild"),
- "",
- "Running the command above creates the following binaries incl. their respective",
- "text format representations and source maps:",
- "",
- colors.cyan(" ./build/untouched.wasm"),
- colors.cyan(" ./build/untouched.wasm.map"),
- colors.cyan(" ./build/untouched.wat"),
- "",
- " ^ The untouched WebAssembly module as generated by the compiler.",
- " This one matches your sources exactly, without any optimizations.",
- "",
- colors.cyan(" ./build/optimized.wasm"),
- colors.cyan(" ./build/optimized.wasm.map"),
- colors.cyan(" ./build/optimized.wat"),
- "",
- " ^ The optimized WebAssembly module using default optimization settings.",
- " You can change the optimization settings in '" + colors.cyan("package.json")+ "'.",
- "",
- "To run the tests, do:",
- "",
- colors.white(" " + commands[pm].test),
- "",
- "The AssemblyScript documentation covers all the details:",
- "",
- " https://docs.assemblyscript.org",
- "",
- "Have a nice day!"
- ].join("\n"));
-}
-
-if (cliOptions.options.yes) {
- createProject("y");
-} else {
- const rl = require("readline").createInterface({
- input: process.stdin,
- output: process.stdout
- });
- rl.question(colors.white("Do you want to proceed?") + " [Y/n] ", result => {
- rl.close();
- createProject(result);
- });
-}
-
-function ensureProjectDirectory() {
- console.log("- Making sure that the project directory exists...");
- if (!fs.existsSync(projectDir)) {
- fs.mkdirSync(projectDir);
- console.log(colors.green(" Created: ") + projectDir);
- } else {
- console.log(colors.yellow(" Exists: ") + projectDir);
- }
- console.log();
-}
-
-function ensureAssemblyDirectory() {
- console.log("- Making sure that the 'assembly' directory exists...");
- if (!fs.existsSync(assemblyDir)) {
- fs.mkdirSync(assemblyDir);
- console.log(colors.green(" Created: ") + assemblyDir);
- } else {
- console.log(colors.yellow(" Exists: ") + assemblyDir);
- }
- console.log();
-}
-
-function ensureTsconfigJson() {
- console.log("- Making sure that 'assembly/tsconfig.json' is set up...");
- const base = tsconfigBase.replace(/\\/g, "/");
- if (!fs.existsSync(tsconfigFile)) {
- fs.writeFileSync(tsconfigFile, JSON.stringify({
- "extends": base,
- "include": [
- "./**/*.ts"
- ]
- }, null, 2));
- console.log(colors.green(" Created: ") + tsconfigFile);
-
- } else {
- let tsconfig = JSON.parse(fs.readFileSync(tsconfigFile, "utf8"));
- tsconfig["extends"] = base;
- fs.writeFileSync(tsconfigFile, JSON.stringify(tsconfig, null, 2));
- console.log(colors.green(" Updated: ") + tsconfigFile);
- }
- console.log();
-}
-
-function ensureAsconfigJson() {
- console.log("- Making sure that 'asconfig.json' is set up...");
- if (!fs.existsSync(asconfigFile)) {
- fs.writeFileSync(asconfigFile, JSON.stringify({
- targets: {
- debug: {
- // -b build/untouched.wasm -t build/untouched.wat --sourceMap --debug
- binaryFile: "build/untouched.wasm",
- textFile: "build/untouched.wat",
- sourceMap: true,
- debug: true
- },
- release: {
- // -b build/optimized.wasm -t build/optimized.wat --sourceMap --optimize
- binaryFile: "build/optimized.wasm",
- textFile: "build/optimized.wat",
- sourceMap: true,
- optimizeLevel: 3,
- shrinkLevel: 1,
- converge: false,
- noAssert: false
- }
- },
- options: {}
- }, null, 2));
- console.log(colors.green(" Created: ") + asconfigFile);
- } else {
- console.log(colors.yellow(" Exists: ") + asconfigFile);
- }
- console.log();
-}
-
-function ensureEntryFile() {
- console.log("- Making sure that 'assembly/index.ts' exists...");
- if (!fs.existsSync(entryFile)) {
- fs.writeFileSync(entryFile, [
- "// The entry file of your WebAssembly module.",
- "",
- "export function add(a: i32, b: i32): i32 {",
- " return a + b;",
- "}"
- ].join("\n") + "\n");
- console.log(colors.green(" Created: ") + entryFile);
- } else {
- console.log(colors.yellow(" Exists: ") + entryFile);
- }
- console.log();
-}
-
-function ensureBuildDirectory() {
- console.log("- Making sure that the 'build' directory exists...");
- if (!fs.existsSync(buildDir)) {
- fs.mkdirSync(buildDir);
- console.log(colors.green(" Created: ") + buildDir);
- } else {
- console.log(colors.yellow(" Exists: ") + buildDir);
- }
- console.log();
-}
-
-function ensureGitignore() {
- console.log("- Making sure that 'build/.gitignore' is set up...");
- if (!fs.existsSync(gitignoreFile)) {
- fs.writeFileSync(gitignoreFile, [
- "*.wasm",
- "*.wasm.map",
- "*.asm.js"
- ].join("\n") + "\n");
- console.log(colors.green(" Created: ") + gitignoreFile);
- } else {
- console.log(colors.yellow(" Exists: ") + gitignoreFile);
- }
- console.log();
-}
-
-function ensurePackageJson() {
- console.log("- Making sure that 'package.json' contains the build commands...");
- const entryPath = path.relative(projectDir, entryFile).replace(/\\/g, "/");
- const buildUntouched = "asc " + entryPath + " --target debug";
- const buildOptimized = "asc " + entryPath + " --target release";
- const buildAll = commands[pm].run + " asbuild:untouched && " + commands[pm].run + " asbuild:optimized";
- if (!fs.existsSync(packageFile)) {
- fs.writeFileSync(packageFile, JSON.stringify({
- "scripts": {
- "asbuild:untouched": buildUntouched,
- "asbuild:optimized": buildOptimized,
- "asbuild": buildAll,
- "test": "node tests"
- },
- "dependencies": {
- "@assemblyscript/loader": "^" + compilerVersion
- },
- "devDependencies": {
- "assemblyscript": "^" + compilerVersion
- }
- }, null, 2));
- console.log(colors.green(" Created: ") + packageFile);
- } else {
- let pkg = JSON.parse(fs.readFileSync(packageFile));
- let scripts = pkg.scripts || {};
- let updated = false;
- if (!scripts["asbuild"]) {
- scripts["asbuild:untouched"] = buildUntouched;
- scripts["asbuild:optimized"] = buildOptimized;
- scripts["asbuild"] = buildAll;
- pkg["scripts"] = scripts;
- updated = true;
- }
- if (!scripts["test"] || scripts["test"] == npmDefaultTest) {
- scripts["test"] = "node tests";
- pkg["scripts"] = scripts;
- updated = true;
- }
- let dependencies = pkg["dependencies"] || {};
- if (!dependencies["@assemblyscript/loader"]) {
- dependencies["@assemblyscript/loader"] = "^" + compilerVersion;
- pkg["dependencies"] = dependencies;
- updated = true;
- }
- let devDependencies = pkg["devDependencies"] || {};
- if (!devDependencies["assemblyscript"]) {
- devDependencies["assemblyscript"] = "^" + compilerVersion;
- pkg["devDependencies"] = devDependencies;
- updated = true;
- }
- if (updated) {
- fs.writeFileSync(packageFile, JSON.stringify(pkg, null, 2));
- console.log(colors.green(" Updated: ") + packageFile);
- } else {
- console.log(colors.yellow(" Exists: ") + packageFile);
- }
- }
- console.log();
-}
-
-function ensureIndexJs() {
- console.log("- Making sure that 'index.js' exists...");
- if (!fs.existsSync(indexFile)) {
- fs.writeFileSync(indexFile, [
- "const fs = require(\"fs\");",
- "const loader = require(\"@assemblyscript/loader\");",
- "const imports = { /* imports go here */ };",
- "const wasmModule = loader.instantiateSync(fs.readFileSync(__dirname + \"/build/optimized.wasm\"), imports);",
- "module.exports = wasmModule.exports;"
- ].join("\n") + "\n");
- console.log(colors.green(" Created: ") + indexFile);
- } else {
- console.log(colors.yellow(" Exists: ") + indexFile);
- }
- console.log();
-}
-
-function ensureTestsDirectory() {
- console.log("- Making sure that the 'tests' directory exists...");
- if (!fs.existsSync(testsDir)) {
- fs.mkdirSync(testsDir);
- console.log(colors.green(" Created: ") + testsDir);
- } else {
- console.log(colors.yellow(" Exists: ") + testsDir);
- }
- console.log();
-}
-
-function ensureTestsIndexJs() {
- console.log("- Making sure that 'tests/index.js' exists...");
- if (!fs.existsSync(testsIndexFile)) {
- fs.writeFileSync(testsIndexFile, [
- "const assert = require(\"assert\");",
- "const myModule = require(\"..\");",
- "assert.equal(myModule.add(1, 2), 3);",
- "console.log(\"ok\");"
- ].join("\n") + "\n");
- console.log(colors.green(" Created: ") + testsIndexFile);
- } else {
- console.log(colors.yellow(" Exists: ") + testsIndexFile);
- }
- console.log();
-}
diff --git a/bin/asinit.js b/bin/asinit.js
new file mode 100755
index 0000000000..5e3566ddc1
--- /dev/null
+++ b/bin/asinit.js
@@ -0,0 +1,468 @@
+#!/usr/bin/env node
+
+import fs from "fs";
+import path from "path";
+import { createRequire } from "module";
+import { fileURLToPath } from "url";
+import { stdoutColors } from "../util/terminal.js";
+import * as optionsUtil from "../util/options.js";
+
+const dirname = path.dirname(fileURLToPath(import.meta.url));
+const require = createRequire(import.meta.url);
+const version = require("../package.json").version; // TODO
+
+const npmDefaultTest = "echo \"Error: no test specified\" && exit 1";
+
+const commands = {
+ "npm": {
+ install: "npm install",
+ run: "npm run",
+ test: "npm test"
+ },
+ "yarn": {
+ install: "yarn install",
+ run: "yarn",
+ test: "yarn test"
+ },
+ "pnpm": {
+ install: "pnpm install",
+ run: "pnpm run",
+ test: "pnpm test"
+ }
+};
+
+let pm = "npm";
+if (typeof process.env.npm_config_user_agent === "string") {
+ if (/\byarn\//.test(process.env.npm_config_user_agent)) {
+ pm = "yarn";
+ } else if (/\bpnpm\//.test(process.env.npm_config_user_agent)) {
+ pm = "pnpm";
+ }
+}
+
+const asinitOptions = {
+ "help": {
+ "category": "General",
+ "description": "Prints this help message.",
+ "type": "b",
+ "alias": "h"
+ },
+ "yes": {
+ "category": "General",
+ "description": [
+ "Answers all questions with their default option",
+ "for non-interactive usage."
+ ],
+ "type": "b",
+ "alias": "y"
+ },
+ "noColors": {
+ "description": "Disables terminal colors.",
+ "type": "b",
+ "default": false
+ },
+};
+
+const cliOptions = optionsUtil.parse(process.argv.slice(2), asinitOptions);
+
+if (cliOptions.options.noColors) {
+ stdoutColors.enabled = false;
+}
+
+if (cliOptions.options.help || cliOptions.arguments.length === 0) printHelp();
+
+function printHelp() {
+ console.log([
+ "Sets up a new AssemblyScript project or updates an existing one.",
+ "",
+ stdoutColors.white("SYNTAX"),
+ " " + stdoutColors.cyan("asinit") + " directory [options]",
+ "",
+ stdoutColors.white("EXAMPLES"),
+ " " + stdoutColors.cyan("asinit") + " .",
+ " " + stdoutColors.cyan("asinit") + " ./newProject -y",
+ "",
+ stdoutColors.white("OPTIONS"),
+ optionsUtil.help(asinitOptions, { noCategories: true })
+ ].join("\n"));
+ process.exit(0);
+}
+
+const compilerDir = path.join(dirname, "..");
+const projectDir = path.resolve(cliOptions.arguments[0]);
+const assemblyDir = path.join(projectDir, "assembly");
+const tsconfigFile = path.join(assemblyDir, "tsconfig.json");
+const asconfigFile = path.join(projectDir, "asconfig.json");
+let tsconfigBase = path.relative(assemblyDir, path.join(compilerDir, "std", "assembly.json"));
+if (/^(\.\.[/\\])*node_modules[/\\]assemblyscript[/\\]/.test(tsconfigBase)) {
+ // Use node resolution if the compiler is a normal dependency
+ tsconfigBase = "assemblyscript/std/assembly.json";
+}
+const entryFile = path.join(assemblyDir, "index.ts");
+const buildDir = path.join(projectDir, "build");
+const testsDir = path.join(projectDir, "test");
+const gitignoreFile = path.join(buildDir, ".gitignore");
+const packageFile = path.join(projectDir, "package.json");
+
+const indexHtmlFile = path.join(projectDir, "index.html");
+const testsIndexFile = path.join(testsDir, "index.js");
+
+const paths = [
+ [assemblyDir, "Directory holding the AssemblyScript sources being compiled to WebAssembly."],
+ [tsconfigFile, "TypeScript configuration inheriting recommended AssemblyScript settings."],
+ [entryFile, "Example entry file being compiled to WebAssembly to get you started."],
+ [buildDir, "Build artifact directory where compiled WebAssembly files are stored."],
+ [gitignoreFile, "Git configuration that excludes compiled binaries from source control."],
+ [asconfigFile, "Configuration file defining both a 'debug' and a 'release' target."],
+ [packageFile, "Package info containing the necessary commands to compile to WebAssembly."],
+ [testsIndexFile, "Starter test to check that the module is functioning."],
+ [indexHtmlFile, "Starter HTML file that loads the module in a browser."]
+];
+
+const formatPath = filePath => "./" + path.relative(projectDir, filePath).replace(/\\/g, "/");
+
+if (fs.existsSync(packageFile)) {
+ const pkg = JSON.parse(fs.readFileSync(packageFile));
+ if ("type" in pkg && pkg["type"] !== "module") {
+ console.error(stdoutColors.red([
+ `Error: The "type" field in ${formatPath(packageFile)} is set to "${pkg["type"]}".`,
+ ` asinit requires the "type" field to be set to "module" (ES modules).`
+ ].join("\n")));
+ process.exit(1);
+ }
+}
+
+console.log([
+ "Version: " + version,
+ "",
+ stdoutColors.white([
+ "This command will make sure that the following files exist in the project",
+ "directory '" + projectDir + "':"
+ ].join("\n")),
+ ...paths.map(([filePath, description]) => "\n " + stdoutColors.cyan(formatPath(filePath)) + "\n " + description),
+ "",
+ "The command will try to update existing files to match the correct settings",
+ "for this instance of the compiler in '" + compilerDir + "'.",
+ ""
+].join("\n"));
+
+function createProject(answer) {
+ if (!/^y?$/i.test(answer)) {
+ process.exit(1);
+ return;
+ }
+ console.log();
+ ensureProjectDirectory();
+ ensureAssemblyDirectory();
+ ensureTsconfigJson();
+ ensureEntryFile();
+ ensureBuildDirectory();
+ ensureGitignore();
+ ensurePackageJson();
+ ensureAsconfigJson();
+ ensureTestsDirectory();
+ ensureTestsIndexJs();
+ ensureIndexHtml();
+
+ console.log([
+ stdoutColors.green("Done!"),
+ "",
+ "Don't forget to install dependencies before you start:",
+ "",
+ stdoutColors.white(" " + commands[pm].install),
+ "",
+ "To edit the entry file, open '" + stdoutColors.cyan("assembly/index.ts") + "' in your editor of choice.",
+ "Create as many additional files as necessary and use them as imports.",
+ "",
+ "To build the entry file to WebAssembly when you are ready, run:",
+ "",
+ stdoutColors.white(" " + commands[pm].run + " asbuild"),
+ "",
+ "Running the command above creates the following binaries incl. their respective",
+ "text format representations and source maps:",
+ "",
+ stdoutColors.cyan(" ./build/debug.wasm"),
+ stdoutColors.cyan(" ./build/debug.wasm.map"),
+ stdoutColors.cyan(" ./build/debug.wat"),
+ "",
+ " ^ The debuggable WebAssembly module as generated by the compiler.",
+ " This one matches your sources exactly, without any optimizations.",
+ "",
+ stdoutColors.cyan(" ./build/release.wasm"),
+ stdoutColors.cyan(" ./build/release.wasm.map"),
+ stdoutColors.cyan(" ./build/release.wat"),
+ "",
+ " ^ The optimized WebAssembly module using default optimization settings.",
+ " You can change the optimization settings in '" + stdoutColors.cyan("package.json")+ "'.",
+ "",
+ "To run the tests, do:",
+ "",
+ stdoutColors.white(" " + commands[pm].test),
+ "",
+ "The AssemblyScript documentation covers all the details:",
+ "",
+ " https://www.assemblyscript.org",
+ "",
+ "Have a nice day!"
+ ].join("\n"));
+}
+
+if (cliOptions.options.yes) {
+ createProject("y");
+} else {
+ const rl = require("readline").createInterface({
+ input: process.stdin,
+ output: process.stdout
+ });
+ rl.question(stdoutColors.white("Do you want to proceed?") + " [Y/n] ", result => {
+ rl.close();
+ createProject(result);
+ });
+}
+
+function ensureProjectDirectory() {
+ console.log("- Making sure that the project directory exists...");
+ if (!fs.existsSync(projectDir)) {
+ fs.mkdirSync(projectDir);
+ console.log(stdoutColors.green(" Created: ") + projectDir);
+ } else {
+ console.log(stdoutColors.yellow(" Exists: ") + projectDir);
+ }
+ console.log();
+}
+
+function ensureAssemblyDirectory() {
+ console.log("- Making sure that the 'assembly' directory exists...");
+ if (!fs.existsSync(assemblyDir)) {
+ fs.mkdirSync(assemblyDir);
+ console.log(stdoutColors.green(" Created: ") + assemblyDir);
+ } else {
+ console.log(stdoutColors.yellow(" Exists: ") + assemblyDir);
+ }
+ console.log();
+}
+
+function ensureTsconfigJson() {
+ console.log("- Making sure that 'assembly/tsconfig.json' is set up...");
+ const base = tsconfigBase.replace(/\\/g, "/");
+ if (!fs.existsSync(tsconfigFile)) {
+ fs.writeFileSync(tsconfigFile, JSON.stringify({
+ "extends": base,
+ "include": [
+ "./**/*.ts"
+ ]
+ }, null, 2));
+ console.log(stdoutColors.green(" Created: ") + tsconfigFile);
+
+ } else {
+ let tsconfig = JSON.parse(fs.readFileSync(tsconfigFile, "utf8"));
+ tsconfig["extends"] = base;
+ fs.writeFileSync(tsconfigFile, JSON.stringify(tsconfig, null, 2));
+ console.log(stdoutColors.green(" Updated: ") + tsconfigFile);
+ }
+ console.log();
+}
+
+function ensureAsconfigJson() {
+ console.log("- Making sure that 'asconfig.json' is set up...");
+ if (!fs.existsSync(asconfigFile)) {
+ fs.writeFileSync(asconfigFile, JSON.stringify({
+ targets: {
+ debug: {
+ // -o build/debug.wasm -t build/debug.wat --sourceMap --debug
+ outFile: "build/debug.wasm",
+ textFile: "build/debug.wat",
+ sourceMap: true,
+ debug: true
+ },
+ release: {
+ // -o build/release.wasm -t build/release.wat --sourceMap --optimize
+ outFile: "build/release.wasm",
+ textFile: "build/release.wat",
+ sourceMap: true,
+ optimizeLevel: 3,
+ shrinkLevel: 0,
+ converge: false,
+ noAssert: false
+ }
+ },
+ options: {
+ bindings: "esm"
+ }
+ }, null, 2));
+ console.log(stdoutColors.green(" Created: ") + asconfigFile);
+ } else {
+ console.log(stdoutColors.yellow(" Exists: ") + asconfigFile);
+ }
+ console.log();
+}
+
+function ensureEntryFile() {
+ console.log("- Making sure that 'assembly/index.ts' exists...");
+ if (!fs.existsSync(entryFile)) {
+ fs.writeFileSync(entryFile, [
+ "// The entry file of your WebAssembly module.",
+ "",
+ "export function add(a: i32, b: i32): i32 {",
+ " return a + b;",
+ "}"
+ ].join("\n") + "\n");
+ console.log(stdoutColors.green(" Created: ") + entryFile);
+ } else {
+ console.log(stdoutColors.yellow(" Exists: ") + entryFile);
+ }
+ console.log();
+}
+
+function ensureBuildDirectory() {
+ console.log("- Making sure that the 'build' directory exists...");
+ if (!fs.existsSync(buildDir)) {
+ fs.mkdirSync(buildDir);
+ console.log(stdoutColors.green(" Created: ") + buildDir);
+ } else {
+ console.log(stdoutColors.yellow(" Exists: ") + buildDir);
+ }
+ console.log();
+}
+
+function ensureGitignore() {
+ console.log("- Making sure that 'build/.gitignore' is set up...");
+ if (!fs.existsSync(gitignoreFile)) {
+ fs.writeFileSync(gitignoreFile, [
+ "*",
+ "!.gitignore"
+ ].join("\n") + "\n");
+ console.log(stdoutColors.green(" Created: ") + gitignoreFile);
+ } else {
+ console.log(stdoutColors.yellow(" Exists: ") + gitignoreFile);
+ }
+ console.log();
+}
+
+function ensurePackageJson() {
+ console.log("- Making sure that 'package.json' contains the build commands...");
+ const entryPath = path.relative(projectDir, entryFile).replace(/\\/g, "/");
+ const buildDebug = "asc " + entryPath + " --target debug";
+ const buildRelease = "asc " + entryPath + " --target release";
+ const buildAll = commands[pm].run + " asbuild:debug && " + commands[pm].run + " asbuild:release";
+ if (!fs.existsSync(packageFile)) {
+ fs.writeFileSync(packageFile, JSON.stringify({
+ "type": "module",
+ "exports": {
+ ".": {
+ "import": "./build/release.js",
+ "types": "./build/release.d.ts"
+ }
+ },
+ "scripts": {
+ "asbuild:debug": buildDebug,
+ "asbuild:release": buildRelease,
+ "asbuild": buildAll,
+ "test": "node --test",
+ "start": "npx serve ."
+ },
+ "devDependencies": {
+ "assemblyscript": "^" + version
+ }
+ }, null, 2));
+ console.log(stdoutColors.green(" Created: ") + packageFile);
+ } else {
+ let pkg = JSON.parse(fs.readFileSync(packageFile));
+ let scripts = pkg.scripts || {};
+ let updated = false;
+ if (!pkg["type"]) {
+ pkg["type"] = "module";
+ updated = true;
+ }
+ if (!pkg["exports"]) {
+ pkg["exports"] = {
+ ".": {
+ "import": "./build/release.js",
+ "types": "./build/release.d.ts"
+ }
+ };
+ }
+ if (!scripts["asbuild"]) {
+ scripts["asbuild:debug"] = buildDebug;
+ scripts["asbuild:release"] = buildRelease;
+ scripts["asbuild"] = buildAll;
+ pkg["scripts"] = scripts;
+ updated = true;
+ }
+ if (!scripts["test"] || scripts["test"] == npmDefaultTest) {
+ scripts["test"] = "node --test";
+ pkg["scripts"] = scripts;
+ updated = true;
+ }
+ if (!scripts["start"]) {
+ scripts["start"] = "npx serve .";
+ pkg["scripts"] = scripts;
+ updated = true;
+ }
+ let devDependencies = pkg["devDependencies"] || {};
+ if (!devDependencies["assemblyscript"]) {
+ devDependencies["assemblyscript"] = "^" + version;
+ pkg["devDependencies"] = devDependencies;
+ updated = true;
+ }
+ if (updated) {
+ fs.writeFileSync(packageFile, JSON.stringify(pkg, null, 2));
+ console.log(stdoutColors.green(" Updated: ") + packageFile);
+ } else {
+ console.log(stdoutColors.yellow(" Exists: ") + packageFile);
+ }
+ }
+ console.log();
+}
+
+function ensureTestsDirectory() {
+ console.log("- Making sure that the 'test' directory exists...");
+ if (!fs.existsSync(testsDir)) {
+ fs.mkdirSync(testsDir);
+ console.log(stdoutColors.green(" Created: ") + testsDir);
+ } else {
+ console.log(stdoutColors.yellow(" Exists: ") + testsDir);
+ }
+ console.log();
+}
+
+function ensureTestsIndexJs() {
+ console.log("- Making sure that 'test/index.js' exists...");
+ if (!fs.existsSync(testsIndexFile)) {
+ fs.writeFileSync(testsIndexFile, [
+ "import assert from \"node:assert/strict\";",
+ "import { it } from \"node:test\";",
+ "import { add } from \"../build/debug.js\";",
+ "",
+ "it(\"add\", () => {",
+ " assert.equal(add(1, 2), 3);",
+ "});"
+ ].join("\n") + "\n");
+ console.log(stdoutColors.green(" Created: ") + testsIndexFile);
+ } else {
+ console.log(stdoutColors.yellow(" Exists: ") + testsIndexFile);
+ }
+ console.log();
+}
+
+function ensureIndexHtml() {
+ console.log("- Making sure that 'index.html' exists...");
+ if (!fs.existsSync(indexHtmlFile)) {
+ fs.writeFileSync(indexHtmlFile, [
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ ].join("\n") + "\n");
+ console.log(stdoutColors.green(" Created: ") + indexHtmlFile);
+ } else {
+ console.log(stdoutColors.yellow(" Exists: ") + indexHtmlFile);
+ }
+ console.log();
+}
diff --git a/cli/README.md b/cli/README.md
index 6033f60451..9e048005e3 100644
--- a/cli/README.md
+++ b/cli/README.md
@@ -1,5 +1,5 @@
-Compiler frontend for node.js
-=============================
+Frontend for Node.js
+====================
Usage
-----
@@ -13,41 +13,46 @@ $> asc --help
API
---
-The API accepts the same options as the CLI but also lets you override stdout and stderr and/or provide a callback. Example:
+The API accepts the same options as the CLI but also lets you override stdout and stderr. Example:
```js
-const asc = require("assemblyscript/cli/asc");
-asc.ready.then(() => {
- asc.main([
- "myModule.ts",
- "--binaryFile", "myModule.wasm",
- "--optimize",
- "--sourceMap",
- "--measure"
- ], {
- stdout: process.stdout,
- stderr: process.stderr
- }, function(err) {
- if (err)
- throw err;
- ...
- });
-});
+import asc from "assemblyscript/asc";
+
+const { error, stdout } = await asc.main([
+ "myModule.ts",
+ "--outFile", "myModule.wasm",
+ "--optimize",
+ "--sourceMap",
+ "--stats"
+]);
+if (error) {
+ console.log("Compilation failed: " + error.message);
+} else {
+ console.log(stdout.toString());
+}
```
-Available command line options can also be obtained programmatically:
+The result has the following structure:
+
+| Property | Description
+|----------|-------------
+| error | Encountered error, if any
+| stdout | Standard output stream
+| stderr | Standard error stream
+| stats | Statistics
+
+You can also compile a single source string directly (note that this API has limited functionality):
```js
-const options = require("assemblyscript/cli/asc.json");
+import asc from "assemblyscript/asc";
+const { binary, text, stdout, stderr } = await asc.compileString(`...`, { optimize: 2 });
...
```
-You can also compile a source string directly, for example in a browser environment:
+
+Available command line options can also be obtained programmatically:
```js
-const asc = require("assemblyscript/cli/asc");
-asc.ready.then(() => {
- const { binary, text, stdout, stderr } = asc.compileString(`...`, { optimize: 2 });
-});
+import { options } from "assemblyscript/asc";
...
```
diff --git a/cli/asc.d.ts b/cli/asc.d.ts
deleted file mode 100644
index 0fcc0a7524..0000000000
--- a/cli/asc.d.ts
+++ /dev/null
@@ -1,253 +0,0 @@
-/**
- * @fileoverview Definitions for asc.
- * @license Apache-2.0
- */
-
-import { OptionDescription } from "./util/options";
-export { OptionDescription };
-import { Transform } from "./transform";
-
-/** Ready promise resolved once/if the compiler is ready. */
-export const ready: Promise;
-
-/** Whether this is a webpack bundle or not. */
-export const isBundle: boolean;
-
-/** Whether asc runs the sources directly or not. */
-export const isDev: boolean;
-
-/** AssemblyScript version. */
-export const version: string;
-
-/** Available CLI options. */
-export const options: { [key: string]: OptionDescription };
-
-/** Common root used in source maps. */
-export var sourceMapRoot: string;
-
-/** Prefix used for library files. */
-export var libraryPrefix: string;
-
-/** Default Binaryen optimization level. */
-export var defaultOptimizeLevel: number;
-
-/** Default Binaryen shrink level. */
-export var defaultShrinkLevel: number;
-
-/** Bundled library files. */
-export const libraryFiles: { [key: string]: string };
-
-/** Bundled definition files. */
-export const definitionFiles: { assembly: string, portable: string };
-
-/** A compatible output stream. */
-export interface OutputStream {
- /** Writes another chunk of data to the stream. */
- write(chunk: Uint8Array | string): void;
-}
-
-/** An in-memory output stream. */
-export interface MemoryStream extends OutputStream {
- /** Resets the stream to offset zero. */
- reset(): void;
- /** Converts the output to a buffer. */
- toBuffer(): Uint8Array;
- /** Converts the output to a string. */
- toString(): string;
-}
-
-/** Relevant subset of the Source class for diagnostic reporting. */
-export interface Source {
- /** Normalized path with file extension. */
- normalizedPath: string;
-}
-
-/** Relevant subset of the Range class for diagnostic reporting. */
-export interface Range {
- /** Start offset within the source file. */
- start: number;
- /** End offset within the source file. */
- end: number;
- /** Respective source file. */
- source: Source;
-}
-
-/** Relevant subset of the DiagnosticMessage class for diagnostic reporting. */
-export interface DiagnosticMessage {
- /** Message code. */
- code: number;
- /** Message category. */
- category: number;
- /** Message text. */
- message: string;
- /** Respective source range, if any. */
- range: Range | null;
- /** Related range, if any. */
- relatedRange: Range | null;
-}
-
-/** A function handling diagnostic messages. */
-type DiagnosticReporter = (diagnostic: DiagnosticMessage) => void;
-
-/** Compiler options. */
-export interface CompilerOptions {
- /** Prints just the compiler's version and exits. */
- version?: boolean;
- /** Prints the help message and exits. */
- help?: boolean;
- /** Optimizes the module. */
- optimize?: boolean;
- /** How much to focus on optimizing code. */
- optimizeLevel?: number;
- /** How much to focus on shrinking code size. */
- shrinkLevel?: number;
- /** Re-optimizes until no further improvements can be made. */
- converge?: boolean;
- /** Specifies the base directory of input and output files. */
- baseDir?: string;
- /** Specifies the output file. File extension indicates format. */
- outFile?: string;
- /** Specifies the binary output file (.wasm). */
- binaryFile?: string;
- /** Specifies the text output file (.wat). */
- textFile?: string;
- /** Specifies the JavaScript (via wasm2js) output file (.js). */
- jsFile?: string;
- /** Specifies the WebIDL output file (.webidl). */
- idlFile?: string;
- /** Specifies the TypeScript definition output file (.d.ts). */
- tsdFile?: string;
- /** Enables source map generation. Optionally takes the URL. */
- sourceMap?: boolean | string;
- /** Specifies the runtime variant to include in the program. */
- runtime?: string;
- /** Disallows the use of unsafe features in user code. */
- noUnsafe?: boolean;
- /** Enables debug information in emitted binaries. */
- debug?: boolean;
- /** Replaces assertions with just their value without trapping. */
- noAssert?: boolean;
- /** Performs compilation as usual but does not emit code. */
- noEmit?: boolean;
- /** Imports the memory provided as 'env.memory'. */
- importMemory?: boolean;
- /** Does not export the memory as 'memory'. */
- noExportMemory?: boolean;
- /** Sets the initial memory size in pages. */
- initialMemory?: number;
- /** Sets the maximum memory size in pages. */
- maximumMemory?: number;
- /** Declare memory as shared. Requires maximumMemory. */
- sharedMemory?: boolean;
- /** Sets the start offset of compiler-generated static memory. */
- memoryBase?: number;
- /** Imports the function table provided as 'env.table'. */
- importTable?: boolean;
- /** Exports the function table as 'table'. */
- exportTable?: boolean;
- /** Exports an explicit start function to be called manually. */
- explicitStart?: boolean;
- /** "Adds one or multiple paths to custom library components. */
- lib?: string | string[];
- /** Adds one or multiple paths to package resolution. */
- path?: string | string[];
- /** Aliases a global object under another name. */
- use?: string | string[];
- /** Sets the trap mode to use. */
- trapMode?: "allow" | "clamp" | "js";
- /** Specifies additional Binaryen passes to run. */
- runPasses?: string | string[];
- /** Skips validating the module using Binaryen. */
- noValidate?: boolean;
- /** Enables WebAssembly features that are disabled by default. */
- enable?: string | string[];
- /** Disables WebAssembly features that are enabled by default. */
- disable?: string | string[];
- /** Specifies the path to a custom transform to 'require'. */
- transform?: string | string[];
- /** Make yourself sad for no good reason. */
- pedantic?: boolean;
- /** Enables tracing of package resolution. */
- traceResolution?: boolean;
- /** Lists files to be compiled and exits. */
- listFiles?: boolean;
- /** Prints measuring information on I/O and compile times. */
- measure?: boolean;
- /** Disables terminal colors. */
- noColors?: boolean;
- /** Specifies an alternative file extension. */
- extension?: string;
-}
-
-/** Compiler API options. */
-export interface APIOptions {
- /** Standard output stream to use. */
- stdout?: OutputStream;
- /** Standard error stream to use. */
- stderr?: OutputStream;
- /** Reads a file from disk (or memory). */
- readFile?: (filename: string, baseDir: string) => string | null;
- /** Writes a file to disk (or memory). */
- writeFile?: (filename: string, contents: Uint8Array, baseDir: string) => void;
- /** Lists all files within a directory. */
- listFiles?: (dirname: string, baseDir: string) => string[] | null;
- /** Handler for diagnostic messages. */
- reportDiagnostic?: DiagnosticReporter;
- /** Additional transforms to apply. */
- transforms?: Transform[];
-}
-
-/** Convenience function that parses and compiles source strings directly. */
-export function compileString(sources: { [key: string]: string } | string, options?: CompilerOptions): {
- /** Standard output. */
- stdout: OutputStream,
- /** Standard error. */
- stderr: OutputStream,
- /** Emitted binary. */
- binary: Uint8Array | null,
- /** Emitted text format. */
- text: string | null
-}
-
-/** Runs the command line utility using the specified arguments array. */
-export function main(argv: string[], options: APIOptions, callback?: (err: Error | null) => number): number;
-export function main(argv: string[], callback?: (err: Error | null) => number): number;
-
-/** Checks diagnostics emitted so far for errors. */
-export function checkDiagnostics(emitter: Record, stderr?: OutputStream, reportDiagnostic?: DiagnosticReporter): boolean;
-
-/** An object of stats for the current task. */
-export interface Stats {
- readTime: number,
- readCount: number,
- writeTime: number,
- writeCount: number,
- parseTime: number,
- parseCount: number,
- compileTime: number,
- compileCount: number,
- emitTime: number,
- emitCount: number,
- validateTime: number,
- validateCount: number,
- optimizeTime: number,
- optimizeCount: number
-}
-
-/** Creates an empty set of stats. */
-export function createStats(): Stats;
-
-/** Measures the execution time of the specified function. */
-export function measure(fn: () => void): number;
-
-/** Formats a high resolution time to a human readable string. */
-export function formatTime(time: number): string;
-
-/** Formats and prints out the contents of a set of stats. */
-export function printStats(stats: Stats, output: OutputStream): void;
-
-/** Creates a memory stream that can be used in place of stdout/stderr. */
-export function createMemoryStream(fn?: (chunk: Uint8Array | string) => void): MemoryStream;
-
-/** Compatible TypeScript compiler options for syntax highlighting etc. */
-export const tscOptions: Record;
diff --git a/cli/asc.js b/cli/asc.js
deleted file mode 100644
index e33875a8dc..0000000000
--- a/cli/asc.js
+++ /dev/null
@@ -1,1445 +0,0 @@
-/**
- * @license
- * Copyright 2020 Daniel Wirtz / The AssemblyScript Authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * SPDX-License-Identifier: Apache-2.0
- */
-
-/**
- * @fileoverview Compiler frontend for node.js
- *
- * Uses the low-level API exported from src/index.ts so it works with the compiler compiled to
- * JavaScript as well as the compiler compiled to WebAssembly (eventually). Runs the sources
- * directly through ts-node if distribution files are not present.
- *
- * Can also be packaged as a bundle suitable for in-browser use with the standard library injected
- * in the build step. See dist/asc.js for the bundle and webpack.config.js for building details.
- */
-
-/* global BUNDLE_VERSION, BUNDLE_LIBRARY, BUNDLE_DEFINITIONS */
-
-const fs = require("fs");
-const path = require("path");
-const process = require("process"); // ensure shim
-const utf8 = require("./util/utf8");
-const colorsUtil = require("./util/colors");
-const optionsUtil = require("./util/options");
-const mkdirp = require("./util/mkdirp");
-const find = require("./util/find");
-const binaryen = global.binaryen || (global.binaryen = require("binaryen"));
-
-const dynrequire = typeof __webpack_require__ === "function"
- ? __non_webpack_require__
- : require;
-
-const WIN = process.platform === "win32";
-const EOL = WIN ? "\r\n" : "\n";
-const SEP = WIN ? "\\" : "/";
-
-// Sets up an extension with its definition counterpart and relevant regexes.
-function setupExtension(ext) {
- if (!ext.startsWith(".")) ext = "." + ext;
- return {
- ext,
- ext_d: ".d" + ext,
- re: new RegExp("\\" + ext + "$"),
- re_d: new RegExp("\\.d\\" + ext + "$"),
- re_except_d: new RegExp("^(?!.*\\.d\\" + ext + "$).*\\" + ext + "$"),
- re_index: new RegExp("(?:^|[\\\\\\/])index\\" + ext + "$")
- };
-}
-
-const defaultExtension = setupExtension(".ts");
-
-// Proxy Binaryen's ready event
-Object.defineProperty(exports, "ready", {
- get() { return binaryen.ready; }
-});
-
-// Emscripten adds an `uncaughtException` listener to Binaryen that results in an additional
-// useless code fragment on top of an actual error. suppress this:
-if (process.removeAllListeners) process.removeAllListeners("uncaughtException");
-
-// Use distribution files if present, otherwise run the sources directly.
-function loadAssemblyScriptJS() {
- var exports;
- try {
- // note that this case will always trigger in recent node.js versions for typical installs
- // see: https://nodejs.org/api/packages.html#packages_self_referencing_a_package_using_its_name
- exports = require("assemblyscript");
- } catch (e) {
- try { // `asc` on the command line (unnecessary in recent node)
- exports = dynrequire("../dist/assemblyscript.js");
- } catch (e) {
- try { // `asc` on the command line without dist files (unnecessary in recent node)
- dynrequire("ts-node").register({
- project: path.join(__dirname, "..", "src", "tsconfig.json"),
- skipIgnore: true,
- compilerOptions: { target: "ES2016" }
- });
- dynrequire("../src/glue/js");
- exports = dynrequire("../src");
- } catch (e_ts) {
- try { // `require("dist/asc.js")` in explicit browser tests
- exports = dynrequire("./assemblyscript");
- } catch (e) {
- throw Error(e_ts.stack + "\n---\n" + e.stack);
- }
- }
- }
- }
- return exports;
-}
-
-// Loads the specified bootstrapped Wasm binary of the compiler.
-function loadAssemblyScriptWasm(binaryPath) {
- const loader = require("../lib/loader/umd/index");
- const rtrace = new (require("../lib/rtrace/umd/index").Rtrace)({
- onerror(err, info) { console.log(err, info); },
- getMemory() { return exports.memory; },
- oncollect() {
- var gcProfile = rtrace.gcProfile;
- if (gcProfile && gcProfile.length && fs.writeFileSync) {
- let timestamp = Date.now();
- fs.writeFileSync(`rtrace-gc-profile-${timestamp}.json`, JSON.stringify(gcProfile));
- fs.writeFileSync(`rtrace-gc-profile-${timestamp}.csv`, `time,memory,pause\n${gcProfile.join("\n")}`);
- }
- }
- });
- var { exports } = loader.instantiateSync(fs.readFileSync(binaryPath), rtrace.install({ binaryen }));
- if (exports._start) exports._start();
- return exports;
-}
-
-/** Ensures that an object is a wrapper class instead of just a pointer. */
-function __wrap(ptrOrObj, wrapperClass) {
- if (typeof ptrOrObj === "number") {
- return ptrOrObj === 0 ? null : wrapperClass.wrap(ptrOrObj);
- }
- return ptrOrObj;
-}
-
-var assemblyscript, __newString, __getString, __pin, __unpin, __collect;
-
-function loadAssemblyScript() {
- const wasmArg = process.argv.findIndex(arg => arg == "--wasm");
- if (~wasmArg) {
- let binaryPath = process.argv[wasmArg + 1];
- process.argv.splice(wasmArg, 2);
- assemblyscript = loadAssemblyScriptWasm(binaryPath);
- __newString = assemblyscript.__newString;
- __getString = assemblyscript.__getString;
- __pin = assemblyscript.__pin;
- __unpin = assemblyscript.__unpin;
- __collect = assemblyscript.__collect;
- } else {
- assemblyscript = loadAssemblyScriptJS();
- __newString = str => str;
- __getString = ptr => ptr;
- __pin = ptr => ptr;
- __unpin = ptr => undefined;
- __collect = incremental => undefined;
- }
-}
-loadAssemblyScript();
-
-/** Whether this is a webpack bundle or not. */
-exports.isBundle = typeof BUNDLE_VERSION === "string";
-
-/** AssemblyScript version. */
-exports.version = exports.isBundle ? BUNDLE_VERSION : dynrequire("../package.json").version;
-
-/** Available CLI options. */
-exports.options = require("./asc.json");
-
-/** Prefix used for library files. */
-exports.libraryPrefix = __getString(assemblyscript.LIBRARY_PREFIX.valueOf());
-
-/** Default Binaryen optimization level. */
-exports.defaultOptimizeLevel = 3;
-
-/** Default Binaryen shrink level. */
-exports.defaultShrinkLevel = 1;
-
-/** Bundled library files. */
-exports.libraryFiles = exports.isBundle ? BUNDLE_LIBRARY : (() => { // set up if not a bundle
- const libDir = path.join(__dirname, "..", "std", "assembly");
- const bundled = {};
- find
- .files(libDir, defaultExtension.re_except_d)
- .forEach(file => {
- bundled[file.replace(defaultExtension.re, "")] = fs.readFileSync(path.join(libDir, file), "utf8");
- });
- return bundled;
-})();
-
-/** Bundled definition files. */
-exports.definitionFiles = exports.isBundle ? BUNDLE_DEFINITIONS : (() => { // set up if not a bundle
- const readDefinition = name => fs.readFileSync(
- path.join(__dirname, "..", "std", name, "index" + defaultExtension.ext_d),
- "utf8"
- );
- return {
- assembly: readDefinition("assembly"),
- portable: readDefinition("portable")
- };
-})();
-
-/** Convenience function that parses and compiles source strings directly. */
-exports.compileString = (sources, options) => {
- if (typeof sources === "string") sources = { ["input" + defaultExtension.ext]: sources };
- const output = Object.create({
- stdout: createMemoryStream(),
- stderr: createMemoryStream()
- });
- var argv = [
- "--binaryFile", "binary",
- "--textFile", "text",
- ];
- Object.keys(options || {}).forEach(key => {
- var val = options[key];
- var opt = exports.options[key];
- if (opt && opt.type === "b") {
- if (val) argv.push("--" + key);
- } else {
- if (Array.isArray(val)) {
- val.forEach(val => { argv.push("--" + key, String(val)); });
- }
- else argv.push("--" + key, String(val));
- }
- });
- exports.main(argv.concat(Object.keys(sources)), {
- stdout: output.stdout,
- stderr: output.stderr,
- readFile: name => Object.prototype.hasOwnProperty.call(sources, name) ? sources[name] : null,
- writeFile: (name, contents) => { output[name] = contents; },
- listFiles: () => []
- });
- return output;
-};
-
-/** Runs the command line utility using the specified arguments array. */
-exports.main = function main(argv, options, callback) {
- if (typeof options === "function") {
- callback = options;
- options = {};
- } else if (!options) {
- options = {};
- }
-
- // Bundle semantic version
- let bundleMinorVersion = 0, bundleMajorVersion = 0, bundlePatchVersion = 0;
- const versionParts = (exports.version || "").split(".");
- if (versionParts.length === 3) {
- bundleMajorVersion = parseInt(versionParts[0]) | 0;
- bundleMinorVersion = parseInt(versionParts[1]) | 0;
- bundlePatchVersion = parseInt(versionParts[2]) | 0;
- }
-
- const stdout = options.stdout || process.stdout;
- const stderr = options.stderr || process.stderr;
- const readFile = options.readFile || readFileNode;
- const writeFile = options.writeFile || writeFileNode;
- const listFiles = options.listFiles || listFilesNode;
- const stats = options.stats || createStats();
- let extension = defaultExtension;
-
- // Output must be specified if not present in the environment
- if (!stdout) throw Error("'options.stdout' must be specified");
- if (!stderr) throw Error("'options.stderr' must be specified");
-
- // Parse command line options but do not populate option defaults yet
- const optionsResult = optionsUtil.parse(argv, exports.options, false);
- let opts = optionsResult.options;
- argv = optionsResult.arguments;
-
- if (opts.noColors) {
- colorsUtil.stdout.supported =
- colorsUtil.stderr.supported = false;
- } else {
- colorsUtil.stdout = colorsUtil.from(stdout);
- colorsUtil.stderr = colorsUtil.from(stderr);
- }
-
- // Check for unknown options
- const unknownOpts = optionsResult.unknown;
- if (unknownOpts.length) {
- unknownOpts.forEach(arg => {
- stderr.write(colorsUtil.stderr.yellow("WARNING ") + "Unknown option '" + arg + "'" + EOL);
- });
- }
-
- // Check for trailing arguments
- const trailingArgv = optionsResult.trailing;
- if (trailingArgv.length) {
- stderr.write(colorsUtil.stderr.yellow("WARNING ") + "Unsupported trailing arguments: " + trailingArgv.join(" ") + EOL);
- }
-
- // Use default callback if none is provided
- if (!callback) callback = function defaultCallback(err) {
- var code = 0;
- if (err) {
- stderr.write(colorsUtil.stderr.red("FAILURE ") + err.stack.replace(/^ERROR: /i, "") + EOL);
- code = 1;
- }
- return code;
- };
-
- // Just print the version if requested
- if (opts.version) {
- stdout.write("Version " + exports.version + EOL);
- return callback(null);
- }
-
- // Use another extension if requested
- if (typeof opts.extension === "string") {
- if (/^\.?[0-9a-zA-Z]{1,14}$/.test(opts.extension)) {
- extension = setupExtension(opts.extension);
- } else {
- return callback(Error("Invalid extension: " + opts.extension));
- }
- }
-
- // Set up base directory
- const baseDir = path.normalize(opts.baseDir || ".");
-
- // Check if a config file is present
- let asconfigPath = optionsUtil.resolvePath(opts.config || "asconfig.json", baseDir);
- let asconfigFile = path.basename(asconfigPath);
- let asconfigDir = path.dirname(asconfigPath);
- let asconfig = getAsconfig(asconfigFile, asconfigDir, readFile);
- let asconfigHasEntries = asconfig != null && Array.isArray(asconfig.entries) && asconfig.entries.length;
-
- // Print the help message if requested or no source files are provided
- if (opts.help || (!argv.length && !asconfigHasEntries)) {
- var out = opts.help ? stdout : stderr;
- var color = opts.help ? colorsUtil.stdout : colorsUtil.stderr;
- out.write([
- color.white("SYNTAX"),
- " " + color.cyan("asc") + " [entryFile ...] [options]",
- "",
- color.white("EXAMPLES"),
- " " + color.cyan("asc") + " hello" + extension.ext,
- " " + color.cyan("asc") + " hello" + extension.ext + " -b hello.wasm -t hello.wat",
- " " + color.cyan("asc") + " hello1" + extension.ext + " hello2" + extension.ext + " -b -O > hello.wasm",
- " " + color.cyan("asc") + " --config asconfig.json --target release",
- "",
- color.white("OPTIONS"),
- ].concat(
- optionsUtil.help(exports.options, 24, EOL)
- ).join(EOL) + EOL);
- return callback(null);
- }
-
- // I/O must be specified if not present in the environment
- if (!fs.readFileSync) {
- if (readFile === readFileNode) throw Error("'options.readFile' must be specified");
- if (writeFile === writeFileNode) throw Error("'options.writeFile' must be specified");
- if (listFiles === listFilesNode) throw Error("'options.listFiles' must be specified");
- }
-
- // Load additional options from asconfig.json
- const seenAsconfig = new Set();
- seenAsconfig.add(asconfigPath);
- const target = opts.target || "release";
- while (asconfig) {
- // Merge target first
- if (asconfig.targets) {
- const targetOptions = asconfig.targets[target];
- if (targetOptions) {
- opts = optionsUtil.merge(exports.options, opts, targetOptions, asconfigDir);
- }
- }
- // Merge general options
- const generalOptions = asconfig.options;
- if (generalOptions) {
- opts = optionsUtil.merge(exports.options, opts, generalOptions, asconfigDir);
- }
-
- // Append entries
- if (asconfig.entries) {
- for (let entry of asconfig.entries) {
- argv.push(optionsUtil.resolvePath(entry, asconfigDir));
- }
- }
-
- // Look up extended asconfig and repeat
- if (asconfig.extends) {
- asconfigPath = optionsUtil.resolvePath(asconfig.extends, asconfigDir, true);
- asconfigFile = path.basename(asconfigPath);
- asconfigDir = path.dirname(asconfigPath);
- if (seenAsconfig.has(asconfigPath)) break;
- seenAsconfig.add(asconfigPath);
- asconfig = getAsconfig(asconfigFile, asconfigDir, readFile);
- } else {
- break;
- }
- }
-
- // Populate option defaults once user-defined options are set
- optionsUtil.addDefaults(exports.options, opts);
-
- // If showConfig print options and exit
- if (opts.showConfig) {
- stderr.write(JSON.stringify({
- options: opts,
- entries: argv
- }, null, 2));
- return callback(null);
- }
-
- // create a unique set of values
- function unique(values) {
- return [...new Set(values)];
- }
-
- // Set up options
- var program;
- const compilerOptions = __pin(assemblyscript.newOptions());
- assemblyscript.setTarget(compilerOptions, 0);
- assemblyscript.setNoAssert(compilerOptions, opts.noAssert);
- assemblyscript.setExportMemory(compilerOptions, !opts.noExportMemory);
- assemblyscript.setImportMemory(compilerOptions, opts.importMemory);
- assemblyscript.setInitialMemory(compilerOptions, opts.initialMemory >>> 0);
- assemblyscript.setMaximumMemory(compilerOptions, opts.maximumMemory >>> 0);
- assemblyscript.setSharedMemory(compilerOptions, opts.sharedMemory);
- assemblyscript.setImportTable(compilerOptions, opts.importTable);
- assemblyscript.setExportTable(compilerOptions, opts.exportTable);
- assemblyscript.setExplicitStart(compilerOptions, opts.explicitStart);
- assemblyscript.setMemoryBase(compilerOptions, opts.memoryBase >>> 0);
- assemblyscript.setTableBase(compilerOptions, opts.tableBase >>> 0);
- assemblyscript.setSourceMap(compilerOptions, opts.sourceMap != null);
- assemblyscript.setNoUnsafe(compilerOptions, opts.noUnsafe);
- assemblyscript.setPedantic(compilerOptions, opts.pedantic);
- assemblyscript.setLowMemoryLimit(compilerOptions, opts.lowMemoryLimit >>> 0);
- assemblyscript.setExportRuntime(compilerOptions, opts.exportRuntime);
- assemblyscript.setBundleVersion(compilerOptions, bundleMajorVersion, bundleMinorVersion, bundlePatchVersion);
- if (!opts.stackSize && opts.runtime == "incremental") {
- opts.stackSize = assemblyscript.DEFAULT_STACK_SIZE;
- }
- assemblyscript.setStackSize(compilerOptions, opts.stackSize);
-
- // Instrument callback to perform GC
- callback = (function(callback) {
- return function wrappedCallback(err) {
- __unpin(compilerOptions);
- if (program) __unpin(program);
- __collect();
- return callback(err);
- };
- })(callback);
-
- // Add or override aliases if specified
- if (opts.use) {
- let aliases = opts.use;
- for (let i = 0, k = aliases.length; i < k; ++i) {
- let part = aliases[i];
- let p = part.indexOf("=");
- if (p < 0) return callback(Error("Global alias '" + part + "' is invalid."));
- let alias = part.substring(0, p).trim();
- let name = part.substring(p + 1).trim();
- if (!alias.length) return callback(Error("Global alias '" + part + "' is invalid."));
- {
- let aliasPtr = __pin(__newString(alias));
- let namePtr = __newString(name);
- assemblyscript.setGlobalAlias(compilerOptions, aliasPtr, namePtr);
- __unpin(aliasPtr);
- }
- }
- }
-
- // Disable default features if specified
- var features;
- if ((features = opts.disable) != null) {
- if (typeof features === "string") features = features.split(",");
- for (let i = 0, k = features.length; i < k; ++i) {
- let name = features[i].trim();
- let flag = assemblyscript["FEATURE_" + name.replace(/-/g, "_").toUpperCase()];
- if (!flag) return callback(Error("Feature '" + name + "' is unknown."));
- assemblyscript.disableFeature(compilerOptions, flag);
- }
- }
-
- // Enable experimental features if specified
- if ((features = opts.enable) != null) {
- if (typeof features === "string") features = features.split(",");
- for (let i = 0, k = features.length; i < k; ++i) {
- let name = features[i].trim();
- let flag = assemblyscript["FEATURE_" + name.replace(/-/g, "_").toUpperCase()];
- if (!flag) return callback(Error("Feature '" + name + "' is unknown."));
- assemblyscript.enableFeature(compilerOptions, flag);
- }
- }
-
- // Set up optimization levels
- var optimizeLevel = 0;
- var shrinkLevel = 0;
- if (opts.optimize) {
- optimizeLevel = exports.defaultOptimizeLevel;
- shrinkLevel = exports.defaultShrinkLevel;
- }
- if (typeof opts.optimizeLevel === "number") optimizeLevel = opts.optimizeLevel;
- if (typeof opts.shrinkLevel === "number") shrinkLevel = opts.shrinkLevel;
- optimizeLevel = Math.min(Math.max(optimizeLevel, 0), 3);
- shrinkLevel = Math.min(Math.max(shrinkLevel, 0), 2);
- assemblyscript.setOptimizeLevelHints(compilerOptions, optimizeLevel, shrinkLevel);
-
- // Initialize the program
- program = __pin(assemblyscript.newProgram(compilerOptions));
-
- // Collect transforms *constructors* from the `--transform` CLI flag as well
- // as the `transform` option into the `transforms` array.
- let transforms = [];
- // `transform` option from `main()`
- if (Array.isArray(options.transforms)) {
- transforms.push(...options.transforms);
- }
- // `--transform` CLI flag
- if (opts.transform) {
- let tsNodeRegistered = false;
- let transformArgs = unique(opts.transform);
- for (let i = 0, k = transformArgs.length; i < k; ++i) {
- let filename = transformArgs[i].trim();
- if (!tsNodeRegistered && filename.endsWith(".ts")) { // ts-node requires .ts specifically
- dynrequire("ts-node").register({ transpileOnly: true, skipProject: true, compilerOptions: { target: "ES2016" } });
- tsNodeRegistered = true;
- }
- try {
- transforms.push(dynrequire(dynrequire.resolve(filename, { paths: [baseDir, process.cwd()] })));
- } catch (e) {
- return callback(e);
- }
- }
- }
-
- // Fix up the prototype of the transforms’ constructors and instantiate them.
- try {
- transforms = transforms.map(classOrModule => {
- // Except if it’s a legacy module, just pass it through.
- if (typeof classOrModule !== "function") {
- return classOrModule;
- }
- Object.assign(classOrModule.prototype, {
- program,
- baseDir,
- stdout,
- stderr,
- log: console.error,
- readFile,
- writeFile,
- listFiles
- });
- return new classOrModule();
- });
- } catch (e) {
- return callback(e);
- }
-
- function applyTransform(name, ...args) {
- for (let i = 0, k = transforms.length; i < k; ++i) {
- let transform = transforms[i];
- if (typeof transform[name] === "function") {
- try {
- stats.transformCount++;
- stats.transfromTime += measure(() => {
- transform[name](...args);
- });
- } catch (e) {
- return e;
- }
- }
- }
- }
-
- // Parse library files
- Object.keys(exports.libraryFiles).forEach(libPath => {
- if (libPath.indexOf("/") >= 0) return; // in sub-directory: imported on demand
- stats.parseCount++;
- stats.parseTime += measure(() => {
- let textPtr = __pin(__newString(exports.libraryFiles[libPath]));
- let pathPtr = __newString(exports.libraryPrefix + libPath + extension.ext);
- assemblyscript.parse(program, textPtr, pathPtr, false);
- __unpin(textPtr);
- });
- });
- let customLibDirs = [];
- if (opts.lib) {
- let lib = opts.lib;
- if (typeof lib === "string") lib = lib.split(",");
- customLibDirs.push(...lib.map(p => p.trim()));
- customLibDirs = unique(customLibDirs); // `lib` and `customLibDirs` may include duplicates
- for (let i = 0, k = customLibDirs.length; i < k; ++i) { // custom
- let libDir = customLibDirs[i];
- let libFiles;
- if (libDir.endsWith(extension.ext)) {
- libFiles = [ path.basename(libDir) ];
- libDir = path.dirname(libDir);
- } else {
- libFiles = listFiles(libDir, baseDir) || [];
- }
- for (let j = 0, l = libFiles.length; j < l; ++j) {
- let libPath = libFiles[j];
- let libText = readFile(libPath, libDir);
- if (libText === null) return callback(Error("Library file '" + libPath + "' not found."));
- stats.parseCount++;
- exports.libraryFiles[libPath.replace(extension.re, "")] = libText;
- stats.parseTime += measure(() => {
- let textPtr = __pin(__newString(libText));
- let pathPtr = __newString(exports.libraryPrefix + libPath);
- assemblyscript.parse(program, textPtr, pathPtr, false);
- __unpin(textPtr);
- });
- }
- }
- }
- opts.path = opts.path || [];
-
- // Maps package names to parent directory
- var packageMains = new Map();
- var packageBases = new Map();
-
- // Gets the file matching the specified source path, imported at the given dependee path
- function getFile(internalPath, dependeePath) {
- var sourceText = null; // text reported back to the compiler
- var sourcePath = null; // path reported back to the compiler
-
- const libraryPrefix = exports.libraryPrefix;
- const libraryFiles = exports.libraryFiles;
-
- // Try file.ext, file/index.ext, file.d.ext
- if (!internalPath.startsWith(libraryPrefix)) {
- if ((sourceText = readFile(sourcePath = internalPath + extension.ext, baseDir)) == null) {
- if ((sourceText = readFile(sourcePath = internalPath + "/index" + extension.ext, baseDir)) == null) {
- // portable d.ext: uses the .js file next to it in JS or becomes an import in Wasm
- sourcePath = internalPath + extension.ext;
- sourceText = readFile(internalPath + extension.ext_d, baseDir);
- }
- }
-
- // Search library in this order: stdlib, custom lib dirs, paths
- } else {
- const plainName = internalPath.substring(libraryPrefix.length);
- const indexName = plainName + "/index";
- if (Object.prototype.hasOwnProperty.call(libraryFiles, plainName)) {
- sourceText = libraryFiles[plainName];
- sourcePath = libraryPrefix + plainName + extension.ext;
- } else if (Object.prototype.hasOwnProperty.call(libraryFiles, indexName)) {
- sourceText = libraryFiles[indexName];
- sourcePath = libraryPrefix + indexName + extension.ext;
- } else { // custom lib dirs
- for (const libDir of customLibDirs) {
- if ((sourceText = readFile(plainName + extension.ext, libDir)) != null) {
- sourcePath = libraryPrefix + plainName + extension.ext;
- break;
- } else {
- if ((sourceText = readFile(indexName + extension.ext, libDir)) != null) {
- sourcePath = libraryPrefix + indexName + extension.ext;
- break;
- }
- }
- }
- if (sourceText == null) { // paths
- const match = internalPath.match(/^~lib\/((?:@[^/]+\/)?[^/]+)(?:\/(.+))?/); // ~lib/(pkg)/(path), ~lib/(@org/pkg)/(path)
- if (match) {
- const packageName = match[1];
- const isPackageRoot = match[2] === undefined;
- const filePath = isPackageRoot ? "index" : match[2];
- const basePath = packageBases.has(dependeePath) ? packageBases.get(dependeePath) : ".";
- if (opts.traceResolution) stderr.write("Looking for package '" + packageName + "' file '" + filePath + "' relative to '" + basePath + "'" + EOL);
- const paths = [];
- const parts = path.resolve(baseDir, basePath).split(SEP);
- for (let i = parts.length, k = WIN ? 1 : 0; i >= k; --i) {
- if (parts[i - 1] !== "node_modules") paths.push(parts.slice(0, i).join(SEP) + SEP + "node_modules");
- }
- for (const currentPath of paths.concat(...opts.path).map(p => path.relative(baseDir, p))) {
- if (opts.traceResolution) stderr.write(" in " + path.join(currentPath, packageName) + EOL);
- let mainPath = "assembly";
- if (packageMains.has(packageName)) { // use cached
- mainPath = packageMains.get(packageName);
- } else { // evaluate package.json
- let jsonPath = path.join(currentPath, packageName, "package.json");
- let jsonText = readFile(jsonPath, baseDir);
- if (jsonText != null) {
- try {
- let json = JSON.parse(jsonText);
- if (typeof json.ascMain === "string") {
- mainPath = json.ascMain.replace(extension.re_index, "");
- packageMains.set(packageName, mainPath);
- }
- } catch (e) { /* nop */ }
- }
- }
- const mainDir = path.join(currentPath, packageName, mainPath);
- const plainName = filePath;
- if ((sourceText = readFile(path.join(mainDir, plainName + extension.ext), baseDir)) != null) {
- sourcePath = libraryPrefix + packageName + "/" + plainName + extension.ext;
- packageBases.set(sourcePath.replace(extension.re, ""), path.join(currentPath, packageName));
- if (opts.traceResolution) stderr.write(" -> " + path.join(mainDir, plainName + extension.ext) + EOL);
- break;
- } else if (!isPackageRoot) {
- const indexName = filePath + "/index";
- if ((sourceText = readFile(path.join(mainDir, indexName + extension.ext), baseDir)) !== null) {
- sourcePath = libraryPrefix + packageName + "/" + indexName + extension.ext;
- packageBases.set(sourcePath.replace(extension.re, ""), path.join(currentPath, packageName));
- if (opts.traceResolution) stderr.write(" -> " + path.join(mainDir, indexName + extension.ext) + EOL);
- break;
- }
- }
- }
- }
- }
- }
- }
- // No such file
- if (sourceText == null) return null;
- return { sourceText, sourcePath };
- }
-
- // Parses the backlog of imported files after including entry files
- function parseBacklog() {
- var internalPath;
- while ((internalPath = __getString(assemblyscript.nextFile(program)))) {
- let file = getFile(internalPath, assemblyscript.getDependee(program, internalPath));
- if (file) {
- stats.parseCount++;
- stats.parseTime += measure(() => {
- let textPtr = __pin(__newString(file.sourceText));
- let pathPtr = __newString(file.sourcePath);
- assemblyscript.parse(program, textPtr, pathPtr, false);
- __unpin(textPtr);
- });
- } else {
- stats.parseTime += measure(() => {
- let textPtr = __newString(null); // no need to pin
- let pathPtr = __newString(internalPath + extension.ext);
- assemblyscript.parse(program, textPtr, pathPtr, false);
- });
- }
- }
- var numErrors = checkDiagnostics(program, stderr, options.reportDiagnostic);
- if (numErrors) {
- const err = Error(numErrors + " parse error(s)");
- err.stack = err.message; // omit stack
- return callback(err);
- }
- }
-
- // Include runtime before entry files so its setup runs first
- {
- let runtimeName = String(opts.runtime);
- let runtimePath = "rt/index-" + runtimeName;
- let runtimeText = exports.libraryFiles[runtimePath];
- if (runtimeText == null) {
- runtimePath = runtimeName;
- runtimeText = readFile(runtimePath + extension.ext, baseDir);
- if (runtimeText == null) return callback(Error(`Runtime '${runtimeName}' not found.`));
- } else {
- runtimePath = "~lib/" + runtimePath;
- }
- stats.parseCount++;
- stats.parseTime += measure(() => {
- let textPtr = __pin(__newString(runtimeText));
- let pathPtr = __newString(runtimePath + extension.ext);
- assemblyscript.parse(program, textPtr, pathPtr, true);
- __unpin(textPtr);
- });
- }
-
- // Include entry files
- for (let i = 0, k = argv.length; i < k; ++i) {
- const filename = argv[i];
-
- let sourcePath = String(filename).replace(/\\/g, "/").replace(extension.re, "").replace(/[\\/]$/, "");
-
- // Setting the path to relative path
- sourcePath = path.isAbsolute(sourcePath) ? path.relative(baseDir, sourcePath).replace(/\\/g, "/") : sourcePath;
-
- // Try entryPath.ext, then entryPath/index.ext
- let sourceText = readFile(sourcePath + extension.ext, baseDir);
- if (sourceText == null) {
- sourceText = readFile(sourcePath + "/index" + extension.ext, baseDir);
- if (sourceText != null) sourcePath += "/index" + extension.ext;
- else sourcePath += extension.ext;
- } else {
- sourcePath += extension.ext;
- }
-
- stats.parseCount++;
- stats.parseTime += measure(() => {
- let textPtr = __pin(__newString(sourceText));
- let pathPtr = __newString(sourcePath);
- assemblyscript.parse(program, textPtr, pathPtr, true);
- __unpin(textPtr);
- });
- }
-
- // Parse entry files
- {
- let code = parseBacklog();
- if (code) return code;
- }
-
- // Call afterParse transform hook
- {
- let error = applyTransform("afterParse", program.parser);
- if (error) return callback(error);
- }
-
- // Parse additional files, if any
- {
- let code = parseBacklog();
- if (code) return code;
- }
-
- // Print files and exit if listFiles
- if (opts.listFiles) {
- // FIXME: not a proper C-like API
- stderr.write(program.sources.map(s => s.normalizedPath).sort().join(EOL) + EOL);
- return callback(null);
- }
-
- // Pre-emptively initialize the program
- stats.initializeCount++;
- stats.initializeTime += measure(() => {
- try {
- assemblyscript.initializeProgram(program);
- } catch (e) {
- crash("initialize", e);
- }
- });
-
- // Call afterInitialize transform hook
- {
- let error = applyTransform("afterInitialize", program);
- if (error) return callback(error);
- }
-
- var module;
- stats.compileCount++;
- stats.compileTime += measure(() => {
- try {
- module = assemblyscript.compile(program);
- } catch (e) {
- crash("compile", e);
- }
- // From here on we are going to use Binaryen.js, except that we keep pass
- // order as defined in the compiler.
- if (typeof module === "number") { // Wasm
- const original = assemblyscript.Module.wrap(module);
- module = binaryen.wrapModule(original.ref);
- module.optimize = function(...args) {
- original.optimize(...args);
- };
- } else { // JS
- const original = module;
- module = binaryen.wrapModule(module.ref);
- module.optimize = function(...args) {
- original.optimize(...args);
- };
- }
- });
- var numErrors = checkDiagnostics(program, stderr, options.reportDiagnostic);
- if (numErrors) {
- if (module) module.dispose();
- const err = Error(numErrors + " compile error(s)");
- err.stack = err.message; // omit stack
- return callback(err);
- }
-
- // Call afterCompile transform hook
- {
- let error = applyTransform("afterCompile", module);
- if (error) return callback(error);
- }
-
- // Validate the module if requested
- if (!opts.noValidate) {
- stats.validateCount++;
- let isValid;
- stats.validateTime += measure(() => {
- isValid = module.validate();
- });
- if (!isValid) {
- module.dispose();
- return callback(Error("validate error"));
- }
- }
-
- // Set Binaryen-specific options
- if (opts.trapMode === "clamp") {
- stats.optimizeCount++;
- stats.optimizeTime += measure(() => {
- module.runPass("trap-mode-clamp");
- });
- } else if (opts.trapMode === "js") {
- stats.optimizeCount++;
- stats.optimizeTime += measure(() => {
- module.runPass("trap-mode-js");
- });
- } else if (opts.trapMode !== "allow") {
- module.dispose();
- return callback(Error("Unsupported trap mode"));
- }
-
- // Optimize the module
- const debugInfo = opts.debug;
- const converge = opts.converge;
- const runPasses = [];
- if (opts.runPasses) {
- if (typeof opts.runPasses === "string") {
- opts.runPasses = opts.runPasses.split(",");
- }
- if (opts.runPasses.length) {
- opts.runPasses.forEach(pass => {
- if (runPasses.indexOf(pass = pass.trim()) < 0) {
- runPasses.push(pass);
- }
- });
- }
- }
-
- stats.optimizeTime += measure(() => {
- stats.optimizeCount++;
- try {
- module.optimize(optimizeLevel, shrinkLevel, debugInfo);
- } catch (e) {
- crash("optimize", e);
- }
- try {
- module.runPasses(runPasses);
- } catch (e) {
- crash("runPasses", e);
- }
- if (converge) {
- let last;
- try {
- last = module.emitBinary();
- } catch (e) {
- crash("emitBinary (converge)", e);
- }
- do {
- stats.optimizeCount++;
- try {
- module.optimize(optimizeLevel, shrinkLevel, debugInfo);
- } catch (e) {
- crash("optimize (converge)", e);
- }
- try {
- module.runPasses(runPasses);
- } catch (e) {
- crash("runPasses (converge)", e);
- }
- let next;
- try {
- next = module.emitBinary();
- } catch (e) {
- crash("emitBinary (converge)", e);
- }
- if (next.length >= last.length) {
- if (next.length > last.length) {
- stderr.write("Last converge was suboptimial." + EOL);
- }
- break;
- }
- last = next;
- } while (true);
- }
- });
-
- // Prepare output
- if (!opts.noEmit) {
- if (opts.outFile != null) {
- if (/\.was?t$/.test(opts.outFile) && opts.textFile == null) {
- opts.textFile = opts.outFile;
- } else if (/\.js$/.test(opts.outFile) && opts.jsFile == null) {
- opts.jsFile = opts.outFile;
- } else if (opts.binaryFile == null) {
- opts.binaryFile = opts.outFile;
- }
- }
-
- let hasStdout = false;
- let hasOutput = opts.textFile != null
- || opts.binaryFile != null
- || opts.jsFile != null
- || opts.tsdFile != null
- || opts.idlFile != null;
-
- // Write binary
- if (opts.binaryFile != null) {
- let basename = path.basename(opts.binaryFile);
- let sourceMapURL = opts.sourceMap != null
- ? opts.sourceMap.length
- ? opts.sourceMap
- : "./" + basename + ".map"
- : null;
-
- let wasm;
- stats.emitCount++;
- stats.emitTime += measure(() => {
- try {
- wasm = module.emitBinary(sourceMapURL);
- } catch (e) {
- crash("emitBinary", e);
- }
- });
-
- if (opts.binaryFile.length) {
- writeFile(opts.binaryFile, wasm.binary, baseDir);
- } else {
- writeStdout(wasm.binary);
- hasStdout = true;
- }
-
- // Post-process source map
- if (wasm.sourceMap != "") {
- if (opts.binaryFile.length) {
- let map = JSON.parse(wasm.sourceMap);
- map.sourceRoot = "./" + basename;
- let contents = [];
- map.sources.forEach((name, index) => {
- let text = assemblyscript.getSource(program, __newString(name.replace(extension.re, "")));
- if (text == null) return callback(Error("Source of file '" + name + "' not found."));
- contents[index] = text;
- });
- map.sourcesContent = contents;
- writeFile(path.join(
- path.dirname(opts.binaryFile),
- path.basename(sourceMapURL)
- ).replace(/^\.\//, ""), JSON.stringify(map), baseDir);
- } else {
- stderr.write("Skipped source map (stdout already occupied)" + EOL);
- }
- }
- }
-
- // Write text (also fallback)
- if (opts.textFile != null || !hasOutput) {
- let out;
- if (opts.textFile != null && opts.textFile.length) {
- // use superset text format when extension is `.wast`.
- // Otherwise use official stack IR format (wat).
- let wastFormat = opts.textFile.endsWith('.wast');
- stats.emitCount++;
- stats.emitTime += measure(() => {
- try {
- if (wastFormat) {
- out = module.emitText();
- } else {
- out = module.emitStackIR(true);
- }
- } catch (e) {
- crash("emitText", e);
- }
- });
- writeFile(opts.textFile, out, baseDir);
- } else if (!hasStdout) {
- stats.emitCount++;
- stats.emitTime += measure(() => {
- try {
- out = module.emitStackIR(true);
- } catch (e) {
- crash("emitText", e);
- }
- });
- writeStdout(out);
- }
- }
-
- // Write WebIDL
- if (opts.idlFile != null) {
- let idl;
- if (opts.idlFile.length) {
- stats.emitCount++;
- stats.emitTime += measure(() => {
- try {
- idl = assemblyscript.buildIDL(program);
- } catch (e) {
- crash("buildIDL", e);
- }
- });
- writeFile(opts.idlFile, __getString(idl), baseDir);
- } else if (!hasStdout) {
- stats.emitCount++;
- stats.emitTime += measure(() => {
- try {
- idl = assemblyscript.buildIDL(program);
- } catch (e) {
- crash("buildIDL", e);
- }
- });
- writeStdout(__getString(idl));
- hasStdout = true;
- }
- }
-
- // Write TypeScript definition
- if (opts.tsdFile != null) {
- let tsd;
- if (opts.tsdFile.length) {
- stats.emitCount++;
- stats.emitTime += measure(() => {
- try {
- tsd = assemblyscript.buildTSD(program);
- } catch (e) {
- crash("buildTSD", e);
- }
- });
- writeFile(opts.tsdFile, __getString(tsd), baseDir);
- } else if (!hasStdout) {
- stats.emitCount++;
- stats.emitTime += measure(() => {
- try {
- tsd = assemblyscript.buildTSD(program);
- } catch (e) {
- crash("buildTSD", e);
- }
- });
- writeStdout(__getString(tsd));
- hasStdout = true;
- }
- }
-
- // Write JS (modifies the binary, so must be last)
- if (opts.jsFile != null) {
- let js;
- if (opts.jsFile.length) {
- stats.emitCount++;
- stats.emitTime += measure(() => {
- try {
- js = module.emitAsmjs();
- } catch (e) {
- crash("emitJS", e);
- }
- });
- writeFile(opts.jsFile, js, baseDir);
- } else if (!hasStdout) {
- stats.emitCount++;
- stats.emitTime += measure(() => {
- try {
- js = module.emitAsmjs();
- } catch (e) {
- crash("emitJS", e);
- }
- });
- writeStdout(js);
- }
- }
- }
-
- module.dispose();
- if (opts.measure) {
- printStats(stats, stderr);
- }
-
- return callback(null);
-
- function readFileNode(filename, baseDir) {
- let name = path.resolve(baseDir, filename);
- try {
- let text;
- stats.readCount++;
- stats.readTime += measure(() => {
- text = fs.readFileSync(name, "utf8");
- });
- return text;
- } catch (e) {
- return null;
- }
- }
-
- function writeFileNode(filename, contents, baseDir) {
- try {
- stats.writeCount++;
- stats.writeTime += measure(() => {
- const dirPath = path.resolve(baseDir, path.dirname(filename));
- filename = path.basename(filename);
- const outputFilePath = path.join(dirPath, filename);
- if (!fs.existsSync(dirPath)) mkdirp(dirPath);
- fs.writeFileSync(outputFilePath, contents);
- });
- return true;
- } catch (e) {
- return false;
- }
- }
-
- function listFilesNode(dirname, baseDir) {
- var files;
- try {
- stats.readCount++;
- stats.readTime += measure(() => {
- files = fs.readdirSync(path.join(baseDir, dirname))
- .filter(file => extension.re_except_d.test(file));
- });
- return files;
- } catch (e) {
- return null;
- }
- }
-
- function writeStdout(contents) {
- if (!writeStdout.used) {
- stats.writeCount++;
- writeStdout.used = true;
- }
- stats.writeTime += measure(() => {
- stdout.write(contents);
- });
- }
-};
-
-const toString = Object.prototype.toString;
-
-function isObject(arg) {
- return toString.call(arg) === "[object Object]";
-}
-
-function getAsconfig(file, baseDir, readFile) {
- const contents = readFile(file, baseDir);
- const location = path.join(baseDir, file);
- if (!contents) return null;
-
- // obtain the configuration
- let config;
- try {
- config = JSON.parse(contents);
- } catch(ex) {
- throw new Error("Asconfig is not valid json: " + location);
- }
-
- // validate asconfig shape
- if (config.options && !isObject(config.options)) {
- throw new Error("Asconfig.options is not an object: " + location);
- }
-
- if (config.include && !Array.isArray(config.include)) {
- throw new Error("Asconfig.include is not an array: " + location);
- }
-
- if (config.targets) {
- if (!isObject(config.targets)) {
- throw new Error("Asconfig.targets is not an object: " + location);
- }
- const targets = Object.keys(config.targets);
- for (let i = 0; i < targets.length; i++) {
- const target = targets[i];
- if (!isObject(config.targets[target])) {
- throw new Error("Asconfig.targets." + target + " is not an object: " + location);
- }
- }
- }
-
- if (config.extends && typeof config.extends !== "string") {
- throw new Error("Asconfig.extends is not a string: " + location);
- }
-
- return config;
-}
-
-exports.getAsconfig = getAsconfig;
-
-/** Checks diagnostics emitted so far for errors. */
-function checkDiagnostics(program, stderr, reportDiagnostic) {
- var numErrors = 0;
- do {
- let diagnosticPtr = assemblyscript.nextDiagnostic(program);
- if (!diagnosticPtr) break;
- __pin(diagnosticPtr);
- if (stderr) {
- stderr.write(
- __getString(assemblyscript.formatDiagnostic(diagnosticPtr, stderr.isTTY, true)) +
- EOL + EOL
- );
- }
- if (reportDiagnostic) {
- const diagnostic = __wrap(diagnosticPtr, assemblyscript.DiagnosticMessage);
- const range = __wrap(diagnostic.range, assemblyscript.Range);
- const relatedRange = __wrap(diagnostic.relatedRange, assemblyscript.Range);
- const rangeSource = range ? __wrap(range.source, assemblyscript.Source) : null;
- const relatedRangeSource = relatedRange ? __wrap(relatedRange.source, assemblyscript.Source) : null;
-
- reportDiagnostic({
- message: __getString(diagnostic.message),
- code: diagnostic.code,
- category: diagnostic.category,
- range: range ? {
- start: range.start,
- end: range.end,
- source: rangeSource ? {
- normalizedPath: __getString(rangeSource.normalizedPath)
- } : null,
- } : null,
- relatedRange: relatedRange ? {
- start: relatedRange.start,
- end: relatedRange.end,
- source: relatedRangeSource ? {
- normalizedPath: __getString(relatedRangeSource.normalizedPath)
- } : null
- } : null
- });
- }
- if (assemblyscript.isError(diagnosticPtr)) ++numErrors;
- __unpin(diagnosticPtr);
- } while (true);
- return numErrors;
-}
-
-exports.checkDiagnostics = checkDiagnostics;
-
-/** Creates an empty set of stats. */
-function createStats() {
- return {
- readTime: 0,
- readCount: 0,
- writeTime: 0,
- writeCount: 0,
- parseTime: 0,
- parseCount: 0,
- initializeTime: 0,
- initializeCount: 0,
- compileTime: 0,
- compileCount: 0,
- emitTime: 0,
- emitCount: 0,
- validateTime: 0,
- validateCount: 0,
- optimizeTime: 0,
- optimizeCount: 0,
- transformTime: 0,
- transformCount: 0
- };
-}
-
-exports.createStats = createStats;
-
-/** Measures the execution time of the specified function. */
-function measure(fn) {
- const start = process.hrtime();
- fn();
- const times = process.hrtime(start);
- return times[0] * 1e9 + times[1];
-}
-
-exports.measure = measure;
-
-function pad(str, len) {
- while (str.length < len) str = " " + str;
- return str;
-}
-
-/** Formats a high resolution time to a human readable string. */
-function formatTime(time) {
- return time ? (time / 1e6).toFixed(3) + " ms" : "n/a";
-}
-
-exports.formatTime = formatTime;
-
-/** Formats and prints out the contents of a set of stats. */
-function printStats(stats, output) {
- const format = (time, count) => pad(formatTime(time), 12) + " n=" + count;
- (output || process.stdout).write([
- "I/O Read : " + format(stats.readTime, stats.readCount),
- "I/O Write : " + format(stats.writeTime, stats.writeCount),
- "Parse : " + format(stats.parseTime, stats.parseCount),
- "Initialize : " + format(stats.initializeTime, stats.initializeCount),
- "Compile : " + format(stats.compileTime, stats.compileCount),
- "Emit : " + format(stats.emitTime, stats.emitCount),
- "Validate : " + format(stats.validateTime, stats.validateCount),
- "Optimize : " + format(stats.optimizeTime, stats.optimizeCount),
- "Transform : " + format(stats.transformTime, stats.transformCount),
- ""
- ].join(EOL) + EOL);
-}
-
-exports.printStats = printStats;
-
-var allocBuffer = typeof global !== "undefined" && global.Buffer
- ? global.Buffer.allocUnsafe || (len => new global.Buffer(len))
- : len => new Uint8Array(len);
-
-/** Creates a memory stream that can be used in place of stdout/stderr. */
-function createMemoryStream(fn) {
- var stream = [];
- stream.write = function(chunk) {
- if (fn) fn(chunk);
- if (typeof chunk === "string") {
- let buffer = allocBuffer(utf8.length(chunk));
- utf8.write(chunk, buffer, 0);
- chunk = buffer;
- }
- this.push(chunk);
- };
- stream.reset = function() {
- stream.length = 0;
- };
- stream.toBuffer = function() {
- var offset = 0, i = 0, k = this.length;
- while (i < k) offset += this[i++].length;
- var buffer = allocBuffer(offset);
- offset = i = 0;
- while (i < k) {
- buffer.set(this[i], offset);
- offset += this[i].length;
- ++i;
- }
- return buffer;
- };
- stream.toString = function() {
- var buffer = this.toBuffer();
- return utf8.read(buffer, 0, buffer.length);
- };
- return stream;
-}
-
-exports.createMemoryStream = createMemoryStream;
-
-/** Compatible TypeScript compiler options for syntax highlighting etc. */
-exports.tscOptions = {
- alwaysStrict: true,
- noImplicitAny: true,
- noImplicitReturns: true,
- noImplicitThis: true,
- noEmitOnError: true,
- strictNullChecks: true,
- experimentalDecorators: true,
- target: "esnext",
- module: "commonjs",
- noLib: true,
- types: [],
- allowJs: false
-};
-
-// Gracefully handle crashes
-function crash(stage, e) {
- const BAR = colorsUtil.red("▌ ");
- console.error([
- EOL,
- BAR, "Whoops, the AssemblyScript compiler has crashed during ", stage, " :-(", EOL,
- BAR, EOL,
- BAR, "Here is a stack trace that may or may not be useful:", EOL,
- BAR, EOL,
- e.stack.replace(/^/mg, BAR), EOL,
- BAR, EOL,
- BAR, "If it refers to the dist files, try to 'npm install source-map-support' and", EOL,
- BAR, "run again, which should then show the actual code location in the sources.", EOL,
- BAR, EOL,
- BAR, "If you see where the error is, feel free to send us a pull request. If not,", EOL,
- BAR, "please let us know: https://github.com/AssemblyScript/assemblyscript/issues", EOL,
- BAR, EOL,
- BAR, "Thank you!", EOL
- ].join(""));
- process.exit(1);
-}
diff --git a/cli/asc.json b/cli/asc.json
deleted file mode 100644
index 68ed4aed4b..0000000000
--- a/cli/asc.json
+++ /dev/null
@@ -1,396 +0,0 @@
-{
- "version": {
- "category": "General",
- "description": "Prints just the compiler's version and exits.",
- "type": "b",
- "alias": "v"
- },
- "help": {
- "category": "General",
- "description": "Prints this message and exits.",
- "type": "b",
- "alias": "h"
- },
- "noColors": {
- "category": "General",
- "description": "Disables terminal colors.",
- "type": "b",
- "default": false
- },
- "config": {
- "category": "General",
- "description": "Configuration file to apply. CLI arguments take precedence.",
- "type": "s",
- "cliOnly": true
- },
- "target": {
- "category": "General",
- "description": "Target configuration to use. Defaults to 'release'.",
- "type": "s",
- "cliOnly": true
- },
-
- "optimize": {
- "category": "Optimization",
- "description": [
- "Optimizes the module. Typical shorthands are:",
- "",
- " Default optimizations -O / -O3s",
- " Make a release build -O --noAssert",
- " Make a debug build --debug",
- " Optimize for speed -Ospeed",
- " Optimize for size -Osize",
- ""
- ],
- "type": "b",
- "alias": "O"
- },
- "optimizeLevel": {
- "category": "Optimization",
- "description": "How much to focus on optimizing code. [0-3]",
- "type": "i"
- },
- "shrinkLevel": {
- "category": "Optimization",
- "description": "How much to focus on shrinking code size. [0-2, s=1, z=2]",
- "type": "i"
- },
- "converge": {
- "category": "Optimization",
- "description": "Re-optimizes until no further improvements can be made.",
- "type": "b",
- "default": false
- },
- "noAssert": {
- "category": "Optimization",
- "description": "Replaces assertions with just their value without trapping.",
- "type": "b",
- "default": false
- },
-
- "outFile": {
- "category": "Output",
- "description": "Specifies the output file. File extension indicates format.",
- "type": "s",
- "alias": "o",
- "isPath": true
- },
- "binaryFile": {
- "category": "Output",
- "description": "Specifies the binary output file (.wasm).",
- "type": "s",
- "alias": "b",
- "isPath": true
- },
- "textFile": {
- "category": "Output",
- "description": "Specifies the text output file (.wat).",
- "type": "s",
- "alias": "t",
- "isPath": true
- },
- "jsFile": {
- "category": "Output",
- "description": "Specifies the JavaScript (via wasm2js) output file (.js).",
- "type": "s",
- "alias": "j",
- "isPath": true
- },
- "idlFile": {
- "category": "Output",
- "description": "Specifies the WebIDL output file (.webidl).",
- "type": "s",
- "alias": "i",
- "isPath": true
- },
- "tsdFile": {
- "category": "Output",
- "description": "Specifies the TypeScript definition output file (.d.ts).",
- "type": "s",
- "alias": "d",
- "isPath": true
- },
-
- "sourceMap": {
- "category": "Debugging",
- "description": [
- "Enables source map generation. Optionally takes the URL",
- "used to reference the source map from the binary file."
- ],
- "type": "s"
- },
- "debug": {
- "category": "Debugging",
- "description": "Enables debug information in emitted binaries.",
- "type": "b",
- "default": false
- },
-
- "importMemory": {
- "category": "Features",
- "description": "Imports the memory from 'env.memory'.",
- "type": "b",
- "default": false
- },
- "noExportMemory": {
- "category": "Features",
- "description": "Does not export the memory as 'memory'.",
- "type": "b",
- "default": false
- },
- "initialMemory": {
- "category": "Features",
- "description": "Sets the initial memory size in pages.",
- "type": "i",
- "default": 0
- },
- "maximumMemory": {
- "category": "Features",
- "description": "Sets the maximum memory size in pages.",
- "type": "i",
- "default": 0
- },
- "sharedMemory": {
- "category": "Features",
- "description": "Declare memory as shared. Requires maximumMemory.",
- "type": "b",
- "default": false
- },
- "importTable": {
- "category": "Features",
- "description": "Imports the function table from 'env.table'.",
- "type": "b",
- "default": false
- },
- "exportTable": {
- "category": "Features",
- "description": "Exports the function table as 'table'.",
- "type": "b",
- "default": false
- },
- "runtime": {
- "category": "Features",
- "description": [
- "Specifies the runtime variant to include in the program.",
- "",
- " incremental TLSF + incremental GC (default)",
- " minimal TLSF + lightweight GC invoked externally",
- " stub Minimal runtime stub (never frees)",
- " ... Path to a custom runtime implementation",
- ""
- ],
- "type": "s",
- "default": "incremental"
- },
- "exportRuntime": {
- "category": "Features",
- "description": "Exports the runtime helpers (__new, __collect etc.).",
- "type": "b",
- "default": false
- },
- "stackSize": {
- "category": "Features",
- "description": [
- "Overrides the stack size. Only relevant for incremental GC",
- "or when using a custom runtime that requires stack space.",
- "Defaults to 0 without and to 16384 with incremental GC."
- ],
- "default": 0,
- "type": "i"
- },
- "explicitStart": {
- "category": "Features",
- "description": "Exports an explicit '_start' function to call.",
- "type": "b",
- "default": false
- },
- "enable": {
- "category": "Features",
- "description": [
- "Enables WebAssembly features being disabled by default.",
- "",
- " sign-extension Sign-extension operations",
- " nontrapping-f2i Non-trapping float to integer ops.",
- " bulk-memory Bulk memory operations.",
- " simd SIMD types and operations.",
- " threads Threading and atomic operations.",
- " reference-types Reference types and operations.",
- " gc Garbage collection (WIP).",
- ""
- ],
- "TODO_doesNothingYet": [
- " exception-handling Exception handling.",
- " tail-calls Tail call operations.",
- " multi-value Multi value types.",
- " memory64 Memory64 operations."
- ],
- "type": "S",
- "mutuallyExclusive": "disable"
- },
- "disable": {
- "category": "Features",
- "description": [
- "Disables WebAssembly features being enabled by default.",
- "",
- " mutable-globals Mutable global imports and exports.",
- ""
- ],
- "type": "S",
- "mutuallyExclusive": "enable"
- },
- "use": {
- "category": "Features",
- "description": [
- "Aliases a global object under another name, e.g., to switch",
- "the default 'Math' implementation used: --use Math=JSMath",
- "Can also be used to introduce an integer constant."
- ],
- "type": "S",
- "alias": "u"
- },
- "lowMemoryLimit": {
- "category": "Features",
- "description": "Enforces very low (<64k) memory constraints.",
- "default": 0,
- "type": "i"
- },
-
- "memoryBase": {
- "category": "Linking",
- "description": "Sets the start offset of emitted memory segments.",
- "type": "i",
- "default": 0
- },
- "tableBase": {
- "category": "Linking",
- "description": "Sets the start offset of emitted table elements.",
- "type": "i",
- "default": 0
- },
-
- "transform": {
- "category": "API",
- "description": "Specifies the path to a custom transform to 'require'.",
- "type": "S",
- "isPath": true,
- "useNodeResolution": true
- },
-
- "trapMode": {
- "category": "Binaryen",
- "description": [
- "Sets the trap mode to use.",
- "",
- " allow Allow trapping operations. This is the default.",
- " clamp Replace trapping operations with clamping semantics.",
- " js Replace trapping operations with JS semantics.",
- ""
- ],
- "type": "s",
- "default": "allow"
- },
- "runPasses": {
- "category": "Binaryen",
- "description": [
- "Specifies additional Binaryen passes to run after other",
- "optimizations, if any. See: Binaryen/src/passes/pass.cpp"
- ],
- "type": "s"
- },
- "noValidate": {
- "category": "Binaryen",
- "description": "Skips validating the module using Binaryen.",
- "type": "b",
- "default": false
- },
-
- "baseDir": {
- "description": "Specifies the base directory of input and output files.",
- "type": "s",
- "default": "."
- },
- "extension": {
- "description": "Specifies an alternative file extension to use.",
- "type": "s",
- "cliOnly": true
- },
- "noUnsafe": {
- "description": [
- "Disallows the use of unsafe features in user code.",
- "Does not affect library files and external modules."
- ],
- "type": "b",
- "default": false
- },
- "noEmit": {
- "description": "Performs compilation as usual but does not emit code.",
- "type": "b",
- "default": false
- },
- "showConfig": {
- "description": "Print computed compiler options and exit.",
- "type": "b",
- "default": false
- },
- "measure": {
- "description": "Prints measuring information on I/O and compile times.",
- "type": "b",
- "default": false
- },
- "pedantic": {
- "description": "Make yourself sad for no good reason.",
- "type": "b",
- "default": false
- },
- "lib": {
- "description": [
- "Adds one or multiple paths to custom library components and",
- "uses exports of all top-level files at this path as globals."
- ],
- "type": "S",
- "isPath": true
- },
- "path": {
- "description": [
- "Adds one or multiple paths to package resolution, similar",
- "to node_modules. Prefers an 'ascMain' entry in a package's",
- "package.json and falls back to an inner 'assembly/' folder."
- ],
- "type": "S",
- "isPath": true
- },
- "traceResolution": {
- "description": "Enables tracing of package resolution.",
- "type": "b",
- "default": false
- },
- "listFiles": {
- "description": "Lists files to be compiled and exits.",
- "type": "b",
- "default": false
- },
- "wasm": {
- "description": "Uses the specified Wasm binary of the compiler.",
- "type": "s"
- },
- " ...": {
- "description": "Specifies node.js options (CLI only). See: node --help"
- },
-
- "-Os": { "value": { "optimize": true, "shrinkLevel": 1 } },
- "-Oz": { "value": { "optimize": true, "shrinkLevel": 2 } },
- "-O0": { "value": { "optimizeLevel": 0, "shrinkLevel": 0 } },
- "-O1": { "value": { "optimizeLevel": 1, "shrinkLevel": 0 } },
- "-O2": { "value": { "optimizeLevel": 2, "shrinkLevel": 0 } },
- "-O3": { "value": { "optimizeLevel": 3, "shrinkLevel": 0 } },
- "-O0s": { "value": { "optimizeLevel": 0, "shrinkLevel": 1 } },
- "-O1s": { "value": { "optimizeLevel": 1, "shrinkLevel": 1 } },
- "-O2s": { "value": { "optimizeLevel": 2, "shrinkLevel": 1 } },
- "-O3s": { "value": { "optimizeLevel": 3, "shrinkLevel": 1 } },
- "-O0z": { "value": { "optimizeLevel": 0, "shrinkLevel": 2 } },
- "-O1z": { "value": { "optimizeLevel": 1, "shrinkLevel": 2 } },
- "-O2z": { "value": { "optimizeLevel": 2, "shrinkLevel": 2 } },
- "-O3z": { "value": { "optimizeLevel": 3, "shrinkLevel": 2 } },
- "-Ospeed": { "value": { "optimizeLevel": 3, "shrinkLevel": 0 } },
- "-Osize": { "value": { "optimizeLevel": 0, "shrinkLevel": 2, "converge": true } }
-}
diff --git a/cli/index.d.ts b/cli/index.d.ts
new file mode 100644
index 0000000000..58c7fb4ef6
--- /dev/null
+++ b/cli/index.d.ts
@@ -0,0 +1,284 @@
+/**
+ * @fileoverview Definitions for asc.
+ * @license Apache-2.0
+ */
+
+import { OptionDescription } from "../util/options";
+export { OptionDescription };
+
+/** AssemblyScript version. */
+export const version: string;
+
+/** Available CLI options. */
+export const options: { [key: string]: OptionDescription };
+
+/** Prefix used for library files. */
+export const libraryPrefix: string;
+
+/** Bundled library files. */
+export const libraryFiles: { [key: string]: string };
+
+/** Bundled definition files. */
+export const definitionFiles: { assembly: string, portable: string };
+
+/** Default Binaryen optimization level. */
+export const defaultOptimizeLevel: number;
+
+/** Default Binaryen shrink level. */
+export const defaultShrinkLevel: number;
+
+/** A compatible output stream. */
+export interface OutputStream {
+ /** Writes a chunk of data to the stream. */
+ write(chunk: Uint8Array | string): void;
+}
+
+/** An in-memory output stream. */
+export interface MemoryStream extends OutputStream {
+ /** Resets the stream to offset zero. */
+ reset(): void;
+ /** Converts the output to a buffer. */
+ toBuffer(): Uint8Array;
+ /** Converts the output to a string. */
+ toString(): string;
+}
+
+/** Relevant subset of the Source class for diagnostic reporting. */
+export interface Source {
+ /** Normalized path with file extension. */
+ normalizedPath: string;
+}
+
+/** Relevant subset of the Range class for diagnostic reporting. */
+export interface Range {
+ /** Start offset within the source file. */
+ start: number;
+ /** End offset within the source file. */
+ end: number;
+ /** Respective source file. */
+ source: Source;
+}
+
+/** Relevant subset of the DiagnosticMessage class for diagnostic reporting. */
+export interface DiagnosticMessage {
+ /** Message code. */
+ code: number;
+ /** Message category. */
+ category: number;
+ /** Message text. */
+ message: string;
+ /** Respective source range, if any. */
+ range: Range | null;
+ /** Related range, if any. */
+ relatedRange: Range | null;
+}
+
+/** A function handling diagnostic messages. */
+type DiagnosticReporter = (diagnostic: DiagnosticMessage) => void;
+
+/** Compiler options. */
+export interface CompilerOptions {
+ /** Prints just the compiler's version and exits. */
+ version?: boolean;
+ /** Prints the help message and exits. */
+ help?: boolean;
+ /** Optimizes the module. */
+ optimize?: boolean;
+ /** How much to focus on optimizing code. */
+ optimizeLevel?: number;
+ /** How much to focus on shrinking code size. */
+ shrinkLevel?: number;
+ /** Re-optimizes until no further improvements can be made. */
+ converge?: boolean;
+ /** Specifies the base directory of input and output files. */
+ baseDir?: string;
+ /** Specifies the WebAssembly output file (.wasm). */
+ outFile?: string;
+ /** Specifies the WebAssembly text output file (.wat). */
+ textFile?: string;
+ /** Specified the bindings to generate. */
+ bindings?: string[];
+ /** Enables source map generation. Optionally takes the URL. */
+ sourceMap?: boolean | string;
+ /** Specifies the runtime variant to include in the program. */
+ runtime?: string;
+ /** Disallows the use of unsafe features in user code. */
+ noUnsafe?: boolean;
+ /** Enables debug information in emitted binaries. */
+ debug?: boolean;
+ /** Replaces assertions with just their value without trapping. */
+ noAssert?: boolean;
+ /** Performs compilation as usual but does not emit code. */
+ noEmit?: boolean;
+ /** Imports the memory provided as 'env.memory'. */
+ importMemory?: boolean;
+ /** Does not export the memory as 'memory'. */
+ noExportMemory?: boolean;
+ /** Sets the initial memory size in pages. */
+ initialMemory?: number;
+ /** Sets the maximum memory size in pages. */
+ maximumMemory?: number;
+ /** Declare memory as shared. Requires maximumMemory. */
+ sharedMemory?: boolean;
+ /** Assume that imported memory is zero filled. Requires importMemory. */
+ zeroFilledMemory?: boolean;
+ /** Sets the start offset of compiler-generated static memory. */
+ memoryBase?: number;
+ /** Imports the function table provided as 'env.table'. */
+ importTable?: boolean;
+ /** Exports the function table as 'table'. */
+ exportTable?: boolean;
+ /** Exports the start function instead of calling it implicitly. */
+ exportStart?: string;
+ /** "Adds one or multiple paths to custom library components. */
+ lib?: string | string[];
+ /** Adds one or multiple paths to package resolution. */
+ path?: string | string[];
+ /** Aliases a global object under another name. */
+ use?: string | string[];
+ /** Sets the trap mode to use. */
+ trapMode?: "allow" | "clamp" | "js";
+ /** Specifies additional Binaryen passes to run. */
+ runPasses?: string | string[];
+ /** Skips validating the module using Binaryen. */
+ noValidate?: boolean;
+ /** Enables WebAssembly features that are disabled by default. */
+ enable?: string | string[];
+ /** Disables WebAssembly features that are enabled by default. */
+ disable?: string | string[];
+ /** Specifies the path to a custom transform to 'require'. */
+ transform?: string | string[];
+ /** Make yourself sad for no good reason. */
+ pedantic?: boolean;
+ /** Prints measuring information on I/O and compile times. */
+ stats?: boolean;
+ /** Disables terminal colors. */
+ noColors?: boolean;
+}
+
+/** Compiler API options. */
+export interface APIOptions {
+ /** Standard output stream to use. */
+ stdout?: OutputStream;
+ /** Standard error stream to use. */
+ stderr?: OutputStream;
+ /** Reads a file from disk (or memory). */
+ readFile?: (filename: string, baseDir: string) => (string | null) | Promise;
+ /** Writes a file to disk (or memory). */
+ writeFile?: (filename: string, contents: Uint8Array | string, baseDir: string) => void | Promise;
+ /** Lists all files within a directory. */
+ listFiles?: (dirname: string, baseDir: string) => (string[] | null) | Promise;
+ /** Handler for diagnostic messages. */
+ reportDiagnostic?: DiagnosticReporter;
+ /** Additional transforms to apply. */
+ transforms?: Transform[];
+}
+
+/** Compiler API result. */
+export interface APIResult {
+ /** Encountered error, if any. */
+ error: Error | null;
+ /** Standard output stream. */
+ stdout: OutputStream;
+ /** Standard error stream. */
+ stderr: OutputStream;
+ /** Statistics. */
+ stats: Stats;
+}
+
+/** Runs the command line utility using the specified arguments array. */
+export function main(argv: string[] | CompilerOptions, options?: APIOptions): Promise;
+
+/** Convenience function that parses and compiles source strings directly. */
+export function compileString(sources: { [key: string]: string } | string, options?: CompilerOptions): Promise;
+
+/** Checks diagnostics emitted so far for errors. */
+export function checkDiagnostics(emitter: Record, stderr?: OutputStream, reportDiagnostic?: DiagnosticReporter, useColors?: boolean): boolean;
+
+/** Statistics for the current task. */
+export class Stats {
+ /** Number of files read. */
+ readCount: number;
+ /** Number of files written. */
+ writeCount: number;
+ /** Time taken to parse files. */
+ parseTime: number;
+ /** Number of files parsed. */
+ parseCount: number;
+ /** Time taken to compile programs. */
+ compileTime: number;
+ /** Number of programs compiled. */
+ compileCount: number;
+ /** Time taken to emit files. */
+ emitTime: number;
+ /** Number of emitted files. */
+ emitCount: number;
+ /** Time taken to validate modules. */
+ validateTime: number;
+ /** Number of modules validated. */
+ validateCount: number;
+ /** Time taken to optimize modules. */
+ optimizeTime: number;
+ /** Number of modules optimized. */
+ optimizeCount: number;
+ /** Begins measuring execution time. */
+ begin(): number;
+ /** Ends measuring execution time since `begin`. */
+ end(begin: number): number;
+ /** Returns a string representation. */
+ toString(): string;
+}
+
+/** Creates a memory stream that can be used in place of stdout/stderr. */
+export function createMemoryStream(fn?: (chunk: Uint8Array | string) => void): MemoryStream;
+
+/** Compatible TypeScript compiler options for syntax highlighting etc. */
+export const tscOptions: Record;
+
+import binaryen from "../lib/binaryen";
+import { Program, Parser } from "../src";
+
+/** Compiler transform base class. */
+export abstract class Transform {
+
+ /** Program reference. */
+ readonly program: Program;
+
+ /** Binaryen reference. */
+ readonly binaryen: typeof binaryen;
+
+ /** Base directory. */
+ readonly baseDir: string;
+
+ /** Output stream used by the compiler. */
+ readonly stdout: OutputStream;
+
+ /** Error stream used by the compiler. */
+ readonly stderr: OutputStream;
+
+ /** Logs a message to console. */
+ readonly log: typeof console.log;
+
+ /** Reads a file from disk. */
+ readFile(filename: string, baseDir: string): (string | null) | Promise;
+
+ /** Writes a file to disk. */
+ writeFile(filename: string, contents: string | Uint8Array, baseDir: string): void | Promise;
+
+ /** Lists all files in a directory. */
+ listFiles(dirname: string, baseDir: string): (string[] | null) | Promise;
+
+ /** Called when parsing is complete, before a program is instantiated from the AST. */
+ afterParse?(parser: Parser): void | Promise;
+
+ /** Called after the program is instantiated. */
+ afterInitialize?(program: Program): void | Promise;
+
+ /** Called when compilation is complete, before the module is being validated. */
+ afterCompile?(module: binaryen.Module): void | Promise;
+}
diff --git a/cli/index.js b/cli/index.js
new file mode 100644
index 0000000000..7e202e4f61
--- /dev/null
+++ b/cli/index.js
@@ -0,0 +1,1290 @@
+/**
+ * @license
+ * Copyright 2020 Daniel Wirtz / The AssemblyScript Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+/**
+ * @fileoverview Compiler frontend for node.js
+ *
+ * Uses the low-level API exported from src/index.ts so it works with the compiler compiled to
+ * JavaScript as well as the compiler compiled to WebAssembly (eventually).
+ *
+ * Can also be packaged as a bundle suitable for in-browser use with the standard library injected
+ * in the build step. See dist/asc.js for the bundle.
+ */
+
+import { fs, module, path, process, url } from "../util/node.js";
+import { Colors } from "../util/terminal.js";
+import { utf8 } from "../util/text.js";
+import * as optionsUtil from "../util/options.js";
+import * as generated from "./index.generated.js";
+
+import binaryen from "../lib/binaryen.js";
+import * as assemblyscriptJS from "assemblyscript";
+
+// Use the TS->JS variant by default
+let assemblyscript = assemblyscriptJS;
+
+// Use the AS->Wasm variant as an option (experimental)
+const wasmPos = process.argv.indexOf("--wasm");
+if (~wasmPos) {
+ const wasmPath = String(process.argv[wasmPos + 1]);
+ process.argv.splice(wasmPos, 2);
+ assemblyscript = await import(new URL(wasmPath, url.pathToFileURL(process.cwd() + "/")));
+}
+
+const require = module.createRequire(import.meta.url);
+
+const WIN = process.platform === "win32";
+const EOL = WIN ? "\r\n" : "\n";
+const SEP = WIN ? "\\" : "/";
+
+const extension = ".ts";
+const extension_d = `.d${extension}`;
+const extension_re = new RegExp("\\" + extension + "$");
+const extension_re_except_d = new RegExp("^(?!.*\\.d\\" + extension + "$).*\\" + extension + "$");
+
+function toUpperSnakeCase(str) {
+ return str.replace(/-/g, "_").toUpperCase();
+}
+
+function isNonEmptyString(value) {
+ return typeof value === "string" && value !== "";
+}
+
+/** Ensures that an object is a wrapper class instead of just a pointer. */
+// function __wrap(ptrOrObj, wrapperClass) {
+// if (typeof ptrOrObj === "number") {
+// return ptrOrObj === 0 ? null : wrapperClass.wrap(ptrOrObj);
+// }
+// return ptrOrObj;
+// }
+
+/** AssemblyScript version. */
+export const version = generated.version;
+
+/** Available CLI options. */
+export const options = generated.options;
+
+/** Prefix used for library files. */
+export const libraryPrefix = generated.libraryPrefix;
+
+/** Bundled library files. */
+export const libraryFiles = generated.libraryFiles;
+
+/** Bundled definition files. */
+export const definitionFiles = generated.definitionFiles;
+
+/** Default Binaryen optimization level. */
+export const defaultOptimizeLevel = 3;
+
+/** Default Binaryen shrink level. */
+export const defaultShrinkLevel = 0;
+
+/** Converts a configuration object to an arguments array. */
+export function configToArguments(options, argv = []) {
+ Object.keys(options || {}).forEach(key => {
+ const val = options[key];
+ const opt = generated.options[key];
+ if (opt && opt.type === "b") {
+ if (val) argv.push(`--${key}`);
+ } else {
+ if (Array.isArray(val)) {
+ val.forEach(val => { argv.push(`--${key}`, String(val)); });
+ }
+ else argv.push(`--${key}`, String(val));
+ }
+ });
+ return argv;
+}
+
+/** Convenience function that parses and compiles source strings directly. */
+export async function compileString(sources, config = {}) {
+ if (typeof sources === "string") sources = { [`input${extension}`]: sources };
+ let argv = [
+ "--outFile", "binary",
+ "--textFile", "text",
+ ];
+ configToArguments(config, argv);
+ const output = {};
+ const result = await main(argv.concat(Object.keys(sources)), {
+ readFile: name => Object.prototype.hasOwnProperty.call(sources, name) ? sources[name] : null,
+ writeFile: (name, contents) => { output[name] = contents; },
+ listFiles: () => []
+ });
+ return Object.assign(result, output);
+}
+
+/** Runs the command line utility using the specified arguments array. */
+export async function main(argv, options) {
+ if (!Array.isArray(argv)) argv = configToArguments(argv);
+ if (!options) options = {};
+
+ const stats = options.stats || new Stats();
+ const statsBegin = stats.begin();
+
+ // Bundle semantic version
+ let bundleMinorVersion = 0, bundleMajorVersion = 0, bundlePatchVersion = 0;
+ const versionParts = (version || "").split(".");
+ if (versionParts.length === 3) {
+ bundleMajorVersion = parseInt(versionParts[0]) | 0;
+ bundleMinorVersion = parseInt(versionParts[1]) | 0;
+ bundlePatchVersion = parseInt(versionParts[2]) | 0;
+ }
+
+ const stdout = options.stdout || createMemoryStream();
+ const stderr = options.stderr || createMemoryStream();
+ const readFile = options.readFile || readFileNode;
+ const writeFile = options.writeFile || writeFileNode;
+ const listFiles = options.listFiles || listFilesNode;
+
+ // Parse command line options but do not populate option defaults yet
+ const optionsResult = optionsUtil.parse(argv, generated.options, false);
+ let opts = optionsResult.options;
+ argv = optionsResult.arguments;
+
+ const stdoutColors = new Colors(stdout);
+ const stderrColors = new Colors(stderr);
+ if (opts.noColors) {
+ stdoutColors.enabled = false;
+ stderrColors.enabled = false;
+ }
+
+ // Check for unknown options
+ const unknownOpts = optionsResult.unknown;
+ if (unknownOpts.length) {
+ unknownOpts.forEach(arg => {
+ stderr.write(
+ `${stderrColors.yellow("WARNING ")}Unknown option '${arg}'${EOL}`
+ );
+ });
+ }
+
+ // Check for trailing arguments
+ const trailingArgv = optionsResult.trailing;
+ if (trailingArgv.length) {
+ stderr.write(
+ `${stderrColors.yellow("WARNING ")}Unsupported trailing arguments: ${trailingArgv.join(" ")}${EOL}`
+ );
+ }
+
+ let module = null;
+ let binaryenModule = null;
+
+ // Prepares the result object
+ let prepareResult = (error, result = {}) => {
+ if (error) {
+ stderr.write(`${stderrColors.red("FAILURE ")}${error.stack.replace(/^ERROR: /i, "")}${EOL}`);
+ }
+ if (binaryenModule) binaryenModule.dispose();
+ if (!stats.total) stats.total = stats.end(statsBegin);
+ return Object.assign({ error, stdout, stderr, stats }, result);
+ };
+
+ // Just print the version if requested
+ if (opts.version) {
+ stdout.write(`Version ${version}${EOL}`);
+ return prepareResult(null);
+ }
+
+ // Set up base directory
+ const baseDir = path.normalize(opts.baseDir || ".");
+
+ // Check if a config file is present
+ let configPath = optionsUtil.resolvePath(opts.config || "asconfig.json", baseDir);
+ let configFile = path.basename(configPath);
+ let configDir = path.dirname(configPath);
+ let config = await getConfig(configFile, configDir, readFile);
+ let configHasEntries = config != null && Array.isArray(config.entries) && config.entries.length;
+
+ // Print the help message if requested or no source files are provided
+ if (opts.help || (!argv.length && !configHasEntries)) {
+ let out = opts.help ? stdout : stderr;
+ let colors = opts.help ? stdoutColors : stderrColors;
+ out.write([
+ colors.white("SYNTAX"),
+ " " + colors.cyan("asc") + " [entryFile ...] [options]",
+ "",
+ colors.white("EXAMPLES"),
+ " " + colors.cyan("asc") + " hello" + extension,
+ " " + colors.cyan("asc") + " hello" + extension + " -o hello.wasm -t hello.wat",
+ " " + colors.cyan("asc") + " hello1" + extension + " hello2" + extension + " -o -O > hello.wasm",
+ " " + colors.cyan("asc") + " --config asconfig.json --target release",
+ "",
+ colors.white("OPTIONS"),
+ ].concat(
+ optionsUtil.help(generated.options, 24, EOL)
+ ).join(EOL) + EOL);
+ return prepareResult(null);
+ }
+
+ // I/O must be specified if not present in the environment
+ if (!(fs.promises && fs.promises.readFile)) {
+ if (readFile === readFileNode) throw Error("'options.readFile' must be specified");
+ if (writeFile === writeFileNode) throw Error("'options.writeFile' must be specified");
+ if (listFiles === listFilesNode) throw Error("'options.listFiles' must be specified");
+ }
+
+ // Load additional options from asconfig.json
+ const seenAsconfig = new Set();
+ seenAsconfig.add(configPath);
+ const target = opts.target || "release";
+ while (config) {
+ // Merge target first
+ if (config.targets) {
+ const targetOptions = config.targets[target];
+ if (targetOptions) {
+ opts = optionsUtil.merge(generated.options, opts, targetOptions, configDir);
+ }
+ }
+ // Merge general options
+ const generalOptions = config.options;
+ if (generalOptions) {
+ opts = optionsUtil.merge(generated.options, opts, generalOptions, configDir);
+ }
+
+ // Append entries
+ if (config.entries) {
+ for (let entry of config.entries) {
+ argv.push(optionsUtil.resolvePath(entry, configDir));
+ }
+ }
+
+ // Look up extended asconfig and repeat
+ if (config.extends) {
+ configPath = optionsUtil.resolvePath(config.extends, configDir, true);
+ configFile = path.basename(configPath);
+ configDir = path.dirname(configPath);
+ if (seenAsconfig.has(configPath)) break;
+ seenAsconfig.add(configPath);
+ config = await getConfig(configFile, configDir, readFile);
+ } else {
+ break;
+ }
+ }
+
+ // Populate option defaults once user-defined options are set
+ optionsUtil.addDefaults(generated.options, opts);
+
+ // If showConfig print options and exit
+ if (opts.showConfig) {
+ stderr.write(JSON.stringify({
+ options: opts,
+ entries: argv
+ }, null, 2));
+ return prepareResult(null);
+ }
+
+ // create a unique set of values
+ function unique(values) {
+ return [...new Set(values)];
+ }
+
+ // Set up options
+ let program, runtime, uncheckedBehavior;
+ const compilerOptions = assemblyscript.newOptions();
+ switch (opts.runtime) {
+ case "stub": runtime = 0; break;
+ case "minimal": runtime = 1; break;
+ /* incremental */
+ default: runtime = 2; break;
+ }
+ switch (opts.uncheckedBehavior) {
+ /* default */
+ default: uncheckedBehavior = 0; break;
+ case "never": uncheckedBehavior = 1; break;
+ case "always": uncheckedBehavior = 2; break;
+ }
+ assemblyscript.setTarget(compilerOptions, 0);
+ assemblyscript.setDebugInfo(compilerOptions, !!opts.debug);
+ assemblyscript.setRuntime(compilerOptions, runtime);
+ assemblyscript.setNoAssert(compilerOptions, opts.noAssert);
+ assemblyscript.setExportMemory(compilerOptions, !opts.noExportMemory);
+ assemblyscript.setImportMemory(compilerOptions, opts.importMemory);
+ assemblyscript.setInitialMemory(compilerOptions, opts.initialMemory >>> 0);
+ assemblyscript.setMaximumMemory(compilerOptions, opts.maximumMemory >>> 0);
+ assemblyscript.setSharedMemory(compilerOptions, opts.sharedMemory);
+ assemblyscript.setImportTable(compilerOptions, opts.importTable);
+ assemblyscript.setExportTable(compilerOptions, opts.exportTable);
+ if (opts.exportStart != null) {
+ assemblyscript.setExportStart(compilerOptions, isNonEmptyString(opts.exportStart) ? opts.exportStart : "_start");
+ }
+ assemblyscript.setMemoryBase(compilerOptions, opts.memoryBase >>> 0);
+ assemblyscript.setTableBase(compilerOptions, opts.tableBase >>> 0);
+ assemblyscript.setSourceMap(compilerOptions, opts.sourceMap != null);
+ assemblyscript.setUncheckedBehavior(compilerOptions, uncheckedBehavior);
+ assemblyscript.setNoUnsafe(compilerOptions, opts.noUnsafe);
+ assemblyscript.setPedantic(compilerOptions, opts.pedantic);
+ assemblyscript.setLowMemoryLimit(compilerOptions, opts.lowMemoryLimit >>> 0);
+ assemblyscript.setExportRuntime(compilerOptions, opts.exportRuntime);
+ assemblyscript.setBundleVersion(compilerOptions, bundleMajorVersion, bundleMinorVersion, bundlePatchVersion);
+ if (!opts.stackSize && runtime === 2 /* incremental */) {
+ opts.stackSize = assemblyscript.DEFAULT_STACK_SIZE;
+ }
+ assemblyscript.setStackSize(compilerOptions, opts.stackSize);
+ assemblyscript.setBindingsHint(compilerOptions, opts.bindings && opts.bindings.length > 0);
+
+ // Instrument callback to perform GC
+ // prepareResult = (original => {
+ // return function gcBeforePrepareResult(err) {
+ // __unpin(compilerOptions);
+ // if (program) __unpin(program);
+ // __collect();
+ // return original(err);
+ // };
+ // })(prepareResult);
+
+ // Add or override aliases if specified
+ if (opts.use) {
+ let aliases = opts.use;
+ for (let i = 0, k = aliases.length; i < k; ++i) {
+ let part = aliases[i];
+ let p = part.indexOf("=");
+ if (p < 0) return prepareResult(Error(`Global alias '${part}' is invalid.`));
+ let alias = part.substring(0, p).trim();
+ let name = part.substring(p + 1).trim();
+ if (!alias.length) {
+ return prepareResult(Error(`Global alias '${part}' is invalid.`));
+ }
+ assemblyscript.addGlobalAlias(compilerOptions, alias, name);
+ }
+ }
+
+ // Disable default features if specified
+ let features;
+ if ((features = opts.disable) != null) {
+ if (typeof features === "string") features = features.split(",");
+ for (let i = 0, k = features.length; i < k; ++i) {
+ let name = features[i].trim();
+ let flag = assemblyscript[`FEATURE_${toUpperSnakeCase(name)}`];
+ if (!flag) return prepareResult(Error(`Feature '${name}' is unknown.`));
+ assemblyscript.setFeature(compilerOptions, flag, false);
+ }
+ }
+
+ // Enable experimental features if specified
+ if ((features = opts.enable) != null) {
+ if (typeof features === "string") features = features.split(",");
+ for (let i = 0, k = features.length; i < k; ++i) {
+ let name = features[i].trim();
+ let flag = assemblyscript[`FEATURE_${toUpperSnakeCase(name)}`];
+ if (!flag) return prepareResult(Error(`Feature '${name}' is unknown.`));
+ assemblyscript.setFeature(compilerOptions, flag, true);
+ }
+ }
+
+ // Set up optimization levels
+ let optimizeLevel = 0;
+ let shrinkLevel = 0;
+ if (opts.optimize) {
+ optimizeLevel = defaultOptimizeLevel;
+ shrinkLevel = defaultShrinkLevel;
+ }
+ if (typeof opts.optimizeLevel === "number") optimizeLevel = opts.optimizeLevel;
+ if (typeof opts.shrinkLevel === "number") shrinkLevel = opts.shrinkLevel;
+ optimizeLevel = Math.min(Math.max(optimizeLevel, 0), 3);
+ shrinkLevel = Math.min(Math.max(shrinkLevel, 0), 2);
+ assemblyscript.setOptimizeLevelHints(compilerOptions, optimizeLevel, shrinkLevel);
+
+ // Initialize the program
+ program = assemblyscript.newProgram(compilerOptions);
+
+ // Collect transforms *constructors* from the `--transform` CLI flag as well
+ // as the `transform` option into the `transforms` array.
+ let transforms = [];
+ // `transform` option from `main()`
+ if (Array.isArray(options.transforms)) {
+ transforms.push(...options.transforms);
+ }
+ // `--transform` CLI flag
+ if (opts.transform) {
+ let transformArgs = unique(opts.transform);
+ for (let i = 0, k = transformArgs.length; i < k; ++i) {
+ let filename = transformArgs[i].trim();
+ let resolved;
+ let transform;
+ if (require.resolve) {
+ try {
+ resolved = require.resolve(filename, { paths: [process.cwd(), baseDir] });
+ transform = await import(url.pathToFileURL(resolved));
+ if (transform.default) transform = transform.default;
+ } catch (e1) {
+ try {
+ transform = require(resolved);
+ } catch {
+ return prepareResult(e1);
+ }
+ }
+ } else {
+ try {
+ transform = await import(new URL(filename, import.meta.url));
+ if (transform.default) transform = transform.default;
+ } catch (e) {
+ return prepareResult(e);
+ }
+ }
+ if (!transform || (typeof transform !== "function" && typeof transform !== "object")) {
+ return prepareResult(Error("not a transform: " + transformArgs[i]));
+ }
+ transforms.push(transform);
+ }
+ }
+
+ // Fix up the prototype of the transforms’ constructors and instantiate them.
+ try {
+ transforms = transforms.map(transform => {
+ if (typeof transform === "function") {
+ Object.assign(transform.prototype, {
+ program,
+ binaryen,
+ baseDir,
+ stdout,
+ stderr,
+ log: console.error,
+ readFile,
+ writeFile,
+ listFiles
+ });
+ transform = new transform();
+ }
+ return transform;
+ });
+ } catch (e) {
+ return prepareResult(e);
+ }
+
+ async function applyTransform(name, ...args) {
+ for (let i = 0, k = transforms.length; i < k; ++i) {
+ let transform = transforms[i];
+ if (typeof transform[name] === "function") {
+ try {
+ let start = stats.begin();
+ stats.transformCount++;
+ await transform[name](...args);
+ stats.transformTime += stats.end(start);
+ } catch (e) {
+ return e;
+ }
+ }
+ }
+ }
+
+ // Parse library files
+ Object.keys(libraryFiles).forEach(libPath => {
+ if (libPath.includes("/")) return; // in sub-directory: imported on demand
+ let begin = stats.begin();
+ stats.parseCount++;
+ assemblyscript.parse(program, libraryFiles[libPath], libraryPrefix + libPath + extension, false);
+ stats.parseTime += stats.end(begin);
+ });
+ let customLibDirs = [];
+ if (opts.lib) {
+ let lib = opts.lib;
+ if (typeof lib === "string") lib = lib.split(",");
+ customLibDirs.push(...lib.map(p => p.trim()));
+ customLibDirs = unique(customLibDirs); // `lib` and `customLibDirs` may include duplicates
+ for (let i = 0, k = customLibDirs.length; i < k; ++i) { // custom
+ let libDir = customLibDirs[i];
+ let libFiles;
+ if (libDir.endsWith(extension)) {
+ libFiles = [ path.basename(libDir) ];
+ libDir = path.dirname(libDir);
+ } else {
+ libFiles = await listFiles(libDir, baseDir) || [];
+ }
+ for (let libPath of libFiles) {
+ let libText = await readFile(libPath, libDir);
+ if (libText == null) {
+ return prepareResult(Error(`Library file '${libPath}' not found.`));
+ }
+ libraryFiles[libPath.replace(extension_re, "")] = libText;
+ let begin = stats.begin();
+ stats.parseCount++;
+ assemblyscript.parse(program, libText, libraryPrefix + libPath, false);
+ stats.parseTime += stats.end(begin);
+ }
+ }
+ }
+ opts.path = opts.path || [];
+
+ // Maps package names to parent directory
+ const packageBases = new Map();
+
+ // Gets the file matching the specified source path, imported at the given dependee path
+ async function getFile(internalPath, dependeePath) {
+ let sourceText = null; // text reported back to the compiler
+ let sourcePath = null; // path reported back to the compiler
+
+ // Try file.ext, file/index.ext, file.d.ext
+ if (!internalPath.startsWith(libraryPrefix)) {
+ if ((sourceText = await readFile(sourcePath = internalPath + extension, baseDir)) == null) {
+ if ((sourceText = await readFile(sourcePath = internalPath + "/index" + extension, baseDir)) == null) {
+ // portable d.ext: uses the .js file next to it in JS or becomes an import in Wasm
+ sourcePath = internalPath + extension;
+ sourceText = await readFile(internalPath + extension_d, baseDir);
+ }
+ }
+
+ // Search library in this order: stdlib, custom lib dirs, paths
+ } else {
+ const plainName = internalPath.substring(libraryPrefix.length);
+ const indexName = `${plainName}/index`;
+ if (Object.prototype.hasOwnProperty.call(libraryFiles, plainName)) {
+ sourceText = libraryFiles[plainName];
+ sourcePath = libraryPrefix + plainName + extension;
+ } else if (Object.prototype.hasOwnProperty.call(libraryFiles, indexName)) {
+ sourceText = libraryFiles[indexName];
+ sourcePath = libraryPrefix + indexName + extension;
+ } else { // custom lib dirs
+ for (const libDir of customLibDirs) {
+ if ((sourceText = await readFile(plainName + extension, libDir)) != null) {
+ sourcePath = libraryPrefix + plainName + extension;
+ break;
+ } else {
+ if ((sourceText = await readFile(indexName + extension, libDir)) != null) {
+ sourcePath = libraryPrefix + indexName + extension;
+ break;
+ }
+ }
+ }
+ if (sourceText == null) { // paths
+ const match = internalPath.match(/^~lib\/((?:@[^/]+\/)?[^/]+)(?:\/(.+))?/); // ~lib/(pkg)/(path), ~lib/(@org/pkg)/(path)
+ if (match) {
+ const packageName = match[1];
+ const filePath = match[2] || "index";
+ const basePath = packageBases.has(dependeePath) ? packageBases.get(dependeePath) : ".";
+ const paths = [];
+ const parts = path.resolve(baseDir, basePath).split(SEP);
+ for (let i = parts.length, k = WIN ? 1 : 0; i >= k; --i) {
+ if (parts[i - 1] !== "node_modules") {
+ paths.push(`${parts.slice(0, i).join(SEP)}${SEP}node_modules`);
+ }
+ }
+ paths.push(...opts.path);
+ for (const currentDir of paths.map(p => path.relative(baseDir, p))) {
+ const plainName = filePath;
+ if ((sourceText = await readFile(path.join(currentDir, packageName, plainName + extension), baseDir)) != null) {
+ sourcePath = `${libraryPrefix}${packageName}/${plainName}${extension}`;
+ packageBases.set(sourcePath.replace(extension_re, ""), path.join(currentDir, packageName));
+ break;
+ }
+ const indexName = `${filePath}/index`;
+ if ((sourceText = await readFile(path.join(currentDir, packageName, indexName + extension), baseDir)) != null) {
+ sourcePath = `${libraryPrefix}${packageName}/${indexName}${extension}`;
+ packageBases.set(sourcePath.replace(extension_re, ""), path.join(currentDir, packageName));
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ // No such file
+ if (sourceText == null) return null;
+ return { sourceText, sourcePath };
+ }
+
+ // Gets all pending imported files from the backlog
+ function getBacklog(paths = []) {
+ do {
+ let internalPath = assemblyscript.nextFile(program);
+ if (internalPath == null) break;
+ paths.push(internalPath);
+ } while (true);
+ return paths;
+ }
+
+ // Parses the backlog of imported files after including entry files
+ async function parseBacklog() {
+ let backlog;
+ while ((backlog = getBacklog()).length) {
+ let files = [];
+ for (let internalPath of backlog) {
+ const dependee = assemblyscript.getDependee(program, internalPath);
+ files.push(getFile(internalPath, dependee)); // queue
+ }
+ files = await Promise.all(files); // parallel
+ for (let i = 0, k = backlog.length; i < k; ++i) {
+ const internalPath = backlog[i];
+ const file = files[i];
+ const begin = stats.begin();
+ stats.parseCount++;
+ if (file) {
+ assemblyscript.parse(program, file.sourceText, file.sourcePath, false);
+ } else {
+ assemblyscript.parse(program, null, internalPath + extension, false);
+ }
+ stats.parseTime += stats.end(begin);
+ }
+ }
+ const numErrors = checkDiagnostics(program, stderr, opts.disableWarning, options.reportDiagnostic, stderrColors.enabled);
+ if (numErrors) {
+ const err = Error(`${numErrors} parse error(s)`);
+ err.stack = err.message; // omit stack
+ return prepareResult(err);
+ }
+ }
+
+ // Include runtime before entry files so its setup runs first
+ {
+ let runtimeName = String(opts.runtime);
+ let runtimePath = `rt/index-${runtimeName}`;
+ let runtimeText = libraryFiles[runtimePath];
+ if (runtimeText == null) {
+ runtimePath = runtimeName;
+ runtimeText = await readFile(runtimePath + extension, baseDir);
+ if (runtimeText == null) return prepareResult(Error(`Runtime '${path.resolve(baseDir, runtimePath + extension)}' is not found.`));
+ } else {
+ runtimePath = `~lib/${runtimePath}`;
+ }
+ let begin = stats.begin();
+ stats.parseCount++;
+ assemblyscript.parse(program, runtimeText, runtimePath + extension, true);
+ stats.parseTime += stats.end(begin);
+ }
+
+ // Include entry files
+ for (let i = 0, k = argv.length; i < k; ++i) {
+ const filename = String(argv[i]);
+
+ // Setting the path to relative path
+ let sourcePath = path.isAbsolute(filename)
+ ? path.relative(baseDir, filename)
+ : path.normalize(filename);
+
+ sourcePath = sourcePath
+ .replace(/\\/g, "/")
+ .replace(extension_re, "")
+ .replace(/\/$/, "");
+
+ // Try entryPath.ext, then entryPath/index.ext
+ let sourceText = await readFile(sourcePath + extension, baseDir);
+ if (sourceText == null) {
+ const path = `${sourcePath}/index${extension}`;
+ sourceText = await readFile(path, baseDir);
+ if (sourceText != null) sourcePath = path;
+ else sourcePath += extension;
+ } else {
+ sourcePath += extension;
+ }
+
+ let begin = stats.begin();
+ stats.parseCount++;
+ assemblyscript.parse(program, sourceText, sourcePath, true);
+ stats.parseTime += stats.end(begin);
+ }
+
+ // Parse entry files
+ {
+ let code = await parseBacklog();
+ if (code) return code;
+ }
+
+ // Call afterParse transform hook
+ {
+ let error = await applyTransform("afterParse", program.parser);
+ if (error) return prepareResult(error);
+ }
+
+ // Parse additional files, if any
+ {
+ let code = await parseBacklog();
+ if (code) return code;
+ }
+
+ // Pre-emptively initialize the program
+ {
+ let begin = stats.begin();
+ stats.initializeCount++;
+ try {
+ assemblyscript.initializeProgram(program);
+ } catch (e) {
+ crash("initialize", e);
+ }
+ stats.initializeTime += stats.end(begin);
+ }
+
+ // Call afterInitialize transform hook
+ {
+ let error = await applyTransform("afterInitialize", program);
+ if (error) return prepareResult(error);
+ }
+
+ // Compile the program
+ {
+ let begin = stats.begin();
+ stats.compileCount++;
+ try {
+ module = assemblyscript.compile(program);
+ } catch (e) {
+ crash("compile", e);
+ }
+ stats.compileTime += stats.end(begin);
+ }
+ // From here on we are going to use Binaryen.js
+ binaryenModule = binaryen.wrapModule(
+ typeof module === "number" || module instanceof Number
+ ? assemblyscript.getBinaryenModuleRef(module)
+ : module.ref
+ );
+ let numErrors = checkDiagnostics(program, stderr, opts.disableWarning, options.reportDiagnostic, stderrColors.enabled);
+ if (numErrors) {
+ const err = Error(`${numErrors} compile error(s)`);
+ err.stack = err.message; // omit stack
+ return prepareResult(err);
+ }
+
+ // Call afterCompile transform hook
+ {
+ let error = await applyTransform("afterCompile", binaryenModule);
+ if (error) return prepareResult(error);
+ }
+
+ numErrors = checkDiagnostics(program, stderr, opts.disableWarning, options.reportDiagnostic, stderrColors.enabled);
+ if (numErrors) {
+ const err = Error(`${numErrors} afterCompile error(s)`);
+ err.stack = err.message; // omit stack
+ return prepareResult(err);
+ }
+
+ // Validate the module if requested
+ if (!opts.noValidate) {
+ let begin = stats.begin();
+ stats.validateCount++;
+ let isValid = assemblyscript.validate(module);
+ stats.validateTime += stats.end(begin);
+ if (!isValid) {
+ return prepareResult(Error("validate error"));
+ }
+ }
+
+ // Set Binaryen-specific options
+ if (opts.trapMode === "clamp" || opts.trapMode === "js") {
+ let begin = stats.begin();
+ try {
+ binaryenModule.runPasses([`trap-mode-${opts.trapMode}`]);
+ } catch (e) {
+ crash("runPasses", e);
+ }
+ stats.compileTime += stats.end(begin);
+ } else if (opts.trapMode !== "allow") {
+ return prepareResult(Error("Unsupported trap mode"));
+ }
+
+ // Optimize the module
+ const debugInfo = opts.debug;
+ const converge = opts.converge;
+ const zeroFilledMemory = opts.importMemory
+ ? opts.zeroFilledMemory
+ : false;
+
+ const runPasses = [];
+ if (opts.runPasses) {
+ if (typeof opts.runPasses === "string") {
+ opts.runPasses = opts.runPasses.split(",");
+ }
+ if (opts.runPasses.length) {
+ opts.runPasses.forEach(pass => {
+ if (!runPasses.includes(pass = pass.trim())) {
+ runPasses.push(pass);
+ }
+ });
+ }
+ }
+
+ {
+ let begin = stats.begin();
+ try {
+ stats.optimizeCount++;
+ assemblyscript.optimize(module, optimizeLevel, shrinkLevel, debugInfo, zeroFilledMemory);
+ } catch (e) {
+ crash("optimize", e);
+ }
+ try {
+ binaryenModule.runPasses(runPasses);
+ } catch (e) {
+ crash("runPasses", e);
+ }
+ if (converge) {
+ let last;
+ try {
+ let begin = stats.begin();
+ stats.emitCount++;
+ last = binaryenModule.emitBinary();
+ stats.emitTime += stats.end(begin);
+ } catch (e) {
+ crash("emitBinary (converge)", e);
+ }
+ do {
+ try {
+ stats.optimizeCount++;
+ assemblyscript.optimize(module, optimizeLevel, shrinkLevel, debugInfo, zeroFilledMemory);
+ } catch (e) {
+ crash("optimize (converge)", e);
+ }
+ try {
+ binaryenModule.runPasses(runPasses);
+ } catch (e) {
+ crash("runPasses (converge)", e);
+ }
+ let next;
+ try {
+ let begin = stats.begin();
+ stats.emitCount++;
+ next = binaryenModule.emitBinary();
+ stats.emitTime += stats.end(begin);
+ } catch (e) {
+ crash("emitBinary (converge)", e);
+ }
+ if (next.length >= last.length) {
+ if (next.length > last.length) {
+ stderr.write(`Last converge was suboptimal.${EOL}`);
+ }
+ break;
+ }
+ last = next;
+ } while (true);
+ }
+ stats.optimizeTime += stats.end(begin);
+ }
+
+ const pending = [];
+
+ // Prepare output
+ if (!opts.noEmit) {
+ if (opts.binaryFile) {
+ // We caught legacy field for binary output (before 0.20)
+ return prepareResult(Error("Usage of the --binaryFile compiler option is no longer supported. Use --outFile instead."));
+ }
+ let bindings = opts.bindings || [];
+ let hasStdout = false;
+ let hasOutFile = opts.outFile != null;
+ let hasTextFile = opts.textFile != null;
+ let hasOutput = hasOutFile || hasTextFile;
+ let hasFileOutput = (hasOutFile && opts.outFile.length > 0) || (hasTextFile && opts.textFile.length > 0);
+ let basepath = hasFileOutput
+ ? (opts.outFile || opts.textFile).replace(/\.\w+$/, "")
+ : null;
+ let basename = hasFileOutput
+ ? path.basename(basepath)
+ : "output";
+
+ assemblyscript.setBasenameHint(compilerOptions, basename);
+
+ // Write binary
+ if (opts.outFile != null) {
+ let sourceMapURL = opts.sourceMap != null
+ ? opts.sourceMap.length
+ ? opts.sourceMap
+ : `./${basename}.wasm.map`
+ : null;
+
+ let begin = stats.begin();
+ stats.emitCount++;
+ let wasm;
+ try {
+ wasm = binaryenModule.emitBinary(sourceMapURL);
+ } catch (e) {
+ crash("emitBinary", e);
+ }
+ stats.emitTime += stats.end(begin);
+
+ if (opts.outFile.length) {
+ pending.push(
+ writeFile(opts.outFile, wasm.binary, baseDir)
+ );
+ } else {
+ hasStdout = true;
+ writeStdout(wasm.binary);
+ }
+
+ // Post-process source map
+ if (wasm.sourceMap != "") {
+ if (opts.outFile.length) {
+ let map = JSON.parse(wasm.sourceMap);
+ map.sourceRoot = `./${basename}`;
+ let contents = [];
+ for (let i = 0, k = map.sources.length; i < k; ++i) {
+ let name = map.sources[i];
+ let text = assemblyscript.getSource(program, name.replace(extension_re, ""));
+ if (text == null) return prepareResult(Error(`Source of file '${name}' not found.`));
+ contents[i] = text;
+ }
+ map.sourcesContent = contents;
+ pending.push(
+ writeFile(path.join(
+ path.dirname(opts.outFile),
+ path.basename(sourceMapURL)
+ ).replace(/^\.\//, ""), JSON.stringify(map), baseDir)
+ );
+ } else {
+ stderr.write(`Skipped source map (no output path)${EOL}`);
+ }
+ }
+ }
+
+ // Write text (also fallback)
+ if (opts.textFile != null || !hasOutput) {
+ let begin = stats.begin();
+ stats.emitCount++;
+ let out;
+ try {
+ // use superset text format when extension is `.wast`.
+ // Otherwise use official stack IR format (wat).
+ binaryen.setOptimizeStackIR(true);
+ out = opts.textFile?.endsWith(".wast")
+ ? binaryenModule.emitText()
+ : binaryenModule.emitStackIR();
+ } catch (e) {
+ crash("emitText", e);
+ }
+ stats.emitTime += stats.end(begin);
+
+ if (opts.textFile != null && opts.textFile.length) {
+ pending.push(
+ writeFile(opts.textFile, out, baseDir)
+ );
+ } else if (!hasStdout) {
+ // hasStdout = true;
+ writeStdout(out);
+ }
+ }
+
+ // Write TypeScript definition
+ const bindingsEsm = bindings.includes("esm");
+ const bindingsRaw = !bindingsEsm && bindings.includes("raw");
+ if (bindingsEsm || bindingsRaw) {
+ if (basepath) {
+ let begin = stats.begin();
+ stats.emitCount++;
+ let source;
+ try {
+ source = assemblyscript.buildTSD(program, bindingsEsm);
+ } catch (e) {
+ crash("buildTSD", e);
+ }
+ stats.emitTime += stats.end(begin);
+ pending.push(
+ writeFile(basepath + ".d.ts", source, baseDir)
+ );
+ } else {
+ stderr.write(`Skipped TypeScript binding (no output path)${EOL}`);
+ }
+ }
+
+ // Write JavaScript bindings
+ if (bindingsEsm || bindingsRaw) {
+ if (basepath) {
+ let begin = stats.begin();
+ stats.emitCount++;
+ let source;
+ try {
+ source = assemblyscript.buildJS(program, bindingsEsm);
+ } catch (e) {
+ crash("buildJS", e);
+ }
+ stats.emitTime += stats.end(begin);
+ pending.push(
+ writeFile(basepath + ".js", source, baseDir)
+ );
+ } else {
+ stderr.write(`Skipped JavaScript binding (no output path)${EOL}`);
+ }
+ }
+ }
+
+ try {
+ await Promise.all(pending);
+ } catch (err) {
+ return prepareResult(err);
+ }
+
+ stats.total = stats.end(statsBegin);
+ if (opts.stats) stderr.write(stats.toString());
+
+ return prepareResult(null);
+
+ // Default implementation to read files on node
+ async function readFileNode(filename, baseDir) {
+ let name = path.resolve(baseDir, filename);
+ try {
+ stats.readCount++;
+ return await fs.promises.readFile(name, "utf8");
+ } catch {
+ return null;
+ }
+ }
+
+ // Default implementation to write files on node
+ async function writeFileNode(filename, contents, baseDir) {
+ try {
+ stats.writeCount++;
+ const dirPath = path.resolve(baseDir, path.dirname(filename));
+ const filePath = path.join(dirPath, path.basename(filename));
+ await fs.promises.mkdir(dirPath, { recursive: true });
+ await fs.promises.writeFile(filePath, contents);
+ return true;
+ } catch {
+ return false;
+ }
+ }
+
+ // Default implementation to list files on node
+ async function listFilesNode(dirname, baseDir) {
+ try {
+ stats.readCount++;
+ return (await fs.promises.readdir(path.join(baseDir, dirname)))
+ .filter(file => extension_re_except_d.test(file));
+ } catch {
+ return null;
+ }
+ }
+
+ // Writes to stdout
+ function writeStdout(contents) {
+ if (!writeStdout.used) {
+ writeStdout.used = true;
+ stats.writeCount++;
+ }
+ stdout.write(contents);
+ }
+
+ // Crash handler
+ function crash(stage, e) {
+ const BAR = stdoutColors.red("▌ ");
+ console.error([
+ EOL,
+ BAR, "Whoops, the AssemblyScript compiler has crashed during ", stage, " :-(", EOL,
+ BAR, EOL,
+ (typeof e.stack === "string"
+ ? [
+ BAR, "Here is the stack trace hinting at the problem, perhaps it's useful?", EOL,
+ BAR, EOL,
+ e.stack.replace(/^/mg, BAR), EOL
+ ]
+ : [
+ BAR, "There is no stack trace. Perhaps a Binaryen exception above / in console?", EOL,
+ BAR, EOL,
+ BAR, "> " + e.stack, EOL
+ ]
+ ).join(""),
+ BAR, EOL,
+ BAR, "If you see where the error is, feel free to send us a pull request. If not,", EOL,
+ BAR, "please let us know: https://github.com/AssemblyScript/assemblyscript/issues", EOL,
+ BAR, EOL,
+ BAR, "Thank you!", EOL
+ ].join(""));
+ process.exit(1);
+ }
+}
+
+function isObject(arg) {
+ return Object.prototype.toString.call(arg) === "[object Object]";
+}
+
+async function getConfig(file, baseDir, readFile) {
+ const contents = await readFile(file, baseDir);
+ const location = path.join(baseDir, file);
+ if (!contents) return null;
+
+ // obtain the configuration
+ let config;
+ try {
+ config = JSON.parse(contents);
+ } catch(ex) {
+ throw new Error(`Asconfig is not valid json: ${location}`, { cause: ex });
+ }
+
+ // validate asconfig shape
+ if (config.options && !isObject(config.options)) {
+ throw new Error(`Asconfig.options is not an object: ${location}`);
+ }
+
+ if (config.include && !Array.isArray(config.include)) {
+ throw new Error(`Asconfig.include is not an array: ${location}`);
+ }
+
+ if (config.targets) {
+ if (!isObject(config.targets)) {
+ throw new Error(`Asconfig.targets is not an object: ${location}`);
+ }
+ const targets = Object.keys(config.targets);
+ for (let i = 0; i < targets.length; i++) {
+ const target = targets[i];
+ if (!isObject(config.targets[target])) {
+ throw new Error(`Asconfig.targets.${target} is not an object: ${location}`);
+ }
+ }
+ }
+
+ if (config.extends && typeof config.extends !== "string") {
+ throw new Error(`Asconfig.extends is not a string: ${location}`);
+ }
+
+ return config;
+}
+
+/** Checks diagnostics emitted so far for errors. */
+export function checkDiagnostics(program, stderr, disableWarning, reportDiagnostic, useColors) {
+ if (typeof useColors === "undefined" && stderr) useColors = stderr.isTTY;
+ let numErrors = 0;
+ do {
+ let diagnostic = assemblyscript.nextDiagnostic(program);
+ if (!diagnostic) break;
+ if (stderr) {
+ const isDisabledWarning = (diagnostic) => {
+ if (disableWarning == null) return false;
+ if (!disableWarning.length) return true;
+ const code = assemblyscript.getDiagnosticCode(diagnostic);
+ return disableWarning.includes(code);
+ };
+ if (assemblyscript.isError(diagnostic) || !isDisabledWarning(diagnostic)) {
+ stderr.write(assemblyscript.formatDiagnostic(diagnostic, useColors, true) + EOL + EOL);
+ }
+ }
+ if (reportDiagnostic) {
+ function wrapRange(range) {
+ return range && {
+ start: assemblyscript.getRangeStart(range),
+ end: assemblyscript.getRangeEnd(range),
+ source: wrapSource(assemblyscript.getRangeSource(range))
+ } || null;
+ }
+ function wrapSource(source) {
+ return source && {
+ normalizedPath: assemblyscript.getSourceNormalizedPath(source)
+ } || null;
+ }
+ reportDiagnostic({
+ message: assemblyscript.getDiagnosticMessage(diagnostic),
+ code: assemblyscript.getDiagnosticCode(diagnostic),
+ category: assemblyscript.getDiagnosticCategory(diagnostic),
+ range: wrapRange(assemblyscript.getDiagnosticRange(diagnostic)),
+ relatedRange: wrapRange(assemblyscript.getDiagnosticRelatedRange(diagnostic))
+ });
+ }
+ if (assemblyscript.isError(diagnostic)) ++numErrors;
+ } while (true);
+ return numErrors;
+}
+
+export class Stats {
+ readCount = 0;
+ writeCount = 0;
+ parseTime = 0;
+ parseCount = 0;
+ initializeTime = 0;
+ initializeCount = 0;
+ compileTime = 0;
+ compileCount = 0;
+ emitTime = 0;
+ emitCount = 0;
+ validateTime = 0;
+ validateCount = 0;
+ optimizeTime = 0;
+ optimizeCount = 0;
+ transformTime = 0;
+ transformCount = 0;
+ begin() {
+ return process.hrtime();
+ }
+ end(begin) {
+ const hrtime = process.hrtime(begin);
+ return hrtime[0] * 1e9 + hrtime[1];
+ }
+ toString() {
+ const formatTime = time => time ? `${(time / 1e6).toFixed(3)} ms` : "n/a";
+ const keys = Object.keys(this).filter(key => key.endsWith("Time")).map(key => key.substring(0, key.length - 4));
+ const times = keys.map(key => formatTime(this[`${key}Time`]));
+ const counts = keys.map(key => this[`${key}Count`].toString());
+ const keysLen = keys.reduce((current, key) => Math.max(key.length, current), 0);
+ const timesLen = times.reduce((current, time) => Math.max(time.length, current), 0);
+ const countsLen = counts.reduce((current, count) => Math.max(count.length, current), 0);
+ const totalLen = keysLen + timesLen + countsLen + 6;
+ const out = [];
+ out.push(`╭─${"─".repeat(totalLen)}─╮${EOL}`);
+ const header = `Stats`;
+ out.push(`│ ${header}${" ".repeat(totalLen - header.length)} │${EOL}`);
+ out.push(`╞═${"═".repeat(keysLen)}═╤═${"═".repeat(timesLen)}═╤═${"═".repeat(countsLen)}═╡${EOL}`);
+ for (let i = 0, k = keys.length; i < k; ++i) {
+ out.push(`│ ${keys[i].padEnd(keysLen)} │ ${times[i].padStart(timesLen)} │ ${counts[i].padStart(countsLen)} │${EOL}`);
+ }
+ out.push(`├─${"─".repeat(keysLen)}─┴─${"─".repeat(timesLen)}─┴─${"─".repeat(countsLen)}─┤${EOL}`);
+ const totalTime = `Took ${formatTime(this.total)}`;
+ out.push(`│ ${totalTime}${" ".repeat(totalLen - totalTime.length)} │${EOL}`);
+ const readsWrites = `${this.readCount} reads, ${this.writeCount} writes`;
+ out.push(`│ ${readsWrites}${" ".repeat(totalLen - readsWrites.length)} │${EOL}`);
+ out.push(`╰─${"─".repeat(totalLen)}─╯${EOL}`);
+ return out.join("");
+ }
+}
+
+let allocBuffer = typeof global !== "undefined" && global.Buffer
+ ? global.Buffer.allocUnsafe || (len => new global.Buffer(len))
+ : len => new Uint8Array(len);
+
+/** Creates a memory stream that can be used in place of stdout/stderr. */
+export function createMemoryStream(fn) {
+ let stream = [];
+ stream.write = function(chunk) {
+ if (fn) fn(chunk);
+ if (typeof chunk === "string") {
+ let buffer = allocBuffer(utf8.length(chunk));
+ utf8.write(chunk, buffer, 0);
+ chunk = buffer;
+ }
+ this.push(chunk);
+ };
+ stream.reset = function() {
+ stream.length = 0;
+ };
+ stream.toBuffer = function() {
+ let offset = 0, i = 0, k = this.length;
+ while (i < k) offset += this[i++].length;
+ let buffer = allocBuffer(offset);
+ offset = i = 0;
+ while (i < k) {
+ buffer.set(this[i], offset);
+ offset += this[i].length;
+ ++i;
+ }
+ return buffer;
+ };
+ stream.toString = function() {
+ let buffer = this.toBuffer();
+ return utf8.read(buffer, 0, buffer.length);
+ };
+ return stream;
+}
+
+/** Compatible TypeScript compiler options for syntax highlighting etc. */
+export const tscOptions = {
+ alwaysStrict: true,
+ strictNullChecks: true,
+ noImplicitAny: true,
+ noImplicitReturns: true,
+ noImplicitThis: true,
+ noEmitOnError: true,
+ noPropertyAccessFromIndexSignature: true,
+ experimentalDecorators: true,
+ target: "esnext",
+ noLib: true,
+ types: [],
+ allowJs: false
+};
+
+export * as default from "./index.js";
diff --git a/cli/options.json b/cli/options.json
new file mode 100644
index 0000000000..f6776dbe26
--- /dev/null
+++ b/cli/options.json
@@ -0,0 +1,403 @@
+{
+ "version": {
+ "category": "General",
+ "description": "Prints just the compiler's version and exits.",
+ "type": "b",
+ "alias": "v"
+ },
+ "help": {
+ "category": "General",
+ "description": "Prints this message and exits.",
+ "type": "b",
+ "alias": "h"
+ },
+ "config": {
+ "category": "General",
+ "description": "Configuration file to apply. CLI arguments take precedence.",
+ "type": "s",
+ "cliOnly": true
+ },
+ "target": {
+ "category": "General",
+ "description": "Configuration file target to use. Defaults to 'release'.",
+ "type": "s",
+ "cliOnly": true
+ },
+
+ "optimize": {
+ "category": "Optimization",
+ "description": [
+ "Optimizes the module. Typical shorthands are:",
+ "",
+ " Default optimizations -O",
+ " Make a release build -O --noAssert",
+ " Make a debug build --debug",
+ " Optimize for speed -Ospeed",
+ " Optimize for size -Osize",
+ ""
+ ],
+ "type": "b",
+ "alias": "O"
+ },
+ "optimizeLevel": {
+ "category": "Optimization",
+ "description": "How much to focus on optimizing code. [0-3]",
+ "type": "i"
+ },
+ "shrinkLevel": {
+ "category": "Optimization",
+ "description": "How much to focus on shrinking code size. [0-2, s=1, z=2]",
+ "type": "i"
+ },
+ "converge": {
+ "category": "Optimization",
+ "description": "Re-optimizes until no further improvements can be made.",
+ "type": "b",
+ "default": false
+ },
+ "noAssert": {
+ "category": "Optimization",
+ "description": "Replaces assertions with just their value without trapping.",
+ "type": "b",
+ "default": false
+ },
+
+ "outFile": {
+ "category": "Output",
+ "description": "Specifies the WebAssembly output file (.wasm).",
+ "type": "s",
+ "alias": "o",
+ "isPath": true
+ },
+ "textFile": {
+ "category": "Output",
+ "description": "Specifies the WebAssembly text output file (.wat).",
+ "type": "s",
+ "alias": "t",
+ "isPath": true
+ },
+ "bindings": {
+ "category": "Output",
+ "description": [
+ "Specifies the bindings to generate (.js + .d.ts).",
+ "",
+ " esm JavaScript bindings & typings for ESM integration.",
+ " raw Like esm, but exports just the instantiate function.",
+ " Useful where modules are meant to be instantiated",
+ " multiple times or non-ESM imports must be provided."
+ ],
+ "type": "S",
+ "alias": "b"
+ },
+
+ "sourceMap": {
+ "category": "Debugging",
+ "description": [
+ "Enables source map generation. Optionally takes the URL",
+ "used to reference the source map from the binary file."
+ ],
+ "type": "s"
+ },
+ "uncheckedBehavior": {
+ "category": "Debugging",
+ "description": [
+ "Changes the behavior of unchecked() expressions.",
+ "Using this option can potentially cause breakage.",
+ "",
+ " default The default behavior: unchecked operations are",
+ " only used inside of unchecked().",
+ " never Unchecked operations are never used, even when",
+ " inside of unchecked().",
+ " always Unchecked operations are always used if possible,",
+ " whether or not unchecked() is used."
+ ],
+ "type": "s",
+ "default": "default"
+ },
+ "debug": {
+ "category": "Debugging",
+ "description": "Enables debug information in emitted binaries.",
+ "type": "b",
+ "default": false
+ },
+
+ "importMemory": {
+ "category": "Features",
+ "description": "Imports the memory from 'env.memory'.",
+ "type": "b",
+ "default": false
+ },
+ "noExportMemory": {
+ "category": "Features",
+ "description": "Does not export the memory as 'memory'.",
+ "type": "b",
+ "default": false
+ },
+ "initialMemory": {
+ "category": "Features",
+ "description": "Sets the initial memory size in pages.",
+ "type": "i",
+ "default": 0
+ },
+ "maximumMemory": {
+ "category": "Features",
+ "description": "Sets the maximum memory size in pages.",
+ "type": "i",
+ "default": 0
+ },
+ "sharedMemory": {
+ "category": "Features",
+ "description": "Declare memory as shared. Requires maximumMemory.",
+ "type": "b",
+ "default": false
+ },
+ "zeroFilledMemory": {
+ "category": "Features",
+ "description": "Assume imported memory is zeroed. Requires importMemory.",
+ "type": "b",
+ "default": false
+ },
+ "importTable": {
+ "category": "Features",
+ "description": "Imports the function table from 'env.table'.",
+ "type": "b",
+ "default": false
+ },
+ "exportTable": {
+ "category": "Features",
+ "description": "Exports the function table as 'table'.",
+ "type": "b",
+ "default": false
+ },
+ "exportStart": {
+ "category": "Features",
+ "description": [
+ "Exports the start function using the specified name instead",
+ "of calling it implicitly. Useful to obtain the exported memory",
+ "before executing any code accessing it."
+ ],
+ "type": "s"
+ },
+ "runtime": {
+ "category": "Features",
+ "description": [
+ "Specifies the runtime variant to include in the program.",
+ "",
+ " incremental TLSF + incremental GC (default)",
+ " minimal TLSF + lightweight GC invoked externally",
+ " stub Minimal runtime stub (never frees)",
+ " ... Path to a custom runtime implementation",
+ ""
+ ],
+ "type": "s",
+ "default": "incremental"
+ },
+ "exportRuntime": {
+ "category": "Features",
+ "description": [
+ "Always exports the runtime helpers (__new, __collect, __pin etc.).",
+ "Automatically determined when generation of --bindings is enabled."
+ ],
+ "type": "b",
+ "default": false
+ },
+ "stackSize": {
+ "category": "Features",
+ "description": [
+ "Overrides the stack size. Only relevant for incremental GC",
+ "or when using a custom runtime that requires stack space.",
+ "Defaults to 0 without and to 32768 with incremental GC."
+ ],
+ "default": 0,
+ "type": "i"
+ },
+ "enable": {
+ "category": "Features",
+ "description": [
+ "Enables WebAssembly features being disabled by default.",
+ "",
+ " threads Threading and atomic operations.",
+ " simd SIMD types and operations.",
+ " reference-types Reference types and operations.",
+ " gc Garbage collection (WIP).",
+ " stringref String reference types.",
+ " relaxed-simd Relaxed SIMD operations.",
+ ""
+ ],
+ "TODO_doesNothingYet": [
+ " exception-handling Exception handling.",
+ " tail-calls Tail call operations.",
+ " multi-value Multi value types.",
+ " memory64 Memory64 operations.",
+ " extended-const Extended const expressions."
+ ],
+ "type": "S",
+ "mutuallyExclusive": "disable"
+ },
+ "disable": {
+ "category": "Features",
+ "description": [
+ "Disables WebAssembly features being enabled by default.",
+ "",
+ " mutable-globals Mutable global imports and exports.",
+ " sign-extension Sign-extension operations",
+ " nontrapping-f2i Non-trapping float to integer ops.",
+ " bulk-memory Bulk memory operations.",
+ ""
+ ],
+ "type": "S",
+ "mutuallyExclusive": "enable"
+ },
+ "use": {
+ "category": "Features",
+ "description": [
+ "Aliases a global object under another name, e.g., to switch",
+ "the default 'Math' implementation used: --use Math=JSMath",
+ "Can also be used to introduce an integer constant."
+ ],
+ "type": "S",
+ "alias": "u"
+ },
+ "lowMemoryLimit": {
+ "category": "Features",
+ "description": "Enforces very low (<64k) memory constraints.",
+ "default": 0,
+ "type": "i"
+ },
+
+ "memoryBase": {
+ "category": "Linking",
+ "description": "Sets the start offset of emitted memory segments.",
+ "type": "i",
+ "default": 0
+ },
+ "tableBase": {
+ "category": "Linking",
+ "description": "Sets the start offset of emitted table elements.",
+ "type": "i",
+ "default": 0
+ },
+
+ "transform": {
+ "category": "API",
+ "description": "Specifies the path to a custom transform to load.",
+ "type": "S",
+ "isPath": true,
+ "useNodeResolution": true
+ },
+
+ "trapMode": {
+ "category": "Binaryen",
+ "description": [
+ "Sets the trap mode to use.",
+ "",
+ " allow Allow trapping operations. This is the default.",
+ " clamp Replace trapping operations with clamping semantics.",
+ " js Replace trapping operations with JS semantics.",
+ ""
+ ],
+ "type": "s",
+ "default": "allow"
+ },
+ "runPasses": {
+ "category": "Binaryen",
+ "description": [
+ "Specifies additional Binaryen passes to run after other",
+ "optimizations, if any. See: Binaryen/src/passes/pass.cpp"
+ ],
+ "type": "s"
+ },
+ "noValidate": {
+ "category": "Binaryen",
+ "description": "Skips validating the module using Binaryen.",
+ "type": "b",
+ "default": false
+ },
+
+ "baseDir": {
+ "description": "Specifies the base directory of input and output files.",
+ "type": "s",
+ "default": "."
+ },
+ "noColors": {
+ "description": "Disables terminal colors.",
+ "type": "b",
+ "default": false
+ },
+ "noUnsafe": {
+ "description": [
+ "Disallows the use of unsafe features in user code.",
+ "Does not affect library files and external modules."
+ ],
+ "type": "b",
+ "default": false
+ },
+ "disableWarning": {
+ "description": [
+ "Disables warnings matching the given diagnostic code.",
+ "If no diagnostic code is given, all warnings are disabled."
+ ],
+ "type": "I"
+ },
+ "noEmit": {
+ "description": "Performs compilation as usual but does not emit code.",
+ "type": "b",
+ "default": false
+ },
+ "showConfig": {
+ "description": "Print computed compiler options and exit.",
+ "type": "b",
+ "default": false
+ },
+ "stats": {
+ "description": "Prints statistics on I/O and compile times.",
+ "type": "b",
+ "default": false
+ },
+ "pedantic": {
+ "description": "Make yourself sad for no good reason.",
+ "type": "b",
+ "default": false
+ },
+ "lib": {
+ "description": [
+ "Adds one or multiple paths to custom library components and",
+ "uses exports of all top-level files at this path as globals."
+ ],
+ "type": "S",
+ "isPath": true
+ },
+ "path": {
+ "description": [
+ "Adds one or multiple paths to package resolution, similar",
+ "to node_modules. Prefers an 'ascMain' entry in a package's",
+ "package.json and falls back to an inner 'assembly/' folder."
+ ],
+ "type": "S",
+ "isPath": true
+ },
+ "wasm": {
+ "description": "Uses the specified Wasm binary of the compiler.",
+ "type": "s"
+ },
+ " ...": {
+ "description": "Specifies node.js options (CLI only). See: node --help"
+ },
+ "-Os": { "value": { "optimizeLevel": 0, "shrinkLevel": 1 } },
+ "-Oz": { "value": { "optimizeLevel": 0, "shrinkLevel": 2 } },
+ "-O0": { "value": { "optimizeLevel": 0, "shrinkLevel": 0 } },
+ "-O1": { "value": { "optimizeLevel": 1, "shrinkLevel": 0 } },
+ "-O2": { "value": { "optimizeLevel": 2, "shrinkLevel": 0 } },
+ "-O3": { "value": { "optimizeLevel": 3, "shrinkLevel": 0 } },
+ "-O0s": { "value": { "optimizeLevel": 0, "shrinkLevel": 1 } },
+ "-O1s": { "value": { "optimizeLevel": 1, "shrinkLevel": 1 } },
+ "-O2s": { "value": { "optimizeLevel": 2, "shrinkLevel": 1 } },
+ "-O3s": { "value": { "optimizeLevel": 3, "shrinkLevel": 1 } },
+ "-O0z": { "value": { "optimizeLevel": 0, "shrinkLevel": 2 } },
+ "-O1z": { "value": { "optimizeLevel": 1, "shrinkLevel": 2 } },
+ "-O2z": { "value": { "optimizeLevel": 2, "shrinkLevel": 2 } },
+ "-O3z": { "value": { "optimizeLevel": 3, "shrinkLevel": 2 } },
+ "-Ospeed": { "value": { "optimizeLevel": 3, "shrinkLevel": 0 } },
+ "-Osize": { "value": { "optimizeLevel": 0, "shrinkLevel": 2, "converge": true } },
+ "--measure": { "value": { "stats": true } }
+}
diff --git a/cli/shim/README.md b/cli/shim/README.md
deleted file mode 100644
index 73b7e60d3c..0000000000
--- a/cli/shim/README.md
+++ /dev/null
@@ -1 +0,0 @@
-Shims used when bundling asc for browser usage.
diff --git a/cli/shim/fs.js b/cli/shim/fs.js
deleted file mode 100644
index f053ebf797..0000000000
--- a/cli/shim/fs.js
+++ /dev/null
@@ -1 +0,0 @@
-module.exports = {};
diff --git a/cli/shim/path.js b/cli/shim/path.js
deleted file mode 100644
index 28978caf27..0000000000
--- a/cli/shim/path.js
+++ /dev/null
@@ -1,531 +0,0 @@
-const process = require("process"); // ensure shim
-
-// https://github.com/browserify/path-browserify v1.0.1
-//
-// Copyright (c) 2013 James Halliday
-// Copyright Joyent, Inc. and other Node contributors.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to permit
-// persons to whom the Software is furnished to do so, subject to the
-// following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
-// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
-// USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-function assertPath(path) {
- if (typeof path !== 'string') {
- throw new TypeError('Path must be a string. Received ' + JSON.stringify(path));
- }
-}
-
-// Resolves . and .. elements in a path with directory names
-function normalizeStringPosix(path, allowAboveRoot) {
- var res = '';
- var lastSegmentLength = 0;
- var lastSlash = -1;
- var dots = 0;
- var code;
- for (var i = 0; i <= path.length; ++i) {
- if (i < path.length)
- code = path.charCodeAt(i);
- else if (code === 47 /*/*/)
- break;
- else
- code = 47 /*/*/;
- if (code === 47 /*/*/) {
- if (lastSlash === i - 1 || dots === 1) {
- // NOOP
- } else if (lastSlash !== i - 1 && dots === 2) {
- if (res.length < 2 || lastSegmentLength !== 2 || res.charCodeAt(res.length - 1) !== 46 || res.charCodeAt(res.length - 2) !== 46) {
- if (res.length > 2) {
- var lastSlashIndex = res.lastIndexOf('/');
- if (lastSlashIndex !== res.length - 1) {
- if (lastSlashIndex === -1) {
- res = '';
- lastSegmentLength = 0;
- } else {
- res = res.slice(0, lastSlashIndex);
- lastSegmentLength = res.length - 1 - res.lastIndexOf('/');
- }
- lastSlash = i;
- dots = 0;
- continue;
- }
- } else if (res.length === 2 || res.length === 1) {
- res = '';
- lastSegmentLength = 0;
- lastSlash = i;
- dots = 0;
- continue;
- }
- }
- if (allowAboveRoot) {
- if (res.length > 0)
- res += '/..';
- else
- res = '..';
- lastSegmentLength = 2;
- }
- } else {
- if (res.length > 0)
- res += '/' + path.slice(lastSlash + 1, i);
- else
- res = path.slice(lastSlash + 1, i);
- lastSegmentLength = i - lastSlash - 1;
- }
- lastSlash = i;
- dots = 0;
- } else if (code === 46 && dots !== -1) {
- ++dots;
- } else {
- dots = -1;
- }
- }
- return res;
-}
-
-function _format(sep, pathObject) {
- var dir = pathObject.dir || pathObject.root;
- var base = pathObject.base || (pathObject.name || '') + (pathObject.ext || '');
- if (!dir) {
- return base;
- }
- if (dir === pathObject.root) {
- return dir + base;
- }
- return dir + sep + base;
-}
-
-var posix = {
- // path.resolve([from ...], to)
- resolve: function resolve() {
- var resolvedPath = '';
- var resolvedAbsolute = false;
- var cwd;
-
- for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
- var path;
- if (i >= 0)
- path = arguments[i];
- else {
- if (cwd === undefined)
- cwd = process.cwd();
- path = cwd;
- }
-
- assertPath(path);
-
- // Skip empty entries
- if (path.length === 0) {
- continue;
- }
-
- resolvedPath = path + '/' + resolvedPath;
- resolvedAbsolute = path.charCodeAt(0) === 47 /*/*/;
- }
-
- // At this point the path should be resolved to a full absolute path, but
- // handle relative paths to be safe (might happen when process.cwd() fails)
-
- // Normalize the path
- resolvedPath = normalizeStringPosix(resolvedPath, !resolvedAbsolute);
-
- if (resolvedAbsolute) {
- if (resolvedPath.length > 0)
- return '/' + resolvedPath;
- else
- return '/';
- } else if (resolvedPath.length > 0) {
- return resolvedPath;
- } else {
- return '.';
- }
- },
-
- normalize: function normalize(path) {
- assertPath(path);
-
- if (path.length === 0) return '.';
-
- var isAbsolute = path.charCodeAt(0) === 47 /*/*/;
- var trailingSeparator = path.charCodeAt(path.length - 1) === 47 /*/*/;
-
- // Normalize the path
- path = normalizeStringPosix(path, !isAbsolute);
-
- if (path.length === 0 && !isAbsolute) path = '.';
- if (path.length > 0 && trailingSeparator) path += '/';
-
- if (isAbsolute) return '/' + path;
- return path;
- },
-
- isAbsolute: function isAbsolute(path) {
- assertPath(path);
- return path.length > 0 && path.charCodeAt(0) === 47 /*/*/;
- },
-
- join: function join() {
- if (arguments.length === 0)
- return '.';
- var joined;
- for (var i = 0; i < arguments.length; ++i) {
- var arg = arguments[i];
- assertPath(arg);
- if (arg.length > 0) {
- if (joined === undefined)
- joined = arg;
- else
- joined += '/' + arg;
- }
- }
- if (joined === undefined)
- return '.';
- return posix.normalize(joined);
- },
-
- relative: function relative(from, to) {
- assertPath(from);
- assertPath(to);
-
- if (from === to) return '';
-
- from = posix.resolve(from);
- to = posix.resolve(to);
-
- if (from === to) return '';
-
- if (from === ".") return to; // FIX for 'odule.ts' (see issue #1398)
-
- // Trim any leading backslashes
- var fromStart = 1;
- for (; fromStart < from.length; ++fromStart) {
- if (from.charCodeAt(fromStart) !== 47 /*/*/)
- break;
- }
- var fromEnd = from.length;
- var fromLen = fromEnd - fromStart;
-
- // Trim any leading backslashes
- var toStart = 1;
- for (; toStart < to.length; ++toStart) {
- if (to.charCodeAt(toStart) !== 47 /*/*/)
- break;
- }
- var toEnd = to.length;
- var toLen = toEnd - toStart;
-
- // Compare paths to find the longest common path from root
- var length = fromLen < toLen ? fromLen : toLen;
- var lastCommonSep = -1;
- var i = 0;
- for (; i <= length; ++i) {
- if (i === length) {
- if (toLen > length) {
- if (to.charCodeAt(toStart + i) === 47 /*/*/) {
- // We get here if `from` is the exact base path for `to`.
- // For example: from='/foo/bar'; to='/foo/bar/baz'
- return to.slice(toStart + i + 1);
- } else if (i === 0) {
- // We get here if `from` is the root
- // For example: from='/'; to='/foo'
- return to.slice(toStart + i);
- }
- } else if (fromLen > length) {
- if (from.charCodeAt(fromStart + i) === 47 /*/*/) {
- // We get here if `to` is the exact base path for `from`.
- // For example: from='/foo/bar/baz'; to='/foo/bar'
- lastCommonSep = i;
- } else if (i === 0) {
- // We get here if `to` is the root.
- // For example: from='/foo'; to='/'
- lastCommonSep = 0;
- }
- }
- break;
- }
- var fromCode = from.charCodeAt(fromStart + i);
- var toCode = to.charCodeAt(toStart + i);
- if (fromCode !== toCode)
- break;
- else if (fromCode === 47 /*/*/)
- lastCommonSep = i;
- }
-
- var out = '';
- // Generate the relative path based on the path difference between `to`
- // and `from`
- for (i = fromStart + lastCommonSep + 1; i <= fromEnd; ++i) {
- if (i === fromEnd || from.charCodeAt(i) === 47 /*/*/) {
- if (out.length === 0)
- out += '..';
- else
- out += '/..';
- }
- }
-
- // Lastly, append the rest of the destination (`to`) path that comes after
- // the common path parts
- if (out.length > 0)
- return out + to.slice(toStart + lastCommonSep);
- else {
- toStart += lastCommonSep;
- if (to.charCodeAt(toStart) === 47 /*/*/)
- ++toStart;
- return to.slice(toStart);
- }
- },
-
- _makeLong: function _makeLong(path) {
- return path;
- },
-
- dirname: function dirname(path) {
- assertPath(path);
- if (path.length === 0) return '.';
- var code = path.charCodeAt(0);
- var hasRoot = code === 47 /*/*/;
- var end = -1;
- var matchedSlash = true;
- for (var i = path.length - 1; i >= 1; --i) {
- code = path.charCodeAt(i);
- if (code === 47 /*/*/) {
- if (!matchedSlash) {
- end = i;
- break;
- }
- } else {
- // We saw the first non-path separator
- matchedSlash = false;
- }
- }
-
- if (end === -1) return hasRoot ? '/' : '.';
- if (hasRoot && end === 1) return '//';
- return path.slice(0, end);
- },
-
- basename: function basename(path, ext) {
- if (ext !== undefined && typeof ext !== 'string') throw new TypeError('"ext" argument must be a string');
- assertPath(path);
-
- var start = 0;
- var end = -1;
- var matchedSlash = true;
- var i;
-
- if (ext !== undefined && ext.length > 0 && ext.length <= path.length) {
- if (ext.length === path.length && ext === path) return '';
- var extIdx = ext.length - 1;
- var firstNonSlashEnd = -1;
- for (i = path.length - 1; i >= 0; --i) {
- var code = path.charCodeAt(i);
- if (code === 47 /*/*/) {
- // If we reached a path separator that was not part of a set of path
- // separators at the end of the string, stop now
- if (!matchedSlash) {
- start = i + 1;
- break;
- }
- } else {
- if (firstNonSlashEnd === -1) {
- // We saw the first non-path separator, remember this index in case
- // we need it if the extension ends up not matching
- matchedSlash = false;
- firstNonSlashEnd = i + 1;
- }
- if (extIdx >= 0) {
- // Try to match the explicit extension
- if (code === ext.charCodeAt(extIdx)) {
- if (--extIdx === -1) {
- // We matched the extension, so mark this as the end of our path
- // component
- end = i;
- }
- } else {
- // Extension does not match, so our result is the entire path
- // component
- extIdx = -1;
- end = firstNonSlashEnd;
- }
- }
- }
- }
-
- if (start === end) end = firstNonSlashEnd;else if (end === -1) end = path.length;
- return path.slice(start, end);
- } else {
- for (i = path.length - 1; i >= 0; --i) {
- if (path.charCodeAt(i) === 47 /*/*/) {
- // If we reached a path separator that was not part of a set of path
- // separators at the end of the string, stop now
- if (!matchedSlash) {
- start = i + 1;
- break;
- }
- } else if (end === -1) {
- // We saw the first non-path separator, mark this as the end of our
- // path component
- matchedSlash = false;
- end = i + 1;
- }
- }
-
- if (end === -1) return '';
- return path.slice(start, end);
- }
- },
-
- extname: function extname(path) {
- assertPath(path);
- var startDot = -1;
- var startPart = 0;
- var end = -1;
- var matchedSlash = true;
- // Track the state of characters (if any) we see before our first dot and
- // after any path separator we find
- var preDotState = 0;
- for (var i = path.length - 1; i >= 0; --i) {
- var code = path.charCodeAt(i);
- if (code === 47 /*/*/) {
- // If we reached a path separator that was not part of a set of path
- // separators at the end of the string, stop now
- if (!matchedSlash) {
- startPart = i + 1;
- break;
- }
- continue;
- }
- if (end === -1) {
- // We saw the first non-path separator, mark this as the end of our
- // extension
- matchedSlash = false;
- end = i + 1;
- }
- if (code === 46) {
- // If this is our first dot, mark it as the start of our extension
- if (startDot === -1)
- startDot = i;
- else if (preDotState !== 1)
- preDotState = 1;
- } else if (startDot !== -1) {
- // We saw a non-dot and non-path separator before our dot, so we should
- // have a good chance at having a non-empty extension
- preDotState = -1;
- }
- }
-
- if (startDot === -1 || end === -1 ||
- // We saw a non-dot character immediately before the dot
- preDotState === 0 ||
- // The (right-most) trimmed path component is exactly '..'
- preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) {
- return '';
- }
- return path.slice(startDot, end);
- },
-
- format: function format(pathObject) {
- if (pathObject === null || typeof pathObject !== 'object') {
- throw new TypeError('The "pathObject" argument must be of type Object. Received type ' + typeof pathObject);
- }
- return _format('/', pathObject);
- },
-
- parse: function parse(path) {
- assertPath(path);
-
- var ret = { root: '', dir: '', base: '', ext: '', name: '' };
- if (path.length === 0) return ret;
- var code = path.charCodeAt(0);
- var isAbsolute = code === 47 /*/*/;
- var start;
- if (isAbsolute) {
- ret.root = '/';
- start = 1;
- } else {
- start = 0;
- }
- var startDot = -1;
- var startPart = 0;
- var end = -1;
- var matchedSlash = true;
- var i = path.length - 1;
-
- // Track the state of characters (if any) we see before our first dot and
- // after any path separator we find
- var preDotState = 0;
-
- // Get non-dir info
- for (; i >= start; --i) {
- code = path.charCodeAt(i);
- if (code === 47 /*/*/) {
- // If we reached a path separator that was not part of a set of path
- // separators at the end of the string, stop now
- if (!matchedSlash) {
- startPart = i + 1;
- break;
- }
- continue;
- }
- if (end === -1) {
- // We saw the first non-path separator, mark this as the end of our
- // extension
- matchedSlash = false;
- end = i + 1;
- }
- if (code === 46) {
- // If this is our first dot, mark it as the start of our extension
- if (startDot === -1) startDot = i;else if (preDotState !== 1) preDotState = 1;
- } else if (startDot !== -1) {
- // We saw a non-dot and non-path separator before our dot, so we should
- // have a good chance at having a non-empty extension
- preDotState = -1;
- }
- }
-
- if (startDot === -1 || end === -1 ||
- // We saw a non-dot character immediately before the dot
- preDotState === 0 ||
- // The (right-most) trimmed path component is exactly '..'
- preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) {
- if (end !== -1) {
- if (startPart === 0 && isAbsolute) ret.base = ret.name = path.slice(1, end);else ret.base = ret.name = path.slice(startPart, end);
- }
- } else {
- if (startPart === 0 && isAbsolute) {
- ret.name = path.slice(1, startDot);
- ret.base = path.slice(1, end);
- } else {
- ret.name = path.slice(startPart, startDot);
- ret.base = path.slice(startPart, end);
- }
- ret.ext = path.slice(startDot, end);
- }
-
- if (startPart > 0) ret.dir = path.slice(0, startPart - 1);else if (isAbsolute) ret.dir = '/';
-
- return ret;
- },
-
- sep: '/',
- delimiter: ':',
- win32: null,
- posix: null
-};
-
-posix.posix = posix;
-
-module.exports = posix;
diff --git a/cli/transform.d.ts b/cli/transform.d.ts
deleted file mode 100644
index c63b3cb4ee..0000000000
--- a/cli/transform.d.ts
+++ /dev/null
@@ -1,43 +0,0 @@
-/**
- * @fileoverview Compiler transform interface definitions.
- * @license Apache-2.0
- */
-
-import { Program, Parser, Module } from "..";
-import { OutputStream } from "./asc";
-
-export abstract class Transform {
-
- /** Program reference. */
- readonly program: Program;
-
- /** Base directory. */
- readonly baseDir: string;
-
- /** Output stream used by the compiler. */
- readonly stdout: OutputStream;
-
- /** Error stream used by the compiler. */
- readonly stderr: OutputStream;
-
- /** Logs a message to console. */
- readonly log: typeof console.log;
-
- /** Writes a file to disk. */
- writeFile(filename: string, contents: string | Uint8Array, baseDir: string): boolean;
-
- /** Reads a file from disk. */
- readFile(filename: string, baseDir: string): string | null;
-
- /** Lists all files in a directory. */
- listFiles(dirname: string, baseDir: string): string[] | null;
-
- /** Called when parsing is complete, before a program is instantiated from the AST. */
- afterParse?(parser: Parser): void;
-
- /** Called after the program is instantiated. */
- afterInitialize?(program: Program): void;
-
- /** Called when compilation is complete, before the module is being validated. */
- afterCompile?(module: Module): void;
-}
diff --git a/cli/transform.js b/cli/transform.js
deleted file mode 100644
index 8f68d7a2e5..0000000000
--- a/cli/transform.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/**
- * @fileoverview Compiler transform interface.
- * @license Apache-2.0
- */
-
-// becomes replaced with the actual base by asc
-exports.Transform = function Transform() { /* nop */ };
diff --git a/cli/tsconfig.json b/cli/tsconfig.json
new file mode 100644
index 0000000000..bcb1b8a11d
--- /dev/null
+++ b/cli/tsconfig.json
@@ -0,0 +1,6 @@
+{
+ "extends": "../tsconfig-base.json",
+ "include": [
+ "./**/*.ts"
+ ]
+}
diff --git a/cli/util/colors.d.ts b/cli/util/colors.d.ts
deleted file mode 100644
index 75d689a50f..0000000000
--- a/cli/util/colors.d.ts
+++ /dev/null
@@ -1,55 +0,0 @@
-/**
- * @fileoverview Terminal colors utility definitions.
- * @license Apache-2.0
- */
-
-interface Colors {
- /** Whether terminal colors are supported. */
- supported: boolean;
- /** Colors a string in gray if {@link supported}. */
- gray(text: string): string;
- /** Colors a string in red if {@link supported}. */
- red(text: string): string;
- /** Colors a string in green if {@link supported}. */
- green(text: string): string;
- /** Colors a string in yellow if {@link supported}. */
- yellow(text: string): string;
- /** Colors a string in blue if {@link supported}. */
- blue(text: string): string;
- /** Colors a string in magenta if {@link supported}. */
- magenta(text: string): string;
- /** Colors a string in cyan if {@link supported}. */
- cyan(text: string): string;
- /** Colors a string in white if {@link supported}. */
- white(text: string): string;
-}
-
-interface Exports extends Colors {
- /** Standard output wrapper. */
- stdout: Colors;
- /** Standard error wrapper. */
- stderr: Colors;
- /** Creates an instance for the specified stream. */
- from(stream: Record, base?: Record): Colors;
- /** Gray color escape sequence. */
- GRAY: string;
- /** Red color escape sequence. */
- RED: string;
- /** Green color escape sequence. */
- GREEN: string;
- /** Yellow color escape sequence. */
- YELLOW: string;
- /** Blue color escape sequence. */
- BLUE: string;
- /** Magenta color escape sequence. */
- MAGENTA: string;
- /** Cyan color escape sequence. */
- CYAN: string;
- /** White color escape sequence. */
- WHITE: string;
- /** Reset color escape sequence. */
- RESET: string;
-}
-
-declare const colors: Exports;
-export = colors;
diff --git a/cli/util/colors.js b/cli/util/colors.js
deleted file mode 100644
index 798960c7a0..0000000000
--- a/cli/util/colors.js
+++ /dev/null
@@ -1,35 +0,0 @@
-/**
- * @fileoverview Terminal colors utility.
- * @license Apache-2.0
- */
-
-var proc = typeof process !== "undefined" && process || {};
-var isCI = proc.env && "CI" in proc.env; // doesn't work when bundled because 'process' is a mock
-
-function from(stream, base) {
- var colors = base || {};
- colors.supported = (stream && !!stream.isTTY) || isCI;
- colors.gray = text => colors.supported ? exports.GRAY + text + exports.RESET : text;
- colors.red = text => colors.supported ? exports.RED + text + exports.RESET : text;
- colors.green = text => colors.supported ? exports.GREEN + text + exports.RESET : text;
- colors.yellow = text => colors.supported ? exports.YELLOW + text + exports.RESET : text;
- colors.blue = text => colors.supported ? exports.BLUE + text + exports.RESET : text;
- colors.magenta = text => colors.supported ? exports.MAGENTA + text + exports.RESET : text;
- colors.cyan = text => colors.supported ? exports.CYAN + text + exports.RESET : text;
- colors.white = text => colors.supported ? exports.WHITE + text + exports.RESET : text;
- return colors;
-}
-
-exports.stdout = from(proc.stdout, exports);
-exports.stderr = from(proc.stderr);
-exports.from = from;
-
-exports.GRAY = "\u001b[90m";
-exports.RED = "\u001b[91m";
-exports.GREEN = "\u001b[92m";
-exports.YELLOW = "\u001b[93m";
-exports.BLUE = "\u001b[94m";
-exports.MAGENTA = "\u001b[95m";
-exports.CYAN = "\u001b[96m";
-exports.WHITE = "\u001b[97m";
-exports.RESET = "\u001b[0m";
diff --git a/cli/util/find.d.ts b/cli/util/find.d.ts
deleted file mode 100644
index cc2aeaed37..0000000000
--- a/cli/util/find.d.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-/**
- * @fileoverview File finding utility definitions.
- * @license Apache-2.0
- */
-
-export function files(dirname: string, filter?: ((name: string) => bool) | RegExp): string[];
diff --git a/cli/util/mkdirp.d.ts b/cli/util/mkdirp.d.ts
deleted file mode 100644
index 7a0658d500..0000000000
--- a/cli/util/mkdirp.d.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-/**
- * @fileoverview Recursive mkdir definitions.
- * @license Apache-2.0
- */
-
-interface Options {
- mode?: number;
-}
-declare function mkdirp(path: string, options?: Options): string | null;
-export = mkdirp;
diff --git a/cli/util/mkdirp.js b/cli/util/mkdirp.js
deleted file mode 100644
index 24d94043b0..0000000000
--- a/cli/util/mkdirp.js
+++ /dev/null
@@ -1,62 +0,0 @@
-/**
- * @fileoverview Recursive mkdir.
- * @license
- * Copyright 2010 James Halliday (mail@substack.net)
- *
- * This project is free software released under the MIT/X11 license:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-const path = require("path");
-const fs = require("fs");
-const process = require("process"); // ensure shim
-
-module.exports = function mkdirp(p, opts, made) {
- if (!opts || typeof opts !== "object") {
- opts = { mode: opts };
- }
- var mode = opts.mode;
- if (mode === undefined) {
- mode = 0o777 & (~process.umask());
- }
- if (!made) made = null;
- p = path.resolve(p);
- try {
- fs.mkdirSync(p, mode);
- made = made || p;
- } catch (err0) {
- switch (err0.code) {
- case "ENOENT":
- made = mkdirp(path.dirname(p), opts, made);
- mkdirp(p, opts, made);
- break;
- default:
- var stat;
- try {
- stat = fs.statSync(p);
- } catch (err1) {
- throw err0;
- }
- if (!stat.isDirectory()) throw err0;
- break;
- }
- }
- return made;
-};
diff --git a/cli/util/utf8.d.ts b/cli/util/utf8.d.ts
deleted file mode 100644
index d419c041e3..0000000000
--- a/cli/util/utf8.d.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-/**
- * @fileoverview UTF8 utility definitions.
- * @license Apache-2.0
- */
-
-/**
- * Calculates the UTF8 byte length of a string.
- * @param {string} string String
- * @returns {number} Byte length
- */
-export function length(string: string): number;
-
-/**
- * Reads UTF8 bytes as a string.
- * @param {Uint8Array} buffer Source buffer
- * @param {number} start Source start
- * @param {number} end Source end
- * @returns {string} String read
- */
-export function read(buffer: Uint8Array, start: number, end: number): string;
-
-/**
- * Writes a string as UTF8 bytes.
- * @param {string} string Source string
- * @param {Uint8Array} buffer Destination buffer
- * @param {number} offset Destination offset
- * @returns {number} Bytes written
- */
-export function write(string: string, buffer: Uint8Array, offset: number): number;
diff --git a/cli/util/utf8.js b/cli/util/utf8.js
deleted file mode 100644
index 22f16671e9..0000000000
--- a/cli/util/utf8.js
+++ /dev/null
@@ -1,110 +0,0 @@
-/**
- * @fileoverview UTF8 utility.
- * @license Apache-2.0
- */
-
-// @protobufjs/utf8
-
-/**
- * A minimal UTF8 implementation for number arrays.
- * @memberof util
- * @namespace
- */
-var utf8 = exports;
-
-/**
- * Calculates the UTF8 byte length of a string.
- * @param {string} string String
- * @returns {number} Byte length
- */
-utf8.length = function utf8_length(string) {
- var len = 0,
- c = 0;
- for (var i = 0, l = string.length; i < l; ++i) {
- c = string.charCodeAt(i);
- if (c < 128)
- len += 1;
- else if (c < 2048)
- len += 2;
- else if ((c & 0xFC00) === 0xD800 && (string.charCodeAt(i + 1) & 0xFC00) === 0xDC00) {
- ++i;
- len += 4;
- } else
- len += 3;
- }
- return len;
-};
-
-/**
- * Reads UTF8 bytes as a string.
- * @param {Uint8Array} buffer Source buffer
- * @param {number} start Source start
- * @param {number} end Source end
- * @returns {string} String read
- */
-utf8.read = function utf8_read(buffer, start, end) {
- var len = end - start;
- if (len < 1)
- return "";
- var parts = null,
- chunk = [],
- i = 0, // char offset
- t; // temporary
- while (start < end) {
- t = buffer[start++];
- if (t < 128)
- chunk[i++] = t;
- else if (t > 191 && t < 224)
- chunk[i++] = (t & 31) << 6 | buffer[start++] & 63;
- else if (t > 239 && t < 365) {
- t = ((t & 7) << 18 | (buffer[start++] & 63) << 12 | (buffer[start++] & 63) << 6 | buffer[start++] & 63) - 0x10000;
- chunk[i++] = 0xD800 + (t >> 10);
- chunk[i++] = 0xDC00 + (t & 1023);
- } else
- chunk[i++] = (t & 15) << 12 | (buffer[start++] & 63) << 6 | buffer[start++] & 63;
- if (i > 8191) {
- (parts || (parts = [])).push(String.fromCharCode.apply(String, chunk));
- i = 0;
- }
- }
- if (parts) {
- if (i)
- parts.push(String.fromCharCode.apply(String, chunk.slice(0, i)));
- return parts.join("");
- }
- return String.fromCharCode.apply(String, chunk.slice(0, i));
-};
-
-/**
- * Writes a string as UTF8 bytes.
- * @param {string} string Source string
- * @param {Uint8Array} buffer Destination buffer
- * @param {number} offset Destination offset
- * @returns {number} Bytes written
- */
-utf8.write = function utf8_write(string, buffer, offset) {
- var start = offset,
- c1, // character 1
- c2; // character 2
- for (var i = 0; i < string.length; ++i) {
- c1 = string.charCodeAt(i);
- if (c1 < 128) {
- buffer[offset++] = c1;
- } else if (c1 < 2048) {
- buffer[offset++] = c1 >> 6 | 192;
- buffer[offset++] = c1 & 63 | 128;
- } else if ((c1 & 0xFC00) === 0xD800 && ((c2 = string.charCodeAt(i + 1)) & 0xFC00) === 0xDC00) {
- c1 = 0x10000 + ((c1 & 0x03FF) << 10) + (c2 & 0x03FF);
- ++i;
- buffer[offset++] = c1 >> 18 | 240;
- buffer[offset++] = c1 >> 12 & 63 | 128;
- buffer[offset++] = c1 >> 6 & 63 | 128;
- buffer[offset++] = c1 & 63 | 128;
- } else {
- buffer[offset++] = c1 >> 12 | 224;
- buffer[offset++] = c1 >> 6 & 63 | 128;
- buffer[offset++] = c1 & 63 | 128;
- }
- }
- return offset - start;
-};
diff --git a/dist/asc.d.ts b/dist/asc.d.ts
new file mode 100644
index 0000000000..17fcb31434
--- /dev/null
+++ b/dist/asc.d.ts
@@ -0,0 +1,4 @@
+///
+export * from "types:assemblyscript/cli/index";
+import * as asc from "types:assemblyscript/cli/index";
+export default asc;
diff --git a/dist/assemblyscript.d.ts b/dist/assemblyscript.d.ts
new file mode 100644
index 0000000000..2b2e4a4403
--- /dev/null
+++ b/dist/assemblyscript.d.ts
@@ -0,0 +1,4 @@
+///
+export * from "types:assemblyscript/src/index";
+import * as assemblyscript from "types:assemblyscript/src/index";
+export default assemblyscript;
diff --git a/dist/transform.cjs b/dist/transform.cjs
new file mode 100644
index 0000000000..a245e852c8
--- /dev/null
+++ b/dist/transform.cjs
@@ -0,0 +1 @@
+module.exports = class Transform { /* stub */ };
diff --git a/dist/transform.d.ts b/dist/transform.d.ts
new file mode 100644
index 0000000000..14efe05e8f
--- /dev/null
+++ b/dist/transform.d.ts
@@ -0,0 +1 @@
+export { Transform } from "./asc";
diff --git a/dist/transform.js b/dist/transform.js
new file mode 100644
index 0000000000..f6c0877686
--- /dev/null
+++ b/dist/transform.js
@@ -0,0 +1 @@
+export class Transform { /* stub */ };
diff --git a/eslint.config.js b/eslint.config.js
new file mode 100644
index 0000000000..4c53f86f2b
--- /dev/null
+++ b/eslint.config.js
@@ -0,0 +1,231 @@
+import { defineConfig, globalIgnores } from "eslint/config";
+
+import js from "@eslint/js";
+import tseslint from "typescript-eslint";
+import globals from "globals";
+
+export default defineConfig([
+ globalIgnores([
+ "**/*.d.ts",
+
+ "dist/**",
+ "lib/binaryen.js",
+ "lib/parse/index.js",
+ "build/**",
+ "raw/**",
+
+ // Exclude AS sources with non-standard decorators
+ "src/glue/wasm/**/*.ts",
+ "std/assembly/**/*.ts",
+
+ "tests/parser/**",
+ "tests/compiler/**",
+ "tests/asconfig/**",
+ "lib/loader/tests/**",
+
+ // FIXME: Tagged template literal tests with invalid escapes
+ "tests/compiler/templateliteral.ts",
+ ]),
+
+ js.configs.recommended,
+ ...tseslint.configs.recommended,
+
+ {
+ files: ["**/*.{js,ts}"],
+
+ languageOptions: {
+ parser: tseslint.parser,
+ ecmaVersion: 2024,
+ sourceType: "module",
+ globals: {
+ ...globals.es2024,
+ globalThis: "readonly",
+ BigInt64Array: "readonly",
+ BigUint64Array: "readonly",
+ WebAssembly: "readonly",
+ FinalizationRegistry: "readonly",
+ fetch: "readonly",
+ URL: "readonly",
+ console: "readonly",
+ },
+ },
+
+ plugins: {
+ "@typescript-eslint": tseslint.plugin,
+ },
+
+ rules: {
+ semi: "error",
+
+ indent: ["error", 2, {
+ SwitchCase: 1,
+ VariableDeclarator: "first",
+ offsetTernaryExpressions: true,
+ ignoredNodes: [
+ "ConditionalExpression > *",
+ "ConditionalExpression > * > *",
+ "ConditionalExpression > * > * > *",
+ ],
+ }],
+
+ "spaced-comment": ["error", "always", {
+ markers: ["/"],
+ exceptions: ["/"],
+ }],
+
+ "prefer-const": "off",
+ "no-var": "off",
+ "no-fallthrough": "off",
+
+ "no-constant-condition": ["error", { checkLoops: false }],
+ "no-inner-declarations": "off",
+
+ "no-loss-of-precision": "off",
+ "no-unused-vars": "off",
+ "no-useless-assignment": "off",
+
+ "@typescript-eslint/no-this-alias": "off",
+ "@typescript-eslint/no-unused-vars": "off",
+ },
+ },
+
+ // === JavaScript ===
+ {
+ files: ["**/*.js", "bin/*"],
+
+ languageOptions: {
+ globals: {
+ ...globals.browser,
+ ...globals.amd,
+ ...globals.node,
+ ...globals.es6,
+ },
+ },
+
+ rules: {
+ "@typescript-eslint/no-var-requires": "off",
+ "@typescript-eslint/explicit-module-boundary-types": "off",
+
+ "no-unused-vars": ["warn", {
+ vars: "local",
+ args: "none",
+ ignoreRestSiblings: false,
+ }],
+
+ "@typescript-eslint/no-loss-of-precision": "error",
+ },
+ },
+
+ // === TypeScript ===
+ {
+ files: ["**/*.ts"],
+
+ rules: {
+ "@typescript-eslint/no-unused-vars": ["warn", {
+ vars: "local",
+ varsIgnorePattern: "^[A-Z](?:From|To)?$",
+ args: "none",
+ ignoreRestSiblings: false,
+ }],
+ },
+ },
+
+ // === AssemblyScript ===
+ {
+ files: [
+ "**/assembly/**/*.ts",
+ "src/**/*.ts",
+ "lib/parse/src/**/*.ts",
+ ],
+
+ rules: {
+ "@typescript-eslint/no-namespace": "off",
+ "@typescript-eslint/no-array-constructor": "off",
+ "@typescript-eslint/ban-ts-comment": "off",
+ "@typescript-eslint/no-non-null-assertion": "off",
+ },
+ },
+
+ // === Compiler ===
+ {
+ files: [
+ "src/**/*.ts",
+ "std/assembly/**/*.ts",
+ ],
+
+ rules: {
+ "no-cond-assign": "off",
+ "@typescript-eslint/no-inferrable-types": "off",
+ "@typescript-eslint/triple-slash-reference": "off",
+ "no-shadow-restricted-names": "off",
+ "@typescript-eslint/ban-types": "off",
+ },
+ },
+
+ // === Standard Library ===
+ {
+ files: ["std/assembly/**/*.ts"],
+
+ rules: {
+ "no-shadow-restricted-names": "off",
+ "@typescript-eslint/ban-types": "off",
+ },
+ },
+
+ // === Definition files ===
+ {
+ files: ["std/**/*.d.ts"],
+
+ rules: {
+ "@typescript-eslint/no-explicit-any": "off",
+ "@typescript-eslint/no-empty-interface": "off",
+ "@typescript-eslint/ban-types": "off",
+ },
+ },
+
+ // === Dist definitions ===
+ {
+ files: ["./dist/*.d.ts"],
+
+ rules: {
+ "@typescript-eslint/no-namespace": "off",
+ "@typescript-eslint/triple-slash-reference": "off",
+ },
+ },
+
+ // === Tests ===
+ {
+ files: [
+ "./tests/compiler/**/*.ts",
+ "./lib/loader/tests/assembly/**/*.ts",
+ ],
+
+ rules: {
+ "no-empty": "off",
+ "no-cond-assign": "off",
+ "no-compare-neg-zero": "off",
+ "no-inner-declarations": "off",
+ "no-constant-condition": "off",
+ "use-isnan": "off",
+
+ "@typescript-eslint/no-namespace": "off",
+ "@typescript-eslint/no-unused-vars": "off",
+ "@typescript-eslint/no-empty-function": "off",
+ "@typescript-eslint/no-non-null-assertion": "off",
+ "@typescript-eslint/no-extra-semi": "off",
+ "@typescript-eslint/no-inferrable-types": "off",
+ "@typescript-eslint/ban-types": "off",
+ "@typescript-eslint/triple-slash-reference": "off",
+ "@typescript-eslint/ban-ts-comment": "off",
+ "@typescript-eslint/no-extra-non-null-assertion": "off",
+ "@typescript-eslint/no-empty-interface": "off",
+ },
+ },
+
+ {
+ files: ["tests/transform/cjs/**/*.js"],
+ rules: {
+ "@typescript-eslint/no-require-imports": "off",
+ },
+ },
+]);
diff --git a/index.d.ts b/index.d.ts
deleted file mode 100644
index c039a8000c..0000000000
--- a/index.d.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-import "./src/glue/js";
-export * from "./src";
diff --git a/index.js b/index.js
deleted file mode 100644
index e8e52df9a7..0000000000
--- a/index.js
+++ /dev/null
@@ -1,7 +0,0 @@
-try { require("source-map-support").install(); } catch (e) { /* nop */ }
-require("ts-node").register({
- project: require("path").join(__dirname, "src", "tsconfig.json"),
- skipIgnore: true
-});
-require("./src/glue/js");
-module.exports = require("./src");
diff --git a/index.release.d.ts b/index.release.d.ts
deleted file mode 100644
index 388aca2060..0000000000
--- a/index.release.d.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-///
-export * from "assemblyscript";
diff --git a/index.release.js b/index.release.js
deleted file mode 100644
index b459cec30a..0000000000
--- a/index.release.js
+++ /dev/null
@@ -1 +0,0 @@
-module.exports = require("./dist/assemblyscript");
diff --git a/lib/README.md b/lib/README.md
new file mode 100644
index 0000000000..9ac01cc665
--- /dev/null
+++ b/lib/README.md
@@ -0,0 +1,14 @@
+Library
+=======
+
+Additional packages provided by the main package.
+
+| Package | Description
+|------------------------------------|-------------------------
+| [@assemblyscript/loader](./loader) | Module loader utility
+| [@assemblyscript/rtrace](./rtrace) | Runtime tracing utility
+| binaryen | Binaryen proxy
+
+The Binaryen proxy herein is imported accross the code base and forwards the
+`binaryen` npm package by default. It can be modified to use a custom build,
+for example for testing purposes.
diff --git a/lib/binaryen.d.ts b/lib/binaryen.d.ts
new file mode 100644
index 0000000000..facd164949
--- /dev/null
+++ b/lib/binaryen.d.ts
@@ -0,0 +1,2 @@
+export * from "binaryen";
+export { default } from "binaryen";
diff --git a/lib/binaryen.js b/lib/binaryen.js
new file mode 100644
index 0000000000..facd164949
--- /dev/null
+++ b/lib/binaryen.js
@@ -0,0 +1,2 @@
+export * from "binaryen";
+export { default } from "binaryen";
diff --git a/lib/loader/README.md b/lib/loader/README.md
index 58ce74c630..ff1e805977 100644
--- a/lib/loader/README.md
+++ b/lib/loader/README.md
@@ -1,5 +1,318 @@
# AssemblyScript Loader
-A convenient loader for [AssemblyScript](https://assemblyscript.org) modules. Demangles module exports to a friendly object structure compatible with TypeScript definitions and provides useful utility to read/write data from/to memory.
+A tiny module loader that makes working with AssemblyScript modules as convenient as it gets without sacrificing efficiency. It about mirrors the relevant parts of the WebAssembly API while also providing utility to allocate and read strings, arrays and classes.
-[Documentation](https://assemblyscript.org/loader.html)
+**DEPRECATION NOTICE:** The loader has been deprecated in AssemblyScript 0.20. It will likely continue to work for a while, but it is recommended to switch to the new [static bindings](https://www.assemblyscript.org/compiler.html#host-bindings) generation.
+
+## Example
+
+```ts
+import loader from "@assemblyscript/loader"; // or require
+loader.instantiate(
+ // Binary to instantiate
+ fetch("optimized.wasm"), // or fs.readFileSync
+ // or fs.promises.readFile
+ // or just a buffer
+ // Additional imports
+ { ... }
+).then(({ exports }) => {
+ ...
+})
+```
+
+The loader basically instantiates the module using `WebAssembly` APIs, but also adds additional utility.
+
+## Installation
+
+The loader can be installed from [npm](https://www.npmjs.com/package/@assemblyscript/loader):
+
+```sh
+npm install --save @assemblyscript/loader
+```
+
+On the web:
+
+```html
+
+
+
+
+```
+
+## Usage
+
+One task the loader does not perform is to implicitly translate between WebAssembly pointers and JavaScript objects, and that's where the mixed in utility comes into play. For example, if one has
+
+```ts
+// AssemblyScript
+export function concat(a: string, b: string): string {
+ return a + b
+}
+```
+
+and then wants to call `concat` externally, the string arguments cannot just be JavaScript strings but must first be allocated in the module's memory with their lifetime tracked, like so:
+
+```js
+// JavaScript
+const { concat } = myModule.exports
+const { __newString, __getString } = myModule.exports
+
+function doConcat(aStr, bStr) {
+ let aPtr = __newString(aStr)
+ let bPtr = __newString(bStr)
+ let cPtr = concat(aPtr, bPtr)
+ let cStr = __getString(cPtr)
+ return cStr
+}
+
+console.log(doConcat("Hello ", "world!"))
+```
+
+### Creating arrays
+
+Arrays (or more advanced classes for that matter) require a bit more cooperation because we need to know their value type in order to work with them properly. To achieve this, every class has a unique id internally, and a chunk of runtime type information (RTTI) is shipped with the module to evaluate class types. Here's an example of working with an `Int32Array`:
+
+```ts
+// AssemblyScript
+export function sum(arr: Int32Array): i32 {
+ let sum = 0
+ for (let i = 0, k = arr.length; i < k; ++i) {
+ sum += unchecked(arr[i])
+ }
+ return sum
+}
+export const Int32Array_ID = idof()
+```
+
+```js
+// JavaScript
+const { sum, Int32Array_ID } = myModule.exports
+const { __newArray } = myModule.exports
+
+function doSum(values) {
+ const arrPtr = __newArray(Int32Array_ID, values)
+ return sum(arrPtr)
+}
+
+console.log(doSum([1, 2, 3]))
+```
+
+This works with all kinds of arrays, except that ids are different and values are interpreted differently, of course.
+
+### Reading arrays
+
+If one is instead interested in the values of an array being returned by the module, there are two approaches to this. Let's say we have the following module:
+
+```ts
+// AssemblyScript
+export function getRandomArray(len: i32): Int32Array {
+ const arr = new Int32Array(len)
+ // fill with random values
+ return arr
+}
+```
+
+The first is, obviously, to read the array's values from the module's memory by essentially copying them to a JS array
+
+```js
+// JavaScript
+const { getRandomArray } = myModule.exports
+const { __getArray } = myModule.exports
+
+function doGetRandomArray(len) {
+ const arrPtr = getRandomArray(len)
+ const values = __getArray(arrPtr)
+ return values
+}
+
+console.log(doGetRandomArray(10))
+```
+
+which is always safe, while the second is to create a live view on the array, enabling two-way modification of its values:
+
+```js
+// JavaScript
+const { getRandomArray } = myModule.exports
+const { __getArrayView, __pin, __unpin } = myModule.exports
+
+function doGetRandomArrayView(len) {
+ const arrPtr = __pin(getRandomArray(len)) // pin if necessary
+ const view = __getArrayView(arrPtr)
+ return { ptr, view }
+}
+
+const randomArray = doGetRandomArrayView(10)
+console.log(randomArray.view)
+__unpin(randomArray.ptr) // unpin if necessary
+```
+
+The latter variant can be more efficient (and useful) but is a little dangerous because the view may become detached from the module's memory when memory automatically grows. Also, the viewed array can grow automatically when pushed to, with the view then referencing random memory. Pushing to an array can be avoided quite easily, yet it is notoriously hard to predict when module memory grows - but one can try to set a sufficiently large size of `--initialMemory` or defensively trigger a sufficiently large dynamic allocation being freed immediately before dealing with potentially problematic views.
+
+### Custom classes
+
+As mentioned earlier, the loader understands how to make a nice object structure of a module's exports, and it is possible to utilize it to work with classes in a more natural way. For example, when calling the following function externally
+
+```ts
+// AssemblyScript
+export class Foo {
+ constructor(public str: string) {}
+ getString(): string {
+ return this.str
+ }
+}
+
+export function getFoo(): Foo { // this one
+ return new Foo("Hello world!")
+}
+```
+
+one can wrap the received pointer in a `myModule.exports.Foo` instance:
+
+```js
+// JavaScript
+const { Foo, getFoo } = myModule.exports
+const { __getString, __pin, __unpin } = myModule.exports
+
+const fooPtr = __pin(getFoo()) // pin if necessary
+const foo = Foo.wrap(fooPtr)
+const strPtr = foo.getString()
+console.log(__getString(strPtr))
+__unpin(fooPtr) // unpin if necessary
+```
+
+## API
+
+For reference, here comes the full API provided by the loader.
+
+::: tip
+Copying from and extending the examples above is typically sufficient.
+:::
+
+### Static members
+
+* ```ts
+ function instantiate(
+ moduleOrBuffer: WasmInstantiable,
+ imports?: WasmImports
+ ): Promise
+ ```
+ Asynchronously instantiates an AssemblyScript module from anything that can be instantiated.
+
+* ```ts
+ function instantiateSync(
+ moduleOrBuffer: WasmInstantiable,
+ imports?: WasmImports
+ ): ASUtil & T
+ ```
+ Synchronously instantiates an AssemblyScript module from a WebAssembly.Module or binary buffer. Not recommended.
+
+* ```ts
+ function instantiateStreaming(
+ response: Response | PromiseLike,
+ imports?: WasmImports
+ ): Promise
+ ```
+ Asynchronously instantiates an AssemblyScript module from a response, i.e. as obtained by fetch.
+
+* ```ts
+ function demangle(
+ exports: WasmExports,
+ baseModule?: Object
+ ): T
+ ```
+ Demangles an AssemblyScript module's exports to a friendly object structure. You usually don't have to call this manually as instantiation does this implicitly.
+
+Note that `T` above can either be omitted if the shape of the module is unknown, or can reference a `.d.ts` (i.e. `typeof MyModule`) as produced by the compiler with the `-d` option.
+
+### Module instance utility
+
+The following utility functions are mixed into the module's exports.
+
+* ```ts
+ function __newString(str: string): number
+ ```
+ Allocates a new string in the module's memory and returns a pointer to it. Requires `--exportRuntime` for access to `__new`.
+
+* ```ts
+ function __newArray(
+ id: number,
+ values: valuesOrCapacity?: number[] | ArrayBufferView | number
+ ): number
+ ```
+ Allocates a new array in the module's memory and returns a pointer to it. The `id` is the unique runtime id of the respective array class. If you are using `Int32Array` for example, the best way to know the id is an `export const Int32Array_ID = idof()`. Requires `--exportRuntime` for access to `__new`. The `values` parameter сan also be used to pre-allocate an otherwise empty array of a certain capacity.
+
+* ```ts
+ function __getString(ptr: number): string
+ ```
+ Copies a string's value from the module's memory to a JavaScript string. `ptr` must not be zero.
+
+* ```ts
+ function __getFunction(ptr: number): ((...args: unknown[]) => unknown) | null
+ ```
+ Gets a callable function object from the module's memory containing its table index. `ptr` must not be zero.
+
+* ```ts
+ function __getArrayBuffer(ptr: number): ArrayBuffer
+ ```
+ Copies an ArrayBuffer's value from the module's memory to a JavaScript buffer. `ptr` must not be zero.
+
+* ```ts
+ function __getArray(ptr: number): number[]
+ ```
+ Copies an array's values from the module's memory to a JavaScript array. Infers the array type from RTTI. `ptr` must not be zero.
+
+* ```ts
+ function __getArrayView(ptr: number): TypedArray
+ ```
+ Gets a live view on the values of an array in the module's memory. Infers the array type from RTTI. `ptr` must not be zero.
+
+ This differs from `__getArray` in that the data isn't copied but remains live in both directions. That's faster but also unsafe because if the array grows or becomes garbage collected, the view will no longer represent the correct memory region and modifying its values in this state will most likely corrupt memory or otherwise explode. Use, but use with care.
+
+* ```ts
+ function __getInt8ArrayView(ptr: number): Int8Array
+ function __getUint8ArrayView(ptr: number): Uint8Array
+ function __getUint8ClampedArrayView(ptr: number): Uint8ClampedArray
+ function __getInt16ArrayView(ptr: number): Int16Array
+ function __getUint16ArrayView(ptr: number): Uint16Array
+ function __getInt32ArrayView(ptr: number): Int32Array
+ function __getUint32ArrayView(ptr: number): Uint32Array
+ function __getInt64ArrayView(ptr: number): BigInt64Array
+ function __getUint64ArrayView(ptr: number): BigUint64Array
+ function __getFloat32ArrayView(ptr: number): Float32Array
+ function __getFloat64ArrayView(ptr: number): Float64Array
+ ```
+ Slightly more efficient variants of `__getArrayView` where the type of the array is know beforehand. Doesn't try to infer the type.
+
+### Module instance runtime interface
+
+When compiling with `--exportRuntime`, the loader will expose the runtime interface (`__new`, `__pin`, `__unpin`, `__collect`) as well.
+
+## Convenience vs. efficiency
+
+Making the loader's API any more convenient has its tradeoffs. One would either have to include extended type information with the module itself or generate an additional JavaScript file of glue code that does (and hides) all the lifting. As such, one can consider the loader as a small and efficient building block that can do it all, yet does not sacrifice efficiency. If that's not exactly what you are looking for, take a look at more convenient tools below. Just remember that these have tradeoffs.
+
+### More convenient tools
+
+* [as-bind](https://github.com/torch2424/as-bind) is a library, built on top of the loader, to make passing high-level data structures between AssemblyScript and JavaScript more convenient.
+
+## Advanced usage
+
+### Direct memory access
+
+All of the above can be mixed with direct memory accesses on `myModule.exports.memory.buffer`, for instance by adhering to class layout.
+
+### TypeScript definitions
+
+The compiler is able to emit definitions using the `-d` command line option that are compatible with modules demangled by the loader, and these can be used for proper typings in development:
+
+```ts
+// TypeScript
+import type * as MyModule from "myModule"; // pointing at the generated d.ts
+
+loader.instantiate(
+ fetch("myModule.wasm"),
+ { ... }
+).then(({ exports }) => {
+ ...
+})
+```
diff --git a/lib/loader/index.d.ts b/lib/loader/index.d.ts
index 3098da6002..39b3dd75ed 100644
--- a/lib/loader/index.d.ts
+++ b/lib/loader/index.d.ts
@@ -24,9 +24,6 @@ export interface ASUtil {
memory?: WebAssembly.Memory;
table?: WebAssembly.Table;
- /** Explicit start function, if requested. */
- _start(): void;
-
/** Copies a string's value from the module's memory. */
__getString(ptr: number): string;
/** Copies an ArrayBuffer's value from the module's memory. */
@@ -82,12 +79,15 @@ export interface ASUtil {
/** Gets a live view on a Float64Array's values in the module's memory. */
__getFloat64ArrayView(ptr: number): Float64Array;
- /** Tests whether a managed object is an instance of the class represented by the specified base id. */
- __instanceof(ptr: number, baseId: number): boolean;
+ /** Gets a function from poiner which contain table's index. */
+ __getFunction(ptr: number): ((...args: unknown[]) => unknown) | null;
+
/** Allocates a new string in the module's memory and returns a reference (pointer) to it. */
__newString(str: string): number;
+ /** Allocates a new ArrayBuffer in the module's memory and returns a reference (pointer) to it. */
+ __newArrayBuffer(buf: ArrayBuffer): number;
/** Allocates a new array in the module's memory and returns a reference (pointer) to it. */
- __newArray(id: number, values: ArrayLike): number;
+ __newArray(id: number, valuesOrCapacity?: Array | ArrayBufferView | number): number;
/** Allocates an instance of the class represented by the specified id. */
__new(size: number, id: number): number;
diff --git a/lib/loader/index.js b/lib/loader/index.js
index b1e01f5323..3c97d7b741 100644
--- a/lib/loader/index.js
+++ b/lib/loader/index.js
@@ -3,9 +3,9 @@ const ID_OFFSET = -8;
const SIZE_OFFSET = -4;
// Runtime ids
-const ARRAYBUFFER_ID = 0;
-const STRING_ID = 1;
-// const ARRAYBUFFERVIEW_ID = 2;
+// const OBJECT_ID = 0;
+const ARRAYBUFFER_ID = 1;
+const STRING_ID = 2;
// Runtime type information
const ARRAYBUFFERVIEW = 1 << 0;
@@ -29,25 +29,41 @@ const VAL_MANAGED = 1 << 14;
// Array(BufferView) layout
const ARRAYBUFFERVIEW_BUFFER_OFFSET = 0;
const ARRAYBUFFERVIEW_DATASTART_OFFSET = 4;
-const ARRAYBUFFERVIEW_DATALENGTH_OFFSET = 8;
+const ARRAYBUFFERVIEW_BYTELENGTH_OFFSET = 8;
const ARRAYBUFFERVIEW_SIZE = 12;
const ARRAY_LENGTH_OFFSET = 12;
const ARRAY_SIZE = 16;
+const E_NO_EXPORT_TABLE = "Operation requires compiling with --exportTable";
+const E_NO_EXPORT_RUNTIME = "Operation requires compiling with --exportRuntime";
+const F_NO_EXPORT_RUNTIME = () => { throw Error(E_NO_EXPORT_RUNTIME); };
+
const BIGINT = typeof BigUint64Array !== "undefined";
const THIS = Symbol();
-const STRING_DECODE_THRESHOLD = 32;
-const decoder = new TextDecoder("utf-16le");
+const STRING_SMALLSIZE = 192; // break-even point in V8
+const STRING_CHUNKSIZE = 1024; // mitigate stack overflow
+const utf16 = new TextDecoder("utf-16le", { fatal: true }); // != wtf16
+
+/** polyfill for Object.hasOwn */
+Object.hasOwn = Object.hasOwn || function(obj, prop) {
+ return Object.prototype.hasOwnProperty.call(obj, prop);
+};
-/** Gets a string from an U32 and an U16 view on a memory. */
+/** Gets a string from memory. */
function getStringImpl(buffer, ptr) {
- const len = new Uint32Array(buffer)[ptr + SIZE_OFFSET >>> 2] >>> 1;
- const arr = new Uint16Array(buffer, ptr, len);
- if (len <= STRING_DECODE_THRESHOLD) {
- return String.fromCharCode.apply(String, arr);
+ let len = new Uint32Array(buffer)[ptr + SIZE_OFFSET >>> 2] >>> 1;
+ const wtf16 = new Uint16Array(buffer, ptr, len);
+ if (len <= STRING_SMALLSIZE) return String.fromCharCode(...wtf16);
+ try {
+ return utf16.decode(wtf16);
+ } catch {
+ let str = "", off = 0;
+ while (len - off > STRING_CHUNKSIZE) {
+ str += String.fromCharCode(...wtf16.subarray(off, off += STRING_CHUNKSIZE));
+ }
+ return str + String.fromCharCode(...wtf16.subarray(off));
}
- return decoder.decode(arr);
}
/** Prepares the base module prior to instantiation. */
@@ -76,22 +92,17 @@ function preInstantiate(imports) {
return extendedExports;
}
-const E_NOEXPORTRUNTIME = "Operation requires compiling with --exportRuntime";
-const F_NOEXPORTRUNTIME = function() { throw Error(E_NOEXPORTRUNTIME); };
-
/** Prepares the final module once instantiation is complete. */
function postInstantiate(extendedExports, instance) {
const exports = instance.exports;
const memory = exports.memory;
const table = exports.table;
- const __new = exports.__new || F_NOEXPORTRUNTIME;
- const __pin = exports.__pin || F_NOEXPORTRUNTIME;
- const __unpin = exports.__unpin || F_NOEXPORTRUNTIME;
- const __collect = exports.__collect || F_NOEXPORTRUNTIME;
+ const __new = exports.__new || F_NO_EXPORT_RUNTIME;
+ const __pin = exports.__pin || F_NO_EXPORT_RUNTIME;
+ const __unpin = exports.__unpin || F_NO_EXPORT_RUNTIME;
+ const __collect = exports.__collect || F_NO_EXPORT_RUNTIME;
const __rtti_base = exports.__rtti_base;
- const getRttiCount = __rtti_base
- ? function (arr) { return arr[__rtti_base >>> 2]; }
- : F_NOEXPORTRUNTIME;
+ const getTypeinfoCount = __rtti_base ? arr => arr[__rtti_base >>> 2] : F_NO_EXPORT_RUNTIME;
extendedExports.__new = __new;
extendedExports.__pin = __pin;
@@ -99,28 +110,19 @@ function postInstantiate(extendedExports, instance) {
extendedExports.__collect = __collect;
/** Gets the runtime type info for the given id. */
- function getInfo(id) {
+ function getTypeinfo(id) {
const U32 = new Uint32Array(memory.buffer);
- const count = getRttiCount(U32);
- if ((id >>>= 0) >= count) throw Error(`invalid id: ${id}`);
- return U32[(__rtti_base + 4 >>> 2) + id * 2];
+ if ((id >>>= 0) >= getTypeinfoCount(U32)) throw Error(`invalid id: ${id}`);
+ return U32[(__rtti_base + 4 >>> 2) + id];
}
- /** Gets and validate runtime type info for the given id for array like objects */
+ /** Gets and validates runtime type info for the given id for array like objects */
function getArrayInfo(id) {
- const info = getInfo(id);
+ const info = getTypeinfo(id);
if (!(info & (ARRAYBUFFERVIEW | ARRAY | STATICARRAY))) throw Error(`not an array: ${id}, flags=${info}`);
return info;
}
- /** Gets the runtime base id for the given id. */
- function getBase(id) {
- const U32 = new Uint32Array(memory.buffer);
- const count = getRttiCount(U32);
- if ((id >>>= 0) >= count) throw Error(`invalid id: ${id}`);
- return U32[(__rtti_base + 4 >>> 2) + id * 2 + 1];
- }
-
/** Gets the runtime alignment of a collection's values. */
function getValueAlign(info) {
return 31 - Math.clz32((info >>> VAL_ALIGN_OFFSET) & 31); // -1 if none
@@ -137,12 +139,24 @@ function postInstantiate(extendedExports, instance) {
const length = str.length;
const ptr = __new(length << 1, STRING_ID);
const U16 = new Uint16Array(memory.buffer);
- for (var i = 0, p = ptr >>> 1; i < length; ++i) U16[p + i] = str.charCodeAt(i);
+ for (let i = 0, p = ptr >>> 1; i < length; ++i) U16[p + i] = str.charCodeAt(i);
return ptr;
}
extendedExports.__newString = __newString;
+ /** Allocates a new ArrayBuffer in the module's memory and returns its pointer. */
+ function __newArrayBuffer(buf) {
+ if (buf == null) return 0;
+ const bufview = new Uint8Array(buf);
+ const ptr = __new(bufview.length, ARRAYBUFFER_ID);
+ const U8 = new Uint8Array(memory.buffer);
+ U8.set(bufview, ptr);
+ return ptr;
+ }
+
+ extendedExports.__newArrayBuffer = __newArrayBuffer;
+
/** Reads a string from the module's memory by its pointer. */
function __getString(ptr) {
if (!ptr) return null;
@@ -174,10 +188,12 @@ function postInstantiate(extendedExports, instance) {
}
/** Allocates a new array in the module's memory and returns its pointer. */
- function __newArray(id, values) {
+ function __newArray(id, valuesOrCapacity = 0) {
+ const input = valuesOrCapacity;
const info = getArrayInfo(id);
const align = getValueAlign(info);
- const length = values.length;
+ const isArrayLike = typeof input !== "number";
+ const length = isArrayLike ? input.length : input;
const buf = __new(length << align, info & STATICARRAY ? id : ARRAYBUFFER_ID);
let result;
if (info & STATICARRAY) {
@@ -189,18 +205,20 @@ function postInstantiate(extendedExports, instance) {
const U32 = new Uint32Array(memory.buffer);
U32[arr + ARRAYBUFFERVIEW_BUFFER_OFFSET >>> 2] = buf;
U32[arr + ARRAYBUFFERVIEW_DATASTART_OFFSET >>> 2] = buf;
- U32[arr + ARRAYBUFFERVIEW_DATALENGTH_OFFSET >>> 2] = length << align;
+ U32[arr + ARRAYBUFFERVIEW_BYTELENGTH_OFFSET >>> 2] = length << align;
if (info & ARRAY) U32[arr + ARRAY_LENGTH_OFFSET >>> 2] = length;
result = arr;
}
- const view = getView(align, info & VAL_SIGNED, info & VAL_FLOAT);
- if (info & VAL_MANAGED) {
- for (let i = 0; i < length; ++i) {
- const value = values[i];
- view[(buf >>> align) + i] = value;
+ if (isArrayLike) {
+ const view = getView(align, info & VAL_SIGNED, info & VAL_FLOAT);
+ const start = buf >>> align;
+ if (info & VAL_MANAGED) {
+ for (let i = 0; i < length; ++i) {
+ view[start + i] = input[i];
+ }
+ } else {
+ view.set(input, start);
}
- } else {
- view.set(values, buf >>> align);
}
return result;
}
@@ -244,6 +262,15 @@ function postInstantiate(extendedExports, instance) {
extendedExports.__getArrayBuffer = __getArrayBuffer;
+ /** Gets a function from poiner which contain table's index. */
+ function __getFunction(ptr) {
+ if (!table) throw Error(E_NO_EXPORT_TABLE);
+ const index = new Uint32Array(memory.buffer)[ptr >>> 2];
+ return table.get(index);
+ }
+
+ extendedExports.__getFunction = __getFunction;
+
/** Copies a typed array's values from the module's memory. */
function getTypedArray(Type, alignLog2, ptr) {
return new Type(getTypedArrayView(Type, alignLog2, ptr));
@@ -253,8 +280,11 @@ function postInstantiate(extendedExports, instance) {
function getTypedArrayView(Type, alignLog2, ptr) {
const buffer = memory.buffer;
const U32 = new Uint32Array(buffer);
- const bufPtr = U32[ptr + ARRAYBUFFERVIEW_DATASTART_OFFSET >>> 2];
- return new Type(buffer, bufPtr, U32[bufPtr + SIZE_OFFSET >>> 2] >>> alignLog2);
+ return new Type(
+ buffer,
+ U32[ptr + ARRAYBUFFERVIEW_DATASTART_OFFSET >>> 2],
+ U32[ptr + ARRAYBUFFERVIEW_BYTELENGTH_OFFSET >>> 2] >>> alignLog2
+ );
}
/** Attach a set of get TypedArray and View functions to the exports. */
@@ -283,21 +313,6 @@ function postInstantiate(extendedExports, instance) {
});
}
- /** Tests whether an object is an instance of the class represented by the specified base id. */
- function __instanceof(ptr, baseId) {
- const U32 = new Uint32Array(memory.buffer);
- let id = U32[ptr + ID_OFFSET >>> 2];
- if (id <= getRttiCount(U32)) {
- do {
- if (id == baseId) return true;
- id = getBase(id);
- } while (id);
- }
- return false;
- }
-
- extendedExports.__instanceof = __instanceof;
-
// Pull basic exports to extendedExports so code in preInstantiate can use them
extendedExports.memory = extendedExports.memory || memory;
extendedExports.table = extendedExports.table || table;
@@ -354,14 +369,13 @@ export function demangle(exports, extendedExports = {}) {
const setArgumentsLength = exports["__argumentsLength"]
? length => { exports["__argumentsLength"].value = length; }
: exports["__setArgumentsLength"] || exports["__setargc"] || (() => { /* nop */ });
- for (let internalName in exports) {
- if (!Object.prototype.hasOwnProperty.call(exports, internalName)) continue;
+ for (let internalName of Object.keys(exports)) {
const elem = exports[internalName];
let parts = internalName.split(".");
let curr = extendedExports;
while (parts.length > 1) {
let part = parts.shift();
- if (!Object.prototype.hasOwnProperty.call(curr, part)) curr[part] = {};
+ if (!Object.hasOwn(curr, part)) curr[part] = {};
curr = curr[part];
}
let name = parts[0];
@@ -387,7 +401,7 @@ export function demangle(exports, extendedExports = {}) {
name = name.substring(hash + 1);
curr = curr[className].prototype;
if (/^(get|set):/.test(name)) {
- if (!Object.prototype.hasOwnProperty.call(curr, name = name.substring(4))) {
+ if (!Object.hasOwn(curr, name = name.substring(4))) {
let getter = exports[internalName.replace("set:", "get:")];
let setter = exports[internalName.replace("get:", "set:")];
Object.defineProperty(curr, name, {
@@ -398,7 +412,7 @@ export function demangle(exports, extendedExports = {}) {
}
} else {
if (name === 'constructor') {
- (curr[name] = (...args) => {
+ (curr[name] = function(...args) {
setArgumentsLength(args.length);
return elem(...args);
}).original = elem;
@@ -411,7 +425,7 @@ export function demangle(exports, extendedExports = {}) {
}
} else {
if (/^(get|set):/.test(name)) {
- if (!Object.prototype.hasOwnProperty.call(curr, name = name.substring(4))) {
+ if (!Object.hasOwn(curr, name = name.substring(4))) {
Object.defineProperty(curr, name, {
get: exports[internalName.replace("set:", "get:")],
set: exports[internalName.replace("get:", "set:")],
diff --git a/lib/loader/package-lock.json b/lib/loader/package-lock.json
new file mode 100644
index 0000000000..a6d2d6962f
--- /dev/null
+++ b/lib/loader/package-lock.json
@@ -0,0 +1,1355 @@
+{
+ "name": "@assemblyscript/loader",
+ "version": "0.0.0",
+ "lockfileVersion": 2,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "@assemblyscript/loader",
+ "version": "0.0.0",
+ "license": "Apache-2.0",
+ "devDependencies": {
+ "esm2umd": "^0.1.2"
+ }
+ },
+ "node_modules/@ampproject/remapping": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz",
+ "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.1.0",
+ "@jridgewell/trace-mapping": "^0.3.9"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/code-frame": {
+ "version": "7.22.13",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz",
+ "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==",
+ "dev": true,
+ "dependencies": {
+ "@babel/highlight": "^7.22.13",
+ "chalk": "^2.4.2"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/compat-data": {
+ "version": "7.17.10",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.17.10.tgz",
+ "integrity": "sha512-GZt/TCsG70Ms19gfZO1tM4CVnXsPgEPBCpJu+Qz3L0LUDsY5nZqFZglIoPC1kIYOtNBZlrnFT+klg12vFGZXrw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/core": {
+ "version": "7.18.2",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.18.2.tgz",
+ "integrity": "sha512-A8pri1YJiC5UnkdrWcmfZTJTV85b4UXTAfImGmCfYmax4TR9Cw8sDS0MOk++Gp2mE/BefVJ5nwy5yzqNJbP/DQ==",
+ "dev": true,
+ "dependencies": {
+ "@ampproject/remapping": "^2.1.0",
+ "@babel/code-frame": "^7.16.7",
+ "@babel/generator": "^7.18.2",
+ "@babel/helper-compilation-targets": "^7.18.2",
+ "@babel/helper-module-transforms": "^7.18.0",
+ "@babel/helpers": "^7.18.2",
+ "@babel/parser": "^7.18.0",
+ "@babel/template": "^7.16.7",
+ "@babel/traverse": "^7.18.2",
+ "@babel/types": "^7.18.2",
+ "convert-source-map": "^1.7.0",
+ "debug": "^4.1.0",
+ "gensync": "^1.0.0-beta.2",
+ "json5": "^2.2.1",
+ "semver": "^6.3.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/babel"
+ }
+ },
+ "node_modules/@babel/generator": {
+ "version": "7.23.0",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz",
+ "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.23.0",
+ "@jridgewell/gen-mapping": "^0.3.2",
+ "@jridgewell/trace-mapping": "^0.3.17",
+ "jsesc": "^2.5.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
+ "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/set-array": "^1.0.1",
+ "@jridgewell/sourcemap-codec": "^1.4.10",
+ "@jridgewell/trace-mapping": "^0.3.9"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/helper-compilation-targets": {
+ "version": "7.18.2",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.18.2.tgz",
+ "integrity": "sha512-s1jnPotJS9uQnzFtiZVBUxe67CuBa679oWFHpxYYnTpRL/1ffhyX44R9uYiXoa/pLXcY9H2moJta0iaanlk/rQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/compat-data": "^7.17.10",
+ "@babel/helper-validator-option": "^7.16.7",
+ "browserslist": "^4.20.2",
+ "semver": "^6.3.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-environment-visitor": {
+ "version": "7.22.20",
+ "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz",
+ "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-function-name": {
+ "version": "7.23.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz",
+ "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/template": "^7.22.15",
+ "@babel/types": "^7.23.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-hoist-variables": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz",
+ "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-imports": {
+ "version": "7.16.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz",
+ "integrity": "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.16.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-transforms": {
+ "version": "7.18.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.18.0.tgz",
+ "integrity": "sha512-kclUYSUBIjlvnzN2++K9f2qzYKFgjmnmjwL4zlmU5f8ZtzgWe8s0rUPSTGy2HmK4P8T52MQsS+HTQAgZd3dMEA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-environment-visitor": "^7.16.7",
+ "@babel/helper-module-imports": "^7.16.7",
+ "@babel/helper-simple-access": "^7.17.7",
+ "@babel/helper-split-export-declaration": "^7.16.7",
+ "@babel/helper-validator-identifier": "^7.16.7",
+ "@babel/template": "^7.16.7",
+ "@babel/traverse": "^7.18.0",
+ "@babel/types": "^7.18.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-plugin-utils": {
+ "version": "7.17.12",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.17.12.tgz",
+ "integrity": "sha512-JDkf04mqtN3y4iAbO1hv9U2ARpPyPL1zqyWs/2WG1pgSq9llHFjStX5jdxb84himgJm+8Ng+x0oiWF/nw/XQKA==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-simple-access": {
+ "version": "7.18.2",
+ "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.18.2.tgz",
+ "integrity": "sha512-7LIrjYzndorDY88MycupkpQLKS1AFfsVRm2k/9PtKScSy5tZq0McZTj+DiMRynboZfIqOKvo03pmhTaUgiD6fQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.18.2"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-split-export-declaration": {
+ "version": "7.22.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz",
+ "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-string-parser": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz",
+ "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-identifier": {
+ "version": "7.22.20",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
+ "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-option": {
+ "version": "7.16.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz",
+ "integrity": "sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helpers": {
+ "version": "7.18.2",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.18.2.tgz",
+ "integrity": "sha512-j+d+u5xT5utcQSzrh9p+PaJX94h++KN+ng9b9WEJq7pkUPAd61FGqhjuUEdfknb3E/uDBb7ruwEeKkIxNJPIrg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/template": "^7.16.7",
+ "@babel/traverse": "^7.18.2",
+ "@babel/types": "^7.18.2"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/highlight": {
+ "version": "7.22.20",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz",
+ "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.22.20",
+ "chalk": "^2.4.2",
+ "js-tokens": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/parser": {
+ "version": "7.23.0",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz",
+ "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==",
+ "dev": true,
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-modules-commonjs": {
+ "version": "7.18.2",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.18.2.tgz",
+ "integrity": "sha512-f5A865gFPAJAEE0K7F/+nm5CmAE3y8AWlMBG9unu5j9+tk50UQVK0QS8RNxSp7MJf0wh97uYyLWt3Zvu71zyOQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-module-transforms": "^7.18.0",
+ "@babel/helper-plugin-utils": "^7.17.12",
+ "@babel/helper-simple-access": "^7.18.2",
+ "babel-plugin-dynamic-import-node": "^2.3.3"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/template": {
+ "version": "7.22.15",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz",
+ "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.22.13",
+ "@babel/parser": "^7.22.15",
+ "@babel/types": "^7.22.15"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/traverse": {
+ "version": "7.23.2",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz",
+ "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.22.13",
+ "@babel/generator": "^7.23.0",
+ "@babel/helper-environment-visitor": "^7.22.20",
+ "@babel/helper-function-name": "^7.23.0",
+ "@babel/helper-hoist-variables": "^7.22.5",
+ "@babel/helper-split-export-declaration": "^7.22.6",
+ "@babel/parser": "^7.23.0",
+ "@babel/types": "^7.23.0",
+ "debug": "^4.1.0",
+ "globals": "^11.1.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/types": {
+ "version": "7.23.0",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz",
+ "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-string-parser": "^7.22.5",
+ "@babel/helper-validator-identifier": "^7.22.20",
+ "to-fast-properties": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@jridgewell/gen-mapping": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz",
+ "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/set-array": "^1.0.0",
+ "@jridgewell/sourcemap-codec": "^1.4.10"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz",
+ "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/set-array": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.1.tgz",
+ "integrity": "sha512-Ct5MqZkLGEXTVmQYbGtx9SVqD2fqwvdubdps5D3djjAkgkKwT918VNOz65pEHFaYTeWcukmJmH5SwsA9Tn2ObQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.4.15",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
+ "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
+ "dev": true
+ },
+ "node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.19",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz",
+ "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
+ }
+ },
+ "node_modules/ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "dependencies": {
+ "color-convert": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/babel-plugin-dynamic-import-node": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz",
+ "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==",
+ "dev": true,
+ "dependencies": {
+ "object.assign": "^4.1.0"
+ }
+ },
+ "node_modules/browserslist": {
+ "version": "4.20.3",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.3.tgz",
+ "integrity": "sha512-NBhymBQl1zM0Y5dQT/O+xiLP9/rzOIQdKM/eMJBAq7yBgaB6krIYLGejrwVYnSHZdqjscB1SPuAjHwxjvN6Wdg==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ }
+ ],
+ "dependencies": {
+ "caniuse-lite": "^1.0.30001332",
+ "electron-to-chromium": "^1.4.118",
+ "escalade": "^3.1.1",
+ "node-releases": "^2.0.3",
+ "picocolors": "^1.0.0"
+ },
+ "bin": {
+ "browserslist": "cli.js"
+ },
+ "engines": {
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+ }
+ },
+ "node_modules/call-bind": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
+ "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+ "dev": true,
+ "dependencies": {
+ "function-bind": "^1.1.1",
+ "get-intrinsic": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/caniuse-lite": {
+ "version": "1.0.30001344",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001344.tgz",
+ "integrity": "sha512-0ZFjnlCaXNOAYcV7i+TtdKBp0L/3XEU2MF/x6Du1lrh+SRX4IfzIVL4HNJg5pB2PmFb8rszIGyOvsZnqqRoc2g==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
+ }
+ ]
+ },
+ "node_modules/chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dev": true,
+ "dependencies": {
+ "color-name": "1.1.3"
+ }
+ },
+ "node_modules/color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
+ "dev": true
+ },
+ "node_modules/convert-source-map": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz",
+ "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==",
+ "dev": true,
+ "dependencies": {
+ "safe-buffer": "~5.1.1"
+ }
+ },
+ "node_modules/debug": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+ "dev": true,
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/define-properties": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz",
+ "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==",
+ "dev": true,
+ "dependencies": {
+ "has-property-descriptors": "^1.0.0",
+ "object-keys": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/electron-to-chromium": {
+ "version": "1.4.141",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.141.tgz",
+ "integrity": "sha512-mfBcbqc0qc6RlxrsIgLG2wCqkiPAjEezHxGTu7p3dHHFOurH4EjS9rFZndX5axC8264rI1Pcbw8uQP39oZckeA==",
+ "dev": true
+ },
+ "node_modules/escalade": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
+ "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/esm2umd": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/esm2umd/-/esm2umd-0.1.2.tgz",
+ "integrity": "sha512-SoCump2d/jzZJ9/0ZY/2AVOWJbyd5bGOMlRSSNqChPvQrwa9Rqzo9wPP+kT77Gys03Sb+rIgseAReVvIrqvglA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/core": "^7",
+ "@babel/plugin-transform-modules-commonjs": "^7"
+ },
+ "bin": {
+ "esm2umd": "bin/esm2umd.js"
+ }
+ },
+ "node_modules/function-bind": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
+ "dev": true
+ },
+ "node_modules/gensync": {
+ "version": "1.0.0-beta.2",
+ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
+ "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/get-intrinsic": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz",
+ "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==",
+ "dev": true,
+ "dependencies": {
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/globals": {
+ "version": "11.12.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
+ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/has": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+ "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+ "dev": true,
+ "dependencies": {
+ "function-bind": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4.0"
+ }
+ },
+ "node_modules/has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/has-property-descriptors": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz",
+ "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==",
+ "dev": true,
+ "dependencies": {
+ "get-intrinsic": "^1.1.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-symbols": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
+ "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+ "dev": true
+ },
+ "node_modules/jsesc": {
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
+ "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
+ "dev": true,
+ "bin": {
+ "jsesc": "bin/jsesc"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/json5": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+ "dev": true,
+ "bin": {
+ "json5": "lib/cli.js"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ },
+ "node_modules/node-releases": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.5.tgz",
+ "integrity": "sha512-U9h1NLROZTq9uE1SNffn6WuPDg8icmi3ns4rEl/oTfIle4iLjTliCzgTsbaIFMq/Xn078/lfY/BL0GWZ+psK4Q==",
+ "dev": true
+ },
+ "node_modules/object-keys": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
+ "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/object.assign": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz",
+ "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.0",
+ "define-properties": "^1.1.3",
+ "has-symbols": "^1.0.1",
+ "object-keys": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/picocolors": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
+ "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
+ "dev": true
+ },
+ "node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "dev": true
+ },
+ "node_modules/semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/to-fast-properties": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
+ "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ }
+ },
+ "dependencies": {
+ "@ampproject/remapping": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz",
+ "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==",
+ "dev": true,
+ "requires": {
+ "@jridgewell/gen-mapping": "^0.1.0",
+ "@jridgewell/trace-mapping": "^0.3.9"
+ }
+ },
+ "@babel/code-frame": {
+ "version": "7.22.13",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz",
+ "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==",
+ "dev": true,
+ "requires": {
+ "@babel/highlight": "^7.22.13",
+ "chalk": "^2.4.2"
+ }
+ },
+ "@babel/compat-data": {
+ "version": "7.17.10",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.17.10.tgz",
+ "integrity": "sha512-GZt/TCsG70Ms19gfZO1tM4CVnXsPgEPBCpJu+Qz3L0LUDsY5nZqFZglIoPC1kIYOtNBZlrnFT+klg12vFGZXrw==",
+ "dev": true
+ },
+ "@babel/core": {
+ "version": "7.18.2",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.18.2.tgz",
+ "integrity": "sha512-A8pri1YJiC5UnkdrWcmfZTJTV85b4UXTAfImGmCfYmax4TR9Cw8sDS0MOk++Gp2mE/BefVJ5nwy5yzqNJbP/DQ==",
+ "dev": true,
+ "requires": {
+ "@ampproject/remapping": "^2.1.0",
+ "@babel/code-frame": "^7.16.7",
+ "@babel/generator": "^7.18.2",
+ "@babel/helper-compilation-targets": "^7.18.2",
+ "@babel/helper-module-transforms": "^7.18.0",
+ "@babel/helpers": "^7.18.2",
+ "@babel/parser": "^7.18.0",
+ "@babel/template": "^7.16.7",
+ "@babel/traverse": "^7.18.2",
+ "@babel/types": "^7.18.2",
+ "convert-source-map": "^1.7.0",
+ "debug": "^4.1.0",
+ "gensync": "^1.0.0-beta.2",
+ "json5": "^2.2.1",
+ "semver": "^6.3.0"
+ }
+ },
+ "@babel/generator": {
+ "version": "7.23.0",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz",
+ "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.23.0",
+ "@jridgewell/gen-mapping": "^0.3.2",
+ "@jridgewell/trace-mapping": "^0.3.17",
+ "jsesc": "^2.5.1"
+ },
+ "dependencies": {
+ "@jridgewell/gen-mapping": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
+ "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==",
+ "dev": true,
+ "requires": {
+ "@jridgewell/set-array": "^1.0.1",
+ "@jridgewell/sourcemap-codec": "^1.4.10",
+ "@jridgewell/trace-mapping": "^0.3.9"
+ }
+ }
+ }
+ },
+ "@babel/helper-compilation-targets": {
+ "version": "7.18.2",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.18.2.tgz",
+ "integrity": "sha512-s1jnPotJS9uQnzFtiZVBUxe67CuBa679oWFHpxYYnTpRL/1ffhyX44R9uYiXoa/pLXcY9H2moJta0iaanlk/rQ==",
+ "dev": true,
+ "requires": {
+ "@babel/compat-data": "^7.17.10",
+ "@babel/helper-validator-option": "^7.16.7",
+ "browserslist": "^4.20.2",
+ "semver": "^6.3.0"
+ }
+ },
+ "@babel/helper-environment-visitor": {
+ "version": "7.22.20",
+ "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz",
+ "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==",
+ "dev": true
+ },
+ "@babel/helper-function-name": {
+ "version": "7.23.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz",
+ "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==",
+ "dev": true,
+ "requires": {
+ "@babel/template": "^7.22.15",
+ "@babel/types": "^7.23.0"
+ }
+ },
+ "@babel/helper-hoist-variables": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz",
+ "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.22.5"
+ }
+ },
+ "@babel/helper-module-imports": {
+ "version": "7.16.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz",
+ "integrity": "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.16.7"
+ }
+ },
+ "@babel/helper-module-transforms": {
+ "version": "7.18.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.18.0.tgz",
+ "integrity": "sha512-kclUYSUBIjlvnzN2++K9f2qzYKFgjmnmjwL4zlmU5f8ZtzgWe8s0rUPSTGy2HmK4P8T52MQsS+HTQAgZd3dMEA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-environment-visitor": "^7.16.7",
+ "@babel/helper-module-imports": "^7.16.7",
+ "@babel/helper-simple-access": "^7.17.7",
+ "@babel/helper-split-export-declaration": "^7.16.7",
+ "@babel/helper-validator-identifier": "^7.16.7",
+ "@babel/template": "^7.16.7",
+ "@babel/traverse": "^7.18.0",
+ "@babel/types": "^7.18.0"
+ }
+ },
+ "@babel/helper-plugin-utils": {
+ "version": "7.17.12",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.17.12.tgz",
+ "integrity": "sha512-JDkf04mqtN3y4iAbO1hv9U2ARpPyPL1zqyWs/2WG1pgSq9llHFjStX5jdxb84himgJm+8Ng+x0oiWF/nw/XQKA==",
+ "dev": true
+ },
+ "@babel/helper-simple-access": {
+ "version": "7.18.2",
+ "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.18.2.tgz",
+ "integrity": "sha512-7LIrjYzndorDY88MycupkpQLKS1AFfsVRm2k/9PtKScSy5tZq0McZTj+DiMRynboZfIqOKvo03pmhTaUgiD6fQ==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.18.2"
+ }
+ },
+ "@babel/helper-split-export-declaration": {
+ "version": "7.22.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz",
+ "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.22.5"
+ }
+ },
+ "@babel/helper-string-parser": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz",
+ "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==",
+ "dev": true
+ },
+ "@babel/helper-validator-identifier": {
+ "version": "7.22.20",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
+ "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==",
+ "dev": true
+ },
+ "@babel/helper-validator-option": {
+ "version": "7.16.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz",
+ "integrity": "sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==",
+ "dev": true
+ },
+ "@babel/helpers": {
+ "version": "7.18.2",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.18.2.tgz",
+ "integrity": "sha512-j+d+u5xT5utcQSzrh9p+PaJX94h++KN+ng9b9WEJq7pkUPAd61FGqhjuUEdfknb3E/uDBb7ruwEeKkIxNJPIrg==",
+ "dev": true,
+ "requires": {
+ "@babel/template": "^7.16.7",
+ "@babel/traverse": "^7.18.2",
+ "@babel/types": "^7.18.2"
+ }
+ },
+ "@babel/highlight": {
+ "version": "7.22.20",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz",
+ "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-validator-identifier": "^7.22.20",
+ "chalk": "^2.4.2",
+ "js-tokens": "^4.0.0"
+ }
+ },
+ "@babel/parser": {
+ "version": "7.23.0",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz",
+ "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==",
+ "dev": true
+ },
+ "@babel/plugin-transform-modules-commonjs": {
+ "version": "7.18.2",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.18.2.tgz",
+ "integrity": "sha512-f5A865gFPAJAEE0K7F/+nm5CmAE3y8AWlMBG9unu5j9+tk50UQVK0QS8RNxSp7MJf0wh97uYyLWt3Zvu71zyOQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-module-transforms": "^7.18.0",
+ "@babel/helper-plugin-utils": "^7.17.12",
+ "@babel/helper-simple-access": "^7.18.2",
+ "babel-plugin-dynamic-import-node": "^2.3.3"
+ }
+ },
+ "@babel/template": {
+ "version": "7.22.15",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz",
+ "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.22.13",
+ "@babel/parser": "^7.22.15",
+ "@babel/types": "^7.22.15"
+ }
+ },
+ "@babel/traverse": {
+ "version": "7.23.2",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz",
+ "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.22.13",
+ "@babel/generator": "^7.23.0",
+ "@babel/helper-environment-visitor": "^7.22.20",
+ "@babel/helper-function-name": "^7.23.0",
+ "@babel/helper-hoist-variables": "^7.22.5",
+ "@babel/helper-split-export-declaration": "^7.22.6",
+ "@babel/parser": "^7.23.0",
+ "@babel/types": "^7.23.0",
+ "debug": "^4.1.0",
+ "globals": "^11.1.0"
+ }
+ },
+ "@babel/types": {
+ "version": "7.23.0",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz",
+ "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-string-parser": "^7.22.5",
+ "@babel/helper-validator-identifier": "^7.22.20",
+ "to-fast-properties": "^2.0.0"
+ }
+ },
+ "@jridgewell/gen-mapping": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz",
+ "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==",
+ "dev": true,
+ "requires": {
+ "@jridgewell/set-array": "^1.0.0",
+ "@jridgewell/sourcemap-codec": "^1.4.10"
+ }
+ },
+ "@jridgewell/resolve-uri": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz",
+ "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==",
+ "dev": true
+ },
+ "@jridgewell/set-array": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.1.tgz",
+ "integrity": "sha512-Ct5MqZkLGEXTVmQYbGtx9SVqD2fqwvdubdps5D3djjAkgkKwT918VNOz65pEHFaYTeWcukmJmH5SwsA9Tn2ObQ==",
+ "dev": true
+ },
+ "@jridgewell/sourcemap-codec": {
+ "version": "1.4.15",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
+ "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
+ "dev": true
+ },
+ "@jridgewell/trace-mapping": {
+ "version": "0.3.19",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz",
+ "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==",
+ "dev": true,
+ "requires": {
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
+ }
+ },
+ "ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "babel-plugin-dynamic-import-node": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz",
+ "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==",
+ "dev": true,
+ "requires": {
+ "object.assign": "^4.1.0"
+ }
+ },
+ "browserslist": {
+ "version": "4.20.3",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.3.tgz",
+ "integrity": "sha512-NBhymBQl1zM0Y5dQT/O+xiLP9/rzOIQdKM/eMJBAq7yBgaB6krIYLGejrwVYnSHZdqjscB1SPuAjHwxjvN6Wdg==",
+ "dev": true,
+ "requires": {
+ "caniuse-lite": "^1.0.30001332",
+ "electron-to-chromium": "^1.4.118",
+ "escalade": "^3.1.1",
+ "node-releases": "^2.0.3",
+ "picocolors": "^1.0.0"
+ }
+ },
+ "call-bind": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
+ "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+ "dev": true,
+ "requires": {
+ "function-bind": "^1.1.1",
+ "get-intrinsic": "^1.0.2"
+ }
+ },
+ "caniuse-lite": {
+ "version": "1.0.30001344",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001344.tgz",
+ "integrity": "sha512-0ZFjnlCaXNOAYcV7i+TtdKBp0L/3XEU2MF/x6Du1lrh+SRX4IfzIVL4HNJg5pB2PmFb8rszIGyOvsZnqqRoc2g==",
+ "dev": true
+ },
+ "chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ }
+ },
+ "color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dev": true,
+ "requires": {
+ "color-name": "1.1.3"
+ }
+ },
+ "color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
+ "dev": true
+ },
+ "convert-source-map": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz",
+ "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.1"
+ }
+ },
+ "debug": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+ "dev": true,
+ "requires": {
+ "ms": "2.1.2"
+ }
+ },
+ "define-properties": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz",
+ "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==",
+ "dev": true,
+ "requires": {
+ "has-property-descriptors": "^1.0.0",
+ "object-keys": "^1.1.1"
+ }
+ },
+ "electron-to-chromium": {
+ "version": "1.4.141",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.141.tgz",
+ "integrity": "sha512-mfBcbqc0qc6RlxrsIgLG2wCqkiPAjEezHxGTu7p3dHHFOurH4EjS9rFZndX5axC8264rI1Pcbw8uQP39oZckeA==",
+ "dev": true
+ },
+ "escalade": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
+ "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
+ "dev": true
+ },
+ "escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+ "dev": true
+ },
+ "esm2umd": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/esm2umd/-/esm2umd-0.1.2.tgz",
+ "integrity": "sha512-SoCump2d/jzZJ9/0ZY/2AVOWJbyd5bGOMlRSSNqChPvQrwa9Rqzo9wPP+kT77Gys03Sb+rIgseAReVvIrqvglA==",
+ "dev": true,
+ "requires": {
+ "@babel/core": "^7",
+ "@babel/plugin-transform-modules-commonjs": "^7"
+ }
+ },
+ "function-bind": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
+ "dev": true
+ },
+ "gensync": {
+ "version": "1.0.0-beta.2",
+ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
+ "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
+ "dev": true
+ },
+ "get-intrinsic": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz",
+ "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==",
+ "dev": true,
+ "requires": {
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.1"
+ }
+ },
+ "globals": {
+ "version": "11.12.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
+ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
+ "dev": true
+ },
+ "has": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+ "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+ "dev": true,
+ "requires": {
+ "function-bind": "^1.1.1"
+ }
+ },
+ "has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+ "dev": true
+ },
+ "has-property-descriptors": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz",
+ "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==",
+ "dev": true,
+ "requires": {
+ "get-intrinsic": "^1.1.1"
+ }
+ },
+ "has-symbols": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
+ "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
+ "dev": true
+ },
+ "js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+ "dev": true
+ },
+ "jsesc": {
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
+ "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
+ "dev": true
+ },
+ "json5": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+ "dev": true
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ },
+ "node-releases": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.5.tgz",
+ "integrity": "sha512-U9h1NLROZTq9uE1SNffn6WuPDg8icmi3ns4rEl/oTfIle4iLjTliCzgTsbaIFMq/Xn078/lfY/BL0GWZ+psK4Q==",
+ "dev": true
+ },
+ "object-keys": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
+ "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
+ "dev": true
+ },
+ "object.assign": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz",
+ "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.0",
+ "define-properties": "^1.1.3",
+ "has-symbols": "^1.0.1",
+ "object-keys": "^1.1.1"
+ }
+ },
+ "picocolors": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
+ "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
+ "dev": true
+ },
+ "safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "dev": true
+ },
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ },
+ "to-fast-properties": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
+ "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=",
+ "dev": true
+ }
+ }
+}
diff --git a/lib/loader/package.json b/lib/loader/package.json
index a75d8053f9..c62c4dc63d 100644
--- a/lib/loader/package.json
+++ b/lib/loader/package.json
@@ -11,6 +11,9 @@
],
"version": "0.0.0",
"author": "Daniel Wirtz ",
+ "contributors": [
+ "MaxGraey "
+ ],
"license": "Apache-2.0",
"homepage": "https://assemblyscript.org",
"repository": {
@@ -22,7 +25,7 @@
"url": "https://github.com/AssemblyScript/assemblyscript/issues"
},
"type": "module",
- "main": "index.js",
+ "main": "./umd/index.js",
"types": "index.d.ts",
"exports": {
"import": "./index.js",
@@ -30,8 +33,8 @@
},
"scripts": {
"asbuild": "npm run asbuild:default && npm run asbuild:legacy",
- "asbuild:default": "node ../../bin/asc tests/assembly/index.ts --binaryFile tests/build/default.wasm --exportRuntime",
- "asbuild:legacy": "node ../../bin/asc tests/assembly/index.ts --disable mutable-globals --binaryFile tests/build/legacy.wasm --exportRuntime",
+ "asbuild:default": "node ../../bin/asc tests/assembly/index.ts --outFile tests/build/default.wasm --exportRuntime --exportTable",
+ "asbuild:legacy": "node ../../bin/asc tests/assembly/index.ts --disable mutable-globals --outFile tests/build/legacy.wasm --exportRuntime --exportTable",
"build": "npx esm2umd loader index.js > umd/index.js",
"test": "node tests && node tests/umd"
},
@@ -43,5 +46,8 @@
"umd/index.js",
"umd/package.json",
"README.md"
- ]
-}
\ No newline at end of file
+ ],
+ "devDependencies": {
+ "esm2umd": "^0.1.2"
+ }
+}
diff --git a/lib/loader/tests/assembly/index.ts b/lib/loader/tests/assembly/index.ts
index af9801e6af..f1cd80592a 100644
--- a/lib/loader/tests/assembly/index.ts
+++ b/lib/loader/tests/assembly/index.ts
@@ -40,13 +40,13 @@ export class Car {
}
export function sum(arr: Int32Array): i32 {
- var v = 0;
+ let v = 0;
for (let i = 0, k = arr.length; i < k; ++i) v += arr[i];
return v;
}
export function sumStatic(arr: StaticArray): i32 {
- var v = 0;
+ let v = 0;
for (let i = 0, k = arr.length; i < k; ++i) v += arr[i];
return v;
}
@@ -69,6 +69,10 @@ export function dotrace(num: f64): void {
trace("The answer is", 1, num);
}
+export function getVaraddFunc(): (a: i32, b: i32) => i32 {
+ return varadd;
+}
+
export const UINT8ARRAY_ID = idof();
export const INT16ARRAY_ID = idof();
export const UINT16ARRAY_ID = idof();
diff --git a/lib/loader/tests/build/default.wasm b/lib/loader/tests/build/default.wasm
index c95f6e5a05..b9188bb52e 100644
Binary files a/lib/loader/tests/build/default.wasm and b/lib/loader/tests/build/default.wasm differ
diff --git a/lib/loader/tests/build/legacy.wasm b/lib/loader/tests/build/legacy.wasm
index c95f6e5a05..b9188bb52e 100644
Binary files a/lib/loader/tests/build/legacy.wasm and b/lib/loader/tests/build/legacy.wasm differ
diff --git a/lib/loader/tests/index.html b/lib/loader/tests/index.html
index 68a98e4c22..7f716575ce 100644
--- a/lib/loader/tests/index.html
+++ b/lib/loader/tests/index.html
@@ -5,39 +5,39 @@
if (!c) throw Error("assertion failed");
}
(async () => {
- var module;
+ let module;
- module = await exports.instantiate(fetch("./build/untouched.wasm"));
+ module = await exports.instantiate(fetch("./build/debug.wasm"));
assert(module.memory);
- module = await exports.instantiate(await fetch("./build/untouched.wasm"));
+ module = await exports.instantiate(await fetch("./build/debug.wasm"));
assert(module.memory);
- module = await exports.instantiate((await fetch("./build/untouched.wasm")).arrayBuffer());
+ module = await exports.instantiate((await fetch("./build/debug.wasm")).arrayBuffer());
assert(module.memory);
- module = await exports.instantiate(await (await fetch("./build/untouched.wasm")).arrayBuffer());
+ module = await exports.instantiate(await (await fetch("./build/debug.wasm")).arrayBuffer());
assert(module.memory);
- module = await exports.instantiateStreaming(fetch("./build/untouched.wasm"));
+ module = await exports.instantiateStreaming(fetch("./build/debug.wasm"));
assert(module.memory);
- module = await exports.instantiateStreaming(await fetch("./build/untouched.wasm"));
+ module = await exports.instantiateStreaming(await fetch("./build/debug.wasm"));
assert(module.memory);
- var instantiateStreaming = WebAssembly.instantiateStreaming;
+ let instantiateStreaming = WebAssembly.instantiateStreaming;
delete WebAssembly.instantiateStreaming;
- module = await exports.instantiate(fetch("./build/untouched.wasm"));
+ module = await exports.instantiate(fetch("./build/debug.wasm"));
assert(module.memory);
- module = await exports.instantiate(await fetch("./build/untouched.wasm"));
+ module = await exports.instantiate(await fetch("./build/debug.wasm"));
assert(module.memory);
- module = await exports.instantiateStreaming(fetch("./build/untouched.wasm"));
+ module = await exports.instantiateStreaming(fetch("./build/debug.wasm"));
assert(module.memory);
- module = await exports.instantiateStreaming(await fetch("./build/untouched.wasm"));
+ module = await exports.instantiateStreaming(await fetch("./build/debug.wasm"));
assert(module.memory);
WebAssembly.instantiateStreaming = instantiateStreaming;
diff --git a/lib/loader/tests/index.js b/lib/loader/tests/index.js
index aac09f91ae..48d008b0da 100644
--- a/lib/loader/tests/index.js
+++ b/lib/loader/tests/index.js
@@ -14,16 +14,25 @@ test("legacy.wasm");
testInstantiate("default.wasm");
testInstantiate("legacy.wasm");
+async function wrapToResponse(source) {
+ return new Response(await source, {
+ status: 200,
+ headers: new Headers([["Content-Type", "application/wasm"]])
+ });
+}
+
function test(file) {
- var buffer = fs.readFileSync(__dirname + "/build/" + file);
- var result = loader.instantiateSync(buffer, {});
+ let buffer = fs.readFileSync(__dirname + "/build/" + file);
+ let result = loader.instantiateSync(buffer, {});
const exports = result.exports;
console.log(inspect(exports, true, 100, true));
// should export memory
assert(exports.memory instanceof WebAssembly.Memory);
- assert(typeof exports.memory.compare === "function");
+
+ // NOTE: Namespace exports have been removed in 0.20
+ // assert(typeof exports.memory.compare === "function");
// should be able to get an exported string
assert.strictEqual(exports.__getString(exports.COLOR), "red");
@@ -36,6 +45,15 @@ function test(file) {
assert.strictEqual(exports.strlen(ref), str.length);
}
+ // should be able to allocate and work with a new small ArrayBuffer
+ {
+ let input = new Uint8Array([1, 2, 3, 4]);
+ let bufPtr = exports.__newArrayBuffer(input.buffer);
+ let output = new Uint8Array(exports.__getArrayBuffer(bufPtr));
+
+ assert.deepStrictEqual(output, input);
+ }
+
// should be able to allocate and work with a new big string
{
let str = `
@@ -50,11 +68,26 @@ function test(file) {
assert.strictEqual(exports.strlen(ref), str.length);
}
+ // should be able to allocate and work with a string containing an isolated high surrogate
+ {
+ let str = "𝄞".substring(0, 1);
+ let ref = exports.__newString(str);
+ assert.strictEqual(exports.__getString(ref), str);
+ assert.strictEqual(exports.strlen(ref), str.length);
+ }
+
+ // should be able to allocate and work with a string containing an isolated low surrogate
+ {
+ let str = "𝄞".substring(1);
+ let ref = exports.__newString(str);
+ assert.strictEqual(exports.__getString(ref), str);
+ assert.strictEqual(exports.strlen(ref), str.length);
+ }
+
// should be able to allocate a typed array
{
let arr = [1, 2, 3, 4, 5, 0x80000000 | 0];
let ref = exports.__newArray(exports.INT32ARRAY_ID, arr);
- assert(exports.__instanceof(ref, exports.INT32ARRAY_ID));
// should be able to get the values of an array
assert.deepStrictEqual(exports.__getArray(ref), arr);
@@ -70,7 +103,6 @@ function test(file) {
{
let arr = [1, 2, 3, 4, 5, 0x80000000 | 0];
let ref = exports.__newArray(exports.STATICARRAYI32_ID, arr);
- assert(exports.__instanceof(ref, exports.STATICARRAYI32_ID));
// should be able to get the values of an array
assert.deepStrictEqual(exports.__getArray(ref), arr);
@@ -86,17 +118,14 @@ function test(file) {
{
let arrU8Arr = new Uint8Array([0, 1, 2]);
let refU8Arr = module.__newUint8Array(arrU8Arr);
- assert(module.__instanceof(refU8Arr, module.UINT8ARRAY_ID));
assert.deepStrictEqual(module.__getUint8Array(refU8Arr), arrU8Arr);
let arrU16Arr = new Uint16Array([0, 0x7FFF, 0xFFFF]);
let refU16Arr = module.__newUint16Array(arrU16Arr);
- assert(module.__instanceof(refU16Arr, module.UINT16ARRAY_ID));
assert.deepStrictEqual(module.__getUint16Array(refU16Arr), arrU16Arr);
let arrI16Arr = new Int16Array([0, -1, -2]);
let refI16Arr = module.__newInt16Array(arrI16Arr);
- assert(module.__instanceof(refI16Arr, module.INT16ARRAY_ID));
assert.deepStrictEqual(module.__getInt16Array(refI16Arr), arrI16Arr);
}
*/
@@ -106,7 +135,6 @@ function test(file) {
let values = [0, 255, 127];
let arr = new Uint8Array(values);
let ref = exports.__newArray(exports.UINT8ARRAY_ID, arr);
- assert(exports.__instanceof(ref, exports.UINT8ARRAY_ID));
assert.deepStrictEqual(exports.__getUint8Array(ref), arr);
assert.deepStrictEqual(exports.__getUint8ArrayView(ref), arr);
assert.deepStrictEqual(exports.__getArray(ref), values);
@@ -116,7 +144,6 @@ function test(file) {
{
let arr = [0, 255, 127];
let ref = exports.__newArray(exports.STATICARRAYU8_ID, arr);
- assert(exports.__instanceof(ref, exports.STATICARRAYU8_ID));
assert.deepStrictEqual(exports.__getArray(ref), arr);
}
@@ -125,7 +152,6 @@ function test(file) {
let values = [0, 0xFFFF, -0x00FF];
let arr = new Int16Array(values);
let ref = exports.__newArray(exports.INT16ARRAY_ID, arr);
- assert(exports.__instanceof(ref, exports.INT16ARRAY_ID));
assert.deepStrictEqual(exports.__getInt16Array(ref), arr);
assert.deepStrictEqual(exports.__getInt16ArrayView(ref), arr);
assert.deepStrictEqual(exports.__getArray(ref), [0, -1, -255]);
@@ -135,7 +161,6 @@ function test(file) {
{
let arr = [0, 0xFFFF, -0x00FF];
let ref = exports.__newArray(exports.STATICARRAYI16_ID, arr);
- assert(exports.__instanceof(ref, exports.STATICARRAYI16_ID));
assert.deepStrictEqual(exports.__getArray(ref), [0, -1, -255]);
}
@@ -144,7 +169,6 @@ function test(file) {
let values = [1, -1 >>> 0, 0x80000000];
let arr = new Uint32Array(values);
let ref = exports.__newArray(exports.UINT32ARRAY_ID, arr);
- assert(exports.__instanceof(ref, exports.UINT32ARRAY_ID));
assert.deepStrictEqual(exports.__getUint32Array(ref), arr);
assert.deepStrictEqual(exports.__getUint32ArrayView(ref), arr);
assert.deepStrictEqual(exports.__getArray(ref), values);
@@ -154,7 +178,6 @@ function test(file) {
{
let arr = [1, -1 >>> 0, 0x80000000];
let ref = exports.__newArray(exports.STATICARRAYU32_ID, arr);
- assert(exports.__instanceof(ref, exports.STATICARRAYU32_ID));
assert.deepStrictEqual(exports.__getArray(ref), arr);
}
@@ -163,7 +186,6 @@ function test(file) {
let values = [0.0, 1.5, 2.5];
let arr = new Float32Array(values);
let ref = exports.__newArray(exports.FLOAT32ARRAY_ID, arr);
- assert(exports.__instanceof(ref, exports.FLOAT32ARRAY_ID));
assert.deepStrictEqual(exports.__getFloat32Array(ref), arr);
assert.deepStrictEqual(exports.__getFloat32ArrayView(ref), arr);
assert.deepStrictEqual(exports.__getArray(ref), values);
@@ -173,15 +195,25 @@ function test(file) {
{
let arr = [0.0, 1.5, 2.5];
let ref = exports.__newArray(exports.STATICARRAYF32_ID, arr);
- assert(exports.__instanceof(ref, exports.STATICARRAYF32_ID));
assert.deepStrictEqual(exports.__getArray(ref), arr);
}
+ // should be able to create empty arrays
+ {
+ let ref = exports.__newArray(exports.ARRAYI32_ID);
+ assert.deepStrictEqual(exports.__getArray(ref), []);
+ }
+
+ // should be able to create arrays with capacity
+ {
+ let ref = exports.__newArray(exports.ARRAYI32_ID, 32);
+ assert.strictEqual(exports.__getArray(ref).length, 32);
+ }
+
// should be able to work with normal arrays
{
let arr = [1, 2, 3, 4, 5];
let ref = exports.__newArray(exports.ARRAYI32_ID, arr);
- assert(exports.__instanceof(ref, exports.ARRAYI32_ID));
exports.changeLength(ref, 3);
assert.deepStrictEqual(exports.__getArray(ref), [1, 2, 3]);
}
@@ -203,7 +235,7 @@ function test(file) {
// TBD: table is no more exported by default to allow more optimizations
// should be able to get a function from the table and just call it with variable arguments
- // var fn = module.getFunction(module.varadd_ref);
+ // let fn = module.getFunction(module.varadd_ref);
// assert.strictEqual(fn(), 3);
// assert.strictEqual(fn(2, 3), 5);
// assert.strictEqual(fn(2), 4);
@@ -212,15 +244,26 @@ function test(file) {
// ref = module.newFunction(module.varadd);
// assert.strictEqual(module.calladd(ref, 2, 3), 5);
+ // NOTE: Class exports have been removed in 0.20
// should be able to use a class
- var car = new exports.Car(5);
- assert.strictEqual(car.numDoors, 5);
- assert.strictEqual(car.isDoorsOpen, 0);
- car.openDoors();
- assert.strictEqual(car.isDoorsOpen, 1);
- car.closeDoors();
- assert.strictEqual(car.isDoorsOpen, 0);
- assert(typeof +car === "number"); // uses Car.prototype.valueOf to obtain `thisPtr`
+ // let car = new exports.Car(5);
+ // assert.strictEqual(car.numDoors, 5);
+ // assert.strictEqual(car.isDoorsOpen, 0);
+ // car.openDoors();
+ // assert.strictEqual(car.isDoorsOpen, 1);
+ // car.closeDoors();
+ // assert.strictEqual(car.isDoorsOpen, 0);
+ // assert(typeof +car === "number"); // uses Car.prototype.valueOf to obtain `thisPtr`
+
+ // should be able to return a function
+ {
+ const addFunc = exports.__getFunction(exports.getVaraddFunc());
+ assert(typeof addFunc === "function");
+ assert.strictEqual(addFunc(1, 2), 3);
+
+ const invalidFunc = exports.__getFunction(0);
+ assert(invalidFunc == null);
+ }
// should be able to use trace
exports.dotrace(42);
@@ -252,7 +295,10 @@ function test(file) {
function testInstantiate(file) {
// should be able to instantiate from a buffer
(async () => {
- const { exports, instance, module } = await loader.instantiate(fs.readFileSync(__dirname + "/build/" + file), {});
+ const { exports, instance, module } = await loader.instantiate(
+ fs.readFileSync(__dirname + "/build/" + file),
+ {}
+ );
assert(exports.memory);
assert(instance && instance instanceof WebAssembly.Instance);
assert(module && module instanceof WebAssembly.Module);
@@ -260,8 +306,10 @@ function testInstantiate(file) {
// should be able to instantiate from a wasm module
(async () => {
- const wasmModule = new WebAssembly.Module(fs.readFileSync(__dirname + "/build/" + file));
- const { exports, instance, module } = await loader.instantiate(wasmModule, {});
+ const { exports, instance, module } = await loader.instantiate(
+ new WebAssembly.Module(fs.readFileSync(__dirname + "/build/" + file)),
+ {}
+ );
assert(exports.memory);
assert(instance && instance instanceof WebAssembly.Instance);
assert(module && module instanceof WebAssembly.Module);
@@ -269,7 +317,10 @@ function testInstantiate(file) {
// should be able to instantiate from a promise yielding a buffer
(async () => {
- const { exports, instance, module } = await loader.instantiate(fs.promises.readFile(__dirname + "/build/" + file), {});
+ const { exports, instance, module } = await loader.instantiate(
+ fs.promises.readFile(__dirname + "/build/" + file),
+ {}
+ );
assert(exports.memory);
assert(instance && instance instanceof WebAssembly.Instance);
assert(module && module instanceof WebAssembly.Module);
@@ -277,7 +328,10 @@ function testInstantiate(file) {
// should be able to mimic instantiateStreaming under node (for now)
(async () => {
- const { exports, instance, module } = await loader.instantiateStreaming(fs.promises.readFile(__dirname + "/build/" + file), {});
+ const { exports, instance, module } = await loader.instantiateStreaming(
+ wrapToResponse(fs.promises.readFile(__dirname + "/build/" + file)),
+ {}
+ );
assert(exports.memory);
assert(instance && instance instanceof WebAssembly.Instance);
assert(module && module instanceof WebAssembly.Module);
diff --git a/lib/loader/umd/index.js b/lib/loader/umd/index.js
index a86ddb9e56..3625fc2cc7 100644
--- a/lib/loader/umd/index.js
+++ b/lib/loader/umd/index.js
@@ -13,10 +13,10 @@ var loader = (function(exports) {
// Runtime header offsets
const ID_OFFSET = -8;
const SIZE_OFFSET = -4; // Runtime ids
+ // const OBJECT_ID = 0;
- const ARRAYBUFFER_ID = 0;
- const STRING_ID = 1; // const ARRAYBUFFERVIEW_ID = 2;
- // Runtime type information
+ const ARRAYBUFFER_ID = 1;
+ const STRING_ID = 2; // Runtime type information
const ARRAYBUFFERVIEW = 1 << 0;
const ARRAY = 1 << 1;
@@ -38,25 +38,52 @@ var loader = (function(exports) {
const ARRAYBUFFERVIEW_BUFFER_OFFSET = 0;
const ARRAYBUFFERVIEW_DATASTART_OFFSET = 4;
- const ARRAYBUFFERVIEW_DATALENGTH_OFFSET = 8;
+ const ARRAYBUFFERVIEW_BYTELENGTH_OFFSET = 8;
const ARRAYBUFFERVIEW_SIZE = 12;
const ARRAY_LENGTH_OFFSET = 12;
const ARRAY_SIZE = 16;
+ const E_NO_EXPORT_TABLE = "Operation requires compiling with --exportTable";
+ const E_NO_EXPORT_RUNTIME = "Operation requires compiling with --exportRuntime";
+
+ const F_NO_EXPORT_RUNTIME = () => {
+ throw Error(E_NO_EXPORT_RUNTIME);
+ };
+
const BIGINT = typeof BigUint64Array !== "undefined";
const THIS = Symbol();
- const STRING_DECODE_THRESHOLD = 32;
- const decoder = new TextDecoder("utf-16le");
- /** Gets a string from an U32 and an U16 view on a memory. */
+ const STRING_SMALLSIZE = 192; // break-even point in V8
+
+ const STRING_CHUNKSIZE = 1024; // mitigate stack overflow
+
+ const utf16 = new TextDecoder("utf-16le", {
+ fatal: true
+ }); // != wtf16
+
+ /** polyfill for Object.hasOwn */
+
+ Object.hasOwn = Object.hasOwn || function (obj, prop) {
+ return Object.prototype.hasOwnProperty.call(obj, prop);
+ };
+ /** Gets a string from memory. */
+
function getStringImpl(buffer, ptr) {
- const len = new Uint32Array(buffer)[ptr + SIZE_OFFSET >>> 2] >>> 1;
- const arr = new Uint16Array(buffer, ptr, len);
+ let len = new Uint32Array(buffer)[ptr + SIZE_OFFSET >>> 2] >>> 1;
+ const wtf16 = new Uint16Array(buffer, ptr, len);
+ if (len <= STRING_SMALLSIZE) return String.fromCharCode(...wtf16);
+
+ try {
+ return utf16.decode(wtf16);
+ } catch {
+ let str = "",
+ off = 0;
+
+ while (len - off > STRING_CHUNKSIZE) {
+ str += String.fromCharCode(...wtf16.subarray(off, off += STRING_CHUNKSIZE));
+ }
- if (len <= STRING_DECODE_THRESHOLD) {
- return String.fromCharCode.apply(String, arr);
+ return str + String.fromCharCode(...wtf16.subarray(off));
}
-
- return decoder.decode(arr);
}
/** Prepares the base module prior to instantiation. */
@@ -88,12 +115,6 @@ var loader = (function(exports) {
imports.Date = imports.Date || Date;
return extendedExports;
}
-
- const E_NOEXPORTRUNTIME = "Operation requires compiling with --exportRuntime";
-
- const F_NOEXPORTRUNTIME = function () {
- throw Error(E_NOEXPORTRUNTIME);
- };
/** Prepares the final module once instantiation is complete. */
@@ -102,46 +123,35 @@ var loader = (function(exports) {
const memory = exports.memory;
const table = exports.table;
- const __new = exports.__new || F_NOEXPORTRUNTIME;
-
- const __pin = exports.__pin || F_NOEXPORTRUNTIME;
-
- const __unpin = exports.__unpin || F_NOEXPORTRUNTIME;
+ const __new = exports.__new || F_NO_EXPORT_RUNTIME;
- const __collect = exports.__collect || F_NOEXPORTRUNTIME;
+ const __pin = exports.__pin || F_NO_EXPORT_RUNTIME;
- const __rtti_base = exports.__rtti_base || ~0; // oob if not present
+ const __unpin = exports.__unpin || F_NO_EXPORT_RUNTIME;
+ const __collect = exports.__collect || F_NO_EXPORT_RUNTIME;
+ const __rtti_base = exports.__rtti_base;
+ const getTypeinfoCount = __rtti_base ? arr => arr[__rtti_base >>> 2] : F_NO_EXPORT_RUNTIME;
extendedExports.__new = __new;
extendedExports.__pin = __pin;
extendedExports.__unpin = __unpin;
extendedExports.__collect = __collect;
/** Gets the runtime type info for the given id. */
- function getInfo(id) {
+ function getTypeinfo(id) {
const U32 = new Uint32Array(memory.buffer);
- const count = U32[__rtti_base >>> 2];
- if ((id >>>= 0) >= count) throw Error(`invalid id: ${id}`);
- return U32[(__rtti_base + 4 >>> 2) + id * 2];
+ if ((id >>>= 0) >= getTypeinfoCount(U32)) throw Error(`invalid id: ${id}`);
+ return U32[(__rtti_base + 4 >>> 2) + id];
}
- /** Gets and validate runtime type info for the given id for array like objects */
+ /** Gets and validates runtime type info for the given id for array like objects */
function getArrayInfo(id) {
- const info = getInfo(id);
+ const info = getTypeinfo(id);
if (!(info & (ARRAYBUFFERVIEW | ARRAY | STATICARRAY))) throw Error(`not an array: ${id}, flags=${info}`);
return info;
}
- /** Gets the runtime base id for the given id. */
-
-
- function getBase(id) {
- const U32 = new Uint32Array(memory.buffer);
- const count = U32[__rtti_base >>> 2];
- if ((id >>>= 0) >= count) throw Error(`invalid id: ${id}`);
- return U32[(__rtti_base + 4 >>> 2) + id * 2 + 1];
- }
/** Gets the runtime alignment of a collection's values. */
@@ -164,12 +174,26 @@ var loader = (function(exports) {
const U16 = new Uint16Array(memory.buffer);
- for (var i = 0, p = ptr >>> 1; i < length; ++i) U16[p + i] = str.charCodeAt(i);
+ for (let i = 0, p = ptr >>> 1; i < length; ++i) U16[p + i] = str.charCodeAt(i);
return ptr;
}
extendedExports.__newString = __newString;
+ /** Allocates a new ArrayBuffer in the module's memory and returns its pointer. */
+
+ function __newArrayBuffer(buf) {
+ if (buf == null) return 0;
+ const bufview = new Uint8Array(buf);
+
+ const ptr = __new(bufview.length, ARRAYBUFFER_ID);
+
+ const U8 = new Uint8Array(memory.buffer);
+ U8.set(bufview, ptr);
+ return ptr;
+ }
+
+ extendedExports.__newArrayBuffer = __newArrayBuffer;
/** Reads a string from the module's memory by its pointer. */
function __getString(ptr) {
@@ -215,10 +239,12 @@ var loader = (function(exports) {
/** Allocates a new array in the module's memory and returns its pointer. */
- function __newArray(id, values) {
+ function __newArray(id, valuesOrCapacity = 0) {
+ const input = valuesOrCapacity;
const info = getArrayInfo(id);
const align = getValueAlign(info);
- const length = values.length;
+ const isArrayLike = typeof input !== "number";
+ const length = isArrayLike ? input.length : input;
const buf = __new(length << align, info & STATICARRAY ? id : ARRAYBUFFER_ID);
@@ -236,20 +262,22 @@ var loader = (function(exports) {
const U32 = new Uint32Array(memory.buffer);
U32[arr + ARRAYBUFFERVIEW_BUFFER_OFFSET >>> 2] = buf;
U32[arr + ARRAYBUFFERVIEW_DATASTART_OFFSET >>> 2] = buf;
- U32[arr + ARRAYBUFFERVIEW_DATALENGTH_OFFSET >>> 2] = length << align;
+ U32[arr + ARRAYBUFFERVIEW_BYTELENGTH_OFFSET >>> 2] = length << align;
if (info & ARRAY) U32[arr + ARRAY_LENGTH_OFFSET >>> 2] = length;
result = arr;
}
- const view = getView(align, info & VAL_SIGNED, info & VAL_FLOAT);
+ if (isArrayLike) {
+ const view = getView(align, info & VAL_SIGNED, info & VAL_FLOAT);
+ const start = buf >>> align;
- if (info & VAL_MANAGED) {
- for (let i = 0; i < length; ++i) {
- const value = values[i];
- view[(buf >>> align) + i] = value;
+ if (info & VAL_MANAGED) {
+ for (let i = 0; i < length; ++i) {
+ view[start + i] = input[i];
+ }
+ } else {
+ view.set(input, start);
}
- } else {
- view.set(values, buf >>> align);
}
return result;
@@ -292,6 +320,15 @@ var loader = (function(exports) {
}
extendedExports.__getArrayBuffer = __getArrayBuffer;
+ /** Gets a function from poiner which contain table's index. */
+
+ function __getFunction(ptr) {
+ if (!table) throw Error(E_NO_EXPORT_TABLE);
+ const index = new Uint32Array(memory.buffer)[ptr >>> 2];
+ return table.get(index);
+ }
+
+ extendedExports.__getFunction = __getFunction;
/** Copies a typed array's values from the module's memory. */
function getTypedArray(Type, alignLog2, ptr) {
@@ -303,8 +340,7 @@ var loader = (function(exports) {
function getTypedArrayView(Type, alignLog2, ptr) {
const buffer = memory.buffer;
const U32 = new Uint32Array(buffer);
- const bufPtr = U32[ptr + ARRAYBUFFERVIEW_DATASTART_OFFSET >>> 2];
- return new Type(buffer, bufPtr, U32[bufPtr + SIZE_OFFSET >>> 2] >>> alignLog2);
+ return new Type(buffer, U32[ptr + ARRAYBUFFERVIEW_DATASTART_OFFSET >>> 2], U32[ptr + ARRAYBUFFERVIEW_BYTELENGTH_OFFSET >>> 2] >>> alignLog2);
}
/** Attach a set of get TypedArray and View functions to the exports. */
@@ -322,25 +358,8 @@ var loader = (function(exports) {
[BigUint64Array, BigInt64Array].forEach(ctor => {
attachTypedArrayFunctions(ctor, ctor.name.slice(3), 3);
});
- }
- /** Tests whether an object is an instance of the class represented by the specified base id. */
-
-
- function __instanceof(ptr, baseId) {
- const U32 = new Uint32Array(memory.buffer);
- let id = U32[ptr + ID_OFFSET >>> 2];
+ } // Pull basic exports to extendedExports so code in preInstantiate can use them
- if (id <= U32[__rtti_base >>> 2]) {
- do {
- if (id == baseId) return true;
- id = getBase(id);
- } while (id);
- }
-
- return false;
- }
-
- extendedExports.__instanceof = __instanceof; // Pull basic exports to extendedExports so code in preInstantiate can use them
extendedExports.memory = extendedExports.memory || memory;
extendedExports.table = extendedExports.table || table; // Demangle exports and provide the usual utility on the prototype
@@ -409,15 +428,14 @@ var loader = (function(exports) {
/* nop */
});
- for (let internalName in exports) {
- if (!Object.prototype.hasOwnProperty.call(exports, internalName)) continue;
+ for (let internalName of Object.keys(exports)) {
const elem = exports[internalName];
let parts = internalName.split(".");
let curr = extendedExports;
while (parts.length > 1) {
let part = parts.shift();
- if (!Object.prototype.hasOwnProperty.call(curr, part)) curr[part] = {};
+ if (!Object.hasOwn(curr, part)) curr[part] = {};
curr = curr[part];
}
@@ -457,7 +475,7 @@ var loader = (function(exports) {
curr = curr[className].prototype;
if (/^(get|set):/.test(name)) {
- if (!Object.prototype.hasOwnProperty.call(curr, name = name.substring(4))) {
+ if (!Object.hasOwn(curr, name = name.substring(4))) {
let getter = exports[internalName.replace("set:", "get:")];
let setter = exports[internalName.replace("get:", "set:")];
Object.defineProperty(curr, name, {
@@ -474,7 +492,7 @@ var loader = (function(exports) {
}
} else {
if (name === 'constructor') {
- (curr[name] = (...args) => {
+ (curr[name] = function (...args) {
setArgumentsLength(args.length);
return elem(...args);
}).original = elem;
@@ -489,7 +507,7 @@ var loader = (function(exports) {
}
} else {
if (/^(get|set):/.test(name)) {
- if (!Object.prototype.hasOwnProperty.call(curr, name = name.substring(4))) {
+ if (!Object.hasOwn(curr, name = name.substring(4))) {
Object.defineProperty(curr, name, {
get: exports[internalName.replace("set:", "get:")],
set: exports[internalName.replace("get:", "set:")],
diff --git a/lib/parse/README.md b/lib/parse/README.md
deleted file mode 100644
index 2864308a11..0000000000
--- a/lib/parse/README.md
+++ /dev/null
@@ -1,107 +0,0 @@
-# WebAssembly Parser
-
-A WebAssembly binary parser in WebAssembly. Super small, super fast, with TypeScript support.
-
-API
----
-
-* **parse**(binary: `Uint8Array`, options?: `ParseOptions`): `void`
- Parses the contents of a WebAssembly binary according to the specified options.
-
-* **ParseOptions**
- Options specified to the parser. The `onSection` callback determines the sections being evaluated in detail.
-
- * **onSection**?(id: `SectionId`, payloadOff: `number`, payloadLen: `number`, nameOff: `number`, nameLen: `number`): `boolean`
- Called with each section in the binary. Returning `true` evaluates the section.
-
- * **onType**?(index: `number`, form: `number`): `void`
- Called with each function type if the type section is evaluated.
-
- * **onTypeParam**?(index: `number`, paramIndex: `number`, paramType: `Type`): `void`
- Called with each function parameter if the type section is evaluated.
-
- * **onTypeReturn**?(index: `number`, returnIndex: `number`, returnType: `Type`): `void`
- Called with each function return type if the type section is evaluated.
-
- * **onImport**?(index: `number`, kind: `ExternalKind`, moduleOff: `number`, moduleLen: `number`, fieldOff: `number`, fieldLen: `number`): `void`
- Called with each import if the import section is evaluated.
-
- * **onFunctionImport**?(index: `number`, type: `number`): `void`
- Called with each function import if the import section is evaluated.
-
- * **onTableImport**?(index: `number`, type: `Type`, initial: `number`, maximum: `number`, flags: `number`): `void`
- Called with each table import if the import section is evaluated.
-
- * **onMemoryImport**?(index: `number`, initial: `number`, maximum: `number`, flags: `number`): `void`
- Called with each memory import if the import section is evaluated.
-
- * **onGlobalImport**?(index: `number`, type: `Type`, mutability: `number`): `void`
- Called with each global import if the import section is evaluated.
-
- * **onMemory**?(index: `number`, initial: `number`, maximum: `number`, flags: `number`): `void`
- Called with each memory if the memory section is evaluated.
-
- * **onFunction**?(index: `number`, typeIndex: `number`): `void`
- Called with each function if the function section is evaluated.
-
- * **onGlobal**?(index: `number`, type: `Type`, mutability: `number`): `void`
- Called with each global if the global section is evaluated.
-
- * **onStart**?(index: `number`): `void`
- Called with the start function index if the start section is evaluated.
-
- * **onExport**?(index: `number`, kind: `ExternalKind`, kindIndex: `number`, nameOff: `number`, nameLen: `number`): `void`
- Called with each export if the export section is evaluated.
-
- * **onSourceMappingURL**?(offset: `number`, length: `number`): `void`
- Called with the source map URL if the 'sourceMappingURL' section is evaluated.
-
- * **onModuleName**?(offset: `number`, length: `number`): `void`
- Called with the module name if present and the 'name' section is evaluated.
-
- * **onFunctionName**?(index: `number`, offset: `number`, length: `number`): `void`
- Called with each function name if present and the 'name' section is evaluated.
-
- * **onLocalName**?(funcIndex: `number`, index: `number`, offset: `number`, length: `number`): `void`
- Called with each local name if present and the 'name' section is evaluated.
-
-* **Type**
- A value or element type, depending on context.
-
- | Name | Value
- |---------|-------
- | i32 | 0x7f
- | i64 | 0x7e
- | f32 | 0x7d
- | f64 | 0x7c
- | anyfunc | 0x70
- | func | 0x60
- | none | 0x40
-
-* **SectionId**
- Numerical id of the current section.
-
- | Name | Value
- |----------|-------
- | Custom | 0
- | Type | 1
- | Import | 2
- | Function | 3
- | Table | 4
- | Memory | 5
- | Global | 6
- | Export | 7
- | Start | 8
- | Element | 9
- | Code | 10
- | Data | 11
-
-* **ExternalKind**
- Kind of an export or import.
-
- | Name | Value
- |----------|-------
- | Function | 0
- | Table | 1
- | Memory | 2
- | Global | 3
diff --git a/lib/parse/assembly/index.ts b/lib/parse/assembly/index.ts
deleted file mode 100644
index 3defa2ec19..0000000000
--- a/lib/parse/assembly/index.ts
+++ /dev/null
@@ -1,406 +0,0 @@
-/** A WebAssembly module that parses WebAssembly modules. */
-
-// Common constants shared between AssemblyScript and TypeScript
-import {
- SectionId,
- ExternalKind,
- NameType,
- MAX_PAGES,
- MAX_ELEMS,
- Opcode
-} from "../src/common";
-
-import * as opt from "./options";
-
-/** Current offset in memory. */
-var off: usize = 0;
-
-/** Reads an unsigned integer from memory. */
-function readUint(): u32 {
- var pos = off;
- var val = load(pos);
- off = pos + sizeof();
- return val;
-}
-
-/** Reads an unsigned 64-bit integer from memory. */
-function readUint64(): u64 {
- var pos = off;
- var val = load(pos);
- off = pos + 8;
- return val;
-}
-
-/** Reads a LEB128-encoded unsigned integer from memory. */
-function readVaruint(size: u32): u32 {
- var val: u32 = 0;
- var shl: u32 = 0;
- var byt: u32;
- var pos = off;
- do {
- byt = load(pos++);
- val |= (byt & 0x7F) << shl;
- if (!(byt & 0x80)) break;
- shl += 7;
- } while (true);
- off = pos;
- return val;
-}
-
-/** Reads a LEB128-encoded signed integer from memory. */
-function readVarint(size: u32): i32 {
- var val: u32 = 0;
- var shl: u32 = 0;
- var byt: u32;
- var pos = off;
- do {
- byt = load(pos++);
- val |= (byt & 0x7F) << shl;
- shl += 7;
- } while (byt & 0x80);
- off = pos;
- return select(val | (~0 << shl), val, shl < size && (byt & 0x40) != 0);
-}
-
-/** Reads a LEB128-encoded signed 64-bit integer from memory. */
-function readVarint64(): i64 {
- var val: u64 = 0;
- var shl: u64 = 0;
- var byt: u64;
- var pos = off;
- do {
- byt = load(pos++);
- val |= (byt & 0x7F) << shl;
- shl += 7;
- } while (byt & 0x80);
- off = pos;
- return select(val | (~0 << shl), val, shl < 64 && (byt & 0x40) != 0);
-}
-
-function skipInitExpr(): void {
- var op = readUint();
- switch (op) {
- case Opcode.i32_const: {
- readVarint(32);
- break;
- }
- case Opcode.i64_const: {
- readVarint64();
- break;
- }
- case Opcode.f32_const: {
- readUint();
- break;
- }
- case Opcode.f64_const: {
- readUint64();
- break;
- }
- case Opcode.get_global: {
- readVaruint(32);
- break;
- }
- default: unreachable(); // MVP
- }
- if (readUint() != Opcode.end) unreachable();
-}
-
-/** Starts parsing the module that has been placed in memory. */
-export function parse(begin: usize, end: usize): void {
- off = begin;
- var magic = readUint();
- if (magic != 0x6D736100) unreachable();
- var version = readUint();
- if (version != 1) unreachable();
- var fun_space_index: u32 = 0;
- var glo_space_index: u32 = 0;
- var mem_space_index: u32 = 0;
- var tbl_space_index: u32 = 0;
- while (off < end) {
- // let section_off = off;
- let id = readVaruint(7);
- let payload_len = readVaruint(32);
- let name_off = 0;
- let name_len = 0;
- if (!id) {
- let before = off;
- name_len = readVaruint(32);
- name_off = off;
- off += name_len;
- payload_len -= off - before;
- } else if (id > SectionId.Data) unreachable();
- let payload_off = off;
- if (opt.onSection(
- id,
- payload_off,
- payload_len,
- name_off,
- name_len
- )) {
- switch (id) {
- case SectionId.Type: {
- let count = readVaruint(32);
- for (let index: u32 = 0; index < count; ++index) {
- let form = readVarint(7) & 0x7f;
- opt.onType(
- index,
- form
- );
- let paramCount = readVaruint(32);
- for (let paramIndex: u32 = 0; paramIndex < paramCount; ++paramIndex) {
- let paramType = readVarint(7) & 0x7f;
- opt.onTypeParam(
- index,
- paramIndex,
- paramType
- );
- }
- let returnCount = readVaruint(1); // MVP
- for (let returnIndex: u32 = 0; returnIndex < returnCount; ++returnIndex) {
- let returnType = readVarint(7) & 0x7f;
- opt.onTypeReturn(
- index,
- returnIndex,
- returnType
- );
- }
- }
- break;
- }
- case SectionId.Import: {
- let count = readVaruint(32);
- for (let index: u32 = 0; index < count; ++index) {
- let module_len = readVaruint(32);
- let module_off = off;
- off += module_len;
- let field_len = readVaruint(32);
- let field_off = off;
- off += field_len;
- let kind = readUint();
- opt.onImport(
- index,
- kind,
- module_off,
- module_len,
- field_off,
- field_len
- );
- switch (kind) {
- case ExternalKind.Function: {
- let type = readVaruint(32);
- opt.onFunctionImport(
- fun_space_index++,
- type
- );
- break;
- }
- case ExternalKind.Table: {
- let type = readVarint(7) & 0x7f;
- let flags = readVaruint(1);
- let initial = readVaruint(32);
- let maximum = flags & 1 ? readVaruint(32) : MAX_ELEMS;
- opt.onTableImport(
- tbl_space_index++,
- type,
- initial,
- maximum,
- flags
- );
- break;
- }
- case ExternalKind.Memory: {
- let flags = readVaruint(1);
- let initial = readVaruint(32);
- let maximum = flags & 1 ? readVaruint(32) : MAX_PAGES;
- opt.onMemoryImport(
- mem_space_index++,
- initial,
- maximum,
- flags
- );
- break;
- }
- case ExternalKind.Global: {
- let type = readVarint(7) & 0x7f;
- let mutability = readVaruint(1);
- opt.onGlobalImport(
- glo_space_index++,
- type,
- mutability
- );
- break;
- }
- default: unreachable();
- }
- }
- break;
- }
- case SectionId.Function: {
- let count = readVaruint(32);
- for (let i: u32 = 0; i < count; ++i) {
- let typeIndex = readVaruint(32);
- opt.onFunction(
- fun_space_index++,
- typeIndex
- );
- }
- break;
- }
- case SectionId.Table: {
- let count = readVaruint(32);
- for (let index: u32 = 0; index < count; ++index) {
- let type = readVaruint(7) & 0x7f;
- let flags = readVaruint(1);
- let initial = readVaruint(32);
- let maximum = flags & 1 ? readVaruint(32) : MAX_ELEMS;
- opt.onTable(
- tbl_space_index++,
- type,
- initial,
- maximum,
- flags
- );
- }
- break;
- }
- case SectionId.Memory: {
- let count = readVaruint(32);
- for (let index: u32 = 0; index < count; ++index) {
- let flags = readVaruint(1);
- let initial = readVaruint(32);
- let maximum = flags & 1 ? readVaruint(32) : MAX_PAGES;
- opt.onMemory(
- mem_space_index++,
- initial,
- maximum,
- flags
- );
- }
- break;
- }
- case SectionId.Global: {
- let count = readVaruint(32);
- for (let i: u32 = 0; i < count; ++i) {
- let type = readVarint(7) & 0x7f;
- let mutability = readVaruint(1);
- skipInitExpr();
- opt.onGlobal(
- glo_space_index++,
- type,
- mutability
- );
- }
- break;
- }
- case SectionId.Export: {
- let count = readVaruint(32);
- for (let index: u32 = 0; index < count; ++index) {
- let field_len = readVaruint(32);
- let field_off = off;
- off += field_len;
- let kind = readUint();
- let kind_index = readVaruint(32);
- opt.onExport(
- index,
- kind,
- kind_index,
- field_off,
- field_len
- );
- }
- break;
- }
- case SectionId.Start: {
- let index = readVaruint(32);
- opt.onStart(
- index
- );
- break;
- }
- case SectionId.Custom: {
- if (
- name_len == 4 &&
- load(name_off) == 0x656D616E // "name"
- ) {
- let name_type = readVaruint(7);
- let name_payload_len = readVaruint(32);
- let name_payload_off = off;
- switch (name_type) {
- case NameType.Module: {
- let module_name_len = readVaruint(32);
- let module_name_off = off;
- opt.onModuleName(
- module_name_off,
- module_name_len
- );
- break;
- }
- case NameType.Function: {
- let count = readVaruint(32);
- for (let i: u32 = 0; i < count; ++i) {
- let fn_index = readVaruint(32);
- let fn_name_len = readVaruint(32);
- let fn_name_off = off;
- off += fn_name_len;
- opt.onFunctionName(
- fn_index,
- fn_name_off,
- fn_name_len
- );
- }
- break;
- }
- case NameType.Local: {
- let count = readVaruint(32);
- for (let i: u32 = 0; i < count; ++i) {
- let fn_index = readVaruint(32);
- let lc_count = readVaruint(32);
- for (let j: u32 = 0; j < lc_count; ++j) {
- let lc_index = readVaruint(32);
- let lc_name_len = readVaruint(32);
- let lc_name_off = off;
- off += lc_name_len;
- opt.onLocalName(
- fn_index,
- lc_index,
- lc_name_off,
- lc_name_len
- );
- }
- }
- break;
- }
- default: unreachable();
- }
- off = name_payload_off + name_payload_len; // ignore errors
- break;
- } else if (
- name_len == 16 &&
- load(name_off ) == 0x614D656372756F73 && // "sourceMa"
- load(name_off + 8) == 0x4C5255676E697070 // "ppingURL"
- ) {
- let url_len = readVaruint(32);
- let url_off = off;
- off += url_len;
- opt.onSourceMappingURL(
- url_off,
- url_len
- );
- }
- off = payload_off + payload_len; // ignore errors
- break;
- }
- case SectionId.Element:
- case SectionId.Code:
- case SectionId.Data: { // skip
- off += payload_len;
- break;
- }
- default: unreachable();
- }
- } else { // skip
- off += payload_len;
- }
- }
- if (off != end) unreachable();
-}
diff --git a/lib/parse/assembly/options.ts b/lib/parse/assembly/options.ts
deleted file mode 100644
index e4ca8ad219..0000000000
--- a/lib/parse/assembly/options.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-// Imported callbacks
-export declare function onSection(id: u32, offset: u32, length: u32, nameOffset: u32, nameLength: u32): bool;
-export declare function onType(index: u32, form: u32): void;
-export declare function onTypeParam(index: u32, paramIndex: u32, paramType: u32): void;
-export declare function onTypeReturn(index: u32, returnIndex: u32, returnType: u32): void;
-export declare function onImport(index: u32, kind: u32, moduleOff: u32, moduleLen: u32, fieldOff: u32, fieldLen: u32): void;
-export declare function onFunctionImport(index: u32, type: u32): void;
-export declare function onTableImport(index: u32, type: u32, initial: u32, maximum: u32, flags: u32): void;
-export declare function onMemoryImport(index: u32, initial: u32, maximum: u32, flags: u32): void;
-export declare function onGlobalImport(index: u32, type: u32, mutability: u32): void;
-export declare function onMemory(index: u32, initial: u32, maximum: u32, flags: u32): void;
-export declare function onFunction(index: u32, typeIndex: u32): void;
-export declare function onTable(index: u32, type: u32, initial: u32, maximum: u32, flags: u32): void;
-export declare function onGlobal(index: u32, type: u32, mutability: u32): void;
-export declare function onExport(index: u32, kind: u32, kindIndex: u32, nameOffset: u32, nameLength: u32): void;
-export declare function onStart(index: u32): void;
-export declare function onSourceMappingURL(offset: u32, length: u32): void;
-export declare function onModuleName(offset: u32, length: u32): void;
-export declare function onFunctionName(index: u32, offset: u32, length: u32): void;
-export declare function onLocalName(funcIndex: u32, index: u32, offset: u32, length: u32): void;
diff --git a/lib/parse/assembly/tsconfig.json b/lib/parse/assembly/tsconfig.json
deleted file mode 100644
index 6e52b21c48..0000000000
--- a/lib/parse/assembly/tsconfig.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "extends": "../../../std/assembly.json",
- "include": [
- "./**/*.ts"
- ]
-}
diff --git a/lib/parse/build/.gitignore b/lib/parse/build/.gitignore
deleted file mode 100644
index d873de2f78..0000000000
--- a/lib/parse/build/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-*.wasm
-*.wasm.map
diff --git a/lib/parse/build/index.wat b/lib/parse/build/index.wat
deleted file mode 100644
index 73b58157fd..0000000000
--- a/lib/parse/build/index.wat
+++ /dev/null
@@ -1,932 +0,0 @@
-(module
- (type $FUNCSIG$vii (func (param i32 i32)))
- (type $FUNCSIG$ii (func (param i32) (result i32)))
- (type $FUNCSIG$iiiiii (func (param i32 i32 i32 i32 i32) (result i32)))
- (type $FUNCSIG$viii (func (param i32 i32 i32)))
- (type $FUNCSIG$viiiiii (func (param i32 i32 i32 i32 i32 i32)))
- (type $FUNCSIG$viiiii (func (param i32 i32 i32 i32 i32)))
- (type $FUNCSIG$viiii (func (param i32 i32 i32 i32)))
- (type $FUNCSIG$v (func))
- (type $FUNCSIG$vi (func (param i32)))
- (type $FUNCSIG$i (func (result i32)))
- (import "env" "memory" (memory $0 0))
- (import "options" "onSection" (func $assembly/options/onSection (param i32 i32 i32 i32 i32) (result i32)))
- (import "options" "onType" (func $assembly/options/onType (param i32 i32)))
- (import "options" "onTypeParam" (func $assembly/options/onTypeParam (param i32 i32 i32)))
- (import "options" "onTypeReturn" (func $assembly/options/onTypeReturn (param i32 i32 i32)))
- (import "options" "onImport" (func $assembly/options/onImport (param i32 i32 i32 i32 i32 i32)))
- (import "options" "onFunctionImport" (func $assembly/options/onFunctionImport (param i32 i32)))
- (import "options" "onTableImport" (func $assembly/options/onTableImport (param i32 i32 i32 i32 i32)))
- (import "options" "onMemoryImport" (func $assembly/options/onMemoryImport (param i32 i32 i32 i32)))
- (import "options" "onGlobalImport" (func $assembly/options/onGlobalImport (param i32 i32 i32)))
- (import "options" "onFunction" (func $assembly/options/onFunction (param i32 i32)))
- (import "options" "onTable" (func $assembly/options/onTable (param i32 i32 i32 i32 i32)))
- (import "options" "onMemory" (func $assembly/options/onMemory (param i32 i32 i32 i32)))
- (import "options" "onGlobal" (func $assembly/options/onGlobal (param i32 i32 i32)))
- (import "options" "onExport" (func $assembly/options/onExport (param i32 i32 i32 i32 i32)))
- (import "options" "onStart" (func $assembly/options/onStart (param i32)))
- (import "options" "onModuleName" (func $assembly/options/onModuleName (param i32 i32)))
- (import "options" "onFunctionName" (func $assembly/options/onFunctionName (param i32 i32 i32)))
- (import "options" "onLocalName" (func $assembly/options/onLocalName (param i32 i32 i32 i32)))
- (import "options" "onSourceMappingURL" (func $assembly/options/onSourceMappingURL (param i32 i32)))
- (global $assembly/index/off (mut i32) (i32.const 0))
- (export "memory" (memory $0))
- (export "parse" (func $assembly/index/parse))
- (func $assembly/index/readVaruint (; 19 ;) (type $FUNCSIG$i) (result i32)
- (local $0 i32)
- (local $1 i32)
- (local $2 i32)
- (local $3 i32)
- global.get $assembly/index/off
- local.set $0
- loop $continue|0
- local.get $0
- local.tee $1
- i32.const 1
- i32.add
- local.set $0
- local.get $1
- i32.load8_u
- local.tee $1
- i32.const 127
- i32.and
- local.get $3
- i32.shl
- local.get $2
- i32.or
- local.set $2
- local.get $1
- i32.const 128
- i32.and
- if
- local.get $3
- i32.const 7
- i32.add
- local.set $3
- br $continue|0
- end
- end
- local.get $0
- global.set $assembly/index/off
- local.get $2
- )
- (func $assembly/index/readVarint (; 20 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
- (local $1 i32)
- (local $2 i32)
- (local $3 i32)
- (local $4 i32)
- global.get $assembly/index/off
- local.set $4
- loop $continue|0
- local.get $4
- local.tee $3
- i32.const 1
- i32.add
- local.set $4
- local.get $3
- i32.load8_u
- local.tee $3
- i32.const 127
- i32.and
- local.get $1
- i32.shl
- local.get $2
- i32.or
- local.set $2
- local.get $1
- i32.const 7
- i32.add
- local.set $1
- local.get $3
- i32.const 128
- i32.and
- br_if $continue|0
- end
- local.get $4
- global.set $assembly/index/off
- i32.const -1
- local.get $1
- i32.shl
- local.get $2
- i32.or
- local.get $2
- local.get $3
- i32.const 64
- i32.and
- i32.const 0
- i32.ne
- i32.const 0
- local.get $1
- local.get $0
- i32.lt_u
- select
- select
- )
- (func $assembly/index/readVarint64 (; 21 ;) (type $FUNCSIG$v)
- (local $0 i32)
- (local $1 i64)
- (local $2 i32)
- (local $3 i64)
- (local $4 i64)
- global.get $assembly/index/off
- local.set $0
- loop $continue|0
- local.get $0
- local.tee $2
- i32.const 1
- i32.add
- local.set $0
- local.get $2
- i64.load8_u
- local.tee $4
- i64.const 127
- i64.and
- local.get $1
- i64.shl
- local.get $3
- i64.or
- local.set $3
- local.get $1
- i64.const 7
- i64.add
- local.set $1
- local.get $4
- i64.const 128
- i64.and
- i64.const 0
- i64.ne
- br_if $continue|0
- end
- local.get $0
- global.set $assembly/index/off
- )
- (func $assembly/index/skipInitExpr (; 22 ;) (type $FUNCSIG$v)
- (local $0 i32)
- (local $1 i32)
- global.get $assembly/index/off
- local.tee $1
- i32.load8_u
- local.set $0
- local.get $1
- i32.const 1
- i32.add
- global.set $assembly/index/off
- block $break|0
- block $case5|0
- block $case4|0
- block $case3|0
- block $case2|0
- block $case1|0
- local.get $0
- i32.const 65
- i32.ne
- if
- local.get $0
- i32.const 66
- i32.eq
- br_if $case1|0
- local.get $0
- i32.const 67
- i32.eq
- br_if $case2|0
- local.get $0
- i32.const 68
- i32.eq
- br_if $case3|0
- local.get $0
- i32.const 35
- i32.eq
- br_if $case4|0
- br $case5|0
- end
- i32.const 32
- call $assembly/index/readVarint
- drop
- br $break|0
- end
- call $assembly/index/readVarint64
- br $break|0
- end
- global.get $assembly/index/off
- local.tee $0
- i32.load
- drop
- local.get $0
- i32.const 4
- i32.add
- global.set $assembly/index/off
- br $break|0
- end
- global.get $assembly/index/off
- local.tee $0
- i64.load
- drop
- local.get $0
- i32.const 8
- i32.add
- global.set $assembly/index/off
- br $break|0
- end
- call $assembly/index/readVaruint
- drop
- br $break|0
- end
- unreachable
- end
- global.get $assembly/index/off
- local.tee $1
- i32.load8_u
- local.get $1
- i32.const 1
- i32.add
- global.set $assembly/index/off
- i32.const 11
- i32.ne
- if
- unreachable
- end
- )
- (func $assembly/index/parse (; 23 ;) (type $FUNCSIG$vii) (param $0 i32) (param $1 i32)
- (local $2 i32)
- (local $3 i32)
- (local $4 i32)
- (local $5 i32)
- (local $6 i32)
- (local $7 i32)
- (local $8 i32)
- (local $9 i32)
- (local $10 i32)
- (local $11 i32)
- (local $12 i32)
- (local $13 i32)
- (local $14 i32)
- local.get $0
- global.set $assembly/index/off
- global.get $assembly/index/off
- local.tee $0
- i32.load
- local.get $0
- i32.const 4
- i32.add
- global.set $assembly/index/off
- i32.const 1836278016
- i32.ne
- if
- unreachable
- end
- global.get $assembly/index/off
- local.tee $0
- i32.load
- local.get $0
- i32.const 4
- i32.add
- global.set $assembly/index/off
- i32.const 1
- i32.ne
- if
- unreachable
- end
- i32.const 0
- local.set $0
- loop $continue|0
- global.get $assembly/index/off
- local.get $1
- i32.lt_u
- if
- call $assembly/index/readVaruint
- local.set $4
- call $assembly/index/readVaruint
- local.set $3
- i32.const 0
- local.set $5
- i32.const 0
- local.set $2
- local.get $4
- if
- local.get $4
- i32.const 11
- i32.gt_u
- if
- unreachable
- end
- else
- global.get $assembly/index/off
- local.set $6
- call $assembly/index/readVaruint
- local.tee $2
- global.get $assembly/index/off
- local.tee $5
- i32.add
- global.set $assembly/index/off
- local.get $3
- global.get $assembly/index/off
- local.get $6
- i32.sub
- i32.sub
- local.set $3
- end
- local.get $4
- global.get $assembly/index/off
- local.tee $6
- local.get $3
- local.get $5
- local.get $2
- call $assembly/options/onSection
- if
- block $break|1
- block $case12|1
- block $case11|1
- block $case8|1
- block $case7|1
- block $case6|1
- block $case5|1
- block $case4|1
- block $case3|1
- block $case2|1
- block $case1|1
- local.get $4
- i32.const 1
- i32.ne
- if
- local.get $4
- i32.const 2
- i32.eq
- br_if $case1|1
- block $tablify|0
- local.get $4
- br_table $case8|1 $tablify|0 $tablify|0 $case2|1 $case3|1 $case4|1 $case5|1 $case6|1 $case7|1 $case11|1 $case11|1 $case11|1 $tablify|0
- end
- br $case12|1
- end
- call $assembly/index/readVaruint
- local.set $4
- i32.const 0
- local.set $2
- loop $loop|2
- local.get $2
- local.get $4
- i32.lt_u
- if
- local.get $2
- i32.const 7
- call $assembly/index/readVarint
- i32.const 127
- i32.and
- call $assembly/options/onType
- call $assembly/index/readVaruint
- local.set $5
- i32.const 0
- local.set $3
- loop $loop|3
- local.get $3
- local.get $5
- i32.lt_u
- if
- local.get $2
- local.get $3
- i32.const 7
- call $assembly/index/readVarint
- i32.const 127
- i32.and
- call $assembly/options/onTypeParam
- local.get $3
- i32.const 1
- i32.add
- local.set $3
- br $loop|3
- end
- end
- call $assembly/index/readVaruint
- local.set $5
- i32.const 0
- local.set $3
- loop $loop|4
- local.get $3
- local.get $5
- i32.lt_u
- if
- local.get $2
- local.get $3
- i32.const 7
- call $assembly/index/readVarint
- i32.const 127
- i32.and
- call $assembly/options/onTypeReturn
- local.get $3
- i32.const 1
- i32.add
- local.set $3
- br $loop|4
- end
- end
- local.get $2
- i32.const 1
- i32.add
- local.set $2
- br $loop|2
- end
- end
- br $break|1
- end
- call $assembly/index/readVaruint
- local.set $7
- i32.const 0
- local.set $4
- loop $loop|5
- local.get $4
- local.get $7
- i32.lt_u
- if
- call $assembly/index/readVaruint
- local.tee $3
- global.get $assembly/index/off
- local.tee $5
- i32.add
- global.set $assembly/index/off
- call $assembly/index/readVaruint
- local.tee $6
- global.get $assembly/index/off
- local.tee $8
- i32.add
- global.set $assembly/index/off
- global.get $assembly/index/off
- local.tee $9
- i32.load8_u
- local.set $2
- local.get $9
- i32.const 1
- i32.add
- global.set $assembly/index/off
- local.get $4
- local.get $2
- local.get $5
- local.get $3
- local.get $8
- local.get $6
- call $assembly/options/onImport
- block $break|6
- block $case4|6
- block $case3|6
- block $case2|6
- block $case1|6
- local.get $2
- if
- local.get $2
- i32.const 1
- i32.sub
- br_table $case1|6 $case2|6 $case3|6 $case4|6
- end
- local.get $10
- local.tee $2
- i32.const 1
- i32.add
- local.set $10
- local.get $2
- call $assembly/index/readVaruint
- call $assembly/options/onFunctionImport
- br $break|6
- end
- i32.const 7
- call $assembly/index/readVarint
- i32.const 127
- i32.and
- local.set $3
- call $assembly/index/readVaruint
- local.set $5
- local.get $0
- local.tee $2
- i32.const 1
- i32.add
- local.set $0
- local.get $2
- local.get $3
- call $assembly/index/readVaruint
- local.get $5
- i32.const 1
- i32.and
- if (result i32)
- call $assembly/index/readVaruint
- else
- i32.const -1
- end
- local.get $5
- call $assembly/options/onTableImport
- br $break|6
- end
- call $assembly/index/readVaruint
- local.set $3
- local.get $11
- local.tee $2
- i32.const 1
- i32.add
- local.set $11
- local.get $2
- call $assembly/index/readVaruint
- local.get $3
- i32.const 1
- i32.and
- if (result i32)
- call $assembly/index/readVaruint
- else
- i32.const 65535
- end
- local.get $3
- call $assembly/options/onMemoryImport
- br $break|6
- end
- local.get $12
- local.tee $2
- i32.const 1
- i32.add
- local.set $12
- local.get $2
- i32.const 7
- call $assembly/index/readVarint
- i32.const 127
- i32.and
- call $assembly/index/readVaruint
- call $assembly/options/onGlobalImport
- br $break|6
- end
- unreachable
- end
- local.get $4
- i32.const 1
- i32.add
- local.set $4
- br $loop|5
- end
- end
- br $break|1
- end
- call $assembly/index/readVaruint
- local.set $4
- i32.const 0
- local.set $3
- loop $loop|7
- local.get $3
- local.get $4
- i32.lt_u
- if
- local.get $10
- local.tee $2
- i32.const 1
- i32.add
- local.set $10
- local.get $2
- call $assembly/index/readVaruint
- call $assembly/options/onFunction
- local.get $3
- i32.const 1
- i32.add
- local.set $3
- br $loop|7
- end
- end
- br $break|1
- end
- call $assembly/index/readVaruint
- local.set $7
- i32.const 0
- local.set $4
- loop $loop|8
- local.get $4
- local.get $7
- i32.lt_u
- if
- call $assembly/index/readVaruint
- i32.const 127
- i32.and
- local.set $3
- call $assembly/index/readVaruint
- local.set $5
- local.get $0
- local.tee $2
- i32.const 1
- i32.add
- local.set $0
- local.get $2
- local.get $3
- call $assembly/index/readVaruint
- local.get $5
- i32.const 1
- i32.and
- if (result i32)
- call $assembly/index/readVaruint
- else
- i32.const -1
- end
- local.get $5
- call $assembly/options/onTable
- local.get $4
- i32.const 1
- i32.add
- local.set $4
- br $loop|8
- end
- end
- br $break|1
- end
- call $assembly/index/readVaruint
- local.set $6
- i32.const 0
- local.set $3
- loop $loop|9
- local.get $3
- local.get $6
- i32.lt_u
- if
- call $assembly/index/readVaruint
- local.set $4
- local.get $11
- local.tee $2
- i32.const 1
- i32.add
- local.set $11
- local.get $2
- call $assembly/index/readVaruint
- local.get $4
- i32.const 1
- i32.and
- if (result i32)
- call $assembly/index/readVaruint
- else
- i32.const 65535
- end
- local.get $4
- call $assembly/options/onMemory
- local.get $3
- i32.const 1
- i32.add
- local.set $3
- br $loop|9
- end
- end
- br $break|1
- end
- call $assembly/index/readVaruint
- local.set $4
- i32.const 0
- local.set $3
- loop $loop|10
- local.get $3
- local.get $4
- i32.lt_u
- if
- i32.const 7
- call $assembly/index/readVarint
- i32.const 127
- i32.and
- local.set $5
- call $assembly/index/readVaruint
- local.set $6
- call $assembly/index/skipInitExpr
- local.get $12
- local.tee $2
- i32.const 1
- i32.add
- local.set $12
- local.get $2
- local.get $5
- local.get $6
- call $assembly/options/onGlobal
- local.get $3
- i32.const 1
- i32.add
- local.set $3
- br $loop|10
- end
- end
- br $break|1
- end
- call $assembly/index/readVaruint
- local.set $3
- i32.const 0
- local.set $2
- loop $loop|11
- local.get $2
- local.get $3
- i32.lt_u
- if
- call $assembly/index/readVaruint
- local.tee $4
- global.get $assembly/index/off
- local.tee $5
- i32.add
- global.set $assembly/index/off
- global.get $assembly/index/off
- local.tee $6
- i32.load8_u
- local.set $7
- local.get $6
- i32.const 1
- i32.add
- global.set $assembly/index/off
- local.get $2
- local.get $7
- call $assembly/index/readVaruint
- local.get $5
- local.get $4
- call $assembly/options/onExport
- local.get $2
- i32.const 1
- i32.add
- local.set $2
- br $loop|11
- end
- end
- br $break|1
- end
- call $assembly/index/readVaruint
- call $assembly/options/onStart
- br $break|1
- end
- local.get $2
- i32.const 4
- i32.eq
- if (result i32)
- local.get $5
- i32.load
- i32.const 1701667182
- i32.eq
- else
- i32.const 0
- end
- if
- call $assembly/index/readVaruint
- local.set $2
- call $assembly/index/readVaruint
- global.get $assembly/index/off
- block $break|12
- block $case3|12
- block $case2|12
- block $case1|12
- local.get $2
- if
- local.get $2
- i32.const 1
- i32.eq
- br_if $case1|12
- local.get $2
- i32.const 2
- i32.eq
- br_if $case2|12
- br $case3|12
- end
- call $assembly/index/readVaruint
- local.set $2
- global.get $assembly/index/off
- local.get $2
- call $assembly/options/onModuleName
- br $break|12
- end
- call $assembly/index/readVaruint
- local.set $2
- i32.const 0
- local.set $3
- loop $loop|13
- local.get $3
- local.get $2
- i32.lt_u
- if
- call $assembly/index/readVaruint
- call $assembly/index/readVaruint
- local.tee $7
- global.get $assembly/index/off
- local.tee $8
- i32.add
- global.set $assembly/index/off
- local.get $8
- local.get $7
- call $assembly/options/onFunctionName
- local.get $3
- i32.const 1
- i32.add
- local.set $3
- br $loop|13
- end
- end
- br $break|12
- end
- call $assembly/index/readVaruint
- local.set $6
- i32.const 0
- local.set $2
- loop $loop|14
- local.get $2
- local.get $6
- i32.lt_u
- if
- call $assembly/index/readVaruint
- local.set $7
- call $assembly/index/readVaruint
- local.set $8
- i32.const 0
- local.set $3
- loop $loop|15
- local.get $3
- local.get $8
- i32.lt_u
- if
- call $assembly/index/readVaruint
- local.set $9
- call $assembly/index/readVaruint
- local.tee $13
- global.get $assembly/index/off
- local.tee $14
- i32.add
- global.set $assembly/index/off
- local.get $7
- local.get $9
- local.get $14
- local.get $13
- call $assembly/options/onLocalName
- local.get $3
- i32.const 1
- i32.add
- local.set $3
- br $loop|15
- end
- end
- local.get $2
- i32.const 1
- i32.add
- local.set $2
- br $loop|14
- end
- end
- br $break|12
- end
- unreachable
- end
- i32.add
- global.set $assembly/index/off
- br $break|1
- else
- local.get $2
- i32.const 16
- i32.eq
- if (result i32)
- local.get $5
- i64.load
- i64.const 7011371672682196851
- i64.eq
- else
- i32.const 0
- end
- if (result i32)
- local.get $5
- i32.const 8
- i32.add
- i64.load
- i64.const 5499551997695193200
- i64.eq
- else
- i32.const 0
- end
- if
- call $assembly/index/readVaruint
- local.tee $2
- global.get $assembly/index/off
- local.tee $4
- i32.add
- global.set $assembly/index/off
- local.get $4
- local.get $2
- call $assembly/options/onSourceMappingURL
- end
- end
- local.get $3
- local.get $6
- i32.add
- global.set $assembly/index/off
- br $break|1
- end
- global.get $assembly/index/off
- local.get $3
- i32.add
- global.set $assembly/index/off
- br $break|1
- end
- unreachable
- end
- else
- global.get $assembly/index/off
- local.get $3
- i32.add
- global.set $assembly/index/off
- end
- br $continue|0
- end
- end
- global.get $assembly/index/off
- local.get $1
- i32.ne
- if
- unreachable
- end
- )
- (func $null (; 24 ;) (type $FUNCSIG$v)
- nop
- )
-)
diff --git a/lib/parse/index.d.ts b/lib/parse/index.d.ts
deleted file mode 100644
index 3bd16e178a..0000000000
--- a/lib/parse/index.d.ts
+++ /dev/null
@@ -1 +0,0 @@
-export * from "./src";
diff --git a/lib/parse/index.js b/lib/parse/index.js
deleted file mode 100644
index 79b2952d67..0000000000
--- a/lib/parse/index.js
+++ /dev/null
@@ -1,2 +0,0 @@
-!function(A,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.asparse=e():A.asparse=e()}("undefined"!=typeof self?self:this,function(){return function(A){var e={};function n(o){if(e[o])return e[o].exports;var Q=e[o]={i:o,l:!1,exports:{}};return A[o].call(Q.exports,Q,Q.exports,n),Q.l=!0,Q.exports}return n.m=A,n.c=e,n.d=function(A,e,o){n.o(A,e)||Object.defineProperty(A,e,{enumerable:!0,get:o})},n.r=function(A){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(A,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(A,"__esModule",{value:!0})},n.t=function(A,e){if(1&e&&(A=n(A)),8&e)return A;if(4&e&&"object"==typeof A&&A&&A.__esModule)return A;var o=Object.create(null);if(n.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:A}),2&e&&"string"!=typeof A)for(var Q in A)n.d(o,Q,function(e){return A[e]}.bind(null,Q));return o},n.n=function(A){var e=A&&A.__esModule?function(){return A.default}:function(){return A};return n.d(e,"a",e),e},n.o=function(A,e){return Object.prototype.hasOwnProperty.call(A,e)},n.p="",n(n.s=0)}([function(A,e,n){A.exports=n(1)},function(A,e,n){"use strict";e.__esModule=!0;var o=n(2);e.Type=o.Type,e.SectionId=o.SectionId,e.ExternalKind=o.ExternalKind;var Q=null;e.parse=function A(e,n){n||(n={}),Q||(Q=new WebAssembly.Module(function(A){var e=A.length;if(e){for(var n=0,o=e;--o%4>1&&61===A.charCodeAt(o);)++n;e=Math.ceil(3*e)/4-n}for(var Q=new Uint8Array(e),B=0,I=0,E=0,r=0,i=A.length;r1)break;if(void 0===(C=t[C]))throw Error();switch(B){case 0:E=C,B=1;break;case 1:Q[I++]=E<<2|(48&C)>>4,E=C,B=2;break;case 2:Q[I++]=(15&E)<<4|(60&C)>>2,E=C,B=3;break;case 3:Q[I++]=(3&E)<<6|C,B=0}}if(1===B)throw Error();return Q}("AGFzbQEAAAABPQpgAn9/AGABfwF/YAV/f39/fwF/YAN/f38AYAZ/f39/f38AYAV/f39/fwBgBH9/f38AYAAAYAF/AGAAAX8CrgMUB29wdGlvbnMJb25TZWN0aW9uAAIHb3B0aW9ucwZvblR5cGUAAAdvcHRpb25zC29uVHlwZVBhcmFtAAMHb3B0aW9ucwxvblR5cGVSZXR1cm4AAwdvcHRpb25zCG9uSW1wb3J0AAQHb3B0aW9ucxBvbkZ1bmN0aW9uSW1wb3J0AAAHb3B0aW9ucw1vblRhYmxlSW1wb3J0AAUHb3B0aW9ucw5vbk1lbW9yeUltcG9ydAAGB29wdGlvbnMOb25HbG9iYWxJbXBvcnQAAwdvcHRpb25zCm9uRnVuY3Rpb24AAAdvcHRpb25zB29uVGFibGUABQdvcHRpb25zCG9uTWVtb3J5AAYHb3B0aW9ucwhvbkdsb2JhbAADB29wdGlvbnMIb25FeHBvcnQABQdvcHRpb25zB29uU3RhcnQACAdvcHRpb25zDG9uTW9kdWxlTmFtZQAAB29wdGlvbnMOb25GdW5jdGlvbk5hbWUAAwdvcHRpb25zC29uTG9jYWxOYW1lAAYHb3B0aW9ucxJvblNvdXJjZU1hcHBpbmdVUkwAAANlbnYGbWVtb3J5AgAAAwcGCQEHBwAHBgYBfwFBAAsHEgIGbWVtb3J5AgAFcGFyc2UAFwrlDAY/AQR/IwAhAANAIAAiAUEBaiEAIAEtAAAiAUH/AHEgA3QgAnIhAiABQYABcQRAIANBB2ohAwwBCwsgACQAIAILVgEEfyMAIQQDQCAEIgNBAWohBCADLQAAIgNB/wBxIAF0IAJyIQIgAUEHaiEBIANBgAFxDQALIAQkAEF/IAF0IAJyIAIgA0HAAHFBAEdBACABIABJGxsLPwICfwN+IwAhAANAIAAiAUEBaiEAIAExAAAiBEL/AIMgAoYgA4QhAyACQgd8IQIgBEKAAYNCAFINAAsgACQAC5wBAQJ/IwAiAS0AACEAIAFBAWokAAJAAkACQAJAAkACQCAAQcEARwRAIABBwgBGDQEgAEHDAEYNAiAAQcQARg0DIABBI0YNBAwFC0EgEBQaDAULEBUMBAsjACIAKAIAGiAAQQRqJAAMAwsjACIAKQMAGiAAQQhqJAAMAgsQExoMAQsACyMAIgEtAAAhACABQQFqJAAgAEELRwRAAAsL6QkBDX8gACQAIwAiACgCACECIABBBGokACACQYDCzesGRwRAAAsjACIAKAIAIQIgAEEEaiQAIAJBAUcEQAALQQAhAANAIwAgAUkEQBATIQQQEyEDQQAhBUEAIQIgBARAIARBC0sEQAALBSMAIQYQEyICIwAiBWokACADIwAgBmtrIQMLIAQjACIGIAMgBSACEAAEQAJAAkACQAJAAkACQAJAAkACQAJAAkAgBEEBRwRAIARBAkYNAQJAIAQODAkAAAMEBQYHCAoKCgALDAoLEBMhBEEAIQIDQCACIARJBEAgAkEHEBRB/wBxEAEQEyEFQQAhAwNAIAMgBUkEQCACIANBBxAUQf8AcRACIANBAWohAwwBCwsQEyEFQQAhAwNAIAMgBUkEQCACIANBBxAUQf8AcRADIANBAWohAwwBCwsgAkEBaiECDAELCwwKCxATIQdBACEEA0AgBCAHSQRAEBMiAyMAIgVqJAAQEyIGIwAiCGokACMAIgktAAAhAiAJQQFqJAAgBCACIAUgAyAIIAYQBAJAAkACQAJAAkAgAgRAIAJBAWsOAwECAwQLIAoiAkEBaiEKIAIQExAFDAQLQQcQFEH/AHEhAxATIQUgACICQQFqIQAgAiADEBMgBUEBcQR/EBMFQX8LIAUQBgwDCxATIQMgCyICQQFqIQsgAhATIANBAXEEfxATBUH//wMLIAMQBwwCCyAMIgJBAWohDCACQQcQFEH/AHEQExAIDAELAAsgBEEBaiEEDAELCwwJCxATIQRBACEDA0AgAyAESQRAIAoiAkEBaiEKIAIQExAJIANBAWohAwwBCwsMCAsQEyEHQQAhBANAIAQgB0kEQBATQf8AcSEDEBMhBSAAIgJBAWohACACIAMQEyAFQQFxBH8QEwVBfwsgBRAKIARBAWohBAwBCwsMBwsQEyEGQQAhAwNAIAMgBkkEQBATIQQgCyICQQFqIQsgAhATIARBAXEEfxATBUH//wMLIAQQCyADQQFqIQMMAQsLDAYLEBMhBEEAIQMDQCADIARJBEBBBxAUQf8AcSEFEBMhBhAWIAwiAkEBaiEMIAIgBSAGEAwgA0EBaiEDDAELCwwFCxATIQNBACECA0AgAiADSQRAEBMiBCMAIgVqJAAjACIGLQAAIQcgBkEBaiQAIAIgBxATIAUgBBANIAJBAWohAgwBCwsMBAsQExAODAMLIAJBBEYEfyAFKAIAQe7CtasGRgVBAAsEQBATIQIQEyEEIwAhBQJAAkACQAJAIAIEQCACQQFGDQEgAkECRg0CDAMLEBMhAiMAIAIQDwwDCxATIQJBACEDA0AgAyACSQRAEBMhBhATIgcjACIIaiQAIAYgCCAHEBAgA0EBaiEDDAELCwwCCxATIQZBACECA0AgAiAGSQRAEBMhBxATIQhBACEDA0AgAyAISQRAEBMhCRATIg0jACIOaiQAIAcgCSAOIA0QESADQQFqIQMMAQsLIAJBAWohAgwBCwsMAQsACyAEIAVqJAAMAwUgAkEQRgR/IAUpAwBC897Vk7es2abhAFEFQQALBH8gBUEIaikDAELw4KXz9qyVqcwAUQVBAAsEQBATIgIjACIEaiQAIAQgAhASCwsgAyAGaiQADAILIwAgA2okAAwBCwALBSMAIANqJAALDAELCyMAIAFHBEAACwsDAAELACAQc291cmNlTWFwcGluZ1VSTA5pbmRleC53YXNtLm1hcA==")));var o=e.length,B=(o+65535&-65536)>>16,I=new WebAssembly.Memory({initial:B}),E=new Uint8Array(I.buffer);E.set(e),A.readString=function(A,e){return function(A,e,n){if(n-e<1)return"";for(var o=null,Q=[],t=0,B=0;e191&&B<224?Q[t++]=(31&B)<<6|63&A[e++]:B>239&&B<365?(B=((7&B)<<18|(63&A[e++])<<12|(63&A[e++])<<6|63&A[e++])-65536,Q[t++]=55296+(B>>10),Q[t++]=56320+(1023&B)):Q[t++]=(15&B)<<12|(63&A[e++])<<6|63&A[e++],t>8191&&((o||(o=[])).push(String.fromCharCode.apply(String,Q)),t=0);return o?(t&&o.push(String.fromCharCode.apply(String,Q.slice(0,t))),o.join("")):String.fromCharCode.apply(String,Q.slice(0,t))}(E,A,A+e)};var r={env:{memory:I},options:{}};["onSection","onType","onTypeParam","onTypeReturn","onImport","onFunctionImport","onTableImport","onMemoryImport","onGlobalImport","onMemory","onFunction","onTable","onGlobal","onExport","onStart","onSourceMappingURL","onModuleName","onFunctionName","onLocalName"].forEach(function(A){return r.options[A]=n[A]||function(){}}),new WebAssembly.Instance(Q,r).exports.parse(0,o)};for(var t=new Array(123),B=0;B<64;)t[B<26?B+65:B<52?B+71:B<62?B-4:B-59|43]=B++},function(A,e,n){"use strict";e.__esModule=!0,function(A){A[A.i32=127]="i32",A[A.i64=126]="i64",A[A.f32=125]="f32",A[A.f64=124]="f64",A[A.anyfunc=112]="anyfunc",A[A.func=96]="func",A[A.none=64]="none"}(e.Type||(e.Type={})),function(A){A[A.Custom=0]="Custom",A[A.Type=1]="Type",A[A.Import=2]="Import",A[A.Function=3]="Function",A[A.Table=4]="Table",A[A.Memory=5]="Memory",A[A.Global=6]="Global",A[A.Export=7]="Export",A[A.Start=8]="Start",A[A.Element=9]="Element",A[A.Code=10]="Code",A[A.Data=11]="Data"}(e.SectionId||(e.SectionId={})),function(A){A[A.Function=0]="Function",A[A.Table=1]="Table",A[A.Memory=2]="Memory",A[A.Global=3]="Global"}(e.ExternalKind||(e.ExternalKind={})),function(A){A[A.Module=0]="Module",A[A.Function=1]="Function",A[A.Local=2]="Local"}(e.NameType||(e.NameType={})),e.MAX_PAGES=65535,e.MAX_ELEMS=4294967295,function(A){A[A.end=11]="end",A[A.get_global=35]="get_global",A[A.i32_const=65]="i32_const",A[A.i64_const=66]="i64_const",A[A.f32_const=67]="f32_const",A[A.f64_const=68]="f64_const"}(e.Opcode||(e.Opcode={}))}])});
-//# sourceMappingURL=index.js.map
\ No newline at end of file
diff --git a/lib/parse/index.js.map b/lib/parse/index.js.map
deleted file mode 100644
index 0253c777cb..0000000000
--- a/lib/parse/index.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"sources":["webpack://asparse/webpack/universalModuleDefinition","webpack://asparse/webpack/bootstrap","webpack://asparse/./src/index.ts","webpack://asparse/./src/common.ts"],"names":["root","factory","exports","module","define","amd","self","this","installedModules","__webpack_require__","moduleId","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","common_1","Type","SectionId","ExternalKind","compiled","parse","binary","options","WebAssembly","Module","string","length","charCodeAt","Math","ceil","buffer","Uint8Array","j","k","undefined","s64","Error","base64_decode","nBytes","nPages","memory","Memory","initial","set","readString","offset","start","end","parts","chunk","push","String","fromCharCode","apply","slice","join","utf8_read","imports","env","forEach","Instance","Array","NameType","MAX_PAGES","MAX_ELEMS","Opcode"],"mappings":"CAAA,SAAAA,EAAAC,GACA,iBAAAC,SAAA,iBAAAC,OACAA,OAAAD,QAAAD,IACA,mBAAAG,eAAAC,IACAD,UAAAH,GACA,iBAAAC,QACAA,QAAA,QAAAD,IAEAD,EAAA,QAAAC,IARA,CASC,oBAAAK,UAAAC,KAAA,WACD,mBCTA,IAAAC,KAGA,SAAAC,EAAAC,GAGA,GAAAF,EAAAE,GACA,OAAAF,EAAAE,GAAAR,QAGA,IAAAC,EAAAK,EAAAE,IACAC,EAAAD,EACAE,GAAA,EACAV,YAUA,OANAW,EAAAH,GAAAI,KAAAX,EAAAD,QAAAC,IAAAD,QAAAO,GAGAN,EAAAS,GAAA,EAGAT,EAAAD,QA0DA,OArDAO,EAAAM,EAAAF,EAGAJ,EAAAO,EAAAR,EAGAC,EAAAQ,EAAA,SAAAf,EAAAgB,EAAAC,GACAV,EAAAW,EAAAlB,EAAAgB,IACAG,OAAAC,eAAApB,EAAAgB,GAA0CK,YAAA,EAAAC,IAAAL,KAK1CV,EAAAgB,EAAA,SAAAvB,GACA,oBAAAwB,eAAAC,aACAN,OAAAC,eAAApB,EAAAwB,OAAAC,aAAwDC,MAAA,WAExDP,OAAAC,eAAApB,EAAA,cAAiD0B,OAAA,KAQjDnB,EAAAoB,EAAA,SAAAD,EAAAE,GAEA,GADA,EAAAA,IAAAF,EAAAnB,EAAAmB,IACA,EAAAE,EAAA,OAAAF,EACA,KAAAE,GAAA,iBAAAF,QAAAG,WAAA,OAAAH,EACA,IAAAI,EAAAX,OAAAY,OAAA,MAGA,GAFAxB,EAAAgB,EAAAO,GACAX,OAAAC,eAAAU,EAAA,WAAyCT,YAAA,EAAAK,UACzC,EAAAE,GAAA,iBAAAF,EAAA,QAAAM,KAAAN,EAAAnB,EAAAQ,EAAAe,EAAAE,EAAA,SAAAA,GAAgH,OAAAN,EAAAM,IAAqBC,KAAA,KAAAD,IACrI,OAAAF,GAIAvB,EAAA2B,EAAA,SAAAjC,GACA,IAAAgB,EAAAhB,KAAA4B,WACA,WAA2B,OAAA5B,EAAA,SAC3B,WAAiC,OAAAA,GAEjC,OADAM,EAAAQ,EAAAE,EAAA,IAAAA,GACAA,GAIAV,EAAAW,EAAA,SAAAiB,EAAAC,GAAsD,OAAAjB,OAAAkB,UAAAC,eAAA1B,KAAAuB,EAAAC,IAGtD7B,EAAAgC,EAAA,GAIAhC,IAAAiC,EAAA,kECjFAxC,EAAA6B,YAAA,EACA,IAAAY,EAAelC,EAAQ,GACvBP,EAAA0C,KAAAD,EAAAC,KACA1C,EAAA2C,UAAAF,EAAAE,UACA3C,EAAA4C,aAAAH,EAAAG,aAEA,IAAAC,EAAA,KAgDA7C,EAAA8C,MA5CA,SAAAA,EAAAC,EAAAC,GACAA,IACAA,MAEAH,IACAA,EAAA,IAAAI,YAAAC,OA4EA,SAAAC,GACA,IAAAC,EAAAD,EAAAC,OACA,GAAAA,EAAA,CAEA,IADA,IAAAlB,EAAA,EAAAK,EAAAa,IACAb,EAAA,UAAAY,EAAAE,WAAAd,MACAL,EACAkB,EAAAE,KAAAC,KAAA,EAAAH,GAAA,EAAAlB,EAIA,IAFA,IAAAsB,EAAA,IAAAC,WAAAL,GACAM,EAAA,EAAAxC,EAAA,EAAAS,EAAA,EACAlB,EAAA,EAAAkD,EAAAR,EAAAC,OAAsC3C,EAAAkD,GAAO,CAC7C,IAAA7C,EAAAqC,EAAAE,WAAA5C,KACA,QAAAK,GAAA4C,EAAA,EACA,MACA,QAAAE,KAAA9C,EAAA+C,EAAA/C,IACA,MAAAgD,QACA,OAAAJ,GACA,OACA/B,EAAAb,EACA4C,EAAA,EACA,MAEA,OACAF,EAAAtC,KAAAS,GAAA,MAAAb,IAAA,EACAa,EAAAb,EACA4C,EAAA,EACA,MAEA,OACAF,EAAAtC,MAAA,GAAAS,IAAA,MAAAb,IAAA,EACAa,EAAAb,EACA4C,EAAA,EACA,MAEA,OACAF,EAAAtC,MAAA,EAAAS,IAAA,EAAAb,EACA4C,EAAA,GAKA,OAAAA,EACA,MAAAI,QACA,OAAAN,EAvHAO,CAAwD,k5FAExD,IAAAC,EAAAjB,EAAAK,OACAa,GAAAD,EAAA,kBACAE,EAAA,IAAAjB,YAAAkB,QAAyCC,QAAAH,IACzCT,EAAA,IAAAC,WAAAS,EAAAV,QACAA,EAAAa,IAAAtB,GAEAD,EAAAwB,WAAA,SAAAC,EAAAnB,GAAkD,OAiClD,SAAAI,EAAAgB,EAAAC,GAEA,GADAA,EAAAD,EACA,EACA,SAGA,IAFA,IAAAE,EAAA,KAAAC,KAAAlE,EAAA,EACAkB,EAAA,EACA6C,EAAAC,IACA9C,EAAA6B,EAAAgB,MACA,IACAG,EAAAlE,KAAAkB,EAEAA,EAAA,KAAAA,EAAA,IACAgD,EAAAlE,MAAA,GAAAkB,IAAA,KAAA6B,EAAAgB,KAEA7C,EAAA,KAAAA,EAAA,KACAA,IAAA,EAAAA,IAAA,OAAA6B,EAAAgB,OAAA,OAAAhB,EAAAgB,OAAA,KAAAhB,EAAAgB,MAAA,MACAG,EAAAlE,KAAA,OAAAkB,GAAA,IACAgD,EAAAlE,KAAA,YAAAkB,IAGAgD,EAAAlE,MAAA,GAAAkB,IAAA,OAAA6B,EAAAgB,OAAA,KAAAhB,EAAAgB,KAEA/D,EAAA,QACAiE,WAAAE,KAAAC,OAAAC,aAAAC,MAAAF,OAAAF,IACAlE,EAAA,GAGA,OAAAiE,GACAjE,GACAiE,EAAAE,KAAAC,OAAAC,aAAAC,MAAAF,OAAAF,EAAAK,MAAA,EAAAvE,KACAiE,EAAAO,KAAA,KAEAJ,OAAAC,aAAAC,MAAAF,OAAAF,EAAAK,MAAA,EAAAvE,IAjEkDyE,CAAA1B,EAAAe,IAAAnB,IAElD,IAAA+B,GACAC,KACAlB,UAEAlB,aAEA,YACA,SACA,cACA,eACA,WACA,mBACA,gBACA,iBACA,iBACA,WACA,aACA,UACA,WACA,WACA,UACA,qBACA,eACA,iBACA,eACAqC,QAAA,SAAArE,GAA+B,OAAAmE,EAAAnC,QAAAhC,GAAAgC,EAAAhC,IAAA,eAC/B,IAAAiC,YAAAqC,SAAAzC,EAAAsC,GACAnF,QAAA8C,MAAA,EAAAkB,IAqFA,IADA,IAAAH,EAAA,IAAA0B,MAAA,KACA9E,EAAA,EAAeA,EAAA,IACfoD,EAAApD,EAAA,GAAAA,EAAA,GAAAA,EAAA,GAAAA,EAAA,GAAAA,EAAA,GAAAA,EAAA,EAAAA,EAAA,OAAAA,kCCzIAT,EAAA6B,YAAA,EAGA,SAAAa,GACAA,IAAA,eACAA,IAAA,eACAA,IAAA,eACAA,IAAA,eACAA,IAAA,uBACAA,IAAA,gBACAA,IAAA,gBAPA,CAQC1C,EAAA0C,OAAA1C,EAAA0C,UAGD,SAAAC,GACAA,IAAA,mBACAA,IAAA,eACAA,IAAA,mBACAA,IAAA,uBACAA,IAAA,iBACAA,IAAA,mBACAA,IAAA,mBACAA,IAAA,mBACAA,IAAA,iBACAA,IAAA,qBACAA,IAAA,gBACAA,IAAA,gBAZA,CAaC3C,EAAA2C,YAAA3C,EAAA2C,eAGD,SAAAC,GACAA,IAAA,uBACAA,IAAA,iBACAA,IAAA,mBACAA,IAAA,mBAJA,CAKC5C,EAAA4C,eAAA5C,EAAA4C,kBAGD,SAAA4C,GACAA,IAAA,mBACAA,IAAA,uBACAA,IAAA,iBAHA,CAICxF,EAAAwF,WAAAxF,EAAAwF,cAEDxF,EAAAyF,UAAA,MAEAzF,EAAA0F,UAAA,WAGA,SAAAC,GAOAA,IAAA,cAYAA,IAAA,4BA2BAA,IAAA,0BACAA,IAAA,0BACAA,IAAA,0BACAA,IAAA,0BAjDA,CA6KC3F,EAAA2F,SAAA3F,EAAA2F","file":"index.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"asparse\"] = factory();\n\telse\n\t\troot[\"asparse\"] = factory();\n})(typeof self !== 'undefined' ? self : this, function() {\nreturn "," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 0);\n","\"use strict\";\r\nexports.__esModule = true;\r\nvar common_1 = require(\"./common\");\r\nexports.Type = common_1.Type;\r\nexports.SectionId = common_1.SectionId;\r\nexports.ExternalKind = common_1.ExternalKind;\r\n/** Cached compiled parser. */\r\nvar compiled = null;\r\nif (typeof WASM_DATA !== \"string\")\r\n WASM_DATA = require(\"fs\").readFileSync(__dirname + \"/../build/index.wasm\", \"base64\");\r\n/** Parses the contents of a WebAssembly binary according to the specified options. */\r\nfunction parse(binary, options) {\r\n if (!options)\r\n options = {};\r\n // compile the parser if not yet compiled\r\n if (!compiled)\r\n compiled = new WebAssembly.Module(base64_decode(WASM_DATA));\r\n // use the binary as the parser's memory\r\n var nBytes = binary.length;\r\n var nPages = ((nBytes + 0xffff) & ~0xffff) >> 16;\r\n var memory = new WebAssembly.Memory({ initial: nPages });\r\n var buffer = new Uint8Array(memory.buffer);\r\n buffer.set(binary);\r\n // provide a way to read strings from memory\r\n parse.readString = function (offset, length) { return utf8_read(buffer, offset, offset + length); };\r\n // instantiate the parser and return its exports\r\n var imports = {\r\n env: {\r\n memory: memory\r\n },\r\n options: {}\r\n };\r\n [\"onSection\",\r\n \"onType\",\r\n \"onTypeParam\",\r\n \"onTypeReturn\",\r\n \"onImport\",\r\n \"onFunctionImport\",\r\n \"onTableImport\",\r\n \"onMemoryImport\",\r\n \"onGlobalImport\",\r\n \"onMemory\",\r\n \"onFunction\",\r\n \"onTable\",\r\n \"onGlobal\",\r\n \"onExport\",\r\n \"onStart\",\r\n \"onSourceMappingURL\",\r\n \"onModuleName\",\r\n \"onFunctionName\",\r\n \"onLocalName\"\r\n ].forEach(function (name) { return imports.options[name] = options[name] || function () { }; });\r\n var instance = new WebAssembly.Instance(compiled, imports);\r\n instance.exports.parse(0, nBytes);\r\n}\r\nexports.parse = parse;\r\n// see: https://github.com/dcodeIO/protobuf.js/tree/master/lib/utf8\r\nfunction utf8_read(buffer, start, end) {\r\n var len = end - start;\r\n if (len < 1)\r\n return \"\";\r\n var parts = null, chunk = [], i = 0, // char offset\r\n t = 0; // temporary\r\n while (start < end) {\r\n t = buffer[start++];\r\n if (t < 128) {\r\n chunk[i++] = t;\r\n }\r\n else if (t > 191 && t < 224) {\r\n chunk[i++] = (t & 31) << 6 | buffer[start++] & 63;\r\n }\r\n else if (t > 239 && t < 365) {\r\n t = ((t & 7) << 18 | (buffer[start++] & 63) << 12 | (buffer[start++] & 63) << 6 | buffer[start++] & 63) - 0x10000;\r\n chunk[i++] = 0xD800 + (t >> 10);\r\n chunk[i++] = 0xDC00 + (t & 1023);\r\n }\r\n else {\r\n chunk[i++] = (t & 15) << 12 | (buffer[start++] & 63) << 6 | buffer[start++] & 63;\r\n }\r\n if (i > 8191) {\r\n (parts || (parts = [])).push(String.fromCharCode.apply(String, chunk));\r\n i = 0;\r\n }\r\n }\r\n if (parts) {\r\n if (i)\r\n parts.push(String.fromCharCode.apply(String, chunk.slice(0, i)));\r\n return parts.join(\"\");\r\n }\r\n return String.fromCharCode.apply(String, chunk.slice(0, i));\r\n}\r\n// see: https://github.com/dcodeIO/protobuf.js/tree/master/lib/base64\r\nfunction base64_decode(string) {\r\n var length = string.length;\r\n if (length) {\r\n var n = 0, p = length;\r\n while (--p % 4 > 1 && string.charCodeAt(p) === 61)\r\n ++n;\r\n length = Math.ceil(length * 3) / 4 - n;\r\n }\r\n var buffer = new Uint8Array(length);\r\n var j = 0, o = 0, t = 0;\r\n for (var i = 0, k = string.length; i < k;) {\r\n var c = string.charCodeAt(i++);\r\n if (c === 61 && j > 1)\r\n break;\r\n if ((c = s64[c]) === undefined)\r\n throw Error();\r\n switch (j) {\r\n case 0: {\r\n t = c;\r\n j = 1;\r\n break;\r\n }\r\n case 1: {\r\n buffer[o++] = t << 2 | (c & 48) >> 4;\r\n t = c;\r\n j = 2;\r\n break;\r\n }\r\n case 2: {\r\n buffer[o++] = (t & 15) << 4 | (c & 60) >> 2;\r\n t = c;\r\n j = 3;\r\n break;\r\n }\r\n case 3: {\r\n buffer[o++] = (t & 3) << 6 | c;\r\n j = 0;\r\n break;\r\n }\r\n }\r\n }\r\n if (j === 1)\r\n throw Error();\r\n return buffer;\r\n}\r\nvar s64 = new Array(123);\r\nfor (var i = 0; i < 64;)\r\n s64[i < 26 ? i + 65 : i < 52 ? i + 71 : i < 62 ? i - 4 : i - 59 | 43] = i++;\r\n","\"use strict\";\r\n/** Common constants shared between AssemblyScript and TypeScript. */\r\nexports.__esModule = true;\r\n/** WebAssembly types. */\r\nvar Type;\r\n(function (Type) {\r\n Type[Type[\"i32\"] = 127] = \"i32\";\r\n Type[Type[\"i64\"] = 126] = \"i64\";\r\n Type[Type[\"f32\"] = 125] = \"f32\";\r\n Type[Type[\"f64\"] = 124] = \"f64\";\r\n Type[Type[\"anyfunc\"] = 112] = \"anyfunc\";\r\n Type[Type[\"func\"] = 96] = \"func\";\r\n Type[Type[\"none\"] = 64] = \"none\";\r\n})(Type = exports.Type || (exports.Type = {}));\r\n/** WebAssembly section ids. */\r\nvar SectionId;\r\n(function (SectionId) {\r\n SectionId[SectionId[\"Custom\"] = 0] = \"Custom\";\r\n SectionId[SectionId[\"Type\"] = 1] = \"Type\";\r\n SectionId[SectionId[\"Import\"] = 2] = \"Import\";\r\n SectionId[SectionId[\"Function\"] = 3] = \"Function\";\r\n SectionId[SectionId[\"Table\"] = 4] = \"Table\";\r\n SectionId[SectionId[\"Memory\"] = 5] = \"Memory\";\r\n SectionId[SectionId[\"Global\"] = 6] = \"Global\";\r\n SectionId[SectionId[\"Export\"] = 7] = \"Export\";\r\n SectionId[SectionId[\"Start\"] = 8] = \"Start\";\r\n SectionId[SectionId[\"Element\"] = 9] = \"Element\";\r\n SectionId[SectionId[\"Code\"] = 10] = \"Code\";\r\n SectionId[SectionId[\"Data\"] = 11] = \"Data\";\r\n})(SectionId = exports.SectionId || (exports.SectionId = {}));\r\n/** WebAssembly external kinds. */\r\nvar ExternalKind;\r\n(function (ExternalKind) {\r\n ExternalKind[ExternalKind[\"Function\"] = 0] = \"Function\";\r\n ExternalKind[ExternalKind[\"Table\"] = 1] = \"Table\";\r\n ExternalKind[ExternalKind[\"Memory\"] = 2] = \"Memory\";\r\n ExternalKind[ExternalKind[\"Global\"] = 3] = \"Global\";\r\n})(ExternalKind = exports.ExternalKind || (exports.ExternalKind = {}));\r\n/** Name section types. */\r\nvar NameType;\r\n(function (NameType) {\r\n NameType[NameType[\"Module\"] = 0] = \"Module\";\r\n NameType[NameType[\"Function\"] = 1] = \"Function\";\r\n NameType[NameType[\"Local\"] = 2] = \"Local\";\r\n})(NameType = exports.NameType || (exports.NameType = {}));\r\n/** Maximum number of memory pages. */\r\nexports.MAX_PAGES = 0xffff;\r\n/** Maximum number of table elements. */\r\nexports.MAX_ELEMS = 0xffffffff;\r\n/** WebAssembly opcodes. */\r\nvar Opcode;\r\n(function (Opcode) {\r\n // unreachable = 0x00,\r\n // nop = 0x01,\r\n // block = 0x02,\r\n // loop = 0x03,\r\n // if_ = 0x04,\r\n // else_ = 0x05,\r\n Opcode[Opcode[\"end\"] = 11] = \"end\";\r\n // br = 0x0c,\r\n // br_if = 0x0d,\r\n // br_table = 0x0e,\r\n // return_ = 0x0f,\r\n // call = 0x10,\r\n // call_indirect = 0x11,\r\n // drop = 0x1a,\r\n // select = 0x1b,\r\n // get_local = 0x20,\r\n // set_local = 0x21,\r\n // tee_local = 0x22,\r\n Opcode[Opcode[\"get_global\"] = 35] = \"get_global\";\r\n // set_global = 0x24,\r\n // i32_load = 0x28,\r\n // i64_load = 0x29,\r\n // f32_load = 0x2a,\r\n // f64_load = 0x2b,\r\n // i32_load8_s = 0x2c,\r\n // i32_load8_u = 0x2d,\r\n // i32_load16_s = 0x2e,\r\n // i32_load16_u = 0x2f,\r\n // i64_load8_s = 0x30,\r\n // i64_load8_u = 0x31,\r\n // i64_load16_s = 0x32,\r\n // i64_load16_u = 0x33,\r\n // i64_load32_s = 0x34,\r\n // i64_load32_u = 0x35,\r\n // i32_store = 0x36,\r\n // i64_store = 0x37,\r\n // f32_store = 0x38,\r\n // f64_store = 0x39,\r\n // i32_store8 = 0x3a,\r\n // i32_store16 = 0x3b,\r\n // i64_store8 = 0x3c,\r\n // i64_store16 = 0x3d,\r\n // i64_store32 = 0x3e,\r\n // current_memory = 0x3f,\r\n // grow_memory = 0x40,\r\n Opcode[Opcode[\"i32_const\"] = 65] = \"i32_const\";\r\n Opcode[Opcode[\"i64_const\"] = 66] = \"i64_const\";\r\n Opcode[Opcode[\"f32_const\"] = 67] = \"f32_const\";\r\n Opcode[Opcode[\"f64_const\"] = 68] = \"f64_const\";\r\n // i32_eqz = 0x45,\r\n // i32_eq = 0x46,\r\n // i32_ne = 0x47,\r\n // i32_lt_s = 0x48,\r\n // i32_lt_u = 0x49,\r\n // i32_gt_s = 0x4a,\r\n // i32_gt_u = 0x4b,\r\n // i32_le_s = 0x4c,\r\n // i32_le_u = 0x4d,\r\n // i32_ge_s = 0x4e,\r\n // i32_ge_u = 0x4f,\r\n // i64_eqz = 0x50,\r\n // i64_eq = 0x51,\r\n // i64_ne = 0x52,\r\n // i64_lt_s = 0x53,\r\n // i64_lt_u = 0x54,\r\n // i64_gt_s = 0x55,\r\n // i64_gt_u = 0x56,\r\n // i64_le_s = 0x57,\r\n // i64_le_u = 0x58,\r\n // i64_ge_s = 0x59,\r\n // i64_ge_u = 0x5a,\r\n // f32_eq = 0x5b,\r\n // f32_ne = 0x5c,\r\n // f32_lt = 0x5d,\r\n // f32_gt = 0x5e,\r\n // f32_le = 0x5f,\r\n // f32_ge = 0x60,\r\n // f64_eq = 0x61,\r\n // f64_ne = 0x62,\r\n // f64_lt = 0x63,\r\n // f64_gt = 0x64,\r\n // f64_le = 0x65,\r\n // f64_ge = 0x66,\r\n // i32_clz = 0x67,\r\n // i32_ctz = 0x68,\r\n // i32_popcnt = 0x69,\r\n // i32_add = 0x6a,\r\n // i32_sub = 0x6b,\r\n // i32_mul = 0x6c,\r\n // i32_div_s = 0x6d,\r\n // i32_div_u = 0x6e,\r\n // i32_rem_s = 0x6f,\r\n // i32_rem_u = 0x70,\r\n // i32_and = 0x71,\r\n // i32_or = 0x72,\r\n // i32_xor = 0x73,\r\n // i32_shl = 0x74,\r\n // i32_shr_s = 0x75,\r\n // i32_shr_u = 0x76,\r\n // i32_rotl = 0x77,\r\n // i32_rotr = 0x78,\r\n // i64_clz = 0x79,\r\n // i64_ctz = 0x7a,\r\n // i64_popcnt = 0x7b,\r\n // i64_add = 0x7c,\r\n // i64_sub = 0x7d,\r\n // i64_mul = 0x7e,\r\n // i64_div_s = 0x7f,\r\n // i64_div_u = 0x80,\r\n // i64_rem_s = 0x81,\r\n // i64_rem_u = 0x82,\r\n // i64_and = 0x83,\r\n // i64_or = 0x84,\r\n // i64_xor = 0x85,\r\n // i64_shl = 0x86,\r\n // i64_shr_s = 0x87,\r\n // i64_shr_u = 0x88,\r\n // i64_rotl = 0x89,\r\n // i64_rotr = 0x8a,\r\n // f32_abs = 0x8b,\r\n // f32_neg = 0x8c,\r\n // f32_ceil = 0x8d,\r\n // f32_floor = 0x8e,\r\n // f32_trunc = 0x8f,\r\n // f32_nearest = 0x90,\r\n // f32_sqrt = 0x91,\r\n // f32_add = 0x92,\r\n // f32_sub = 0x93,\r\n // f32_mul = 0x94,\r\n // f32_div = 0x95,\r\n // f32_min = 0x96,\r\n // f32_max = 0x97,\r\n // f32_copysign = 0x98,\r\n // f64_abs = 0x99,\r\n // f64_neg = 0x9a,\r\n // f64_ceil = 0x9b,\r\n // f64_floor = 0x9c,\r\n // f64_trunc = 0x9d,\r\n // f64_nearest = 0x9e,\r\n // f64_sqrt = 0x9f,\r\n // f64_add = 0xa0,\r\n // f64_sub = 0xa1,\r\n // f64_mul = 0xa2,\r\n // f64_div = 0xa3,\r\n // f64_min = 0xa4,\r\n // f64_max = 0xa5,\r\n // f64_copysign = 0xa6,\r\n // i32_wrap_i64 = 0xa7,\r\n // i32_trunc_s_f32 = 0xa8,\r\n // i32_trunc_u_f32 = 0xa9,\r\n // i32_trunc_s_f64 = 0xaa,\r\n // i32_trunc_u_f64 = 0xab,\r\n // i64_extend_s_i32 = 0xac,\r\n // i64_extend_u_i32 = 0xad,\r\n // i64_trunc_s_f32 = 0xae,\r\n // i64_trunc_u_f32 = 0xaf,\r\n // i64_trunc_s_f64 = 0xb0,\r\n // i64_trunc_u_f64 = 0xb1,\r\n // f32_convert_s_i32 = 0xb2,\r\n // f32_convert_u_i32 = 0xb3,\r\n // f32_convert_s_i64 = 0xb4,\r\n // f32_convert_u_i64 = 0xb5,\r\n // f32_demote_f64 = 0xb6,\r\n // f64_convert_s_i32 = 0xb7,\r\n // f64_convert_u_i32 = 0xb8,\r\n // f64_convert_s_i64 = 0xb9,\r\n // f64_convert_u_i64 = 0xba,\r\n // f64_promote_f32 = 0xbb,\r\n // i32_reinterpret_f32 = 0xbc,\r\n // i64_reinterpret_f64 = 0xbd,\r\n // f32_reinterpret_i32 = 0xbe,\r\n // f64_reinterpret_i64 = 0xbf\r\n})(Opcode = exports.Opcode || (exports.Opcode = {}));\r\n"],"sourceRoot":""}
\ No newline at end of file
diff --git a/lib/parse/package.json b/lib/parse/package.json
deleted file mode 100644
index f91a68c569..0000000000
--- a/lib/parse/package.json
+++ /dev/null
@@ -1,30 +0,0 @@
-{
- "name": "@assemblyscript/parse",
- "version": "1.0.0",
- "license": "Apache-2.0",
- "main": "index.js",
- "types": "index.d.ts",
- "scripts": {
- "asbuild": "asc assembly/index.ts -O3 -b build/index.wasm -t build/index.wat --importMemory --runtime none --sourceMap",
- "build": "npm run asbuild && webpack --mode production --display-modules",
- "test": "ts-node tests/"
- },
- "files": [
- "package.json",
- "index.d.ts",
- "index.js",
- "index.js.map",
- "src/",
- "README.md"
- ],
- "dependencies": {},
- "devDependencies": {
- "@types/webassembly-js-api": "0.0.1",
- "assemblyscript": "AssemblyScript/assemblyscript",
- "ts-loader": "^5.2.1",
- "ts-node": "^6.2.0",
- "typescript": "^3.1.2",
- "webpack": "^4.20.2",
- "webpack-cli": "^3.1.2"
- }
-}
diff --git a/lib/parse/src/common.ts b/lib/parse/src/common.ts
deleted file mode 100644
index e45100db5f..0000000000
--- a/lib/parse/src/common.ts
+++ /dev/null
@@ -1,225 +0,0 @@
-/** Common constants shared between AssemblyScript and TypeScript. */
-
-/** WebAssembly types. */
-export enum Type {
- i32 = 0x7f,
- i64 = 0x7e,
- f32 = 0x7d,
- f64 = 0x7c,
- anyfunc = 0x70,
- func = 0x60,
- none = 0x40
-}
-
-/** WebAssembly section ids. */
-export enum SectionId {
- Custom = 0,
- Type = 1,
- Import = 2,
- Function = 3,
- Table = 4,
- Memory = 5,
- Global = 6,
- Export = 7,
- Start = 8,
- Element = 9,
- Code = 10,
- Data = 11
-}
-
-/** WebAssembly external kinds. */
-export enum ExternalKind {
- Function = 0,
- Table = 1,
- Memory = 2,
- Global = 3
-}
-
-/** Name section types. */
-export enum NameType {
- Module = 0,
- Function = 1,
- Local = 2
-}
-
-/** Maximum number of memory pages. */
-export const MAX_PAGES = 0xffff;
-
-/** Maximum number of table elements. */
-export const MAX_ELEMS = 0xffffffff;
-
-/** WebAssembly opcodes. */
-export enum Opcode { // just a few of these are actually used
- // unreachable = 0x00,
- // nop = 0x01,
- // block = 0x02,
- // loop = 0x03,
- // if_ = 0x04,
- // else_ = 0x05,
- end = 0x0b,
- // br = 0x0c,
- // br_if = 0x0d,
- // br_table = 0x0e,
- // return_ = 0x0f,
- // call = 0x10,
- // call_indirect = 0x11,
- // drop = 0x1a,
- // select = 0x1b,
- // get_local = 0x20,
- // set_local = 0x21,
- // tee_local = 0x22,
- get_global = 0x23,
- // set_global = 0x24,
- // i32_load = 0x28,
- // i64_load = 0x29,
- // f32_load = 0x2a,
- // f64_load = 0x2b,
- // i32_load8_s = 0x2c,
- // i32_load8_u = 0x2d,
- // i32_load16_s = 0x2e,
- // i32_load16_u = 0x2f,
- // i64_load8_s = 0x30,
- // i64_load8_u = 0x31,
- // i64_load16_s = 0x32,
- // i64_load16_u = 0x33,
- // i64_load32_s = 0x34,
- // i64_load32_u = 0x35,
- // i32_store = 0x36,
- // i64_store = 0x37,
- // f32_store = 0x38,
- // f64_store = 0x39,
- // i32_store8 = 0x3a,
- // i32_store16 = 0x3b,
- // i64_store8 = 0x3c,
- // i64_store16 = 0x3d,
- // i64_store32 = 0x3e,
- // current_memory = 0x3f,
- // grow_memory = 0x40,
- i32_const = 0x41,
- i64_const = 0x42,
- f32_const = 0x43,
- f64_const = 0x44
- // i32_eqz = 0x45,
- // i32_eq = 0x46,
- // i32_ne = 0x47,
- // i32_lt_s = 0x48,
- // i32_lt_u = 0x49,
- // i32_gt_s = 0x4a,
- // i32_gt_u = 0x4b,
- // i32_le_s = 0x4c,
- // i32_le_u = 0x4d,
- // i32_ge_s = 0x4e,
- // i32_ge_u = 0x4f,
- // i64_eqz = 0x50,
- // i64_eq = 0x51,
- // i64_ne = 0x52,
- // i64_lt_s = 0x53,
- // i64_lt_u = 0x54,
- // i64_gt_s = 0x55,
- // i64_gt_u = 0x56,
- // i64_le_s = 0x57,
- // i64_le_u = 0x58,
- // i64_ge_s = 0x59,
- // i64_ge_u = 0x5a,
- // f32_eq = 0x5b,
- // f32_ne = 0x5c,
- // f32_lt = 0x5d,
- // f32_gt = 0x5e,
- // f32_le = 0x5f,
- // f32_ge = 0x60,
- // f64_eq = 0x61,
- // f64_ne = 0x62,
- // f64_lt = 0x63,
- // f64_gt = 0x64,
- // f64_le = 0x65,
- // f64_ge = 0x66,
- // i32_clz = 0x67,
- // i32_ctz = 0x68,
- // i32_popcnt = 0x69,
- // i32_add = 0x6a,
- // i32_sub = 0x6b,
- // i32_mul = 0x6c,
- // i32_div_s = 0x6d,
- // i32_div_u = 0x6e,
- // i32_rem_s = 0x6f,
- // i32_rem_u = 0x70,
- // i32_and = 0x71,
- // i32_or = 0x72,
- // i32_xor = 0x73,
- // i32_shl = 0x74,
- // i32_shr_s = 0x75,
- // i32_shr_u = 0x76,
- // i32_rotl = 0x77,
- // i32_rotr = 0x78,
- // i64_clz = 0x79,
- // i64_ctz = 0x7a,
- // i64_popcnt = 0x7b,
- // i64_add = 0x7c,
- // i64_sub = 0x7d,
- // i64_mul = 0x7e,
- // i64_div_s = 0x7f,
- // i64_div_u = 0x80,
- // i64_rem_s = 0x81,
- // i64_rem_u = 0x82,
- // i64_and = 0x83,
- // i64_or = 0x84,
- // i64_xor = 0x85,
- // i64_shl = 0x86,
- // i64_shr_s = 0x87,
- // i64_shr_u = 0x88,
- // i64_rotl = 0x89,
- // i64_rotr = 0x8a,
- // f32_abs = 0x8b,
- // f32_neg = 0x8c,
- // f32_ceil = 0x8d,
- // f32_floor = 0x8e,
- // f32_trunc = 0x8f,
- // f32_nearest = 0x90,
- // f32_sqrt = 0x91,
- // f32_add = 0x92,
- // f32_sub = 0x93,
- // f32_mul = 0x94,
- // f32_div = 0x95,
- // f32_min = 0x96,
- // f32_max = 0x97,
- // f32_copysign = 0x98,
- // f64_abs = 0x99,
- // f64_neg = 0x9a,
- // f64_ceil = 0x9b,
- // f64_floor = 0x9c,
- // f64_trunc = 0x9d,
- // f64_nearest = 0x9e,
- // f64_sqrt = 0x9f,
- // f64_add = 0xa0,
- // f64_sub = 0xa1,
- // f64_mul = 0xa2,
- // f64_div = 0xa3,
- // f64_min = 0xa4,
- // f64_max = 0xa5,
- // f64_copysign = 0xa6,
- // i32_wrap_i64 = 0xa7,
- // i32_trunc_s_f32 = 0xa8,
- // i32_trunc_u_f32 = 0xa9,
- // i32_trunc_s_f64 = 0xaa,
- // i32_trunc_u_f64 = 0xab,
- // i64_extend_s_i32 = 0xac,
- // i64_extend_u_i32 = 0xad,
- // i64_trunc_s_f32 = 0xae,
- // i64_trunc_u_f32 = 0xaf,
- // i64_trunc_s_f64 = 0xb0,
- // i64_trunc_u_f64 = 0xb1,
- // f32_convert_s_i32 = 0xb2,
- // f32_convert_u_i32 = 0xb3,
- // f32_convert_s_i64 = 0xb4,
- // f32_convert_u_i64 = 0xb5,
- // f32_demote_f64 = 0xb6,
- // f64_convert_s_i32 = 0xb7,
- // f64_convert_u_i32 = 0xb8,
- // f64_convert_s_i64 = 0xb9,
- // f64_convert_u_i64 = 0xba,
- // f64_promote_f32 = 0xbb,
- // i32_reinterpret_f32 = 0xbc,
- // i64_reinterpret_f64 = 0xbd,
- // f32_reinterpret_i32 = 0xbe,
- // f64_reinterpret_i64 = 0xbf
-}
diff --git a/lib/parse/src/index.ts b/lib/parse/src/index.ts
deleted file mode 100644
index ebd48a3541..0000000000
--- a/lib/parse/src/index.ts
+++ /dev/null
@@ -1,165 +0,0 @@
-import { Type, SectionId, ExternalKind } from "./common";
-export { Type, SectionId, ExternalKind };
-
-/** Cached compiled parser. */
-var compiled: WebAssembly.Module | null = null;
-
-declare var WASM_DATA: string; // injected by webpack
-if (typeof WASM_DATA !== "string") {
- // eslint-disable-next-line @typescript-eslint/no-var-requires
- WASM_DATA = require("fs").readFileSync(__dirname + "/../build/index.wasm", "base64");
-}
-
-/** Options specified to the parser. The `onSection` callback determines the sections being evaluated in detail. */
-export interface ParseOptions {
- /** Called with each section in the binary. Returning `true` evaluates the section. */
- onSection?(id: SectionId, payloadOff: number, payloadLen: number, nameOff: number, nameLen: number): boolean;
- /** Called with each function type if the type section is evaluated. */
- onType?(index: number, form: number): void;
- /** Called with each function parameter if the type section is evaluated. */
- onTypeParam?(index: number, paramIndex: number, paramType: Type): void;
- /** Called with each function return type if the type section is evaluated. */
- onTypeReturn?(index: number, returnIndex: number, returnType: Type): void;
- /** Called with each import if the import section is evaluated. */
- onImport?(index: number, kind: ExternalKind, moduleOff: number, moduleLen: number, fieldOff: number, fieldLen: number): void;
- /** Called with each function import if the import section is evaluated. */
- onFunctionImport?(index: number, type: number): void;
- /** Called with each table import if the import section is evaluated. */
- onTableImport?(index: number, type: Type, initial: number, maximum: number, flags: number): void;
- /** Called with each memory import if the import section is evaluated. */
- onMemoryImport?(index: number, initial: number, maximum: number, flags: number): void;
- /** Called with each global import if the import section is evaluated. */
- onGlobalImport?(index: number, type: Type, mutability: number): void;
- /** Called with each memory if the memory section is evaluated.*/
- onMemory?(index: number, initial: number, maximum: number, flags: number): void;
- /** Called with each function if the function section is evaluated. */
- onFunction?(index: number, typeIndex: number): void;
- /** Called with each table if the table section is evaluated.*/
- onTable?(index: number, type: Type, initial: number, maximum: number, flags: number): void;
- /** Called with each global if the global section is evaluated. */
- onGlobal?(index: number, type: Type, mutability: number): void;
- /** Called with the start function index if the start section is evaluated. */
- onStart?(index: number): void;
- /** Called with each export if the export section is evaluated. */
- onExport?(index: number, kind: ExternalKind, kindIndex: number, nameOff: number, nameLen: number): void;
- /** Called with the source map URL if the 'sourceMappingURL' section is evaluated. */
- onSourceMappingURL?(offset: number, length: number): void;
- /** Called with the module name if present and the 'name' section is evaluated. */
- onModuleName?(offset: number, length: number): void;
- /** Called with each function name if present and the 'name' section is evaluated. */
- onFunctionName?(index: number, offset: number, length: number): void;
- /** Called with each local name if present and the 'name' section is evaluated. */
- onLocalName?(funcIndex: number, index: number, offset: number, length: number): void;
-}
-
-/** Parses the contents of a WebAssembly binary according to the specified options. */
-export function parse(binary: Uint8Array, options?: ParseOptions): void {
- if (!options) options = {};
-
- // compile the parser if not yet compiled
- if (!compiled) compiled = new WebAssembly.Module(base64_decode(WASM_DATA));
-
- // use the binary as the parser's memory
- var nBytes = binary.length;
- var nPages = ((nBytes + 0xffff) & ~0xffff) >> 16;
- var memory = new WebAssembly.Memory({ initial: nPages });
- var buffer = new Uint8Array(memory.buffer);
- buffer.set(binary);
-
- // provide a way to read strings from memory
- parse.readString = (offset: number, length: number): string => utf8_read(buffer, offset, offset + length);
-
- // instantiate the parser and return its exports
- var imports = {
- env: {
- memory
- },
- options: {}
- };
- [ "onSection",
- "onType",
- "onTypeParam",
- "onTypeReturn",
- "onImport",
- "onFunctionImport",
- "onTableImport",
- "onMemoryImport",
- "onGlobalImport",
- "onMemory",
- "onFunction",
- "onTable",
- "onGlobal",
- "onExport",
- "onStart",
- "onSourceMappingURL",
- "onModuleName",
- "onFunctionName",
- "onLocalName"
- ].forEach((name: string) => imports.options[name] = options[name] || function() { /* nop */ });
- var instance = new WebAssembly.Instance(compiled, imports);
- instance.exports.parse(0, nBytes);
-}
-
-export declare namespace parse {
- /** Utility function for reading an UTF8 encoded string from memory while parsing. */
- function readString(offset: number, length: number): string;
-}
-
-// see: https://github.com/dcodeIO/protobuf.js/tree/master/lib/utf8
-function utf8_read(buffer: Uint8Array, start: number, end: number): string {
- var len = end - start;
- if (len < 1) return "";
- var parts: string[] | null = null, chunk: number[] = [];
- var i = 0, t = 0; // char offset and temporary
- while (start < end) {
- t = buffer[start++];
- if (t < 128) {
- chunk[i++] = t;
- } else if (t > 191 && t < 224) {
- chunk[i++] = (t & 31) << 6 | buffer[start++] & 63;
- } else if (t > 239 && t < 365) {
- t = ((t & 7) << 18 | (buffer[start++] & 63) << 12 | (buffer[start++] & 63) << 6 | buffer[start++] & 63) - 0x10000;
- chunk[i++] = 0xD800 + (t >> 10);
- chunk[i++] = 0xDC00 + (t & 1023);
- } else {
- chunk[i++] = (t & 15) << 12 | (buffer[start++] & 63) << 6 | buffer[start++] & 63;
- }
- if (i > 8191) {
- (parts || (parts = [])).push(String.fromCharCode(...chunk));
- i = 0;
- }
- }
- if (parts) {
- if (i) parts.push(String.fromCharCode(...chunk.slice(0, i)));
- return parts.join("");
- }
- return String.fromCharCode(...chunk.slice(0, i));
-}
-
-// see: https://github.com/dcodeIO/protobuf.js/tree/master/lib/base64
-function base64_decode(string: string): Uint8Array {
- var length = string.length;
- if (length) {
- let n = 0, p = length;
- while (--p % 4 > 1 && string.charCodeAt(p) === 61) ++n;
- length = Math.ceil(length * 3) / 4 - n;
- }
- var buffer = new Uint8Array(length);
- var j = 0, o = 0, t = 0;
- for (let i = 0, k = string.length; i < k;) {
- let c = string.charCodeAt(i++);
- if (c === 61 && j > 1) break;
- if ((c = s64[c]) === undefined) throw Error();
- switch (j) {
- case 0: { t = c; j = 1; break; }
- case 1: { buffer[o++] = t << 2 | (c & 48) >> 4; t = c; j = 2; break; }
- case 2: { buffer[o++] = (t & 15) << 4 | (c & 60) >> 2; t = c; j = 3; break; }
- case 3: { buffer[o++] = (t & 3) << 6 | c; j = 0; break; }
- }
- }
- if (j === 1) throw Error();
- return buffer;
-}
-
-var s64 = new Array(123);
-for (let i = 0; i < 64;) s64[i < 26 ? i + 65 : i < 52 ? i + 71 : i < 62 ? i - 4 : i - 59 | 43] = i++;
diff --git a/lib/parse/src/tsconfig.json b/lib/parse/src/tsconfig.json
deleted file mode 100644
index 6aaa787469..0000000000
--- a/lib/parse/src/tsconfig.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "compilerOptions": {
- "module": "commonjs"
- },
- "include": [
- "./**/*.ts"
- ]
-}
diff --git a/lib/parse/tests/index.ts b/lib/parse/tests/index.ts
deleted file mode 100644
index 3ca12d4c62..0000000000
--- a/lib/parse/tests/index.ts
+++ /dev/null
@@ -1,121 +0,0 @@
-import * as fs from "fs";
-import {
- Type,
- SectionId,
- ExternalKind,
- parse
-} from "..";
-
-function onSection(id: SectionId, offset: number, length: number, nameOffset: number, nameLength: number): boolean {
- var name = id == 0 ? "'" + parse.readString(nameOffset, nameLength) + "'" : SectionId[id];
- console.log(name + " section at " + offset + ".." + (offset + length));
- return true;
-}
-
-function onType(index: number, form: Type): void {
- console.log("- FunctionType[" + index + "]: " + Type[form]);
-}
-
-function onTypeParam(index: number, paramIndex: number, paramType: Type): void {
- console.log(" > param[" + paramIndex + "] -> " + Type[paramType]);
-}
-
-function onTypeReturn(index: number, returnIndex: number, returnType: Type): void {
- console.log(" > return[" + returnIndex + "] -> " + Type[returnType]);
-}
-
-function onImport(index: number, kind: ExternalKind, moduleOff: number, moduleLen: number, fieldOff: number, fieldLen: number): void {
- var moduleName = parse.readString(moduleOff, moduleLen);
- var fieldName = parse.readString(fieldOff, fieldLen);
- console.log("- Import[" + index + "]: '" + moduleName + "." + fieldName + "'");
-}
-
-function onFunctionImport(funIndex: number, type: number): void {
- console.log(" - Function[" + funIndex + "] -> FunctionType[" + type + "]");
-}
-
-function onTableImport(tblIndex: number, type: Type, initial: number, maximum: number, flags: number): void {
- console.log(" - Table[" + tblIndex + "] -> " + Type[type] + ": initial=" + initial + ", maximum=" + maximum);
-}
-
-function onMemoryImport(memIndex: number, initial: number, maximum: number, flags: number): void {
- console.log(" - Memory[" + memIndex + "]: initial=" + initial + ", maximum=" + maximum);
-}
-
-function onGlobalImport(gloIndex: number, type: Type, mutability: number): void {
- console.log(" - Global[" + gloIndex + "]: " + (mutability & 1 ? "mutable " : "const ") + Type[type]);
-}
-
-function onMemory(memIndex: number, initial: number, maximum: number, flags: number): void {
- console.log("- Memory[" + memIndex + "]: initial=" + initial + ", maximum=" + maximum);
-}
-
-function onFunction(funIndex: number, typeIndex: number): void {
- console.log("- Function[" + funIndex + "] -> FunctionType[" + typeIndex + "]");
-}
-
-function onTable(tblIndex: number, type: number, initial: number, maximum: number, flags: number): void {
- console.log("- Table[" + tblIndex + "] -> " + Type[type] + ": initial=" + initial + ", maximum=" + (maximum >>> 0));
-}
-
-function onGlobal(gloIndex: number, type: Type, mutability: number): void {
- console.log("- Global[" + gloIndex + "]: " + (mutability & 1 ? "mutable " : "const ") + Type[type]);
-}
-
-function onStart(index: number): void {
- console.log("- Start: Function[" + index + "]");
-}
-
-function onExport(index: number, kind: ExternalKind, kindIndex: number, fieldOffset: number, fieldLength: number): void {
- var field = parse.readString(fieldOffset, fieldLength);
- console.log("- Export[" + index + "], '" + field + "' -> " + ExternalKind[kind] + "[" + kindIndex + "]");
-}
-
-function onSourceMappingURL(offset: number, length: number): void {
- var url = parse.readString(offset, length);
- console.log("- sourceMap: " + url);
-}
-
-function onModuleName(offset: number, length: number): void {
- var name = parse.readString(offset, length);
- console.log("- moduleName: " + name);
-}
-
-function onFunctionName(index: number, offset: number, length: number): void {
- var name = parse.readString(offset, length);
- console.log(" - Function[" + index + "] name: " + name);
-}
-
-function onLocalName(funcIndex: number, index: number, offset: number, length: number): void {
- var name = parse.readString(offset, length);
- console.log(" - Function[" + funcIndex + "].local[" + index + "] name: " + name);
-}
-
-[ "../build/index.wasm",
- "libm.wasm"
-].forEach((filename: string): void => {
- const binary: Uint8Array = fs.readFileSync(__dirname + "/" + filename);
- console.log("Testing '" + filename + "' ...");
- parse(binary, {
- onSection,
- onType,
- onTypeParam,
- onTypeReturn,
- onImport,
- onFunctionImport,
- onTableImport,
- onMemoryImport,
- onGlobalImport,
- onMemory,
- onFunction,
- onTable,
- onGlobal,
- onStart,
- onExport,
- onSourceMappingURL,
- onModuleName,
- onFunctionName,
- onLocalName
- });
- console.log();
-});
diff --git a/lib/parse/tests/libm.wasm b/lib/parse/tests/libm.wasm
deleted file mode 100644
index 44467da623..0000000000
Binary files a/lib/parse/tests/libm.wasm and /dev/null differ
diff --git a/lib/parse/webpack.config.js b/lib/parse/webpack.config.js
deleted file mode 100644
index 61fee7db6f..0000000000
--- a/lib/parse/webpack.config.js
+++ /dev/null
@@ -1,36 +0,0 @@
-const fs = require("fs");
-const webpack = require("webpack");
-
-const wasmData = fs.readFileSync(__dirname + "/build/index.wasm");
-
-module.exports = {
- entry: [ "./src/index.ts" ],
- module: {
- rules: [
- {
- test: /\.ts$/,
- use: "ts-loader",
- exclude: /node_modules/
- }
- ]
- },
- resolve: {
- extensions: [ ".ts", ".js" ]
- },
- node: {
- fs: false
- },
- output: {
- filename: "index.js",
- path: __dirname,
- library: "asparse",
- libraryTarget: "umd",
- globalObject: "typeof self !== 'undefined' ? self : this"
- },
- plugins: [
- new webpack.DefinePlugin({
- WASM_DATA: JSON.stringify(wasmData.toString("base64"))
- })
- ],
- devtool: "source-map"
-};
diff --git a/lib/rtrace/README.md b/lib/rtrace/README.md
index 27635a6824..622f41a1fd 100644
--- a/lib/rtrace/README.md
+++ b/lib/rtrace/README.md
@@ -5,7 +5,7 @@ A tiny utility to sanitize the AssemblyScript runtime. Records allocations and f
Instructions
------------
-Compile your module that uses the full or half runtime with `-use ASC_RTRACE=1 --explicitStart` and include an instance of this module as the import named `rtrace`.
+Compile your module that uses the full or half runtime with `-use ASC_RTRACE=1 --exportStart _initialize` and include an instance of this module as the import named `rtrace`.
```js
const rtrace = new Rtrace({
@@ -17,7 +17,7 @@ const rtrace = new Rtrace({
},
getMemory() {
// obtain the module's memory,
- // e.g. with --explicitStart:
+ // e.g. using --exportStart:
return instance.exports.memory;
}
});
@@ -27,7 +27,7 @@ const { module, instance } = await WebAssembly.instantiate(...,
...imports...
})
);
-instance.exports._start();
+instance.exports._initialize();
...
if (rtrace.active) {
diff --git a/lib/rtrace/index.js b/lib/rtrace/index.js
index 7e04b5f483..44999712e2 100644
--- a/lib/rtrace/index.js
+++ b/lib/rtrace/index.js
@@ -93,7 +93,7 @@ export class Rtrace {
initial: ((this.memory.buffer.byteLength + PAGE_MASK) & ~PAGE_MASK) >>> PAGE_SIZE_BITS
});
} else {
- var diff = this.memory.buffer.byteLength - this.shadow.buffer.byteLength;
+ let diff = this.memory.buffer.byteLength - this.shadow.buffer.byteLength;
if (diff > 0) this.shadow.grow(diff >>> 16);
}
}
@@ -105,10 +105,10 @@ export class Rtrace {
if (info.ptr < this.shadowStart) {
this.shadowStart = info.ptr;
}
- var len = info.size >>> PTR_SIZE_BITS;
- var view = new PTR_VIEW(this.shadow.buffer, info.ptr, len);
- var errored = false;
- var start = oldSize >>> PTR_SIZE_BITS;
+ let len = info.size >>> PTR_SIZE_BITS;
+ let view = new PTR_VIEW(this.shadow.buffer, info.ptr, len);
+ let errored = false;
+ let start = oldSize >>> PTR_SIZE_BITS;
for (let i = 0; i < start; ++i) {
if (view[i] != info.ptr && !errored) {
this.onerror(Error("shadow region mismatch: " + view[i] + " != " + info.ptr), info);
@@ -128,10 +128,10 @@ export class Rtrace {
/** Unmarks a block's presence in shadow memory. */
unmarkShadow(info, oldSize = info.size) {
assert(this.shadow && this.shadow.byteLength == this.memory.byteLength);
- var len = oldSize >>> PTR_SIZE_BITS;
- var view = new PTR_VIEW(this.shadow.buffer, info.ptr, len);
- var errored = false;
- var start = 0;
+ let len = oldSize >>> PTR_SIZE_BITS;
+ let view = new PTR_VIEW(this.shadow.buffer, info.ptr, len);
+ let errored = false;
+ let start = 0;
if (oldSize != info.size) {
assert(oldSize > info.size);
start = info.size >>> PTR_SIZE_BITS;
@@ -149,7 +149,7 @@ export class Rtrace {
accessShadow(ptr, size, isLoad, isRT) {
this.syncShadow();
if (ptr < this.shadowStart) return;
- var value = new Uint32Array(this.shadow.buffer, ptr & ~PTR_MASK, 1)[0];
+ let value = new Uint32Array(this.shadow.buffer, ptr & ~PTR_MASK, 1)[0];
if (value != 0) return;
if (!isRT) {
let stack = trimStacktrace(new Error().stack, 2);
@@ -211,7 +211,7 @@ export class Rtrace {
onalloc(ptr) {
this.syncShadow();
++this.allocCount;
- var info = this.getBlockInfo(ptr);
+ let info = this.getBlockInfo(ptr);
if (this.blocks.has(ptr)) {
this.onerror(Error("duplicate alloc: " + ptr), info);
} else {
@@ -247,8 +247,8 @@ export class Rtrace {
onmove(oldPtr, newPtr) {
this.syncShadow();
++this.moveCount;
- var oldInfo = this.getBlockInfo(oldPtr);
- var newInfo = this.getBlockInfo(newPtr);
+ let oldInfo = this.getBlockInfo(oldPtr);
+ let newInfo = this.getBlockInfo(newPtr);
if (!this.blocks.has(oldPtr)) {
this.onerror(Error("orphaned move (old): " + oldPtr), oldInfo);
} else {
@@ -285,7 +285,7 @@ export class Rtrace {
onfree(ptr) {
this.syncShadow();
++this.freeCount;
- var info = this.getBlockInfo(ptr);
+ let info = this.getBlockInfo(ptr);
if (!this.blocks.has(ptr)) {
this.onerror(Error("orphaned free: " + ptr), info);
} else {
@@ -323,7 +323,7 @@ export class Rtrace {
}
onyield(total) {
- var pause = hrtime() - this.interruptStart;
+ let pause = hrtime() - this.interruptStart;
if (pause >= 1) console.log("interrupted for " + pause.toFixed(1) + "ms");
this.plot(total, pause);
}
diff --git a/lib/rtrace/tlsfvis.html b/lib/rtrace/tlsfvis.html
index aa359833a3..16c022b270 100644
--- a/lib/rtrace/tlsfvis.html
+++ b/lib/rtrace/tlsfvis.html
@@ -12,7 +12,7 @@
var exports;
var ROOT;
var U32;
-fetch("untouched.wasm").then(result =>
+fetch("debug.wasm").then(result =>
result.arrayBuffer()
).then(buffer =>
WebAssembly.instantiate(buffer, {
@@ -27,7 +27,7 @@
})
).then(result => {
exports = result.instance.exports;
- if (exports._start) exports._start();
+ if (exports._initialize) exports._initialize();
U32 = new Uint32Array(exports.memory.buffer);
var first = exports.__alloc(255);
exports.__free(first);
@@ -169,8 +169,8 @@
TLSF visualizer
-
- Notes:
+
+
Notes:
It is expected that there is exactly one block on initialization. This is the remaining space (< 64K) within the last page after static data.
It is expected that if two adjacent blocks of size K are freed, the merged block doesn't go into the first level list for K*2 because its size is actually larger than that (K + OVERHEAD + K).
@@ -178,7 +178,7 @@
TLSF visualizer
It is expected that after other operations have already been performed, being able to allocate 1GB can't be guaranteed anymore, even if there should be enough space left in absolute terms, if prior subdivision prevents it.
It is expected that the second level 0 in first level 0 isn't ever used due to alignment guarantees. Smallest block is 32 bytes (16 bytes overhead + 16 bytes payload if used, respectively linking information if free) in this implementation.
-
+
Implementation constants:? bits alignment, ? bits first level, ? bits second level, ? B overhead
First level bitmap
@@ -229,7 +229,6 @@
Allocator
-
Segments
Allocations performed above are tracked here so you can free them again. Note that TLSF alone does not keep track of used blocks (unless free'd and put in a free list again). It is expected that adjacent free blocks become merged automatically.