Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
/target
*.wasm
*.mrb
*.mrb

.claude/
50 changes: 9 additions & 41 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions mruby-math/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
[package]
name = "mrubyedge-math"
version = "0.1.0"
version = "0.1.1"
edition = "2024"
authors = ["Uchio Kondo <[email protected]>"]
description = "mruby-math provides Math module for mruby/edge"
license = "BSD-3-Clause"

[dependencies]
mrubyedge = { version = ">= 1.1.3" }
mrubyedge = { path = "../mrubyedge" }

[dev-dependencies]
mrubyedge = { version = ">= 1.1.3", features = ["default"] }
mrubyedge = { path = "../mrubyedge", features = ["default"] }
mec-mrbc-sys = "3.3.1"
26 changes: 7 additions & 19 deletions mruby-math/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,14 +107,8 @@ fn get_float_arg(obj: &RObject) -> Result<f64, Error> {
}
}

// Helper function to check argument count (excluding trailing nil)
// Helper function to check argument count
fn check_args_count(args: &[Rc<RObject>], expected: usize) -> Result<Vec<Rc<RObject>>, Error> {
let args = if !args.is_empty() && args[args.len() - 1].is_nil() {
&args[0..args.len() - 1]
} else {
args
};

if args.len() != expected {
return Err(Error::ArgumentError(format!(
"wrong number of arguments (given {}, expected {})",
Expand Down Expand Up @@ -217,23 +211,17 @@ pub fn mrb_math_exp(_vm: &mut VM, args: &[Rc<RObject>]) -> Result<Rc<RObject>, E
}

pub fn mrb_math_log(_vm: &mut VM, args: &[Rc<RObject>]) -> Result<Rc<RObject>, Error> {
let args_vec = if !args.is_empty() && args[args.len() - 1].is_nil() {
args[0..args.len() - 1].to_vec()
} else {
args.to_vec()
};

if args_vec.len() == 1 {
let x = get_float_arg(&args_vec[0])?;
if args.len() == 1 {
let x = get_float_arg(&args[0])?;
Ok(RObject::float(x.ln()).to_refcount_assigned())
} else if args_vec.len() == 2 {
let x = get_float_arg(&args_vec[0])?;
let base = get_float_arg(&args_vec[1])?;
} else if args.len() == 2 {
let x = get_float_arg(&args[0])?;
let base = get_float_arg(&args[1])?;
Ok(RObject::float(x.log(base)).to_refcount_assigned())
} else {
Err(Error::ArgumentError(format!(
"wrong number of arguments (given {}, expected 1..2)",
args_vec.len()
args.len()
)))
}
}
Expand Down
7 changes: 3 additions & 4 deletions mruby-serde-json/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
[package]
name = "mrubyedge-serde-json"
version = "0.1.0"
version = "0.1.1"
edition = "2024"
authors = ["Uchio Kondo <[email protected]>"]
description = "mruby-serde-json provides JSON serialization/deserialization for mruby/edge using serde_json"
license = "BSD-3-Clause"

[dependencies]
mrubyedge = ">= 1.1.3"
# mrubyedge = { version = "1.1.3", path = "../mrubyedge", default-features = false }
mrubyedge = { path = "../mrubyedge" }
serde = ">= 1.0.228"
serde_json = ">= 1.0.149"

[dev-dependencies]
mrubyedge = { version = ">= 1.1.3", features = ["default"] }
mrubyedge = { path = "../mrubyedge", features = ["default"] }
mec-mrbc-sys = "3.3.1"
10 changes: 0 additions & 10 deletions mruby-serde-json/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,6 @@ pub fn init_json(vm: &mut VM) {
}

pub fn mrb_json_class_dump(vm: &mut VM, args: &[Rc<RObject>]) -> Result<Rc<RObject>, Error> {
let args = if args[args.len() - 1].is_nil() {
&args[0..args.len() - 1]
} else {
args
};
if args.len() != 1 {
return Err(Error::ArgumentError(
"wrong number of arguments".to_string(),
Expand All @@ -52,11 +47,6 @@ pub fn mrb_json_class_dump(vm: &mut VM, args: &[Rc<RObject>]) -> Result<Rc<RObje
}

pub fn mrb_json_class_load(vm: &mut VM, args: &[Rc<RObject>]) -> Result<Rc<RObject>, Error> {
let args = if args[args.len() - 1].is_nil() {
&args[0..args.len() - 1]
} else {
args
};
if args.len() != 1 {
return Err(Error::ArgumentError(
"wrong number of arguments".to_string(),
Expand Down
6 changes: 3 additions & 3 deletions mruby-time/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
[package]
name = "mrubyedge-time"
version = "0.1.1"
version = "0.1.2"
edition = "2024"
authors = ["Uchio Kondo <[email protected]>"]
description = "mruby-time provides Time class for mruby/edge"
license = "BSD-3-Clause"

[dependencies]
mrubyedge = ">= 1.1.8"
mrubyedge = { path = "../mrubyedge" }
libc = "0.2"

[dev-dependencies]
mrubyedge = { version = ">= 1.1.8", features = ["default"] }
mrubyedge = { path = "../mrubyedge", features = ["default"] }
mec-mrbc-sys = "3.3.1"

[features]
Expand Down
13 changes: 0 additions & 13 deletions mruby-time/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,6 @@ fn mrb_time_now(vm: &mut VM, _args: &[Rc<RObject>]) -> Result<Rc<RObject>, Error

/// Time.at(sec) or Time.at(sec, nsec)
fn mrb_time_at(vm: &mut VM, args: &[Rc<RObject>]) -> Result<Rc<RObject>, Error> {
let args = strip_trailing_nil(args);
if args.is_empty() {
return Err(Error::ArgumentError(
"wrong number of arguments (given 0, expected 1+)".to_string(),
Expand Down Expand Up @@ -253,7 +252,6 @@ fn mrb_time_to_s(vm: &mut VM, _args: &[Rc<RObject>]) -> Result<Rc<RObject>, Erro

/// Time#+ (sec as integer or float)
fn mrb_time_add(vm: &mut VM, args: &[Rc<RObject>]) -> Result<Rc<RObject>, Error> {
let args = strip_trailing_nil(args);
if args.is_empty() {
return Err(Error::ArgumentError(
"wrong number of arguments (given 0, expected 1)".to_string(),
Expand All @@ -276,7 +274,6 @@ fn mrb_time_add(vm: &mut VM, args: &[Rc<RObject>]) -> Result<Rc<RObject>, Error>

/// Time#- (sec as integer or float), also supports Time - Time -> Float (seconds)
fn mrb_time_sub(vm: &mut VM, args: &[Rc<RObject>]) -> Result<Rc<RObject>, Error> {
let args = strip_trailing_nil(args);
if args.is_empty() {
return Err(Error::ArgumentError(
"wrong number of arguments (given 0, expected 1)".to_string(),
Expand Down Expand Up @@ -309,7 +306,6 @@ fn mrb_time_sub(vm: &mut VM, args: &[Rc<RObject>]) -> Result<Rc<RObject>, Error>

/// Time#<=> (compare with another Time object)
fn mrb_time_cmp(vm: &mut VM, args: &[Rc<RObject>]) -> Result<Rc<RObject>, Error> {
let args = strip_trailing_nil(args);
if args.is_empty() {
return Err(Error::ArgumentError(
"wrong number of arguments (given 0, expected 1)".to_string(),
Expand Down Expand Up @@ -345,7 +341,6 @@ fn mrb_time_utc_offset(vm: &mut VM, _args: &[Rc<RObject>]) -> Result<Rc<RObject>

/// Time#localtime(offset) - returns a new Time with the given UTC offset (in seconds)
fn mrb_time_localtime(vm: &mut VM, args: &[Rc<RObject>]) -> Result<Rc<RObject>, Error> {
let args = strip_trailing_nil(args);
let self_obj = vm.getself()?;
let t = get_time_data(&self_obj)?;

Expand Down Expand Up @@ -424,14 +419,6 @@ fn local_utc_offset_secs() -> i32 {
// Helper utilities
// ---------------------------------------------------------------------------

fn strip_trailing_nil(args: &[Rc<RObject>]) -> &[Rc<RObject>] {
if !args.is_empty() && args[args.len() - 1].is_nil() {
&args[0..args.len() - 1]
} else {
args
}
}

fn get_integer_or_float_as_i64(obj: &RObject) -> Result<i64, Error> {
match &obj.value {
RValue::Integer(i) => Ok(*i),
Expand Down
1 change: 1 addition & 0 deletions mruby-time/tests/smoke.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ mod helpers;
use helpers::*;

/// Helper: build a VM with Time initialized and a fixed Time.__source returning [sec, nsec].
#[allow(unused)]
fn make_vm_with_time_source(sec: i64, nsec: u32) -> mrubyedge::yamrb::vm::VM {
use mrubyedge::yamrb::helpers::mrb_define_singleton_cmethod;
use mrubyedge::yamrb::value::RObject;
Expand Down
6 changes: 3 additions & 3 deletions mrubyedge-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ path = "src/main.rs"
clap = { version = "4.5", features = ["derive"] }
crossterm = "0.28"
mruby-compiler2-sys = "0.3.0"
mrubyedge = { version = "1.1.7", features = [
mrubyedge = { path = "../mrubyedge", features = [
"default",
"mruby-random",
"mruby-regexp",
] }
mrubyedge-math = "0.1.0"
mrubyedge-time = "0.1.1"
mrubyedge-math = { path = "../mruby-math" }
mrubyedge-time = { path = "../mruby-time" }
rand = "0.9.2"
nom = "7.1.3"
askama = "0.12.1"
Expand Down
4 changes: 4 additions & 0 deletions mrubyedge/COVERAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ A list of currently supported classes and methods, based on the implementations
| `#method_missing` | |
| `#extend` | |
| `#loop` | |
| `#block_given?` | |
| `#respond_to?` | |
| `#public_send` | |
| `#wasm?` | mruby/edge specific |
| `#puts` | `[feature: wasi]` only |
| `#p` | `[feature: wasi]` only |
Expand Down Expand Up @@ -209,6 +212,7 @@ Exception
|---|---|
| `#to_s` | |
| `#inspect` | `:sym` format |
| `#to_proc` | converts symbol to a proc that calls the method |

---

Expand Down
35 changes: 23 additions & 12 deletions mrubyedge/src/yamrb/optable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,7 @@ pub(crate) fn push_callinfo(
return_reg,
target_class: vm.target_class.clone(),
method_owner,
has_block: Cell::new(false),
};
vm.current_callinfo = Some(Rc::new(callinfo));
}
Expand Down Expand Up @@ -1023,11 +1024,16 @@ pub(crate) fn do_op_send(
vm.kargs.borrow_mut().replace(map);

if let Some(blk_index) = blk_index {
args.push(vm.get_current_regs_cloned(blk_index)?);
let blk_val = vm.get_current_regs_cloned(blk_index)?;
if matches!(blk_val.tt, RType::Symbol) {
let proc_val = mrb_funcall(vm, Some(blk_val), "to_proc", &[])?;
args.push(proc_val);
} else {
args.push(blk_val);
}
} else {
// When no block is provided, set nil in the block register
// When no block is provided, do not push a nil placeholder
vm.current_regs()[block_index].replace(Rc::new(RObject::nil()));
args.push(Rc::new(RObject::nil()));
}

let klass = recv.get_class(vm);
Expand Down Expand Up @@ -1099,6 +1105,11 @@ pub(crate) fn do_op_send(

push_callinfo(vm, method_id, n, Some(owner_module), a as usize);

// Set has_block flag based on whether a block was provided
if let Some(ci) = vm.current_callinfo.as_ref() {
ci.has_block.set(blk_index.is_some());
}

vm.pc.set(0);
vm.current_irep = method.irep.ok_or_else(|| Error::internal("empry irep"))?;
vm.current_regs_offset += a as usize;
Expand Down Expand Up @@ -1253,15 +1264,15 @@ pub(crate) fn op_super(vm: &mut VM, operand: &Fetched) -> Result<(), Error> {
}

#[allow(dead_code)]
#[derive(Debug)]
struct EnterArgInfo {
m1: u32,
o: u32,
r: u32,
m2: u32,
k: u32,
d: u32,
b: u32,
#[derive(Debug, Copy, Clone)]
pub(crate) struct EnterArgInfo {
pub m1: u32,
pub o: u32,
pub r: u32,
pub m2: u32,
pub k: u32,
pub d: u32,
pub b: u32,
}

impl From<u32> for EnterArgInfo {
Expand Down
Loading