mirror of
https://github.com/fluencelabs/assemblyscript
synced 2025-06-11 05:51:38 +00:00
if that's what's necessary
This commit is contained in:
@ -91,6 +91,7 @@ export namespace BuiltinSymbols {
|
||||
// std/builtins.ts
|
||||
export const isInteger = "~lib/builtins/isInteger";
|
||||
export const isFloat = "~lib/builtins/isFloat";
|
||||
export const isBoolean = "~lib/builtins/isBoolean";
|
||||
export const isSigned = "~lib/builtins/isSigned";
|
||||
export const isReference = "~lib/builtins/isReference";
|
||||
export const isString = "~lib/builtins/isString";
|
||||
@ -542,6 +543,14 @@ export function compileCall(
|
||||
? module.createI32(1)
|
||||
: module.createI32(0);
|
||||
}
|
||||
case BuiltinSymbols.isBoolean: { // isBoolean<T!>() / isBoolean<T?>(value: T) -> bool
|
||||
let type = evaluateConstantType(compiler, typeArguments, operands, reportNode);
|
||||
compiler.currentType = Type.bool;
|
||||
if (!type) return module.createUnreachable();
|
||||
return type == Type.bool
|
||||
? module.createI32(1)
|
||||
: module.createI32(0);
|
||||
}
|
||||
case BuiltinSymbols.isSigned: { // isSigned<T!>() / isSigned<T?>(value: T) -> bool
|
||||
let type = evaluateConstantType(compiler, typeArguments, operands, reportNode);
|
||||
compiler.currentType = Type.bool;
|
||||
|
@ -2,13 +2,16 @@ import { HEAP_BASE, memory } from "../memory";
|
||||
import { AL_MASK, MAX_SIZE_32 } from "../util/allocator";
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy var startOffset: usize = (HEAP_BASE + AL_MASK) & ~AL_MASK;
|
||||
@lazy
|
||||
var startOffset: usize = (HEAP_BASE + AL_MASK) & ~AL_MASK;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy var offset: usize = startOffset;
|
||||
@lazy
|
||||
var offset: usize = startOffset;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@unsafe @global function __memory_allocate(size: usize): usize {
|
||||
@unsafe @global
|
||||
function __memory_allocate(size: usize): usize {
|
||||
if (size > MAX_SIZE_32) unreachable();
|
||||
var ptr = offset;
|
||||
var newPtr = (ptr + max<usize>(size, 1) + AL_MASK) & ~AL_MASK;
|
||||
@ -27,10 +30,12 @@ import { AL_MASK, MAX_SIZE_32 } from "../util/allocator";
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@unsafe @global function __memory_free(ptr: usize): void {
|
||||
@unsafe @global
|
||||
function __memory_free(ptr: usize): void {
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@unsafe @global function __memory_reset(): void {
|
||||
@unsafe @global
|
||||
function __memory_reset(): void {
|
||||
offset = startOffset;
|
||||
}
|
||||
|
@ -1,15 +1,19 @@
|
||||
// @ts-ignore: decorator
|
||||
@unsafe declare function _malloc(size: usize): usize;
|
||||
@unsafe
|
||||
declare function _malloc(size: usize): usize;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@unsafe declare function _free(ptr: usize): void;
|
||||
@unsafe
|
||||
declare function _free(ptr: usize): void;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@unsafe @global function __memory_allocate(size: usize): usize {
|
||||
@unsafe @global
|
||||
function __memory_allocate(size: usize): usize {
|
||||
return _malloc(size);
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@unsafe @global function __memory_free(ptr: usize): void {
|
||||
@unsafe @global
|
||||
function __memory_free(ptr: usize): void {
|
||||
_free(ptr);
|
||||
}
|
||||
|
@ -1,15 +1,19 @@
|
||||
// @ts-ignore: decorator
|
||||
@unsafe declare function malloc(size: usize): usize;
|
||||
@unsafe
|
||||
declare function malloc(size: usize): usize;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@unsafe declare function free(ptr: usize): void;
|
||||
@unsafe
|
||||
declare function free(ptr: usize): void;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@unsafe @global function __memory_allocate(size: usize): usize {
|
||||
@unsafe @global
|
||||
function __memory_allocate(size: usize): usize {
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@unsafe @global function __memory_free(ptr: usize): void {
|
||||
@unsafe @global
|
||||
function __memory_free(ptr: usize): void {
|
||||
free(ptr);
|
||||
}
|
||||
|
@ -423,7 +423,8 @@ var ROOT: Root = changetype<Root>(0);
|
||||
|
||||
/** Allocates a chunk of memory. */
|
||||
// @ts-ignore: decorator
|
||||
@unsafe @global function __memory_allocate(size: usize): usize {
|
||||
@unsafe @global
|
||||
function __memory_allocate(size: usize): usize {
|
||||
// initialize if necessary
|
||||
var root = ROOT;
|
||||
if (!root) {
|
||||
@ -471,8 +472,9 @@ var ROOT: Root = changetype<Root>(0);
|
||||
}
|
||||
|
||||
/** Frees the chunk of memory at the specified address. */
|
||||
// @ts-ignore
|
||||
@unsafe @global function __memory_free(data: usize): void {
|
||||
// @ts-ignore: decorator
|
||||
@unsafe @global
|
||||
function __memory_free(data: usize): void {
|
||||
if (data) {
|
||||
let root = ROOT;
|
||||
if (root) {
|
||||
|
@ -95,8 +95,7 @@ export class Array<T> extends ArrayBufferView {
|
||||
if (start < end) {
|
||||
memory.fill(
|
||||
dataStart + <usize>start,
|
||||
// @ts-ignore: cast
|
||||
<u8>value,
|
||||
u8(value),
|
||||
<usize>(end - start)
|
||||
);
|
||||
}
|
||||
@ -269,8 +268,10 @@ export class Array<T> extends ArrayBufferView {
|
||||
base + sizeof<T>(),
|
||||
<usize>lastIndex << alignof<T>()
|
||||
);
|
||||
// @ts-ignore: cast
|
||||
store<T>(base + (<usize>lastIndex << alignof<T>()), <T>null);
|
||||
store<T>(base + (<usize>lastIndex << alignof<T>()),
|
||||
// @ts-ignore: cast
|
||||
<T>null
|
||||
);
|
||||
this.length_ = lastIndex;
|
||||
return element;
|
||||
}
|
||||
@ -376,11 +377,8 @@ export class Array<T> extends ArrayBufferView {
|
||||
}
|
||||
|
||||
join(separator: string = ","): string {
|
||||
if (isInteger<T>()) {
|
||||
// @ts-ignore: type
|
||||
if (value instanceof bool) return this.join_bool(separator);
|
||||
return this.join_int(separator);
|
||||
}
|
||||
if (isBoolean<T>()) return this.join_bool(separator);
|
||||
if (isInteger<T>()) return this.join_int(separator);
|
||||
if (isFloat<T>()) return this.join_flt(separator);
|
||||
if (isString<T>()) return this.join_str(separator);
|
||||
if (isArray<T>()) return this.join_arr(separator);
|
||||
@ -403,8 +401,7 @@ export class Array<T> extends ArrayBufferView {
|
||||
var value: bool;
|
||||
for (let i = 0; i < lastIndex; ++i) {
|
||||
value = load<bool>(dataStart + i);
|
||||
// @ts-ignore: cast
|
||||
valueLen = 4 + <i32>(!value);
|
||||
valueLen = 4 + i32(!value);
|
||||
memory.copy(
|
||||
result + (<usize>offset << 1),
|
||||
changetype<usize>(select("true", "false", value)),
|
||||
@ -421,8 +418,7 @@ export class Array<T> extends ArrayBufferView {
|
||||
}
|
||||
}
|
||||
value = load<bool>(dataStart + <usize>lastIndex);
|
||||
// @ts-ignore: cast
|
||||
valueLen = 4 + <i32>(!value);
|
||||
valueLen = 4 + i32(!value);
|
||||
memory.copy(
|
||||
result + (<usize>offset << 1),
|
||||
changetype<usize>(select("true", "false", value)),
|
||||
@ -445,8 +441,7 @@ export class Array<T> extends ArrayBufferView {
|
||||
if (!lastIndex) return changetype<string>(itoa<T>(load<T>(dataStart)));
|
||||
|
||||
var sepLen = separator.length;
|
||||
// @ts-ignore: cast
|
||||
const valueLen = (sizeof<T>() <= 4 ? 10 : 20) + <i32>isSigned<T>();
|
||||
const valueLen = (sizeof<T>() <= 4 ? 10 : 20) + i32(isSigned<T>());
|
||||
var estLen = (valueLen + sepLen) * lastIndex + valueLen;
|
||||
var result = runtime.alloc(estLen << 1);
|
||||
var offset = 0;
|
||||
@ -477,8 +472,12 @@ export class Array<T> extends ArrayBufferView {
|
||||
var lastIndex = this.length_ - 1;
|
||||
if (lastIndex < 0) return "";
|
||||
var dataStart = this.dataStart;
|
||||
// @ts-ignore: type
|
||||
if (!lastIndex) return changetype<string>(dtoa(load<T>(dataStart)));
|
||||
if (!lastIndex) {
|
||||
return changetype<string>(dtoa(
|
||||
// @ts-ignore: type
|
||||
load<T>(dataStart))
|
||||
);
|
||||
}
|
||||
|
||||
const valueLen = MAX_DOUBLE_LENGTH;
|
||||
var sepLen = separator.length;
|
||||
@ -488,8 +487,10 @@ export class Array<T> extends ArrayBufferView {
|
||||
var value: T;
|
||||
for (let i = 0; i < lastIndex; ++i) {
|
||||
value = load<T>(dataStart + (<usize>i << alignof<T>()));
|
||||
// @ts-ignore: type
|
||||
offset += dtoa_stream(result, offset, value);
|
||||
offset += dtoa_stream(result, offset,
|
||||
// @ts-ignore: type
|
||||
value
|
||||
);
|
||||
if (sepLen) {
|
||||
memory.copy(
|
||||
result + (<usize>offset << 1),
|
||||
@ -500,8 +501,10 @@ export class Array<T> extends ArrayBufferView {
|
||||
}
|
||||
}
|
||||
value = load<T>(dataStart + (<usize>lastIndex << alignof<T>()));
|
||||
// @ts-ignore: type
|
||||
offset += dtoa_stream(result, offset, value);
|
||||
offset += dtoa_stream(result, offset,
|
||||
// @ts-ignore: type
|
||||
value
|
||||
);
|
||||
if (estLen > offset) {
|
||||
let trimmed = changetype<string>(result).substring(0, offset);
|
||||
runtime.free(result);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,11 +1,13 @@
|
||||
// Largely based on Bach Le's μgc, see: https://github.com/bullno1/ugc
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@inline const TRACE = false;
|
||||
@inline
|
||||
const TRACE = false;
|
||||
|
||||
/** Size of a managed object header. */
|
||||
// @ts-ignore: decorator
|
||||
@inline export const HEADER_SIZE: usize = (offsetof<ManagedObject>() + AL_MASK) & ~AL_MASK;
|
||||
@inline
|
||||
export const HEADER_SIZE: usize = (offsetof<ManagedObject>() + AL_MASK) & ~AL_MASK;
|
||||
|
||||
import { AL_MASK, MAX_SIZE_32 } from "../util/allocator";
|
||||
import { gc } from "../gc";
|
||||
@ -148,8 +150,7 @@ function step(): void {
|
||||
if (obj !== toSpace) {
|
||||
if (TRACE) trace("gc~step/MARK iterate", 1, objToRef(obj));
|
||||
iter = obj;
|
||||
// @ts-ignore: cast
|
||||
obj.color = <i32>!white;
|
||||
obj.color = i32(!white);
|
||||
// if (TRACE) {
|
||||
// trace(" next/prev/hook", 3,
|
||||
// changetype<usize>(obj.next),
|
||||
@ -166,8 +167,7 @@ function step(): void {
|
||||
let from = fromSpace;
|
||||
fromSpace = toSpace;
|
||||
toSpace = from;
|
||||
// @ts-ignore: cast
|
||||
white = <i32>!white;
|
||||
white = i32(!white);
|
||||
iter = from.next;
|
||||
state = State.SWEEP;
|
||||
if (TRACE) trace("gc~state = SWEEP");
|
||||
@ -193,17 +193,20 @@ function step(): void {
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@inline function refToObj(ref: usize): ManagedObject {
|
||||
@inline
|
||||
function refToObj(ref: usize): ManagedObject {
|
||||
return changetype<ManagedObject>(ref - HEADER_SIZE);
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@inline function objToRef(obj: ManagedObject): usize {
|
||||
@inline
|
||||
function objToRef(obj: ManagedObject): usize {
|
||||
return changetype<usize>(obj) + HEADER_SIZE;
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@global @unsafe export function __gc_allocate( // TODO: make this register only / reuse header
|
||||
@global @unsafe
|
||||
export function __gc_allocate( // TODO: make this register only / reuse header
|
||||
size: usize,
|
||||
markFn: (ref: usize) => void
|
||||
): usize {
|
||||
@ -218,15 +221,16 @@ function step(): void {
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@global @unsafe export function __gc_link(parentRef: usize, childRef: usize): void {
|
||||
@global @unsafe
|
||||
export function __gc_link(parentRef: usize, childRef: usize): void {
|
||||
if (TRACE) trace("gc.link", 2, parentRef, childRef);
|
||||
var parent = refToObj(parentRef);
|
||||
// @ts-ignore: cast
|
||||
if (parent.color == <i32>!white && refToObj(childRef).color == white) parent.makeGray();
|
||||
if (parent.color == i32(!white) && refToObj(childRef).color == white) parent.makeGray();
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@global @unsafe export function __gc_mark(ref: usize): void {
|
||||
@global @unsafe
|
||||
export function __gc_mark(ref: usize): void {
|
||||
if (TRACE) trace("gc.mark", 1, ref);
|
||||
if (ref) {
|
||||
let obj = refToObj(ref);
|
||||
@ -235,7 +239,8 @@ function step(): void {
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@global @unsafe export function __gc_collect(): void {
|
||||
@global @unsafe
|
||||
export function __gc_collect(): void {
|
||||
if (TRACE) trace("gc.collect");
|
||||
// begin collecting if not yet collecting
|
||||
switch (state) {
|
||||
|
@ -1,8 +1,11 @@
|
||||
// @ts-ignore: decorator
|
||||
@builtin export declare function ERROR(message?: string): void;
|
||||
@builtin
|
||||
export declare function ERROR(message?: string): void;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@builtin export declare function WARNING(message?: string): void;
|
||||
@builtin
|
||||
export declare function WARNING(message?: string): void;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@builtin export declare function INFO(message?: string): void;
|
||||
@builtin
|
||||
export declare function INFO(message?: string): void;
|
||||
|
@ -2,39 +2,53 @@
|
||||
export namespace gc {
|
||||
|
||||
/** Whether the garbage collector interface is implemented. */
|
||||
// @ts-ignore: decorator, undefined
|
||||
@lazy export const implemented: bool = isDefined(__gc_register);
|
||||
// @ts-ignore: decorator
|
||||
@lazy
|
||||
export const implemented: bool = isDefined(
|
||||
// @ts-ignore: stub
|
||||
__gc_register
|
||||
);
|
||||
|
||||
/** Gets the computed unique class id of a class type. */
|
||||
@unsafe @builtin export declare function classId<T>(): u32;
|
||||
// @ts-ignore: decorator
|
||||
@unsafe @builtin
|
||||
export declare function classId<T>(): u32;
|
||||
|
||||
/** Iterates reference root objects. */
|
||||
@unsafe @builtin export declare function iterateRoots(fn: (ref: usize) => void): void;
|
||||
// @ts-ignore: decorator
|
||||
@unsafe @builtin
|
||||
export declare function iterateRoots(fn: (ref: usize) => void): void;
|
||||
|
||||
/** Registers a managed object to be tracked by the garbage collector. */
|
||||
@unsafe export function register(ref: usize): void {
|
||||
// @ts-ignore: undefined
|
||||
// @ts-ignore: decorator
|
||||
@unsafe
|
||||
export function register(ref: usize): void {
|
||||
// @ts-ignore: stub
|
||||
if (isDefined(__gc_register)) __gc_register(ref);
|
||||
else ERROR("missing implementation: gc.register");
|
||||
}
|
||||
|
||||
/** Links a registered object with the registered object now referencing it. */
|
||||
@unsafe export function link(ref: usize, parentRef: usize): void {
|
||||
// @ts-ignore: undefined
|
||||
// @ts-ignore: decorator
|
||||
@unsafe
|
||||
export function link(ref: usize, parentRef: usize): void {
|
||||
// @ts-ignore: stub
|
||||
if (isDefined(__gc_link)) __gc_link(ref, parentRef);
|
||||
else ERROR("missing implementation: gc.link");
|
||||
}
|
||||
|
||||
/** Marks an object as being reachable. */
|
||||
@unsafe export function mark(ref: usize): void {
|
||||
// @ts-ignore: undefined
|
||||
// @ts-ignore: decorator
|
||||
@unsafe
|
||||
export function mark(ref: usize): void {
|
||||
// @ts-ignore: stub
|
||||
if (isDefined(__gc_mark)) __gc_mark(ref);
|
||||
else ERROR("missing implementation: gc.mark");
|
||||
}
|
||||
|
||||
/** Performs a full garbage collection cycle. */
|
||||
export function collect(): void {
|
||||
// @ts-ignore: undefined
|
||||
// @ts-ignore: stub
|
||||
if (isDefined(__gc_collect)) __gc_collect();
|
||||
else WARNING("missing implementation: gc.collect");
|
||||
}
|
||||
|
24
std/assembly/index.d.ts
vendored
24
std/assembly/index.d.ts
vendored
@ -128,6 +128,8 @@ declare function isFinite<T = f32 | f64>(value: T): bool;
|
||||
declare function isInteger<T>(value?: any): value is number;
|
||||
/** Tests if the specified type *or* expression is of a float type. Compiles to a constant. */
|
||||
declare function isFloat<T>(value?: any): value is number;
|
||||
/** Tests if the specified type *or* expression is of a boolean type. */
|
||||
declare function isBoolean<T>(value?: any): value is number;
|
||||
/** Tests if the specified type *or* expression can represent negative numbers. Compiles to a constant. */
|
||||
declare function isSigned<T>(value?: any): value is number;
|
||||
/** Tests if the specified type *or* expression is of a reference type. Compiles to a constant. */
|
||||
@ -200,7 +202,7 @@ declare enum AtomicWaitResult {
|
||||
}
|
||||
|
||||
/** Converts any other numeric value to an 8-bit signed integer. */
|
||||
declare function i8(value: i8 | i16 | i32 | i64 | isize | u8 | u16 | u32 | u64 | usize | bool | f32 | f64): i8;
|
||||
declare function i8(value: any): i8;
|
||||
declare namespace i8 {
|
||||
/** Smallest representable value. */
|
||||
export const MIN_VALUE: i8;
|
||||
@ -208,7 +210,7 @@ declare namespace i8 {
|
||||
export const MAX_VALUE: i8;
|
||||
}
|
||||
/** Converts any other numeric value to a 16-bit signed integer. */
|
||||
declare function i16(value: i8 | i16 | i32 | i64 | isize | u8 | u16 | u32 | u64 | usize | bool | f32 | f64): i8;
|
||||
declare function i16(value: any): i8;
|
||||
declare namespace i16 {
|
||||
/** Smallest representable value. */
|
||||
export const MIN_VALUE: i16;
|
||||
@ -216,7 +218,7 @@ declare namespace i16 {
|
||||
export const MAX_VALUE: i16;
|
||||
}
|
||||
/** Converts any other numeric value to a 32-bit signed integer. */
|
||||
declare function i32(value: i8 | i16 | i32 | i64 | isize | u8 | u16 | u32 | u64 | usize | bool | f32 | f64): i32;
|
||||
declare function i32(value: any): i32;
|
||||
declare namespace i32 {
|
||||
/** Smallest representable value. */
|
||||
export const MIN_VALUE: i32;
|
||||
@ -310,7 +312,7 @@ declare namespace i32 {
|
||||
}
|
||||
}
|
||||
/** Converts any other numeric value to a 64-bit signed integer. */
|
||||
declare function i64(value: i8 | i16 | i32 | i64 | isize | u8 | u16 | u32 | u64 | usize | bool | f32 | f64): i64;
|
||||
declare function i64(value: any): i64;
|
||||
declare namespace i64 {
|
||||
/** Smallest representable value. */
|
||||
export const MIN_VALUE: i64;
|
||||
@ -433,7 +435,7 @@ declare namespace i64 {
|
||||
/** Converts any other numeric value to a 32-bit (in WASM32) respectivel 64-bit (in WASM64) signed integer. */
|
||||
declare var isize: typeof i32 | typeof i64;
|
||||
/** Converts any other numeric value to an 8-bit unsigned integer. */
|
||||
declare function u8(value: i8 | i16 | i32 | i64 | isize | u8 | u16 | u32 | u64 | usize | bool | f32 | f64): i8;
|
||||
declare function u8(value: any): i8;
|
||||
declare namespace u8 {
|
||||
/** Smallest representable value. */
|
||||
export const MIN_VALUE: u8;
|
||||
@ -441,7 +443,7 @@ declare namespace u8 {
|
||||
export const MAX_VALUE: u8;
|
||||
}
|
||||
/** Converts any other numeric value to a 16-bit unsigned integer. */
|
||||
declare function u16(value: i8 | i16 | i32 | i64 | isize | u8 | u16 | u32 | u64 | usize | bool | f32 | f64): i8;
|
||||
declare function u16(value: any): i8;
|
||||
declare namespace u16 {
|
||||
/** Smallest representable value. */
|
||||
export const MIN_VALUE: u16;
|
||||
@ -449,7 +451,7 @@ declare namespace u16 {
|
||||
export const MAX_VALUE: u16;
|
||||
}
|
||||
/** Converts any other numeric value to a 32-bit unsigned integer. */
|
||||
declare function u32(value: i8 | i16 | i32 | i64 | isize | u8 | u16 | u32 | u64 | usize | bool | f32 | f64): i32;
|
||||
declare function u32(value: any): i32;
|
||||
declare namespace u32 {
|
||||
/** Smallest representable value. */
|
||||
export const MIN_VALUE: u32;
|
||||
@ -457,7 +459,7 @@ declare namespace u32 {
|
||||
export const MAX_VALUE: u32;
|
||||
}
|
||||
/** Converts any other numeric value to a 64-bit unsigned integer. */
|
||||
declare function u64(value: i8 | i16 | i32 | i64 | isize | u8 | u16 | u32 | u64 | usize | bool | f32 | f64): i64;
|
||||
declare function u64(value: any): i64;
|
||||
declare namespace u64 {
|
||||
/** Smallest representable value. */
|
||||
export const MIN_VALUE: u64;
|
||||
@ -467,7 +469,7 @@ declare namespace u64 {
|
||||
/** Converts any other numeric value to a 32-bit (in WASM32) respectivel 64-bit (in WASM64) unsigned integer. */
|
||||
declare var usize: typeof u32 | typeof u64;
|
||||
/** Converts any other numeric value to a 1-bit unsigned integer. */
|
||||
declare function bool(value: i8 | i16 | i32 | i64 | isize | u8 | u16 | u32 | u64 | usize | bool | f32 | f64): bool;
|
||||
declare function bool(value: any): bool;
|
||||
declare namespace bool {
|
||||
/** Smallest representable value. */
|
||||
export const MIN_VALUE: bool;
|
||||
@ -475,7 +477,7 @@ declare namespace bool {
|
||||
export const MAX_VALUE: bool;
|
||||
}
|
||||
/** Converts any other numeric value to a 32-bit float. */
|
||||
declare function f32(value: i8 | i16 | i32 | i64 | isize | u8 | u16 | u32 | u64 | usize | bool | f32 | f64): f32;
|
||||
declare function f32(value: any): f32;
|
||||
declare namespace f32 {
|
||||
/** Smallest representable value. */
|
||||
export const MIN_VALUE: f32;
|
||||
@ -495,7 +497,7 @@ declare namespace f32 {
|
||||
export function store(offset: usize, value: f32, immOffset?: usize, immAlign?: usize): void;
|
||||
}
|
||||
/** Converts any other numeric value to a 64-bit float. */
|
||||
declare function f64(value: i8 | i16 | i32 | i64 | isize | u8 | u16 | u32 | u64 | usize | bool | f32 | f64): f64;
|
||||
declare function f64(value: any): f64;
|
||||
declare namespace f64 {
|
||||
/** Smallest representable value. */
|
||||
export const MIN_VALUE: f64;
|
||||
|
@ -4,13 +4,16 @@ import { HASH } from "./util/hash";
|
||||
// A deterministic hash map based on CloseTable from https://github.com/jorendorff/dht
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@inline const INITIAL_CAPACITY = 4;
|
||||
@inline
|
||||
const INITIAL_CAPACITY = 4;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@inline const FILL_FACTOR: f64 = 8 / 3;
|
||||
@inline const
|
||||
FILL_FACTOR: f64 = 8 / 3;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@inline const FREE_FACTOR: f64 = 3 / 4;
|
||||
@inline const
|
||||
FREE_FACTOR: f64 = 3 / 4;
|
||||
|
||||
/** Structure of a map entry. */
|
||||
@unmanaged class MapEntry<K,V> {
|
||||
@ -21,15 +24,18 @@ import { HASH } from "./util/hash";
|
||||
|
||||
/** Empty bit. */
|
||||
// @ts-ignore: decorator
|
||||
@inline const EMPTY: usize = 1 << 0;
|
||||
@inline
|
||||
const EMPTY: usize = 1 << 0;
|
||||
|
||||
/** Size of a bucket. */
|
||||
// @ts-ignore: decorator
|
||||
@inline const BUCKET_SIZE = sizeof<usize>();
|
||||
@inline
|
||||
const BUCKET_SIZE = sizeof<usize>();
|
||||
|
||||
/** Computes the alignment of an entry. */
|
||||
// @ts-ignore: decorator
|
||||
@inline function ENTRY_ALIGN<K,V>(): usize {
|
||||
@inline
|
||||
function ENTRY_ALIGN<K,V>(): usize {
|
||||
// can align to 4 instead of 8 if 32-bit and K/V is <= 32-bits
|
||||
const maxkv = sizeof<K>() > sizeof<V>() ? sizeof<K>() : sizeof<V>();
|
||||
const align = (maxkv > sizeof<usize>() ? maxkv : sizeof<usize>()) - 1;
|
||||
@ -38,7 +44,8 @@ import { HASH } from "./util/hash";
|
||||
|
||||
/** Computes the aligned size of an entry. */
|
||||
// @ts-ignore: decorator
|
||||
@inline function ENTRY_SIZE<K,V>(): usize {
|
||||
@inline
|
||||
function ENTRY_SIZE<K,V>(): usize {
|
||||
const align = ENTRY_ALIGN<K,V>();
|
||||
const size = (offsetof<MapEntry<K,V>>() + align) & ~align;
|
||||
return size;
|
||||
|
@ -43,7 +43,8 @@ function R(z: f64): f64 { // Rational approximation of (asin(x)-x)/x^3
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@inline function expo2(x: f64): f64 { // exp(x)/2 for x >= log(DBL_MAX)
|
||||
@inline
|
||||
function expo2(x: f64): f64 { // exp(x)/2 for x >= log(DBL_MAX)
|
||||
const // see: musl/src/math/__expo2.c
|
||||
k = <u32>2043,
|
||||
kln2 = reinterpret<f64>(0x40962066151ADD8B); // 0x1.62066151add8bp+10
|
||||
@ -52,15 +53,24 @@ function R(z: f64): f64 { // Rational approximation of (asin(x)-x)/x^3
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy var random_seeded = false;
|
||||
@lazy
|
||||
var random_seeded = false;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy var random_state0_64: u64;
|
||||
@lazy
|
||||
var random_state0_64: u64;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy var random_state1_64: u64;
|
||||
@lazy
|
||||
var random_state1_64: u64;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy var random_state0_32: u32;
|
||||
@lazy
|
||||
var random_state0_32: u32;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy var random_state1_32: u32;
|
||||
@lazy
|
||||
var random_state1_32: u32;
|
||||
|
||||
function murmurHash3(h: u64): u64 { // Force all bits of a hash block to avalanche
|
||||
h ^= h >> 33; // see: https://github.com/aappleby/smhasher
|
||||
@ -81,21 +91,36 @@ function splitMix32(h: u32): u32 {
|
||||
export namespace NativeMath {
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy export const E = reinterpret<f64>(0x4005BF0A8B145769); // 2.7182818284590452354
|
||||
@lazy
|
||||
export const E = reinterpret<f64>(0x4005BF0A8B145769); // 2.7182818284590452354
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy export const LN2 = reinterpret<f64>(0x3FE62E42FEFA39EF); // 0.69314718055994530942
|
||||
@lazy
|
||||
export const LN2 = reinterpret<f64>(0x3FE62E42FEFA39EF); // 0.69314718055994530942
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy export const LN10 = reinterpret<f64>(0x40026BB1BBB55516); // 2.30258509299404568402
|
||||
@lazy
|
||||
export const LN10 = reinterpret<f64>(0x40026BB1BBB55516); // 2.30258509299404568402
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy export const LOG2E = reinterpret<f64>(0x3FF71547652B82FE); // 1.4426950408889634074
|
||||
@lazy
|
||||
export const LOG2E = reinterpret<f64>(0x3FF71547652B82FE); // 1.4426950408889634074
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy export const LOG10E = reinterpret<f64>(0x3FDBCB7B1526E50E); // 0.43429448190325182765
|
||||
@lazy
|
||||
export const LOG10E = reinterpret<f64>(0x3FDBCB7B1526E50E); // 0.43429448190325182765
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy export const PI = reinterpret<f64>(0x400921FB54442D18); // 3.14159265358979323846
|
||||
@lazy
|
||||
export const PI = reinterpret<f64>(0x400921FB54442D18); // 3.14159265358979323846
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy export const SQRT1_2 = reinterpret<f64>(0x3FE6A09E667F3BCD); // 0.70710678118654752440
|
||||
@lazy
|
||||
export const SQRT1_2 = reinterpret<f64>(0x3FE6A09E667F3BCD); // 0.70710678118654752440
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy export const SQRT2 = reinterpret<f64>(0x3FF6A09E667F3BCD); // 1.41421356237309504880
|
||||
@lazy
|
||||
export const SQRT2 = reinterpret<f64>(0x3FF6A09E667F3BCD); // 1.41421356237309504880
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@inline export function abs(x: f64): f64 {
|
||||
@ -360,7 +385,8 @@ export namespace NativeMath {
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@inline export function ceil(x: f64): f64 {
|
||||
@inline
|
||||
export function ceil(x: f64): f64 {
|
||||
return builtin_ceil<f64>(x);
|
||||
}
|
||||
|
||||
@ -511,12 +537,14 @@ export namespace NativeMath {
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@inline export function floor(x: f64): f64 {
|
||||
@inline
|
||||
export function floor(x: f64): f64 {
|
||||
return builtin_floor<f64>(x);
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@inline export function fround(x: f64): f32 {
|
||||
@inline
|
||||
export function fround(x: f64): f32 {
|
||||
return <f32>x;
|
||||
}
|
||||
|
||||
@ -777,12 +805,14 @@ export namespace NativeMath {
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@inline export function max(value1: f64, value2: f64): f64 {
|
||||
@inline
|
||||
export function max(value1: f64, value2: f64): f64 {
|
||||
return builtin_max<f64>(value1, value2);
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@inline export function min(value1: f64, value2: f64): f64 {
|
||||
@inline
|
||||
export function min(value1: f64, value2: f64): f64 {
|
||||
return builtin_min<f64>(value1, value2);
|
||||
}
|
||||
|
||||
@ -1011,12 +1041,14 @@ export namespace NativeMath {
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@inline export function round(x: f64): f64 {
|
||||
@inline
|
||||
export function round(x: f64): f64 {
|
||||
return builtin_copysign<f64>(builtin_floor<f64>(x + 0.5), x);
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@inline export function sign(x: f64): f64 {
|
||||
@inline
|
||||
export function sign(x: f64): f64 {
|
||||
if (ASC_SHRINK_LEVEL > 0) {
|
||||
return builtin_abs(x) > 0 ? builtin_copysign<f64>(1, x) : x;
|
||||
} else {
|
||||
@ -1025,11 +1057,11 @@ export namespace NativeMath {
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@inline export function signbit(x: f64): bool {
|
||||
@inline
|
||||
export function signbit(x: f64): bool {
|
||||
// In ECMAScript all NaN values are indistinguishable from each other
|
||||
// so we need handle NaN and negative NaN in similar way
|
||||
// @ts-ignore: type
|
||||
return <bool>(<i32>(reinterpret<u64>(x) >>> 63) & (x == x));
|
||||
return <bool>(<i32>(reinterpret<u64>(x) >>> 63) & i32(x == x));
|
||||
}
|
||||
|
||||
export function sin(x: f64): f64 { // TODO
|
||||
@ -1056,7 +1088,8 @@ export namespace NativeMath {
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@inline export function sqrt(x: f64): f64 {
|
||||
@inline
|
||||
export function sqrt(x: f64): f64 {
|
||||
return builtin_sqrt<f64>(x);
|
||||
}
|
||||
|
||||
@ -1089,7 +1122,8 @@ export namespace NativeMath {
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@inline export function trunc(x: f64): f64 {
|
||||
@inline
|
||||
export function trunc(x: f64): f64 {
|
||||
return builtin_trunc<f64>(x);
|
||||
}
|
||||
|
||||
@ -1247,9 +1281,12 @@ export namespace NativeMath {
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy var rempio2f_y: f64;
|
||||
@lazy
|
||||
var rempio2f_y: f64;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy const PIO2_TABLE: u64[] = [
|
||||
@lazy
|
||||
const PIO2_TABLE: u64[] = [
|
||||
0xA2F9836E4E441529,
|
||||
0xFC2757D1F534DDC0,
|
||||
0xDB6295993C439041,
|
||||
@ -1268,7 +1305,8 @@ function Rf(z: f32): f32 { // Rational approximation of (asin(x)-x)/x^3
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@inline function expo2f(x: f32): f32 { // exp(x)/2 for x >= log(DBL_MAX)
|
||||
@inline
|
||||
function expo2f(x: f32): f32 { // exp(x)/2 for x >= log(DBL_MAX)
|
||||
const // see: musl/src/math/__expo2f.c
|
||||
k = <u32>235,
|
||||
kln2 = reinterpret<f32>(0x4322E3BC); // 0x1.45c778p+7f
|
||||
@ -1277,7 +1315,8 @@ function Rf(z: f32): f32 { // Rational approximation of (asin(x)-x)/x^3
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@inline function pio2_large_quot(x: f32, u: i32): i32 { // see: jdh8/metallic/blob/master/src/math/float/rem_pio2f.c
|
||||
@inline
|
||||
function pio2_large_quot(x: f32, u: i32): i32 { // see: jdh8/metallic/blob/master/src/math/float/rem_pio2f.c
|
||||
const coeff = reinterpret<f64>(0x3BF921FB54442D18); // π * 0x1p-65 = 8.51530395021638647334e-20
|
||||
const bits = PIO2_TABLE;
|
||||
|
||||
@ -1307,7 +1346,8 @@ function Rf(z: f32): f32 { // Rational approximation of (asin(x)-x)/x^3
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@inline function rempio2f(x: f32, u: u32, sign: i32): i32 { // see: jdh8/metallic/blob/master/src/math/float/rem_pio2f.c
|
||||
@inline
|
||||
function rempio2f(x: f32, u: u32, sign: i32): i32 { // see: jdh8/metallic/blob/master/src/math/float/rem_pio2f.c
|
||||
const pi2hi = reinterpret<f64>(0x3FF921FB50000000); // 1.57079631090164184570
|
||||
const pi2lo = reinterpret<f64>(0x3E5110B4611A6263); // 1.58932547735281966916e-8
|
||||
const _2_pi = reinterpret<f64>(0x3FE45F306DC9C883); // 0.63661977236758134308
|
||||
@ -1324,7 +1364,8 @@ function Rf(z: f32): f32 { // Rational approximation of (asin(x)-x)/x^3
|
||||
|
||||
/* |sin(x)/x - s(x)| < 2**-37.5 (~[-4.89e-12, 4.824e-12]). */
|
||||
// @ts-ignore: decorator
|
||||
@inline function sin_kernf(x: f64): f32 { // see: musl/tree/src/math/__sindf.c
|
||||
@inline
|
||||
function sin_kernf(x: f64): f32 { // see: musl/tree/src/math/__sindf.c
|
||||
const S1 = reinterpret<f64>(0xBFC5555554CBAC77); // -0x15555554cbac77.0p-55
|
||||
const S2 = reinterpret<f64>(0x3F811110896EFBB2); // 0x111110896efbb2.0p-59
|
||||
const S3 = reinterpret<f64>(0xBF2A00F9E2CAE774); // -0x1a00f9e2cae774.0p-65
|
||||
@ -1339,7 +1380,8 @@ function Rf(z: f32): f32 { // Rational approximation of (asin(x)-x)/x^3
|
||||
|
||||
/* |cos(x) - c(x)| < 2**-34.1 (~[-5.37e-11, 5.295e-11]). */
|
||||
// @ts-ignore: decorator
|
||||
@inline function cos_kernf(x: f64): f32 { // see: musl/tree/src/math/__cosdf.c
|
||||
@inline
|
||||
function cos_kernf(x: f64): f32 { // see: musl/tree/src/math/__cosdf.c
|
||||
const C0 = reinterpret<f64>(0xBFDFFFFFFD0C5E81); // -0x1ffffffd0c5e81.0p-54
|
||||
const C1 = reinterpret<f64>(0x3FA55553E1053A42); // 0x155553e1053a42.0p-57
|
||||
const C2 = reinterpret<f64>(0xBF56C087E80F1E27); // -0x16c087e80f1e27.0p-62
|
||||
@ -1353,7 +1395,8 @@ function Rf(z: f32): f32 { // Rational approximation of (asin(x)-x)/x^3
|
||||
|
||||
/* |tan(x)/x - t(x)| < 2**-25.5 (~[-2e-08, 2e-08]). */
|
||||
// @ts-ignore: decorator
|
||||
@inline function tan_kernf(x: f64, odd: i32): f32 { // see: musl/tree/src/math/__tandf.c
|
||||
@inline
|
||||
function tan_kernf(x: f64, odd: i32): f32 { // see: musl/tree/src/math/__tandf.c
|
||||
|
||||
const T0 = reinterpret<f64>(0x3FD5554D3418C99F); /* 0x15554d3418c99f.0p-54 */
|
||||
const T1 = reinterpret<f64>(0x3FC112FD38999F72); /* 0x1112fd38999f72.0p-55 */
|
||||
@ -1376,30 +1419,48 @@ function Rf(z: f32): f32 { // Rational approximation of (asin(x)-x)/x^3
|
||||
export namespace NativeMathf {
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy export const E = <f32>NativeMath.E;
|
||||
// @ts-ignore: decorator
|
||||
@lazy export const LN2 = <f32>NativeMath.LN2;
|
||||
// @ts-ignore: decorator
|
||||
@lazy export const LN10 = <f32>NativeMath.LN10;
|
||||
// @ts-ignore: decorator
|
||||
@lazy export const LOG2E = <f32>NativeMath.LOG2E;
|
||||
// @ts-ignore: decorator
|
||||
@lazy export const LOG10E = <f32>NativeMath.LOG10E;
|
||||
// @ts-ignore: decorator
|
||||
@lazy export const PI = <f32>NativeMath.PI;
|
||||
// @ts-ignore: decorator
|
||||
@lazy export const SQRT1_2 = <f32>NativeMath.SQRT1_2;
|
||||
// @ts-ignore: decorator
|
||||
@lazy export const SQRT2 = <f32>NativeMath.SQRT2;
|
||||
|
||||
/** Used as return values from Mathf.sincos */
|
||||
// @ts-ignore: decorator
|
||||
@lazy export var sincos_sin: f32 = 0;
|
||||
// @ts-ignore: decorator
|
||||
@lazy export var sincos_cos: f32 = 0;
|
||||
@lazy
|
||||
export const E = <f32>NativeMath.E;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@inline export function abs(x: f32): f32 {
|
||||
@lazy
|
||||
export const LN2 = <f32>NativeMath.LN2;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy
|
||||
export const LN10 = <f32>NativeMath.LN10;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy
|
||||
export const LOG2E = <f32>NativeMath.LOG2E;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy
|
||||
export const LOG10E = <f32>NativeMath.LOG10E;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy
|
||||
export const PI = <f32>NativeMath.PI;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy
|
||||
export const SQRT1_2 = <f32>NativeMath.SQRT1_2;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy
|
||||
export const SQRT2 = <f32>NativeMath.SQRT2;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy
|
||||
export var sincos_sin: f32 = 0;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy
|
||||
export var sincos_cos: f32 = 0;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@inline
|
||||
export function abs(x: f32): f32 {
|
||||
return builtin_abs<f32>(x);
|
||||
}
|
||||
|
||||
@ -1635,7 +1696,8 @@ export namespace NativeMathf {
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@inline export function ceil(x: f32): f32 {
|
||||
@inline
|
||||
export function ceil(x: f32): f32 {
|
||||
return builtin_ceil<f32>(x);
|
||||
}
|
||||
|
||||
@ -1711,7 +1773,8 @@ export namespace NativeMathf {
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@inline export function floor(x: f32): f32 {
|
||||
@inline
|
||||
export function floor(x: f32): f32 {
|
||||
return builtin_floor<f32>(x);
|
||||
}
|
||||
|
||||
@ -1822,7 +1885,8 @@ export namespace NativeMathf {
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@inline export function fround(x: f32): f32 {
|
||||
@inline
|
||||
export function fround(x: f32): f32 {
|
||||
return x;
|
||||
}
|
||||
|
||||
@ -1857,7 +1921,8 @@ export namespace NativeMathf {
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@inline export function imul(x: f32, y: f32): f32 {
|
||||
@inline
|
||||
export function imul(x: f32, y: f32): f32 {
|
||||
/*
|
||||
* Wasm (MVP) and JS have different approaches for double->int conversions.
|
||||
*
|
||||
@ -2036,12 +2101,14 @@ export namespace NativeMathf {
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@inline export function max(value1: f32, value2: f32): f32 {
|
||||
@inline
|
||||
export function max(value1: f32, value2: f32): f32 {
|
||||
return builtin_max<f32>(value1, value2);
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@inline export function min(value1: f32, value2: f32): f32 {
|
||||
@inline
|
||||
export function min(value1: f32, value2: f32): f32 {
|
||||
return builtin_min<f32>(value1, value2);
|
||||
}
|
||||
|
||||
@ -2235,7 +2302,8 @@ export namespace NativeMathf {
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@inline export function seedRandom(value: i64): void {
|
||||
@inline
|
||||
export function seedRandom(value: i64): void {
|
||||
NativeMath.seedRandom(value);
|
||||
}
|
||||
|
||||
@ -2255,12 +2323,14 @@ export namespace NativeMathf {
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@inline export function round(x: f32): f32 {
|
||||
@inline
|
||||
export function round(x: f32): f32 {
|
||||
return builtin_copysign<f32>(builtin_floor<f32>(x + 0.5), x);
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@inline export function sign(x: f32): f32 {
|
||||
@inline
|
||||
export function sign(x: f32): f32 {
|
||||
if (ASC_SHRINK_LEVEL > 0) {
|
||||
return builtin_abs(x) > 0 ? builtin_copysign<f32>(1, x) : x;
|
||||
} else {
|
||||
@ -2269,7 +2339,8 @@ export namespace NativeMathf {
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@inline export function signbit(x: f32): bool {
|
||||
@inline
|
||||
export function signbit(x: f32): bool {
|
||||
// @ts-ignore: type
|
||||
return <bool>((reinterpret<u32>(x) >>> 31) & (x == x));
|
||||
}
|
||||
@ -2335,7 +2406,8 @@ export namespace NativeMathf {
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@inline export function sqrt(x: f32): f32 {
|
||||
@inline
|
||||
export function sqrt(x: f32): f32 {
|
||||
return builtin_sqrt<f32>(x);
|
||||
}
|
||||
|
||||
@ -2404,7 +2476,8 @@ export namespace NativeMathf {
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@inline export function trunc(x: f32): f32 {
|
||||
@inline
|
||||
export function trunc(x: f32): f32 {
|
||||
return builtin_trunc<f32>(x);
|
||||
}
|
||||
|
||||
|
@ -1,47 +1,55 @@
|
||||
import { memcmp, memmove, memset } from "./util/memory";
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@builtin export declare const HEAP_BASE: usize;
|
||||
@builtin
|
||||
export declare const HEAP_BASE: usize;
|
||||
|
||||
/** Memory manager interface. */
|
||||
export namespace memory {
|
||||
|
||||
/** Gets the size of the memory in pages. */
|
||||
// @ts-ignore: decorator
|
||||
@builtin export declare function size(): i32;
|
||||
@builtin
|
||||
export declare function size(): i32;
|
||||
|
||||
/** Grows the memory by the given size in pages and returns the previous size in pages. */
|
||||
// @ts-ignore: decorator
|
||||
@unsafe @builtin export declare function grow(pages: i32): i32;
|
||||
@unsafe @builtin
|
||||
export declare function grow(pages: i32): i32;
|
||||
|
||||
/** Fills a section in memory with the specified byte value. */
|
||||
// @ts-ignore: decorator
|
||||
@unsafe @builtin export function fill(dst: usize, c: u8, n: usize): void {
|
||||
@unsafe @builtin
|
||||
export function fill(dst: usize, c: u8, n: usize): void {
|
||||
memset(dst, c, n); // fallback if "bulk-memory" isn't enabled
|
||||
}
|
||||
|
||||
/** Copies a section of memory to another. Has move semantics. */
|
||||
// @ts-ignore: decorator
|
||||
@unsafe @builtin export function copy(dst: usize, src: usize, n: usize): void {
|
||||
@unsafe @builtin
|
||||
export function copy(dst: usize, src: usize, n: usize): void {
|
||||
memmove(dst, src, n); // fallback if "bulk-memory" isn't enabled
|
||||
}
|
||||
|
||||
/** Initializes a memory segment. */
|
||||
// @ts-ignore: decorator
|
||||
@unsafe export function init(segmentIndex: u32, srcOffset: usize, dstOffset: usize, n: usize): void {
|
||||
@unsafe
|
||||
export function init(segmentIndex: u32, srcOffset: usize, dstOffset: usize, n: usize): void {
|
||||
ERROR("not implemented");
|
||||
}
|
||||
|
||||
/** Drops a memory segment. */
|
||||
// @ts-ignore: decorator
|
||||
@unsafe export function drop(segmentIndex: u32): void {
|
||||
@unsafe
|
||||
export function drop(segmentIndex: u32): void {
|
||||
ERROR("not implemented");
|
||||
}
|
||||
|
||||
/** Dynamically allocates a section of memory and returns its address. */
|
||||
// @ts-ignore: decorator
|
||||
@unsafe export function allocate(size: usize): usize {
|
||||
// @ts-ignore: undefined
|
||||
@unsafe
|
||||
export function allocate(size: usize): usize {
|
||||
// @ts-ignore: stub
|
||||
if (isDefined(__memory_allocate)) return __memory_allocate(size);
|
||||
else ERROR("missing implementation: memory.allocate");
|
||||
return <usize>unreachable();
|
||||
@ -49,23 +57,26 @@ export namespace memory {
|
||||
|
||||
/** Dynamically frees a section of memory by the previously allocated address. */
|
||||
// @ts-ignore: decorator
|
||||
@unsafe export function free(ptr: usize): void {
|
||||
// @ts-ignore: undefined
|
||||
@unsafe
|
||||
export function free(ptr: usize): void {
|
||||
// @ts-ignore: stub
|
||||
if (isDefined(__memory_free)) __memory_free(ptr);
|
||||
else ERROR("missing implementation: memory.free");
|
||||
}
|
||||
|
||||
/** Resets the memory to its initial state. Arena allocator only. */
|
||||
// @ts-ignore: decorator
|
||||
@unsafe export function reset(): void {
|
||||
// @ts-ignore: undefined
|
||||
@unsafe
|
||||
export function reset(): void {
|
||||
// @ts-ignore: stub
|
||||
if (isDefined(__memory_reset)) __memory_reset();
|
||||
else ERROR("missing implementation: memory.reset");
|
||||
}
|
||||
|
||||
/** Repeats a section of memory at a specific address. */
|
||||
// @ts-ignore: decorator
|
||||
@unsafe export function repeat(dst: usize, src: usize, srcLength: usize, count: usize): void {
|
||||
@unsafe
|
||||
export function repeat(dst: usize, src: usize, srcLength: usize, count: usize): void {
|
||||
var index: usize = 0;
|
||||
var total = srcLength * count;
|
||||
while (index < total) {
|
||||
@ -76,7 +87,8 @@ export namespace memory {
|
||||
|
||||
/** Compares a section of memory to another. */
|
||||
// @ts-ignore: decorator
|
||||
@inline export function compare(vl: usize, vr: usize, n: usize): i32 {
|
||||
@inline
|
||||
export function compare(vl: usize, vr: usize, n: usize): i32 {
|
||||
return memcmp(vl, vr, n);
|
||||
}
|
||||
}
|
||||
|
@ -4,9 +4,12 @@ import { isNaN as builtin_isNaN, isFinite as builtin_isFinite } from "./builtins
|
||||
@sealed export abstract class I8 {
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy static readonly MIN_VALUE: i8 = i8.MIN_VALUE;
|
||||
@lazy
|
||||
static readonly MIN_VALUE: i8 = i8.MIN_VALUE;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy static readonly MAX_VALUE: i8 = i8.MAX_VALUE;
|
||||
@lazy
|
||||
static readonly MAX_VALUE: i8 = i8.MAX_VALUE;
|
||||
|
||||
static parseInt(value: string, radix: i32 = 0): i8 {
|
||||
return <i8>parseI32(value, radix);
|
||||
@ -21,9 +24,12 @@ import { isNaN as builtin_isNaN, isFinite as builtin_isFinite } from "./builtins
|
||||
@sealed export abstract class I16 {
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy static readonly MIN_VALUE: i16 = i16.MIN_VALUE;
|
||||
@lazy
|
||||
static readonly MIN_VALUE: i16 = i16.MIN_VALUE;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy static readonly MAX_VALUE: i16 = i16.MAX_VALUE;
|
||||
@lazy
|
||||
static readonly MAX_VALUE: i16 = i16.MAX_VALUE;
|
||||
|
||||
static parseInt(value: string, radix: i32 = 0): i16 {
|
||||
return <i16>parseI32(value, radix);
|
||||
@ -38,9 +44,12 @@ import { isNaN as builtin_isNaN, isFinite as builtin_isFinite } from "./builtins
|
||||
@sealed export abstract class I32 {
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy static readonly MIN_VALUE: i32 = i32.MIN_VALUE;
|
||||
@lazy
|
||||
static readonly MIN_VALUE: i32 = i32.MIN_VALUE;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy static readonly MAX_VALUE: i32 = i32.MAX_VALUE;
|
||||
@lazy
|
||||
static readonly MAX_VALUE: i32 = i32.MAX_VALUE;
|
||||
|
||||
static parseInt(value: string, radix: i32 = 0): i32 {
|
||||
return <i32>parseI32(value, radix);
|
||||
@ -55,9 +64,12 @@ import { isNaN as builtin_isNaN, isFinite as builtin_isFinite } from "./builtins
|
||||
@sealed export abstract class I64 {
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy static readonly MIN_VALUE: i64 = i64.MIN_VALUE;
|
||||
@lazy
|
||||
static readonly MIN_VALUE: i64 = i64.MIN_VALUE;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy static readonly MAX_VALUE: i64 = i64.MAX_VALUE;
|
||||
@lazy
|
||||
static readonly MAX_VALUE: i64 = i64.MAX_VALUE;
|
||||
|
||||
static parseInt(value: string, radix: i32 = 0): i64 {
|
||||
return <i64>parseI64(value, radix);
|
||||
@ -72,9 +84,12 @@ import { isNaN as builtin_isNaN, isFinite as builtin_isFinite } from "./builtins
|
||||
@sealed export abstract class Isize {
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy static readonly MIN_VALUE: isize = isize.MIN_VALUE;
|
||||
@lazy
|
||||
static readonly MIN_VALUE: isize = isize.MIN_VALUE;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy static readonly MAX_VALUE: isize = isize.MAX_VALUE;
|
||||
@lazy
|
||||
static readonly MAX_VALUE: isize = isize.MAX_VALUE;
|
||||
|
||||
static parseInt(value: string, radix: i32 = 0): isize {
|
||||
return <isize>parseI64(value, radix);
|
||||
@ -89,9 +104,12 @@ import { isNaN as builtin_isNaN, isFinite as builtin_isFinite } from "./builtins
|
||||
@sealed export abstract class U8 {
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy static readonly MIN_VALUE: u8 = u8.MIN_VALUE;
|
||||
@lazy
|
||||
static readonly MIN_VALUE: u8 = u8.MIN_VALUE;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy static readonly MAX_VALUE: u8 = u8.MAX_VALUE;
|
||||
@lazy
|
||||
static readonly MAX_VALUE: u8 = u8.MAX_VALUE;
|
||||
|
||||
static parseInt(value: string, radix: i32 = 0): u8 {
|
||||
return <u8>parseI32(value, radix);
|
||||
@ -106,9 +124,12 @@ import { isNaN as builtin_isNaN, isFinite as builtin_isFinite } from "./builtins
|
||||
@sealed export abstract class U16 {
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy static readonly MIN_VALUE: u16 = u16.MIN_VALUE;
|
||||
@lazy
|
||||
static readonly MIN_VALUE: u16 = u16.MIN_VALUE;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy static readonly MAX_VALUE: u16 = u16.MAX_VALUE;
|
||||
@lazy
|
||||
static readonly MAX_VALUE: u16 = u16.MAX_VALUE;
|
||||
|
||||
static parseInt(value: string, radix: i32 = 0): u16 {
|
||||
return <u16>parseI32(value, radix);
|
||||
@ -123,9 +144,12 @@ import { isNaN as builtin_isNaN, isFinite as builtin_isFinite } from "./builtins
|
||||
@sealed export abstract class U32 {
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy static readonly MIN_VALUE: u32 = u32.MIN_VALUE;
|
||||
@lazy
|
||||
static readonly MIN_VALUE: u32 = u32.MIN_VALUE;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy static readonly MAX_VALUE: u32 = u32.MAX_VALUE;
|
||||
@lazy
|
||||
static readonly MAX_VALUE: u32 = u32.MAX_VALUE;
|
||||
|
||||
static parseInt(value: string, radix: i32 = 0): u32 {
|
||||
return <u32>parseI32(value, radix);
|
||||
@ -140,9 +164,12 @@ import { isNaN as builtin_isNaN, isFinite as builtin_isFinite } from "./builtins
|
||||
@sealed export abstract class U64 {
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy static readonly MIN_VALUE: u64 = u64.MIN_VALUE;
|
||||
@lazy
|
||||
static readonly MIN_VALUE: u64 = u64.MIN_VALUE;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy static readonly MAX_VALUE: u64 = u64.MAX_VALUE;
|
||||
@lazy
|
||||
static readonly MAX_VALUE: u64 = u64.MAX_VALUE;
|
||||
|
||||
static parseInt(value: string, radix: i32 = 0): u64 {
|
||||
return <u64>parseI64(value, radix);
|
||||
@ -157,9 +184,12 @@ import { isNaN as builtin_isNaN, isFinite as builtin_isFinite } from "./builtins
|
||||
@sealed export abstract class Usize {
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy static readonly MIN_VALUE: usize = usize.MIN_VALUE;
|
||||
@lazy
|
||||
static readonly MIN_VALUE: usize = usize.MIN_VALUE;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy static readonly MAX_VALUE: usize = usize.MAX_VALUE;
|
||||
@lazy
|
||||
static readonly MAX_VALUE: usize = usize.MAX_VALUE;
|
||||
|
||||
static parseInt(value: string, radix: i32 = 0): usize {
|
||||
return <usize>parseI64(value, radix);
|
||||
@ -174,9 +204,12 @@ import { isNaN as builtin_isNaN, isFinite as builtin_isFinite } from "./builtins
|
||||
@sealed export abstract class Bool {
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy static readonly MIN_VALUE: bool = bool.MIN_VALUE;
|
||||
@lazy
|
||||
static readonly MIN_VALUE: bool = bool.MIN_VALUE;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy static readonly MAX_VALUE: bool = bool.MAX_VALUE;
|
||||
@lazy
|
||||
static readonly MAX_VALUE: bool = bool.MAX_VALUE;
|
||||
|
||||
toString(this: bool): String {
|
||||
// TODO: radix?
|
||||
@ -189,21 +222,36 @@ export { Bool as Boolean };
|
||||
@sealed export abstract class F32 {
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy static readonly EPSILON: f32 = f32.EPSILON;
|
||||
@lazy
|
||||
static readonly EPSILON: f32 = f32.EPSILON;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy static readonly MIN_VALUE: f32 = f32.MIN_VALUE;
|
||||
@lazy
|
||||
static readonly MIN_VALUE: f32 = f32.MIN_VALUE;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy static readonly MAX_VALUE: f32 = f32.MAX_VALUE;
|
||||
@lazy
|
||||
static readonly MAX_VALUE: f32 = f32.MAX_VALUE;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy static readonly MIN_SAFE_INTEGER: f32 = f32.MIN_SAFE_INTEGER;
|
||||
@lazy
|
||||
static readonly MIN_SAFE_INTEGER: f32 = f32.MIN_SAFE_INTEGER;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy static readonly MAX_SAFE_INTEGER: f32 = f32.MAX_SAFE_INTEGER;
|
||||
@lazy
|
||||
static readonly MAX_SAFE_INTEGER: f32 = f32.MAX_SAFE_INTEGER;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy static readonly POSITIVE_INFINITY: f32 = Infinity;
|
||||
@lazy
|
||||
static readonly POSITIVE_INFINITY: f32 = Infinity;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy static readonly NEGATIVE_INFINITY: f32 = -Infinity;
|
||||
@lazy
|
||||
static readonly NEGATIVE_INFINITY: f32 = -Infinity;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy static readonly NaN: f32 = NaN;
|
||||
@lazy
|
||||
static readonly NaN: f32 = NaN;
|
||||
|
||||
static isNaN(value: f32): bool {
|
||||
return isNaN<f32>(value);
|
||||
@ -238,21 +286,36 @@ export { Bool as Boolean };
|
||||
@sealed export abstract class F64 {
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy static readonly EPSILON: f64 = f64.EPSILON;
|
||||
@lazy
|
||||
static readonly EPSILON: f64 = f64.EPSILON;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy static readonly MIN_VALUE: f64 = f64.MIN_VALUE;
|
||||
@lazy
|
||||
static readonly MIN_VALUE: f64 = f64.MIN_VALUE;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy static readonly MAX_VALUE: f64 = f64.MAX_VALUE;
|
||||
@lazy
|
||||
static readonly MAX_VALUE: f64 = f64.MAX_VALUE;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy static readonly MIN_SAFE_INTEGER: f64 = f64.MIN_SAFE_INTEGER;
|
||||
@lazy
|
||||
static readonly MIN_SAFE_INTEGER: f64 = f64.MIN_SAFE_INTEGER;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy static readonly MAX_SAFE_INTEGER: f64 = f64.MAX_SAFE_INTEGER;
|
||||
@lazy
|
||||
static readonly MAX_SAFE_INTEGER: f64 = f64.MAX_SAFE_INTEGER;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy static readonly POSITIVE_INFINITY: f64 = Infinity;
|
||||
@lazy
|
||||
static readonly POSITIVE_INFINITY: f64 = Infinity;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy static readonly NEGATIVE_INFINITY: f64 = -Infinity;
|
||||
@lazy
|
||||
static readonly NEGATIVE_INFINITY: f64 = -Infinity;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy static readonly NaN: f64 = NaN;
|
||||
@lazy
|
||||
static readonly NaN: f64 = NaN;
|
||||
|
||||
static isNaN(value: f64): bool {
|
||||
return builtin_isNaN<f64>(value);
|
||||
|
@ -10,13 +10,15 @@ export namespace runtime {
|
||||
|
||||
/** Size of a runtime header. */
|
||||
// @ts-ignore: decorator
|
||||
@lazy @inline static readonly SIZE: usize = gc.implemented
|
||||
@lazy @inline
|
||||
static readonly SIZE: usize = gc.implemented
|
||||
? (offsetof<Header>( ) + AL_MASK) & ~AL_MASK // full header if GC is present
|
||||
: (offsetof<Header>("gc1") + AL_MASK) & ~AL_MASK; // half header if GC is absent
|
||||
|
||||
/** Magic value used to validate runtime headers. */
|
||||
// @ts-ignore: decorator
|
||||
@lazy @inline static readonly MAGIC: u32 = 0xA55E4B17;
|
||||
@lazy @inline
|
||||
static readonly MAGIC: u32 = 0xA55E4B17;
|
||||
|
||||
/** Unique id of the respective class or a magic value if not yet registered.*/
|
||||
classId: u32;
|
||||
@ -45,7 +47,8 @@ export namespace runtime {
|
||||
|
||||
/** Allocates a new object and returns a pointer to its payload. Does not fill. */
|
||||
// @ts-ignore: decorator
|
||||
@unsafe export function allocRaw(payloadSize: u32): usize {
|
||||
@unsafe
|
||||
export function allocRaw(payloadSize: u32): usize {
|
||||
var header = changetype<Header>(memory.allocate(adjust(payloadSize)));
|
||||
header.classId = Header.MAGIC;
|
||||
header.payloadSize = payloadSize;
|
||||
@ -58,7 +61,8 @@ export namespace runtime {
|
||||
|
||||
/** Allocates a new object and returns a pointer to its payload. Fills with zeroes.*/
|
||||
// @ts-ignore: decorator
|
||||
@unsafe export function alloc(payloadSize: u32): usize {
|
||||
@unsafe
|
||||
export function alloc(payloadSize: u32): usize {
|
||||
var ref = allocRaw(payloadSize);
|
||||
memory.fill(ref, 0, payloadSize);
|
||||
return ref;
|
||||
@ -66,7 +70,8 @@ export namespace runtime {
|
||||
|
||||
/** Reallocates an object if necessary. Returns a pointer to its (moved) payload. */
|
||||
// @ts-ignore: decorator
|
||||
@unsafe export function realloc(ref: usize, newPayloadSize: u32): usize {
|
||||
@unsafe
|
||||
export function realloc(ref: usize, newPayloadSize: u32): usize {
|
||||
// Background: When managed objects are allocated these aren't immediately registered with GC
|
||||
// but can be used as scratch objects while unregistered. This is useful in situations where
|
||||
// the object must be reallocated multiple times because its final size isn't known beforehand,
|
||||
@ -117,13 +122,15 @@ export namespace runtime {
|
||||
|
||||
/** Frees an object. Must not have been registered with GC yet. */
|
||||
// @ts-ignore: decorator
|
||||
@unsafe @inline export function free<T>(ref: T): void {
|
||||
@unsafe @inline
|
||||
export function free<T>(ref: T): void {
|
||||
memory.free(changetype<usize>(unref(changetype<usize>(ref))));
|
||||
}
|
||||
|
||||
/** Registers a managed object. Cannot be free'd anymore afterwards. */
|
||||
// @ts-ignore: decorator
|
||||
@unsafe @inline export function register<T>(ref: usize): T {
|
||||
@unsafe @inline
|
||||
export function register<T>(ref: usize): T {
|
||||
if (!isReference<T>()) ERROR("reference expected");
|
||||
// see comment in REALLOC why this is useful. also inline this because
|
||||
// it's generic so we don't get a bunch of functions.
|
||||
@ -134,7 +141,8 @@ export namespace runtime {
|
||||
|
||||
/** Links a managed object with its managed parent. */
|
||||
// @ts-ignore: decorator
|
||||
@unsafe @inline export function link<T, TParent>(ref: T, parentRef: TParent): void {
|
||||
@unsafe @inline
|
||||
export function link<T, TParent>(ref: T, parentRef: TParent): void {
|
||||
assert(changetype<usize>(ref) >= HEAP_BASE + Header.SIZE); // must be a heap object
|
||||
var header = changetype<Header>(changetype<usize>(ref) - Header.SIZE);
|
||||
assert(header.classId != Header.MAGIC && header.gc1 != 0 && header.gc2 != 0); // must be registered
|
||||
@ -145,16 +153,24 @@ export namespace runtime {
|
||||
import { ArrayBuffer } from "./arraybuffer";
|
||||
|
||||
export abstract class ArrayBufferView {
|
||||
@lazy static readonly MAX_BYTELENGTH: i32 = MAX_SIZE_32 - runtime.Header.SIZE;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy
|
||||
static readonly MAX_BYTELENGTH: i32 = MAX_SIZE_32 - runtime.Header.SIZE;
|
||||
|
||||
[key: number]: number;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@unsafe data: ArrayBuffer;
|
||||
@unsafe
|
||||
data: ArrayBuffer;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@unsafe dataStart: usize;
|
||||
@unsafe
|
||||
dataStart: usize;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@unsafe dataEnd: usize;
|
||||
@unsafe
|
||||
dataEnd: usize;
|
||||
|
||||
constructor(length: i32, alignLog2: i32) {
|
||||
if (<u32>length > <u32>ArrayBufferView.MAX_BYTELENGTH >>> alignLog2) throw new RangeError("Invalid length");
|
||||
|
@ -4,11 +4,16 @@ import { HASH } from "./util/hash";
|
||||
// A deterministic hash set based on CloseTable from https://github.com/jorendorff/dht
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@inline const INITIAL_CAPACITY = 4;
|
||||
@inline
|
||||
const INITIAL_CAPACITY = 4;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@inline const FILL_FACTOR: f64 = 8 / 3;
|
||||
@inline
|
||||
const FILL_FACTOR: f64 = 8 / 3;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@inline const FREE_FACTOR: f64 = 3 / 4;
|
||||
@inline
|
||||
const FREE_FACTOR: f64 = 3 / 4;
|
||||
|
||||
/** Structure of a set entry. */
|
||||
@unmanaged class SetEntry<K> {
|
||||
@ -18,15 +23,18 @@ import { HASH } from "./util/hash";
|
||||
|
||||
/** Empty bit. */
|
||||
// @ts-ignore: decorator
|
||||
@inline const EMPTY: usize = 1 << 0;
|
||||
@inline
|
||||
const EMPTY: usize = 1 << 0;
|
||||
|
||||
/** Size of a bucket. */
|
||||
// @ts-ignore: decorator
|
||||
@inline const BUCKET_SIZE = sizeof<usize>();
|
||||
@inline
|
||||
const BUCKET_SIZE = sizeof<usize>();
|
||||
|
||||
/** Computes the alignment of an entry. */
|
||||
// @ts-ignore: decorator
|
||||
@inline function ENTRY_ALIGN<K>(): usize {
|
||||
@inline
|
||||
function ENTRY_ALIGN<K>(): usize {
|
||||
// can align to 4 instead of 8 if 32-bit and K is <= 32-bits
|
||||
const align = (sizeof<K>() > sizeof<usize>() ? sizeof<K>() : sizeof<usize>()) - 1;
|
||||
return align;
|
||||
@ -34,7 +42,8 @@ import { HASH } from "./util/hash";
|
||||
|
||||
/** Computes the aligned size of an entry. */
|
||||
// @ts-ignore: decorator
|
||||
@inline function ENTRY_SIZE<K>(): usize {
|
||||
@inline
|
||||
function ENTRY_SIZE<K>(): usize {
|
||||
const align = ENTRY_ALIGN<K>();
|
||||
const size = (offsetof<SetEntry<K>>() + align) & ~align;
|
||||
return size;
|
||||
|
@ -3,8 +3,10 @@ import { MAX_SIZE_32 } from "./util/allocator";
|
||||
import { compareImpl, parse, CharCode, isWhiteSpaceOrLineTerminator } from "./util/string";
|
||||
|
||||
@sealed export abstract class String {
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy static readonly MAX_LENGTH: i32 = (MAX_SIZE_32 - runtime.Header.SIZE) >> alignof<u16>();
|
||||
@lazy
|
||||
static readonly MAX_LENGTH: i32 = (MAX_SIZE_32 - runtime.Header.SIZE) >> alignof<u16>();
|
||||
|
||||
get length(): i32 {
|
||||
return changetype<runtime.Header>(changetype<usize>(this) - runtime.Header.SIZE).payloadSize >> 1;
|
||||
@ -20,8 +22,7 @@ import { compareImpl, parse, CharCode, isWhiteSpaceOrLineTerminator } from "./ut
|
||||
static fromCodePoint(code: i32): String {
|
||||
assert(<u32>code <= 0x10FFFF);
|
||||
var sur = code > 0xFFFF;
|
||||
// @ts-ignore: type
|
||||
var out = runtime.allocRaw((<i32>sur + 1) << 1);
|
||||
var out = runtime.allocRaw((i32(sur) + 1) << 1);
|
||||
if (!sur) {
|
||||
store<u16>(out, <u16>code);
|
||||
} else {
|
||||
@ -82,7 +83,7 @@ import { compareImpl, parse, CharCode, isWhiteSpaceOrLineTerminator } from "./ut
|
||||
var searchLength: isize = searchString.length;
|
||||
var start: isize = end - searchLength;
|
||||
if (start < 0) return false;
|
||||
// @ts-ignore: string/String
|
||||
// @ts-ignore: string <-> String
|
||||
return !compareImpl(this, start, searchString, 0, searchLength);
|
||||
}
|
||||
|
||||
@ -91,7 +92,7 @@ import { compareImpl, parse, CharCode, isWhiteSpaceOrLineTerminator } from "./ut
|
||||
if (left === null || right === null) return false;
|
||||
var leftLength = left.length;
|
||||
if (leftLength != right.length) return false;
|
||||
// @ts-ignore: string/String
|
||||
// @ts-ignore: string <-> String
|
||||
return !compareImpl(left, 0, right, 0, leftLength);
|
||||
}
|
||||
|
||||
@ -105,7 +106,7 @@ import { compareImpl, parse, CharCode, isWhiteSpaceOrLineTerminator } from "./ut
|
||||
var rightLength = right.length;
|
||||
if (!leftLength) return false;
|
||||
if (!rightLength) return true;
|
||||
// @ts-ignore: string/String
|
||||
// @ts-ignore: string <-> String
|
||||
return compareImpl(left, 0, right, 0, min(leftLength, rightLength)) > 0;
|
||||
}
|
||||
|
||||
@ -119,7 +120,7 @@ import { compareImpl, parse, CharCode, isWhiteSpaceOrLineTerminator } from "./ut
|
||||
var rightLength = right.length;
|
||||
if (!rightLength) return false;
|
||||
if (!leftLength) return true;
|
||||
// @ts-ignore: string/String
|
||||
// @ts-ignore: string <-> String
|
||||
return compareImpl(left, 0, right, 0, min(leftLength, rightLength)) < 0;
|
||||
}
|
||||
|
||||
@ -141,7 +142,7 @@ import { compareImpl, parse, CharCode, isWhiteSpaceOrLineTerminator } from "./ut
|
||||
var start = min<isize>(max<isize>(fromIndex, 0), len);
|
||||
len -= searchLen;
|
||||
for (let k: isize = start; k <= len; ++k) {
|
||||
// @ts-ignore: string/String
|
||||
// @ts-ignore: string <-> String
|
||||
if (!compareImpl(this, k, searchString, 0, searchLen)) return <i32>k;
|
||||
}
|
||||
return -1;
|
||||
@ -156,7 +157,7 @@ import { compareImpl, parse, CharCode, isWhiteSpaceOrLineTerminator } from "./ut
|
||||
if (!len) return -1;
|
||||
var start = min<isize>(max(fromIndex, 0), len - searchLen);
|
||||
for (let k = start; k >= 0; --k) {
|
||||
// @ts-ignore: string/String
|
||||
// @ts-ignore: string <-> String
|
||||
if (!compareImpl(this, k, searchString, 0, searchLen)) return <i32>k;
|
||||
}
|
||||
return -1;
|
||||
@ -170,7 +171,7 @@ import { compareImpl, parse, CharCode, isWhiteSpaceOrLineTerminator } from "./ut
|
||||
var start = min(max(pos, 0), len);
|
||||
var searchLength: isize = searchString.length;
|
||||
if (searchLength + start > len) return false;
|
||||
// @ts-ignore: string/String
|
||||
// @ts-ignore: string <-> String
|
||||
return !compareImpl(this, start, searchString, 0, searchLength);
|
||||
}
|
||||
|
||||
@ -523,17 +524,17 @@ import { compareImpl, parse, CharCode, isWhiteSpaceOrLineTerminator } from "./ut
|
||||
export type string = String;
|
||||
|
||||
export function parseInt(str: String, radix: i32 = 0): f64 {
|
||||
// @ts-ignore: string/String
|
||||
// @ts-ignore: string <-> String
|
||||
return parse<f64>(str, radix);
|
||||
}
|
||||
|
||||
export function parseI32(str: String, radix: i32 = 0): i32 {
|
||||
// @ts-ignore: string/String
|
||||
// @ts-ignore: string <-> String
|
||||
return parse<i32>(str, radix);
|
||||
}
|
||||
|
||||
export function parseI64(str: String, radix: i32 = 0): i64 {
|
||||
// @ts-ignore: string/String
|
||||
// @ts-ignore: string <-> String
|
||||
return parse<i64>(str, radix);
|
||||
}
|
||||
|
||||
|
@ -4,8 +4,9 @@ import { Map } from "./map";
|
||||
@lazy var idToString: Map<usize, string>;
|
||||
@lazy var nextId: usize = 12; // Symbol.unscopables + 1
|
||||
|
||||
@unmanaged
|
||||
// @ts-ignore: nolib
|
||||
@unmanaged export class symbol {
|
||||
export class symbol {
|
||||
toString(): string {
|
||||
var id = changetype<usize>(this);
|
||||
var str = "";
|
||||
@ -52,6 +53,8 @@ export namespace Symbol {
|
||||
@lazy export const toStringTag = changetype<symbol>(10);
|
||||
@lazy export const unscopables = changetype<symbol>(11);
|
||||
|
||||
// FIXME
|
||||
|
||||
/* tslint:disable */// not valid TS
|
||||
// @ts-ignore: identifier
|
||||
export function for(key: string): symbol {
|
||||
|
@ -6,8 +6,10 @@ function clampToByte(value: i32): i32 {
|
||||
}
|
||||
|
||||
export class Int8Array extends ArrayBufferView {
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy static readonly BYTES_PER_ELEMENT: usize = sizeof<i8>();
|
||||
@lazy
|
||||
static readonly BYTES_PER_ELEMENT: usize = sizeof<i8>();
|
||||
|
||||
constructor(length: i32) {
|
||||
super(length, alignof<i8>());
|
||||
@ -69,8 +71,10 @@ export class Int8Array extends ArrayBufferView {
|
||||
}
|
||||
|
||||
export class Uint8Array extends ArrayBufferView {
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy static readonly BYTES_PER_ELEMENT: usize = sizeof<u8>();
|
||||
@lazy
|
||||
static readonly BYTES_PER_ELEMENT: usize = sizeof<u8>();
|
||||
|
||||
constructor(length: i32) {
|
||||
super(length, alignof<u8>());
|
||||
@ -126,8 +130,10 @@ export class Uint8Array extends ArrayBufferView {
|
||||
}
|
||||
|
||||
export class Uint8ClampedArray extends Uint8Array {
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy static readonly BYTES_PER_ELEMENT: usize = sizeof<u8>();
|
||||
@lazy
|
||||
static readonly BYTES_PER_ELEMENT: usize = sizeof<u8>();
|
||||
|
||||
fill(value: u32, start: i32 = 0, end: i32 = i32.MAX_VALUE): Uint8ClampedArray {
|
||||
return changetype<Uint8ClampedArray>(super.fill(value, start, end)); // safe because '.fill' reuses 'this'
|
||||
@ -177,8 +183,10 @@ export class Uint8ClampedArray extends Uint8Array {
|
||||
}
|
||||
|
||||
export class Int16Array extends ArrayBufferView {
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy static readonly BYTES_PER_ELEMENT: usize = sizeof<i16>();
|
||||
@lazy
|
||||
static readonly BYTES_PER_ELEMENT: usize = sizeof<i16>();
|
||||
|
||||
constructor(length: i32) {
|
||||
super(length, alignof<i16>());
|
||||
@ -240,8 +248,10 @@ export class Int16Array extends ArrayBufferView {
|
||||
}
|
||||
|
||||
export class Uint16Array extends ArrayBufferView {
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy static readonly BYTES_PER_ELEMENT: usize = sizeof<u16>();
|
||||
@lazy
|
||||
static readonly BYTES_PER_ELEMENT: usize = sizeof<u16>();
|
||||
|
||||
constructor(length: i32) {
|
||||
super(length, alignof<u16>());
|
||||
@ -303,8 +313,10 @@ export class Uint16Array extends ArrayBufferView {
|
||||
}
|
||||
|
||||
export class Int32Array extends ArrayBufferView {
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy static readonly BYTES_PER_ELEMENT: usize = sizeof<i32>();
|
||||
@lazy
|
||||
static readonly BYTES_PER_ELEMENT: usize = sizeof<i32>();
|
||||
|
||||
constructor(length: i32) {
|
||||
super(length, alignof<i32>());
|
||||
@ -366,8 +378,10 @@ export class Int32Array extends ArrayBufferView {
|
||||
}
|
||||
|
||||
export class Uint32Array extends ArrayBufferView {
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy static readonly BYTES_PER_ELEMENT: usize = sizeof<u32>();
|
||||
@lazy
|
||||
static readonly BYTES_PER_ELEMENT: usize = sizeof<u32>();
|
||||
|
||||
constructor(length: i32) {
|
||||
super(length, alignof<u32>());
|
||||
@ -429,8 +443,10 @@ export class Uint32Array extends ArrayBufferView {
|
||||
}
|
||||
|
||||
export class Int64Array extends ArrayBufferView {
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy static readonly BYTES_PER_ELEMENT: usize = sizeof<i64>();
|
||||
@lazy
|
||||
static readonly BYTES_PER_ELEMENT: usize = sizeof<i64>();
|
||||
|
||||
constructor(length: i32) {
|
||||
super(length, alignof<i64>());
|
||||
@ -492,8 +508,10 @@ export class Int64Array extends ArrayBufferView {
|
||||
}
|
||||
|
||||
export class Uint64Array extends ArrayBufferView {
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy static readonly BYTES_PER_ELEMENT: usize = sizeof<u64>();
|
||||
@lazy
|
||||
static readonly BYTES_PER_ELEMENT: usize = sizeof<u64>();
|
||||
|
||||
constructor(length: i32) {
|
||||
super(length, alignof<u64>());
|
||||
@ -555,8 +573,10 @@ export class Uint64Array extends ArrayBufferView {
|
||||
}
|
||||
|
||||
export class Float32Array extends ArrayBufferView {
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy static readonly BYTES_PER_ELEMENT: usize = sizeof<f32>();
|
||||
@lazy
|
||||
static readonly BYTES_PER_ELEMENT: usize = sizeof<f32>();
|
||||
|
||||
constructor(length: i32) {
|
||||
super(length, alignof<f32>());
|
||||
@ -618,8 +638,10 @@ export class Float32Array extends ArrayBufferView {
|
||||
}
|
||||
|
||||
export class Float64Array extends ArrayBufferView {
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy static readonly BYTES_PER_ELEMENT: usize = sizeof<f64>();
|
||||
@lazy
|
||||
static readonly BYTES_PER_ELEMENT: usize = sizeof<f64>();
|
||||
|
||||
constructor(length: i32) {
|
||||
super(length, alignof<f64>());
|
||||
@ -681,7 +703,8 @@ export class Float64Array extends ArrayBufferView {
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@inline function FILL<TArray extends ArrayBufferView, T extends number>(
|
||||
@inline
|
||||
function FILL<TArray extends ArrayBufferView, T extends number>(
|
||||
array: TArray,
|
||||
value: native<T>,
|
||||
start: i32,
|
||||
@ -702,7 +725,8 @@ export class Float64Array extends ArrayBufferView {
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@inline function SORT<TArray extends ArrayBufferView, T>(
|
||||
@inline
|
||||
function SORT<TArray extends ArrayBufferView, T>(
|
||||
array: TArray,
|
||||
comparator: (a: T, b: T) => i32
|
||||
): TArray {
|
||||
@ -723,7 +747,8 @@ export class Float64Array extends ArrayBufferView {
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@inline function SUBARRAY<TArray extends ArrayBufferView, T>(
|
||||
@inline
|
||||
function SUBARRAY<TArray extends ArrayBufferView, T>(
|
||||
array: TArray,
|
||||
begin: i32,
|
||||
end: i32
|
||||
@ -743,7 +768,8 @@ export class Float64Array extends ArrayBufferView {
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@inline function REDUCE<TArray extends ArrayBufferView, T, TRet>(
|
||||
@inline
|
||||
function REDUCE<TArray extends ArrayBufferView, T, TRet>(
|
||||
array: TArray,
|
||||
callbackfn: (accumulator: TRet, value: T, index: i32, array: TArray) => TRet,
|
||||
initialValue: TRet
|
||||
@ -756,7 +782,8 @@ export class Float64Array extends ArrayBufferView {
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@inline function REDUCE_RIGHT<TArray extends ArrayBufferView, T, TRet>(
|
||||
@inline
|
||||
function REDUCE_RIGHT<TArray extends ArrayBufferView, T, TRet>(
|
||||
array: TArray,
|
||||
callbackfn: (accumulator: TRet, value: T, index: i32, array: TArray) => TRet,
|
||||
initialValue: TRet
|
||||
@ -769,7 +796,8 @@ export class Float64Array extends ArrayBufferView {
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@inline function MAP<TArray extends ArrayBufferView, T>(
|
||||
@inline
|
||||
function MAP<TArray extends ArrayBufferView, T>(
|
||||
array: TArray,
|
||||
callbackfn: (value: T, index: i32, self: TArray) => T,
|
||||
): TArray {
|
||||
@ -787,7 +815,8 @@ export class Float64Array extends ArrayBufferView {
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@inline function FIND_INDEX<TArray extends ArrayBufferView, T>(
|
||||
@inline
|
||||
function FIND_INDEX<TArray extends ArrayBufferView, T>(
|
||||
array: TArray,
|
||||
callbackfn: (value: T, index: i32, array: TArray) => bool,
|
||||
): i32 {
|
||||
@ -799,7 +828,8 @@ export class Float64Array extends ArrayBufferView {
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@inline function SOME<TArray extends ArrayBufferView, T>(
|
||||
@inline
|
||||
function SOME<TArray extends ArrayBufferView, T>(
|
||||
array: TArray,
|
||||
callbackfn: (value: T, index: i32, array: TArray) => bool,
|
||||
): bool {
|
||||
@ -811,7 +841,8 @@ export class Float64Array extends ArrayBufferView {
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@inline function EVERY<TArray extends ArrayBufferView, T>(
|
||||
@inline
|
||||
function EVERY<TArray extends ArrayBufferView, T>(
|
||||
array: TArray,
|
||||
callbackfn: (value: T, index: i32, array: TArray) => bool,
|
||||
): bool {
|
||||
@ -824,7 +855,8 @@ export class Float64Array extends ArrayBufferView {
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@inline function FOREACH<TArray extends ArrayBufferView, T>(
|
||||
@inline
|
||||
function FOREACH<TArray extends ArrayBufferView, T>(
|
||||
array: TArray,
|
||||
callbackfn: (value: T, index: i32, array: TArray) => void,
|
||||
): void {
|
||||
|
@ -1,15 +1,19 @@
|
||||
/** Number of alignment bits. */
|
||||
// @ts-ignore: decorator
|
||||
@inline export const AL_BITS: u32 = 3;
|
||||
@inline
|
||||
export const AL_BITS: u32 = 3;
|
||||
|
||||
/** Number of possible alignment values. */
|
||||
// @ts-ignore: decorator
|
||||
@inline export const AL_SIZE: usize = 1 << <usize>AL_BITS;
|
||||
@inline
|
||||
export const AL_SIZE: usize = 1 << <usize>AL_BITS;
|
||||
|
||||
/** Mask to obtain just the alignment bits. */
|
||||
// @ts-ignore: decorator
|
||||
@inline export const AL_MASK: usize = AL_SIZE - 1;
|
||||
@inline
|
||||
export const AL_MASK: usize = AL_SIZE - 1;
|
||||
|
||||
/** Maximum 32-bit allocation size. */
|
||||
// @ts-ignore: decorator
|
||||
@inline export const MAX_SIZE_32: usize = 1 << 30; // 1GB
|
||||
@inline
|
||||
export const MAX_SIZE_32: usize = 1 << 30; // 1GB
|
||||
|
@ -1,35 +1,32 @@
|
||||
// @ts-ignore: decorator
|
||||
@inline export function HASH<T>(key: T): u32 {
|
||||
@inline
|
||||
export function HASH<T>(key: T): u32 {
|
||||
if (isString(key)) {
|
||||
// @ts-ignore: type
|
||||
return hashStr(key);
|
||||
return hashStr(changetype<string>(key));
|
||||
} else if (isReference<T>()) {
|
||||
if (sizeof<T>() == 4) return hash32(changetype<u32>(key));
|
||||
if (sizeof<T>() == 8) return hash64(changetype<u64>(key));
|
||||
} else if (isFloat<T>()) {
|
||||
// @ts-ignore: type
|
||||
if (sizeof<T>() == 4) return hash32(reinterpret<u32>(key));
|
||||
// @ts-ignore: type
|
||||
if (sizeof<T>() == 8) return hash64(reinterpret<u64>(key));
|
||||
if (sizeof<T>() == 4) return hash32(reinterpret<u32>(f32(key)));
|
||||
if (sizeof<T>() == 8) return hash64(reinterpret<u64>(f64(key)));
|
||||
} else {
|
||||
// @ts-ignore: type
|
||||
if (sizeof<T>() == 1) return hash8 (<u32>key);
|
||||
// @ts-ignore: type
|
||||
if (sizeof<T>() == 2) return hash16(<u32>key);
|
||||
// @ts-ignore: type
|
||||
if (sizeof<T>() == 4) return hash32(<u32>key);
|
||||
// @ts-ignore: type
|
||||
if (sizeof<T>() == 8) return hash64(<u64>key);
|
||||
if (sizeof<T>() == 1) return hash8 (u32(key));
|
||||
if (sizeof<T>() == 2) return hash16(u32(key));
|
||||
if (sizeof<T>() == 4) return hash32(u32(key));
|
||||
if (sizeof<T>() == 8) return hash64(u64(key));
|
||||
}
|
||||
unreachable();
|
||||
return unreachable();
|
||||
}
|
||||
|
||||
// FNV-1a 32-bit as a starting point, see: http://isthe.com/chongo/tech/comp/fnv/
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@inline const FNV_OFFSET: u32 = 2166136261;
|
||||
@inline
|
||||
const FNV_OFFSET: u32 = 2166136261;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@inline const FNV_PRIME: u32 = 16777619;
|
||||
@inline
|
||||
const FNV_PRIME: u32 = 16777619;
|
||||
|
||||
function hash8(key: u32): u32 {
|
||||
return (FNV_OFFSET ^ key) * FNV_PRIME;
|
||||
|
@ -2,10 +2,12 @@ import { runtime } from "../runtime";
|
||||
import { CharCode } from "./string";
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@inline export const MAX_DOUBLE_LENGTH = 28;
|
||||
@inline
|
||||
export const MAX_DOUBLE_LENGTH = 28;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy @inline const POWERS10: u32[] = [
|
||||
@lazy @inline
|
||||
const POWERS10: u32[] = [
|
||||
1,
|
||||
10,
|
||||
100,
|
||||
@ -33,7 +35,8 @@ import { CharCode } from "./string";
|
||||
"90", "91", "92", "93", "94", "95", "96", "97", "98", "99"
|
||||
*/
|
||||
// @ts-ignore: decorator
|
||||
@lazy @inline const DIGITS: u32[] = [
|
||||
@lazy @inline
|
||||
const DIGITS: u32[] = [
|
||||
0x00300030, 0x00310030, 0x00320030, 0x00330030, 0x00340030,
|
||||
0x00350030, 0x00360030, 0x00370030, 0x00380030, 0x00390030,
|
||||
0x00300031, 0x00310031, 0x00320031, 0x00330031, 0x00340031,
|
||||
@ -57,7 +60,8 @@ import { CharCode } from "./string";
|
||||
];
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@lazy @inline const EXP_POWERS: i16[] = [
|
||||
@lazy @inline
|
||||
const EXP_POWERS: i16[] = [
|
||||
-1220, -1193, -1166, -1140, -1113, -1087, -1060, -1034, -1007, -980,
|
||||
-954, -927, -901, -874, -847, -821, -794, -768, -741, -715,
|
||||
-688, -661, -635, -608, -582, -555, -529, -502, -475, -449,
|
||||
@ -71,7 +75,8 @@ import { CharCode } from "./string";
|
||||
|
||||
// 1e-348, 1e-340, ..., 1e340
|
||||
// @ts-ignore: decorator
|
||||
@lazy @inline const FRC_POWERS: u64[] = [
|
||||
@lazy @inline
|
||||
const FRC_POWERS: u64[] = [
|
||||
0xFA8FD5A0081C0288, 0xBAAEE17FA23EBF76, 0x8B16FB203055AC76, 0xCF42894A5DCE35EA,
|
||||
0x9A6BB0AA55653B2D, 0xE61ACF033D1A45DF, 0xAB70FE17C79AC6CA, 0xFF77B1FCBEBCDC4F,
|
||||
0xBE5691EF416BD60C, 0x8DD01FAD907FFC3C, 0xD3515C2831559A83, 0x9D71AC8FADA6C9B5,
|
||||
@ -105,7 +110,7 @@ export function decimalCount32(value: u32): u32 {
|
||||
|
||||
let lutbuf = <ArrayBuffer>POWERS10.buffer_;
|
||||
let power = LOAD<u32>(lutbuf, t);
|
||||
t -= <u32>(value < power);
|
||||
t -= u32(value < power);
|
||||
return t + 1;
|
||||
} else {
|
||||
if (value < 100000) {
|
||||
@ -135,7 +140,7 @@ export function decimalCount64(value: u64): u32 {
|
||||
|
||||
let lutbuf = <ArrayBuffer>POWERS10.buffer_;
|
||||
let power = LOAD<u32,u64>(lutbuf, t - 10);
|
||||
t -= <u32>(value < 10000000000 * power);
|
||||
t -= u32(value < 10000000000 * power);
|
||||
return t + 1;
|
||||
} else {
|
||||
if (value < 1000000000000000) {
|
||||
|
@ -1,60 +1,50 @@
|
||||
import { compareImpl } from "./string";
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@inline export function COMPARATOR<T>(): (a: T, b: T) => i32 {
|
||||
@inline
|
||||
export function COMPARATOR<T>(): (a: T, b: T) => i32 {
|
||||
if (isInteger<T>()) {
|
||||
if (isSigned<T>() && sizeof<T>() <= 4) {
|
||||
// @ts-ignore: type
|
||||
return (a: T, b: T): i32 => (<i32>(a - b));
|
||||
return (a: T, b: T): i32 => (i32(a) - i32(b));
|
||||
} else {
|
||||
// @ts-ignore: type
|
||||
return (a: T, b: T): i32 => (<i32>(a > b) - <i32>(a < b));
|
||||
return (a: T, b: T): i32 => (i32(a > b) - i32(a < b));
|
||||
}
|
||||
} else if (isFloat<T>()) {
|
||||
if (sizeof<T>() == 4) {
|
||||
return (a: T, b: T): i32 => {
|
||||
// @ts-ignore: type
|
||||
var ia = reinterpret<i32>(a);
|
||||
// @ts-ignore: type
|
||||
var ib = reinterpret<i32>(b);
|
||||
var ia = reinterpret<i32>(f32(a));
|
||||
var ib = reinterpret<i32>(f32(b));
|
||||
ia ^= (ia >> 31) >>> 1;
|
||||
ib ^= (ib >> 31) >>> 1;
|
||||
// @ts-ignore: type
|
||||
return <i32>(ia > ib) - <i32>(ia < ib);
|
||||
return i32(ia > ib) - i32(ia < ib);
|
||||
};
|
||||
} else {
|
||||
return (a: T, b: T): i32 => {
|
||||
// @ts-ignore: type
|
||||
var ia = reinterpret<i64>(a);
|
||||
// @ts-ignore: type
|
||||
var ib = reinterpret<i64>(b);
|
||||
var ia = reinterpret<i64>(f64(a));
|
||||
var ib = reinterpret<i64>(f64(b));
|
||||
ia ^= (ia >> 63) >>> 1;
|
||||
ib ^= (ib >> 63) >>> 1;
|
||||
// @ts-ignore: type
|
||||
return <i32>(ia > ib) - <i32>(ia < ib);
|
||||
return i32(ia > ib) - i32(ia < ib);
|
||||
};
|
||||
}
|
||||
} else if (isString<T>()) {
|
||||
return (a: T, b: T): i32 => {
|
||||
if (a === b || a === null || b === null) return 0;
|
||||
// @ts-ignore: type
|
||||
var alen = (<string>a).length;
|
||||
// @ts-ignore: type
|
||||
var blen = (<string>b).length;
|
||||
var alen = changetype<string>(a).length;
|
||||
var blen = changetype<string>(b).length;
|
||||
if (!alen && !blen) return 0;
|
||||
if (!alen) return -1;
|
||||
if (!blen) return 1;
|
||||
// @ts-ignore: type
|
||||
return compareImpl(<string>a, 0, <string>b, 0, <usize>min(alen, blen));
|
||||
return compareImpl(changetype<string>(a), 0, changetype<string>(b), 0, <usize>min(alen, blen));
|
||||
};
|
||||
} else {
|
||||
// @ts-ignore: type
|
||||
return (a: T, b: T): i32 => (<i32>(a > b) - <i32>(a < b));
|
||||
return (a: T, b: T): i32 => (i32(a > b) - i32(a < b));
|
||||
}
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@inline export function SORT<T>(
|
||||
@inline
|
||||
export function SORT<T>(
|
||||
dataStart: usize,
|
||||
length: i32,
|
||||
comparator: (a: T, b: T) => i32
|
||||
|
@ -9,7 +9,8 @@ export function compareImpl(str1: string, index1: usize, str2: string, index2: u
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@inline export const enum CharCode {
|
||||
@inline
|
||||
export const enum CharCode {
|
||||
PLUS = 0x2B,
|
||||
MINUS = 0x2D,
|
||||
DOT = 0x2E,
|
||||
@ -58,7 +59,7 @@ export function isWhiteSpaceOrLineTerminator(c: u16): bool {
|
||||
/** Parses a string to an integer (usually), using the specified radix. */
|
||||
export function parse<T>(str: string, radix: i32 = 0): T {
|
||||
var len: i32 = str.length;
|
||||
// @ts-ignore: type
|
||||
// @ts-ignore: cast
|
||||
if (!len) return <T>NaN;
|
||||
|
||||
var ptr = changetype<usize>(str) /* + HEAD -> offset */;
|
||||
@ -67,13 +68,13 @@ export function parse<T>(str: string, radix: i32 = 0): T {
|
||||
// determine sign
|
||||
var sign: T;
|
||||
if (code == CharCode.MINUS) {
|
||||
// @ts-ignore: type
|
||||
// @ts-ignore: cast
|
||||
if (!--len) return <T>NaN;
|
||||
code = <i32>load<u16>(ptr += 2);
|
||||
// @ts-ignore: type
|
||||
sign = -1;
|
||||
} else if (code == CharCode.PLUS) {
|
||||
// @ts-ignore: type
|
||||
// @ts-ignore: cast
|
||||
if (!--len) return <T>NaN;
|
||||
code = <i32>load<u16>(ptr += 2);
|
||||
// @ts-ignore: type
|
||||
|
Reference in New Issue
Block a user