Skip to content

Commit 4829f3a

Browse files
MaxGraeydcodeIO
authored andcommitted
Add ArrayBuffer.isView and rework Array.isArray (AssemblyScript#431)
1 parent 1867416 commit 4829f3a

18 files changed

+3335
-2372
lines changed

src/builtins.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,6 @@ export function compileCall(
113113
let type = evaluateConstantType(compiler, typeArguments, operands, reportNode);
114114
compiler.currentType = Type.bool;
115115
if (!type) return module.createUnreachable();
116-
compiler.currentType = Type.bool;
117116
return type.is(TypeFlags.REFERENCE)
118117
? module.createI32(1)
119118
: module.createI32(0);
@@ -134,9 +133,9 @@ export function compileCall(
134133
compiler.currentType = Type.bool;
135134
if (!type) return module.createUnreachable();
136135
let classType = type.classReference;
137-
return classType !== null && classType.lookupOverload(OperatorKind.INDEXED_GET) !== null
138-
? module.createI32(1)
139-
: module.createI32(0);
136+
return (
137+
classType !== null && classType.prototype.extends(compiler.program.arrayPrototype)
138+
) ? module.createI32(1) : module.createI32(0);
140139
}
141140
case "isDefined": { // isDefined(expression) -> bool
142141
compiler.currentType = Type.bool;

src/program.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2856,6 +2856,14 @@ export class ClassPrototype extends Element {
28562856
this.decoratorFlags = decoratorFlags;
28572857
}
28582858

2859+
extends(basePtototype: ClassPrototype | null): bool {
2860+
var current: ClassPrototype | null = this;
2861+
do {
2862+
if (current === basePtototype) return true;
2863+
} while (current = current.basePrototype);
2864+
return false;
2865+
}
2866+
28592867
toString(): string {
28602868
return this.simpleName;
28612869
}
@@ -2969,6 +2977,16 @@ export class Class extends Element {
29692977
return null;
29702978
}
29712979

2980+
lookupField(name: string, shouldReadonly: boolean = false): Element | null {
2981+
if (this.members == null) return null;
2982+
var member = this.members.get(name);
2983+
if (
2984+
member == null || member.kind != ElementKind.FIELD ||
2985+
(shouldReadonly && !member.is(CommonFlags.READONLY))
2986+
) return null;
2987+
return member;
2988+
}
2989+
29722990
offsetof(fieldName: string): u32 {
29732991
var members = assert(this.members);
29742992
assert(members.has(fieldName));

std/assembly/arraybuffer.ts

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,44 @@ import {
44
allocateUnsafe
55
} from "./internal/arraybuffer";
66

7+
import {
8+
Uint8ClampedArray,
9+
Uint8Array,
10+
Int8Array,
11+
Uint16Array,
12+
Int16Array,
13+
Uint32Array,
14+
Int32Array,
15+
Uint64Array,
16+
Int64Array
17+
} from "./typedarray";
18+
19+
import {
20+
DataView
21+
} from "./dataview";
22+
723
@sealed
824
export class ArrayBuffer {
925

1026
readonly byteLength: i32; // capped to [0, MAX_LENGTH]
1127

28+
@inline static isView<T>(value: T): bool {
29+
if (value === null) return false;
30+
if (value instanceof Uint8ClampedArray) return true;
31+
if (value instanceof Uint8Array) return true;
32+
if (value instanceof Int8Array) return true;
33+
if (value instanceof Uint16Array) return true;
34+
if (value instanceof Int16Array) return true;
35+
if (value instanceof Uint32Array) return true;
36+
if (value instanceof Int32Array) return true;
37+
if (value instanceof Uint64Array) return true;
38+
if (value instanceof Int64Array) return true;
39+
if (value instanceof DataView) return true;
40+
return false;
41+
}
42+
1243
// @unsafe
13-
get data(): usize { return changetype<usize>(this) + HEADER_SIZE; }
44+
@inline get data(): usize { return changetype<usize>(this) + HEADER_SIZE; }
1445

1546
constructor(length: i32, unsafe: bool = false) {
1647
if (<u32>length > <u32>MAX_BLENGTH) throw new RangeError("Invalid array buffer length");

std/assembly/index.d.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,10 +493,14 @@ declare class ArrayBuffer {
493493
readonly byteLength: i32;
494494
/** Unsafe pointer to the start of the data in memory. */
495495
readonly data: usize;
496+
/** Returns true if value is one of the ArrayBuffer views, such as typed array or a DataView **/
497+
static isView<T>(value: T): bool;
496498
/** Constructs a new array buffer of the given length in bytes. */
497499
constructor(length: i32, unsafe?: bool);
498500
/** Returns a copy of this array buffer's bytes from begin, inclusive, up to end, exclusive. */
499501
slice(begin?: i32, end?: i32): ArrayBuffer;
502+
/** Returns a string representation of ArrayBuffer. */
503+
toString(): string;
500504
}
501505

502506
/** The `DataView` view provides a low-level interface for reading and writing multiple number types in a binary `ArrayBuffer`, without having to care about the platform's endianness. */

std/portable/index.d.ts

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,14 @@
1616

1717
// Types
1818

19+
declare type bool = boolean;
1920
declare type i8 = number;
2021
declare type i16 = number;
2122
declare type i32 = number;
2223
declare type isize = number;
2324
declare type u8 = number;
2425
declare type u16 = number;
2526
declare type u32 = number;
26-
declare type bool = boolean;
2727
declare type usize = number;
2828
declare type f32 = number;
2929
declare type f64 = number;
@@ -32,6 +32,20 @@ declare type f64 = number;
3232

3333
/** Compiler target. 0 = JS, 1 = WASM32, 2 = WASM64. */
3434
declare const ASC_TARGET: i32;
35+
/** Provided noTreeshaking option. */
36+
declare const ASC_NO_TREESHAKING: bool;
37+
/** Provided noAssert option. */
38+
declare const ASC_NO_ASSERT: bool;
39+
/** Provided memoryBase option. */
40+
declare const ASC_MEMORY_BASE: i32;
41+
/** Provided optimizeLevel option. */
42+
declare const ASC_OPTIMIZE_LEVEL: i32;
43+
/** Provided shrinkLevel option. */
44+
declare const ASC_SHRINK_LEVEL: i32;
45+
/** Whether the mutable global feature is enabled. */
46+
declare const ASC_FEATURE_MUTABLE_GLOBAL: bool;
47+
/** Whether the sign extension feature is enabled. */
48+
declare const ASC_FEATURE_SIGN_EXTENSION: bool;
3549

3650
// Builtins
3751

@@ -299,6 +313,8 @@ declare namespace memory {
299313
declare class ArrayBuffer {
300314
/** The size, in bytes, of the array. */
301315
readonly byteLength: i32;
316+
/** Returns true if value is one of the ArrayBuffer views, such as typed array or a DataView **/
317+
static isView<T>(value: T): bool;
302318
/** Constructs a new array buffer of the given length in bytes. */
303319
constructor(length: i32);
304320
/** Returns a copy of this array buffer's bytes from begin, inclusive, up to end, exclusive. */
@@ -397,6 +413,17 @@ declare class Int32Array extends Array<i32> {}
397413
declare class Float32Array extends Array<f32> {}
398414
declare class Float64Array extends Array<f64> {}
399415

416+
/** Interface for a typed view on an array buffer. */
417+
interface ArrayBufferView<T> {
418+
[key: number]: T;
419+
/** The {@link ArrayBuffer} referenced by this view. */
420+
readonly buffer: ArrayBuffer;
421+
/** The offset in bytes from the start of the referenced {@link ArrayBuffer}. */
422+
readonly byteOffset: i32;
423+
/** The length in bytes from the start of the referenced {@link ArrayBuffer}. */
424+
readonly byteLength: i32;
425+
}
426+
400427
declare class String {
401428

402429
static fromCharCode(ls: i32, hs?: i32): string;

std/portable/index.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,14 @@
22

33
var globalScope = typeof window !== "undefined" && window || typeof global !== "undefined" && global || self;
44

5-
globalScope.ASC_TARGET = 0;
5+
globalScope.ASC_TARGET = 0; // JS
6+
globalScope.ASC_NO_TREESHAKING = false;
7+
globalScope.ASC_NO_ASSERT = false;
8+
globalScope.ASC_MEMORY_BASE = 0;
9+
globalScope.ASC_OPTIMIZE_LEVEL = 3;
10+
globalScope.ASC_SHRINK_LEVEL = 0;
11+
globalScope.ASC_FEATURE_MUTABLE_GLOBAL = false;
12+
globalScope.ASC_FEATURE_SIGN_EXTENSION = false;
613

714
var F64 = new Float64Array(1);
815
var U64 = new Uint32Array(F64.buffer);
@@ -197,7 +204,7 @@ globalScope["isFloat"] = function isFloat(arg) {
197204
return typeof arg === "number";
198205
};
199206

200-
globalScope["isReference"] = function isClass(arg) {
207+
globalScope["isReference"] = function isReference(arg) {
201208
return typeof arg === "object" || typeof arg === "string";
202209
};
203210

0 commit comments

Comments
 (0)