smokes: add curated LLVM runner; archive legacy smokes; PHI-off unified across Bridge/Builder; LLVM resolver tracing; minimal Throw lowering; config env getters; dev profile and root cleaner; docs updated; CI workflow runs curated LLVM (PHI-on/off)
This commit is contained in:
@ -6,4 +6,3 @@
|
||||
pub fn version() -> &'static str {
|
||||
"0.1.0-dev"
|
||||
}
|
||||
|
||||
|
||||
@ -2,4 +2,3 @@ fn main() {
|
||||
env_logger::init();
|
||||
println!("nyash-next: workspace skeleton is ready.");
|
||||
}
|
||||
|
||||
|
||||
@ -111,14 +111,26 @@ pub extern "C" fn nyash_string_substring_hii_export(h: i64, start: i64, end: i64
|
||||
return 0;
|
||||
}
|
||||
let s = if let Some(obj) = handles::get(h as u64) {
|
||||
if let Some(sb) = obj.as_any().downcast_ref::<StringBox>() { sb.value.clone() } else { String::new() }
|
||||
} else { String::new() };
|
||||
if let Some(sb) = obj.as_any().downcast_ref::<StringBox>() {
|
||||
sb.value.clone()
|
||||
} else {
|
||||
String::new()
|
||||
}
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
let n = s.len() as i64;
|
||||
let mut st = if start < 0 { 0 } else { start };
|
||||
let mut en = if end < 0 { 0 } else { end };
|
||||
if st > n { st = n; }
|
||||
if en > n { en = n; }
|
||||
if en < st { std::mem::swap(&mut st, &mut en); }
|
||||
if st > n {
|
||||
st = n;
|
||||
}
|
||||
if en > n {
|
||||
en = n;
|
||||
}
|
||||
if en < st {
|
||||
std::mem::swap(&mut st, &mut en);
|
||||
}
|
||||
let (st_u, en_u) = (st as usize, en as usize);
|
||||
let sub = s.get(st_u.min(s.len())..en_u.min(s.len())).unwrap_or("");
|
||||
let arc: std::sync::Arc<dyn NyashBox> = std::sync::Arc::new(StringBox::new(sub.to_string()));
|
||||
@ -133,16 +145,38 @@ pub extern "C" fn nyash_string_lastindexof_hh_export(h: i64, n: i64) -> i64 {
|
||||
use nyash_rust::{box_trait::StringBox, jit::rt::handles};
|
||||
let hay = if h > 0 {
|
||||
if let Some(o) = handles::get(h as u64) {
|
||||
if let Some(sb) = o.as_any().downcast_ref::<StringBox>() { sb.value.clone() } else { String::new() }
|
||||
} else { String::new() }
|
||||
} else { String::new() };
|
||||
if let Some(sb) = o.as_any().downcast_ref::<StringBox>() {
|
||||
sb.value.clone()
|
||||
} else {
|
||||
String::new()
|
||||
}
|
||||
} else {
|
||||
String::new()
|
||||
}
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
let nee = if n > 0 {
|
||||
if let Some(o) = handles::get(n as u64) {
|
||||
if let Some(sb) = o.as_any().downcast_ref::<StringBox>() { sb.value.clone() } else { String::new() }
|
||||
} else { String::new() }
|
||||
} else { String::new() };
|
||||
if nee.is_empty() { return hay.len() as i64; }
|
||||
if let Some(pos) = hay.rfind(&nee) { pos as i64 } else { -1 }
|
||||
if let Some(sb) = o.as_any().downcast_ref::<StringBox>() {
|
||||
sb.value.clone()
|
||||
} else {
|
||||
String::new()
|
||||
}
|
||||
} else {
|
||||
String::new()
|
||||
}
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
if nee.is_empty() {
|
||||
return hay.len() as i64;
|
||||
}
|
||||
if let Some(pos) = hay.rfind(&nee) {
|
||||
pos as i64
|
||||
} else {
|
||||
-1
|
||||
}
|
||||
}
|
||||
|
||||
// box.from_i8_string(ptr) -> handle
|
||||
@ -181,7 +215,10 @@ pub extern "C" fn nyash_box_from_f64(val: f64) -> i64 {
|
||||
// Helper: build an IntegerBox and return a handle
|
||||
#[export_name = "nyash.box.from_i64"]
|
||||
pub extern "C" fn nyash_box_from_i64(val: i64) -> i64 {
|
||||
use nyash_rust::{box_trait::{NyashBox, IntegerBox}, jit::rt::handles};
|
||||
use nyash_rust::{
|
||||
box_trait::{IntegerBox, NyashBox},
|
||||
jit::rt::handles,
|
||||
};
|
||||
let arc: std::sync::Arc<dyn NyashBox> = std::sync::Arc::new(IntegerBox::new(val));
|
||||
handles::to_handle(arc) as i64
|
||||
}
|
||||
@ -545,8 +582,6 @@ pub extern "C" fn nyash_console_birth_h_export() -> i64 {
|
||||
0
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ArrayBox birth shim for AOT/JIT handle-based creation
|
||||
#[export_name = "nyash.array.birth_h"]
|
||||
pub extern "C" fn nyash_array_birth_h_export() -> i64 {
|
||||
|
||||
@ -9,28 +9,23 @@ pub extern "C" fn nyash_box_birth_h_export(type_id: i64) -> i64 {
|
||||
}
|
||||
let tid = type_id as u32;
|
||||
// Map type_id back to type name
|
||||
let name_opt = nyash_rust::runtime::plugin_loader_unified::get_global_plugin_host()
|
||||
.read()
|
||||
.ok()
|
||||
.and_then(|h| h.config_ref().map(|cfg| cfg.box_types.clone()))
|
||||
.and_then(|m| m.into_iter().find(|(_k, v)| *v == tid).map(|(k, _v)| k));
|
||||
if let Some(box_type) = name_opt {
|
||||
if let Some(meta) = nyash_rust::runtime::plugin_loader_v2::metadata_for_type_id(tid) {
|
||||
if let Ok(host_g) = nyash_rust::runtime::get_global_plugin_host().read() {
|
||||
if let Ok(b) = host_g.create_box(&box_type, &[]) {
|
||||
if let Ok(b) = host_g.create_box(&meta.box_type, &[]) {
|
||||
let arc: std::sync::Arc<dyn nyash_rust::box_trait::NyashBox> =
|
||||
std::sync::Arc::from(b);
|
||||
let h = nyash_rust::jit::rt::handles::to_handle(arc);
|
||||
if std::env::var("NYASH_CLI_VERBOSE").ok().as_deref() == Some("1") {
|
||||
println!(
|
||||
"nyrt: birth_h {} (type_id={}) -> handle={}",
|
||||
box_type, tid, h
|
||||
meta.box_type, meta.type_id, h
|
||||
);
|
||||
}
|
||||
return h as i64;
|
||||
} else if std::env::var("NYASH_CLI_VERBOSE").ok().as_deref() == Some("1") {
|
||||
eprintln!(
|
||||
"nyrt: birth_h {} (type_id={}) FAILED: create_box",
|
||||
box_type, tid
|
||||
meta.box_type, tid
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -47,33 +42,19 @@ pub extern "C" fn nyash_box_birth_i64_export(type_id: i64, argc: i64, a1: i64, a
|
||||
if type_id <= 0 {
|
||||
return 0;
|
||||
}
|
||||
let mut invoke: Option<
|
||||
unsafe extern "C" fn(u32, u32, u32, *const u8, usize, *mut u8, *mut usize) -> i32,
|
||||
> = None;
|
||||
// Resolve invoke_fn via temporary instance
|
||||
let box_type_name = nyash_rust::runtime::plugin_loader_unified::get_global_plugin_host()
|
||||
.read()
|
||||
.ok()
|
||||
.and_then(|h| h.config_ref().map(|cfg| cfg.box_types.clone()))
|
||||
.and_then(|m| {
|
||||
m.into_iter()
|
||||
.find(|(_k, v)| *v == (type_id as u32))
|
||||
.map(|(k, _v)| k)
|
||||
})
|
||||
.unwrap_or_else(|| "PluginBox".to_string());
|
||||
if let Ok(host_g) = nyash_rust::runtime::get_global_plugin_host().read() {
|
||||
if let Ok(b) = host_g.create_box(&box_type_name, &[]) {
|
||||
if let Some(p) = b.as_any().downcast_ref::<PluginBoxV2>() {
|
||||
invoke = Some(p.inner.invoke_fn);
|
||||
}
|
||||
}
|
||||
}
|
||||
if invoke.is_none() {
|
||||
// Resolve invoke_fn via loader metadata
|
||||
let meta = if let Some(meta) =
|
||||
nyash_rust::runtime::plugin_loader_v2::metadata_for_type_id(type_id as u32)
|
||||
{
|
||||
meta
|
||||
} else {
|
||||
if std::env::var("NYASH_CLI_VERBOSE").ok().as_deref() == Some("1") {
|
||||
eprintln!("nyrt: birth_i64 (type_id={}) FAILED: no invoke", type_id);
|
||||
eprintln!("nyrt: birth_i64 (type_id={}) FAILED: type map", type_id);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
let box_type_name = meta.box_type.clone();
|
||||
let invoke_fn = meta.invoke_fn;
|
||||
let method_id: u32 = 0; // birth
|
||||
let instance_id: u32 = 0; // static
|
||||
// Build TLV args
|
||||
@ -186,7 +167,7 @@ pub extern "C" fn nyash_box_birth_i64_export(type_id: i64, argc: i64, a1: i64, a
|
||||
let mut out = vec![0u8; 1024];
|
||||
let mut out_len: usize = out.len();
|
||||
let rc = unsafe {
|
||||
invoke.unwrap()(
|
||||
invoke_fn(
|
||||
type_id as u32,
|
||||
method_id,
|
||||
instance_id,
|
||||
@ -219,7 +200,7 @@ pub extern "C" fn nyash_box_birth_i64_export(type_id: i64, argc: i64, a1: i64, a
|
||||
box_type_name.clone(),
|
||||
r_type,
|
||||
r_inst,
|
||||
invoke.unwrap(),
|
||||
invoke_fn,
|
||||
);
|
||||
let arc: std::sync::Arc<dyn nyash_rust::box_trait::NyashBox> = std::sync::Arc::new(pb);
|
||||
let h = nyash_rust::jit::rt::handles::to_handle(arc);
|
||||
|
||||
@ -197,22 +197,20 @@ pub extern "C" fn nyash_future_spawn_method_h(
|
||||
let r_type = u32::from_le_bytes(t);
|
||||
let r_inst = u32::from_le_bytes(i);
|
||||
// Map type_id -> box type name (best-effort)
|
||||
let box_type_name =
|
||||
nyash_rust::runtime::plugin_loader_unified::get_global_plugin_host(
|
||||
)
|
||||
.read()
|
||||
.ok()
|
||||
.and_then(|h| h.config_ref().map(|cfg| cfg.box_types.clone()))
|
||||
.and_then(|m| {
|
||||
m.into_iter().find(|(_k, v)| *v == r_type).map(|(k, _v)| k)
|
||||
})
|
||||
.unwrap_or_else(|| "PluginBox".to_string());
|
||||
let meta_opt =
|
||||
nyash_rust::runtime::plugin_loader_v2::metadata_for_type_id(r_type);
|
||||
let (box_type_name, invoke_ptr, fini_id) = if let Some(meta) = meta_opt
|
||||
{
|
||||
(meta.box_type.clone(), meta.invoke_fn, meta.fini_method_id)
|
||||
} else {
|
||||
("PluginBox".to_string(), inv, None)
|
||||
};
|
||||
let pb = nyash_rust::runtime::plugin_loader_v2::construct_plugin_box(
|
||||
box_type_name,
|
||||
r_type,
|
||||
inv,
|
||||
invoke_ptr,
|
||||
r_inst,
|
||||
None,
|
||||
fini_id,
|
||||
);
|
||||
fut_box.set_result(Box::new(pb));
|
||||
return;
|
||||
@ -260,15 +258,8 @@ pub extern "C" fn nyash_future_spawn_instance3_i64(a0: i64, a1: i64, a2: i64, ar
|
||||
}
|
||||
let invoke = invoke.unwrap();
|
||||
// Determine box type name from type_id
|
||||
let box_type_name = nyash_rust::runtime::plugin_loader_unified::get_global_plugin_host()
|
||||
.read()
|
||||
.ok()
|
||||
.and_then(|h| h.config_ref().map(|cfg| cfg.box_types.clone()))
|
||||
.and_then(|m| {
|
||||
m.into_iter()
|
||||
.find(|(_k, v)| *v == real_type_id)
|
||||
.map(|(k, _v)| k)
|
||||
})
|
||||
let box_type_name = nyash_rust::runtime::plugin_loader_v2::metadata_for_type_id(real_type_id)
|
||||
.map(|meta| meta.box_type)
|
||||
.unwrap_or_else(|| "PluginBox".to_string());
|
||||
// Determine method name string (from a1 handle→StringBox, or a1 as C string pointer, or legacy VM args)
|
||||
let mut method_name: Option<String> = None;
|
||||
|
||||
@ -295,20 +295,18 @@ pub extern "C" fn nyash_plugin_invoke3_i64(
|
||||
let r_type = u32::from_le_bytes(t);
|
||||
let r_inst = u32::from_le_bytes(i);
|
||||
// Build PluginBoxV2 and register into handle-registry
|
||||
let box_type_name =
|
||||
nyash_rust::runtime::plugin_loader_unified::get_global_plugin_host()
|
||||
.read()
|
||||
.ok()
|
||||
.and_then(|h| h.config_ref().map(|cfg| cfg.box_types.clone()))
|
||||
.and_then(|m| {
|
||||
m.into_iter().find(|(_k, v)| *v == r_type).map(|(k, _v)| k)
|
||||
})
|
||||
.unwrap_or_else(|| "PluginBox".to_string());
|
||||
let meta_opt =
|
||||
nyash_rust::runtime::plugin_loader_v2::metadata_for_type_id(r_type);
|
||||
let (box_type_name, invoke_ptr) = if let Some(meta) = meta_opt {
|
||||
(meta.box_type.clone(), meta.invoke_fn)
|
||||
} else {
|
||||
("PluginBox".to_string(), invoke.unwrap())
|
||||
};
|
||||
let pb = nyash_rust::runtime::plugin_loader_v2::make_plugin_box_v2(
|
||||
box_type_name.clone(),
|
||||
r_type,
|
||||
r_inst,
|
||||
invoke.unwrap(),
|
||||
invoke_ptr,
|
||||
);
|
||||
let arc: std::sync::Arc<dyn nyash_rust::box_trait::NyashBox> =
|
||||
std::sync::Arc::new(pb);
|
||||
@ -977,11 +975,18 @@ pub extern "C" fn nyash_plugin_invoke_by_name_i64(
|
||||
i.copy_from_slice(&payload[4..8]);
|
||||
let r_type = u32::from_le_bytes(t);
|
||||
let r_inst = u32::from_le_bytes(i);
|
||||
let meta_opt =
|
||||
nyash_rust::runtime::plugin_loader_v2::metadata_for_type_id(r_type);
|
||||
let (box_type_name, invoke_ptr) = if let Some(meta) = meta_opt {
|
||||
(meta.box_type.clone(), meta.invoke_fn)
|
||||
} else {
|
||||
(box_type.clone(), invoke.unwrap())
|
||||
};
|
||||
let pb = nyash_rust::runtime::plugin_loader_v2::make_plugin_box_v2(
|
||||
box_type.clone(),
|
||||
box_type_name,
|
||||
r_type,
|
||||
r_inst,
|
||||
invoke.unwrap(),
|
||||
invoke_ptr,
|
||||
);
|
||||
let arc: std::sync::Arc<dyn nyash_rust::box_trait::NyashBox> =
|
||||
std::sync::Arc::new(pb);
|
||||
|
||||
@ -64,13 +64,27 @@ pub extern "C" fn nyash_map_get_h(handle: i64, key: i64) -> i64 {
|
||||
// get_hh: (map_handle, key_handle) -> value_handle
|
||||
#[export_name = "nyash.map.get_hh"]
|
||||
pub extern "C" fn nyash_map_get_hh(handle: i64, key_any: i64) -> i64 {
|
||||
use nyash_rust::{box_trait::{NyashBox, IntegerBox}, jit::rt::handles};
|
||||
if handle <= 0 { return 0; }
|
||||
use nyash_rust::{
|
||||
box_trait::{IntegerBox, NyashBox},
|
||||
jit::rt::handles,
|
||||
};
|
||||
if handle <= 0 {
|
||||
return 0;
|
||||
}
|
||||
if let Some(obj) = handles::get(handle as u64) {
|
||||
if let Some(map) = obj.as_any().downcast_ref::<nyash_rust::boxes::map_box::MapBox>() {
|
||||
if let Some(map) = obj
|
||||
.as_any()
|
||||
.downcast_ref::<nyash_rust::boxes::map_box::MapBox>()
|
||||
{
|
||||
let key_box: Box<dyn NyashBox> = if key_any > 0 {
|
||||
if let Some(k) = handles::get(key_any as u64) { k.clone_box() } else { Box::new(IntegerBox::new(key_any)) }
|
||||
} else { Box::new(IntegerBox::new(key_any)) };
|
||||
if let Some(k) = handles::get(key_any as u64) {
|
||||
k.clone_box()
|
||||
} else {
|
||||
Box::new(IntegerBox::new(key_any))
|
||||
}
|
||||
} else {
|
||||
Box::new(IntegerBox::new(key_any))
|
||||
};
|
||||
let v = map.get(key_box);
|
||||
let arc: std::sync::Arc<dyn NyashBox> = std::sync::Arc::from(v);
|
||||
let h = handles::to_handle(arc);
|
||||
@ -80,7 +94,6 @@ pub extern "C" fn nyash_map_get_hh(handle: i64, key_any: i64) -> i64 {
|
||||
0
|
||||
}
|
||||
|
||||
|
||||
// set_h: (map_handle, key_i64, val) -> i64 (ignored/0)
|
||||
#[export_name = "nyash.map.set_h"]
|
||||
pub extern "C" fn nyash_map_set_h(handle: i64, key: i64, val: i64) -> i64 {
|
||||
@ -125,20 +138,39 @@ pub extern "C" fn nyash_map_set_h(handle: i64, key: i64, val: i64) -> i64 {
|
||||
0
|
||||
}
|
||||
|
||||
|
||||
// set_hh: (map_handle, key_any: handle or i64, val_any: handle or i64) -> i64
|
||||
#[export_name = "nyash.map.set_hh"]
|
||||
pub extern "C" fn nyash_map_set_hh(handle: i64, key_any: i64, val_any: i64) -> i64 {
|
||||
use nyash_rust::{box_trait::{NyashBox, IntegerBox}, jit::rt::handles};
|
||||
if handle <= 0 { return 0; }
|
||||
use nyash_rust::{
|
||||
box_trait::{IntegerBox, NyashBox},
|
||||
jit::rt::handles,
|
||||
};
|
||||
if handle <= 0 {
|
||||
return 0;
|
||||
}
|
||||
if let Some(obj) = handles::get(handle as u64) {
|
||||
if let Some(map) = obj.as_any().downcast_ref::<nyash_rust::boxes::map_box::MapBox>() {
|
||||
if let Some(map) = obj
|
||||
.as_any()
|
||||
.downcast_ref::<nyash_rust::boxes::map_box::MapBox>()
|
||||
{
|
||||
let kbox: Box<dyn NyashBox> = if key_any > 0 {
|
||||
if let Some(k) = handles::get(key_any as u64) { k.clone_box() } else { Box::new(IntegerBox::new(key_any)) }
|
||||
} else { Box::new(IntegerBox::new(key_any)) };
|
||||
if let Some(k) = handles::get(key_any as u64) {
|
||||
k.clone_box()
|
||||
} else {
|
||||
Box::new(IntegerBox::new(key_any))
|
||||
}
|
||||
} else {
|
||||
Box::new(IntegerBox::new(key_any))
|
||||
};
|
||||
let vbox: Box<dyn NyashBox> = if val_any > 0 {
|
||||
if let Some(v) = handles::get(val_any as u64) { v.clone_box() } else { Box::new(IntegerBox::new(val_any)) }
|
||||
} else { Box::new(IntegerBox::new(val_any)) };
|
||||
if let Some(v) = handles::get(val_any as u64) {
|
||||
v.clone_box()
|
||||
} else {
|
||||
Box::new(IntegerBox::new(val_any))
|
||||
}
|
||||
} else {
|
||||
Box::new(IntegerBox::new(val_any))
|
||||
};
|
||||
let _ = map.set(kbox, vbox);
|
||||
return 0;
|
||||
}
|
||||
@ -149,15 +181,31 @@ pub extern "C" fn nyash_map_set_hh(handle: i64, key_any: i64, val_any: i64) -> i
|
||||
// has_hh: (map_handle, key_any: handle or i64) -> i64 (0/1)
|
||||
#[export_name = "nyash.map.has_hh"]
|
||||
pub extern "C" fn nyash_map_has_hh(handle: i64, key_any: i64) -> i64 {
|
||||
use nyash_rust::{box_trait::{NyashBox, IntegerBox, BoolBox}, jit::rt::handles};
|
||||
if handle <= 0 { return 0; }
|
||||
use nyash_rust::{
|
||||
box_trait::{BoolBox, IntegerBox, NyashBox},
|
||||
jit::rt::handles,
|
||||
};
|
||||
if handle <= 0 {
|
||||
return 0;
|
||||
}
|
||||
if let Some(obj) = handles::get(handle as u64) {
|
||||
if let Some(map) = obj.as_any().downcast_ref::<nyash_rust::boxes::map_box::MapBox>() {
|
||||
if let Some(map) = obj
|
||||
.as_any()
|
||||
.downcast_ref::<nyash_rust::boxes::map_box::MapBox>()
|
||||
{
|
||||
let kbox: Box<dyn NyashBox> = if key_any > 0 {
|
||||
if let Some(k) = handles::get(key_any as u64) { k.clone_box() } else { Box::new(IntegerBox::new(key_any)) }
|
||||
} else { Box::new(IntegerBox::new(key_any)) };
|
||||
if let Some(k) = handles::get(key_any as u64) {
|
||||
k.clone_box()
|
||||
} else {
|
||||
Box::new(IntegerBox::new(key_any))
|
||||
}
|
||||
} else {
|
||||
Box::new(IntegerBox::new(key_any))
|
||||
};
|
||||
let v = map.has(kbox);
|
||||
if let Some(b) = v.as_any().downcast_ref::<BoolBox>() { return if b.value { 1 } else { 0 }; }
|
||||
if let Some(b) = v.as_any().downcast_ref::<BoolBox>() {
|
||||
return if b.value { 1 } else { 0 };
|
||||
}
|
||||
}
|
||||
}
|
||||
0
|
||||
@ -177,7 +225,9 @@ pub extern "C" fn nyash_map_has_h(handle: i64, key: i64) -> i64 {
|
||||
{
|
||||
let kbox = Box::new(IntegerBox::new(key));
|
||||
let v = map.has(kbox);
|
||||
if let Some(b) = v.as_any().downcast_ref::<nyash_rust::box_trait::BoolBox>() { return if b.value { 1 } else { 0 }; }
|
||||
if let Some(b) = v.as_any().downcast_ref::<nyash_rust::box_trait::BoolBox>() {
|
||||
return if b.value { 1 } else { 0 };
|
||||
}
|
||||
}
|
||||
}
|
||||
0
|
||||
|
||||
@ -83,7 +83,7 @@ pub extern "C" fn nyash_string_concat_is(a: i64, b: *const i8) -> *mut i8 {
|
||||
// Exported as: nyash.string.substring_sii(i8* s, i64 start, i64 end) -> i8*
|
||||
#[export_name = "nyash.string.substring_sii"]
|
||||
pub extern "C" fn nyash_string_substring_sii(s: *const i8, start: i64, end: i64) -> *mut i8 {
|
||||
use std::ffi::CStr;
|
||||
use std::ffi::CStr;
|
||||
if s.is_null() {
|
||||
return std::ptr::null_mut();
|
||||
}
|
||||
@ -95,9 +95,15 @@ use std::ffi::CStr;
|
||||
let n = src.len() as i64;
|
||||
let mut st = if start < 0 { 0 } else { start };
|
||||
let mut en = if end < 0 { 0 } else { end };
|
||||
if st > n { st = n; }
|
||||
if en > n { en = n; }
|
||||
if en < st { std::mem::swap(&mut st, &mut en); }
|
||||
if st > n {
|
||||
st = n;
|
||||
}
|
||||
if en > n {
|
||||
en = n;
|
||||
}
|
||||
if en < st {
|
||||
std::mem::swap(&mut st, &mut en);
|
||||
}
|
||||
let (st_u, en_u) = (st as usize, en as usize);
|
||||
let sub = &src[st_u.min(src.len())..en_u.min(src.len())];
|
||||
let mut bytes = sub.as_bytes().to_vec();
|
||||
@ -111,15 +117,27 @@ use std::ffi::CStr;
|
||||
#[export_name = "nyash.string.lastIndexOf_ss"]
|
||||
pub extern "C" fn nyash_string_lastindexof_ss(s: *const i8, needle: *const i8) -> i64 {
|
||||
use std::ffi::CStr;
|
||||
if s.is_null() || needle.is_null() { return -1; }
|
||||
if s.is_null() || needle.is_null() {
|
||||
return -1;
|
||||
}
|
||||
let hs = unsafe { CStr::from_ptr(s) };
|
||||
let ns = unsafe { CStr::from_ptr(needle) };
|
||||
let h = match hs.to_str() { Ok(v) => v, Err(_) => return -1 };
|
||||
let n = match ns.to_str() { Ok(v) => v, Err(_) => return -1 };
|
||||
if n.is_empty() { return h.len() as i64; }
|
||||
let h = match hs.to_str() {
|
||||
Ok(v) => v,
|
||||
Err(_) => return -1,
|
||||
};
|
||||
let n = match ns.to_str() {
|
||||
Ok(v) => v,
|
||||
Err(_) => return -1,
|
||||
};
|
||||
if n.is_empty() {
|
||||
return h.len() as i64;
|
||||
}
|
||||
if let Some(pos) = h.rfind(n) {
|
||||
pos as i64
|
||||
} else { -1 }
|
||||
} else {
|
||||
-1
|
||||
}
|
||||
}
|
||||
|
||||
// Exported as: nyash.string.to_i8p_h(i64 handle) -> i8*
|
||||
|
||||
Reference in New Issue
Block a user