e5f95df4b2a8 — Vesa Norilo 2 years ago
Binaryen update and build fixes
M .build.yml +8 -22
@@ 1,36 1,22 @@ 
-image: ubuntu/latest
+image: ubuntu/20.04
 packages:
-- libsndfile-dev
-- libjack-jackd2-dev
-- libz-dev
 - cmake
-- llvm-6.0-dev
-- libcurl4-openssl-dev
-- libfmt-dev
-secrets:
-  - 571eec1e-e160-4e54-a8cf-c44b0b91e1a1
-  - 2c57e405-7f00-4c43-b59a-3cc1304e545a
 sources:
 - hg+https://hg.sr.ht/~vnorilo/kronos
 tasks:
-- identity: |
-    set +x
-    cd kronos
-    hg sum
 - configure: |
-    set +x
+    set -ex
+    git clone --depth 1 https://github.com/emscripten-core/emsdk.git
+    emsdk/emsdk install latest
+    emsdk/emsdk activate latest
+    chmod 777 emsdk/emsdk_env.sh
+    . ./emsdk/emsdk_env.sh 
     mkdir build
     cd build
-    cmake ../kronos -DCMAKE_BUILD_TYPE=Release
-- authorize-ci: |
-    cd kronos
-    ~/authorize_ci.sh
+    emcmake cmake ../kronos -DCMAKE_BUILD_TYPE=Release
 - build: |
     cd build
     make -j
-- test: |
-    cd build
-    env CTEST_OUTPUT_ON_FAILURE=1 make test
 triggers:
 - action: email
   condition: failure

          
M CMakeLists.txt +2 -2
@@ 14,7 14,7 @@ set(PAF_LIBRARY_TARGET_ONLY ON)
 set(PAD_LIBRARY_TARGET_ONLY ON)
 set(LITHE_LIBRARY_TARGETS_ONLY ON)
 
-set(CMAKE_CXX_STANDARD 14)
+set(CMAKE_CXX_STANDARD 17)
 set(CMAKE_CXX_STANDARD_REQUIRED ON)
 
 include(FindCURL)

          
@@ 263,7 263,7 @@ function(add_o2)
     set(BUILD_WITH_MESSAGE_PRINT OFF)
     set(BUILD_WITH_O2LITE_DISCOVERY OFF)
     set(BUILD_WITH_O2LITE_CLOCKSYNC OFF)
-	add_definitions("-DO2_EXPORT=extern" -DO2L_NO_BROADCAST)
+	add_definitions("-DO2_EXPORT=extern" -DO2L_NO_BROADCAST -DO2_NO_O2DISCOVERY)
 
 	add_subdirectory(${O2_DIR} o2)
 	set_target_properties(o2_static o2lite_static PROPERTIES FOLDER libs)

          
M cmake/Binaryen.cmake +9 -18
@@ 18,24 18,15 @@ else()
 	set(CMAKE_ARGS "-DENABLE_WERROR=OFF" "-DBUILD_STATIC_LIB=ON")
 endif()
 
-if (WIN32)
-	ExternalProject_Add(
-		binaryen 
-		SVN_REPOSITORY "https://github.com/WebAssembly/binaryen.git/tags/${BINARYEN_VERSION}"
-		CMAKE_COMMAND "${CMAKE_CMD}"
-		CMAKE_ARGS ${CMAKE_ARGS}
-		BUILD_COMMAND cmake --build . --target binaryen
-		INSTALL_COMMAND "")
-else()
-	ExternalProject_Add(
-		binaryen 
-		GIT_REPOSITORY https://github.com/WebAssembly/binaryen.git
-		GIT_TAG ${BINARYEN_VERSION}
-		CMAKE_COMMAND "${CMAKE_CMD}"
-		CMAKE_ARGS ${CMAKE_ARGS}
-		BUILD_COMMAND cmake --build . --target binaryen -- -j4
-		INSTALL_COMMAND "")
-endif()
+ExternalProject_Add(
+	binaryen 
+	GIT_REPOSITORY https://github.com/WebAssembly/binaryen.git
+	GIT_TAG ${BINARYEN_VERSION}
+	CMAKE_COMMAND "${CMAKE_CMD}"
+	CMAKE_ARGS ${CMAKE_ARGS} -DCMAKE_CXX_STANDARD=17
+	BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/binaryen/$<CONFIG>"
+	BUILD_COMMAND cmake --build . --target binaryen --config $<CONFIG>
+	INSTALL_COMMAND "")
 
 if (EMSCRIPTEN)
 	set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g -O2 -s STACK_OVERFLOW_CHECK=2 -s WARN_UNALIGNED=1 -s DEMANGLE_SUPPORT=1 -s DISABLE_EXCEPTION_CATCHING=0 -s DISABLE_EXCEPTION_THROWING=0 -s ASSERTIONS=2")

          
