diff --git a/src/Walrus.h b/src/Walrus.h index c304727b2..985c87bbc 100755 --- a/src/Walrus.h +++ b/src/Walrus.h @@ -343,10 +343,16 @@ if (f.type == Type::B) { puts("failed in msvc."); } static void operator delete(void*) = delete; \ static void operator delete[](void*) = delete; -#define ALLOCA(Type, Result, Bytes, Success) \ - Type* Result = (Type*)(LIKELY(Bytes < 512) ? alloca(Bytes) \ - : new char[Bytes]); \ - bool Success = LIKELY(Bytes < 512) ? true : false; +#define ALLOCA(Type, Result, Bytes) \ + std::unique_ptr Result##HolderWhenUsingMalloc; \ + size_t bytes##Result = (Bytes); \ + Type* Result; \ + if (LIKELY(bytes##Result < 512)) { \ + Result = (Type*)alloca(bytes##Result); \ + } else { \ + Result##HolderWhenUsingMalloc = std::unique_ptr(new uint8_t[bytes##Result]); \ + Result = (Type*)Result##HolderWhenUsingMalloc.get(); \ + } #if !defined(STACK_GROWS_DOWN) && !defined(STACK_GROWS_UP) #define STACK_GROWS_DOWN diff --git a/src/interpreter/Interpreter.cpp b/src/interpreter/Interpreter.cpp index 4558650d6..0e7f5e35f 100644 --- a/src/interpreter/Interpreter.cpp +++ b/src/interpreter/Interpreter.cpp @@ -1359,7 +1359,7 @@ NEVER_INLINE void Interpreter::callOperation( Function* target = instance->function(code->index()); const FunctionType* ft = target->functionType(); const ValueTypeVector& param = ft->param(); - ALLOCA(Value, paramVector, sizeof(Value) * param.size(), isAllocaParam); + ALLOCA(Value, paramVector, sizeof(Value) * param.size()); size_t c = 0; for (size_t i = 0; i < param.size(); i++) { @@ -1367,7 +1367,7 @@ NEVER_INLINE void Interpreter::callOperation( } const ValueTypeVector& result = ft->result(); - ALLOCA(Value, resultVector, sizeof(Value) * result.size(), isAllocaResult); + ALLOCA(Value, resultVector, sizeof(Value) * result.size()); size_t codeExtraOffsetsSize = sizeof(ByteCodeStackOffset) * ft->param().size() + sizeof(ByteCodeStackOffset) * ft->result().size(); target->call(state, param.size(), paramVector, resultVector); @@ -1377,13 +1377,6 @@ NEVER_INLINE void Interpreter::callOperation( resultVector[i].writeToMemory(resultStackPointer); } - if (UNLIKELY(!isAllocaParam)) { - delete[] paramVector; - } - if (UNLIKELY(!isAllocaResult)) { - delete[] resultVector; - } - programCounter += sizeof(Call) + codeExtraOffsetsSize; } @@ -1409,7 +1402,7 @@ NEVER_INLINE void Interpreter::callIndirectOperation( Trap::throwException(state, "indirect call type mismatch"); } const ValueTypeVector& param = ft->param(); - ALLOCA(Value, paramVector, sizeof(Value) * param.size(), isAllocaParam); + ALLOCA(Value, paramVector, sizeof(Value) * param.size()); size_t c = 0; for (size_t i = 0; i < param.size(); i++) { @@ -1417,7 +1410,7 @@ NEVER_INLINE void Interpreter::callIndirectOperation( } const ValueTypeVector& result = ft->result(); - ALLOCA(Value, resultVector, sizeof(Value) * result.size(), isAllocaResult); + ALLOCA(Value, resultVector, sizeof(Value) * result.size()); size_t codeExtraOffsetsSize = sizeof(ByteCodeStackOffset) * ft->param().size() + sizeof(ByteCodeStackOffset) * ft->result().size(); target->call(state, param.size(), paramVector, resultVector); @@ -1427,14 +1420,6 @@ NEVER_INLINE void Interpreter::callIndirectOperation( resultVector[i].writeToMemory(resultStackPointer); } - if (UNLIKELY(!isAllocaParam)) { - delete[] paramVector; - } - if (UNLIKELY(!isAllocaResult)) { - delete[] resultVector; - } - programCounter += sizeof(CallIndirect) + codeExtraOffsetsSize; } - } // namespace Walrus diff --git a/src/runtime/Function.cpp b/src/runtime/Function.cpp index a7c21c35b..de9a8027a 100644 --- a/src/runtime/Function.cpp +++ b/src/runtime/Function.cpp @@ -45,7 +45,7 @@ void DefinedFunction::call(ExecutionState& state, const uint32_t argc, Value* ar { ExecutionState newState(state, this); checkStackLimit(newState); - ALLOCA(uint8_t, functionStackBase, m_moduleFunction->requiredStackSize(), isAlloca); + ALLOCA(uint8_t, functionStackBase, m_moduleFunction->requiredStackSize()); uint8_t* functionStackPointer = functionStackBase; // init parameter space @@ -100,10 +100,6 @@ void DefinedFunction::call(ExecutionState& state, const uint32_t argc, Value* ar for (size_t i = 0; i < resultTypeInfo.size(); i++) { result[i] = Value(resultTypeInfo[i], functionStackBase + resultOffsets[i]); } - - if (UNLIKELY(!isAlloca)) { - delete[] functionStackBase; - } } ImportedFunction* ImportedFunction::createImportedFunction(Store* store, diff --git a/src/runtime/Module.cpp b/src/runtime/Module.cpp index 6146267cc..a3b9a0e93 100644 --- a/src/runtime/Module.cpp +++ b/src/runtime/Module.cpp @@ -226,16 +226,12 @@ Instance* Module::instantiate(ExecutionState& state, const ExternVector& imports Walrus::Trap trap; trap.run([](Walrus::ExecutionState& state, void* d) { RunData* data = reinterpret_cast(d); - ALLOCA(uint8_t, functionStackBase, data->mf->requiredStackSize(), isAlloca); + ALLOCA(uint8_t, functionStackBase, data->mf->requiredStackSize()); DefinedFunction fakeFunction(data->instance, data->mf); ExecutionState newState(state, &fakeFunction); auto resultOffset = Interpreter::interpret(newState, functionStackBase); data->instance->m_globals[data->index]->setValue(Value(data->type, functionStackBase + resultOffset[0])); - - if (UNLIKELY(!isAlloca)) { - delete[] functionStackBase; - } }, &data); } @@ -261,7 +257,7 @@ Instance* Module::instantiate(ExecutionState& state, const ExternVector& imports Walrus::Trap trap; trap.run([](Walrus::ExecutionState& state, void* d) { RunData* data = reinterpret_cast(d); - ALLOCA(uint8_t, functionStackBase, data->elem->moduleFunction()->requiredStackSize(), isAlloca); + ALLOCA(uint8_t, functionStackBase, data->elem->moduleFunction()->requiredStackSize()); DefinedFunction fakeFunction(data->instance, data->elem->moduleFunction()); @@ -270,10 +266,6 @@ Instance* Module::instantiate(ExecutionState& state, const ExternVector& imports auto resultOffset = Interpreter::interpret(newState, functionStackBase); Value offset(Value::I32, functionStackBase + resultOffset[0]); data->index = offset.asI32(); - - if (UNLIKELY(!isAlloca)) { - delete[] functionStackBase; - } }, &data); } @@ -312,7 +304,7 @@ Instance* Module::instantiate(ExecutionState& state, const ExternVector& imports auto result = trap.run([](Walrus::ExecutionState& state, void* d) { RunData* data = reinterpret_cast(d); if (data->init->moduleFunction()->currentByteCodeSize()) { - ALLOCA(uint8_t, functionStackBase, data->init->moduleFunction()->requiredStackSize(), isAlloca); + ALLOCA(uint8_t, functionStackBase, data->init->moduleFunction()->requiredStackSize()); DefinedFunction fakeFunction(data->instance, data->init->moduleFunction()); @@ -321,10 +313,6 @@ Instance* Module::instantiate(ExecutionState& state, const ExternVector& imports auto resultOffset = Interpreter::interpret(newState, functionStackBase); Value offset(Value::I32, functionStackBase + resultOffset[0]); - if (UNLIKELY(!isAlloca)) { - delete[] functionStackBase; - } - Memory* m = data->instance->memory(0); const auto& initData = data->init->initData(); if (m->sizeInByte() >= initData.size() && (offset.asI32() + initData.size()) <= m->sizeInByte() && offset.asI32() >= 0) {