<|start_filename|>src/binaryen_stubs_memory.c<|end_filename|>
#define CAML_NAME_SPACE
#include <caml/mlvalues.h>
#include <caml/fail.h>
#include <caml/memory.h>

#include "binaryen-c.h"
#include "ocaml_helpers.h"


CAMLprim value
caml_binaryen_set_memory(value _module, value _initial, value _maximum, value _exportName, value _segments, value _segmentPassive, value _segmentOffsets, value _segmentSizes, value _shared) {
  CAMLparam5(_module, _initial, _maximum, _exportName, _segments);
  CAMLxparam4(_segmentPassive, _segmentOffsets, _segmentSizes, _shared);
  BinaryenModuleRef module = BinaryenModuleRef_val(_module);
  BinaryenIndex initial = Int_val(_initial);
  BinaryenIndex maximum = Int_val(_maximum);
  char* exportName = Safe_String_val(_exportName);
  _segments = array_of_list(_segments);
  int segmentsLen = array_length(_segments);
  const char* segments[segmentsLen];
  for (int i = 0; i < segmentsLen; i++) {
    segments[i] = Safe_String_val(Field(_segments, i));
  }
  _segmentPassive = array_of_list(_segmentPassive);
  int segmentPassiveLen = array_length(_segmentPassive);
  bool segmentPassive[segmentPassiveLen];
  for (int i = 0; i < segmentPassiveLen; i++) {
    segmentPassive[i] = Bool_val(Field(_segmentPassive, i));
  }
  _segmentOffsets = array_of_list(_segmentOffsets);
  int segmentOffsetsLen = array_length(_segmentOffsets);
  BinaryenExpressionRef segmentOffsets[segmentOffsetsLen];
  for (int i = 0; i < segmentOffsetsLen; i++) {
    segmentOffsets[i] = BinaryenExpressionRef_val(Field(_segmentOffsets, i));
  }
  _segmentSizes = array_of_list(_segmentSizes);
  int segmentSizesLen = array_length(_segmentSizes);
  BinaryenIndex segmentSizes[segmentSizesLen];
  for (int i = 0; i < segmentSizesLen; i++) {
    segmentSizes[i] = Int_val(Field(_segmentSizes, i));
  }
  uint8_t shared = Bool_val(_shared);
  BinaryenSetMemory(module, initial, maximum, exportName, segments, segmentPassive, segmentOffsets, segmentSizes, segmentsLen, shared);
  CAMLreturn(Val_unit);
}
CAMLprim value
caml_binaryen_set_memory__bytecode(value * argv) {
  return caml_binaryen_set_memory(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8]);
}


<|start_filename|>src/binaryen_stubs_globals.c<|end_filename|>
#define CAML_NAME_SPACE
#include <caml/mlvalues.h>
#include <caml/fail.h>
#include <caml/memory.h>
#include <caml/alloc.h>

#include "binaryen-c.h"
#include "ocaml_helpers.h"


/* Allocating an OCaml custom block to hold the given BinaryenGlobalRef */
static value alloc_BinaryenGlobalRef(BinaryenGlobalRef exp)
{
  value v = caml_alloc_custom(&binaryen_ops, sizeof(BinaryenGlobalRef), 0, 1);
  BinaryenGlobalRef_val(v) = exp;
  return v;
}

/* Allocating an OCaml custom block to hold the given BinaryenType */
static value alloc_BinaryenType(BinaryenType typ)
{
  value v = caml_alloc_custom(&binaryen_ops, sizeof(BinaryenType), 0, 1);
  BinaryenType_val(v) = typ;
  return v;
}

/* Allocating an OCaml custom block to hold the given BinaryenExpressionRef */
static value alloc_BinaryenExpressionRef(BinaryenExpressionRef exp)
{
  value v = caml_alloc_custom(&binaryen_ops, sizeof(BinaryenExpressionRef), 0, 1);
  BinaryenExpressionRef_val(v) = exp;
  return v;
}

