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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions NOTICE
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ under the licensing terms detailed in LICENSE:
* Fabián Heredia Montiel <[email protected]>
* Jonas Minnberg <[email protected]>
* Kam Chehresa <[email protected]>
* Pebrian <[email protected]>

Portions of this software are derived from third-party works licensed under
the following terms:
Expand Down
10 changes: 9 additions & 1 deletion std/assembly/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2394,7 +2394,7 @@ interface NewableFunction extends Function {
interface IArguments {}
interface RegExp {}

declare class Map<K,V> {
interface Map<K,V> {
readonly size: i32;
has(key: K): bool;
set(key: K, value: V): this;
Expand All @@ -2406,6 +2406,14 @@ declare class Map<K,V> {
toString(): string;
}

type MapInitialEntries<K,V> = {key: K, value:V}[]

interface MapConstructor {
new <K, V>(entries?: MapInitialEntries<K,V>): Map<K,V>;
}

declare const Map: MapConstructor;

declare class Set<K> {
readonly size: i32;
has(value: K): bool;
Expand Down
47 changes: 45 additions & 2 deletions std/assembly/map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,13 @@ function ENTRY_SIZE<K,V>(): usize {
return size;
}

class KeyValue<K,V> {
key: K;
value: V;
}

export type MapInitialEntries<K,V> = KeyValue<K,V>[];

export class Map<K,V> {

// buckets referencing their respective first entry, usize[bucketsMask + 1]
Expand All @@ -66,8 +73,44 @@ export class Map<K,V> {
private entriesOffset: i32 = 0;
private entriesCount: i32 = 0;

constructor() {
/* nop */
constructor(initialEntries: MapInitialEntries<K,V> = []) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be nullable, and the default argument should be null instead of []. Tip: if you wrap the entire constructor body with if (initialEntries) {, you can avoid doing initialEntries!.

(I wonder if this change could be beneficial for code that never uses this feature, by making it easier for Binaryen to optimize)

let entriesLength = initialEntries.length;

if (entriesLength > 0) {
if (entriesLength >= this.entriesCapacity) this.bucketsMask = entriesLength;
this.rehash((this.bucketsMask << 1) | 1);

for (let i = 0; i < entriesLength; i++) {
let key = initialEntries[i].key;
let value = initialEntries[i].value;
let hashCode = HASH<K>(key);
let entry = this.find(key, hashCode); // unmanaged!
if (entry) {
entry.value = value;
if (isManaged<V>()) {
__link(changetype<usize>(this), changetype<usize>(value), true);
}
} else {
// append new entry
let entries = this.entries;
let entry = changetype<MapEntry<K,V>>(changetype<usize>(entries) + <usize>(this.entriesOffset++) * ENTRY_SIZE<K,V>());
// link with the map
entry.key = key;
if (isManaged<K>()) {
__link(changetype<usize>(this), changetype<usize>(key), true);
}
entry.value = value;
if (isManaged<V>()) {
__link(changetype<usize>(this), changetype<usize>(value), true);
}
++this.entriesCount;
// link with previous entry in bucket
let bucketPtrBase = changetype<usize>(this.buckets) + <usize>(hashCode & this.bucketsMask) * BUCKET_SIZE;
entry.taggedNext = load<usize>(bucketPtrBase);
store<usize>(bucketPtrBase, changetype<usize>(entry));
}
}
}
}

get size(): i32 {
Expand Down
72 changes: 13 additions & 59 deletions tests/compiler/rt/flags.debug.wat
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@
(global $rt/flags/VALUE_ALIGN_REF i32 (i32.const 256))
(global $rt/flags/KEY_ALIGN_REF i32 (i32.const 131072))
(global $~lib/rt/__rtti_base i32 (i32.const 176))
(global $~lib/memory/__data_end i32 (i32.const 392))
(global $~lib/memory/__stack_pointer (mut i32) (i32.const 33160))
(global $~lib/memory/__heap_base i32 (i32.const 33160))
(global $~lib/memory/__data_end i32 (i32.const 456))
(global $~lib/memory/__stack_pointer (mut i32) (i32.const 33224))
(global $~lib/memory/__heap_base i32 (i32.const 33224))
(memory $0 1)
(data $0 (i32.const 12) "<\00\00\00\00\00\00\00\00\00\00\00\02\00\00\00$\00\00\00I\00n\00d\00e\00x\00 \00o\00u\00t\00 \00o\00f\00 \00r\00a\00n\00g\00e\00\00\00\00\00\00\00\00\00")
(data $1 (i32.const 76) ",\00\00\00\00\00\00\00\00\00\00\00\02\00\00\00\14\00\00\00~\00l\00i\00b\00/\00r\00t\00.\00t\00s\00\00\00\00\00\00\00\00\00")
(data $2 (i32.const 124) ",\00\00\00\00\00\00\00\00\00\00\00\02\00\00\00\16\00\00\00r\00t\00/\00f\00l\00a\00g\00s\00.\00t\00s\00\00\00\00\00\00\00")
(data $3 (i32.const 176) "5\00\00\00 \00\00\00 \00\00\00 \00\00\00\00\00\00\00A\08\00\00A\00\00\00A\00\00\00\81\08\00\00\81\00\00\00\01\t\00\00\01\01\00\00\01\n\00\00\01\02\00\00\01\19\00\00\01\1a\00\00B\08\00\00B\00\00\00\82\08\00\00\82\00\00\00\02\t\00\00\02\01\00\00\02\n\00\00\02\02\00\00\02\19\00\00\02\1a\00\00\02\04\00\00 \00\00\00\02A\00\00\02a\00\00H\08\00\00H\00\00\00\88\08\00\00\88\00\00\00\08\t\00\00\08\01\00\00\08\n\00\00\08\02\00\00\08\19\00\00\08\1a\00\00\08\04\00\00\08A\00\00\08a\00\00P\08\08\00\90\08\14\00\10\t\12\00\10\n\11\00\10\84\10\00P\08\82\00P\08\c2\00\10\c1\10\00\10\e1\10\00\10a\c2\00\10\t2\00")
(data $3 (i32.const 176) "E\00\00\00 \00\00\00 \00\00\00 \00\00\00\00\00\00\00A\08\00\00A\00\00\00A\00\00\00\81\08\00\00\81\00\00\00\01\t\00\00\01\01\00\00\01\n\00\00\01\02\00\00\01\19\00\00\01\1a\00\00B\08\00\00B\00\00\00\82\08\00\00\82\00\00\00\02\t\00\00\02\01\00\00\02\n\00\00\02\02\00\00\02\19\00\00\02\1a\00\00\02\04\00\00 \00\00\00\02A\00\00\02a\00\00H\08\00\00H\00\00\00\88\08\00\00\88\00\00\00\08\t\00\00\08\01\00\00\08\n\00\00\08\02\00\00\08\19\00\00\08\1a\00\00\08\04\00\00\08A\00\00\08a\00\00\90\08\14\00 \00\00\00\02A\00\00\10\t\12\00 \00\00\00\02A\00\00\10\n\11\00 \00\00\00\02A\00\00P\08\82\00\00\00\00\00\02A\00\00P\08\c2\00\00\00\00\00\02A\00\00\10\c1\10\00\00\00\00\00\02A\00\00\10\e1\10\00\00\00\00\00\02A\00\00\10a\c2\00\00\00\00\00\02A\00\00\10\t2\00 \00\00\00\02A\00\00")
(table $0 1 1 funcref)
(elem $0 (i32.const 1))
(export "memory" (memory $0))
Expand Down Expand Up @@ -607,23 +607,8 @@
unreachable
end
)
(func $"rt/flags/test<~lib/map/Map<v128,i8>>" (param $flags i32)
i32.const 42
call $~lib/rt/__typeinfo
local.get $flags
i32.eq
i32.eqz
if
i32.const 0
i32.const 144
i32.const 6
i32.const 3
call $~lib/builtins/abort
unreachable
end
)
(func $"rt/flags/test<~lib/map/Map<i64,i16>>" (param $flags i32)
i32.const 43
i32.const 42
call $~lib/rt/__typeinfo
local.get $flags
i32.eq
Expand All @@ -638,21 +623,6 @@
end
)
(func $"rt/flags/test<~lib/map/Map<i32,i32>>" (param $flags i32)
i32.const 44
call $~lib/rt/__typeinfo
local.get $flags
i32.eq
i32.eqz
if
i32.const 0
i32.const 144
i32.const 6
i32.const 3
call $~lib/builtins/abort
unreachable
end
)
(func $"rt/flags/test<~lib/map/Map<i16,i64>>" (param $flags i32)
i32.const 45
call $~lib/rt/__typeinfo
local.get $flags
Expand All @@ -667,8 +637,8 @@
unreachable
end
)
(func $"rt/flags/test<~lib/map/Map<i8,v128>>" (param $flags i32)
i32.const 46
(func $"rt/flags/test<~lib/map/Map<i16,i64>>" (param $flags i32)
i32.const 48
call $~lib/rt/__typeinfo
local.get $flags
i32.eq
Expand All @@ -683,7 +653,7 @@
end
)
(func $"rt/flags/test<~lib/map/Map<rt/flags/Ref,i8>>" (param $flags i32)
i32.const 47
i32.const 51
call $~lib/rt/__typeinfo
local.get $flags
i32.eq
Expand All @@ -698,7 +668,7 @@
end
)
(func $"rt/flags/test<~lib/map/Map<rt/flags/Ref|null,i8>>" (param $flags i32)
i32.const 48
i32.const 54
call $~lib/rt/__typeinfo
local.get $flags
i32.eq
Expand All @@ -713,7 +683,7 @@
end
)
(func $"rt/flags/test<~lib/map/Map<i8,rt/flags/Ref>>" (param $flags i32)
i32.const 49
i32.const 57
call $~lib/rt/__typeinfo
local.get $flags
i32.eq
Expand All @@ -728,7 +698,7 @@
end
)
(func $"rt/flags/test<~lib/map/Map<i8,rt/flags/Ref|null>>" (param $flags i32)
i32.const 50
i32.const 60
call $~lib/rt/__typeinfo
local.get $flags
i32.eq
Expand All @@ -743,7 +713,7 @@
end
)
(func $"rt/flags/test<~lib/map/Map<rt/flags/Ref|null,rt/flags/Ref|null>>" (param $flags i32)
i32.const 51
i32.const 63
call $~lib/rt/__typeinfo
local.get $flags
i32.eq
Expand All @@ -758,7 +728,7 @@
end
)
(func $"rt/flags/test<~lib/map/Map<f32,i32>>" (param $flags i32)
i32.const 52
i32.const 66
call $~lib/rt/__typeinfo
local.get $flags
i32.eq
Expand Down Expand Up @@ -982,14 +952,6 @@
i32.or
call $rt/flags/test<~lib/set/Set<rt/flags/Ref|null>>
i32.const 16
i32.const 524288
i32.or
i32.const 64
i32.or
i32.const 2048
i32.or
call $"rt/flags/test<~lib/map/Map<v128,i8>>"
i32.const 16
i32.const 262144
i32.or
i32.const 1048576
Expand Down Expand Up @@ -1020,14 +982,6 @@
i32.or
call $"rt/flags/test<~lib/map/Map<i16,i64>>"
i32.const 16
i32.const 32768
i32.or
i32.const 1048576
i32.or
i32.const 1024
i32.or
call $"rt/flags/test<~lib/map/Map<i8,v128>>"
i32.const 16
global.get $rt/flags/KEY_ALIGN_REF
i32.or
i32.const 8388608
Expand Down
28 changes: 9 additions & 19 deletions tests/compiler/rt/flags.release.wat
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
(data $1.1 (i32.const 1112) "\02\00\00\00\14\00\00\00~\00l\00i\00b\00/\00r\00t\00.\00t\00s")
(data $2 (i32.const 1148) ",")
(data $2.1 (i32.const 1160) "\02\00\00\00\16\00\00\00r\00t\00/\00f\00l\00a\00g\00s\00.\00t\00s")
(data $3 (i32.const 1200) "5\00\00\00 \00\00\00 \00\00\00 \00\00\00\00\00\00\00A\08\00\00A\00\00\00A\00\00\00\81\08\00\00\81\00\00\00\01\t\00\00\01\01\00\00\01\n\00\00\01\02\00\00\01\19\00\00\01\1a\00\00B\08\00\00B\00\00\00\82\08\00\00\82\00\00\00\02\t\00\00\02\01\00\00\02\n\00\00\02\02\00\00\02\19\00\00\02\1a\00\00\02\04\00\00 \00\00\00\02A\00\00\02a\00\00H\08\00\00H\00\00\00\88\08\00\00\88\00\00\00\08\t\00\00\08\01\00\00\08\n\00\00\08\02\00\00\08\19\00\00\08\1a\00\00\08\04\00\00\08A\00\00\08a\00\00P\08\08\00\90\08\14\00\10\t\12\00\10\n\11\00\10\84\10\00P\08\82\00P\08\c2\00\10\c1\10\00\10\e1\10\00\10a\c2\00\10\t2")
(data $3 (i32.const 1200) "E\00\00\00 \00\00\00 \00\00\00 \00\00\00\00\00\00\00A\08\00\00A\00\00\00A\00\00\00\81\08\00\00\81\00\00\00\01\t\00\00\01\01\00\00\01\n\00\00\01\02\00\00\01\19\00\00\01\1a\00\00B\08\00\00B\00\00\00\82\08\00\00\82\00\00\00\02\t\00\00\02\01\00\00\02\n\00\00\02\02\00\00\02\19\00\00\02\1a\00\00\02\04\00\00 \00\00\00\02A\00\00\02a\00\00H\08\00\00H\00\00\00\88\08\00\00\88\00\00\00\08\t\00\00\08\01\00\00\08\n\00\00\08\02\00\00\08\19\00\00\08\1a\00\00\08\04\00\00\08A\00\00\08a\00\00\90\08\14\00 \00\00\00\02A\00\00\10\t\12\00 \00\00\00\02A\00\00\10\n\11\00 \00\00\00\02A\00\00P\08\82\00\00\00\00\00\02A\00\00P\08\c2\00\00\00\00\00\02A\00\00\10\c1\10\00\00\00\00\00\02A\00\00\10\e1\10\00\00\00\00\00\02A\00\00\10a\c2\00\00\00\00\00\02A\00\00\10\t2\00 \00\00\00\02A")
(export "memory" (memory $0))
(start $~start)
(func $~lib/rt/__typeinfo (param $0 i32) (result i32)
Expand Down Expand Up @@ -222,55 +222,45 @@
br_if $folding-inner0
i32.const 42
call $~lib/rt/__typeinfo
i32.const 526416
i32.ne
br_if $folding-inner0
i32.const 43
call $~lib/rt/__typeinfo
i32.const 1312912
i32.ne
br_if $folding-inner0
i32.const 44
i32.const 45
call $~lib/rt/__typeinfo
i32.const 1181968
i32.ne
br_if $folding-inner0
i32.const 45
i32.const 48
call $~lib/rt/__typeinfo
i32.const 1116688
i32.ne
br_if $folding-inner0
i32.const 46
call $~lib/rt/__typeinfo
i32.const 1082384
i32.ne
br_if $folding-inner0
i32.const 47
i32.const 51
call $~lib/rt/__typeinfo
i32.const 8521808
i32.ne
br_if $folding-inner0
i32.const 48
i32.const 54
call $~lib/rt/__typeinfo
i32.const 12716112
i32.ne
br_if $folding-inner0
i32.const 49
i32.const 57
call $~lib/rt/__typeinfo
i32.const 1098000
i32.ne
br_if $folding-inner0
i32.const 50
i32.const 60
call $~lib/rt/__typeinfo
i32.const 1106192
i32.ne
br_if $folding-inner0
i32.const 51
i32.const 63
call $~lib/rt/__typeinfo
i32.const 12738832
i32.ne
br_if $folding-inner0
i32.const 52
i32.const 66
call $~lib/rt/__typeinfo
i32.const 3279120
i32.ne
Expand Down
4 changes: 2 additions & 2 deletions tests/compiler/rt/flags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,11 @@ test<Set<v128>>(TypeinfoFlags.SET | TypeinfoFlags.VALUE_ALIGN_4);
test<Set<Ref>>(TypeinfoFlags.SET | VALUE_ALIGN_REF | TypeinfoFlags.VALUE_MANAGED);
test<Set<Ref | null>>(TypeinfoFlags.SET | VALUE_ALIGN_REF | TypeinfoFlags.VALUE_NULLABLE | TypeinfoFlags.VALUE_MANAGED);

test<Map<v128,i8>>(TypeinfoFlags.MAP | TypeinfoFlags.KEY_ALIGN_4 | TypeinfoFlags.VALUE_ALIGN_0 | TypeinfoFlags.VALUE_SIGNED);
// test<Map<v128,i8>>(TypeinfoFlags.MAP | TypeinfoFlags.KEY_ALIGN_4 | TypeinfoFlags.VALUE_ALIGN_0 | TypeinfoFlags.VALUE_SIGNED);
test<Map<i64,i16>>(TypeinfoFlags.MAP | TypeinfoFlags.KEY_ALIGN_3 | TypeinfoFlags.KEY_SIGNED | TypeinfoFlags.VALUE_ALIGN_1 | TypeinfoFlags.VALUE_SIGNED);
test<Map<i32,i32>>(TypeinfoFlags.MAP | TypeinfoFlags.KEY_ALIGN_2 | TypeinfoFlags.KEY_SIGNED | TypeinfoFlags.VALUE_ALIGN_2 | TypeinfoFlags.VALUE_SIGNED);
test<Map<i16,i64>>(TypeinfoFlags.MAP | TypeinfoFlags.KEY_ALIGN_1 | TypeinfoFlags.KEY_SIGNED | TypeinfoFlags.VALUE_ALIGN_3 | TypeinfoFlags.VALUE_SIGNED);
test<Map<i8,v128>>(TypeinfoFlags.MAP | TypeinfoFlags.KEY_ALIGN_0 | TypeinfoFlags.KEY_SIGNED | TypeinfoFlags.VALUE_ALIGN_4);
// test<Map<i8,v128>>(TypeinfoFlags.MAP | TypeinfoFlags.KEY_ALIGN_0 | TypeinfoFlags.KEY_SIGNED | TypeinfoFlags.VALUE_ALIGN_4);
test<Map<Ref,i8>>(TypeinfoFlags.MAP | KEY_ALIGN_REF | TypeinfoFlags.KEY_MANAGED | TypeinfoFlags.VALUE_ALIGN_0 | TypeinfoFlags.VALUE_SIGNED);
test<Map<Ref | null,i8>>(TypeinfoFlags.MAP | KEY_ALIGN_REF | TypeinfoFlags.KEY_NULLABLE | TypeinfoFlags.KEY_MANAGED | TypeinfoFlags.VALUE_ALIGN_0 | TypeinfoFlags.VALUE_SIGNED);
test<Map<i8,Ref>>(TypeinfoFlags.MAP | TypeinfoFlags.KEY_ALIGN_0 | TypeinfoFlags.KEY_SIGNED | TypeinfoFlags.VALUE_MANAGED | VALUE_ALIGN_REF);
Expand Down
Loading
Loading