mirror of
https://github.com/fluencelabs/assemblyscript
synced 2025-06-19 09:51:33 +00:00
Use long.js in JS and native i64 in WASM; Compile literals more thoroughly
This commit is contained in:
@ -1,54 +0,0 @@
|
||||
require("../../std/portable");
|
||||
|
||||
// Copy Binaryen exports to global scope
|
||||
var globalScope = typeof window !== "undefined" && window || typeof global !== "undefined" && global || self;
|
||||
var binaryen = globalScope["Binaryen"]; // allow overriding for testing purposes
|
||||
if (!binaryen) {
|
||||
try {
|
||||
binaryen = require("binaryen");
|
||||
} catch (e) {
|
||||
binaryen = globalScope["Binaryen"];
|
||||
}
|
||||
}
|
||||
for (var key in binaryen)
|
||||
if (/^_(?:Binaryen|Relooper)/.test(key))
|
||||
globalScope[key] = binaryen[key];
|
||||
|
||||
// Use Binaryen's heap instead of std heap
|
||||
globalScope["allocate_memory"] = function allocate_memory(size) {
|
||||
if (!size) return 0; // should be safe in our case
|
||||
return binaryen._malloc(size);
|
||||
};
|
||||
globalScope["free_memory"] = function free_memory(ptr) {
|
||||
if (ptr) binaryen._free(ptr);
|
||||
};
|
||||
globalScope["move_memory"] = function move_memory(dest, src, n) {
|
||||
return binaryen._memmove(dest, src, n);
|
||||
};
|
||||
globalScope["store"] = function store(ptr, val) {
|
||||
binaryen.HEAPU8[ptr] = val;
|
||||
};
|
||||
globalScope["load"] = function load(ptr) {
|
||||
return binaryen.HEAPU8[ptr];
|
||||
};
|
||||
|
||||
// Implement module stubs
|
||||
var Module = require("../module").Module;
|
||||
|
||||
Module.prototype.toText = function toText() {
|
||||
var previousPrint = binaryen.print;
|
||||
var ret = "";
|
||||
binaryen.print = function print(x) { ret += x + "\n" };
|
||||
this.print();
|
||||
binaryen.print = previousPrint;
|
||||
return ret;
|
||||
};
|
||||
|
||||
Module.prototype.toAsmjs = function toAsmjs() {
|
||||
var previousPrint = binaryen.print;
|
||||
var ret = "";
|
||||
binaryen.print = function print(x) { ret += x + "\n" };
|
||||
this.printAsmjs();
|
||||
binaryen.print = previousPrint;
|
||||
return ret;
|
||||
};
|
36
src/glue/js/i64.d.ts
vendored
Normal file
36
src/glue/js/i64.d.ts
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
declare type I64 = Long;
|
||||
|
||||
declare function i64_new(lo: i32, hi?: i32): I64;
|
||||
declare function i64_low(value: I64): i32;
|
||||
declare function i64_high(value: I64): i32;
|
||||
|
||||
declare function i64_add(left: I64, right: I64): I64;
|
||||
declare function i64_sub(left: I64, right: I64): I64;
|
||||
declare function i64_mul(left: I64, right: I64): I64;
|
||||
declare function i64_div(left: I64, right: I64): I64;
|
||||
declare function i64_div_u(left: I64, right: I64): I64;
|
||||
declare function i64_rem(left: I64, right: I64): I64;
|
||||
declare function i64_rem_u(left: I64, right: I64): I64;
|
||||
declare function i64_and(left: I64, right: I64): I64;
|
||||
declare function i64_or(left: I64, right: I64): I64;
|
||||
declare function i64_xor(left: I64, right: I64): I64;
|
||||
declare function i64_shl(left: I64, right: I64): I64;
|
||||
declare function i64_shr(left: I64, right: I64): I64;
|
||||
declare function i64_shr_u(left: I64, right: I64): I64;
|
||||
declare function i64_not(value: I64): I64;
|
||||
|
||||
declare function i64_align(value: I64, alignment: i32): I64;
|
||||
|
||||
declare function i64_is_i8(value: I64): bool;
|
||||
declare function i64_is_i16(value: I64): bool;
|
||||
declare function i64_is_i32(value: I64): bool;
|
||||
declare function i64_is_u8(value: I64): bool;
|
||||
declare function i64_is_u16(value: I64): bool;
|
||||
declare function i64_is_u32(value: I64): bool;
|
||||
declare function i64_is_bool(value: I64): bool;
|
||||
declare function i64_is_f32(value: I64): bool;
|
||||
declare function i64_is_f64(value: I64): bool;
|
||||
|
||||
declare function i64_to_f32(value: I64): f64;
|
||||
declare function i64_to_f64(value: I64): f64;
|
||||
declare function i64_to_string(value: I64, unsigned?: bool): string;
|
193
src/glue/js/index.ts
Normal file
193
src/glue/js/index.ts
Normal file
@ -0,0 +1,193 @@
|
||||
import "../../../std/portable";
|
||||
|
||||
// Copy Binaryen exports to global scope
|
||||
|
||||
declare const global: any;
|
||||
declare function require(name: string): any;
|
||||
|
||||
const binaryen: any = global.Binaryen || require("binaryen");
|
||||
|
||||
for (let key in binaryen)
|
||||
if (key.startsWith("_Binaryen") || key.startsWith("_Relooper"))
|
||||
global[key] = (<any>binaryen)[key];
|
||||
|
||||
// Use Binaryen's heap instead of std heap
|
||||
|
||||
global.allocate_memory = function(size: number): number {
|
||||
if (!size) return 0; // should be safe in our case
|
||||
return (<any>binaryen)._malloc(size);
|
||||
};
|
||||
|
||||
global.free_memory = function(ptr: number): void {
|
||||
if (ptr) (<any>binaryen)._free(ptr);
|
||||
};
|
||||
|
||||
global.move_memory = function(dest: number, src: number, n: number): number {
|
||||
return (<any>binaryen)._memmove(dest, src, n);
|
||||
};
|
||||
|
||||
global.store = function(ptr: number, val: number): void {
|
||||
(<any>binaryen).HEAPU8[ptr] = val;
|
||||
};
|
||||
|
||||
global.load = function(ptr: number): number {
|
||||
return (<any>binaryen).HEAPU8[ptr];
|
||||
};
|
||||
|
||||
// Implement module stubs
|
||||
|
||||
import { Module } from "../../module";
|
||||
|
||||
Module.prototype.toText = function toText() {
|
||||
var previousPrint = binaryen.print;
|
||||
var ret = "";
|
||||
binaryen.print = (x: string) => { ret += x + "\n" };
|
||||
this.print();
|
||||
binaryen.print = previousPrint;
|
||||
return ret;
|
||||
};
|
||||
|
||||
Module.prototype.toAsmjs = function toAsmjs() {
|
||||
var previousPrint = binaryen.print;
|
||||
var ret = "";
|
||||
binaryen.print = (x: string) => { ret += x + "\n" };
|
||||
this.printAsmjs();
|
||||
binaryen.print = previousPrint;
|
||||
return ret;
|
||||
};
|
||||
|
||||
// Implement I64 using long.js
|
||||
|
||||
import * as Long from "long";
|
||||
|
||||
/// <reference path="./i64.d.ts" />
|
||||
|
||||
global.i64_new = function(lo: number, hi: number = 0): I64 {
|
||||
return Long.fromBits(lo, hi);
|
||||
};
|
||||
|
||||
global.i64_low = function(value: I64): i32 {
|
||||
return value.low;
|
||||
};
|
||||
|
||||
global.i64_high = function(value: I64): i32 {
|
||||
return value.high;
|
||||
};
|
||||
|
||||
global.i64_add = function(left: I64, right: I64): I64 {
|
||||
return left.add(right);
|
||||
};
|
||||
|
||||
global.i64_sub = function(left: I64, right: I64): I64 {
|
||||
return left.sub(right);
|
||||
};
|
||||
|
||||
global.i64_mul = function(left: I64, right: I64): I64 {
|
||||
return left.mul(right);
|
||||
};
|
||||
|
||||
global.i64_div = function(left: I64, right: I64): I64 {
|
||||
return left.div(right);
|
||||
};
|
||||
|
||||
global.i64_div_u = function(left: I64, right: I64): I64 {
|
||||
return left.toUnsigned().div(right.toUnsigned()).toSigned();
|
||||
};
|
||||
|
||||
global.i64_rem = function(left: I64, right: I64): I64 {
|
||||
return left.mod(right);
|
||||
};
|
||||
|
||||
global.i64_rem_u = function(left: I64, right: I64): I64 {
|
||||
return left.toUnsigned().mod(right.toUnsigned()).toSigned();
|
||||
};
|
||||
|
||||
global.i64_and = function(left: I64, right: I64): I64 {
|
||||
return left.and(right);
|
||||
};
|
||||
|
||||
global.i64_or = function(left: I64, right: I64): I64 {
|
||||
return left.or(right);
|
||||
};
|
||||
|
||||
global.i64_xor = function(left: I64, right: I64): I64 {
|
||||
return left.xor(right);
|
||||
};
|
||||
|
||||
global.i64_shl = function(left: I64, right: I64): I64 {
|
||||
return left.shl(right);
|
||||
};
|
||||
|
||||
global.i64_shr = function(left: I64, right: I64): I64 {
|
||||
return left.shr(right);
|
||||
};
|
||||
|
||||
global.i64_shr_u = function(left: I64, right: I64): I64 {
|
||||
return left.shru(right);
|
||||
};
|
||||
|
||||
global.i64_not = function(value: I64): I64 {
|
||||
return value.not();
|
||||
};
|
||||
|
||||
global.i64_align = function(value: I64, alignment: i32): I64 {
|
||||
assert(alignment && (alignment & (alignment - 1)) == 0);
|
||||
var mask = Long.fromInt(alignment - 1);
|
||||
return value.add(mask).and(mask.not());
|
||||
};
|
||||
|
||||
global.i64_is_i8 = function(value: I64): bool {
|
||||
return value.high === 0 && (value.low >= 0 && value.low <= i8.MAX_VALUE)
|
||||
|| value.high === -1 && (value.low >= i8.MIN_VALUE && value.low < 0);
|
||||
};
|
||||
|
||||
global.i64_is_i16 = function(value: I64): bool {
|
||||
return value.high === 0 && (value.low >= 0 && value.low <= i16.MAX_VALUE)
|
||||
|| value.high === -1 && (value.low >= i16.MIN_VALUE && value.low < 0);
|
||||
};
|
||||
|
||||
global.i64_is_i32 = function(value: I64): bool {
|
||||
return (value.high === 0 && value.low >= 0) || (value.high === -1 && value.low < 0);
|
||||
};
|
||||
|
||||
global.i64_is_u8 = function(value: I64): bool {
|
||||
return value.high === 0 && value.low >= 0 && value.low <= u8.MAX_VALUE;
|
||||
};
|
||||
|
||||
global.i64_is_u16 = function(value: I64): bool {
|
||||
return value.high === 0 && value.low >= 0 && value.low <= u16.MAX_VALUE;
|
||||
};
|
||||
|
||||
global.i64_is_u32 = function(value: I64): bool {
|
||||
return value.high === 0;
|
||||
};
|
||||
|
||||
global.i64_is_bool = function(value: I64): bool {
|
||||
return value.high === 0 && (value.low === 0 || value.low === 1);
|
||||
};
|
||||
|
||||
const minSafeF32 = Long.fromNumber(f32.MIN_SAFE_INTEGER);
|
||||
const maxSafeF32 = Long.fromNumber(f32.MAX_SAFE_INTEGER);
|
||||
|
||||
global.i64_is_f32 = function(value: I64): bool {
|
||||
return value.gte(minSafeF32) && value.lte(maxSafeF32);
|
||||
};
|
||||
|
||||
const minSafeF64 = Long.fromNumber(f64.MIN_SAFE_INTEGER);
|
||||
const maxSafeF64 = Long.fromNumber(f64.MAX_SAFE_INTEGER);
|
||||
|
||||
global.i64_is_f64 = function(value: I64): bool {
|
||||
return value.gte(minSafeF64) && value.lte(maxSafeF64);
|
||||
};
|
||||
|
||||
global.i64_to_f32 = function(value: I64): f64 {
|
||||
return global.Math.fround(value.toNumber());
|
||||
};
|
||||
|
||||
global.i64_to_f64 = function(value: I64): f64 {
|
||||
return value.toNumber();
|
||||
};
|
||||
|
||||
global.i64_to_string = function(value: I64, unsigned: bool = false): string {
|
||||
return (unsigned ? value.toUnsigned() : value).toString(10);
|
||||
};
|
164
src/glue/wasm/index.ts
Normal file
164
src/glue/wasm/index.ts
Normal file
@ -0,0 +1,164 @@
|
||||
type I64 = i64;
|
||||
|
||||
@global
|
||||
function i64_new(lo: i32, hi: i32 = 0): I64 {
|
||||
return lo | (hi << 32);
|
||||
}
|
||||
|
||||
@global
|
||||
function i64_low(value: I64): i32 {
|
||||
return <i32>value;
|
||||
}
|
||||
|
||||
@global
|
||||
function i64_high(value: I64): i32 {
|
||||
return <i32>(value >>> 32);
|
||||
}
|
||||
|
||||
@global
|
||||
function i64_add(left: I64, right: I64): I64 {
|
||||
return left + right;
|
||||
}
|
||||
|
||||
@global
|
||||
function i64_sub(left: I64, right: I64): I64 {
|
||||
return left - right;
|
||||
}
|
||||
|
||||
@global
|
||||
function i64_mul(left: I64, right: I64): I64 {
|
||||
return left * right;
|
||||
}
|
||||
|
||||
@global
|
||||
function i64_div(left: I64, right: I64): I64 {
|
||||
return left / right;
|
||||
}
|
||||
|
||||
@global
|
||||
function i64_div_u(left: I64, right: I64): I64 {
|
||||
return <u64>left / <u64>right;
|
||||
}
|
||||
|
||||
@global
|
||||
function i64_rem(left: I64, right: I64): I64 {
|
||||
return left % right;
|
||||
}
|
||||
|
||||
@global
|
||||
function i64_rem_u(left: I64, right: I64): I64 {
|
||||
return <u64>left % <u64>right;
|
||||
}
|
||||
|
||||
@global
|
||||
function i64_and(left: I64, right: I64): I64 {
|
||||
return left & right;
|
||||
}
|
||||
|
||||
@global
|
||||
function i64_or(left: I64, right: I64): I64 {
|
||||
return left | right;
|
||||
}
|
||||
|
||||
@global
|
||||
function i64_xor(left: I64, right: I64): I64 {
|
||||
return left ^ right;
|
||||
}
|
||||
|
||||
@global
|
||||
function i64_shl(left: I64, right: I64): I64 {
|
||||
return left << right;
|
||||
}
|
||||
|
||||
@global
|
||||
function i64_shr(left: I64, right: I64): I64 {
|
||||
return left >> right;
|
||||
}
|
||||
|
||||
@global
|
||||
function i64_shr_u(left: I64, right: I64): I64 {
|
||||
return left >>> right;
|
||||
}
|
||||
|
||||
@global
|
||||
function i64_not(value: I64): I64 {
|
||||
return ~value;
|
||||
}
|
||||
|
||||
@global
|
||||
function i64_align(value: I64, alignment: i64): I64 {
|
||||
var mask: i64 = alignment - 1;
|
||||
assert(alignment && (alignment & mask) == 0);
|
||||
return (value + mask) & ~mask;
|
||||
}
|
||||
|
||||
@global
|
||||
function i64_is_i8(value: I64): bool {
|
||||
return value >= i8.MIN_VALUE && value <= i8.MAX_VALUE;
|
||||
}
|
||||
|
||||
@global
|
||||
function i64_is_i16(value: I64): bool {
|
||||
return value >= i16.MIN_VALUE && value <= i16.MAX_VALUE;
|
||||
}
|
||||
|
||||
@global
|
||||
function i64_is_i32(value: I64): bool {
|
||||
return value >= i32.MIN_VALUE && value <= i32.MAX_VALUE;
|
||||
}
|
||||
|
||||
@global
|
||||
function i64_is_u8(value: I64): bool {
|
||||
return value >= 0 && value <= u8.MAX_VALUE;
|
||||
}
|
||||
|
||||
@global
|
||||
function i64_is_u16(value: I64): bool {
|
||||
return value >= 0 && value <= u16.MAX_VALUE;
|
||||
}
|
||||
|
||||
@global
|
||||
function i64_is_u32(value: I64): bool {
|
||||
return value >= 0 && value <= u32.MAX_VALUE;
|
||||
}
|
||||
|
||||
@global
|
||||
function i64_is_bool(value: I64): bool {
|
||||
return value === 0 || value === 1;
|
||||
}
|
||||
|
||||
@global
|
||||
function i64_is_f32(value: I64): bool {
|
||||
return value >= f32.MIN_SAFE_INTEGER && value <= f32.MAX_SAFE_INTEGER;
|
||||
}
|
||||
|
||||
@global
|
||||
function i64_is_f64(value: I64): bool {
|
||||
return value >= f64.MIN_SAFE_INTEGER && value <= f64.MAX_SAFE_INTEGER;
|
||||
}
|
||||
|
||||
@global
|
||||
function i64_to_f32(value: I64): f32 {
|
||||
return <f32>value;
|
||||
}
|
||||
|
||||
@global
|
||||
function i64_to_f64(value: I64): f64 {
|
||||
return <f64>value;
|
||||
}
|
||||
|
||||
import { CharCode } from "../../util/charcode";
|
||||
|
||||
@global
|
||||
function i64_to_string(value: I64): string {
|
||||
var chars = new Array<u16>();
|
||||
if (value < 0) {
|
||||
chars.push(CharCode.MINUS);
|
||||
value = -value;
|
||||
}
|
||||
do {
|
||||
chars.push(CharCode._0 + (value % 10));
|
||||
value /= 10;
|
||||
} while (value);
|
||||
return String.fromCharCodes(chars);
|
||||
}
|
6
src/glue/wasm/tsconfig.json
Normal file
6
src/glue/wasm/tsconfig.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"extends": "../../../std/assembly.json",
|
||||
"include": [
|
||||
"./**/*.ts"
|
||||
]
|
||||
}
|
Reference in New Issue
Block a user