How to compile console.log("1") with asc in AssemblyScript?

1.1k views Asked by At

I want to compile in AssemblyScript (TypeScript) a code that shows a 1, using console.log.

My file called example.ts contains the following:

console.log("1")

I compile it as follows:

asc example.ts

But I get the following error:

ERROR TS2304: Cannot find name 'console'.

 console.log("1")
 ~~~~~~~
 in example.ts(1,1)

FAILURE 1 compile error(s)

The same thing happens with process.stdout.write("1").

How is this solved?

1

There are 1 answers

0
ArtEze On

I asked for help on AssemblyScript server on Discord and a contributor (dcodeIO) was able to fix a bug about UTF-8 encoding. So for this it is necessary to have AssemblyScript as of version 0.17.7, the version in which this error was fixed. Also, another collaborator (MaxGraey), helped me to create the codes, and also to install the packages.

First you have to install the loader:

npm i @assemblyscript/loader

In my case I couldn't, I had to install it globally, due to reading problems on the USB where I have the operating system installed:

npm install --force -g @assemblyscript/loader

You have to be careful, there is an npm package called assemblyscript-loader, notice that it has a minus sign in the center, you don't have to do the following:

npm install --force -g assemblyscript-loader # Do not do it, it is wrong.

The code of example.ts has to be as follows:

namespace console {
    declare function log(str: string): void;
}

/*
  main generally unnecessary if you don't use
   the `import` object on the host side,
   but in this case it's better to delay the implicit
   initialization during module instantiation
*/
export function main(): void {
    console.log("1");
}

To compile the example.ts with asc, you can do the following ... I add optimizations for less file weight:

asc -O3z --converge -b ./example.wasm ./example.ts

This generates a file of 3033 bytes, equivalently to 3 kb.

To execute the wasm code from Node.js you have to create a file, for example, example.js, and it would look like the following:

const fs = require("fs")
const loader = require('@assemblyscript/loader/umd');

loader.instantiate( fs.readFileSync("./example.wasm"), {
    example: { // if your file called "example.ts"
        "console.log"(ptr) {
            console.log(exports.__getString(ptr));
        }
    }
})
.then(module => {
    exports = module.exports;

    exports.main(); // call entry point
})
.catch(e => {
    console.error(e);
})

It is important to use fs.readFileSync("./example.wasm"), since when using only "./example.wasm", it does not work. This is because the implementation of the loader AssemblyScript (which is created in Node.js), in the index.js file approximately on line 333, asks as an argument a variable of type Buffer, which are the bytes of the example.wasm.

In my case, as I install it globally, in the example.js I changed it to the following:

const loader = require('/usr/lib/node_modules/@assemblyscript/loader/umd');

To run the example.js file from Node.js, it can be done as follows. I put code tracing arguments in case something strange happens:

node --trace-warnings --track-heap-objects ./example.js

The output of running the command is as follows:

1

As you can see, it works correctly.