統一TypeBox ABIの最終形:ユーザー定義BoxもC ABIプラグインとして扱える!
// ユーザーBoxもプラグインとして動的登録
NyashTypeBox* register_user_box(const char* name,
NyashBoxMethods* methods) {
// ユーザーBoxに一時的なtype_idを割り当て
// メソッドテーブルを登録
// → プラグインと同じように扱える
}
typedef struct NyashTypeBox {
// === ヘッダー情報 ===
uint32_t abi_tag; // 'TYBX'
uint16_t version; // 2 (ユーザーBox対応)
uint16_t flags; // HOST_MANAGED | THREAD_SAFE等
// === 型情報 ===
uint32_t type_id; // 動的割り当て(高ビットで区別)
const char* name; // "UserDefinedBox"
// === 基本操作 ===
void* (*create)(void* args);
void (*destroy)(void* self);
void (*retain)(void* self); // 参照カウント増加
void (*release)(void* self); // 参照カウント減少
// === メソッドディスパッチ ===
uint32_t (*resolve)(const char* name);
NyResult (*invoke_id)(void* self, uint32_t method_id,
NyValue* args, int argc);
// === メタ情報(オプション)===
size_t instance_size; // インスタンスサイズ
void* metadata; // 追加メタデータ
} NyashTypeBox;
// 高ビットでホスト/プラグイン区別
#define HOST_TYPE_FLAG 0x80000000
#define PLUGIN_TYPE_FLAG 0x40000000
#define BUILTIN_TYPE_FLAG 0x00000000
// 例
uint32_t user_box_id = HOST_TYPE_FLAG | 0x00001234;
uint32_t plugin_box_id = PLUGIN_TYPE_FLAG | 0x00005678;
uint32_t builtin_box_id = BUILTIN_TYPE_FLAG | 0x00000001;
typedef struct {
atomic_uint ref_count; // アトミック参照カウント
uint32_t finalizer_id; // クリーンアップ用ID
void (*destroy)(void*); // デストラクタ
} NyashBoxHeader;
// すべてのBoxインスタンスの先頭に配置
typedef struct {
NyashBoxHeader header;
// ... Box固有のデータ
} UserBoxInstance;
// Nyashでユーザー定義Box
box Person {
init { name, age }
greet() {
return "Hello, I'm " + me.name
}
}
// 内部で自動的に以下が実行される:
// 1. Personボックスのメソッドテーブル生成
// 2. register_user_box("Person", methods)でC ABIに登録
// 3. type_id割り当て(例: 0x80001234)
// 4. プラグインから呼び出し可能に!
// プラグイン側でユーザーBoxを受け取る
NyResult process_person(void* self, uint32_t method_id,
NyValue* args, int argc) {
// args[0]がPersonBoxのhandle
if (args[0].type_tag == TAG_HANDLE) {
uint32_t type_id = extract_type_id(args[0]);
uint32_t instance_id = extract_instance_id(args[0]);
// ホストに問い合わせてメソッド呼び出し
NyValue result = ny_host_invoke(type_id, instance_id,
"greet", NULL, 0);
// 結果を処理
return ny_result_ok(result);
}
}
if (is_trusted_source(box_source)) {
// 直接登録(高速パス)
register_user_box_direct(name, methods);
} else {
// Wasmサンドボックス内で実行
register_user_box_sandboxed(name, methods);
}
bool validate_method_pointer(void* ptr) {
// 実行可能メモリ領域をチェック
return is_executable_memory(ptr);
}
#define CAP_FILE_ACCESS (1 << 0)
#define CAP_NET_ACCESS (1 << 1)
#define CAP_SPAWN_THREAD (1 << 2)
// 登録時に権限を指定
register_user_box_with_caps(name, methods,
CAP_FILE_ACCESS);
ネイティブメソッド呼び出し : 1ns
プラグイン内メソッド呼び出し : 15ns
ユーザーBox(同一プロセス) : 20ns
ユーザーBox(Wasmサンドボックス): 100ns
register_user_box
APIの実装この実装により:
「Everything is Box」哲学が、言語の境界を越えて完全に実現されます!