| 103 | // ============================================================================ |
| 104 | |
| 105 | CCFunc* CodeCompiler::newFunc(const FuncSignature& sign) noexcept { |
| 106 | Error err; |
| 107 | |
| 108 | CCFunc* func = newNodeT<CCFunc>(); |
| 109 | if (!func) goto _NoMemory; |
| 110 | |
| 111 | err = registerLabelNode(func); |
| 112 | if (ASMJIT_UNLIKELY(err)) { |
| 113 | // TODO: Calls setLastError, maybe rethink noexcept? |
| 114 | setLastError(err); |
| 115 | return nullptr; |
| 116 | } |
| 117 | |
| 118 | // Create helper nodes. |
| 119 | func->_exitNode = newLabelNode(); |
| 120 | func->_end = newNodeT<CBSentinel>(); |
| 121 | |
| 122 | if (!func->_exitNode || !func->_end) |
| 123 | goto _NoMemory; |
| 124 | |
| 125 | // Function prototype. |
| 126 | err = func->getDetail().init(sign); |
| 127 | if (err != kErrorOk) { |
| 128 | setLastError(err); |
| 129 | return nullptr; |
| 130 | } |
| 131 | |
| 132 | // If the CodeInfo guarantees higher alignment honor it. |
| 133 | if (_codeInfo.getStackAlignment() > func->_funcDetail._callConv.getNaturalStackAlignment()) |
| 134 | func->_funcDetail._callConv.setNaturalStackAlignment(_codeInfo.getStackAlignment()); |
| 135 | |
| 136 | // Allocate space for function arguments. |
| 137 | func->_args = nullptr; |
| 138 | if (func->getArgCount() != 0) { |
| 139 | func->_args = _cbHeap.allocT<VirtReg*>(func->getArgCount() * sizeof(VirtReg*)); |
| 140 | if (!func->_args) goto _NoMemory; |
| 141 | |
| 142 | ::memset(func->_args, 0, func->getArgCount() * sizeof(VirtReg*)); |
| 143 | } |
| 144 | |
| 145 | return func; |
| 146 | |
| 147 | _NoMemory: |
| 148 | setLastError(DebugUtils::errored(kErrorNoHeapMemory)); |
| 149 | return nullptr; |
| 150 | } |
| 151 | |
| 152 | CCFunc* CodeCompiler::addFunc(CCFunc* func) { |
| 153 | ASMJIT_ASSERT(_func == nullptr); |
nothing calls this directly
no test coverage detected