Closed3

binaryen C API でちょろっとだけ遊ぶ

tanishikingtanishiking

開発環境

$ brew install binaryen

$ wasm-as --version
wasm-as version 116

$ ls /opt/homebrew/include/binaryen-c.h
/opt/homebrew/include/binaryen-c.h@

$ ls /opt/homebrew/lib/libbinaryen.dylib
/opt/homebrew/lib/libbinaryen.dylib@

$ gcc -I/opt/homebrew/include -L/opt/homebrew/lib -lbinaryen foo.c

API と kitchen sink

https://raw.githubusercontent.com/WebAssembly/binaryen/main/src/binaryen-c.h

https://raw.githubusercontent.com/WebAssembly/binaryen/main/test/example/c-api-kitchen-sink.c

tanishikingtanishiking

incr

constant and literal

#include <binaryen-c.h>

int main() {
  BinaryenModuleRef module = BinaryenModuleCreate();

  BinaryenType ii[1] = {BinaryenTypeInt32()};
  BinaryenType params = BinaryenTypeCreate(ii, 1);
  BinaryenType results = BinaryenTypeInt32();

  BinaryenExpressionRef x = BinaryenLocalGet(module, 0, BinaryenTypeInt32());
  BinaryenExpressionRef one = BinaryenConst(module, BinaryenLiteralInt32(1));
  BinaryenExpressionRef add = BinaryenBinary(module, BinaryenAddInt32(), x, one);

  BinaryenFunctionRef adder =
    BinaryenAddFunction(module, "adder", params, results, NULL, 0, add);

  BinaryenModulePrint(module);
  BinaryenModuleDispose(module);
  return 0;
}
$ gcc -I/opt/homebrew/include -L/opt/homebrew/lib -lbinaryen incr.c
$ ./a.out
(module
 (type $0 (func (param i32) (result i32)))
 (func $adder (param $0 i32) (result i32)
  (i32.add
   (local.get $0)
   (i32.const 1)
  )
 )
)
tanishikingtanishiking

struct

// struct.c
#include <binaryen-c.h>

BinaryenExpressionRef makeInt32(BinaryenModuleRef module, int x) {
  return BinaryenConst(module, BinaryenLiteralInt32(x));
}

int main() {
  BinaryenModuleRef module = BinaryenModuleCreate();

  TypeBuilderRef builder = TypeBuilderCreate(1);
  BinaryenType fieldTypes[] = {
    BinaryenTypeInt32(), BinaryenTypeInt32()}; // must repeat existing fields
  BinaryenPackedType fieldPackedTypes[] = {BinaryenPackedTypeInt8(), BinaryenPackedTypeInt8()};
  bool fieldMutables[] = {true, true};
  TypeBuilderSetStructType(builder,
                           0,
                           fieldTypes,
                           fieldPackedTypes,
                           fieldMutables,
                           2);
  // TypeBuilderSetOpen(builder, tempSubStructIndex);
  // TypeBuilderSetSubType(builder, tempSubStructIndex, tempStructHeapType);

  // Build the type hierarchy and dispose the builder
  BinaryenHeapType heapTypes[1];
  BinaryenIndex errorIndex;
  TypeBuilderErrorReason errorReason;
  bool didBuildAndDispose = TypeBuilderBuildAndDispose(
    builder, heapTypes, &errorIndex, &errorReason);
  // assert(didBuildAndDispose);

  BinaryenHeapType str = heapTypes[0];
  BinaryenType i32Struct = BinaryenTypeFromHeapType(heapTypes[0], true);

  BinaryenAddGlobal(
    module,
    "i32Struct-global",
    i32Struct,
    true,
    BinaryenStructNew(module, (BinaryenExpressionRef[]){makeInt32(module, 0), makeInt32(module, 1)}, 2, BinaryenTypeGetHeapType(i32Struct))
  );
  BinaryenModulePrint(module);
  BinaryenModuleDispose(module);

  return 0;
}
$ gcc -I/opt/homebrew/include -L/opt/homebrew/lib -lbinaryen struct.c
$ ./a.out
didBuildAndDispose: 1
(module
 (type $0 (struct (field (mut i8)) (field (mut i8))))
 (global $i32Struct-global (mut (ref null $0)) (struct.new $0
  (i32.const 0)
  (i32.const 1)
 ))
)

packed type を {} にすると、unexpected packed type って言われた。BinaryenPackedTypeNotPacked() とかにすると mut i32 のままでいてくれるのかな?

  BinaryenPackedType fieldPackedTypes[] = {
    BinaryenPackedTypeNotPacked(),
    BinaryenPackedTypeNotPacked()
  };

こうすると、こうじゃ

(module
 (type $0 (struct (field (mut i32)) (field (mut i32))))
 (global $i32Struct-global (mut (ref null $0)) (struct.new $0
  (i32.const 0)
  (i32.const 1)
 ))
)
このスクラップは2024/01/29にクローズされました