Skip to content

Commit f3853de

Browse files
ericvergnaudradekdoulik
authored andcommitted
C API: Use segment names (WebAssembly#6254)
Move from segment indexes to names. This is a breaking change to make the API more capable and consistent. An effort has been made to reduce the burden on C API users where possible (specifically, you can avoid providing names and let Binaryen make them for you, which will basically be numbers that match the indexes from before). Fixes WebAssembly#6247
1 parent 3bf7836 commit f3853de

19 files changed

+155
-116
lines changed

src/binaryen-c.cpp

Lines changed: 30 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5329,8 +5329,9 @@ void BinaryenSetMemory(BinaryenModuleRef module,
53295329
BinaryenIndex initial,
53305330
BinaryenIndex maximum,
53315331
const char* exportName,
5332-
const char** segments,
5333-
bool* segmentPassive,
5332+
const char** segmentNames,
5333+
const char** segmentDatas,
5334+
bool* segmentPassives,
53345335
BinaryenExpressionRef* segmentOffsets,
53355336
BinaryenIndex* segmentSizes,
53365337
BinaryenIndex numSegments,
@@ -5354,13 +5355,15 @@ void BinaryenSetMemory(BinaryenModuleRef module,
53545355
return true;
53555356
});
53565357
for (BinaryenIndex i = 0; i < numSegments; i++) {
5357-
auto curr = Builder::makeDataSegment(Name::fromInt(i),
5358+
auto explicitName = segmentNames && segmentNames[i];
5359+
auto name = explicitName ? Name(segmentNames[i]) : Name::fromInt(i);
5360+
auto curr = Builder::makeDataSegment(name,
53585361
memory->name,
5359-
segmentPassive[i],
5362+
segmentPassives[i],
53605363
(Expression*)segmentOffsets[i],
5361-
segments[i],
5364+
segmentDatas[i],
53625365
segmentSizes[i]);
5363-
curr->hasExplicitName = false;
5366+
curr->hasExplicitName = explicitName;
53645367
((Module*)module)->addDataSegment(std::move(curr));
53655368
}
53665369
((Module*)module)->removeMemories([&](Memory* curr) { return true; });
@@ -5373,10 +5376,11 @@ uint32_t BinaryenGetNumMemorySegments(BinaryenModuleRef module) {
53735376
return ((Module*)module)->dataSegments.size();
53745377
}
53755378
uint32_t BinaryenGetMemorySegmentByteOffset(BinaryenModuleRef module,
5376-
BinaryenIndex id) {
5379+
const char* segmentName) {
53775380
auto* wasm = (Module*)module;
5378-
if (wasm->dataSegments.size() <= id) {
5379-
Fatal() << "invalid segment id.";
5381+
const auto* segment = wasm->getDataSegmentOrNull(Name(segmentName));
5382+
if (segment == NULL) {
5383+
Fatal() << "invalid segment name.";
53805384
}
53815385

53825386
auto globalOffset = [&](const Expression* const& expr,
@@ -5388,8 +5392,6 @@ uint32_t BinaryenGetMemorySegmentByteOffset(BinaryenModuleRef module,
53885392
return false;
53895393
};
53905394

5391-
const auto& segment = wasm->dataSegments[id];
5392-
53935395
int64_t ret;
53945396
if (globalOffset(segment->offset, ret)) {
53955397
return ret;
@@ -5496,29 +5498,31 @@ bool BinaryenMemoryIs64(BinaryenModuleRef module, const char* name) {
54965498
return memory->is64();
54975499
}
54985500
size_t BinaryenGetMemorySegmentByteLength(BinaryenModuleRef module,
5499-
BinaryenIndex id) {
5500-
const auto& segments = ((Module*)module)->dataSegments;
5501-
if (segments.size() <= id) {
5502-
Fatal() << "invalid segment id.";
5501+
const char* segmentName) {
5502+
auto* wasm = (Module*)module;
5503+
const auto* segment = wasm->getDataSegmentOrNull(Name(segmentName));
5504+
if (segment == NULL) {
5505+
Fatal() << "invalid segment name.";
55035506
}
5504-
return segments[id]->data.size();
5507+
return segment->data.size();
55055508
}
55065509
bool BinaryenGetMemorySegmentPassive(BinaryenModuleRef module,
5507-
BinaryenIndex id) {
5508-
const auto& segments = ((Module*)module)->dataSegments;
5509-
if (segments.size() <= id) {
5510-
Fatal() << "invalid segment id.";
5510+
const char* segmentName) {
5511+
auto* wasm = (Module*)module;
5512+
const auto* segment = wasm->getDataSegmentOrNull(Name(segmentName));
5513+
if (segment == NULL) {
5514+
Fatal() << "invalid segment name.";
55115515
}
5512-
return segments[id]->isPassive;
5516+
return segment->isPassive;
55135517
}
55145518
void BinaryenCopyMemorySegmentData(BinaryenModuleRef module,
5515-
BinaryenIndex id,
5519+
const char* segmentName,
55165520
char* buffer) {
5517-
const auto& segments = ((Module*)module)->dataSegments;
5518-
if (segments.size() <= id) {
5519-
Fatal() << "invalid segment id.";
5521+
auto* wasm = (Module*)module;
5522+
const auto* segment = wasm->getDataSegmentOrNull(Name(segmentName));
5523+
if (segment == NULL) {
5524+
Fatal() << "invalid segment name.";
55205525
}
5521-
const auto& segment = segments[id];
55225526
std::copy(segment->data.cbegin(), segment->data.cend(), buffer);
55235527
}
55245528

src/binaryen-c.h

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2028,11 +2028,11 @@ BINARYEN_API bool BinaryenSIMDLoadStoreLaneIsStore(BinaryenExpressionRef expr);
20282028

20292029
// MemoryInit
20302030

2031-
// Gets the index of the segment being initialized by a `memory.init`
2031+
// Gets the name of the segment being initialized by a `memory.init`
20322032
// expression.
20332033
BINARYEN_API const char*
20342034
BinaryenMemoryInitGetSegment(BinaryenExpressionRef expr);
2035-
// Sets the index of the segment being initialized by a `memory.init`
2035+
// Sets the name of the segment being initialized by a `memory.init`
20362036
// expression.
20372037
BINARYEN_API void BinaryenMemoryInitSetSegment(BinaryenExpressionRef expr,
20382038
const char* segment);
@@ -2057,9 +2057,9 @@ BINARYEN_API void BinaryenMemoryInitSetSize(BinaryenExpressionRef expr,
20572057

20582058
// DataDrop
20592059

2060-
// Gets the index of the segment being dropped by a `data.drop` expression.
2060+
// Gets the name of the segment being dropped by a `data.drop` expression.
20612061
BINARYEN_API const char* BinaryenDataDropGetSegment(BinaryenExpressionRef expr);
2062-
// Sets the index of the segment being dropped by a `data.drop` expression.
2062+
// Sets the name of the segment being dropped by a `data.drop` expression.
20632063
BINARYEN_API void BinaryenDataDropSetSegment(BinaryenExpressionRef expr,
20642064
const char* segment);
20652065

@@ -2906,14 +2906,17 @@ BINARYEN_API BinaryenElementSegmentRef
29062906
BinaryenGetElementSegmentByIndex(BinaryenModuleRef module, BinaryenIndex index);
29072907

29082908
// This will create a memory, overwriting any existing memory
2909-
// Each memory has data in segments, a start offset in segmentOffsets, and a
2910-
// size in segmentSizes. exportName can be NULL
2909+
// Each memory segment has a name in segmentNames, data in segmentDatas,
2910+
// a start offset in segmentOffsets, a passive flag in segmentPassives
2911+
// and a size in segmentSizes. segmentNames and exportName can be NULL
2912+
// If segmentNames is null, BinaryenSetMemory creates names from indices
29112913
BINARYEN_API void BinaryenSetMemory(BinaryenModuleRef module,
29122914
BinaryenIndex initial,
29132915
BinaryenIndex maximum,
29142916
const char* exportName,
2915-
const char** segments,
2916-
bool* segmentPassive,
2917+
const char** segmentNames,
2918+
const char** segmentDatas,
2919+
bool* segmentPassives,
29172920
BinaryenExpressionRef* segmentOffsets,
29182921
BinaryenIndex* segmentSizes,
29192922
BinaryenIndex numSegments,
@@ -2940,14 +2943,14 @@ BINARYEN_API bool BinaryenMemoryIs64(BinaryenModuleRef module,
29402943
// Memory segments. Query utilities.
29412944

29422945
BINARYEN_API uint32_t BinaryenGetNumMemorySegments(BinaryenModuleRef module);
2943-
BINARYEN_API uint32_t
2944-
BinaryenGetMemorySegmentByteOffset(BinaryenModuleRef module, BinaryenIndex id);
2946+
BINARYEN_API uint32_t BinaryenGetMemorySegmentByteOffset(
2947+
BinaryenModuleRef module, const char* segmentName);
29452948
BINARYEN_API size_t BinaryenGetMemorySegmentByteLength(BinaryenModuleRef module,
2946-
BinaryenIndex id);
2949+
const char* segmentName);
29472950
BINARYEN_API bool BinaryenGetMemorySegmentPassive(BinaryenModuleRef module,
2948-
BinaryenIndex id);
2951+
const char* segmentName);
29492952
BINARYEN_API void BinaryenCopyMemorySegmentData(BinaryenModuleRef module,
2950-
BinaryenIndex id,
2953+
const char* segmentName,
29512954
char* buffer);
29522955

29532956
// Start function. One per module

src/js/binaryen.js-post.js

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2565,31 +2565,34 @@ function wrapModule(module, self = {}) {
25652565
// segments are assumed to be { passive: bool, offset: expression ref, data: array of 8-bit data }
25662566
return preserveStack(() => {
25672567
const segmentsLen = segments.length;
2568-
const segmentData = new Array(segmentsLen);
2569-
const segmentDataLen = new Array(segmentsLen);
2570-
const segmentPassive = new Array(segmentsLen);
2571-
const segmentOffset = new Array(segmentsLen);
2568+
const names = new Array(segmentsLen);
2569+
const datas = new Array(segmentsLen);
2570+
const lengths = new Array(segmentsLen);
2571+
const passives = new Array(segmentsLen);
2572+
const offsets = new Array(segmentsLen);
25722573
for (let i = 0; i < segmentsLen; i++) {
2573-
const { data, offset, passive } = segments[i];
2574-
segmentData[i] = _malloc(data.length);
2575-
HEAP8.set(data, segmentData[i]);
2576-
segmentDataLen[i] = data.length;
2577-
segmentPassive[i] = passive;
2578-
segmentOffset[i] = offset;
2574+
const { name, data, offset, passive } = segments[i];
2575+
names[i] = name ? strToStack(name) : null;
2576+
datas[i] = _malloc(data.length);
2577+
HEAP8.set(data, datas[i]);
2578+
lengths[i] = data.length;
2579+
passives[i] = passive;
2580+
offsets[i] = offset;
25792581
}
25802582
const ret = Module['_BinaryenSetMemory'](
25812583
module, initial, maximum, strToStack(exportName),
2582-
i32sToStack(segmentData),
2583-
i8sToStack(segmentPassive),
2584-
i32sToStack(segmentOffset),
2585-
i32sToStack(segmentDataLen),
2586-
segmentsLen,
2587-
shared,
2588-
memory64,
2589-
strToStack(internalName)
2590-
);
2584+
i32sToStack(names),
2585+
i32sToStack(datas),
2586+
i8sToStack(passives),
2587+
i32sToStack(offsets),
2588+
i32sToStack(lengths),
2589+
segmentsLen,
2590+
shared,
2591+
memory64,
2592+
strToStack(internalName)
2593+
);
25912594
for (let i = 0; i < segmentsLen; i++) {
2592-
_free(segmentData[i]);
2595+
_free(datas[i]);
25932596
}
25942597
return ret;
25952598
});
@@ -2613,18 +2616,18 @@ function wrapModule(module, self = {}) {
26132616
self['getNumMemorySegments'] = function() {
26142617
return Module['_BinaryenGetNumMemorySegments'](module);
26152618
};
2616-
self['getMemorySegmentInfoByIndex'] = function(id) {
2617-
const passive = Boolean(Module['_BinaryenGetMemorySegmentPassive'](module, id));
2619+
self['getMemorySegmentInfo'] = function(name) {
2620+
const passive = Boolean(Module['_BinaryenGetMemorySegmentPassive'](module, strToStack(name)));
26182621
let offset = null;
26192622
if (!passive) {
2620-
offset = Module['_BinaryenGetMemorySegmentByteOffset'](module, id);
2623+
offset = Module['_BinaryenGetMemorySegmentByteOffset'](module, strToStack(name));
26212624
}
26222625
return {
26232626
'offset': offset,
26242627
'data': (function(){
2625-
const size = Module['_BinaryenGetMemorySegmentByteLength'](module, id);
2628+
const size = Module['_BinaryenGetMemorySegmentByteLength'](module, strToStack(name));
26262629
const ptr = _malloc(size);
2627-
Module['_BinaryenCopyMemorySegmentData'](module, id, ptr);
2630+
Module['_BinaryenCopyMemorySegmentData'](module, strToStack(name), ptr);
26282631
const res = new Uint8Array(size);
26292632
res.set(HEAP8.subarray(ptr, ptr + size));
26302633
_free(ptr);

test/binaryen.js/kitchen-sink.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -196,11 +196,13 @@ function test_core() {
196196
// Memory
197197
module.setMemory(1, 256, "mem", [
198198
{
199+
name: "x0",
199200
passive: false,
200201
offset: module.i32.const(10),
201202
data: "hello, world".split('').map(function(x) { return x.charCodeAt(0) })
202203
},
203204
{
205+
name: "y1",
204206
passive: true,
205207
offset: null,
206208
data: "I am passive".split('').map(function(x) { return x.charCodeAt(0) })
@@ -555,8 +557,8 @@ function test_core() {
555557
module.i8x16.shuffle(module.v128.const(v128_bytes), module.v128.const(v128_bytes), v128_bytes),
556558
module.v128.bitselect(module.v128.const(v128_bytes), module.v128.const(v128_bytes), module.v128.const(v128_bytes)),
557559
// Bulk memory
558-
module.memory.init("0", makeInt32(1024), makeInt32(0), makeInt32(12)),
559-
module.data.drop("0"),
560+
module.memory.init("x0", makeInt32(1024), makeInt32(0), makeInt32(12)),
561+
module.data.drop("x0"),
560562
module.memory.copy(makeInt32(2048), makeInt32(1024), makeInt32(12)),
561563
module.memory.fill(makeInt32(0), makeInt32(42), makeInt32(1024)),
562564
// All the rest
@@ -1090,6 +1092,7 @@ function test_for_each() {
10901092
}
10911093

10921094
var expected_offsets = [10, 125, null];
1095+
var expected_names = ["x0", "y1", "z2"];
10931096
var expected_data = ["hello, world", "segment data 2", "hello, passive"];
10941097
var expected_passive = [false, false, true];
10951098

@@ -1105,23 +1108,26 @@ function test_for_each() {
11051108

11061109
module.setMemory(1, 256, "mem", [
11071110
{
1111+
name: expected_names[0],
11081112
passive: expected_passive[0],
11091113
offset: module.i32.const(expected_offsets[0]),
11101114
data: expected_data[0].split('').map(function(x) { return x.charCodeAt(0) })
11111115
},
11121116
{
1117+
name: expected_names[1],
11131118
passive: expected_passive[1],
11141119
offset: module.global.get("a-global"),
11151120
data: expected_data[1].split('').map(function(x) { return x.charCodeAt(0) })
11161121
},
11171122
{
1123+
name: expected_names[2],
11181124
passive: expected_passive[2],
11191125
offset: expected_offsets[2],
11201126
data: expected_data[2].split('').map(function(x) { return x.charCodeAt(0) })
11211127
}
11221128
], false);
11231129
for (i = 0; i < module.getNumMemorySegments(); i++) {
1124-
var segment = module.getMemorySegmentInfoByIndex(i);
1130+
var segment = module.getMemorySegmentInfo(expected_names[i]);
11251131
assert(expected_offsets[i] === segment.offset);
11261132
var data8 = new Uint8Array(segment.data);
11271133
var str = String.fromCharCode.apply(null, data8);

test/binaryen.js/kitchen-sink.js.txt

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,8 @@ getExpressionInfo(tuple[3])={"id":14,"type":5,"value":3.7}
140140
(import "module" "base" (tag $a-tag-imp (param i32)))
141141
(global $a-global i32 (i32.const 1))
142142
(memory $0 1 256 shared)
143-
(data $0 (i32.const 10) "hello, world")
144-
(data $1 "I am passive")
143+
(data $x0 (i32.const 10) "hello, world")
144+
(data $y1 "I am passive")
145145
(table $t0 1 funcref)
146146
(elem $e0 (i32.const 0) $"kitchen()sinker")
147147
(tag $a-tag (param i32))
@@ -1914,12 +1914,12 @@ getExpressionInfo(tuple[3])={"id":14,"type":5,"value":3.7}
19141914
(v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)
19151915
)
19161916
)
1917-
(memory.init $0
1917+
(memory.init $x0
19181918
(i32.const 1024)
19191919
(i32.const 0)
19201920
(i32.const 12)
19211921
)
1922-
(data.drop $0)
1922+
(data.drop $x0)
19231923
(memory.copy
19241924
(i32.const 2048)
19251925
(i32.const 1024)
@@ -2250,8 +2250,8 @@ getExpressionInfo(tuple[3])={"id":14,"type":5,"value":3.7}
22502250
(import "module" "base" (tag $a-tag-imp (param i32)))
22512251
(global $a-global i32 (i32.const 1))
22522252
(memory $0 1 256 shared)
2253-
(data $0 (i32.const 10) "hello, world")
2254-
(data $1 "I am passive")
2253+
(data $x0 (i32.const 10) "hello, world")
2254+
(data $y1 "I am passive")
22552255
(table $t0 1 funcref)
22562256
(elem $e0 (i32.const 0) $"kitchen()sinker")
22572257
(tag $a-tag (param i32))
@@ -4024,12 +4024,12 @@ getExpressionInfo(tuple[3])={"id":14,"type":5,"value":3.7}
40244024
(v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)
40254025
)
40264026
)
4027-
(memory.init $0
4027+
(memory.init $x0
40284028
(i32.const 1024)
40294029
(i32.const 0)
40304030
(i32.const 12)
40314031
)
4032-
(data.drop $0)
4032+
(data.drop $x0)
40334033
(memory.copy
40344034
(i32.const 2048)
40354035
(i32.const 1024)
@@ -4922,9 +4922,9 @@ sizeof Literal: 24
49224922
(global $a-global2 i32 (i32.const 2))
49234923
(global $a-global3 i32 (i32.const 3))
49244924
(memory $0 1 256)
4925-
(data $0 (i32.const 10) "hello, world")
4926-
(data $1 (global.get $a-global) "segment data 2")
4927-
(data $2 "hello, passive")
4925+
(data $x0 (i32.const 10) "hello, world")
4926+
(data $y1 (global.get $a-global) "segment data 2")
4927+
(data $z2 "hello, passive")
49284928
(table $t0 1 funcref)
49294929
(elem $e0 (i32.const 0) $fn0 $fn1 $fn2)
49304930
(export "export0" (func $fn0))

test/binaryen.js/reloc.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ var module = new binaryen.Module();
55
module.addGlobalImport("memory_base", "env", "memory_base", binaryen.i32, false);
66
module.setMemory(1, -1, null, [
77
{
8+
name: "x0",
89
offset: module.global.get("memory_base", binaryen.i32),
910
data: "data data".split('').map(function(x) { return x.charCodeAt(0) })
1011
}

test/binaryen.js/reloc.js.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
(import "env" "memory_base" (global $memory_base i32))
44
(import "env" "table_base" (global $table_base i32))
55
(memory $0 1)
6-
(data $0 (global.get $memory_base) "data data")
6+
(data $x0 (global.get $memory_base) "data data")
77
(table $0 1 funcref)
88
(elem $0 (global.get $table_base) $func $func)
99
(func $func

0 commit comments

Comments
 (0)