Skip to content

Commit 67019f9

Browse files
authored
Add missing methods for globals to binaryen.js (#2099)
- Print `globals` array in the tracing mode like other arrays (`functions`, `exports`, `imports`, ...) - Add accessor functions for globals
1 parent a1ff274 commit 67019f9

11 files changed

Lines changed: 151 additions & 19 deletions

build-js.sh

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -795,6 +795,12 @@ export_function "_BinaryenFunctionOptimize"
795795
export_function "_BinaryenFunctionRunPasses"
796796
export_function "_BinaryenFunctionSetDebugLocation"
797797

798+
# 'Global' operations
799+
export_function "_BinaryenGlobalGetName"
800+
export_function "_BinaryenGlobalGetType"
801+
export_function "_BinaryenGlobalIsMutable"
802+
export_function "_BinaryenGlobalGetInitExpr"
803+
798804
# 'Import' operations
799805
export_function "_BinaryenGlobalImportGetModule"
800806
export_function "_BinaryenGlobalImportGetBase"

src/binaryen-c.cpp

Lines changed: 47 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2699,19 +2699,24 @@ void BinaryenRemoveFunction(BinaryenModuleRef module, const char* name) {
26992699
wasm->removeFunction(name);
27002700
}
27012701

2702+
// Globals
2703+
27022704
BinaryenGlobalRef BinaryenAddGlobal(BinaryenModuleRef module,
27032705
const char* name,
27042706
BinaryenType type,
27052707
int8_t mutable_,
27062708
BinaryenExpressionRef init) {
2709+
auto* wasm = (Module*)module;
2710+
auto* ret = new Global();
2711+
27072712
if (tracing) {
2708-
std::cout << " BinaryenAddGlobal(the_module, \"" << name << "\", " << type
2709-
<< ", " << int(mutable_) << ", expressions[" << expressions[init]
2710-
<< "]);\n";
2713+
auto id = globals.size();
2714+
globals[ret] = id;
2715+
std::cout << " globals[" << id << "] = BinaryenAddGlobal(the_module, \""
2716+
<< name << "\", " << type << ", " << int(mutable_)
2717+
<< ", expressions[" << expressions[init] << "]);\n";
27112718
}
27122719

2713-
auto* wasm = (Module*)module;
2714-
auto* ret = new Global();
27152720
ret->name = name;
27162721
ret->type = Type(type);
27172722
ret->mutable_ = !!mutable_;
@@ -3517,6 +3522,43 @@ void BinaryenFunctionSetDebugLocation(BinaryenFunctionRef func,
35173522
fn->debugLocations[ex] = loc;
35183523
}
35193524

3525+
//
3526+
// =========== Global operations ===========
3527+
//
3528+
3529+
const char* BinaryenGlobalGetName(BinaryenGlobalRef global) {
3530+
if (tracing) {
3531+
std::cout << " BinaryenGlobalGetName(globals[" << globals[global]
3532+
<< "]);\n";
3533+
}
3534+
3535+
return ((Global*)global)->name.c_str();
3536+
}
3537+
BinaryenType BinaryenGlobalGetType(BinaryenGlobalRef global) {
3538+
if (tracing) {
3539+
std::cout << " BinaryenGlobalGetType(globals[" << globals[global]
3540+
<< "]);\n";
3541+
}
3542+
3543+
return ((Global*)global)->type;
3544+
}
3545+
int BinaryenGlobalIsMutable(BinaryenGlobalRef global) {
3546+
if (tracing) {
3547+
std::cout << " BinaryenGlobalIsMutable(globals[" << globals[global]
3548+
<< "]);\n";
3549+
}
3550+
3551+
return ((Global*)global)->mutable_;
3552+
}
3553+
BinaryenExpressionRef BinaryenGlobalGetInitExpr(BinaryenGlobalRef global) {
3554+
if (tracing) {
3555+
std::cout << " BinaryenGlobalGetInitExpr(globals[" << globals[global]
3556+
<< "]);\n";
3557+
}
3558+
3559+
return ((Global*)global)->init;
3560+
}
3561+
35203562
//
35213563
// =========== Import operations ===========
35223564
//

src/binaryen-c.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1104,6 +1104,21 @@ void BinaryenFunctionSetDebugLocation(BinaryenFunctionRef func,
11041104
BinaryenIndex lineNumber,
11051105
BinaryenIndex columnNumber);
11061106

1107+
//
1108+
// ========== Global Operations ==========
1109+
//
1110+
1111+
// Gets the name of the specified `Global`.
1112+
const char* BinaryenGlobalGetName(BinaryenGlobalRef global);
1113+
// Gets the name of the `GlobalType` associated with the specified `Global`. May
1114+
// be `NULL` if the signature is implicit.
1115+
BinaryenType BinaryenGlobalGetType(BinaryenGlobalRef global);
1116+
// Returns true if the specified `Global` is mutable.
1117+
int BinaryenGlobalIsMutable(BinaryenGlobalRef global);
1118+
// Gets the initialization expression of the specified `Global`.
1119+
BinaryenExpressionRef BinaryenGlobalGetInitExpr(BinaryenGlobalRef global);
1120+
1121+
//
11071122
//
11081123
// ========== Import Operations ==========
11091124
//

src/js/binaryen.js-post.js

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2327,12 +2327,14 @@ Module['getFunctionInfo'] = function(func) {
23272327
};
23282328

23292329
// Obtains information about a 'Global'
2330-
Module['getGlobalInfo'] = function(func) {
2330+
Module['getGlobalInfo'] = function(global) {
23312331
return {
2332-
'name': UTF8ToString(Module['_BinaryenGlobalGetName'](func)),
2333-
'module': UTF8ToString(Module['_BinaryenGlobalImportGetModule'](func)),
2334-
'base': UTF8ToString(Module['_BinaryenGlobalImportGetBase'](func)),
2335-
'type': UTF8ToString(Module['_BinaryenGlobalGetType'](func))
2332+
'name': UTF8ToString(Module['_BinaryenGlobalGetName'](global)),
2333+
'module': UTF8ToString(Module['_BinaryenGlobalImportGetModule'](global)),
2334+
'base': UTF8ToString(Module['_BinaryenGlobalImportGetBase'](global)),
2335+
'type': Module['_BinaryenGlobalGetType'](global),
2336+
'mutable': Boolean(Module['_BinaryenGlobalIsMutable'](global)),
2337+
'init': Module['_BinaryenGlobalGetInitExpr'](global)
23362338
};
23372339
};
23382340

test/binaryen.js/functions.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,6 @@ console.log(Binaryen.emitText(funcInfo.body));
3333

3434
module.removeFunction("a-function");
3535

36-
module.addGlobal("a-global", Binaryen.i32, false, funcInfo.body);
37-
3836
module.validate();
3937

4038
console.log(module.emitText());

test/binaryen.js/functions.js.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,5 @@ getExpressionInfo(body)={"id":14,"value":3}
66

77
(module
88
(type $i (func (result i32)))
9-
(global $a-global i32 (i32.const 3))
109
)
1110

test/binaryen.js/global.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
function cleanInfo(info) {
2+
var ret = {};
3+
for (var x in info) {
4+
if (x !== 'name' && x !== 'body' && x !== 'type' && x !== 'init') {
5+
ret[x] = info[x];
6+
}
7+
}
8+
return ret;
9+
}
10+
11+
var module = new Binaryen.Module();
12+
13+
var initExpr = module.i32.const(1);
14+
var global = module.addGlobal("a-global", Binaryen.i32, false, initExpr);
15+
16+
var globalInfo = Binaryen.getGlobalInfo(global);
17+
console.log("getGlobalInfo=" + JSON.stringify(cleanInfo(globalInfo)));
18+
19+
var initExpInfo = Binaryen.getExpressionInfo(globalInfo.init);
20+
console.log("getExpressionInfo(init)=" + JSON.stringify(cleanInfo(initExpInfo)));
21+
console.log(Binaryen.emitText(globalInfo.init));
22+
23+
module.addGlobalExport("a-global", "a-global-exp");
24+
module.addGlobalImport("a-global-imp", "module", "base", Binaryen.i32);
25+
26+
module.validate();
27+
console.log(module.emitText());
28+
29+
module.removeGlobal("a-global");
30+
module.removeExport("a-global-exp");
31+
32+
module.validate();
33+
console.log(module.emitText());

test/binaryen.js/global.js.txt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
getGlobalInfo={"module":"","base":"","mutable":false}
2+
getExpressionInfo(init)={"id":14,"value":1}
3+
(i32.const 1)
4+
5+
(module
6+
(import "module" "base" (global $a-global-imp i32))
7+
(global $a-global i32 (i32.const 1))
8+
(export "a-global-exp" (global $a-global))
9+
)
10+
11+
(module
12+
(import "module" "base" (global $a-global-imp i32))
13+
)
14+

test/binaryen.js/kitchen-sink.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,14 +407,20 @@ function test_core() {
407407
// Create the function
408408
var sinker = module.addFunction("kitchen()sinker", iiIfF, [ Binaryen.i32 ], body);
409409

410+
// Create a global
411+
var initExpr = module.i32.const(1);
412+
var global = module.addGlobal("a-global", Binaryen.i32, false, initExpr)
413+
410414
// Imports
411415

412416
var fiF = module.addFunctionType("fiF", Binaryen.f32, [ Binaryen.i32, Binaryen.f64 ]);
413417
module.addFunctionImport("an-imported", "module", "base", fiF);
418+
module.addGlobalImport("a-global-imp", "module", "base", Binaryen.i32);
414419

415420
// Exports
416421

417422
module.addFunctionExport("kitchen()sinker", "kitchen_sinker");
423+
module.addGlobalExport("a-global", "a-global-exp");
418424

419425
// Function table. One per module
420426

@@ -666,6 +672,8 @@ function test_binaries() {
666672
y = module.getLocal(1, Binaryen.i32);
667673
var add = module.i32.add(x, y);
668674
var adder = module.addFunction("adder", iii, [], add);
675+
var initExpr = module.i32.const(3);
676+
var global = module.addGlobal("a-global", Binaryen.i32, false, initExpr)
669677
Binaryen.setDebugInfo(true); // include names section
670678
buffer = module.emitBinary();
671679
Binaryen.setDebugInfo(false);
@@ -736,6 +744,8 @@ function test_parsing() {
736744
y = module.getLocal(1, Binaryen.i32);
737745
var add = module.i32.add(x, y);
738746
var adder = module.addFunction("adder", iii, [], add);
747+
var initExpr = module.i32.const(3);
748+
var global = module.addGlobal("a-global", Binaryen.i32, false, initExpr)
739749
text = module.emitText();
740750
module.dispose();
741751
module = null;

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

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,16 @@ getExpressionInfo(f64.const)={"id":14,"type":4,"value":9.5}
5757
(type $fiF (func (param i32 f64) (result f32)))
5858
(type $v (func))
5959
(type $3 (func))
60+
(import "module" "base" (global $a-global-imp i32))
6061
(import "module" "base" (func $an-imported (param i32 f64) (result f32)))
6162
(memory $0 1 256)
6263
(data (i32.const 10) "hello, world")
6364
(data passive "I am passive")
6465
(table $0 1 funcref)
6566
(elem (i32.const 0) "$kitchen()sinker")
67+
(global $a-global i32 (i32.const 1))
6668
(export "kitchen_sinker" (func "$kitchen()sinker"))
69+
(export "a-global-exp" (global $a-global))
6770
(export "mem" (memory $0))
6871
(start $starter)
6972
(func "$kitchen()sinker" (; 1 ;) (type $iiIfF) (param $0 i32) (param $1 i64) (param $2 f32) (param $3 f64) (result i32)
@@ -1886,6 +1889,7 @@ optimized:
18861889
module loaded from binary form:
18871890
(module
18881891
(type $0 (func (param i32 i32) (result i32)))
1892+
(global $global$0 i32 (i32.const 3))
18891893
(func $adder (; 0 ;) (type $0) (param $0 i32) (param $1 i32) (result i32)
18901894
(i32.add
18911895
(local.get $0)
@@ -3327,12 +3331,16 @@ getExpressionInfo(f64.const)={"id":14,"type":4,"value":9.5}
33273331
BinaryenType varTypes[] = { 1 };
33283332
functions[0] = BinaryenAddFunction(the_module, "kitchen()sinker", functionTypes[0], varTypes, 1, expressions[655]);
33293333
}
3334+
expressions[656] = BinaryenConst(the_module, BinaryenLiteralInt32(1));
3335+
globals[0] = BinaryenAddGlobal(the_module, "a-global", 1, 0, expressions[656]);
33303336
{
33313337
BinaryenType paramTypes[] = { 1, 4 };
33323338
functionTypes[1] = BinaryenAddFunctionType(the_module, "fiF", 3, paramTypes, 2);
33333339
}
33343340
BinaryenAddFunctionImport(the_module, "an-imported", "module", "base", functionTypes[1]);
3341+
BinaryenAddGlobalImport(the_module, "a-global-imp", "module", "base", 1);
33353342
exports[0] = BinaryenAddFunctionExport(the_module, "kitchen()sinker", "kitchen_sinker");
3343+
exports[1] = BinaryenAddGlobalExport(the_module, "a-global", "a-global-exp");
33363344
BinaryenFunctionGetName(functions[0]);
33373345
BinaryenFunctionImportGetModule(functions[0]);
33383346
BinaryenFunctionImportGetBase(functions[0]);
@@ -3350,24 +3358,24 @@ getExpressionInfo(f64.const)={"id":14,"type":4,"value":9.5}
33503358
const char* funcNames[] = { "kitchen()sinker" };
33513359
BinaryenSetFunctionTable(the_module, 1, 4294967295, funcNames, 1);
33523360
}
3353-
expressions[656] = BinaryenConst(the_module, BinaryenLiteralInt32(10));
3361+
expressions[657] = BinaryenConst(the_module, BinaryenLiteralInt32(10));
33543362
{
33553363
const char segment0[] = { 104, 101, 108, 108, 111, 44, 32, 119, 111, 114, 108, 100 };
33563364
const char segment1[] = { 73, 32, 97, 109, 32, 112, 97, 115, 115, 105, 118, 101 };
33573365
const char* segments[] = { segment0, segment1 };
33583366
int8_t segmentPassive[] = { 0, 1 };
3359-
BinaryenExpressionRef segmentOffsets[] = { expressions[656], expressions[0] };
3367+
BinaryenExpressionRef segmentOffsets[] = { expressions[657], expressions[0] };
33603368
BinaryenIndex segmentSizes[] = { 12, 12 };
33613369
BinaryenSetMemory(the_module, 1, 256, "mem", segments, segmentPassive, segmentOffsets, segmentSizes, 2, 0);
33623370
}
33633371
{
33643372
BinaryenType paramTypes[] = { 0 };
33653373
functionTypes[2] = BinaryenAddFunctionType(the_module, "v", 0, paramTypes, 0);
33663374
}
3367-
expressions[657] = BinaryenNop(the_module);
3375+
expressions[658] = BinaryenNop(the_module);
33683376
{
33693377
BinaryenType varTypes[] = { 0 };
3370-
functions[1] = BinaryenAddFunction(the_module, "starter", functionTypes[2], varTypes, 0, expressions[657]);
3378+
functions[1] = BinaryenAddFunction(the_module, "starter", functionTypes[2], varTypes, 0, expressions[658]);
33713379
}
33723380
BinaryenSetStart(the_module, functions[1]);
33733381
{
@@ -3382,13 +3390,16 @@ getExpressionInfo(f64.const)={"id":14,"type":4,"value":9.5}
33823390
(type $fiF (func (param i32 f64) (result f32)))
33833391
(type $v (func))
33843392
(type $3 (func))
3393+
(import "module" "base" (global $a-global-imp i32))
33853394
(import "module" "base" (func $an-imported (param i32 f64) (result f32)))
33863395
(memory $0 1 256)
33873396
(data (i32.const 10) "hello, world")
33883397
(data passive "I am passive")
33893398
(table $0 1 funcref)
33903399
(elem (i32.const 0) "$kitchen()sinker")
3400+
(global $a-global i32 (i32.const 1))
33913401
(export "kitchen_sinker" (func "$kitchen()sinker"))
3402+
(export "a-global-exp" (global $a-global))
33923403
(export "mem" (memory $0))
33933404
(start $starter)
33943405
(func "$kitchen()sinker" (; 1 ;) (type $iiIfF) (param $0 i32) (param $1 i64) (param $2 f32) (param $3 f64) (result i32)
@@ -5691,6 +5702,7 @@ optimized:
56915702
test_parsing text:
56925703
(module
56935704
(type $iii (func (param i32 i32) (result i32)))
5705+
(global $a-global i32 (i32.const 3))
56945706
(func $adder (; 0 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32)
56955707
(i32.add
56965708
(local.get $0)
@@ -5702,6 +5714,7 @@ test_parsing text:
57025714
module loaded from text form:
57035715
(module
57045716
(type $iii (func (param i32 i32) (result i32)))
5717+
(global $a-global i32 (i32.const 3))
57055718
(func $ADD_ER (; 0 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32)
57065719
(i32.add
57075720
(local.get $0)

0 commit comments

Comments
 (0)