diff options
Diffstat (limited to 'src/abi/stack.h')
-rw-r--r-- | src/abi/stack.h | 144 |
1 files changed, 0 insertions, 144 deletions
diff --git a/src/abi/stack.h b/src/abi/stack.h deleted file mode 100644 index e217d7caa..000000000 --- a/src/abi/stack.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright 2017 WebAssembly Community Group participants - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef wasm_abi_stack_h -#define wasm_abi_stack_h - -#include "abi.h" -#include "asmjs/shared-constants.h" -#include "ir/find_all.h" -#include "ir/global-utils.h" -#include "shared-constants.h" -#include "wasm-builder.h" -#include "wasm.h" - -namespace wasm { - -namespace ABI { - -enum { StackAlign = 16 }; - -inline Index stackAlign(Index size) { - return (size + StackAlign - 1) & -StackAlign; -} - -// Allocate some space on the stack, and assign it to a local. -// The local will have the same constant value in all the function, so you can -// just local.get it anywhere there. -// -// FIXME: This function assumes that the stack grows upward, per the convention -// used by fastcomp. The stack grows downward when using the WASM backend. - -inline void -getStackSpace(Index local, Function* func, Index size, Module& wasm) { - // Attempt to locate the stack pointer by recognizing code idioms - // used by Emscripten. First, look for a global initialized to an - // imported variable named "STACKTOP" in environment "env". - auto* stackPointer = - GlobalUtils::getGlobalInitializedToImport(wasm, ENV, "STACKTOP"); - // Starting with Emscripten 1.38.24, the stack pointer variable is - // initialized with a literal constant, eliminating the import that - // we used to locate the stack pointer by name. We must match a more - // complicated idiom, expecting to see the module structured as follows: - // - //(module - // ... - // (export "stackSave" (func $stackSave)) - // ... - // (func $stackSave (; 410 ;) (; has Stack IR ;) (result i32) - // (global.get $STACKTOP) - // ) - // ... - //) - if (!stackPointer) { - auto* stackSaveFunctionExport = wasm.getExportOrNull("stackSave"); - if (stackSaveFunctionExport && - stackSaveFunctionExport->kind == ExternalKind::Function) { - auto* stackSaveFunction = - wasm.getFunction(stackSaveFunctionExport->value); - assert(!stackSaveFunction->imported()); - auto* globalGet = stackSaveFunction->body->dynCast<GlobalGet>(); - if (globalGet) { - stackPointer = wasm.getGlobal(globalGet->name); - } - } - } - if (!stackPointer) { - Fatal() << "getStackSpace: failed to find the stack pointer"; - } - // align the size - size = stackAlign(size); - // TODO: find existing stack usage, and add on top of that - carefully - Builder builder(wasm); - auto* block = builder.makeBlock(); - block->list.push_back(builder.makeLocalSet( - local, builder.makeGlobalGet(stackPointer->name, PointerType))); - // TODO: add stack max check - Expression* added; - if (PointerType == Type::i32) { - added = builder.makeBinary(AddInt32, - builder.makeLocalGet(local, PointerType), - builder.makeConst(int32_t(size))); - } else { - WASM_UNREACHABLE("unhandled PointerType"); - } - block->list.push_back(builder.makeGlobalSet(stackPointer->name, added)); - auto makeStackRestore = [&]() { - return builder.makeGlobalSet(stackPointer->name, - builder.makeLocalGet(local, PointerType)); - }; - // add stack restores to the returns - FindAllPointers<Return> finder(func->body); - for (auto** ptr : finder.list) { - auto* ret = (*ptr)->cast<Return>(); - if (ret->value && ret->value->type != Type::unreachable) { - // handle the returned value - auto* block = builder.makeBlock(); - auto temp = builder.addVar(func, ret->value->type); - block->list.push_back(builder.makeLocalSet(temp, ret->value)); - block->list.push_back(makeStackRestore()); - block->list.push_back( - builder.makeReturn(builder.makeLocalGet(temp, ret->value->type))); - block->finalize(); - *ptr = block; - } else { - // restore, then return - *ptr = builder.makeSequence(makeStackRestore(), ret); - } - } - // add stack restores to the body - if (func->body->type == Type::none) { - block->list.push_back(func->body); - block->list.push_back(makeStackRestore()); - } else if (func->body->type == Type::unreachable) { - block->list.push_back(func->body); - // no need to restore the old stack value, we're gone anyhow - } else { - // save the return value - auto temp = builder.addVar(func, func->sig.results); - block->list.push_back(builder.makeLocalSet(temp, func->body)); - block->list.push_back(makeStackRestore()); - block->list.push_back(builder.makeLocalGet(temp, func->sig.results)); - } - block->finalize(); - func->body = block; -} - -} // namespace ABI - -} // namespace wasm - -#endif // wasm_abi_stack_h |