Skip to content

Commit

Permalink
Support Array#all?.
Browse files Browse the repository at this point in the history
  • Loading branch information
sisshiki1969 committed Nov 9, 2023
1 parent ad4df12 commit cbf2b53
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 11 deletions.
40 changes: 40 additions & 0 deletions monoruby/src/builtins/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ pub(super) fn init(globals: &mut Globals) {
globals.define_builtin_func(ARRAY_CLASS, "map", map);
globals.define_builtin_func(ARRAY_CLASS, "flat_map", flat_map);
globals.define_builtin_func(ARRAY_CLASS, "collect_concat", flat_map);
globals.define_builtin_func(ARRAY_CLASS, "all?", all_);
globals.define_builtin_func(ARRAY_CLASS, "detect", detect);
globals.define_builtin_func(ARRAY_CLASS, "find", detect);
globals.define_builtin_func(ARRAY_CLASS, "grep", grep);
Expand Down Expand Up @@ -874,6 +875,36 @@ fn flat_map(vm: &mut Executor, globals: &mut Globals, lfp: LFP, _: Arg) -> Resul
Ok(Value::array_from_vec(v))
}

///
/// #### Array#all?
///
/// - all? -> bool
/// - all? {|item| ... } -> bool
/// - [NOT SUPPORTED] all?(pattern) -> bool
///
/// [https://docs.ruby-lang.org/ja/latest/method/Array/i/all=3f.html]
#[monoruby_builtin]
fn all_(vm: &mut Executor, globals: &mut Globals, lfp: LFP, _arg: Arg) -> Result<Value> {
let len = lfp.arg_len();
MonorubyErr::check_number_of_arguments(len, 0)?;
let ary: Array = lfp.self_val().into();
if let Some(bh) = lfp.block() {
let data = globals.get_block_data(vm.cfp(), bh);
for elem in ary.iter() {
if !vm.invoke_block(globals, &data, &[*elem])?.as_bool() {
return Ok(Value::bool(false));
};
}
} else {
for elem in ary.iter() {
if !elem.as_bool() {
return Ok(Value::bool(false));
};
}
}
Ok(Value::bool(true))
}

///
/// #### Enumerable#detect
///
Expand Down Expand Up @@ -1657,6 +1688,15 @@ mod test {
);
}

#[test]
fn all_() {
run_test(r#"[5, 6, 7].all? {|v| v > 0 }"#);
run_test(r#"[5, -1, 7].all? {|v| v > 0 }"#);
run_test(r#"[5, -1, 7].all?"#);
run_test(r#"[5, nil, 7].all?"#);
run_test(r#"[5, -1, false].all?"#);
}

#[test]
fn detect() {
run_test(r#"[1, 2, 3, 4, 5].find {|i| i % 3 == 0 }"#);
Expand Down
4 changes: 2 additions & 2 deletions monoruby/src/executor/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -772,11 +772,11 @@ impl Codegen {
movq rdi, rax;
movzxw rdx, [rsi + 8]; // rdx <- req
lea rsi, [rsp - (16 + LBP_ARG0)]; // rsi <- dst
subq rsp, 1024;
subq rsp, 4096;
movq rax, (block_expand_array); // extern "C" fn block_expand_array(src: Value, dst: *mut Value, min_len: usize) -> usize
call rax;
movq rdi, rax;
addq rsp, 1024;
addq rsp, 4096;
l1:
};
}
Expand Down
11 changes: 10 additions & 1 deletion monoruby/src/executor/compiler/jitgen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ pub mod trace_ir;
/// Context for JIT compilation.
///
struct JitContext {
fid: FuncId,
///
/// Destination labels for jump instructions.
///
Expand Down Expand Up @@ -137,6 +138,7 @@ impl JitContext {
let total_reg_num = func.total_reg_num();
let local_num = func.local_num();
Self {
fid: func.id(),
labels,
bb_scan,
loop_backedges: HashMap::default(),
Expand Down Expand Up @@ -245,6 +247,7 @@ impl WriteBack {
///
#[derive(Debug, Clone, PartialEq)]
pub(crate) struct BBContext {
fid: FuncId,
/// Information for stack slots.
slot_state: SlotState,
/// Stack top register.
Expand All @@ -270,6 +273,7 @@ impl std::ops::DerefMut for BBContext {
impl BBContext {
fn new(cc: &JitContext) -> Self {
Self {
fid: cc.fid,
slot_state: SlotState::new(cc),
sp: SlotId(cc.local_num as u16),
next_sp: SlotId(cc.local_num as u16),
Expand All @@ -288,7 +292,12 @@ impl BBContext {

fn merge(&mut self, other: &Self) {
if self.sp != other.sp {
eprintln!("sp mismatch: {:?} {:?}", self.sp, other.sp);
eprintln!(
"in {:?} sp mismatch: {:?} {:?}",
self.fid, self.sp, other.sp
);
eprintln!("self: {:?}", self.slot_state);
eprintln!("other: {:?}", other.slot_state);
panic!();
};
self.slot_state.merge(&other.slot_state);
Expand Down
8 changes: 4 additions & 4 deletions monoruby/src/executor/compiler/jitgen/method_call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -511,7 +511,7 @@ impl Codegen {
if !callsite.hash_splat_pos.is_empty() {
monoasm! { &mut self.jit,
lea rcx, [rsp - (16 + LBP_SELF)];
subq rsp, 1016;
subq rsp, 4088;
pushq rdi;
movq rdi, rbx;
movq rsi, r12;
Expand All @@ -520,7 +520,7 @@ impl Codegen {
movq rax, (runtime::jit_handle_hash_splat);
call rax;
popq rdi;
addq rsp, 1016;
addq rsp, 4088;
}
}
} else {
Expand Down Expand Up @@ -702,7 +702,7 @@ impl Codegen {
if has_splat {
monoasm!( &mut self.jit,
lea r8, [rsp - (16 + LBP_ARG0)];
subq rsp, 1016;
subq rsp, 4088;
pushq r15;
movq r15, r8;
movq r8, (pos_num);
Expand Down Expand Up @@ -733,7 +733,7 @@ impl Codegen {
}
monoasm!( &mut self.jit,
popq r15;
addq rsp, 1016;
addq rsp, 4088;
movq rdi, r8;
);
} else {
Expand Down
4 changes: 2 additions & 2 deletions monoruby/src/executor/compiler/vmgen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -620,14 +620,14 @@ impl Codegen {
fn invoker_call(&mut self) {
monoasm! { &mut self.jit,
lea rsi, [rsp - 16];
subq rsp, 1024;
subq rsp, 4096;
movq rdx, rdi; // arg_num
movq rdi, r12; // &Globals
movq rax, (runtime::handle_invoker_arguments);
call rax;
// set arg len
movq rdx, rax;
addq rsp, 1024;
addq rsp, 4096;
}
self.push_frame();
self.set_lfp();
Expand Down
4 changes: 2 additions & 2 deletions monoruby/src/executor/compiler/wrapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,10 @@ impl Codegen {
movl rsi, [r14 - (LBP_META_FUNCID)];
movq rdx, [r14 - (LBP_SELF)];
movq rcx, (entry.to_usize());
subq rsp, 1032;
subq rsp, 4088;
movq rax, (exec_jit_compile_patch);
call rax;
addq rsp, 1032;
addq rsp, 4088;
jmp entry;
);
}
Expand Down

0 comments on commit cbf2b53

Please sign in to comment.