Label::getAddress() returns 0 if ready() is not called and in AutoGrow mode
diff --git a/readme.md b/readme.md
index d945615..f99de64 100644
--- a/readme.md
+++ b/readme.md
@@ -1,5 +1,5 @@
-Xbyak 5.34 ; JIT assembler for x86(IA32), x64(AMD64, x86-64) by C++
+Xbyak 5.40 ; JIT assembler for x86(IA32), x64(AMD64, x86-64) by C++
=============
Abstract
@@ -220,6 +220,15 @@
* srcLabel must be used in L().
* dstLabel must not be used in L().
+Label::getAddress() returns the address specified by the label instance and 0 if not specified.
+```
+// not AutoGrow mode
+Label label;
+assert(label.getAddress() == 0);
+L(label);
+assert(label.getAddress() == getCurr());
+```
+
### Rip
```
Label label;
@@ -323,6 +332,7 @@
History
-------------
+* 2016/Dec/14 ver 5.40 add Label::getAddress() method to get the pointer specified by the label
* 2016/Dec/09 ver 5.34 fix handling of negative offsets when encoding disp8N(thanks to rsdubtso)
* 2016/Dec/08 ver 5.33 fix encoding of vpbroadcast{b,w,d,q}, vpinsr{b,w}, vpextr{b,w} for disp8N
* 2016/Dec/01 ver 5.32 rename __xgetbv() to _xgetbv() to support clang for Visual Studio(thanks to freiro)
diff --git a/readme.txt b/readme.txt
index c2f8f4c..b5b87aa 100644
--- a/readme.txt
+++ b/readme.txt
@@ -1,5 +1,5 @@
- C++用x86(IA-32), x64(AMD64, x86-64) JITアセンブラ Xbyak 5.34
+ C++用x86(IA-32), x64(AMD64, x86-64) JITアセンブラ Xbyak 5.40
-----------------------------------------------------------------------------
◎概要
@@ -258,6 +258,16 @@
* srcLabelはL()により飛び先が確定していないといけません。
* dstLabelはL()により飛び先が確定していてはいけません。
+ラベルは`getAddress()`によりそのアドレスを取得できます。
+未定義のときは0が返ります。
+```
+// not AutoGrow mode
+Label label;
+assert(label.getAddress(), 0);
+L(label);
+assert(label.getAddress(), getCurr());
+```
+
・Xbyak::CodeGenerator()コンストラクタインタフェース
@param maxSize [in] コード生成最大サイズ(デフォルト4096byte)
@@ -333,6 +343,7 @@
-----------------------------------------------------------------------------
◎履歴
+2016/12/14 ver 5.40 Labelが示すアドレスを取得するLabel::getAddress()追加
2016/12/07 ver 5.34 disp8N時の負のオフセット処理の修正(thanks to rsdubtso)
2016/12/06 ver 5.33 disp8N時のvpbroadcast{b,w,d,q}, vpinsr{b,w}, vpextr{b,w}のバグ修正
2016/12/01 ver 5.32 clang for Visual Studioサポートのために__xgetbv()を_xgetbv()に変更(thanks to freiro)
diff --git a/test/jmp.cpp b/test/jmp.cpp
index 338aae3..eb2c9c7 100644
--- a/test/jmp.cpp
+++ b/test/jmp.cpp
@@ -1001,15 +1001,28 @@
, a1(0)
, a3(0)
{
+ bool autoGrow = size != 4096;
nop();
L(L1);
+ if (autoGrow) {
+ CYBOZU_TEST_EQUAL_POINTER(L1.getAddress(), 0);
+ }
a1 = getSize();
nop();
jmp(L2);
+ if (autoGrow) {
+ CYBOZU_TEST_EQUAL_POINTER(L2.getAddress(), 0);
+ }
L(L3);
a3 = getSize();
+ if (autoGrow) {
+ CYBOZU_TEST_EQUAL_POINTER(L3.getAddress(), 0);
+ }
nop();
assignL(L2, L1);
+ if (autoGrow) {
+ CYBOZU_TEST_EQUAL_POINTER(L2.getAddress(), 0);
+ }
}
};
diff --git a/xbyak/xbyak.h b/xbyak/xbyak.h
index 9f72c78..4b10626 100644
--- a/xbyak/xbyak.h
+++ b/xbyak/xbyak.h
@@ -105,7 +105,7 @@
enum {
DEFAULT_MAX_CODE_SIZE = 4096,
- VERSION = 0x5340 /* 0xABCD = A.BC(D) */
+ VERSION = 0x5400 /* 0xABCD = A.BC(D) */
};
#ifndef MIE_INTEGER_TYPE_DEFINED
@@ -786,6 +786,7 @@
size_t maxSize_;
uint8 *top_;
size_t size_;
+ bool isCalledCalcJmpAddress_;
/*
allocate new memory and copy old data to the new area
@@ -805,11 +806,13 @@
*/
void calcJmpAddress()
{
+ if (isCalledCalcJmpAddress_) return;
for (AddrInfoList::const_iterator i = addrInfoList_.begin(), ie = addrInfoList_.end(); i != ie; ++i) {
uint64 disp = i->getVal(top_);
rewrite(i->codeOffset, disp, i->jmpSize);
}
if (alloc_->useProtect() && !protect(top_, size_, true)) throw Error(ERR_CANT_PROTECT);
+ isCalledCalcJmpAddress_ = true;
}
public:
explicit CodeArray(size_t maxSize, void *userPtr = 0, Allocator *allocator = 0)
@@ -818,6 +821,7 @@
, maxSize_(maxSize)
, top_(type_ == USER_BUF ? reinterpret_cast<uint8*>(userPtr) : alloc_->alloc((std::max<size_t>)(maxSize, 1)))
, size_(0)
+ , isCalledCalcJmpAddress_(false)
{
if (maxSize_ > 0 && top_ == 0) throw Error(ERR_CANT_ALLOC);
if ((type_ == ALLOC_BUF && alloc_->useProtect()) && !protect(top_, maxSize, true)) {
@@ -913,6 +917,7 @@
addrInfoList_.push_back(AddrInfo(offset, val, size, mode));
}
bool isAutoGrow() const { return type_ == AUTO_GROW; }
+ bool isCalledCalcJmpAddress() const { return isCalledCalcJmpAddress_; }
/**
change exec permission of memory
@param addr [in] buffer address
@@ -1258,6 +1263,7 @@
}
bool hasUndefClabel() const { return hasUndefinedLabel_inner(clabelUndefList_); }
const uint8 *getCode() const { return base_->getCode(); }
+ bool isReady() const { return !base_->isAutoGrow() || base_->isCalledCalcJmpAddress(); }
};
inline Label::Label(const Label& rhs)
@@ -1280,7 +1286,7 @@
}
inline const uint8* Label::getAddress() const
{
- if (mgr == 0) return 0;
+ if (mgr == 0 || !mgr->isReady()) return 0;
size_t offset;
if (!mgr->getOffset(&offset, *this)) return 0;
return mgr->getCode() + offset;