CAMLprim value
caml_binaryen_add_global(value _module, value _name, value _ty, value _mutable_, value _init) {
  CAMLparam5(_module, _name, _ty, _mutable_, _init);
  BinaryenModuleRef module = BinaryenModuleRef_val(_module);
  char* name = Safe_String_val(_name);
  BinaryenType ty = BinaryenType_val(_ty);
  int8_t mutable_ = Bool_val(_mutable_);
  BinaryenExpressionRef init = BinaryenExpressionRef_val(_init);
  BinaryenGlobalRef glob = BinaryenAddGlobal(module, name, ty, mutable_, init);
  CAMLreturn(alloc_BinaryenGlobalRef(glob));
}

CAMLprim value
caml_binaryen_get_global(value _module, value _name) {
  CAMLparam2(_module, _name);
  BinaryenModuleRef module = BinaryenModuleRef_val(_module);
  char* name = Safe_String_val(_name);
  BinaryenGlobalRef glob = BinaryenGetGlobal(module, name);
  CAMLreturn(alloc_BinaryenGlobalRef(glob));
}

CAMLprim value
caml_binaryen_remove_global(value _module, value _name) {
  CAMLparam2(_module, _name);
  BinaryenModuleRef module = BinaryenModuleRef_val(_module);
  char* name = Safe_String_val(_name);
  BinaryenRemoveGlobal(module, name);
  CAMLreturn(Val_unit);
}

CAMLprim value
caml_binaryen_get_num_globals(value _module) {
  CAMLparam1(_module);
  BinaryenModuleRef module = BinaryenModuleRef_val(_module);
  CAMLreturn(Val_int(BinaryenGetNumGlobals(module)));
}

CAMLprim value
caml_binaryen_get_global_by_index(value _module, value _index) {
  CAMLparam2(_module, _index);
  BinaryenModuleRef module = BinaryenModuleRef_val(_module);
  BinaryenIndex index = Int_val(_index);
  CAMLreturn(alloc_BinaryenGlobalRef(BinaryenGetGlobalByIndex(module, index)));
}

CAMLprim value
caml_binaryen_global_get_name(value _global) {
  CAMLparam1(_global);
  BinaryenGlobalRef global = BinaryenGlobalRef_val(_global);
  const char* name = BinaryenGlobalGetName(global);
  CAMLreturn(caml_copy_string(name));
}

CAMLprim value
caml_binaryen_global_get_type(value _global) {
  CAMLparam1(_global);
  BinaryenGlobalRef global = BinaryenGlobalRef_val(_global);
  BinaryenType ty = BinaryenGlobalGetType(global);
  CAMLreturn(alloc_BinaryenType(ty));
}

CAMLprim value
caml_binaryen_global_is_mutable(value _global) {
  CAMLparam1(_global);
  BinaryenGlobalRef global = BinaryenGlobalRef_val(_global);
  CAMLreturn(Val_bool(BinaryenGlobalIsMutable(global)));
}

CAMLprim value
caml_binaryen_global_get_init_expr(value _global) {
  CAMLparam1(_global);
  BinaryenGlobalRef global = BinaryenGlobalRef_val(_global);
  BinaryenExpressionRef exp = BinaryenGlobalGetInitExpr(global);
  CAMLreturn(alloc_BinaryenExpressionRef(exp));
}


<|start_filename|>src/binaryen_stubs_settings.c<|end_filename|>
#define CAML_NAME_SPACE
#include <caml/mlvalues.h>
#include <caml/alloc.h>
#include <caml/fail.h>
#include <caml/memory.h>

#include "binaryen-c.h"
#include "ocaml_helpers.h"

CAMLprim value
caml_binaryen_get_optimize_level(value unit) {
  CAMLparam1(unit);
  int res = BinaryenGetOptimizeLevel();
  CAMLreturn(Val_int(res));
}

CAMLprim value
caml_binaryen_set_optimize_level(value _level) {
  CAMLparam1(_level);
  int level = Int_val(_level);
  BinaryenSetOptimizeLevel(level);
  CAMLreturn(Val_unit);
}