M src/backends/BinaryenCompiler.cpp +2 -2
@@ 56,7 56,7 @@ namespace K3 {
 
 		CODEGEN_EMIT(SubroutineStateAllocation) {
 			if (xfm.IsSizingPass()) {
-				return subr->Compile(xfm, avm);
+				return (decltype(xfm(this, avm)))subr->Compile(xfm, avm);
 			} else {
 				return 
 					xfm->Offset(

          
@@ 218,7 218,7 @@ namespace K3 {
 			std::string cfgName = "dconf_" + std::to_string((std::uintptr_t)cfg);
 			if (xfm.IsSizingPass()) {
 				xfm.GetCompilationPass().SetPassType(Backends::BuilderPass::InitializationWithReturn);
-				auto val = xfm->TmpVar(cfg->Compile(xfm, avm));
+				auto val = xfm->TmpVar((decltype(xfm(this, avm)))cfg->Compile(xfm, avm));
 				xfm.GetCompilationPass().SetPassType(Backends::BuilderPass::Sizing);
 				xfm->SetGVar(cfgName, val, true);
 				return val;

          
M src/backends/BinaryenCompiler.h +1 -1
@@ 122,7 122,7 @@ namespace K3 {
 					return state.var;
 				}
 
-				BinaryenExpressionRef val = n->Compile(*this, currentActivityMask);
+				BinaryenExpressionRef val = (BinaryenExpressionRef)n->Compile(*this, currentActivityMask);
 				if (!val) return val;
 
 				if (inBranch) {

          
M src/backends/BinaryenEmitter.cpp +38 -31
@@ 3,18 3,38 @@ 
 
 #include <string>
 
+namespace std {
+	size_t hash<K3::Backends::BinaryenFunctionTypeRef>::operator()(K3::Backends::BinaryenFunctionTypeRef const& fty) const {
+		hash<BinaryenType> hasher;
+
+		auto h = hasher(fty.returnType);
+
+		for (auto&& at : fty.argumentType) {
+			h ^= hasher(at);
+		}
+
+		return h;
+	}
+}
+
 namespace K3 {
 	namespace Backends {
+		bool BinaryenFunctionTypeRef::operator==(const BinaryenFunctionTypeRef& other) const {
+			return std::equal(argumentType.cbegin(), argumentType.cend(),
+				other.argumentType.cbegin(), other.argumentType.cend())
+				&& returnType == other.returnType;
+		}
+
 		BinaryenExpressionRef BinaryenEmitter::FnArg(int i, BinaryenType ty) {
 			return BinaryenLocalGet(M, i, ty);
 		}
 
 		BinaryenExpressionRef BinaryenEmitter::FnArg(int i) {
-			return BinaryenLocalGet(M, i, BinaryenFunctionTypeGetParam(fn.d->ty, i));
+			return BinaryenLocalGet(M, i, fn.d->ty.argumentType[i]);
 		}
 
 		int BinaryenEmitter::NumFnArgs() {
-			return BinaryenFunctionTypeGetNumParams(fn.d->ty);
+			return fn.d->GetNumParams();
 		}
 
 		BinaryenExpressionRef BinaryenEmitter::GetSlot(int index) {

          
@@ 52,14 72,14 @@ namespace K3 {
 				DeclareGVar(M, name, BinaryenExpressionGetType(value), value);
 			} else {
 				DeclareGVar(M, name, BinaryenExpressionGetType(value), constant);
-				b->instr.push_back(BinaryenSetGlobal(M, name.c_str(), value));
+				b->instr.push_back(BinaryenGlobalSet(M, name.c_str(), value));
 			}
 		}
 
 
 		void BinaryenEmitter::SetSlot(int index, BinaryenExpressionRef val) {
 			Use(val);
-			b->instr.emplace_back(BinaryenSetGlobal(M, ("slot" + std::to_string(index)).c_str(), val));
+			b->instr.emplace_back(BinaryenGlobalSet(M, ("slot" + std::to_string(index)).c_str(), val));
 		}
 
 		BinaryenExpressionRef BinaryenEmitter::PtrToInt(BinaryenExpressionRef ptr) { return ptr; }

          
@@ 80,7 100,7 @@ namespace K3 {
 		BinaryenExpressionRef BinaryenEmitter::Call(const BinaryenFunction& fn, const std::vector<BinaryenExpressionRef>& params, bool internalCall) {
 			if (fn.d != this->fn.d) fn.Complete();
 			for (auto &p : params) Use(p);
-			auto fncall = BinaryenCall(M, fn.d->name.c_str(), (BinaryenExpressionRef*)params.data(), (int)params.size(), BinaryenFunctionTypeGetResult(fn.d->ty));
+			auto fncall = BinaryenCall(M, fn.d->name.c_str(), (BinaryenExpressionRef*)params.data(), (int)params.size(), (fn.d->ty.returnType));
 			b->instr.emplace_back(fncall);
 			return fncall;
 		}

          
@@ 88,13 108,13 @@ namespace K3 {
 		BinaryenExpressionRef BinaryenEmitter::PureCall(const BinaryenFunction& fn, const std::vector<BinaryenExpressionRef>& params, bool internalCall) {
 			if (fn.d != this->fn.d) fn.Complete();
 #ifndef NDEBUG
-			assert(BinaryenFunctionTypeGetNumParams(fn.d->ty) == params.size());
+			assert(fn.d->GetNumParams() == params.size());
 			for (int i = 0;i < params.size();++i) {
 				Use(params[i]);
-				assert(BinaryenFunctionTypeGetParam(fn.d->ty, i) == BinaryenExpressionGetType(params[i]));
+				assert(fn.d->ty.argumentType[i] == BinaryenExpressionGetType(params[i]));
 			}
 #endif
-			auto fncall = BinaryenCall(M, fn.d->name.c_str(), (BinaryenExpressionRef*)params.data(), (int)params.size(), BinaryenFunctionTypeGetResult(fn.d->ty));
+			auto fncall = BinaryenCall(M, fn.d->name.c_str(), (BinaryenExpressionRef*)params.data(), (int)params.size(), fn.d->ty.returnType);
 			return fncall;
 		}
 

          
@@ 142,7 162,7 @@ namespace K3 {
 			int wordIdx = bitIdx / 32;
 			auto sigmask = "sigmask" + std::to_string(wordIdx);
 			DeclareGVar(M, sigmask, BinaryenTypeInt32());
-			b->instr.push_back(BinaryenSetGlobal(M, sigmask.c_str(), word));
+			b->instr.push_back(BinaryenGlobalSet(M, sigmask.c_str(), word));
 		}
 
 		BinaryenExpressionRef BinaryenEmitter::NonZero(BinaryenExpressionRef v) {

          
@@ 163,12 183,12 @@ namespace K3 {
 			KRONOS_UNREACHABLE;
 		}
 
-		BinaryenType BinaryenEmitter::FnArgTy(BinaryenFunctionTypeRef fnTy, int index) {
-			return BinaryenFunctionTypeGetParam(fnTy, index);
+		BinaryenType BinaryenEmitter::FnArgTy(BinaryenFunctionTypeRef const& fnTy, int index) {
+			return fnTy.argumentType[index];
 		}
 
-		int BinaryenEmitter::NumFnArgs(BinaryenFunctionTypeRef fnTy) {
-			return BinaryenFunctionTypeGetNumParams(fnTy);
+		int BinaryenEmitter::NumFnArgs(BinaryenFunctionTypeRef const& fnTy) {
+			return (int)fnTy.argumentType.size();
 		}
 
 		void BinaryenEmitter::TCO(BinaryenExpressionRef cond, const std::vector<BinaryenValue>& params) {

          
@@ 206,20 226,15 @@ namespace K3 {
 					bl = BinaryenLoop(d->M, TCO_RECURSION, bl);
 				}
 
-				if (Mod->getFunctionTypeOrNull(BinaryenFunctionTypeGetName(d->ty)) == nullptr) {
-					std::clog << "Type not found\n";
-					//Mod->addFunctionType((wasm::FunctionType*)d->ty);
-				}
-
 				BinaryenExpressionRef saveStack[] = {
-					BinaryenSetLocal(d->M, BinaryenFunctionTypeGetNumParams(d->ty),
+					BinaryenLocalSet(d->M, d->GetNumParams(),
 					BinaryenGlobalGet(d->M, STACK_PTR, BinaryenTypeInt32())),
 					bl
 				};
 
 				bl = ::BinaryenBlock(d->M, nullptr, saveStack, 2, BinaryenTypeAuto());
 
-				d->fn = BinaryenAddFunction(d->M, nm.c_str(), d->ty, d->lvars.data(), (int)d->lvars.size(), bl);
+				d->fn = BinaryenAddFunction(d->M, nm.c_str(), d->GetParamType(), d->ty.returnType, d->lvars.data(), (int)d->lvars.size(), bl);
 				d->emitted = true;
 			}
 		}

          
@@ 227,7 242,7 @@ namespace K3 {
 		BinaryenIndex BinaryenFunction::LVar(const std::string& nm, BinaryenType vty) {
 			assert(vty != BinaryenTypeNone());
 			d->lvars.push_back(vty);
-			return (int)(BinaryenFunctionTypeGetNumParams(d->ty) + d->lvars.size() - 1);
+			return (int)(d->GetNumParams() + d->lvars.size() - 1);
 		}
 
 		BinaryenIndex BinaryenFunction::LVar(BinaryenExpressionRef expr) {

          
@@ 501,7 516,7 @@ namespace K3 {
 		BinaryenExpressionRef BinaryenEmitter::GlobalExternal(BinaryenType t, const std::string& mod, const std::string& sym) {
 			auto Mod = (wasm::Module*)M;
 			if (Mod->getGlobalOrNull(sym) == nullptr) {
-				BinaryenAddGlobalImport(M, sym.c_str(), mod.c_str(), sym.c_str(), t);
+				BinaryenAddGlobalImport(M, sym.c_str(), mod.c_str(), sym.c_str(), t, true);
 			}
 			return BinaryenGlobalGet(M, sym.c_str(), t);
 		}

          
@@ 534,19 549,11 @@ namespace K3 {
 				returnTy = BinaryenTypeNone();
 			}
 
-			auto fty = BinaryenAddFunctionType(M, nullptr, returnTy, paramTys.data(), (int)paramTys.size());
-
 			auto Mod = (wasm::Module*)M;
 			if (Mod->getFunctionOrNull(sym.c_str()) == nullptr) {
-				BinaryenAddFunctionImport(M, sym.c_str(), "import", sym.c_str(), fty);
+				BinaryenAddFunctionImport(M, sym.c_str(), "import", sym.c_str(), fn.d->GetParamType(), fn.d->ty.returnType);
 			}
 
-#ifndef NDEBUG
-			for (int i = 0;i < BinaryenFunctionTypeGetNumParams(fty); ++i) {
-				assert(BinaryenFunctionTypeGetParam(fty, i) == BinaryenExpressionGetType(pass[i]));
-			}
-#endif
-
 			auto fncall = BinaryenCall(M, sym.c_str(), (BinaryenExpressionRef*)pass.data(), (int)pass.size(), returnTy);
 
 			if (returnByHeap) {

          
M src/backends/BinaryenEmitter.h +29 -8
@@ 22,6 22,13 @@ namespace K3 {
 			BinaryenExpressionRef GetBlock(BinaryenModuleRef M, const char *nm = nullptr) const;
 		};
 
+		struct BinaryenFunctionTypeRef {
+			std::vector<BinaryenType> argumentType;
+			BinaryenType returnType;
+
+			bool operator==(const BinaryenFunctionTypeRef&) const;
+		};
+
 		struct FnData {
 			std::string name;
 			bool exported;

          
@@ 33,6 40,14 @@ namespace K3 {
 			mutable bool emitted = false;
 			bool hasTco = false;
 			std::unordered_set<BinaryenExpressionRef> seen;
+
+			int GetNumParams() const {
+				return (int)ty.argumentType.size();
+			}
+
+			BinaryenType GetParamType() const {
+				return BinaryenTypeCreate((BinaryenType*)ty.argumentType.data(), (BinaryenIndex)ty.argumentType.size());
+			}
 		};
 
 		struct BinaryenFunction {

          
@@ 88,11 103,11 @@ namespace K3 {
 					}
 					KRONOS_UNREACHABLE;
 				} else if (BinaryenExpressionGetId(expr) == BinaryenLocalGetId() && 
-						   BinaryenLocalGetGetIndex(expr) < BinaryenFunctionTypeGetNumParams(fn.d->ty)) {
+						   BinaryenLocalGetGetIndex(expr) < fn.d->GetNumParams()) {
 					idx = BinaryenLocalGetGetIndex(expr);
 				} else {
 					idx = fn.LVar("", L.type);
-					b.instr.emplace_back(BinaryenSetLocal(fn.d->M, idx, expr));
+					b.instr.emplace_back(BinaryenLocalSet(fn.d->M, idx, expr));
 				}
 			}
 

          
@@ 189,7 204,7 @@ namespace K3 {
 
 			BinaryenExpressionRef Select(BinaryenExpressionRef which, BinaryenExpressionRef whenTrue, BinaryenExpressionRef whenFalse) {
 				Use(which); Use(whenTrue); Use(whenFalse);
-				return BinaryenSelect(M, which, whenTrue, whenFalse);
+				return BinaryenSelect(M, which, whenTrue, whenFalse, BinaryenExpressionGetType(whenTrue));
 			}
 
 			BinaryenExpressionRef NonZero(BinaryenExpressionRef expr);

          
@@ 245,7 260,7 @@ namespace K3 {
 			void Ret(BinaryenExpressionRef v = nullptr) {
 				auto retVal = v ? (BinaryenExpressionRef)TmpVar(v) : nullptr;
 				b->instr.emplace_back(
-					BinaryenSetGlobal(M, STACK_PTR, BinaryenLocalGet(M, BinaryenFunctionTypeGetNumParams(fn.d->ty), BinaryenTypeInt32())));
+					BinaryenGlobalSet(M, STACK_PTR, BinaryenLocalGet(M, fn.d->GetNumParams(), BinaryenTypeInt32())));
 				b->instr.emplace_back(BinaryenReturn(M, retVal));
 			}
 

          
@@ 265,8 280,8 @@ namespace K3 {
 			BinaryenExpressionRef FnArg(int index, BinaryenType ty);
 			int NumFnArgs();
 
-			BinaryenType FnArgTy(BinaryenFunctionTypeRef, int index);
-			int NumFnArgs(BinaryenFunctionTypeRef);
+			BinaryenType FnArgTy(BinaryenFunctionTypeRef const&, int index);
+			int NumFnArgs(BinaryenFunctionTypeRef const&);
 
 
 			BinaryenExpressionRef GetSlot(int index);

          
@@ 374,7 389,7 @@ namespace K3 {
 			void Set(BinaryenIndex i, BinaryenExpressionRef val) {
 				Use(val);
 				assert(BinaryenExpressionGetType(val) != BinaryenTypeNone());
-				b->instr.push_back(BinaryenSetLocal(M, i, val));
+				b->instr.push_back(BinaryenLocalSet(M, i, val));
 			}
 
 			BinaryenExpressionRef Get(BinaryenIndex i, BinaryenType ty) {

          
@@ 383,7 398,7 @@ namespace K3 {
 			}
 
 			BinaryenExpressionRef Get(BinaryenIndex i) {
-				return BinaryenLocalGet(M, i, fn.TypeOfVar(i - BinaryenFunctionTypeGetNumParams(fn.d->ty)));
+				return BinaryenLocalGet(M, i, fn.TypeOfVar(i - fn.d->GetNumParams()));
 			}
 
 			BinaryenExpressionRef False() { return Const(0); }

          
@@ 420,4 435,10 @@ namespace K3 {
 			BinaryenExpressionRef UnaryOp(Nodes::Native::Opcode, BinaryenExpressionRef up);
 		};
 	}
+}
+
+namespace std {
+	template <> struct hash<K3::Backends::BinaryenFunctionTypeRef> {
+		size_t operator()(const K3::Backends::BinaryenFunctionTypeRef& r) const;
+	};
 }
  No newline at end of file

          
M src/backends/BinaryenModule.cpp +40 -28
@@ 1,6 1,5 @@ 
 #include "binaryen-c.h"
 #include "wasm.h"
-#include "wasm-printing.h"
 
 #include "BinaryenModule.h"
 #include "Binaryen.h"

          
@@ 43,8 42,8 @@ namespace K3 {
 			if (flags & Kronos::BuildFlags::WasmStandaloneModule) {
 				StandaloneModule = true;
 			} else {
-				BinaryenAddGlobalImport(M, STATIC_DATA, "DS", "addr", BinaryenTypeInt32());
-				StaticData = BinaryenGetGlobal(M, STATIC_DATA, BinaryenTypeInt32());
+				BinaryenAddGlobalImport(M, STATIC_DATA, "DS", "addr", BinaryenTypeInt32(), false);
+				StaticData = BinaryenGlobalGet(M, STATIC_DATA, BinaryenTypeInt32());
 			}
 
 			RegionAllocator alloc;

          
@@ 65,8 64,9 @@ namespace K3 {
 			};
 
 			BinaryenType slotSetterArgTys[] = { BinaryenTypeInt32() };
-			auto slotSetterTy = BinaryenAddFunctionType(M, "SlotSetterTy", BinaryenTypeNone(), slotSetterArgTys, 1);
-			auto slotGetterTy = BinaryenAddFunctionType(M, "SlotGetterTy", BinaryenTypeInt32(), nullptr, 0);
+			BinaryenType slotSetterArgTy = BinaryenTypeInt32();
+//			auto slotSetterTy = BinaryenAddFunctionType(M, "SlotSetterTy", BinaryenTypeNone(), slotSetterArgTys, 1);
+//			auto slotGetterTy = BinaryenAddFunctionType(M, "SlotGetterTy", BinaryenTypeInt32(), nullptr, 0);
 
 			for (auto &gk : globalKeyTable) {
 				auto uid = gk.second.uid;

          
@@ 78,12 78,14 @@ namespace K3 {
 
 				std::string setter = "set_" + key.str(), getter = "get_" + key.str();
 
-				BinaryenAddFunction(M, setter.c_str(), slotSetterTy, nullptr, 0,
-									BinaryenSetGlobal(M, nm.c_str(),
-										BinaryenGetLocal(M, 0, BinaryenTypeInt32())));
+				BinaryenAddFunction(M, setter.c_str(), BinaryenTypeInt32(), BinaryenTypeNone(),
+									nullptr, 0,
+									BinaryenGlobalSet(M, nm.c_str(),
+										BinaryenLocalGet(M, 0, BinaryenTypeInt32())));
 
-				BinaryenAddFunction(M, getter.c_str(), slotGetterTy, nullptr, 0,
-									BinaryenGetGlobal(M, nm.c_str(), BinaryenTypeInt32()));
+				BinaryenAddFunction(M, getter.c_str(), BinaryenTypeNone(), BinaryenTypeInt32(), 
+									nullptr, 0,
+									BinaryenGlobalGet(M, nm.c_str(), BinaryenTypeInt32()));
 
 				BinaryenAddFunctionExport(M, setter.c_str(), setter.c_str());
 				BinaryenAddFunctionExport(M, getter.c_str(), getter.c_str());

          
@@ 140,18 142,18 @@ namespace K3 {
 				auto addInstance = CreateFunction("AddInstance", Int32Ty(), { }, true);
 				{
 					BuilderTy b{ addInstance };
-					auto inst = b.TmpVar(BinaryenGetGlobal(M, HEAP_TOP, BinaryenTypeInt32()));
+					auto inst = b.TmpVar(BinaryenGlobalGet(M, HEAP_TOP, BinaryenTypeInt32()));
 					auto sz = b.TmpVar(b.PureCall(sizeExport, {}, false));
-					b.Sfx(BinaryenSetGlobal(M, HEAP_TOP, b.AddInt32(inst, sz)));
+					b.Sfx(BinaryenGlobalSet(M, HEAP_TOP, b.AddInt32(inst, sz)));
 					auto newSize = b.AddInt32(b.Const(16), b.DivSInt32(sz, b.Const(0x10000)));
-					b.Sfx(BinaryenHost(M, BinaryenGrowMemory(), nullptr, &newSize, 1));
+					b.Sfx(BinaryenMemoryGrow(M, newSize));
 					b.Ret(inst);
 				}
 
 				auto unwindStack = CreateFunction("UnwindStack", VoidTy(), {}, true);
 				{
 					BuilderTy b{ unwindStack };
-					b.Set(0, BinaryenGetGlobal(M, HEAP_TOP, BinaryenTypeInt32()));
+					b.Set(0, BinaryenGlobalGet(M, HEAP_TOP, BinaryenTypeInt32()));
 					b.Ret();
 				}
 

          
@@ 167,13 169,13 @@ namespace K3 {
 			auto getStackPointer = CreateFunction("GetStackPointer", Int32Ty(), {}, true);
 			{
 				BuilderTy b{ getStackPointer };
-				b.Ret(BinaryenGetGlobal(M, STACK_PTR, BinaryenTypeInt32()));
+				b.Ret(BinaryenGlobalGet(M, STACK_PTR, BinaryenTypeInt32()));
 			}
 
 			auto setStackPointer = CreateFunction("SetStackPointer", VoidTy(), { Int32Ty() }, true);
 			{
 				BuilderTy b{ setStackPointer };
-				b.Sfx(BinaryenSetGlobal(M, STACK_PTR, b.FnArg(0)));
+				b.Sfx(BinaryenGlobalSet(M, STACK_PTR, b.FnArg(0)));
 				b.RetNoUnwind();
 			}
 

          
@@ 271,9 273,10 @@ namespace K3 {
 		}
 
 		BinaryenFunctionTypeRef BinaryenModule::CreateFunctionTy(BinaryenType retTy, const std::vector<BinaryenType>& params) {
-			auto ty = BinaryenGetFunctionTypeBySignature(M, retTy, (BinaryenType*)params.data(), (int)params.size());
-			if (ty) return ty;
-			return BinaryenAddFunctionType(M, nullptr, retTy, (BinaryenType*)params.data(), (int)params.size());
+			BinaryenFunctionTypeRef ty;
+			ty.argumentType = params;
+			ty.returnType = retTy;
+			return ty;
 		}
 
 		BinaryenSpec::FunctionTy BinaryenSpec::CompilePass(const std::string& name, Backends::BuilderPass passCategory, const DriverSet& drivers) { 

          
@@ 281,13 284,22 @@ namespace K3 {
 			return CompilePass(name, passCategory, drivers, emptySet);
 		}
 
+		template <typename T>
+		static size_t get_hash(T const& v) {
+			return std::hash<T>()(v);
+		}
+
 		BinaryenSpec::FunctionTy BinaryenSpec::CompilePass(const std::string& name, Backends::BuilderPass passCategory, const DriverSet& drivers, const CounterIndiceSet& counters) {
 			using FunctionKey = std::tuple<Graph<const Typed>, FunctionTyTy>;
 
 			struct FunctionKeyHash {
+
 				size_t operator()(const FunctionKey& fk) const {
-					return std::get<Graph<const Typed>>(fk)->GetHash() ^ 
-						  (intptr_t)std::get<FunctionTyTy>(fk);
+					auto fty = std::get<FunctionTyTy>(fk);
+
+					auto h = std::get<Graph<const Typed>>(fk)->GetHash() ^ get_hash(fty);
+
+					return h;
 				}
 			};
 

          
@@ 300,7 312,7 @@ namespace K3 {
 				FunctionTyTy SizingFunctionCacheTy;
 
 				Pass(CTRef ast, BinaryenSpec& s, const std::string& l, Backends::BuilderPass pt, const CounterIndiceSet& counters) :build(s), CodeGenPass(l, ast, counters), passType(pt) {
-					SizingFunctionCacheTy = BinaryenAddFunctionType(s.M, nullptr, BinaryenTypeInt32(), nullptr, 0);
+//					SizingFunctionCacheTy = BinaryenAddFunctionType(s.M, nullptr, BinaryenTypeInt32(), nullptr, 0);
 				}
 
 				ModuleTy& GetModule() override {

          
@@ 354,7 366,7 @@ namespace K3 {
 				sz = BinaryenUnary(M, BinaryenWrapInt64(), sz);
 			}		
 			
-			auto sp = BinaryenGetGlobal(M, STACK_PTR, BinaryenTypeInt32());
+			auto sp = BinaryenGlobalGet(M, STACK_PTR, BinaryenTypeInt32());
 
 			if (align > 4) {
 				sp =  BinaryenBinary(M, BinaryenAndInt32(), 

          
@@ 365,7 377,7 @@ namespace K3 {
 			auto mem = TmpVar(sp);
 			
 			sp = BinaryenBinary(M, BinaryenAddInt32(), mem, sz);
-			b->instr.emplace_back(BinaryenSetGlobal(M, STACK_PTR, sp));
+			b->instr.emplace_back(BinaryenGlobalSet(M, STACK_PTR, sp));
 			return mem;
 		}
 

          
@@ 382,7 394,7 @@ namespace K3 {
 		static BinaryenExpressionRef Relocatable(BinaryenModuleRef M, BinaryenExpressionRef offset) {
 			wasm::Module *mod = (wasm::Module*)M;
 			if (auto ds = mod->getGlobalOrNull(STATIC_DATA)) {
-				return BinaryenBinary(M, BinaryenAddInt32(), offset, BinaryenGetGlobal(M, STATIC_DATA, BinaryenTypeInt32()));
+				return BinaryenBinary(M, BinaryenAddInt32(), offset, BinaryenGlobalGet(M, STATIC_DATA, BinaryenTypeInt32()));
 			}
 			return offset;
 		}

          
@@ 429,15 441,15 @@ namespace K3 {
 
 			wasm::Module *mod = (wasm::Module*)M;
 			BinaryenExpressionRef segOffset[] = {
-				mod->getGlobalOrNull(STATIC_DATA) ? BinaryenGetGlobal(M, STATIC_DATA, BinaryenTypeInt32()) : BinaryenConst(M, BinaryenLiteralInt32(0))
+				mod->getGlobalOrNull(STATIC_DATA) ? BinaryenGlobalGet(M, STATIC_DATA, BinaryenTypeInt32()) : BinaryenConst(M, BinaryenLiteralInt32(0))
 			};
 
 			BinaryenIndex segSize[] = {
 				(BinaryenIndex)dataBlob.size()
 			};
 
-			int8_t segPassive[] = {
-				0
+			bool segPassive[] = {
+				false
 			};
 
 			BinaryenSetMemory(M, (((int)dataBlob.size() + 65536) / 65536), 65535, memExportName, segData, segPassive, segOffset, segSize, 1, 0);

          
M src/backends/BinaryenModule.h +1 -1
@@ 30,7 30,7 @@ namespace K3 {
 				};
 
 				BinaryenAddFunctionImport(M, "alloca", "builtin", "alloca",
-										  BinaryenAddFunctionType(M, nullptr, BinaryenTypeInt32(), params, 2));
+					BinaryenTypeCreate(params, 2), BinaryenTypeInt32());
 			}
 
 			~BinaryenSpec() {

          
M src/backends/GenericCompiler.h +1 -1
@@ 24,7 24,7 @@ namespace K3 {
 				FunctionKey(const Graph<const Typed>& key, FunctionTyTy fty) :std::tuple<FunctionTyTy, Graph<const Typed>>(fty, key) {}
 				FunctionTyTy GetFunctionTy() const { return std::get<0>(*this); }
 				Graph<const Typed> GetGraph() const { return std::get<1>(*this); }
-				size_t GetHash() const { return GetGraph()->GetHash(true) ^ (size_t)GetFunctionTy(); }
+				size_t GetHash() const { return GetGraph()->GetHash(true) ^ std::hash<FunctionTyTy>()(GetFunctionTy()); }
 				bool operator==(const FunctionKey& rhs) const { return (CTRef)GetGraph() == (CTRef)rhs.GetGraph() && GetFunctionTy() == rhs.GetFunctionTy(); }
 			};