@eqlabs/assemblyscript

0.0.0-alpha.1676898497 • Public • Published

HookScript

HookScript compiles a variant of AssemblyScript (basically TypeScript for WebAssembly) compatible with XRPL Hooks.

XRPL Hooks Introduction  ·  Examples


AssemblyScript modifications & current limitations

  • Strings are stored as UTF-8 in HookScript linear memory, for compatibility with Hook API.
  • No garbage collection. Only the stub AssemblyScript runtime is supported; it can allocate memory from one WebAssembly linear memory page but terminates the script when asked to allocate more than that.
  • Hook API support, currently unfinished (see below).
  • Hooks can define their own functions, but they have to mark them @inline .
  • hook and cbak functions are always exported (when defined), even if not explicitly marked as such. They also don't have to declare their return types (i64 is used automatically) nor contain an explicit return statement (they return 0).
  • _g function is always imported - even if not called by the hook script.

Hook API support

Currently only the basic functions (accept, rollback etc.) are supported for use without declaring - patches welcome. As the C conventions of Hook API are inconvenient for HookScript, the functions are generally imported with a prepended '$' sign (e.g. $accept, $rollback) and wrapped in a function with the original name but higher-level arguments (e.g. a string instead of a pointer + length), which also provides basic error handling, calling rollback on API error - so, for example, etxn_reserve is implemented as

// @ts-ignore: decorator
@external("env", "etxn_reserve")
export declare function $etxn_reserve(
  count: u32
): i64

@global @inline
export function etxn_reserve(count: u32): void {
  let r = $etxn_reserve(count);
  if (r != count)
	rollback("", r);
}

where rollback is

// @ts-ignore: decorator
@external("env", "rollback")
declare function $rollback(
  read_ptr: string,
  read_len: u32,
  error_code: i64
): i64;

@global @inline
export function rollback(msg: string = "", err: i64 = 0): void {
  $rollback(msg, msg.length, err);
  // does not return
}

Both imported lower-level and inlined higher-level APIS are callable from user code. The guard function _g is available, but it's probably more convenient to call its wrapper, max_iterations, which takes care of generating a unique first argument to _g (max_iterations also increments the second argument by 1, like the GUARD macro in the C interface).

Some classes (e.g. Account and Amount) were added for high-level Hooks support - see the standard library for details. Note that while most of AssemblyScript standard library is still there, that doesn't mean it's working - hooks require bounded computation with guarding, which the code hadn't been updated (and in some case cannot be updated) to use.

Development instructions

A development environment can be set up by cloning the repository:

git clone https://github.com/eqlabs/assemblyscript.git
cd assemblyscript

After building the compiler, you can invoke it using cli from bin/asc or directly using the compiled bundles from dist folder in any browser/server environments.

Build using Docker.

A docker image can be created using.

docker build -t asc/img .

To create a container and copy built artifacts to the dist folder.

docker create --name asc-cont asc-img && docker cp asc-cont:/app/dist/ ./

Build manually.

Install NodeJS version >=16 and npm >=6.

Install dependencies.

npm install

Build the compiler.

npm run build

Watch for changes.

npm run watch

The full process is documented as part of the repository:

Package Sidebar

Install

npm i @eqlabs/assemblyscript

Weekly Downloads

0

Version

0.0.0-alpha.1676898497

License

Apache-2.0

Unpacked Size

12.4 MB

Total Files

144

Last publish

Collaborators

  • janianttonen