Example #1
0
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 = &current->_jumpNext;
      }

      label->subNumRefs();
    }
  }
}
Example #2
0
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);
}
Example #3
0
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);
}
Example #4
0
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;
}
Example #5
0
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;
}