| 182 | } |
| 183 | |
| 184 | Error CodeHolder::detach(CodeEmitter* emitter) noexcept { |
| 185 | if (!emitter) |
| 186 | return DebugUtils::errored(kErrorInvalidArgument); |
| 187 | |
| 188 | if (emitter->_code != this) |
| 189 | return DebugUtils::errored(kErrorInvalidState); |
| 190 | |
| 191 | uint32_t type = emitter->getType(); |
| 192 | Error err = kErrorOk; |
| 193 | |
| 194 | // NOTE: We always detach if we were asked to, if error happens during |
| 195 | // `emitter->onDetach()` we just propagate it, but the CodeEmitter will |
| 196 | // be detached. |
| 197 | if (!emitter->_destroyed) { |
| 198 | if (type == CodeEmitter::kTypeAssembler) |
| 199 | static_cast<Assembler*>(emitter)->sync(); |
| 200 | err = emitter->onDetach(this); |
| 201 | } |
| 202 | |
| 203 | // Special case - detach `Assembler`. |
| 204 | if (type == CodeEmitter::kTypeAssembler) |
| 205 | _cgAsm = nullptr; |
| 206 | |
| 207 | // Remove from a single-linked list of `CodeEmitter`s. |
| 208 | CodeEmitter** pPrev = &_emitters; |
| 209 | for (;;) { |
| 210 | ASMJIT_ASSERT(*pPrev != nullptr); |
| 211 | CodeEmitter* cur = *pPrev; |
| 212 | |
| 213 | if (cur == emitter) { |
| 214 | *pPrev = emitter->_nextEmitter; |
| 215 | break; |
| 216 | } |
| 217 | |
| 218 | pPrev = &cur->_nextEmitter; |
| 219 | } |
| 220 | |
| 221 | emitter->_code = nullptr; |
| 222 | emitter->_nextEmitter = nullptr; |
| 223 | |
| 224 | return err; |
| 225 | } |
| 226 | |
| 227 | // ============================================================================ |
| 228 | // [asmjit::CodeHolder - Sync] |
no test coverage detected