static ASMJIT_INLINE void CodeBuilder_nodeRemoved(CodeBuilder* self, CBNode* node_) noexcept { if (node_->isJmpOrJcc()) { CBJump* node = static_cast<CBJump*>(node_); CBLabel* label = node->getTarget(); if (label) { // Disconnect. CBJump** pPrev = &label->_from; for (;;) { ASMJIT_ASSERT(*pPrev != nullptr); CBJump* current = *pPrev; if (!current) break; if (current == node) { *pPrev = node->_jumpNext; break; } pPrev = ¤t->_jumpNext; } label->subNumRefs(); } } }
Label CodeBuilder::newLabel() { uint32_t id = kInvalidValue; if (!_lastError) { CBLabel* node = newNodeT<CBLabel>(id); if (ASMJIT_UNLIKELY(!node)) { setLastError(DebugUtils::errored(kErrorNoHeapMemory)); } else { Error err = registerLabelNode(node); if (ASMJIT_UNLIKELY(err)) setLastError(err); else id = node->getId(); } } return Label(id); }
Label CodeBuilder::newNamedLabel(const char* name, size_t nameLength, uint32_t type, uint32_t parentId) { uint32_t id = kInvalidValue; if (!_lastError) { CBLabel* node = newNodeT<CBLabel>(id); if (ASMJIT_UNLIKELY(!node)) { setLastError(DebugUtils::errored(kErrorNoHeapMemory)); } else { Error err = _code->newNamedLabelId(id, name, nameLength, type, parentId); if (ASMJIT_UNLIKELY(err)) setLastError(err); else id = node->getId(); } } return Label(id); }
Error CodeBuilder::serialize(CodeEmitter* dst) { Error err = kErrorOk; CBNode* node_ = getFirstNode(); do { dst->setInlineComment(node_->getInlineComment()); switch (node_->getType()) { case CBNode::kNodeAlign: { CBAlign* node = static_cast<CBAlign*>(node_); err = dst->align(node->getMode(), node->getAlignment()); break; } case CBNode::kNodeData: { CBData* node = static_cast<CBData*>(node_); err = dst->embed(node->getData(), node->getSize()); break; } case CBNode::kNodeFunc: case CBNode::kNodeLabel: { CBLabel* node = static_cast<CBLabel*>(node_); err = dst->bind(node->getLabel()); break; } case CBNode::kNodeLabelData: { CBLabelData* node = static_cast<CBLabelData*>(node_); err = dst->embedLabel(node->getLabel()); break; } case CBNode::kNodeConstPool: { CBConstPool* node = static_cast<CBConstPool*>(node_); err = dst->embedConstPool(node->getLabel(), node->getConstPool()); break; } case CBNode::kNodeInst: case CBNode::kNodeFuncCall: { CBInst* node = static_cast<CBInst*>(node_); uint32_t instId = node->getInstId(); uint32_t options = node->getOptions(); const Operand* opArray = node->getOpArray(); uint32_t opCount = node->getOpCount(); const Operand_* o0 = &dst->_none; const Operand_* o1 = &dst->_none; const Operand_* o2 = &dst->_none; const Operand_* o3 = &dst->_none; switch (opCount) { case 6: dst->_op5 = opArray[5]; options |= CodeEmitter::kOptionOp5; ASMJIT_FALLTHROUGH; case 5: dst->_op4 = opArray[4]; options |= CodeEmitter::kOptionOp4; ASMJIT_FALLTHROUGH; case 4: o3 = &opArray[3]; ASMJIT_FALLTHROUGH; case 3: o2 = &opArray[2]; ASMJIT_FALLTHROUGH; case 2: o1 = &opArray[1]; ASMJIT_FALLTHROUGH; case 1: o0 = &opArray[0]; ASMJIT_FALLTHROUGH; case 0: break; } dst->setOptions(options); err = dst->_emit(instId, *o0, *o1, *o2, *o3); break; } case CBNode::kNodeComment: { CBComment* node = static_cast<CBComment*>(node_); err = dst->comment(node->getInlineComment()); break; } default: break; } if (err) break; node_ = node_->getNext(); } while (node_); return err; }
Error CodeBuilder::serialize(CodeEmitter* dst) { Error err = kErrorOk; CBNode* node_ = getFirstNode(); do { dst->setInlineComment(node_->getInlineComment()); switch (node_->getType()) { case CBNode::kNodeAlign: { CBAlign* node = static_cast<CBAlign*>(node_); err = dst->align(node->getMode(), node->getAlignment()); break; } case CBNode::kNodeData: { CBData* node = static_cast<CBData*>(node_); err = dst->embed(node->getData(), node->getSize()); break; } case CBNode::kNodeFunc: case CBNode::kNodeLabel: { CBLabel* node = static_cast<CBLabel*>(node_); err = dst->bind(node->getLabel()); break; } case CBNode::kNodeLabelData: { CBLabelData* node = static_cast<CBLabelData*>(node_); err = dst->embedLabel(node->getLabel()); break; } case CBNode::kNodeConstPool: { CBConstPool* node = static_cast<CBConstPool*>(node_); err = dst->embedConstPool(node->getLabel(), node->getConstPool()); break; } case CBNode::kNodeInst: case CBNode::kNodeFuncCall: { CBInst* node = node_->as<CBInst>(); dst->setOptions(node->getOptions()); dst->setExtraReg(node->getExtraReg()); err = dst->emitOpArray(node->getInstId(), node->getOpArray(), node->getOpCount()); break; } case CBNode::kNodeComment: { CBComment* node = static_cast<CBComment*>(node_); err = dst->comment(node->getInlineComment()); break; } default: break; } if (err) break; node_ = node_->getNext(); } while (node_); return err; }