refactor: 大規模ファイル分割とプラグインリファクタリング
## 🎯 プラグイン整理 - ✅ **nyash-json-plugin**: プロバイダー抽象化、NodeRep統一 - ✅ **nyash-string-plugin**: TLVヘルパー整理 - ✅ **nyash-net-plugin**: HTTPヘルパー分離、ソケット管理改善 - ✅ **nyash-counter-plugin/fixture-plugin**: 基本構造整理 ## 📂 mir_interpreter分割 - ✅ **mir_interpreter.rs → mir_interpreter/ディレクトリ** - mod.rs: メイン構造体定義 - execution.rs: 実行エンジン - memory.rs: メモリ管理 - instructions/: 命令別実装 ## 🔧 その他の改善 - テストファイル群の最適化 - LLVMコンパイラのメイン関数整理 - 不要なインポート削除 1000行超のファイルを適切なモジュール構造に分割完了! 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@ -143,7 +143,9 @@ unsafe impl Sync for NyashTypeBoxFfi {}
|
||||
|
||||
extern "C" fn counter_resolve(name: *const std::os::raw::c_char) -> u32 {
|
||||
unsafe {
|
||||
if name.is_null() { return 0; }
|
||||
if name.is_null() {
|
||||
return 0;
|
||||
}
|
||||
let s = std::ffi::CStr::from_ptr(name).to_string_lossy();
|
||||
match s.as_ref() {
|
||||
"birth" => METHOD_BIRTH,
|
||||
@ -167,34 +169,53 @@ extern "C" fn counter_invoke(
|
||||
match method_id {
|
||||
METHOD_BIRTH => {
|
||||
// Return new instance handle (u32 id) as raw 4 bytes (not TLV)
|
||||
if result_len.is_null() { return NYB_E_INVALID_ARGS; }
|
||||
if preflight(result, result_len, 4) { return NYB_E_SHORT_BUFFER; }
|
||||
if result_len.is_null() {
|
||||
return NYB_E_INVALID_ARGS;
|
||||
}
|
||||
if preflight(result, result_len, 4) {
|
||||
return NYB_E_SHORT_BUFFER;
|
||||
}
|
||||
let id = INSTANCE_COUNTER.fetch_add(1, Ordering::Relaxed);
|
||||
if let Ok(mut map) = INSTANCES.lock() {
|
||||
map.insert(id, CounterInstance { count: 0 });
|
||||
} else { return NYB_E_PLUGIN_ERROR; }
|
||||
} else {
|
||||
return NYB_E_PLUGIN_ERROR;
|
||||
}
|
||||
let bytes = id.to_le_bytes();
|
||||
std::ptr::copy_nonoverlapping(bytes.as_ptr(), result, 4);
|
||||
*result_len = 4;
|
||||
NYB_SUCCESS
|
||||
}
|
||||
METHOD_FINI => {
|
||||
if let Ok(mut map) = INSTANCES.lock() { map.remove(&instance_id); NYB_SUCCESS } else { NYB_E_PLUGIN_ERROR }
|
||||
if let Ok(mut map) = INSTANCES.lock() {
|
||||
map.remove(&instance_id);
|
||||
NYB_SUCCESS
|
||||
} else {
|
||||
NYB_E_PLUGIN_ERROR
|
||||
}
|
||||
}
|
||||
METHOD_INC => {
|
||||
if let Ok(mut map) = INSTANCES.lock() {
|
||||
if let Some(inst) = map.get_mut(&instance_id) {
|
||||
inst.count += 1;
|
||||
return write_tlv_i32(inst.count, result, result_len);
|
||||
} else { return NYB_E_INVALID_HANDLE; }
|
||||
} else { return NYB_E_PLUGIN_ERROR; }
|
||||
} else {
|
||||
return NYB_E_INVALID_HANDLE;
|
||||
}
|
||||
} else {
|
||||
return NYB_E_PLUGIN_ERROR;
|
||||
}
|
||||
}
|
||||
METHOD_GET => {
|
||||
if let Ok(map) = INSTANCES.lock() {
|
||||
if let Some(inst) = map.get(&instance_id) {
|
||||
return write_tlv_i32(inst.count, result, result_len);
|
||||
} else { return NYB_E_INVALID_HANDLE; }
|
||||
} else { return NYB_E_PLUGIN_ERROR; }
|
||||
} else {
|
||||
return NYB_E_INVALID_HANDLE;
|
||||
}
|
||||
} else {
|
||||
return NYB_E_PLUGIN_ERROR;
|
||||
}
|
||||
}
|
||||
_ => NYB_E_INVALID_METHOD,
|
||||
}
|
||||
|
||||
@ -2,7 +2,10 @@
|
||||
|
||||
use once_cell::sync::Lazy;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::{atomic::{AtomicU32, Ordering}, Mutex};
|
||||
use std::sync::{
|
||||
atomic::{AtomicU32, Ordering},
|
||||
Mutex,
|
||||
};
|
||||
|
||||
// ===== Error Codes (BID-1 alignment) =====
|
||||
const NYB_SUCCESS: i32 = 0;
|
||||
@ -42,7 +45,9 @@ pub extern "C" fn nyash_plugin_invoke(
|
||||
result: *mut u8,
|
||||
result_len: *mut usize,
|
||||
) -> i32 {
|
||||
if type_id != TYPE_ID_FIXTURE { return NYB_E_INVALID_TYPE; }
|
||||
if type_id != TYPE_ID_FIXTURE {
|
||||
return NYB_E_INVALID_TYPE;
|
||||
}
|
||||
unsafe { dispatch(method_id, instance_id, args, args_len, result, result_len) }
|
||||
}
|
||||
|
||||
@ -72,7 +77,9 @@ unsafe impl Sync for NyashTypeBoxFfi {}
|
||||
|
||||
extern "C" fn fixture_resolve(name: *const std::os::raw::c_char) -> u32 {
|
||||
unsafe {
|
||||
if name.is_null() { return 0; }
|
||||
if name.is_null() {
|
||||
return 0;
|
||||
}
|
||||
let s = std::ffi::CStr::from_ptr(name).to_string_lossy();
|
||||
match s.as_ref() {
|
||||
"birth" => METHOD_BIRTH,
|
||||
@ -125,12 +132,18 @@ unsafe fn dispatch(
|
||||
}
|
||||
|
||||
unsafe fn birth(result: *mut u8, result_len: *mut usize) -> i32 {
|
||||
if result_len.is_null() { return NYB_E_INVALID_ARGS; }
|
||||
if preflight(result, result_len, 4) { return NYB_E_SHORT_BUFFER; }
|
||||
if result_len.is_null() {
|
||||
return NYB_E_INVALID_ARGS;
|
||||
}
|
||||
if preflight(result, result_len, 4) {
|
||||
return NYB_E_SHORT_BUFFER;
|
||||
}
|
||||
let id = INSTANCE_COUNTER.fetch_add(1, Ordering::Relaxed);
|
||||
if let Ok(mut map) = INSTANCES.lock() {
|
||||
map.insert(id, FixtureInstance { alive: true });
|
||||
} else { return NYB_E_PLUGIN_ERROR; }
|
||||
} else {
|
||||
return NYB_E_PLUGIN_ERROR;
|
||||
}
|
||||
let bytes = id.to_le_bytes();
|
||||
std::ptr::copy_nonoverlapping(bytes.as_ptr(), result, 4);
|
||||
*result_len = 4;
|
||||
@ -141,33 +154,43 @@ unsafe fn fini(instance_id: u32) -> i32 {
|
||||
if let Ok(mut map) = INSTANCES.lock() {
|
||||
map.remove(&instance_id);
|
||||
NYB_SUCCESS
|
||||
} else { NYB_E_PLUGIN_ERROR }
|
||||
} else {
|
||||
NYB_E_PLUGIN_ERROR
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn echo(
|
||||
args: *const u8,
|
||||
args_len: usize,
|
||||
result: *mut u8,
|
||||
result_len: *mut usize,
|
||||
) -> i32 {
|
||||
unsafe fn echo(args: *const u8, args_len: usize, result: *mut u8, result_len: *mut usize) -> i32 {
|
||||
// Expect TLV with 1 argument: tag=6 (String)
|
||||
if args.is_null() || args_len < 4 { return NYB_E_INVALID_ARGS; }
|
||||
if args.is_null() || args_len < 4 {
|
||||
return NYB_E_INVALID_ARGS;
|
||||
}
|
||||
let slice = std::slice::from_raw_parts(args, args_len);
|
||||
// Minimal TLV parse: skip header (ver/argc) and verify first entry is String
|
||||
if slice.len() < 8 { return NYB_E_INVALID_ARGS; }
|
||||
if slice.len() < 8 {
|
||||
return NYB_E_INVALID_ARGS;
|
||||
}
|
||||
if slice[0] != 1 || slice[1] != 0 { /* ver=1 little endian */ }
|
||||
// position 4.. is first entry; [tag, rsv, sz_lo, sz_hi, payload...]
|
||||
let tag = slice[4];
|
||||
if tag != 6 { return NYB_E_INVALID_ARGS; }
|
||||
if tag != 6 {
|
||||
return NYB_E_INVALID_ARGS;
|
||||
}
|
||||
let sz = u16::from_le_bytes([slice[6], slice[7]]) as usize;
|
||||
if 8 + sz > slice.len() { return NYB_E_INVALID_ARGS; }
|
||||
if 8 + sz > slice.len() {
|
||||
return NYB_E_INVALID_ARGS;
|
||||
}
|
||||
let payload = &slice[8..8 + sz];
|
||||
let s = match std::str::from_utf8(payload) { Ok(t) => t, Err(_) => return NYB_E_INVALID_ARGS };
|
||||
let s = match std::str::from_utf8(payload) {
|
||||
Ok(t) => t,
|
||||
Err(_) => return NYB_E_INVALID_ARGS,
|
||||
};
|
||||
write_tlv_str(s, result, result_len)
|
||||
}
|
||||
|
||||
fn write_tlv_result(payloads: &[(u8, &[u8])], result: *mut u8, result_len: *mut usize) -> i32 {
|
||||
if result_len.is_null() { return NYB_E_INVALID_ARGS; }
|
||||
if result_len.is_null() {
|
||||
return NYB_E_INVALID_ARGS;
|
||||
}
|
||||
let needed = 4 + payloads.iter().map(|(_, p)| 4 + p.len()).sum::<usize>();
|
||||
let mut buf: Vec<u8> = Vec::with_capacity(needed);
|
||||
buf.extend_from_slice(&1u16.to_le_bytes()); // ver
|
||||
@ -195,7 +218,9 @@ fn write_tlv_str(s: &str, result: *mut u8, result_len: *mut usize) -> i32 {
|
||||
|
||||
fn preflight(result: *mut u8, result_len: *mut usize, needed: usize) -> bool {
|
||||
unsafe {
|
||||
if result_len.is_null() { return false; }
|
||||
if result_len.is_null() {
|
||||
return false;
|
||||
}
|
||||
if result.is_null() || *result_len < needed {
|
||||
*result_len = needed;
|
||||
return true;
|
||||
@ -203,4 +228,3 @@ fn preflight(result: *mut u8, result_len: *mut usize, needed: usize) -> bool {
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
|
||||
@ -51,8 +51,8 @@ enum NodeRep {
|
||||
}
|
||||
|
||||
struct DocInst {
|
||||
root: Option<Arc<Value>>, // Serde provider
|
||||
doc_ptr: Option<usize>, // Yyjson provider (opaque pointer value)
|
||||
root: Option<Arc<Value>>, // Serde provider
|
||||
doc_ptr: Option<usize>, // Yyjson provider (opaque pointer value)
|
||||
last_err: Option<String>,
|
||||
}
|
||||
static DOCS: Lazy<Mutex<HashMap<u32, DocInst>>> = Lazy::new(|| Mutex::new(HashMap::new()));
|
||||
@ -150,7 +150,14 @@ extern "C" fn jsondoc_invoke_id(
|
||||
JD_BIRTH => {
|
||||
let id = NEXT_ID.fetch_add(1, Ordering::Relaxed);
|
||||
if let Ok(mut m) = DOCS.lock() {
|
||||
m.insert(id, DocInst { root: None, doc_ptr: None, last_err: None });
|
||||
m.insert(
|
||||
id,
|
||||
DocInst {
|
||||
root: None,
|
||||
doc_ptr: None,
|
||||
last_err: None,
|
||||
},
|
||||
);
|
||||
} else {
|
||||
return E_PLUGIN;
|
||||
}
|
||||
@ -166,19 +173,32 @@ extern "C" fn jsondoc_invoke_id(
|
||||
match provider_kind() {
|
||||
ProviderKind::Serde => {
|
||||
match provider_parse(&text) {
|
||||
Ok(v) => { doc.root = Some(Arc::new(v)); doc.doc_ptr = None; doc.last_err = None; }
|
||||
Err(e) => { doc.root = None; doc.doc_ptr = None; doc.last_err = Some(e.to_string()); }
|
||||
Ok(v) => {
|
||||
doc.root = Some(Arc::new(v));
|
||||
doc.doc_ptr = None;
|
||||
doc.last_err = None;
|
||||
}
|
||||
Err(e) => {
|
||||
doc.root = None;
|
||||
doc.doc_ptr = None;
|
||||
doc.last_err = Some(e.to_string());
|
||||
}
|
||||
}
|
||||
return write_tlv_void(result, result_len);
|
||||
}
|
||||
ProviderKind::Yyjson => {
|
||||
let c = CString::new(text.as_bytes()).unwrap_or_default();
|
||||
let mut ec: i32 = -1;
|
||||
let p = nyjson_parse_doc(c.as_ptr(), text.len(), &mut ec as *mut i32);
|
||||
let p =
|
||||
nyjson_parse_doc(c.as_ptr(), text.len(), &mut ec as *mut i32);
|
||||
if p.is_null() {
|
||||
doc.root = None; doc.doc_ptr = None; doc.last_err = Some(format!("E{}", ec));
|
||||
doc.root = None;
|
||||
doc.doc_ptr = None;
|
||||
doc.last_err = Some(format!("E{}", ec));
|
||||
} else {
|
||||
doc.root = None; doc.doc_ptr = Some(p as usize); doc.last_err = None;
|
||||
doc.root = None;
|
||||
doc.doc_ptr = Some(p as usize);
|
||||
doc.last_err = None;
|
||||
}
|
||||
return write_tlv_void(result, result_len);
|
||||
}
|
||||
@ -197,8 +217,15 @@ extern "C" fn jsondoc_invoke_id(
|
||||
ProviderKind::Serde => {
|
||||
if let Some(root_arc) = doc.root.as_ref().map(|r| Arc::clone(r)) {
|
||||
let node_id = NEXT_ID.fetch_add(1, Ordering::Relaxed);
|
||||
if let Ok(mut nn) = NODES.lock() { nn.insert(node_id, NodeRep::Serde(root_arc)); }
|
||||
return write_tlv_handle(T_JSON_NODE, node_id, result, result_len);
|
||||
if let Ok(mut nn) = NODES.lock() {
|
||||
nn.insert(node_id, NodeRep::Serde(root_arc));
|
||||
}
|
||||
return write_tlv_handle(
|
||||
T_JSON_NODE,
|
||||
node_id,
|
||||
result,
|
||||
result_len,
|
||||
);
|
||||
}
|
||||
return E_PLUGIN;
|
||||
}
|
||||
@ -206,8 +233,21 @@ extern "C" fn jsondoc_invoke_id(
|
||||
if let Some(dp) = doc.doc_ptr {
|
||||
let vp = nyjson_doc_root(dp as *mut c_void);
|
||||
let node_id = NEXT_ID.fetch_add(1, Ordering::Relaxed);
|
||||
if let Ok(mut nn) = NODES.lock() { nn.insert(node_id, NodeRep::Yy { doc_id: instance_id, ptr: vp as usize }); }
|
||||
return write_tlv_handle(T_JSON_NODE, node_id, result, result_len);
|
||||
if let Ok(mut nn) = NODES.lock() {
|
||||
nn.insert(
|
||||
node_id,
|
||||
NodeRep::Yy {
|
||||
doc_id: instance_id,
|
||||
ptr: vp as usize,
|
||||
},
|
||||
);
|
||||
}
|
||||
return write_tlv_handle(
|
||||
T_JSON_NODE,
|
||||
node_id,
|
||||
result,
|
||||
result_len,
|
||||
);
|
||||
}
|
||||
return E_PLUGIN;
|
||||
}
|
||||
@ -231,7 +271,9 @@ extern "C" fn jsondoc_invoke_id(
|
||||
JD_FINI => {
|
||||
if let Ok(mut m) = DOCS.lock() {
|
||||
if let Some(mut di) = m.remove(&instance_id) {
|
||||
if let Some(dp) = di.doc_ptr.take() { nyjson_doc_free(dp as *mut c_void); }
|
||||
if let Some(dp) = di.doc_ptr.take() {
|
||||
nyjson_doc_free(dp as *mut c_void);
|
||||
}
|
||||
}
|
||||
}
|
||||
return write_tlv_void(result, result_len);
|
||||
@ -281,146 +323,330 @@ extern "C" fn jsonnode_invoke_id(
|
||||
) -> i32 {
|
||||
unsafe {
|
||||
let node_rep = match NODES.lock() {
|
||||
Ok(m) => match m.get(&instance_id) { Some(v) => v.clone(), None => return E_HANDLE },
|
||||
Ok(m) => match m.get(&instance_id) {
|
||||
Some(v) => v.clone(),
|
||||
None => return E_HANDLE,
|
||||
},
|
||||
Err(_) => return E_PLUGIN,
|
||||
};
|
||||
match method_id {
|
||||
JN_BIRTH => {
|
||||
let id = NEXT_ID.fetch_add(1, Ordering::Relaxed);
|
||||
if let Ok(mut m) = NODES.lock() { m.insert(id, NodeRep::Serde(Arc::new(Value::Null))); } else { return E_PLUGIN; }
|
||||
if let Ok(mut m) = NODES.lock() {
|
||||
m.insert(id, NodeRep::Serde(Arc::new(Value::Null)));
|
||||
} else {
|
||||
return E_PLUGIN;
|
||||
}
|
||||
return write_u32(id, result, result_len);
|
||||
}
|
||||
JN_KIND => {
|
||||
match provider_kind() {
|
||||
ProviderKind::Serde => {
|
||||
let k = match node_rep { NodeRep::Serde(ref a) => match &**a {
|
||||
JN_KIND => match provider_kind() {
|
||||
ProviderKind::Serde => {
|
||||
let k = match node_rep {
|
||||
NodeRep::Serde(ref a) => match &**a {
|
||||
Value::Null => "null",
|
||||
Value::Bool(_) => "bool",
|
||||
Value::Number(n) => { if n.is_i64() { "int" } else { "real" } },
|
||||
Value::Number(n) => {
|
||||
if n.is_i64() {
|
||||
"int"
|
||||
} else {
|
||||
"real"
|
||||
}
|
||||
}
|
||||
Value::String(_) => "string",
|
||||
Value::Array(_) => "array",
|
||||
Value::Object(_) => "object",
|
||||
}, _ => "null"};
|
||||
write_tlv_string(k, result, result_len)
|
||||
}
|
||||
ProviderKind::Yyjson => {
|
||||
let v = if let NodeRep::Yy { ptr, .. } = node_rep { ptr as *mut c_void } else { std::ptr::null_mut() };
|
||||
let k = if v.is_null() { "null" }
|
||||
else if nyjson_is_obj(v) != 0 { "object" }
|
||||
else if nyjson_is_arr(v) != 0 { "array" }
|
||||
else if nyjson_is_str(v) != 0 { "string" }
|
||||
else if nyjson_is_int(v) != 0 { "int" }
|
||||
else if nyjson_is_real(v) != 0 { "real" }
|
||||
else if nyjson_is_bool(v) != 0 { "bool" }
|
||||
else { "null" };
|
||||
write_tlv_string(k, result, result_len)
|
||||
}
|
||||
},
|
||||
_ => "null",
|
||||
};
|
||||
write_tlv_string(k, result, result_len)
|
||||
}
|
||||
}
|
||||
ProviderKind::Yyjson => {
|
||||
let v = if let NodeRep::Yy { ptr, .. } = node_rep {
|
||||
ptr as *mut c_void
|
||||
} else {
|
||||
std::ptr::null_mut()
|
||||
};
|
||||
let k = if v.is_null() {
|
||||
"null"
|
||||
} else if nyjson_is_obj(v) != 0 {
|
||||
"object"
|
||||
} else if nyjson_is_arr(v) != 0 {
|
||||
"array"
|
||||
} else if nyjson_is_str(v) != 0 {
|
||||
"string"
|
||||
} else if nyjson_is_int(v) != 0 {
|
||||
"int"
|
||||
} else if nyjson_is_real(v) != 0 {
|
||||
"real"
|
||||
} else if nyjson_is_bool(v) != 0 {
|
||||
"bool"
|
||||
} else {
|
||||
"null"
|
||||
};
|
||||
write_tlv_string(k, result, result_len)
|
||||
}
|
||||
},
|
||||
JN_GET => {
|
||||
let key = match read_arg_string(args, args_len, 0) { Some(s) => s, None => return E_ARGS };
|
||||
let key = match read_arg_string(args, args_len, 0) {
|
||||
Some(s) => s,
|
||||
None => return E_ARGS,
|
||||
};
|
||||
match provider_kind() {
|
||||
ProviderKind::Serde => {
|
||||
let id = NEXT_ID.fetch_add(1, Ordering::Relaxed);
|
||||
if let NodeRep::Serde(ref a) = node_rep {
|
||||
if let Value::Object(map) = &**a {
|
||||
if let Some(child) = map.get(&key) {
|
||||
if let Ok(mut mm) = NODES.lock() { mm.insert(id, NodeRep::Serde(Arc::new(child.clone()))); }
|
||||
if let Ok(mut mm) = NODES.lock() {
|
||||
mm.insert(id, NodeRep::Serde(Arc::new(child.clone())));
|
||||
}
|
||||
return write_tlv_handle(T_JSON_NODE, id, result, result_len);
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Ok(mut mm) = NODES.lock() { mm.insert(id, NodeRep::Serde(Arc::new(Value::Null))); }
|
||||
if let Ok(mut mm) = NODES.lock() {
|
||||
mm.insert(id, NodeRep::Serde(Arc::new(Value::Null)));
|
||||
}
|
||||
write_tlv_handle(T_JSON_NODE, id, result, result_len)
|
||||
}
|
||||
ProviderKind::Yyjson => {
|
||||
let v = if let NodeRep::Yy { ptr, .. } = node_rep { ptr as *mut c_void } else { std::ptr::null_mut() };
|
||||
let v = if let NodeRep::Yy { ptr, .. } = node_rep {
|
||||
ptr as *mut c_void
|
||||
} else {
|
||||
std::ptr::null_mut()
|
||||
};
|
||||
let id = NEXT_ID.fetch_add(1, Ordering::Relaxed);
|
||||
let mut out_ptr: *mut c_void = std::ptr::null_mut();
|
||||
if !v.is_null() && nyjson_is_obj(v) != 0 {
|
||||
let c = CString::new(key).unwrap_or_default();
|
||||
out_ptr = nyjson_obj_get_key(v, c.as_ptr());
|
||||
}
|
||||
let doc_id = if let NodeRep::Yy { doc_id, .. } = node_rep { doc_id } else { 0 };
|
||||
let doc_id = if let NodeRep::Yy { doc_id, .. } = node_rep {
|
||||
doc_id
|
||||
} else {
|
||||
0
|
||||
};
|
||||
let rep = if out_ptr.is_null() {
|
||||
NodeRep::Yy { doc_id, ptr: 0 }
|
||||
} else {
|
||||
NodeRep::Yy { doc_id, ptr: out_ptr as usize }
|
||||
NodeRep::Yy {
|
||||
doc_id,
|
||||
ptr: out_ptr as usize,
|
||||
}
|
||||
};
|
||||
if let Ok(mut mm) = NODES.lock() { mm.insert(id, rep); }
|
||||
if let Ok(mut mm) = NODES.lock() {
|
||||
mm.insert(id, rep);
|
||||
}
|
||||
write_tlv_handle(T_JSON_NODE, id, result, result_len)
|
||||
}
|
||||
}
|
||||
}
|
||||
JN_SIZE => {
|
||||
match provider_kind() {
|
||||
ProviderKind::Serde => {
|
||||
let n = match node_rep { NodeRep::Serde(ref a) => match &**a { Value::Array(a) => a.len() as i64, Value::Object(o) => o.len() as i64, _ => 0 }, _ => 0 };
|
||||
write_tlv_i64(n, result, result_len)
|
||||
}
|
||||
ProviderKind::Yyjson => {
|
||||
let v = if let NodeRep::Yy { ptr, .. } = node_rep { ptr as *mut c_void } else { std::ptr::null_mut() };
|
||||
let n = if !v.is_null() { if nyjson_is_arr(v) != 0 { nyjson_arr_size_val(v) as i64 } else if nyjson_is_obj(v) != 0 { nyjson_obj_size_val(v) as i64 } else { 0 } } else { 0 };
|
||||
write_tlv_i64(n, result, result_len)
|
||||
}
|
||||
JN_SIZE => match provider_kind() {
|
||||
ProviderKind::Serde => {
|
||||
let n = match node_rep {
|
||||
NodeRep::Serde(ref a) => match &**a {
|
||||
Value::Array(a) => a.len() as i64,
|
||||
Value::Object(o) => o.len() as i64,
|
||||
_ => 0,
|
||||
},
|
||||
_ => 0,
|
||||
};
|
||||
write_tlv_i64(n, result, result_len)
|
||||
}
|
||||
}
|
||||
ProviderKind::Yyjson => {
|
||||
let v = if let NodeRep::Yy { ptr, .. } = node_rep {
|
||||
ptr as *mut c_void
|
||||
} else {
|
||||
std::ptr::null_mut()
|
||||
};
|
||||
let n = if !v.is_null() {
|
||||
if nyjson_is_arr(v) != 0 {
|
||||
nyjson_arr_size_val(v) as i64
|
||||
} else if nyjson_is_obj(v) != 0 {
|
||||
nyjson_obj_size_val(v) as i64
|
||||
} else {
|
||||
0
|
||||
}
|
||||
} else {
|
||||
0
|
||||
};
|
||||
write_tlv_i64(n, result, result_len)
|
||||
}
|
||||
},
|
||||
JN_AT => {
|
||||
let idx = match read_arg_i64(args, args_len, 0) { Some(v) => v, None => return E_ARGS };
|
||||
if idx < 0 { return E_ARGS; }
|
||||
let idx = match read_arg_i64(args, args_len, 0) {
|
||||
Some(v) => v,
|
||||
None => return E_ARGS,
|
||||
};
|
||||
if idx < 0 {
|
||||
return E_ARGS;
|
||||
}
|
||||
match provider_kind() {
|
||||
ProviderKind::Serde => {
|
||||
let id = NEXT_ID.fetch_add(1, Ordering::Relaxed);
|
||||
if let NodeRep::Serde(ref a) = node_rep {
|
||||
if let Value::Array(arr) = &**a {
|
||||
let i = idx as usize;
|
||||
if i < arr.len() { if let Ok(mut mm) = NODES.lock() { mm.insert(id, NodeRep::Serde(Arc::new(arr[i].clone()))); } return write_tlv_handle(T_JSON_NODE, id, result, result_len); }
|
||||
if i < arr.len() {
|
||||
if let Ok(mut mm) = NODES.lock() {
|
||||
mm.insert(id, NodeRep::Serde(Arc::new(arr[i].clone())));
|
||||
}
|
||||
return write_tlv_handle(T_JSON_NODE, id, result, result_len);
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Ok(mut mm) = NODES.lock() { mm.insert(id, NodeRep::Serde(Arc::new(Value::Null))); }
|
||||
if let Ok(mut mm) = NODES.lock() {
|
||||
mm.insert(id, NodeRep::Serde(Arc::new(Value::Null)));
|
||||
}
|
||||
write_tlv_handle(T_JSON_NODE, id, result, result_len)
|
||||
}
|
||||
ProviderKind::Yyjson => {
|
||||
let v = if let NodeRep::Yy { ptr, .. } = node_rep { ptr as *mut c_void } else { std::ptr::null_mut() };
|
||||
let v = if let NodeRep::Yy { ptr, .. } = node_rep {
|
||||
ptr as *mut c_void
|
||||
} else {
|
||||
std::ptr::null_mut()
|
||||
};
|
||||
let id = NEXT_ID.fetch_add(1, Ordering::Relaxed);
|
||||
let mut child: *mut c_void = std::ptr::null_mut();
|
||||
if !v.is_null() && nyjson_is_arr(v) != 0 { child = nyjson_arr_get_val(v, idx as usize); }
|
||||
let doc_id = if let NodeRep::Yy { doc_id, .. } = node_rep { doc_id } else { 0 };
|
||||
if !v.is_null() && nyjson_is_arr(v) != 0 {
|
||||
child = nyjson_arr_get_val(v, idx as usize);
|
||||
}
|
||||
let doc_id = if let NodeRep::Yy { doc_id, .. } = node_rep {
|
||||
doc_id
|
||||
} else {
|
||||
0
|
||||
};
|
||||
let rep = if child.is_null() {
|
||||
NodeRep::Yy { doc_id, ptr: 0 }
|
||||
} else {
|
||||
NodeRep::Yy { doc_id, ptr: child as usize }
|
||||
NodeRep::Yy {
|
||||
doc_id,
|
||||
ptr: child as usize,
|
||||
}
|
||||
};
|
||||
if let Ok(mut mm) = NODES.lock() { mm.insert(id, rep); }
|
||||
if let Ok(mut mm) = NODES.lock() {
|
||||
mm.insert(id, rep);
|
||||
}
|
||||
write_tlv_handle(T_JSON_NODE, id, result, result_len)
|
||||
}
|
||||
}
|
||||
}
|
||||
JN_STR => match provider_kind() {
|
||||
ProviderKind::Serde => {
|
||||
if let NodeRep::Serde(ref a) = node_rep { match &**a { Value::String(s) => write_tlv_string(s, result, result_len), Value::Object(o) => { if let Some(Value::String(s)) = o.get("value") { write_tlv_string(s, result, result_len) } else { write_tlv_string("", result, result_len) } }, _ => write_tlv_string("", result, result_len) } } else { write_tlv_string("", result, result_len) }
|
||||
if let NodeRep::Serde(ref a) = node_rep {
|
||||
match &**a {
|
||||
Value::String(s) => write_tlv_string(s, result, result_len),
|
||||
Value::Object(o) => {
|
||||
if let Some(Value::String(s)) = o.get("value") {
|
||||
write_tlv_string(s, result, result_len)
|
||||
} else {
|
||||
write_tlv_string("", result, result_len)
|
||||
}
|
||||
}
|
||||
_ => write_tlv_string("", result, result_len),
|
||||
}
|
||||
} else {
|
||||
write_tlv_string("", result, result_len)
|
||||
}
|
||||
}
|
||||
ProviderKind::Yyjson => {
|
||||
let v = if let NodeRep::Yy { ptr, .. } = node_rep { ptr as *mut c_void } else { std::ptr::null_mut() };
|
||||
if !v.is_null() && nyjson_is_str(v) != 0 { let s = nyjson_get_str_val(v); if s.is_null() { write_tlv_string("", result, result_len) } else { let rs = CStr::from_ptr(s).to_string_lossy().to_string(); write_tlv_string(&rs, result, result_len) } }
|
||||
else if !v.is_null() && nyjson_is_obj(v) != 0 { let key = CString::new("value").unwrap(); let child = nyjson_obj_get_key(v, key.as_ptr()); if !child.is_null() && nyjson_is_str(child) != 0 { let s = nyjson_get_str_val(child); if s.is_null() { write_tlv_string("", result, result_len) } else { let rs = CStr::from_ptr(s).to_string_lossy().to_string(); write_tlv_string(&rs, result, result_len) } } else { write_tlv_string("", result, result_len) } }
|
||||
else { write_tlv_string("", result, result_len) }
|
||||
let v = if let NodeRep::Yy { ptr, .. } = node_rep {
|
||||
ptr as *mut c_void
|
||||
} else {
|
||||
std::ptr::null_mut()
|
||||
};
|
||||
if !v.is_null() && nyjson_is_str(v) != 0 {
|
||||
let s = nyjson_get_str_val(v);
|
||||
if s.is_null() {
|
||||
write_tlv_string("", result, result_len)
|
||||
} else {
|
||||
let rs = CStr::from_ptr(s).to_string_lossy().to_string();
|
||||
write_tlv_string(&rs, result, result_len)
|
||||
}
|
||||
} else if !v.is_null() && nyjson_is_obj(v) != 0 {
|
||||
let key = CString::new("value").unwrap();
|
||||
let child = nyjson_obj_get_key(v, key.as_ptr());
|
||||
if !child.is_null() && nyjson_is_str(child) != 0 {
|
||||
let s = nyjson_get_str_val(child);
|
||||
if s.is_null() {
|
||||
write_tlv_string("", result, result_len)
|
||||
} else {
|
||||
let rs = CStr::from_ptr(s).to_string_lossy().to_string();
|
||||
write_tlv_string(&rs, result, result_len)
|
||||
}
|
||||
} else {
|
||||
write_tlv_string("", result, result_len)
|
||||
}
|
||||
} else {
|
||||
write_tlv_string("", result, result_len)
|
||||
}
|
||||
}
|
||||
},
|
||||
JN_INT => match provider_kind() {
|
||||
ProviderKind::Serde => {
|
||||
if let NodeRep::Serde(ref a) = node_rep { match &**a { Value::Number(n) => write_tlv_i64(n.as_i64().unwrap_or(0), result, result_len), Value::Object(o) => { if let Some(Value::Number(n)) = o.get("value") { write_tlv_i64(n.as_i64().unwrap_or(0), result, result_len) } else { write_tlv_i64(0, result, result_len) } }, _ => write_tlv_i64(0, result, result_len) } } else { write_tlv_i64(0, result, result_len) }
|
||||
if let NodeRep::Serde(ref a) = node_rep {
|
||||
match &**a {
|
||||
Value::Number(n) => {
|
||||
write_tlv_i64(n.as_i64().unwrap_or(0), result, result_len)
|
||||
}
|
||||
Value::Object(o) => {
|
||||
if let Some(Value::Number(n)) = o.get("value") {
|
||||
write_tlv_i64(n.as_i64().unwrap_or(0), result, result_len)
|
||||
} else {
|
||||
write_tlv_i64(0, result, result_len)
|
||||
}
|
||||
}
|
||||
_ => write_tlv_i64(0, result, result_len),
|
||||
}
|
||||
} else {
|
||||
write_tlv_i64(0, result, result_len)
|
||||
}
|
||||
}
|
||||
ProviderKind::Yyjson => {
|
||||
let v = if let NodeRep::Yy { ptr, .. } = node_rep { ptr as *mut c_void } else { std::ptr::null_mut() };
|
||||
if !v.is_null() && nyjson_is_int(v) != 0 { write_tlv_i64(nyjson_get_sint_val(v) as i64, result, result_len) }
|
||||
else if !v.is_null() && nyjson_is_obj(v) != 0 { let key = CString::new("value").unwrap(); let child = nyjson_obj_get_key(v, key.as_ptr()); if !child.is_null() && nyjson_is_int(child) != 0 { write_tlv_i64(nyjson_get_sint_val(child) as i64, result, result_len) } else { write_tlv_i64(0, result, result_len) } }
|
||||
else { write_tlv_i64(0, result, result_len) }
|
||||
let v = if let NodeRep::Yy { ptr, .. } = node_rep {
|
||||
ptr as *mut c_void
|
||||
} else {
|
||||
std::ptr::null_mut()
|
||||
};
|
||||
if !v.is_null() && nyjson_is_int(v) != 0 {
|
||||
write_tlv_i64(nyjson_get_sint_val(v) as i64, result, result_len)
|
||||
} else if !v.is_null() && nyjson_is_obj(v) != 0 {
|
||||
let key = CString::new("value").unwrap();
|
||||
let child = nyjson_obj_get_key(v, key.as_ptr());
|
||||
if !child.is_null() && nyjson_is_int(child) != 0 {
|
||||
write_tlv_i64(nyjson_get_sint_val(child) as i64, result, result_len)
|
||||
} else {
|
||||
write_tlv_i64(0, result, result_len)
|
||||
}
|
||||
} else {
|
||||
write_tlv_i64(0, result, result_len)
|
||||
}
|
||||
}
|
||||
},
|
||||
JN_BOOL => match provider_kind() {
|
||||
ProviderKind::Serde => { if let NodeRep::Serde(ref a) = node_rep { if let Value::Bool(b) = **a { write_tlv_bool(b, result, result_len) } else { write_tlv_bool(false, result, result_len) } } else { write_tlv_bool(false, result, result_len) } }
|
||||
ProviderKind::Yyjson => { let v = if let NodeRep::Yy { ptr, .. } = node_rep { ptr as *mut c_void } else { std::ptr::null_mut() }; if !v.is_null() && nyjson_is_bool(v) != 0 { write_tlv_bool(nyjson_get_bool_val(v) != 0, result, result_len) } else { write_tlv_bool(false, result, result_len) } }
|
||||
ProviderKind::Serde => {
|
||||
if let NodeRep::Serde(ref a) = node_rep {
|
||||
if let Value::Bool(b) = **a {
|
||||
write_tlv_bool(b, result, result_len)
|
||||
} else {
|
||||
write_tlv_bool(false, result, result_len)
|
||||
}
|
||||
} else {
|
||||
write_tlv_bool(false, result, result_len)
|
||||
}
|
||||
}
|
||||
ProviderKind::Yyjson => {
|
||||
let v = if let NodeRep::Yy { ptr, .. } = node_rep {
|
||||
ptr as *mut c_void
|
||||
} else {
|
||||
std::ptr::null_mut()
|
||||
};
|
||||
if !v.is_null() && nyjson_is_bool(v) != 0 {
|
||||
write_tlv_bool(nyjson_get_bool_val(v) != 0, result, result_len)
|
||||
} else {
|
||||
write_tlv_bool(false, result, result_len)
|
||||
}
|
||||
}
|
||||
},
|
||||
_ => E_METHOD,
|
||||
}
|
||||
|
||||
@ -61,4 +61,3 @@ pub(crate) const M_CONN_SEND: u32 = 1; // bytes/string -> void
|
||||
pub(crate) const M_CONN_RECV: u32 = 2; // -> bytes
|
||||
pub(crate) const M_CONN_CLOSE: u32 = 3; // -> void
|
||||
pub(crate) const M_CONN_RECV_TIMEOUT: u32 = 4; // ms -> bytes (empty if timeout)
|
||||
|
||||
|
||||
@ -149,11 +149,17 @@ pub fn parse_client_response_into(resp_id: u32, conn_id: u32) {
|
||||
let mut tmp = [0u8; 2048];
|
||||
loop {
|
||||
match s.read(&mut tmp) {
|
||||
Ok(0) => { return; }
|
||||
Ok(0) => {
|
||||
return;
|
||||
}
|
||||
Ok(n) => {
|
||||
buf.extend_from_slice(&tmp[..n]);
|
||||
if find_header_end(&buf).is_some() { break; }
|
||||
if buf.len() > 256 * 1024 { break; }
|
||||
if find_header_end(&buf).is_some() {
|
||||
break;
|
||||
}
|
||||
if buf.len() > 256 * 1024 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
Err(_) => return,
|
||||
}
|
||||
@ -191,7 +197,9 @@ pub fn parse_client_response_into(resp_id: u32, conn_id: u32) {
|
||||
}
|
||||
}
|
||||
}
|
||||
if should_remove { map.remove(&conn_id); }
|
||||
if should_remove {
|
||||
map.remove(&conn_id);
|
||||
}
|
||||
}
|
||||
if let Some(rp) = state::RESPONSES.lock().unwrap().get_mut(&resp_id) {
|
||||
rp.status = status;
|
||||
@ -201,4 +209,3 @@ pub fn parse_client_response_into(resp_id: u32, conn_id: u32) {
|
||||
rp.client_conn_id = None;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
//! Provides ServerBox/RequestBox/ResponseBox/ClientBox and socket variants.
|
||||
//! Pure in-process HTTP over localhost for E2E of BoxRef args/returns.
|
||||
|
||||
use crate::state::{ClientState, RequestState, ResponseState, ServerState, SockConnState};
|
||||
use once_cell::sync::Lazy;
|
||||
use std::collections::{HashMap, VecDeque};
|
||||
use std::io::Write as IoWrite;
|
||||
@ -11,7 +12,6 @@ use std::sync::{
|
||||
Arc, Mutex,
|
||||
};
|
||||
use std::time::Duration;
|
||||
use crate::state::{ClientState, RequestState, ResponseState, ServerState, SockConnState};
|
||||
|
||||
// ===== Simple logger (enabled when NYASH_NET_LOG=1) =====
|
||||
static LOG_ON: Lazy<bool> = Lazy::new(|| std::env::var("NYASH_NET_LOG").unwrap_or_default() == "1");
|
||||
@ -234,7 +234,9 @@ extern "C" fn sockserver_invoke_id(
|
||||
result: *mut u8,
|
||||
result_len: *mut usize,
|
||||
) -> i32 {
|
||||
unsafe { sockets::sock_server_invoke(method_id, instance_id, args, args_len, result, result_len) }
|
||||
unsafe {
|
||||
sockets::sock_server_invoke(method_id, instance_id, args, args_len, result, result_len)
|
||||
}
|
||||
}
|
||||
#[no_mangle]
|
||||
pub static nyash_typebox_SockServerBox: NyashTypeBoxFfi = NyashTypeBoxFfi {
|
||||
@ -268,7 +270,9 @@ extern "C" fn sockclient_invoke_id(
|
||||
result: *mut u8,
|
||||
result_len: *mut usize,
|
||||
) -> i32 {
|
||||
unsafe { sockets::sock_client_invoke(method_id, instance_id, args, args_len, result, result_len) }
|
||||
unsafe {
|
||||
sockets::sock_client_invoke(method_id, instance_id, args, args_len, result, result_len)
|
||||
}
|
||||
}
|
||||
#[no_mangle]
|
||||
pub static nyash_typebox_SockClientBox: NyashTypeBoxFfi = NyashTypeBoxFfi {
|
||||
@ -1012,7 +1016,8 @@ unsafe fn client_invoke(
|
||||
let body_len = body.len();
|
||||
// Create client response handle
|
||||
let resp_id = state::next_response_id();
|
||||
let (_h, _p, req_bytes) = http_helpers::build_http_request("POST", &url, Some(&body), resp_id);
|
||||
let (_h, _p, req_bytes) =
|
||||
http_helpers::build_http_request("POST", &url, Some(&body), resp_id);
|
||||
let mut tcp_ok = false;
|
||||
if let Ok(mut stream) = TcpStream::connect(format!("{}:{}", host, port)) {
|
||||
let _ = stream.write_all(&req_bytes);
|
||||
@ -1086,9 +1091,9 @@ unsafe fn client_invoke(
|
||||
|
||||
// ===== Helpers =====
|
||||
use ffi::slice;
|
||||
mod tlv;
|
||||
mod http_helpers;
|
||||
mod sockets;
|
||||
mod tlv;
|
||||
|
||||
// ===== HTTP helpers =====
|
||||
// moved
|
||||
|
||||
@ -1,14 +1,19 @@
|
||||
use std::collections::VecDeque;
|
||||
use std::io::{Read, Write as IoWrite};
|
||||
use std::net::{TcpListener, TcpStream};
|
||||
use std::sync::{atomic::{AtomicBool, Ordering}, Arc, Mutex};
|
||||
use std::sync::{
|
||||
atomic::{AtomicBool, Ordering},
|
||||
Arc, Mutex,
|
||||
};
|
||||
use std::time::Duration;
|
||||
|
||||
use crate::consts::*;
|
||||
use crate::state::{self, SockConnState, SockServerState};
|
||||
|
||||
// Utilities provided by parent module
|
||||
fn logf(s: String) { super::net_log(&s); }
|
||||
fn logf(s: String) {
|
||||
super::net_log(&s);
|
||||
}
|
||||
|
||||
pub(crate) unsafe fn sock_server_invoke(
|
||||
m: u32,
|
||||
@ -51,7 +56,9 @@ pub(crate) unsafe fn sock_server_invoke(
|
||||
let conn_id = state::next_sock_conn_id();
|
||||
state::SOCK_CONNS.lock().unwrap().insert(
|
||||
conn_id,
|
||||
SockConnState { stream: Mutex::new(stream) },
|
||||
SockConnState {
|
||||
stream: Mutex::new(stream),
|
||||
},
|
||||
);
|
||||
logf(format!("sock:accept conn_id={}", conn_id));
|
||||
pending.lock().unwrap().push_back(conn_id);
|
||||
@ -161,7 +168,9 @@ pub(crate) unsafe fn sock_client_invoke(
|
||||
let conn_id = state::next_sock_conn_id();
|
||||
state::SOCK_CONNS.lock().unwrap().insert(
|
||||
conn_id,
|
||||
SockConnState { stream: Mutex::new(stream) },
|
||||
SockConnState {
|
||||
stream: Mutex::new(stream),
|
||||
},
|
||||
);
|
||||
logf(format!("sock:connect ok conn_id={}", conn_id));
|
||||
crate::tlv::write_tlv_handle(T_SOCK_CONN, conn_id, res, res_len)
|
||||
@ -190,7 +199,8 @@ pub(crate) unsafe fn sock_conn_invoke(
|
||||
crate::tlv::write_u32(0, res, res_len)
|
||||
}
|
||||
M_CONN_SEND => {
|
||||
let bytes = crate::tlv::tlv_parse_bytes(super::ffi::slice(args, args_len)).unwrap_or_default();
|
||||
let bytes =
|
||||
crate::tlv::tlv_parse_bytes(super::ffi::slice(args, args_len)).unwrap_or_default();
|
||||
if let Some(conn) = state::SOCK_CONNS.lock().unwrap().get(&id) {
|
||||
if let Ok(mut s) = conn.stream.lock() {
|
||||
let _ = s.write_all(&bytes);
|
||||
@ -229,11 +239,17 @@ pub(crate) unsafe fn sock_conn_invoke(
|
||||
match resv {
|
||||
Ok(n) => {
|
||||
buf.truncate(n);
|
||||
logf(format!("sock:recvTimeout id={} n={} ms={}", id, n, timeout_ms));
|
||||
logf(format!(
|
||||
"sock:recvTimeout id={} n={} ms={}",
|
||||
id, n, timeout_ms
|
||||
));
|
||||
return crate::tlv::write_tlv_bytes(&buf, res, res_len);
|
||||
}
|
||||
Err(e) => {
|
||||
logf(format!("sock:recvTimeout error id={} ms={} err={:?}", id, timeout_ms, e));
|
||||
logf(format!(
|
||||
"sock:recvTimeout error id={} ms={} err={:?}",
|
||||
id, timeout_ms, e
|
||||
));
|
||||
return E_ERR;
|
||||
}
|
||||
}
|
||||
@ -249,4 +265,3 @@ pub(crate) unsafe fn sock_conn_invoke(
|
||||
_ => E_INV_METHOD,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -27,7 +27,7 @@ const M_FROM_UTF8: u32 = 5; // fromUtf8(data: String|Bytes) -> Handle(new)
|
||||
const M_TO_UTF8: u32 = 6; // toUtf8() -> String
|
||||
const M_FINI: u32 = u32::MAX;
|
||||
|
||||
const TYPE_ID_STRING: u32 = 10; // Match nyash.toml type_id
|
||||
const TYPE_ID_STRING: u32 = 10; // Match nyash.toml type_id
|
||||
|
||||
struct StrInstance {
|
||||
s: String,
|
||||
@ -222,7 +222,7 @@ extern "C" fn string_resolve(name: *const c_char) -> u32 {
|
||||
"charCodeAt" => M_CHAR_CODE_AT,
|
||||
"concat" => M_CONCAT,
|
||||
"fromUtf8" => M_FROM_UTF8,
|
||||
"toUtf8" | "toString" => M_TO_UTF8, // Map toString to toUtf8
|
||||
"toUtf8" | "toString" => M_TO_UTF8, // Map toString to toUtf8
|
||||
_ => 0,
|
||||
}
|
||||
}
|
||||
@ -264,10 +264,16 @@ extern "C" fn string_invoke_id(
|
||||
if let Ok(m) = INST.lock() {
|
||||
if let Some(inst) = m.get(&instance_id) {
|
||||
let len = inst.s.len();
|
||||
eprintln!("[StringBox] Found instance, string={:?}, len={}", inst.s, len);
|
||||
eprintln!(
|
||||
"[StringBox] Found instance, string={:?}, len={}",
|
||||
inst.s, len
|
||||
);
|
||||
return write_tlv_i64(len as i64, result, result_len);
|
||||
} else {
|
||||
eprintln!("[StringBox] Instance {} not found in INST map!", instance_id);
|
||||
eprintln!(
|
||||
"[StringBox] Instance {} not found in INST map!",
|
||||
instance_id
|
||||
);
|
||||
return E_HANDLE;
|
||||
}
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user