diff --git a/package-lock.json b/package-lock.json index f31a860..4b42224 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1805,13 +1805,14 @@ "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=" }, "as-pect": { - "version": "github:jtenner/as-pect#acc1d30a6741cf93d024898ccfd01e58c50446db", + "version": "github:jtenner/as-pect#88b80ab69401113a215af31555279d2b585a9df2", "from": "github:jtenner/as-pect", "dev": true, "requires": { "assemblyscript": "github:assemblyscript/assemblyscript", "chalk": "^2.4.2", "glob": "^7.1.3", + "mathjs": "^5.9.0", "ts-node": "^6.2.0", "yargs-parser": "^13.0.0" }, @@ -2760,6 +2761,12 @@ "integrity": "sha512-tK69D7oNXXqUW3ZNo/z7NXTEz22TCF0pTE+YF9cxvaAM9XnkLo1fV621xCLrRR6aevJlKxExkss0vWqUCUpqdg==", "dev": true }, + "complex.js": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/complex.js/-/complex.js-2.0.11.tgz", + "integrity": "sha512-6IArJLApNtdg1P1dFtn3dnyzoZBEF0MwMnrfF1exSBRpZYoy4yieMkpZhQDC0uwctw48vii0CFVyHfpgZ/DfGw==", + "dev": true + }, "component-emitter": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", @@ -3280,6 +3287,12 @@ } } }, + "decimal.js": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.1.1.tgz", + "integrity": "sha512-vEEgyk1fWVEnv7lPjkNedAIjzxQDue5Iw4FeX4UkNUDSVyD/jZTD0Bw2kAO7k6iyyJRAhM9oxxI0D1ET6k0Mmg==", + "dev": true + }, "decode-uri-component": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", @@ -3756,6 +3769,12 @@ "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", "dev": true }, + "escape-latex": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/escape-latex/-/escape-latex-1.2.0.tgz", + "integrity": "sha512-nV5aVWW1K0wEiUIEdZ4erkGGH8mDxGyxSeqPzRNtWP7ataw+/olFObw7hujFWlVjNsaDFw5VZ5NzVSIqRgfTiw==", + "dev": true + }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", @@ -4288,6 +4307,12 @@ "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", "dev": true }, + "fraction.js": { + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.0.12.tgz", + "integrity": "sha512-8Z1K0VTG4hzYY7kA/1sj4/r1/RWLBD3xwReT/RCrUCbzPszjNQCCsy3ktkU/eaEqX3MYa4pY37a52eiBlPMlhA==", + "dev": true + }, "fragment-cache": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", @@ -6168,6 +6193,12 @@ "handlebars": "^4.1.0" } }, + "javascript-natural-sort": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz", + "integrity": "sha1-+eIwPUUH9tdDVac2ZNFED7Wg71k=", + "dev": true + }, "jest": { "version": "24.1.0", "resolved": "https://registry.npmjs.org/jest/-/jest-24.1.0.tgz", @@ -7135,6 +7166,22 @@ "object-visit": "^1.0.0" } }, + "mathjs": { + "version": "5.9.0", + "resolved": "https://registry.npmjs.org/mathjs/-/mathjs-5.9.0.tgz", + "integrity": "sha512-f1xmJklkTCr48y023cFy/ZSoVzOfgHp1gutvebi/Vv5RLly6j8G9T2/XHkfXewZKcwPDbhBkFEYljaCjudxulQ==", + "dev": true, + "requires": { + "complex.js": "2.0.11", + "decimal.js": "10.1.1", + "escape-latex": "1.2.0", + "fraction.js": "4.0.12", + "javascript-natural-sort": "0.7.1", + "seed-random": "2.2.0", + "tiny-emitter": "2.1.0", + "typed-function": "1.1.0" + } + }, "md5.js": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", @@ -9033,6 +9080,12 @@ "ajv-keywords": "^3.1.0" } }, + "seed-random": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/seed-random/-/seed-random-2.2.0.tgz", + "integrity": "sha1-KpsZ4lCoFwmSMaW5mk2vgLf77VQ=", + "dev": true + }, "select-hose": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", @@ -9916,6 +9969,12 @@ "setimmediate": "^1.0.4" } }, + "tiny-emitter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz", + "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==", + "dev": true + }, "tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", @@ -10125,6 +10184,12 @@ "mime-types": "~2.1.18" } }, + "typed-function": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/typed-function/-/typed-function-1.1.0.tgz", + "integrity": "sha512-TuQzwiT4DDg19beHam3E66oRXhyqlyfgjHB/5fcvsRXbfmWPJfto9B4a0TBdTrQAPGlGmXh/k7iUI+WsObgORA==", + "dev": true + }, "typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", diff --git a/package.json b/package.json index 718330d..d8eb335 100644 --- a/package.json +++ b/package.json @@ -4,14 +4,16 @@ "description": "A set of runtime tools for WebAssembly and AssemblyScript", "main": "dist/index.js", "scripts": { - "test": "jest", + "test:jest": "jest", "test:as": "asp", + "test": "npm-run-all test:jest test:as", "check": "tsc --noEmit", "bootstrap": "lerna bootstrap && npm run linkDev", "clean": "lerna clean -y", + "clean:soft": "lerna exec \"rm -rf node_modules/**/node_modules\" ", "linkDev": "lerna exec \"ldev\"", - "ci": "npm-run-all clean bootstrap check ci:test", - "ci:test": "npm run test -- -i || npm run test -- -i" + "ci": "npm-run-all clean bootstrap check ci:test test:as", + "ci:test": "npm run test:jest -- -i || npm run test:jest -- -i" }, "repository": { "type": "git", diff --git a/packages/as-node/package-lock.json b/packages/as-node/package-lock.json index e4c1e38..d91689b 100644 --- a/packages/as-node/package-lock.json +++ b/packages/as-node/package-lock.json @@ -25,28 +25,44 @@ "requires": { "@types/node": "^10.12.24", "@types/webassembly-js-api": "0.0.1", + "as-pect": "github:jtenner/as-pect", "assemblyscript": "github:willemneal/assemblyscript#b7d8e1300a578fb76ff25f9dfab9de8c5a1cde94" + } + }, + "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==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=" + }, + "as-pect": { + "version": "github:jtenner/as-pect#acc1d30a6741cf93d024898ccfd01e58c50446db", + "from": "github:jtenner/as-pect", + "requires": { + "assemblyscript": "github:assemblyscript/assemblyscript", + "chalk": "^2.4.2", + "glob": "^7.1.3", + "ts-node": "^6.2.0", + "yargs-parser": "^13.0.0" }, "dependencies": { - "as-pect": { - "version": "github:jtenner/as-pect#acc1d30a6741cf93d024898ccfd01e58c50446db", - "from": "github:jtenner/as-pect#acc1d30a6741cf93d024898ccfd01e58c50446db", + "assemblyscript": { + "version": "github:assemblyscript/assemblyscript#36040d5b5312f19a025782b5e36663823494c2f3", + "from": "github:assemblyscript/assemblyscript", "requires": { - "assemblyscript": "github:assemblyscript/assemblyscript", - "glob": "^7.1.3" - }, - "dependencies": { - "assemblyscript": { - "version": "github:assemblyscript/assemblyscript#36040d5b5312f19a025782b5e36663823494c2f3", - "from": "github:assemblyscript/assemblyscript", - "requires": { - "@protobufjs/utf8": "^1.1.0", - "glob": "^7.1.3", - "long": "^4.0.0", - "opencollective-postinstall": "^2.0.0", - "source-map-support": "^0.5.11" - } - } + "@protobufjs/utf8": "^1.1.0", + "binaryen": "77.0.0-nightly.20190407", + "glob": "^7.1.3", + "long": "^4.0.0", + "opencollective-postinstall": "^2.0.0", + "source-map-support": "^0.5.11" } } } @@ -75,6 +91,11 @@ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" }, + "binaryen": { + "version": "77.0.0-nightly.20190407", + "resolved": "https://registry.npmjs.org/binaryen/-/binaryen-77.0.0-nightly.20190407.tgz", + "integrity": "sha512-1mxYNvQ0xywMe582K7V6Vo2zzhZZxMTeGHH8aE/+/AND8f64D8Q1GThVY3RVRwGY/4p+p95ccw9Xbw2ovFXRIg==" + }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -89,11 +110,54 @@ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "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==", + "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": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + }, + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -112,6 +176,11 @@ "path-is-absolute": "^1.0.0" } }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -131,6 +200,11 @@ "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" }, + "make-error": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", + "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==" + }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", @@ -139,6 +213,26 @@ "brace-expansion": "^1.1.7" } }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "requires": { + "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + } + } + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -171,10 +265,47 @@ "source-map": "^0.6.0" } }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + }, + "ts-node": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-6.2.0.tgz", + "integrity": "sha512-ZNT+OEGfUNVMGkpIaDJJ44Zq3Yr0bkU/ugN1PHbU+/01Z7UV1fsELRiTx1KuQNvQ1A3pGh3y25iYF6jXgxV21A==", + "requires": { + "arrify": "^1.0.0", + "buffer-from": "^1.1.0", + "diff": "^3.1.0", + "make-error": "^1.1.1", + "minimist": "^1.2.0", + "mkdirp": "^0.5.1", + "source-map-support": "^0.5.6", + "yn": "^2.0.0" + } + }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "yargs-parser": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.0.0.tgz", + "integrity": "sha512-w2LXjoL8oRdRQN+hOyppuXs+V/fVAYtpcrRxZuF7Kt/Oc+Jr2uAcVntaUTNT6w5ihoWfFDpNY8CPx1QskxZ/pw==", + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "yn": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", + "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=" } } } diff --git a/packages/assemblyscript/assembly/__tests__/as-pect.d.ts b/packages/assemblyscript/assembly/__tests__/as-pect.d.ts deleted file mode 100644 index 722164e..0000000 --- a/packages/assemblyscript/assembly/__tests__/as-pect.d.ts +++ /dev/null @@ -1,410 +0,0 @@ - -/** - * This function creates a test group in the test loader. - * - * @param {string} description - This is the name of the test group. - * @param {() => void} callback - A function that contains all of the closures for this test group. - * - * @example - * describe("my test suite", (): void => { - * // put your tests here - * }); - */ -declare function describe(description: string, callback: () => void): void; - -declare function test(): void; -/** - * This function creates a test inside the given test group. It must be placed inside a describe - * block. - * - * @param {string} description - This is the name of the test, and should describe a behavior. - * @param {() => void} callback - A function that contains a set of expectations for this test. - * - * @example - * describe("the meaning of life", (): void => { - * it("should be 42", (): void => { - * // put your expectations here - * expect(29 + 13).toBe(42); - * }); - * }); - */ -declare function it(description: string, callback: () => void): void; - -/** - * A test that does not run, and is longhand equivalent to using todo function without a - * callback. This test does not get run and is reported like a todo. - * - * @param {string} description - This is the name of the test, and should describe a behavior. - * @param {() => void} callback - A function that contains a set of expectations for this test. - */ -declare function xit(description: string, callback: () => void): void; - -/** - * A test that does not run, and is longhand equivalent to using todo function without a - * callback. This test does not get run and is reported like a todo. - * - * @param {string} description - This is the name of the test, and should describe a behavior. - * @param {() => void} callback - A function that contains a set of expectations for this test. - */ -declare function xtest(description: string, callback: () => void): void; - -/** - * This function creates a test inside the given test group. It must be placed inside a describe - * block. - * - * @param {string} description - This is the name of the test, and should describe a behavior. - * @param {() => void} callback - A function that contains a set of expectations for this test. - * - * @example - * describe("the meaning of life", (): void => { - * test("the value should be 42", (): void => { - * // put your expectations here - * expect(29 + 13).toBe(42); - * }); - * }); - */ -declare function test(description: string, callback: () => void): void; - -/** - * This function creates a test that is expected to fail. This is useful to verify if a given - * behavior is expected to throw. - * - * @param {string} description - This is the name of the test, and should describe a behavior. - * @param {() => void} callback - A function that contains a set of expectations for this test. - * @param {string?} message - A message that describes why the test should fail. - * @example - * describe("the meaning of life", (): void => { - * throws("the value should be 42", (): void => { - * // put your expectations here - * expect(29 + 13).toBe(42); - * }); - * }); - */ - declare function throws(description: string, callback: () => void, message?: string): void; - -/** - * This function creates a callback that is called before each individual test is run in this test - * group. - * - * @param {function} callback - The function to be run before each test in the current test group. - * - * @example - * // create a global - * var cat: Cat = new Cat(); - * - * describe("cats", (): void => { - * beforeEach((): void => { - * cat.meow(1); // meow once per test - * }); - * }); - */ -declare function beforeEach(callback: () => void): void; - -/** - * This function creates a callback that is called before the whole test group is run, and only - * once. - * - * @param {function} callback - The function to be run before each test in the current test group. - * - * @example - * // create a global - * var dog: Dog = null; - * describe("dogs", (): void => { - * beforeAll((): void => { - * dog = new Dog(); // create a single dog once before the tests start - * }); - * }); - */ -declare function beforeAll(callback: () => void): void; - -/** - * This function creates a callback that is called after each individual test is run in this test - * group. - * - * @param {function} callback - The function to be run after each test in the current test group. - * - * @example - * // create a global - * var cat: Cat = new Cat(); - * - * describe("cats", (): void => { - * afterEach((): void => { - * cat.sleep(12); // cats sleep a lot - * }); - * }); - */ -declare function afterEach(callback: () => void): void; - -/** - * This function creates a callback that is called after the whole test group is run, and only - * once. - * - * @param {function} callback - The function to be run after each test in the current test group. - * - * @example - * // create a global - * var dog: Dog = null; - * describe("dogs", (): void => { - * afterAll((): void => { - * memory.free(changetype(dog)); // free some memory - * }); - * }); - */ -declare function afterAll(callback: () => void): void; - -/** - * Describes a value and returns an expectation to test the value. - * - * @type {T} - The test's type - * @param {T} actual - The value being tested. - * - * @example - * expect(42).not.toBe(-1, "42 should not be -1"); - * expect(19 + 23).toBe(42, "19 + 23 should equal 42"); - */ -declare function expect(actual: T | null): Expectation; - -/** - * Describes a function and returns an expectation to test the function. - * - * @param {() => void} callback - The callback being tested. - * - * @example - * expectFn((): void => unreachable()).toThrow("unreachables do not throw"); - * expectFn((): void => { - * cat.meow(); - * }).not.toThrow("Uhoh, cats can't meow!");; - */ -declare function expectFn(cb: () => void): Expectation<() => void>; - -/** - * Describes a test that needs to be written. - * - * @param {string} description - The description of the test that needs to be written. - */ -declare function todo(description: string): void; - -/** - * Logs a single value to the logger, and is stringified. It works for references, values, and - * strings. - * - * @type {T} - The type to be logged. - * @param {T | null} value - The value to be logged. - * @example - * log("This is a logged value."); - * log(42); - * log(new Vec(1, 2, 3)); - * log(null); - */ -declare function log(value: T | null): void; - -/** -* An expectation for a value. -*/ -declare class Expectation { - - /** - * Create a new expectation. - * - * @param {T | null} actual - The actual value of the expectation. - */ - constructor(actual: T | null); - - /** - * This expectation performs a strict equality on value types and reference types. - * - * @param {T | null} expected - The value to be compared. - * @param {string} message - The optional message that describes the expectation. - * - * @example - * expect(42).not.toBe(-1, "42 should not be -1"); - * expect(19 + 23).toBe(42, "19 + 23 should equal 42"); - */ - toBe(expected: T | null, message?: string): void; - - /** - * This expectation performs a strict equality on value types and performs a memcompare on - * reference types. If the reference type T has reference types as properties, the comparison does - * not perform property traversal. It will only compare the pointer values in the memory block. - * - * @param {T | null} expected - The value to be compared. - * @param {string} message - The optional message that describes the expectation. - * - * @example - * expect(new Vec3(1, 2, 3)).toStrictEqual(new Vec(1, 2, 3), "Vectors of the same shape should be equal"); - */ - toStrictEqual(expected: T | null, message?: string): void; - - /** - * If the value is callable, it calls the function, and fails the expectation if it throws, or hits - * an unreachable(). - * - * @param {string} message - The optional message that describes the expectation. - * - * @example - * expectFn((): void => unreachable()).toThrow("unreachable() should throw."); - * expectFn((): void => { - * cat.sleep(100); // cats can sleep quite a lot - * }).not.toThrow("cats should sleep, not throw"); - */ - toThrow(message?: string): void; - - /** - * This expecation asserts that the value is truthy, like in javascript. If the value is a string, - * then strings of length 0 are not truthy. - * - * @param {string} message - The optional message that describes the expectation. - * - * @example - * expect(true).toBeTruthy("true is truthy."); - * expect(1).toBeTruthy("numeric values that are not 0 are truthy."); - * expect(new Vec3(1, 2, 3)).toBeTruthy("reference types that aren't null are truthy."); - * expect(false).not.toBeTruthy("false is not truthy."); - * expect(0).not.toBeTruthy("0 is not truthy."); - * expect(null).not.toBeTruthy("null is not truthy."); - */ - toBeTruthy(message?: string): void; - - /** - * This expectation tests the value to see if it is null. If the value is a value type, it is - * never null. If the value is a reference type, it performs a strict null comparison. - * - * @param {string} message - The optional message that describes the expectation. - * - * @example - * expect(0).not.toBeNull("numbers are never null"); - * expect(null).toBeNull("null reference types are null."); - */ - toBeNull(message?: string): void; - - /** - * This expecation assert that the value is falsy, like in javascript. If the value is a string, - * then strings of length 0 are falsy. - * - * @param {string} message - The optional message that describes the expectation. - * - * @example - * expect(false).toBeFalsy("false is falsy."); - * expect(0).toBeFalsy("0 is falsy."); - * expect(null).toBeFalsy("null is falsy."); - * expect(true).not.toBeFalsy("true is not falsy."); - * expect(1).not.toBeFalsy("numeric values that are not 0 are not falsy."); - * expect(new Vec3(1, 2, 3)).not.toBeFalsy("reference types that aren't null are not falsy."); - */ - toBeFalsy(message?: string): void; - - /** - * This expectation asserts that the value is greater than the expected value. Since operators can - * be overloaded in assemblyscript, it's possible for this to work on reference types. - * - * @param {T | null} expected - The expected value that the actual value should be greater than. - * @param {string} message - The optional message that describes this expectation. - * - * @example - * expect(10).toBeGreaterThan(4); - * expect(12).not.toBeGreaterThan(42); - */ - toBeGreaterThan(expected: T | null, message?: string): void; - - /** - * This expectation asserts that the value is less than the expected value. Since operators can - * be overloaded in assemblyscript, it's possible for this to work on reference types. - * - * @param {T | null} value - The expected value that the actual value should be less than. - * @param {string} message - The optional message that describes this expectation. - * - * @example - * expect(10).not.toBeLessThan(4); - * expect(12).toBeLessThan(42); - */ - toBeLessThan(expected: T | null, message?: string): void; - - /** - * This expectation asserts that the value is greater than or equal to the expected value. Since - * operators can be overloaded in assemblyscript, it's possible for this to work on reference - * types. - * - * @param {T | null} value - The expected value that the actual value should be greater than or - * equal to. - * @param {string} message - The optional message that describes this expectation. - * - * @example - * expect(42).toBeGreaterThanOrEqualTo(42); - * expect(10).toBeGreaterThanOrEqualTo(4); - * expect(12).not.toBeGreaterThanOrEqualTo(42); - */ - toBeGreaterThanOrEqualTo(expected: T | null, message?: string): void; - - /** - * This expectation asserts that the value is less than or equal to the expected value. Since - * operators can be overloaded in assemblyscript, it's possible for this to work on reference - * types. - * - * @param {T | null} value - The expected value that the actual value should be less than or equal - * to. - * @param {string} message - The optional message that describes this expectation. - * - * @example - * expect(42).toBeLessThanOrEqualTo(42); - * expect(10).not.toBeLessThanOrEqualTo(4); - * expect(12).toBeLessThanOrEqualTo(42); - */ - toBeLessThanOrEqualTo(expected: T | null, message?: string): void; - - /** - * This expectation asserts that the value is close to another value. Both numbers must be finite, - * and T must extend f64 or f32. - * - * @param {T extends f64 | f32} value - The expected value to be close to. - * @param {i32} decimalPlaces - The number of decimal places used to calculate epsilon. Default is - * 2. - * @param {string} message - The optional message that describes this expectation. - */ - toBeCloseTo(expected: T, decimalPlaces?: number, message?: string): void; - - /** - * This function asserts the float type value is NaN. - * - * @param {string} message - The optional message the describes this expectation. - * @example - * expect(NaN).toBeNaN(); - * expect(42).not.toBeNaN(); - */ - toBeNaN(message?: string): void; - - /** - * This function asserts a float is finite. - * - * @param {string} message - The optional message the describes this expectation. - * @example - * expect(42).toBeFinite(); - * expect(Infinity).not.toBeFinite(); - */ - toBeFinite(message?: string): void; - - /** - * This method asserts the item has the expected length. - * - * @param {i32} expected - The expected length. - * @param {string} message - The optional message the describes this expectation. - */ - toHaveLength(expected: i32, message?: string): void; - - /** - * This computed property is chainable, and negates the existing expectation. It returns itself. - * - * @type {Expectation} - */ - not: Expectation; - - /** - * The actual value of the expectation. - */ - actual: T | null; - private _not: boolean; -} - -/** - * This is called to stop the debugger. e.g. `node --inspect-brk asp`. - */ -declare function debug(): void; diff --git a/packages/assemblyscript/assembly/__tests__/example.spec.ts b/packages/assemblyscript/assembly/__tests__/example.spec.ts deleted file mode 100644 index cdb0025..0000000 --- a/packages/assemblyscript/assembly/__tests__/example.spec.ts +++ /dev/null @@ -1,5 +0,0 @@ -describe("example", (): void => { - it("should be truthy", (): void => { - expect(19 + 23).toBe(42, "42 is the meaning of life."); - }); -}); diff --git a/packages/assemblyscript/assembly/__tests__/wasa.spec.ts b/packages/assemblyscript/assembly/__tests__/wasa.spec.ts new file mode 100644 index 0000000..670e3e4 --- /dev/null +++ b/packages/assemblyscript/assembly/__tests__/wasa.spec.ts @@ -0,0 +1,78 @@ +import { Console, IO, fs } from "../wasa/mock"; +import * as echo from "../bin/echo"; +import { JSONDecoder } from "../../node_modules/assemblyscript-json/assembly/decoder"; +import { JSONEncoder } from "../../node_modules/assemblyscript-json/assembly/encoder"; +import { FileDescriptor } from "../wasa/mock/fs"; + +let jsonStr = '{"hello":"world"}'; + +const STDOUT: string = "/dev/fd/1"; +var stdout: FileDescriptor; +var encoder: JSONEncoder; + +var std_out: FileDescriptor; +var std_in: FileDescriptor; +var std_err: FileDescriptor; + +function roundripTest(jsonString: string, expectedString: string = ""): bool { + log("--------" + jsonString + (expectedString ? " " + expectedString : "")); + expectedString = expectedString || jsonString; + let buffer: Uint8Array = new Uint8Array(jsonString.lengthUTF8); + let utf8ptr = jsonString.toUTF8(); + // TODO: std should expose memcpy? + for (let i = 0; i < buffer.length; i++) { + buffer[i] = load(utf8ptr + i); + } + let decoder: JSONDecoder = new JSONDecoder(encoder); + decoder.deserialize(buffer); + let resultBuffer = encoder.serialize(); + let resultString = String.fromUTF8( + resultBuffer.buffer.data, + resultBuffer.length + ); + expect(resultString).toStrictEqual(expectedString); + expect(encoder.toString()).toStrictEqual(expectedString); + return true; +} + +beforeAll( + (): void => { + encoder = new JSONEncoder(); + std_in = fs.get(Console.stdin); + std_out = fs.get(Console.stdout); + std_err = fs.get(Console.stderr); + } +); + +describe("Console", (): void => { + it("should be print hello World", (): void => { + Console.log(jsonStr); + let std1 = fs.get(std_out.id); + let std2 = fs.get(std_out.id); + expect(std1).toStrictEqual( + std2, + "Two non-unique file descriptors points to the same object" + ); + + stdout = fs.get(fs.open("/dev/fd/1")); + expect(stdout.offset).toBe( + 0, + "A fresh file descriptor has a seek (offset) of 0" + ); + + expect(std_out.offset).toBe( + jsonStr.lengthUTF8 + 1, + "length of string + \\n" + ); + // expect(stdout.offset).toBe(0); //"new line addded" + // let stdoutStr = fs.readString(stdout.id); + let newLineStr = jsonStr + "\n"; + expect(stdout.readString()).toStrictEqual(newLineStr); + }); +}); + +describe("Json", (): void => { + it("simple hello world", (): void => { + roundripTest(jsonStr, jsonStr); + }); +}); diff --git a/packages/assemblyscript/assembly/bin/echo.ts b/packages/assemblyscript/assembly/bin/echo.ts index 10283f5..97ee83c 100644 --- a/packages/assemblyscript/assembly/bin/echo.ts +++ b/packages/assemblyscript/assembly/bin/echo.ts @@ -4,7 +4,7 @@ // import { Console } from "@wasmos/wasa"; // import "allocator/arena"; -import { Console } from "../wasa"; +// import { Console } from "../wasa/mock"; export const enum ExitStatus { EXIT_FAILURE = -1, diff --git a/packages/assemblyscript/assembly/json/index.ts b/packages/assemblyscript/assembly/json/index.ts new file mode 100644 index 0000000..5373b75 --- /dev/null +++ b/packages/assemblyscript/assembly/json/index.ts @@ -0,0 +1,3 @@ +import {JSONDecoder, JSONEncoder} from "../../node_modules/assemblyscript-json/assembly"; + +export {JSONDecoder as Decoder, JSONEncoder as Encoder} diff --git a/packages/assemblyscript/assembly/tsconfig.json b/packages/assemblyscript/assembly/tsconfig.json index a6bb052..8ad52d3 100644 --- a/packages/assemblyscript/assembly/tsconfig.json +++ b/packages/assemblyscript/assembly/tsconfig.json @@ -13,7 +13,10 @@ "module": "commonjs", "noLib": true, "allowJs": false, - "typeRoots": ["./types"], - "types": ["assembly"] + "typeRoots": [ + "./types", + "../node_modules/*/assembly/types", + "../../../node_modules/as-pect/assembly/__tests__" + ] } } diff --git a/packages/assemblyscript/assembly/types/as-pect.d.ts b/packages/assemblyscript/assembly/types/as-pect.d.ts new file mode 100644 index 0000000..ac7d10a --- /dev/null +++ b/packages/assemblyscript/assembly/types/as-pect.d.ts @@ -0,0 +1 @@ +import "../../node_modules/as-pect/assembly/__tests__/as-pect"; diff --git a/packages/assemblyscript/assembly/types/assembly.d.ts b/packages/assemblyscript/assembly/types/assembly.d.ts new file mode 100644 index 0000000..6b48d45 --- /dev/null +++ b/packages/assemblyscript/assembly/types/assembly.d.ts @@ -0,0 +1 @@ +import "./assembly" \ No newline at end of file diff --git a/packages/assemblyscript/assembly/types/assembly/index.d.ts b/packages/assemblyscript/assembly/types/assembly/index.d.ts index de19ad9..1c1f856 100644 --- a/packages/assemblyscript/assembly/types/assembly/index.d.ts +++ b/packages/assemblyscript/assembly/types/assembly/index.d.ts @@ -1,31 +1,7 @@ -import "@wasmos/wasa/assembly"; +// import "@wasmos/wasa/assembly"; import "../../../node_modules/assemblyscript/std/assembly/index"; + +// @ts-ignore: Decorators *are* valid here! + +declare function abort(): void; // -// declare class Console { -// /** -// * Write a string to the console -// * @param s string -// * @param newline `false` to avoid inserting a newline after the string -// */ -// static write(s: string, newline?: boolean): void; -// -// /** -// * Read an UTF8 string from the console, convert it to a native string -// */ -// static readAll(): string | null; -// -// /** -// * Alias for `Console.write()` -// */ -// static log(s: string): void; -// -// /** -// * Write an error to the console -// * @param s string -// * @param newline `false` to avoid inserting a newline after the string -// */ -// static error(s: string, newline?: boolean): void; -// } -// // declare const Cons: number; -// // declare function Cons1(): void; -// // declare type IO = wasa.IO; diff --git a/packages/assemblyscript/assembly/types/index.d.ts b/packages/assemblyscript/assembly/types/index.d.ts deleted file mode 100644 index 62711bf..0000000 --- a/packages/assemblyscript/assembly/types/index.d.ts +++ /dev/null @@ -1,30 +0,0 @@ -export * from "@wasmos/wasa"; -// -// declare class Console { -// /** -// * Write a string to the console -// * @param s string -// * @param newline `false` to avoid inserting a newline after the string -// */ -// static write(s: string, newline?: boolean): void; -// -// /** -// * Read an UTF8 string from the console, convert it to a native string -// */ -// static readAll(): string | null; -// -// /** -// * Alias for `Console.write()` -// */ -// static log(s: string): void; -// -// /** -// * Write an error to the console -// * @param s string -// * @param newline `false` to avoid inserting a newline after the string -// */ -// static error(s: string, newline?: boolean): void; -// } -// // declare const Cons: number; -// // declare function Cons1(): void; -// // declare type IO = wasa.IO; diff --git a/packages/assemblyscript/assembly/types/package.json b/packages/assemblyscript/assembly/types/package.json deleted file mode 100644 index ddd2ec3..0000000 --- a/packages/assemblyscript/assembly/types/package.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "types": "index.d.ts" -} diff --git a/packages/assemblyscript/assembly/types/wasa.d.ts b/packages/assemblyscript/assembly/types/wasa.d.ts new file mode 100644 index 0000000..35e75a4 --- /dev/null +++ b/packages/assemblyscript/assembly/types/wasa.d.ts @@ -0,0 +1,29 @@ +declare class Console { + /** + * Write a string to the console + * @param s string + * @param newline `false` to avoid inserting a newline after the string + */ + static write(s: string, newline?: boolean): void; + + /** + * Read an UTF8 string from the console, convert it to a native string + */ + static readAll(): string | null; + + /** + * Alias for `Console.write()` + */ + static log(s: string): void; + + /** + * Write an error to the console + * @param s string + * @param newline `false` to avoid inserting a newline after the string + */ + static error(s: string, newline?: boolean): void; +} +// // declare const Cons: number; +// // declare function Cons1(): void; +// // declare type IO = wasa.IO; +declare function abort():void; diff --git a/packages/assemblyscript/assembly/wasa/index.ts b/packages/assemblyscript/assembly/wasa/index.ts index a2f5de1..bd54852 100644 --- a/packages/assemblyscript/assembly/wasa/index.ts +++ b/packages/assemblyscript/assembly/wasa/index.ts @@ -1,3 +1,3 @@ -import { Console, CommandLine } from "@wasmos/wasa"; - -export { Console, CommandLine }; +import * as wasa from "@wasmos/wasa"; +import * as mock from "./mock"; +export { wasa }; diff --git a/packages/assemblyscript/assembly/wasa/mock/fs.ts b/packages/assemblyscript/assembly/wasa/mock/fs.ts new file mode 100644 index 0000000..7e82c47 --- /dev/null +++ b/packages/assemblyscript/assembly/wasa/mock/fs.ts @@ -0,0 +1,135 @@ +import { FileDescriptor as _FileDescriptor } from "../../../../kernel/packages/fs/src/wasi/index"; +import { StringUtils } from "."; + +type path = string; +type fd = usize; + +export class FileDescriptor { + constructor(public file: File, public id: u32, public offset: u32) {} + + write(bytes: Array): void { + for (let i = 0; i < bytes.length; i++) { + this.writeByte(bytes[i]); + } + } + + writeString(str: string): void { + log(str); + // TODO: std should expose memcpy? + memory.copy(this.data + this.offset, str.toUTF8(), str.lengthUTF8); + this.offset += str.lengthUTF8; + } + + copyByte(ptr: usize): void { + this.writeByte(load(ptr)); + } + + writeByte(byte: u8): void { + store(this.file.data + this.offset++, byte); + } + + read(bytes: Array): void { + for (let i = 0; i < bytes.length; i++) { + bytes[i] = this.readByte(); + } + } + + readByte(): u8 { + return load(this.data + this.offset++); + } + + pread(bytes: Array): void { + let offset = this.offset; + this.read(bytes); + this.offset = offset; + } + + readString(): string { + let str = StringUtils.fromCString(this.data + this.offset); + this.offset += str.lengthUTF8 + 1; //For new line + return str; + } + + reset(): void { + this.offset = 0; + } + + get data(): usize { + return this.file.data; + } +} + +export class Stdout extends FileDescriptor { + constructor(file: File) { + super(file, 1, 0); + } +} + +class File { + static DefaultSize: u32 = 1024; + private _data: ArrayBuffer; + constructor(public path: string) { + this._data = new ArrayBuffer(File.DefaultSize); + } + get data(): usize { + return this._data.data; + } + + grow(): File { + let newData = new ArrayBuffer(this._data.byteLength * 2); + memory.copy(newData.data, this.data, this._data.byteLength); + return this; + } +} + +class Directory extends File { + parent: Directory; + children: Array; +} + +export class Filesystem { + files: Map = new Map(); + paths: Map = new Map(); + highestFD: usize = 0; + + static Default(): Filesystem { + let fs = new Filesystem(); + return fs; + } + + set(fd: fd, FD: FileDescriptor): void { + this.files.set(fd, FD); + } + + get(fd: fd): FileDescriptor { + return this.files.get(fd); + } + + open(path: path): fd { + let fd = this.highestFD++; + if (!this.paths.has(path)) { + this.paths.set(path, new File(path)); + } + this.set(fd, new FileDescriptor(this.paths.get(path), fd, 0)); + return fd; + } + + write(fd: fd, data: Array): void { + this.get(fd).write(data); + } + + read(fd: fd, data: Array): void { + this.get(fd).read(data); + } + + readString(fd: fd, offset: usize = 0): string { + return this.get(fd).readString(); + } + + writeString(fd: fd, data: string): void { + this.get(fd).writeString(data); + } + close(fd: number): void { + this.files.delete(fd); + } +} diff --git a/packages/assemblyscript/assembly/wasa/mock/index.ts b/packages/assemblyscript/assembly/wasa/mock/index.ts new file mode 100644 index 0000000..02de664 --- /dev/null +++ b/packages/assemblyscript/assembly/wasa/mock/index.ts @@ -0,0 +1,296 @@ +// The entry file of your WebAssembly module. + +import { RNG } from "./random"; +import { Filesystem as _fs, FileDescriptor, Stdout } from "./fs"; + +let fs = _fs.Default(); +export { fs }; +var fd = 1; +export type Descriptor = usize; + +export class Filesystem { + /** + * A simplified interface to open a file for read operations + * @param path Path + * @param dirfd Base directory descriptor (will be automatically set soon) + */ + static openForRead(path: string, dirfd: Descriptor = 3): Descriptor { + return fs.open(path); + } + + /** + * A simplified interface to open a file for write operations + * @param path Path + * @param dirfd Base directory descriptor (will be automatically set soon) + */ + static openForWrite(path: string, dirfd: Descriptor = 3): Descriptor { + return fs.open(path); + } +} + +export class IO { + data: Uint8Array; + /** + * Close a file descriptor + * @param fd file descriptor + */ + static close(fd: Descriptor): void { + fs.close(fd); + } + + /** + * Write data to a file descriptor + * @param fd file descriptor + * @param data data + */ + static write(fd: Descriptor, data: Array): void { + fs.write(fd, data); + } + + /** + * Write a string to a file descriptor, after encoding it to UTF8 + * @param fd file descriptor + * @param s string + * @param newline `true` to add a newline after the string + */ + static writeString(fd: Descriptor, s: string, newline: bool = false): void { + let str = s + (newline ? "\n" : ""); + fs.get(fd).writeString(str); + } + + /** + * Write a string to a file descriptor, after encoding it to UTF8, with a newline + * @param fd file descriptor + * @param s string + */ + static writeStringLn(fd: Descriptor, s: string): void { + this.writeString(fd, s, true); + } + + /** + * Read data from a file descriptor + * @param fd file descriptor + * @param data existing array to push data to + * @param chunk_size chunk size (default: 4096) + */ + static read( + fd: Descriptor, + data: Array = [], + chunk_size: usize = 4096 + ): Array | null { + return data; + } + + /** + * Read from a file descriptor until the end of the stream + * @param fd file descriptor + * @param data existing array to push data to + * @param chunk_size chunk size (default: 4096) + */ + static readAll( + fd: Descriptor, + data: Array = [], + chunk_size: usize = 4096 + ): Array | null { + return data; + } + + /** + * Read an UTF8 string from a file descriptor, convert it to a native string + * @param fd file descriptor + * @param chunk_size chunk size (default: 4096) + */ + static readString(fd: Descriptor, chunk_size: usize = 4096): string | null { + let s = "hello world"; + return s; + } + + static reset(fd: Descriptor): void { + fs.get(fd).reset(); + } +} + +// @ts-ignore: Decorators *are* valid here! +@global +export class Console { + private static _stdin: Descriptor | null = null; + private static _stdout: Descriptor | null = null; + private static _stderr: Descriptor | null = null; + + static get stdin(): Descriptor { + if (Console._stdin == null) { + Console._stdin = Filesystem.openForRead("/dev/fd/0"); + } + return Console._stdin; + } + + static get stdout(): Descriptor { + if (Console._stdout == null) { + Console._stdout = Filesystem.openForWrite("/dev/fd/1"); + } + return Console._stdout; + } + + static get stderr(): Descriptor { + if (Console._stderr == null) { + Console._stderr = Filesystem.openForRead("/dev/fd/2"); + } + return Console._stderr; + } + + /** + * Write a string to the console + * @param s string + * @param newline `false` to avoid inserting a newline after the string + */ + static write(s: string, newline: bool = true): void { + IO.writeString(this.stdout, s, newline); + } + + /** + * Read an UTF8 string from the console, convert it to a native string + */ + static readAll(): string | null { + return IO.readString(this.stdin); + } + + /** + * Alias for `Console.write()` + */ + static log(s: string): void { + this.write(s); + } + + /** + * Write an error to the console + * @param s string + * @param newline `false` to avoid inserting a newline after the string + */ + static error(s: string, newline: bool = true): void { + IO.writeString(this.stdout, s, newline); + } +} + +export class Random { + static RNG: RNG = RNG.fromSeed(42); + + /** + * Fill a buffer with random data + * @param buffer An array buffer + */ + static randomFill(buffer: ArrayBuffer): void { + for (let i = 0; i < buffer.byteLength; i++) { + store(buffer.data, this.RNG.next(), i); + } + } + + /** + * Return an array of random bytes + * @param len length + */ + static randomBytes(len: usize): Uint8Array { + let array = new Uint8Array(len); + this.randomFill(array.buffer); + return array; + } +} + +export class Date { + /** + * Return the current timestamp, as a number of milliseconds since the epoch + */ + static now(): f64 { + let time_ptr = memory.allocate(8); + let unix_ts = load(time_ptr); + memory.free(time_ptr); + return (unix_ts as f64) / 1000.0; + } +} + +export class Performance { + static now(): f64 { + let time_ptr = memory.allocate(8); + let res_ts = load(time_ptr); + memory.free(time_ptr); + return res_ts as f64; + } +} + +export class Process { + /** + * Cleanly terminate the current process + * @param status exit code + */ + static exit(status: u32): void { + abort(); + } +} + +export class EnvironEntry { + constructor(readonly key: string, readonly value: string) {} +} + +export class Environ { + env: Array = new Array(); + + add(key: string, value: string): void { + this.env.push(new EnvironEntry(key, value)); + } + + /** + * Return all environment variables + */ + all(): Array { + return this.env; + } + + /** + * Return the value for an environment variable + * @param key environment variable name + */ + get(key: string): string | null { + for (let i = 0, j = this.env.length; i < j; i++) { + if (this.env[i].key == key) { + return this.env[i].value; + } + } + return null; + } +} + +export class CommandLine { + args: Array = new Array(); + + push(item: string): void { + this.args.push(item); + } + + /** + * Return all the command-line arguments + */ + all(): Array { + return this.args; + } + + /** + * Return the i-th command-ine argument + * @param i index + */ + get(i: usize): string | null { + let args_len: usize = this.args[0].length; + if (i < args_len) { + return this.args[i]; + } + return null; + } +} + +export class StringUtils { + static fromCString(cstring: usize): string { + let size = 0; + while (load(cstring + size) != 0) { + size++; + } + return String.fromUTF8(cstring, size); + } +} diff --git a/packages/assemblyscript/assembly/wasa/mock/random.ts b/packages/assemblyscript/assembly/wasa/mock/random.ts new file mode 100644 index 0000000..9e4eaa2 --- /dev/null +++ b/packages/assemblyscript/assembly/wasa/mock/random.ts @@ -0,0 +1,47 @@ +class RandomNumberGenerator { + next(): u32 { + return 0; + } +} + +//inspired by https://github.com/dubzzz/pure-rand/blob/master/src/generator/XorShift.ts + +type RNG = RandomNumberGenerator; + +class XorShift128Plus extends RandomNumberGenerator { + constructor( + private s01: u32, + private s00: u32, + private s11: u32, + private s10: u32 + ) { + super(); + } + min(): u32 { + return -0x80000000; + } + max(): u32 { + return 0x7fffffff; + } + next(): u32 { + const a0 = this.s00 ^ (this.s00 << 23); + const a1 = this.s01 ^ ((this.s01 << 23) | (this.s00 >>> 9)); + const b0 = + a0 ^ + this.s10 ^ + ((a0 >>> 17) | (a1 << 15)) ^ + ((this.s10 >>> 26) | (this.s11 << 6)); + const b1 = a1 ^ this.s11 ^ (a1 >>> 17) ^ (this.s11 >>> 26); + this.s01 = this.s11; + this.s00 = this.s10; + this.s11 = b1; + this.s10 = b0; + return (b0 + this.s10) | 0; + } + + static fromSeed(seed: u32): XorShift128Plus { + return new XorShift128Plus(-1, ~seed, 0, seed | 0); + }; +} +export {XorShift128Plus as RNG} + diff --git a/packages/assemblyscript/package-lock.json b/packages/assemblyscript/package-lock.json index fb7d989..2bcd18a 100644 --- a/packages/assemblyscript/package-lock.json +++ b/packages/assemblyscript/package-lock.json @@ -25,36 +25,10 @@ "requires": { "@types/node": "^10.12.24", "@types/webassembly-js-api": "0.0.1", + "as-pect": "github:jtenner/as-pect", "assemblyscript": "github:willemneal/assemblyscript#b7d8e1300a578fb76ff25f9dfab9de8c5a1cde94" }, "dependencies": { - "as-pect": { - "version": "github:jtenner/as-pect#acc1d30a6741cf93d024898ccfd01e58c50446db", - "from": "github:jtenner/as-pect#acc1d30a6741cf93d024898ccfd01e58c50446db", - "requires": { - "assemblyscript": "github:assemblyscript/assemblyscript", - "glob": "^7.1.3" - }, - "dependencies": { - "assemblyscript": { - "version": "github:assemblyscript/assemblyscript#36040d5b5312f19a025782b5e36663823494c2f3", - "from": "github:assemblyscript/assemblyscript", - "requires": { - "@protobufjs/utf8": "^1.1.0", - "binaryen": "77.0.0-nightly.20190407", - "glob": "^7.1.3", - "long": "^4.0.0", - "opencollective-postinstall": "^2.0.0", - "source-map-support": "^0.5.11" - } - }, - "binaryen": { - "version": "77.0.0-nightly.20190407", - "resolved": "https://registry.npmjs.org/binaryen/-/binaryen-77.0.0-nightly.20190407.tgz", - "integrity": "sha512-1mxYNvQ0xywMe582K7V6Vo2zzhZZxMTeGHH8aE/+/AND8f64D8Q1GThVY3RVRwGY/4p+p95ccw9Xbw2ovFXRIg==" - } - } - }, "assemblyscript": { "version": "github:willemneal/assemblyscript#b7d8e1300a578fb76ff25f9dfab9de8c5a1cde94", "from": "github:willemneal/assemblyscript#b7d8e1300a578fb76ff25f9dfab9de8c5a1cde94", @@ -69,6 +43,49 @@ } } }, + "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==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=" + }, + "as-pect": { + "version": "github:jtenner/as-pect#acc1d30a6741cf93d024898ccfd01e58c50446db", + "from": "github:jtenner/as-pect", + "requires": { + "assemblyscript": "github:assemblyscript/assemblyscript", + "chalk": "^2.4.2", + "glob": "^7.1.3", + "ts-node": "^6.2.0", + "yargs-parser": "^13.0.0" + }, + "dependencies": { + "assemblyscript": { + "version": "github:assemblyscript/assemblyscript#36040d5b5312f19a025782b5e36663823494c2f3", + "from": "github:assemblyscript/assemblyscript", + "requires": { + "@protobufjs/utf8": "^1.1.0", + "binaryen": "77.0.0-nightly.20190407", + "glob": "^7.1.3", + "long": "^4.0.0", + "opencollective-postinstall": "^2.0.0", + "source-map-support": "^0.5.11" + } + }, + "binaryen": { + "version": "77.0.0-nightly.20190407", + "resolved": "https://registry.npmjs.org/binaryen/-/binaryen-77.0.0-nightly.20190407.tgz", + "integrity": "sha512-1mxYNvQ0xywMe582K7V6Vo2zzhZZxMTeGHH8aE/+/AND8f64D8Q1GThVY3RVRwGY/4p+p95ccw9Xbw2ovFXRIg==" + } + } + }, "assemblyscript": { "version": "github:willemneal/assemblyscript#fa7c0fa7ec4d0e623731efbbb01547921e2f8b1f", "from": "github:willemneal/assemblyscript#fa7c0fa7ec4d0e623731efbbb01547921e2f8b1f", @@ -81,6 +98,10 @@ "source-map-support": "^0.5.11" } }, + "assemblyscript-json": { + "version": "github:WebAssemblyOS/assemblyscript-json#2af3623ae1ebdb6e6ee9f59c4e87803bdae68728", + "from": "github:WebAssemblyOS/assemblyscript-json" + }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", diff --git a/packages/assemblyscript/package.json b/packages/assemblyscript/package.json index 9aee144..38b410b 100644 --- a/packages/assemblyscript/package.json +++ b/packages/assemblyscript/package.json @@ -29,7 +29,8 @@ "license": "MIT", "dependencies": { "@wasmos/fs": "git:github.com/WebAssemblyOS/fs#v0.0.2", + "@wasmos/wasa": "git:github.com/WebAssemblyOS/wasa", "assemblyscript": "github:willemneal/assemblyscript#fa7c0fa7ec4d0e623731efbbb01547921e2f8b1f", - "@wasmos/wasa": "git:github.com/WebAssemblyOS/wasa" + "assemblyscript-json": "github:WebAssemblyOS/assemblyscript-json" } } diff --git a/packages/assemblyscript/src/compiler.ts b/packages/assemblyscript/src/compiler/compiler.ts similarity index 83% rename from packages/assemblyscript/src/compiler.ts rename to packages/assemblyscript/src/compiler/compiler.ts index 5d09eb4..32ac3bd 100644 --- a/packages/assemblyscript/src/compiler.ts +++ b/packages/assemblyscript/src/compiler/compiler.ts @@ -1,6 +1,6 @@ -import { glob, fs, mkdirp, assemblyFolders } from "@wasmos/fs/src/index"; +import { glob, fs, mkdirp } from "@wasmos/fs/src/index"; import * as asc from "assemblyscript/cli/asc"; - +import { linkLibrary } from "../linker"; import * as path from "path"; import assert = require("assert"); @@ -37,36 +37,6 @@ function isRoot(dir: string): boolean { return path.basename(dir) !== ""; } -export async function linkLibrary(rootPath: string): Promise { - let folders = await assemblyFolders(rootPath); - let assemblyFolder = path.join(rootPath, "node_modules", ".assembly"); - await mkdirp(assemblyFolder); - let pwd = process.cwd(); - process.chdir(assemblyFolder); - await Promise.all( - folders.map(async (v: string) => { - let folder = path.dirname(v); - let grandFolder = path.dirname(folder); - folder = path.basename(folder); - while (path.basename(grandFolder) != "node_modules") { - folder = path.join(path.basename(grandFolder), folder); - grandFolder = path.dirname(grandFolder); - } - if (path.basename(path.dirname(folder)) != "node_modules") { - await mkdirp(path.dirname(folder)); - } - let folderExists = await fs.pathExists(folder); - if (!folderExists) { - let realPath = await fs.realpath(v); - await fs.symlink(realPath, folder, "dir"); - } - }) - ); - process.chdir(pwd); - - return assemblyFolder; -} - export class Compiler { static get opts(): CompilerOptions { return Compiler._opts; diff --git a/packages/assemblyscript/src/index.ts b/packages/assemblyscript/src/index.ts index 78f9695..cd56917 100644 --- a/packages/assemblyscript/src/index.ts +++ b/packages/assemblyscript/src/index.ts @@ -1,9 +1,7 @@ -export * from "./compiler"; +export * from "./compiler/compiler"; import * as loader from "assemblyscript/lib/loader/lib"; export { loader }; export * from "assemblyscript/lib/host/lib"; +export * from "./linker"; - -export async function main() { - -} +export async function main() {} diff --git a/packages/assemblyscript/src/linker.ts b/packages/assemblyscript/src/linker.ts new file mode 100644 index 0000000..d92f5a3 --- /dev/null +++ b/packages/assemblyscript/src/linker.ts @@ -0,0 +1,32 @@ +import * as path from "path"; +import { glob, fs, mkdirp, assemblyFolders } from "@wasmos/fs/src/index"; + +export async function linkLibrary(rootPath: string): Promise { + let folders = await assemblyFolders(rootPath); + let assemblyFolder = path.join(rootPath, "node_modules", ".assembly"); + await mkdirp(assemblyFolder); + let pwd = process.cwd(); + process.chdir(assemblyFolder); + await Promise.all( + folders.map(async (v: string) => { + let folder = path.dirname(v); + let grandFolder = path.dirname(folder); + folder = path.basename(folder); + while (path.basename(grandFolder) != "node_modules") { + folder = path.join(path.basename(grandFolder), folder); + grandFolder = path.dirname(grandFolder); + } + if (path.basename(path.dirname(folder)) != "node_modules") { + await mkdirp(path.dirname(folder)); + } + let folderExists = await fs.pathExists(folder); + if (!folderExists) { + let realPath = await fs.realpath(v); + await fs.symlink(realPath, folder, "dir"); + } + }) + ); + process.chdir(pwd); + + return assemblyFolder; +} diff --git a/packages/kernel/assembly/__tests__/example.spec.ts b/packages/kernel/assembly/__tests__/example.spec.ts index f9e95a6..66e2db2 100644 --- a/packages/kernel/assembly/__tests__/example.spec.ts +++ b/packages/kernel/assembly/__tests__/example.spec.ts @@ -1,4 +1,3 @@ -import { CommandLine } from "../../../assemblyscript/assembly/wasa"; describe("args", (): void => { it("should be truthy", (): void => { diff --git a/packages/kernel/package-lock.json b/packages/kernel/package-lock.json index aece49e..a499a29 100644 --- a/packages/kernel/package-lock.json +++ b/packages/kernel/package-lock.json @@ -25,28 +25,44 @@ "requires": { "@types/node": "^10.12.24", "@types/webassembly-js-api": "0.0.1", + "as-pect": "github:jtenner/as-pect", "assemblyscript": "github:willemneal/assemblyscript#b7d8e1300a578fb76ff25f9dfab9de8c5a1cde94" + } + }, + "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==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=" + }, + "as-pect": { + "version": "github:jtenner/as-pect#acc1d30a6741cf93d024898ccfd01e58c50446db", + "from": "github:jtenner/as-pect", + "requires": { + "assemblyscript": "github:assemblyscript/assemblyscript", + "chalk": "^2.4.2", + "glob": "^7.1.3", + "ts-node": "^6.2.0", + "yargs-parser": "^13.0.0" }, "dependencies": { - "as-pect": { - "version": "github:jtenner/as-pect#acc1d30a6741cf93d024898ccfd01e58c50446db", - "from": "github:jtenner/as-pect#acc1d30a6741cf93d024898ccfd01e58c50446db", + "assemblyscript": { + "version": "github:assemblyscript/assemblyscript#36040d5b5312f19a025782b5e36663823494c2f3", + "from": "github:assemblyscript/assemblyscript", "requires": { - "assemblyscript": "github:assemblyscript/assemblyscript", - "glob": "^7.1.3" - }, - "dependencies": { - "assemblyscript": { - "version": "github:assemblyscript/assemblyscript#36040d5b5312f19a025782b5e36663823494c2f3", - "from": "github:assemblyscript/assemblyscript", - "requires": { - "@protobufjs/utf8": "^1.1.0", - "glob": "^7.1.3", - "long": "^4.0.0", - "opencollective-postinstall": "^2.0.0", - "source-map-support": "^0.5.11" - } - } + "@protobufjs/utf8": "^1.1.0", + "binaryen": "77.0.0-nightly.20190407", + "glob": "^7.1.3", + "long": "^4.0.0", + "opencollective-postinstall": "^2.0.0", + "source-map-support": "^0.5.11" } } } @@ -75,6 +91,11 @@ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" }, + "binaryen": { + "version": "77.0.0-nightly.20190407", + "resolved": "https://registry.npmjs.org/binaryen/-/binaryen-77.0.0-nightly.20190407.tgz", + "integrity": "sha512-1mxYNvQ0xywMe582K7V6Vo2zzhZZxMTeGHH8aE/+/AND8f64D8Q1GThVY3RVRwGY/4p+p95ccw9Xbw2ovFXRIg==" + }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -89,11 +110,54 @@ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "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==", + "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": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + }, + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -112,6 +176,11 @@ "path-is-absolute": "^1.0.0" } }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -131,6 +200,11 @@ "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" }, + "make-error": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", + "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==" + }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", @@ -139,6 +213,26 @@ "brace-expansion": "^1.1.7" } }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "requires": { + "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + } + } + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -171,10 +265,47 @@ "source-map": "^0.6.0" } }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + }, + "ts-node": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-6.2.0.tgz", + "integrity": "sha512-ZNT+OEGfUNVMGkpIaDJJ44Zq3Yr0bkU/ugN1PHbU+/01Z7UV1fsELRiTx1KuQNvQ1A3pGh3y25iYF6jXgxV21A==", + "requires": { + "arrify": "^1.0.0", + "buffer-from": "^1.1.0", + "diff": "^3.1.0", + "make-error": "^1.1.1", + "minimist": "^1.2.0", + "mkdirp": "^0.5.1", + "source-map-support": "^0.5.6", + "yn": "^2.0.0" + } + }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "yargs-parser": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.0.0.tgz", + "integrity": "sha512-w2LXjoL8oRdRQN+hOyppuXs+V/fVAYtpcrRxZuF7Kt/Oc+Jr2uAcVntaUTNT6w5ihoWfFDpNY8CPx1QskxZ/pw==", + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "yn": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", + "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=" } } } diff --git a/packages/kernel/packages/fs/src/wasi/index.ts b/packages/kernel/packages/fs/src/wasi/index.ts index 2c23ef0..3136cbc 100644 --- a/packages/kernel/packages/fs/src/wasi/index.ts +++ b/packages/kernel/packages/fs/src/wasi/index.ts @@ -1,4 +1,3 @@ export class FileDescriptor { - id: number; - offset: number; + constructor(public id: u32, public offset: u32 = 0) {} }