Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions cli/asc.js
Original file line number Diff line number Diff line change
Expand Up @@ -248,12 +248,6 @@ exports.main = function main(argv, options, callback) {
assemblyscript.setNoUnsafe(compilerOptions, args.noUnsafe);
assemblyscript.setPedantic(compilerOptions, args.pedantic);

// Initialize default aliases
assemblyscript.setGlobalAlias(compilerOptions, "Math", "NativeMath");
assemblyscript.setGlobalAlias(compilerOptions, "Mathf", "NativeMathf");
assemblyscript.setGlobalAlias(compilerOptions, "abort", "~lib/builtins/abort");
assemblyscript.setGlobalAlias(compilerOptions, "trace", "~lib/builtins/trace");

// Add or override aliases if specified
if (args.use) {
let aliases = args.use;
Expand Down
9 changes: 6 additions & 3 deletions lib/loader/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,15 @@ function preInstantiate(imports) {
const env = (imports.env = imports.env || {});
env.abort = env.abort || function abort(mesg, file, line, colm) {
const memory = baseModule.memory || env.memory; // prefer exported, otherwise try imported
throw Error("abort: " + getString(memory, mesg) + " at " + getString(memory, file) + ":" + line + ":" + colm);
}
throw Error("abort: " + getString(memory, mesg) + " in " + getString(memory, file) + "(" + line + ":" + colm + ")");
};
env.trace = env.trace || function trace(mesg, n) {
const memory = baseModule.memory || env.memory;
console.log("trace: " + getString(memory, mesg) + (n ? " " : "") + Array.prototype.slice.call(arguments, 2, 2 + n).join(", "));
}
};
env.seed = env.seed || function seed() {
return Date.now();
};
imports.Math = imports.Math || Math;
imports.Date = imports.Date || Date;

Expand Down
9 changes: 9 additions & 0 deletions src/builtins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,10 @@ export namespace BuiltinNames {
export const setArgumentsLength = "~setArgumentsLength";

// std/builtins.ts
export const abort = "~lib/builtins/abort";
export const trace = "~lib/builtins/trace";
export const seed = "~lib/builtins/seed";

export const isInteger = "~lib/builtins/isInteger";
export const isFloat = "~lib/builtins/isFloat";
export const isBoolean = "~lib/builtins/isBoolean";
Expand Down Expand Up @@ -586,6 +590,11 @@ export namespace BuiltinNames {
export const Uint64Array = "~lib/typedarray/Uint64Array";
export const Float32Array = "~lib/typedarray/Float32Array";
export const Float64Array = "~lib/typedarray/Float64Array";

// std/bindings/wasi.ts
export const wasiAbort = "~lib/bindings/wasi/abort";
export const wasiTrace = "~lib/bindings/wasi/trace";
export const wasiSeed = "~lib/bindings/wasi/seed";
}

/** Builtin compilation context. */
Expand Down
4 changes: 4 additions & 0 deletions src/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,8 @@ export namespace CommonNames {
export const ArrayBuffer = "ArrayBuffer";
export const Math = "Math";
export const Mathf = "Mathf";
export const NativeMath = "NativeMath";
export const NativeMathf = "NativeMathf";
export const Int8Array = "Int8Array";
export const Int16Array = "Int16Array";
export const Int32Array = "Int32Array";
Expand All @@ -203,6 +205,8 @@ export namespace CommonNames {
export const Error = "Error";
// runtime
export const abort = "abort";
export const trace = "trace";
export const seed = "seed";
export const pow = "pow";
export const mod = "mod";
export const alloc = "__alloc";
Expand Down
58 changes: 42 additions & 16 deletions src/program.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ import {
import {
Parser
} from "./parser";
import { BuiltinNames } from "./builtins";

/** Represents a yet unresolved `import`. */
class QueuedImport {
Expand Down Expand Up @@ -980,23 +981,48 @@ export class Program extends DiagnosticEmitter {
// set up global aliases
{
let globalAliases = options.globalAliases;
if (globalAliases) {
// TODO: for (let [alias, name] of globalAliases) {
for (let _keys = Map_keys(globalAliases), i = 0, k = _keys.length; i < k; ++i) {
let alias = unchecked(_keys[i]);
let name = assert(globalAliases.get(alias));
if (!name.length) continue; // explicitly disabled
let firstChar = name.charCodeAt(0);
if (firstChar >= CharCode._0 && firstChar <= CharCode._9) {
this.registerConstantInteger(alias, Type.i32, i64_new(<i32>parseInt(name, 10)));
if (!globalAliases) globalAliases = new Map();
if (!globalAliases.has(CommonNames.abort)) {
globalAliases.set(CommonNames.abort,
this.elementsByName.has(BuiltinNames.wasiAbort)
? BuiltinNames.wasiAbort
: BuiltinNames.abort
);
}
if (!globalAliases.has(CommonNames.trace)) {
globalAliases.set(CommonNames.trace,
this.elementsByName.has(BuiltinNames.wasiTrace)
? BuiltinNames.wasiTrace
: BuiltinNames.trace
);
}
if (!globalAliases.has(CommonNames.seed)) {
globalAliases.set(CommonNames.seed,
this.elementsByName.has(BuiltinNames.wasiSeed)
? BuiltinNames.wasiSeed
: BuiltinNames.seed
);
}
if (!globalAliases.has(CommonNames.Math)) {
globalAliases.set(CommonNames.Math, CommonNames.NativeMath);
}
if (!globalAliases.has(CommonNames.Mathf)) {
globalAliases.set(CommonNames.Mathf, CommonNames.NativeMathf);
}
// TODO: for (let [alias, name] of globalAliases) {
for (let _keys = Map_keys(globalAliases), i = 0, k = _keys.length; i < k; ++i) {
let alias = unchecked(_keys[i]);
let name = assert(globalAliases.get(alias));
if (!name.length) continue; // explicitly disabled
let firstChar = name.charCodeAt(0);
if (firstChar >= CharCode._0 && firstChar <= CharCode._9) {
this.registerConstantInteger(alias, Type.i32, i64_new(<i32>parseInt(name, 10)));
} else {
let elementsByName = this.elementsByName;
if (elementsByName.has(name)) {
elementsByName.set(alias, assert(elementsByName.get(name)));
} else {
let elementsByName = this.elementsByName;
let element = elementsByName.get(name);
if (element) {
if (elementsByName.has(alias)) throw new Error("duplicate global element: " + name);
elementsByName.set(alias, element);
}
else throw new Error("no such global element: " + name);
throw new Error("no such global element: " + name);
}
}
}
Expand Down
119 changes: 119 additions & 0 deletions std/assembly/bindings/wasi.ts
Original file line number Diff line number Diff line change
@@ -1 +1,120 @@
import {
proc_exit,
fd_write,
iovec,
random_get
} from "./wasi_snapshot_preview1";

import {
MAX_DOUBLE_LENGTH,
decimalCount32,
dtoa_stream
} from "util/number";

export * from "./wasi_snapshot_preview1";

/** A WASI-aware abort implementation. */
function abort(
message: string | null = null,
fileName: string | null = null,
lineNumber: u32 = 0,
columnNumber: u32 = 0
): void {
// 0: iov.buf
// 4: iov.buf_len
// 8: len
// 12: buf...
const iovPtr: usize = 0;
const bufPtr: usize = iovPtr + offsetof<iovec>() + sizeof<usize>();
changetype<iovec>(iovPtr).buf = bufPtr;
var ptr = bufPtr;
store<u64>(ptr, 0x203A74726F6261); ptr += 7; // 'abort: '
if (message !== null) {
ptr += String.UTF8.encodeUnsafe(changetype<usize>(message), message.length, ptr);
}
store<u32>(ptr, 0x206E6920); ptr += 4; // ' in '
if (fileName !== null) {
ptr += String.UTF8.encodeUnsafe(changetype<usize>(fileName), fileName.length, ptr);
}
store<u8>(ptr++, 0x28); // (
var len = decimalCount32(lineNumber); ptr += len;
do {
let t = lineNumber / 10;
store<u8>(--ptr, 0x30 + lineNumber % 10);
lineNumber = t;
} while (lineNumber); ptr += len;
store<u8>(ptr++, 0x3A); // :
len = decimalCount32(columnNumber); ptr += len;
do {
let t = columnNumber / 10;
store<u8>(--ptr, 0x30 + columnNumber % 10);
columnNumber = t;
} while (columnNumber); ptr += len;
store<u16>(ptr, 0x0A29); ptr += 2; // )\n
changetype<iovec>(iovPtr).buf_len = ptr - bufPtr;
fd_write(2, iovPtr, 1, offsetof<iovec>());
proc_exit(255);
}

/** A WASI-aware trace implementation. */
function trace(
message: string,
n: i32 = 0,
a0: f64 = 0,
a1: f64 = 0,
a2: f64 = 0,
a3: f64 = 0,
a4: f64 = 0
): void {
// 0: iov.buf
// 4: iov.buf_len
// 8: len
// 12: buf...
var iovPtr = __alloc(offsetof<iovec>() + sizeof<usize>() + 1 + <usize>(max(String.UTF8.byteLength(message), MAX_DOUBLE_LENGTH << 1)), 0);
var lenPtr = iovPtr + offsetof<iovec>();
var bufPtr = lenPtr + sizeof<usize>();
changetype<iovec>(iovPtr).buf = bufPtr;
store<u64>(bufPtr, 0x203A6563617274); // 'trace: '
changetype<iovec>(iovPtr).buf_len = 7;
fd_write(1, iovPtr, 1, lenPtr);
changetype<iovec>(iovPtr).buf_len = String.UTF8.encodeUnsafe(changetype<usize>(message), message.length, bufPtr);
fd_write(1, iovPtr, 1, lenPtr);
if (n) {
store<u8>(bufPtr++, 0x20); // space
changetype<iovec>(iovPtr).buf_len = 1 + String.UTF8.encodeUnsafe(bufPtr, dtoa_stream(bufPtr, 0, a0), bufPtr);
fd_write(1, iovPtr, 1, lenPtr);
if (n > 1) {
changetype<iovec>(iovPtr).buf_len = 1 + String.UTF8.encodeUnsafe(bufPtr, dtoa_stream(bufPtr, 0, a1), bufPtr);
fd_write(1, iovPtr, 1, lenPtr);
if (n > 2) {
changetype<iovec>(iovPtr).buf_len = 1 + String.UTF8.encodeUnsafe(bufPtr, dtoa_stream(bufPtr, 0, a2), bufPtr);
fd_write(1, iovPtr, 1, lenPtr);
if (n > 3) {
changetype<iovec>(iovPtr).buf_len = 1 + String.UTF8.encodeUnsafe(bufPtr, dtoa_stream(bufPtr, 0, a3), bufPtr);
fd_write(1, iovPtr, 1, lenPtr);
if (n > 4) {
changetype<iovec>(iovPtr).buf_len = 1 + String.UTF8.encodeUnsafe(bufPtr, dtoa_stream(bufPtr, 0, a4), bufPtr);
fd_write(1, iovPtr, 1, lenPtr);
}
}
}
}
--bufPtr;
}
store<u8>(bufPtr, 0x0A); // \n
changetype<iovec>(iovPtr).buf_len = 1;
fd_write(1, iovPtr, 1, lenPtr);
__free(iovPtr);
}

/** A WASI-aware seed implementation. */
function seed(): f64 {
var temp = load<u64>(0);
var rand: u64;
do {
random_get(0, 8); // to be sure
rand = load<u64>(0);
} while (!rand);
store<u64>(0, temp);
return reinterpret<f64>(rand);
}
4 changes: 4 additions & 0 deletions std/assembly/builtins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1939,3 +1939,7 @@ declare function trace(
a3?: f64,
a4?: f64
): void;

// @ts-ignore: decorator
@external("env", "seed")
declare function seed(): f64;
10 changes: 9 additions & 1 deletion std/assembly/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1460,6 +1460,8 @@ declare namespace String {
export function byteLength(str: string, nullTerminated?: bool): i32;
/** Encodes the specified string to UTF-8 bytes, optionally null terminated. */
export function encode(str: string, nullTerminated?: bool): ArrayBuffer;
/** Encodes the specified raw string to UTF-8 bytes, opionally null terminated. Returns the number of bytes written. */
export function encodeUnsafe(str: usize, len: i32, buf: usize, nullTerminated?: bool): usize;
/** Decodes the specified buffer from UTF-8 bytes to a string, optionally null terminated. */
export function decode(buf: ArrayBuffer, nullTerminated?: bool): string;
/** Decodes raw UTF-8 bytes to a string, optionally null terminated. */
Expand All @@ -1471,6 +1473,8 @@ declare namespace String {
export function byteLength(str: string): i32;
/** Encodes the specified string to UTF-16 bytes. */
export function encode(str: string): ArrayBuffer;
/** Encodes the specified raw string to UTF-16 bytes. Returns the number of bytes written. */
export function encodeUnsafe(str: usize, len: i32, buf: usize): usize;
/** Decodes the specified buffer from UTF-16 bytes to a string. */
export function decode(buf: ArrayBuffer): string;
/** Decodes raw UTF-16 bytes to a string. */
Expand Down Expand Up @@ -1707,8 +1711,12 @@ declare const Math: IMath<f64>;
/** Alias of {@link NativeMathf} or {@link JSMath} respectively. Defaults to `NativeMathf`. */
declare const Mathf: IMath<f32>;

/** Environmental tracing function for debugging purposes. */
/** Environmental abort function. */
declare function abort(msg?: string | null, fileName?: string | null, lineNumber?: i32, columnNumber?: i32): never;
/** Environmental tracing function. */
declare function trace(msg: string, n?: i32, a0?: f64, a1?: f64, a2?: f64, a3?: f64, a4?: f64): void;
/** Environmental seeding function. */
declare function seed(): f64;

// Decorators

Expand Down
4 changes: 2 additions & 2 deletions std/assembly/math.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1410,7 +1410,7 @@ export namespace NativeMath {
}

export function random(): f64 { // see: v8/src/base/utils/random-number-generator.cc
if (!random_seeded) throw new Error("PRNG must be seeded.");
if (!random_seeded) seedRandom(reinterpret<i64>(seed()));
var s1 = random_state0_64;
var s0 = random_state1_64;
random_state0_64 = s0;
Expand Down Expand Up @@ -2603,7 +2603,7 @@ export namespace NativeMathf {

// Using xoroshiro64starstar from http://xoshiro.di.unimi.it/xoroshiro64starstar.c
export function random(): f32 {
if (!random_seeded) throw new Error("PRNG must be seeded.");
if (!random_seeded) seedRandom(reinterpret<i64>(seed()));

var s0 = random_state0_32;
var s1 = random_state1_32;
Expand Down
Loading