Skip to content

Commit cc9ff81

Browse files
committed
merge to single segment
1 parent 2b30501 commit cc9ff81

File tree

10 files changed

+122
-25
lines changed

10 files changed

+122
-25
lines changed

src/glue/js/i64.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ declare function i64_not(value: I64): I64;
2626

2727
declare function i64_eq(left: I64, right: I64): bool;
2828
declare function i64_ne(left: I64, right: I64): bool;
29+
declare function i64_gt(left: I64, right: I64): bool;
2930

3031
declare function i64_align(value: I64, alignment: i32): I64;
3132

src/glue/js/i64.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,10 @@ global.i64_ne = function(left, right) {
8080
return left.ne(right);
8181
};
8282

83+
global.i64_gt = function(left, right) {
84+
return left.gt(right);
85+
};
86+
8387
global.i64_align = function(value, alignment) {
8488
assert(alignment && (alignment & (alignment - 1)) == 0);
8589
var mask = Long.fromInt(alignment - 1);

src/glue/wasm/i64.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,11 @@ function i64_ne(left: I64, right: I64): bool {
103103
return left != right;
104104
}
105105

106+
@global
107+
function i64_gt(left: I64, right: I64): bool {
108+
return left > right;
109+
}
110+
106111
@global
107112
function i64_align(value: I64, alignment: i64): I64 {
108113
var mask: i64 = alignment - 1;

src/module.ts

Lines changed: 39 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1167,22 +1167,45 @@ export class Module {
11671167
): void {
11681168
var cStr = this.allocStringCached(exportName);
11691169
var k = segments.length;
1170-
var segs = new Array<usize>(k);
1171-
var psvs = new Array<i8>(k);
1172-
var offs = new Array<ExpressionRef>(k);
1173-
var sizs = new Array<Index>(k);
1174-
for (let i = 0; i < k; ++i) {
1175-
let buffer = segments[i].buffer;
1176-
let offset = segments[i].offset;
1177-
segs[i] = allocU8Array(buffer);
1178-
psvs[i] = 0; // no passive segments currently
1179-
offs[i] = target == Target.WASM64
1180-
? this.i64(i64_low(offset), i64_high(offset))
1181-
: this.i32(i64_low(offset));
1182-
sizs[i] = buffer.length;
1183-
}
11841170
var mbase = this.mbase;
1185-
if (mbase) for (let i = 0; i < k; ++i) offs[i] = this.relocMem(offs[i]);
1171+
var segs: usize[], psvs: i8[], offs: ExpressionRef[], sizs: Index[];
1172+
if (mbase) {
1173+
// Offset expressions cannot currently use an addition but are restricted
1174+
// to a constant or a global.get, so make one large memory segment in the
1175+
// relocation case that starts exactly at the value of __memory_base.
1176+
let maxOffset = i64_zero;
1177+
for (let i = 0; i < k; ++i) {
1178+
let segment = segments[i];
1179+
let endOffset = i64_add(segment.offset, i64_new(segment.buffer.length));
1180+
if (i64_gt(endOffset, maxOffset)) maxOffset = endOffset;
1181+
}
1182+
assert(!i64_high(maxOffset)); // TODO: WASM64
1183+
let buffer = new Uint8Array(i64_low(maxOffset));
1184+
for (let i = 0; i < k; ++i) {
1185+
let segment = segments[i];
1186+
buffer.set(segment.buffer, i64_low(segment.offset));
1187+
}
1188+
segs = [ allocU8Array(buffer) ];
1189+
psvs = [ 0 ];
1190+
offs = [ _BinaryenGlobalGet(this.ref, mbase, target == Target.WASM64 ? NativeType.I64 : NativeType.I32) ];
1191+
sizs = [ buffer.length ];
1192+
k = 1;
1193+
} else {
1194+
segs = new Array<usize>(k);
1195+
psvs = new Array<i8>(k);
1196+
offs = new Array<ExpressionRef>(k);
1197+
sizs = new Array<Index>(k);
1198+
for (let i = 0; i < k; ++i) {
1199+
let buffer = segments[i].buffer;
1200+
let offset = segments[i].offset;
1201+
segs[i] = allocU8Array(buffer);
1202+
psvs[i] = 0; // no passive segments currently
1203+
offs[i] = target == Target.WASM64
1204+
? this.i64(i64_low(offset), i64_high(offset))
1205+
: this.i32(i64_low(offset));
1206+
sizs[i] = buffer.length;
1207+
}
1208+
}
11861209
var cArr1 = allocI32Array(segs);
11871210
var cArr2 = allocU8Array(psvs);
11881211
var cArr3 = allocI32Array(offs);
@@ -1796,7 +1819,7 @@ export class Relooper {
17961819
// helpers
17971820
// can't do stack allocation here: STACKTOP is a global in WASM but a hidden variable in asm.js
17981821

1799-
function allocU8Array(u8s: Uint8Array | null): usize {
1822+
function allocU8Array(u8s: u8[] | null): usize {
18001823
if (!u8s) return 0;
18011824
var numValues = u8s.length;
18021825
var ptr = memory.allocate(numValues);

std/portable/index.d.ts

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -410,15 +410,19 @@ declare class Array<T> {
410410
toString(): string;
411411
}
412412

413-
declare class Uint8Array extends Array<u8> {}
414-
declare class Uint8ClampedArray extends Array<u8> {}
415-
declare class Uint16Array extends Array<u16> {}
416-
declare class Uint32Array extends Array<u32> {}
417-
declare class Int8Array extends Array<i8> {}
418-
declare class Int16Array extends Array<i16> {}
419-
declare class Int32Array extends Array<i32> {}
420-
declare class Float32Array extends Array<f32> {}
421-
declare class Float64Array extends Array<f64> {}
413+
declare class TypedArray<T> extends Array<T> {
414+
set(array: TypedArray<T>, offset: i32): void;
415+
}
416+
417+
declare class Uint8Array extends TypedArray<u8> {}
418+
declare class Uint8ClampedArray extends TypedArray<u8> {}
419+
declare class Uint16Array extends TypedArray<u16> {}
420+
declare class Uint32Array extends TypedArray<u32> {}
421+
declare class Int8Array extends TypedArray<i8> {}
422+
declare class Int16Array extends TypedArray<i16> {}
423+
declare class Int32Array extends TypedArray<i32> {}
424+
declare class Float32Array extends TypedArray<f32> {}
425+
declare class Float64Array extends TypedArray<f64> {}
422426

423427
interface ArrayLike<T> {
424428
length: i32;

tests/compiler/relocatable.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
exports.preInstantiate = function(imports, exports) {
2+
// compiler generates initial = 1 because it doesn't know the imported value
3+
// of env.memory_base yet, hence we need to import a suitable memory as well:
4+
imports["env"] = {
5+
"memory": new WebAssembly.Memory({ initial: 2 }),
6+
"memory_base": 65536,
7+
"table_base": 100
8+
};
9+
};

tests/compiler/relocatable.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"asc_flags": [
3+
"--runtime none",
4+
"--relocatable",
5+
"--importMemory"
6+
]
7+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
(module
2+
(type $FUNCSIG$v (func))
3+
(import "env" "memory" (memory $0 1))
4+
(data (global.get $__memory_base) "\00\00\00\00\00\00\00\00\04\00\00\00\01\00\00\00\00\00\00\00\04\00\00\00\00\00\00\00\00\00\00\00\10\00\00\00\01\00\00\00\03\00\00\00\10\00\00\00\18\00\00\00\18\00\00\00\04\00\00\00\01\00\00\00")
5+
(import "env" "memory_base" (global $__memory_base i32))
6+
(global $__memory_size i32 (i32.const 64))
7+
(global $__table_size i32 (i32.const 1))
8+
(export "memory" (memory $0))
9+
(export "__memory_size" (global $__memory_size))
10+
(export "__table_size" (global $__table_size))
11+
(func $start (; 0 ;) (type $FUNCSIG$v)
12+
nop
13+
)
14+
)

tests/compiler/relocatable.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
const someStaticStuff: i32[] = [0];
2+
3+
someStaticStuff;
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
(module
2+
(type $FUNCSIG$v (func))
3+
(import "env" "memory" (memory $0 1))
4+
(data (global.get $__memory_base) "\00\00\00\00\00\00\00\00\04\00\00\00\01\00\00\00\00\00\00\00\04\00\00\00\00\00\00\00\00\00\00\00\10\00\00\00\01\00\00\00\03\00\00\00\10\00\00\00\18\00\00\00\18\00\00\00\04\00\00\00\01\00\00\00")
5+
(import "env" "memory_base" (global $__memory_base i32))
6+
(import "env" "table_base" (global $__table_base i32))
7+
(table $0 1 funcref)
8+
(elem (i32.const 0) $null)
9+
(global $relocatable/someStaticStuff i32 (i32.const 48))
10+
(global $__memory_size i32 (i32.const 64))
11+
(global $__table_size i32 (i32.const 1))
12+
(export "memory" (memory $0))
13+
(export "__memory_size" (global $__memory_size))
14+
(export "__table_size" (global $__table_size))
15+
(start $start)
16+
(func $start:relocatable (; 0 ;) (type $FUNCSIG$v)
17+
(local $0 i32)
18+
(local $1 i32)
19+
global.get $relocatable/someStaticStuff
20+
drop
21+
)
22+
(func $start (; 1 ;) (type $FUNCSIG$v)
23+
call $start:relocatable
24+
)
25+
(func $null (; 2 ;) (type $FUNCSIG$v)
26+
)
27+
)

0 commit comments

Comments
 (0)