CAMLprim value
caml_binaryen_get_shrink_level(value unit) {
  CAMLparam1(unit);
  int res = BinaryenGetShrinkLevel();
  CAMLreturn(Val_int(res));
}

CAMLprim value
caml_binaryen_set_shrink_level(value _level) {
  CAMLparam1(_level);
  int level = Int_val(_level);
  BinaryenSetShrinkLevel(level);
  CAMLreturn(Val_unit);
}

CAMLprim value
caml_binaryen_get_debug_info(value unit) {
  CAMLparam1(unit);
  bool res = BinaryenGetDebugInfo();
  CAMLreturn(Val_bool(res));
}

CAMLprim value
caml_binaryen_set_debug_info(value _on) {
  CAMLparam1(_on);
  bool on = Bool_val(_on);
  BinaryenSetDebugInfo(on);
  CAMLreturn(Val_unit);
}

CAMLprim value
caml_binaryen_get_low_memory_unused(value unit) {
  CAMLparam1(unit);
  bool res = BinaryenGetLowMemoryUnused();
  CAMLreturn(Val_bool(res));
}

CAMLprim value
caml_binaryen_set_low_memory_unused(value _on) {
  CAMLparam1(_on);
  bool on = Bool_val(_on);
  BinaryenSetLowMemoryUnused(on);
  CAMLreturn(Val_unit);
}

CAMLprim value
caml_binaryen_get_pass_argument(value _name) {
  CAMLparam1(_name);
  const char* name = Safe_String_val(_name);
  const char* val = BinaryenGetPassArgument(name);
  CAMLreturn(caml_copy_string(val));
}

CAMLprim value
caml_binaryen_set_pass_argument(value _name, value _val) {
  CAMLparam2(_name, _val);
  const char* name = Safe_String_val(_name);
  const char* val = Safe_String_val(_val);
  BinaryenSetPassArgument(name, val);
  CAMLreturn(Val_unit);
}

CAMLprim value
caml_binaryen_get_always_inline_max_size(value unit) {
  CAMLparam1(unit);
  int res = BinaryenGetAlwaysInlineMaxSize();
  CAMLreturn(Val_int(res));
}

CAMLprim value
caml_binaryen_set_always_inline_max_size(value _size) {
  CAMLparam1(_size);
  int size = Int_val(_size);
  BinaryenSetAlwaysInlineMaxSize(size);
  CAMLreturn(Val_unit);
}

CAMLprim value
caml_binaryen_get_flexible_inline_max_size(value unit) {
  CAMLparam1(unit);
  int res = BinaryenGetFlexibleInlineMaxSize();
  CAMLreturn(Val_int(res));
}

CAMLprim value
caml_binaryen_set_flexible_inline_max_size(value _size) {
  CAMLparam1(_size);
  int size = Int_val(_size);
  BinaryenSetFlexibleInlineMaxSize(size);
  CAMLreturn(Val_unit);
}

CAMLprim value
caml_binaryen_get_one_caller_inline_max_size(value unit) {
  CAMLparam1(unit);
  int res = BinaryenGetOneCallerInlineMaxSize();
  CAMLreturn(Val_int(res));
}

CAMLprim value
caml_binaryen_set_one_caller_inline_max_size(value _size) {
  CAMLparam1(_size);
  int size = Int_val(_size);
  BinaryenSetOneCallerInlineMaxSize(size);
  CAMLreturn(Val_unit);
}

CAMLprim value
caml_binaryen_set_colors_enabled(value _on) {
  CAMLparam1(_on);
  bool on = Bool_val(_on);
  BinaryenSetColorsEnabled(on);
  CAMLreturn(Val_unit);
}

CAMLprim value
caml_binaryen_are_colors_enabled(value unit) {
  CAMLparam1(unit);
  bool res = BinaryenAreColorsEnabled();
  CAMLreturn(Val_bool(res));
}


