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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion std/assembly/array.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ export class Array<T> {

@operator("[]") private __get(index: i32): T {
if (<u32>index >= <u32>this.length_) throw new RangeError(E_INDEXOUTOFRANGE);
var value = this.__uget(index);
var value = load<T>(this.dataStart + (<usize>index << alignof<T>()));
if (isReference<T>()) {
if (!isNullable<T>()) {
if (!changetype<usize>(value)) throw new Error(E_HOLEYARRAY);
Expand Down Expand Up @@ -119,6 +119,19 @@ export class Array<T> {
}
}

at(index: i32): T {
var len = this.length_;
index += select(0, len, index >= 0);
if (<u32>index >= <u32>len) throw new RangeError(E_INDEXOUTOFRANGE);
var value = load<T>(this.dataStart + (<usize>index << alignof<T>()));
if (isReference<T>()) {
if (!isNullable<T>()) {
if (!changetype<usize>(value)) throw new Error(E_HOLEYARRAY);
}
}
return value;
}

fill(value: T, start: i32 = 0, end: i32 = i32.MAX_VALUE): this {
var dataStart = this.dataStart;
var length = this.length_;
Expand Down
5 changes: 5 additions & 0 deletions std/assembly/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1460,6 +1460,8 @@ declare abstract class TypedArray<T> implements ArrayBufferView {
readonly byteLength: i32;
/** The length (in elements). */
readonly length: i32;
/** Returns value using relative indexing. Index may be negative */
at(index: i32): T;
/** The includes() method determines whether a typed array includes a certain element, returning true or false as appropriate. */
includes(searchElement: T, fromIndex?: i32): bool;
/** The indexOf() method returns the first index at which a given element can be found in the typed array, or -1 if it is not present. */
Expand Down Expand Up @@ -1570,6 +1572,7 @@ declare class Array<T> {
/** Constructs a new array. */
constructor(capacity?: i32);

at(index: i32): T;
fill(value: T, start?: i32, end?: i32): this;
every(callbackfn: (element: T, index: i32, array?: Array<T>) => bool): bool;
findIndex(predicate: (element: T, index: i32, array?: Array<T>) => bool): i32;
Expand Down Expand Up @@ -1606,6 +1609,7 @@ declare class StaticArray<T> {
static slice<T>(source: StaticArray<T>, start?: i32, end?: i32): StaticArray<T>;
readonly length: i32;
constructor(length?: i32);
at(index: i32): T;
includes(searchElement: T, fromIndex?: i32): bool;
indexOf(searchElement: T, fromIndex?: i32): i32;
lastIndexOf(searchElement: T, fromIndex?: i32): i32;
Expand All @@ -1622,6 +1626,7 @@ declare class String {
static fromCodePoint(code: i32): string;
static fromCodePoints(arr: i32[]): string;
readonly length: i32;
at(index: i32): string;
charAt(index: i32): string;
charCodeAt(index: i32): i32;
codePointAt(index: i32): i32;
Expand Down
15 changes: 14 additions & 1 deletion std/assembly/staticarray.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,22 @@ export class StaticArray<T> {
return changetype<OBJECT>(changetype<usize>(this) - TOTAL_OVERHEAD).rtSize >>> alignof<T>();
}

at(index: i32): T {
var len = this.length;
index += select(0, len, index >= 0);
if (<u32>index >= <u32>len) throw new RangeError(E_INDEXOUTOFRANGE);
var value = load<T>(changetype<usize>(this) + (<usize>index << alignof<T>()));
if (isReference<T>()) {
if (!isNullable<T>()) {
if (!changetype<usize>(value)) throw new Error(E_HOLEYARRAY);
}
}
return value;
}

@operator("[]") private __get(index: i32): T {
if (<u32>index >= <u32>this.length) throw new RangeError(E_INDEXOUTOFRANGE);
var value = this.__uget(index);
var value = load<T>(changetype<usize>(this) + (<usize>index << alignof<T>()));
if (isReference<T>()) {
if (!isNullable<T>()) {
if (!changetype<usize>(value)) throw new Error(E_HOLEYARRAY);
Expand Down
11 changes: 10 additions & 1 deletion std/assembly/string.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import { OBJECT, BLOCK_MAXSIZE, TOTAL_OVERHEAD } from "./rt/common";
import { compareImpl, strtol, strtod, isSpace, isAscii, isFinalSigma, toLower8, toUpper8 } from "./util/string";
import { SPECIALS_UPPER, casemap, bsearch } from "./util/casemap";
import { E_INVALIDLENGTH } from "./util/error";
import { E_INDEXOUTOFRANGE, E_INVALIDLENGTH } from "./util/error";
import { idof } from "./builtins";
import { Array } from "./array";

Expand Down Expand Up @@ -48,6 +48,15 @@ import { Array } from "./array";
return changetype<OBJECT>(changetype<usize>(this) - TOTAL_OVERHEAD).rtSize >> 1;
}

at(pos: i32): String {
var len = this.length;
pos += select(0, len, pos >= 0);
if (<u32>pos >= <u32>len) throw new RangeError(E_INDEXOUTOFRANGE);
var out = __new(2, idof<String>());
store<u16>(out, load<u16>(changetype<usize>(this) + (<usize>pos << 1)));
return changetype<String>(out); // retains
}

@operator("[]") charAt(pos: i32): String {
if (<u32>pos >= <u32>this.length) return changetype<String>("");
var out = changetype<String>(__new(2, idof<String>()));
Expand Down
91 changes: 88 additions & 3 deletions std/assembly/typedarray.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,13 @@ export class Int8Array extends ArrayBufferView {
store<i8>(this.dataStart + <usize>index, value);
}

at(index: i32): i8 {
var len = this.byteLength;
index += select(0, len, index >= 0);
if (<u32>index >= <u32>len) throw new RangeError(E_INDEXOUTOFRANGE);
return load<i8>(this.dataStart + <usize>index);
}

includes(searchElement: i8, fromIndex: i32 = 0): bool {
return INCLUDES<Int8Array, i8>(this, searchElement, fromIndex);
}
Expand Down Expand Up @@ -169,6 +176,13 @@ export class Uint8Array extends ArrayBufferView {
store<u8>(this.dataStart + <usize>index, value);
}

at(index: i32): u8 {
var len = this.byteLength;
index += select(0, len, index >= 0);
if (<u32>index >= <u32>len) throw new RangeError(E_INDEXOUTOFRANGE);
return load<u8>(this.dataStart + <usize>index);
}

includes(searchElement: u8, fromIndex: i32 = 0): bool {
return INCLUDES<Uint8Array, u8>(this, searchElement, fromIndex);
}
Expand Down Expand Up @@ -297,6 +311,13 @@ export class Uint8ClampedArray extends ArrayBufferView {
store<u8>(this.dataStart + <usize>index, ~(<i32>value >> 31) & (((255 - value) >> 31) | value));
}

at(index: i32): u8 {
var len = this.byteLength;
index += select(0, len, index >= 0);
if (<u32>index >= <u32>len) throw new RangeError(E_INDEXOUTOFRANGE);
return load<u8>(this.dataStart + <usize>index);
}

includes(searchElement: u8, fromIndex: i32 = 0): bool {
return INCLUDES<Uint8ClampedArray, u8>(this, searchElement, fromIndex);
}
Expand Down Expand Up @@ -425,6 +446,13 @@ export class Int16Array extends ArrayBufferView {
store<i16>(this.dataStart + (<usize>index << alignof<i16>()), value);
}

at(index: i32): i16 {
var len = this.byteLength >>> alignof<i16>();
index += select(0, len, index >= 0);
if (<u32>index >= <u32>len) throw new RangeError(E_INDEXOUTOFRANGE);
return load<i16>(this.dataStart + (<usize>index << alignof<i16>()));
}

includes(searchElement: i16, fromIndex: i32 = 0): bool {
return INCLUDES<Int16Array, i16>(this, searchElement, fromIndex);
}
Expand Down Expand Up @@ -553,6 +581,13 @@ export class Uint16Array extends ArrayBufferView {
store<u16>(this.dataStart + (<usize>index << alignof<u16>()), value);
}

at(index: i32): u16 {
var len = this.byteLength >>> alignof<u16>();
index += select(0, len, index >= 0);
if (<u32>index >= <u32>len) throw new RangeError(E_INDEXOUTOFRANGE);
return load<u16>(this.dataStart + (<usize>index << alignof<u16>()));
}

includes(searchElement: u16, fromIndex: i32 = 0): bool {
return INCLUDES<Uint16Array, u16>(this, searchElement, fromIndex);
}
Expand Down Expand Up @@ -681,6 +716,13 @@ export class Int32Array extends ArrayBufferView {
store<i32>(this.dataStart + (<usize>index << alignof<i32>()), value);
}

at(index: i32): i32 {
var len = this.byteLength >>> alignof<i32>();
index += select(0, len, index >= 0);
if (<u32>index >= <u32>len) throw new RangeError(E_INDEXOUTOFRANGE);
return load<i32>(this.dataStart + (<usize>index << alignof<i32>()));
}

includes(searchElement: i32, fromIndex: i32 = 0): bool {
return INCLUDES<Int32Array, i32>(this, searchElement, fromIndex);
}
Expand Down Expand Up @@ -809,6 +851,13 @@ export class Uint32Array extends ArrayBufferView {
store<u32>(this.dataStart + (<usize>index << alignof<u32>()), value);
}

at(index: i32): u32 {
var len = this.byteLength >>> alignof<u32>();
index += select(0, len, index >= 0);
if (<u32>index >= <u32>len) throw new RangeError(E_INDEXOUTOFRANGE);
return load<u32>(this.dataStart + (<usize>index << alignof<u32>()));
}

includes(searchElement: u32, fromIndex: i32 = 0): bool {
return INCLUDES<Uint32Array, u32>(this, searchElement, fromIndex);
}
Expand Down Expand Up @@ -937,6 +986,13 @@ export class Int64Array extends ArrayBufferView {
store<i64>(this.dataStart + (<usize>index << alignof<i64>()), value);
}

at(index: i32): i64 {
var len = this.byteLength >>> alignof<i64>();
index += select(0, len, index >= 0);
if (<u32>index >= <u32>len) throw new RangeError(E_INDEXOUTOFRANGE);
return load<i64>(this.dataStart + (<usize>index << alignof<i64>()));
}

includes(searchElement: i64, fromIndex: i32 = 0): bool {
return INCLUDES<Int64Array, i64>(this, searchElement, fromIndex);
}
Expand Down Expand Up @@ -1065,6 +1121,13 @@ export class Uint64Array extends ArrayBufferView {
store<u64>(this.dataStart + (<usize>index << alignof<u64>()), value);
}

at(index: i32): u64 {
var len = this.byteLength >>> alignof<u64>();
index += select(0, len, index >= 0);
if (<u32>index >= <u32>len) throw new RangeError(E_INDEXOUTOFRANGE);
return load<u64>(this.dataStart + (<usize>index << alignof<u64>()));
}

includes(searchElement: u64, fromIndex: i32 = 0): bool {
return INCLUDES<Uint64Array, u64>(this, searchElement, fromIndex);
}
Expand Down Expand Up @@ -1193,6 +1256,13 @@ export class Float32Array extends ArrayBufferView {
store<f32>(this.dataStart + (<usize>index << alignof<f32>()), value);
}

at(index: i32): f32 {
var len = this.byteLength >>> alignof<f32>();
index += select(0, len, index >= 0);
if (<u32>index >= <u32>len) throw new RangeError(E_INDEXOUTOFRANGE);
return load<f32>(this.dataStart + (<usize>index << alignof<f32>()));
}

includes(searchElement: f32, fromIndex: i32 = 0): bool {
return INCLUDES<Float32Array, f32>(this, searchElement, fromIndex);
}
Expand Down Expand Up @@ -1321,6 +1391,13 @@ export class Float64Array extends ArrayBufferView {
store<f64>(this.dataStart + (<usize>index << alignof<f64>()), value);
}

at(index: i32): f64 {
var len = this.byteLength >>> alignof<f64>();
index += select(0, len, index >= 0);
if (<u32>index >= <u32>len) throw new RangeError(E_INDEXOUTOFRANGE);
return load<f64>(this.dataStart + (<usize>index << alignof<f64>()));
}

includes(searchElement: f64, fromIndex: i32 = 0): bool {
return INCLUDES<Float64Array, f64>(this, searchElement, fromIndex);
}
Expand Down Expand Up @@ -1737,7 +1814,11 @@ function REVERSE<TArray extends ArrayBufferView, T>(array: TArray): TArray {

// @ts-ignore: decorator
@inline
function WRAP<TArray extends ArrayBufferView, T>(buffer: ArrayBuffer, byteOffset: i32 = 0, length: i32 = -1): TArray {
function WRAP<TArray extends ArrayBufferView, T>(
buffer: ArrayBuffer,
byteOffset: i32 = 0,
length: i32 = -1
): TArray {
var byteLength: i32;
var bufferByteLength = buffer.byteLength;
const mask: u32 = sizeof<T>() - 1;
Expand Down Expand Up @@ -1769,7 +1850,11 @@ function WRAP<TArray extends ArrayBufferView, T>(buffer: ArrayBuffer, byteOffset

// @ts-ignore: decorator
@inline
function SET<TArray extends ArrayBufferView, T, UArray extends ArrayBufferView, U>(target: TArray, source: UArray, offset: i32 = 0): void {
function SET<TArray extends ArrayBufferView, T, UArray extends ArrayBufferView, U>(
target: TArray,
source: UArray,
offset: i32 = 0
): void {
// need to assert at compile time that U is not a reference or a function
if (isReference<U>()) {
ERROR(E_NOTIMPLEMENTED);
Expand Down Expand Up @@ -1798,7 +1883,7 @@ function SET<TArray extends ArrayBufferView, T, UArray extends ArrayBufferView,
let value = load<U>(sourceDataStart + (<usize>i << alignof<U>()));
store<T>(
targetDataStart + (<usize>i << alignof<T>()),
isFinite<U>(value) ? <T>max<U>(0, min<U>(255, value)) : 0
isFinite<U>(value) ? <T>max<U>(0, min<U>(255, value)) : <T>0
);
} else {
let value = load<U>(sourceDataStart + (<usize>i << alignof<U>()));
Expand Down
29 changes: 28 additions & 1 deletion std/portable/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -239,13 +239,23 @@ String["fromCodePoints"] = function fromCodePoints(arr) {
return parts;
};

if (!String.prototype.at) {
Object.defineProperty(String.prototype, "at", {
value: function at(index) {
return this.charAt(index >= 0 ? index : index + this.length);
},
configurable: true
});
}

if (!String.prototype.replaceAll) {
Object.defineProperty(String.prototype, "replaceAll", {
value: function replaceAll(search, replacment) {
var res = this.split(search).join(replacment);
if (!search.length) res = replacment + res + replacment;
return res;
}
},
configurable: true
});
}

Expand All @@ -267,6 +277,23 @@ Array.prototype.sort = function sort(comparator) {
return arraySort.call(this, comparator || defaultComparator);
};

[ Array,
Uint8ClampedArray,
Uint8Array, Int8Array,
Uint16Array, Int16Array,
Uint32Array, Int32Array,
Float32Array, Float64Array
].forEach(Ctr => {
if (!Ctr.prototype.at) {
Object.defineProperty(Ctr.prototype, "at", {
value: function at(index) {
return this[index >= 0 ? index : index + this.length];
},
configurable: true
});
}
});

globalScope["isInteger"] = Number.isInteger;

globalScope["isFloat"] = function isFloat(arg) {
Expand Down
Loading