Taihe ABI 内存布局文档
字符串类型
Taihe 字符串的 ABI 定义如下:
struct TString {
uint32_t flags;
uint32_t length;
char const *ptr; // always valid and non-null
};
在内存中的布局:
+-------------+--------------+---------------------------+
| flags (u32) | length (u32) | ptr (char*, always valid) |
+-------------+--------------+---------------------------+
作者侧,即下层创建 Taihe 字符串时,会创建带有引用计数的 char* 字符串 TStringData:
struct TStringData {
TRefCount count;
char buffer[];
};
在内存中的布局:
+---------------------+--------------------------+
| TRefCount count | buffer[] |
+---------------------+--------------------------+
| 字符串内容(可变长度) |
| 以 '\0' 作为结尾 |
注:下层创建的字符串 TString 的指针指向 TStringData 的 buffer。
定长数组(Array)
Taihe 数组类型的 ABI 定义如下:
struct TArray {
size_t m_size;
void *m_data;
};
在内存中的布局:
+-----------------+----------------+
| m_size (size_t) | m_data (void*) |
+-----------------+----------------+
m_data 里面存的是实际类型的指针,举例: 如果在 c++ 侧为 taihe::array<int64_t>,则 m_data 实际为 int64_t*。
optional
Taihe 可空类型的 ABI 定义如下:
struct TOptional {
void const *m_data;
};
在内存中的布局:
+----------------+
| m_data (void*) |
+----------------+
同上,m_data 里面存的是实际类型的指针。
vector
Taihe 的 vector 类型采用动态数组实现,类似于 C++ 的 std::vector。
template<typename T>
struct vector_view {
using item_t = T const;
private:
struct handle_t {
TRefCount count;
std::size_t cap;
item_t *data;
std::size_t size;
} *m_handle;
};
set
Taihe 的 set 类型采用哈希表实现,类似于 C++ 的 std::unordered_set。
template<typename K>
struct set_view {
using item_t = K const;
struct node_t {
item_t item;
node_t *next;
};
private:
struct handle_t {
TRefCount count;
std::size_t cap;
node_t **bucket;
std::size_t size;
} *m_handle;
};
在内存中的布局如下:
set_view<K>
┌─────────────────────┐
│ m_handle ───────┐ │
└───────────────────│─┘
│
handle_t
┌──────────────────────┐
│ TRefCount count │
│ std::size_t cap │
│ node_t** bucket ──────┐
│ std::size_t size │ │
└──────────────────────┘ │
│
node_t* bucket[0..cap-1]
┌───────────────┬────────────────────────────────────┐
│ bucket[0] │ node_t --> node_t --> ... --> NULL │
│ bucket[1] │ NULL │
│ ... │ ... │
│ bucket[cap-1] │ node_t --> NULL │
└───────────────┴────────────────────────────────────┘
map
Taihe 的 map 类型与 set 类型类似,采用哈希表实现,类似于 C++ 的 std::unordered_map。
template<typename K, typename V>
struct map_view {
public:
using item_t = std::pair<K const, V>;
struct node_t {
item_t item;
node_t *next;
};
private:
struct handle_t {
TRefCount count;
std::size_t cap;
node_t **bucket;
std::size_t size;
} *m_handle;
};
struct
taihe 的 struct 类型直接对应 C 中的结构体,例如以下 Taihe struct 定义:
struct Color {
R: i32;
G: i32;
B: i32;
}
在 C 中会生成如下结构体:
struct binding_Color_t {
int32_t R;
int32_t G;
int32_t B;
};
enum
以以下 Taihe enum 定义为例:
enum MessageType: i32 {
Text = 1,
Number = 2,
}
enum EnumString: String {
ONE = "hello",
TWO = "world",
THREE = "good morning"
}
C++ 侧会生成:
struct MessageType {
public:
enum class key_t: int {
Text,
Number,
};
static constexpr int32_t table[] = {
1,
2,
};
// ...
private:
key_t key;
};
struct EnumString {
public:
enum class key_t: int {
ONE,
TWO,
THREE,
};
static constexpr char const* table[] = {
"hello",
"world",
"good morning",
};
// ...
private:
key_t key;
};
在 C 侧,它们本质上都是 int。
union
以以下 Taihe union 定义为例:
union MessageData {
textVal: String;
numVal: i64;
}
在 C++ 侧会生成如下结构体:
union message_MessageData_union {
struct TString textVal;
int64_t numVal;
};
struct message_MessageData_t {
int m_tag;
union message_MessageData_union m_data;
};
Taihe union 实际内存布局即struct message_MessageData_t。
interface
函数闭包
Taihe 的 callback 的内存布局类似于 Taihe interface。
struct TCallback {
void *vtbl_ptr; // 指向函数实现
struct DataBlockHead *data_ptr; // 指向闭包数据
};