<|start_filename|>src/binaryen_stubs_functions.c<|end_filename|>
#define CAML_NAME_SPACE
#include <caml/mlvalues.h>
#include <caml/fail.h>
#include <caml/memory.h>
#include <caml/alloc.h>

#include "binaryen-c.h"
#include "ocaml_helpers.h"


/* Allocating an OCaml custom block to hold the given BinaryenFunctionRef */
static value alloc_BinaryenFunctionRef(BinaryenFunctionRef fun)
{
  value v = caml_alloc_custom(&binaryen_ops, sizeof(BinaryenFunctionRef), 0, 1);
  BinaryenFunctionRef_val(v) = fun;
  return v;
}

/* Allocating an OCaml custom block to hold the given BinaryenExpressionRef */
static value alloc_BinaryenExpressionRef(BinaryenExpressionRef exp)
{
  value v = caml_alloc_custom(&binaryen_ops, sizeof(BinaryenExpressionRef), 0, 1);
  BinaryenExpressionRef_val(v) = exp;
  return v;
}

/* Allocating an OCaml custom block to hold the given BinaryenType */
static value alloc_BinaryenType(BinaryenType typ)
{
  value v = caml_alloc_custom(&binaryen_ops, sizeof(BinaryenType), 0, 1);
  BinaryenType_val(v) = typ;
  return v;
}

CAMLprim value
caml_binaryen_add_function(value _module, value _name, value _params, value _results, value _locals, value _body) {
  CAMLparam5(_module, _name, _params, _results, _locals);
  CAMLxparam1(_body);
  BinaryenModuleRef module = BinaryenModuleRef_val(_module);
  char* name = Safe_String_val(_name);
  BinaryenType params = BinaryenType_val(_params);
  BinaryenType results = BinaryenType_val(_results);
  int len = array_length(_locals);
  BinaryenType locals[len];
  for (int i = 0; i < len; i++) {
    locals[i] = BinaryenType_val(Field(_locals, i));
  }
  BinaryenExpressionRef body = BinaryenExpressionRef_val(_body);
  BinaryenFunctionRef fun = BinaryenAddFunction(module, name, params, results, locals, len, body);
  CAMLreturn(alloc_BinaryenFunctionRef(fun));
}
CAMLprim value
caml_binaryen_add_function__bytecode(value * argv) {
  return caml_binaryen_add_function(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]);
}

CAMLprim value
caml_binaryen_get_function(value _module, value _name) {
  CAMLparam2(_module, _name);
  BinaryenModuleRef module = BinaryenModuleRef_val(_module);
  char* name = Safe_String_val(_name);
  BinaryenFunctionRef fun = BinaryenGetFunction(module, name);
  CAMLreturn(alloc_BinaryenFunctionRef(fun));
}

CAMLprim value
caml_binaryen_remove_function(value _module, value _name) {
  CAMLparam2(_module, _name);
  BinaryenModuleRef module = BinaryenModuleRef_val(_module);
  char* name = Safe_String_val(_name);
  BinaryenRemoveFunction(module, name);
  CAMLreturn(Val_unit);
}

CAMLprim value
caml_binaryen_get_num_functions(value _module) {
  CAMLparam1(_module);
  BinaryenModuleRef module = BinaryenModuleRef_val(_module);
  CAMLreturn(Val_int(BinaryenGetNumFunctions(module)));
}

CAMLprim value
caml_binaryen_get_function_by_index(value _module, value _index) {
  CAMLparam2(_module, _index);
  BinaryenModuleRef module = BinaryenModuleRef_val(_module);
  BinaryenIndex index = Int_val(_index);
  BinaryenFunctionRef fun = BinaryenGetFunctionByIndex(module, index);
  CAMLreturn(alloc_BinaryenFunctionRef(fun));
}

CAMLprim value
caml_binaryen_set_start(value _module, value _fun) {
  CAMLparam2(_module, _fun);
  BinaryenModuleRef module = BinaryenModuleRef_val(_module);
  BinaryenFunctionRef fun = BinaryenFunctionRef_val(_fun);
  BinaryenSetStart(module, fun);
  CAMLreturn(Val_unit);
}

