X86FuncNode* X86Compiler::newFunc(const FuncPrototype& p) { X86FuncNode* func = newNode<X86FuncNode>(); Error error; if (func == NULL) goto _NoMemory; // Create helper nodes. func->_entryNode = newLabelNode(); func->_exitNode = newLabelNode(); func->_end = newNode<HLSentinel>(); if (func->_entryNode == NULL || func->_exitNode == NULL || func->_end == NULL) goto _NoMemory; // Function prototype. if ((error = func->_x86Decl.setPrototype(p)) != kErrorOk) { setLastError(error); return NULL; } // Function arguments stack size. Since function requires _argStackSize to be // set, we have to copy it from X86FuncDecl. func->_argStackSize = func->_x86Decl.getArgStackSize(); func->_redZoneSize = static_cast<uint16_t>(func->_x86Decl.getRedZoneSize()); func->_spillZoneSize = static_cast<uint16_t>(func->_x86Decl.getSpillZoneSize()); // Expected/Required stack alignment. func->_expectedStackAlignment = getRuntime()->getStackAlignment(); func->_requiredStackAlignment = 0; // Allocate space for function arguments. func->_args = NULL; if (func->getNumArgs() != 0) { func->_args = _zoneAllocator.allocT<VarData*>(func->getNumArgs() * sizeof(VarData*)); if (func->_args == NULL) goto _NoMemory; ::memset(func->_args, 0, func->getNumArgs() * sizeof(VarData*)); } return func; _NoMemory: setLastError(kErrorNoHeapMemory); return NULL; }
uint32_t Compiler::_newLabelId() noexcept { HLLabel* node = newLabelNode(); if (node == nullptr) { setLastError(kErrorNoHeapMemory); return kInvalidValue; } return node->getLabelId(); }