CAMLprim value
caml_binaryen_function_set_debug_location(value _fun, value _exp, value _file, value _line, value _column) {
  CAMLparam5(_fun, _exp, _file, _line, _column);
  BinaryenFunctionRef fun = BinaryenFunctionRef_val(_fun);
  BinaryenExpressionRef exp = BinaryenExpressionRef_val(_exp);
  BinaryenIndex file = Int_val(_file);
  BinaryenIndex line = Int_val(_line);
  BinaryenIndex column = Int_val(_column);
  BinaryenFunctionSetDebugLocation(fun, exp, file, line, column);
  CAMLreturn(Val_unit);
}

CAMLprim value
caml_binaryen_function_get_name(value _fun) {
  CAMLparam1(_fun);
  BinaryenFunctionRef fun = BinaryenFunctionRef_val(_fun);
  CAMLreturn(caml_copy_string(BinaryenFunctionGetName(fun)));
}

CAMLprim value
caml_binaryen_function_get_params(value _fun) {
  CAMLparam1(_fun);
  BinaryenFunctionRef fun = BinaryenFunctionRef_val(_fun);
  CAMLreturn(alloc_BinaryenType(BinaryenFunctionGetParams(fun)));
}

CAMLprim value
caml_binaryen_function_get_results(value _fun) {
  CAMLparam1(_fun);
  BinaryenFunctionRef fun = BinaryenFunctionRef_val(_fun);
  CAMLreturn(alloc_BinaryenType(BinaryenFunctionGetResults(fun)));
}

CAMLprim value
caml_binaryen_function_get_num_vars(value _fun) {
  CAMLparam1(_fun);
  BinaryenFunctionRef fun = BinaryenFunctionRef_val(_fun);
  CAMLreturn(Val_int(BinaryenFunctionGetNumVars(fun)));
}

CAMLprim value
caml_binaryen_function_get_var(value _fun, value _index) {
  CAMLparam2(_fun, _index);
  BinaryenFunctionRef fun = BinaryenFunctionRef_val(_fun);
  BinaryenIndex index = Int_val(_index);
  CAMLreturn(alloc_BinaryenType(BinaryenFunctionGetVar(fun, index)));
}

CAMLprim value
caml_binaryen_function_get_body(value _fun) {
  CAMLparam1(_fun);
  BinaryenFunctionRef fun = BinaryenFunctionRef_val(_fun);
  CAMLreturn(alloc_BinaryenExpressionRef(BinaryenFunctionGetBody(fun)));
}

CAMLprim value
caml_binaryen_function_set_body(value _fun, value _body) {
  CAMLparam2(_fun, _body);
  BinaryenFunctionRef fun = BinaryenFunctionRef_val(_fun);
  BinaryenExpressionRef body = BinaryenExpressionRef_val(_body);
  BinaryenFunctionSetBody(fun, body);
  CAMLreturn(Val_unit);
}


<|start_filename|>src/ocaml_helpers.c<|end_filename|>
#define CAML_NAME_SPACE
#include <caml/mlvalues.h>
#include <caml/fail.h>
#include <caml/memory.h>
#include <caml/callback.h>

#include "ocaml_helpers.h"


CAMLprim value
array_of_list(value list) {
  CAMLparam1(list);
  static const value *closure_f = NULL;
  if (closure_f == NULL) {
      /* First time around, look up by name */
      closure_f = caml_named_value("array_of_list");
  }
  CAMLreturn(caml_callback(*closure_f, list));
}

int array_length(value array) {
  CAMLparam1(array);
  static const value * closure_f = NULL;
  if (closure_f == NULL) {
    /* First time around, look up by name */
    closure_f = caml_named_value("array_length");
  }
  CAMLlocal1(res);
  res = caml_callback(*closure_f, array);
  CAMLreturnT(int, Int_val(res));
}
