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
2 changes: 1 addition & 1 deletion ext/win32/resolv/extconf.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
require 'mkmf'
if RUBY_ENGINE == "ruby" and have_library('iphlpapi', 'GetNetworkParams')
if RUBY_ENGINE == "ruby" and have_library('iphlpapi', 'GetNetworkParams', ['windows.h', 'iphlpapi.h'])
create_makefile('win32/resolv')
else
File.write('Makefile', "all clean install:\n\t@echo Done: $(@)\n")
Expand Down
75 changes: 75 additions & 0 deletions test/ruby/test_zjit.rb
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,16 @@ def test
}, insns: [:setglobal]
end

def test_string_intern
assert_compiles ':foo123', %q{
def test
:"foo#{123}"
end

test
}, insns: [:intern]
end

def test_setglobal_with_trace_var_exception
assert_compiles '"rescued"', %q{
def test
Expand Down Expand Up @@ -1343,6 +1353,71 @@ def test(mod)
}, call_threshold: 2
end

def test_objtostring_calls_to_s_on_non_strings
assert_compiles '["foo", "foo"]', %q{
results = []

class Foo
def to_s
"foo"
end
end

def test(str)
"#{str}"
end

results << test(Foo.new)
results << test(Foo.new)

results
}
end

def test_objtostring_rewrite_does_not_call_to_s_on_strings
assert_compiles '["foo", "foo"]', %q{
results = []

class String
def to_s
"bad"
end
end

def test(foo)
"#{foo}"
end

results << test("foo")
results << test("foo")

results
}
end

def test_objtostring_rewrite_does_not_call_to_s_on_string_subclasses
assert_compiles '["foo", "foo"]', %q{
results = []

class StringSubclass < String
def to_s
"bad"
end
end

foo = StringSubclass.new("foo")

def test(str)
"#{str}"
end

results << test(foo)
results << test(foo)

results
}
end

def test_string_bytesize_with_guard
assert_compiles '5', %q{
def test(str)
Expand Down
8 changes: 8 additions & 0 deletions vm_insnhelper.c
Original file line number Diff line number Diff line change
Expand Up @@ -6209,6 +6209,14 @@ vm_objtostring(const rb_iseq_t *iseq, VALUE recv, CALL_DATA cd)
return Qundef;
}

// ZJIT implementation is using the C function
// and needs to call a non-static function
VALUE
rb_vm_objtostring(const rb_iseq_t *iseq, VALUE recv, CALL_DATA cd)
{
return vm_objtostring(iseq, recv, cd);
}

static VALUE
vm_opt_ary_freeze(VALUE ary, int bop, ID id)
{
Expand Down
2 changes: 0 additions & 2 deletions zjit/src/asm/arm64/inst/branch_cond.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ impl From<BranchCond> for [u8; 4] {
}
}

/*
#[cfg(test)]
mod tests {
use super::*;
Expand Down Expand Up @@ -77,4 +76,3 @@ mod tests {
assert_eq!(0x54800000, result);
}
}
*/
2 changes: 0 additions & 2 deletions zjit/src/asm/arm64/inst/conditional.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ impl From<Conditional> for [u8; 4] {
}
}

/*
#[cfg(test)]
mod tests {
use super::*;
Expand All @@ -72,4 +71,3 @@ mod tests {
assert_eq!(0x9a821020, result);
}
}
*/
28 changes: 0 additions & 28 deletions zjit/src/asm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,6 @@ pub fn uimm_num_bits(uimm: u64) -> u8
return 64;
}

/*
#[cfg(test)]
mod tests
{
Expand Down Expand Up @@ -381,32 +380,5 @@ mod tests
assert_eq!(uimm_num_bits((u32::MAX as u64) + 1), 64);
assert_eq!(uimm_num_bits(u64::MAX), 64);
}

#[test]
fn test_code_size() {
// Write 4 bytes in the first page
let mut cb = CodeBlock::new_dummy(CodeBlock::PREFERRED_CODE_PAGE_SIZE * 2);
cb.write_bytes(&[0, 0, 0, 0]);
assert_eq!(cb.code_size(), 4);

// Moving to the next page should not increase code_size
cb.next_page(cb.get_write_ptr(), |_, _| {});
assert_eq!(cb.code_size(), 4);

// Write 4 bytes in the second page
cb.write_bytes(&[0, 0, 0, 0]);
assert_eq!(cb.code_size(), 8);

// Rewrite 4 bytes in the first page
let old_write_pos = cb.get_write_pos();
cb.set_pos(0);
cb.write_bytes(&[1, 1, 1, 1]);

// Moving from an old page to the next page should not increase code_size
cb.next_page(cb.get_write_ptr(), |_, _| {});
cb.set_pos(old_write_pos);
assert_eq!(cb.code_size(), 8);
}
}

*/
68 changes: 0 additions & 68 deletions zjit/src/asm/x86_64/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -317,34 +317,6 @@ pub fn mem_opnd_sib(num_bits: u8, base_opnd: X86Opnd, index_opnd: X86Opnd, scale
}
}

/*
// Struct member operand
#define member_opnd(base_reg, struct_type, member_name) mem_opnd( \
8 * sizeof(((struct_type*)0)->member_name), \
base_reg, \
offsetof(struct_type, member_name) \
)

// Struct member operand with an array index
#define member_opnd_idx(base_reg, struct_type, member_name, idx) mem_opnd( \
8 * sizeof(((struct_type*)0)->member_name[0]), \
base_reg, \
(offsetof(struct_type, member_name) + \
sizeof(((struct_type*)0)->member_name[0]) * idx) \
)
*/

/*
// TODO: this should be a method, X86Opnd.resize() or X86Opnd.subreg()
static x86opnd_t resize_opnd(x86opnd_t opnd, uint32_t num_bits)
{
assert (num_bits % 8 == 0);
x86opnd_t sub = opnd;
sub.num_bits = num_bits;
return sub;
}
*/

pub fn imm_opnd(value: i64) -> X86Opnd
{
X86Opnd::Imm(X86Imm { num_bits: imm_num_bits(value), value })
Expand Down Expand Up @@ -1103,46 +1075,6 @@ pub fn movsx(cb: &mut CodeBlock, dst: X86Opnd, src: X86Opnd) {
}
}

/*
/// movzx - Move with zero extension (unsigned values)
void movzx(codeblock_t *cb, x86opnd_t dst, x86opnd_t src)
{
cb.writeASM("movzx", dst, src);

uint32_t dstSize;
if (dst.isReg)
dstSize = dst.reg.size;
else
assert (false, "movzx dst must be a register");

uint32_t srcSize;
if (src.isReg)
srcSize = src.reg.size;
else if (src.isMem)
srcSize = src.mem.size;
else
assert (false);

assert (
srcSize < dstSize,
"movzx: srcSize >= dstSize"
);

if (srcSize is 8)
{
cb.writeRMInstr!('r', 0xFF, 0x0F, 0xB6)(dstSize is 16, dstSize is 64, dst, src);
}
else if (srcSize is 16)
{
cb.writeRMInstr!('r', 0xFF, 0x0F, 0xB7)(dstSize is 16, dstSize is 64, dst, src);
}
else
{
assert (false, "invalid src operand size for movxz");
}
}
*/

/// nop - Noop, one or multiple bytes long
pub fn nop(cb: &mut CodeBlock, length: u32) {
match length {
Expand Down
70 changes: 12 additions & 58 deletions zjit/src/backend/arm64/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ impl Assembler
asm.load(opnd)
}
},
Opnd::None | Opnd::Value(_) /*| Opnd::Stack { .. }*/ => unreachable!()
Opnd::None | Opnd::Value(_) => unreachable!()
}
}

Expand Down Expand Up @@ -1742,21 +1742,19 @@ mod tests {
asm.compile_with_num_regs(&mut cb, 0);
}

/*
#[test]
fn test_emit_lea_label() {
let (mut asm, mut cb) = setup_asm();

let label = asm.new_label("label");
let opnd = asm.lea_jump_target(label);
let opnd = asm.lea_jump_target(label.clone());

asm.write_label(label);
asm.bake_string("Hello, world!");
asm.store(Opnd::mem(64, SP, 0), opnd);

asm.compile_with_num_regs(&mut cb, 1);
}
*/

#[test]
fn test_emit_load_mem_disp_fits_into_load() {
Expand Down Expand Up @@ -1967,48 +1965,6 @@ mod tests {
asm.compile_with_num_regs(&mut cb, 2);
}

/*
#[test]
fn test_bcond_straddling_code_pages() {
const LANDING_PAGE: usize = 65;
let mut asm = Assembler::new(0);
let mut cb = CodeBlock::new_dummy_with_freed_pages(vec![0, LANDING_PAGE]);

// Skip to near the end of the page. Room for two instructions.
cb.set_pos(cb.page_start_pos() + cb.page_end() - 8);

let end = asm.new_label("end");
// Start with a conditional jump...
asm.jz(end);

// A few instructions, enough to cause a page switch.
let sum = asm.add(399.into(), 111.into());
let xorred = asm.xor(sum, 859.into());
asm.store(Opnd::mem(64, Opnd::Reg(X2_REG), 0), xorred);
asm.store(Opnd::mem(64, Opnd::Reg(X0_REG), 0), xorred);

// The branch target. It should be in the landing page.
asm.write_label(end);
asm.cret(xorred);

// [Bug #19385]
// This used to panic with "The offset must be 19 bits or less."
// due to attempting to lower the `asm.jz` above to a `b.e` with an offset that's > 1 MiB.
let starting_pos = cb.get_write_pos();
asm.compile_with_num_regs(&mut cb, 2);
let gap = cb.get_write_pos() - starting_pos;
assert!(gap > 0b1111111111111111111);

let instruction_at_starting_pos: [u8; 4] = unsafe {
std::slice::from_raw_parts(cb.get_ptr(starting_pos).raw_ptr(&cb), 4)
}.try_into().unwrap();
assert_eq!(
0b000101 << 26_u32,
u32::from_le_bytes(instruction_at_starting_pos) & (0b111111 << 26_u32),
"starting instruction should be an unconditional branch to the new page (B)"
);
}

#[test]
fn test_emit_xor() {
let (mut asm, mut cb) = setup_asm();
Expand All @@ -2018,9 +1974,9 @@ mod tests {

asm.compile_with_num_regs(&mut cb, 1);

assert_disasm!(cb, "0b0001ca4b0000f8", "
0x0: eor x11, x0, x1
0x4: stur x11, [x2]
assert_disasm!(cb, "000001ca400000f8", "
0x0: eor x0, x0, x1
0x4: stur x0, [x2]
");
}

Expand Down Expand Up @@ -2082,10 +2038,10 @@ mod tests {
asm.mov(Opnd::Reg(TEMP_REGS[0]), out);
asm.compile_with_num_regs(&mut cb, 2);

assert_disasm!(cb, "8b0280d20c0080d261b18c9a", {"
0x0: mov x11, #0x14
0x4: mov x12, #0
0x8: csel x1, x11, x12, lt
assert_disasm!(cb, "800280d2010080d201b0819a", {"
0x0: mov x0, #0x14
0x4: mov x1, #0
0x8: csel x1, x0, x1, lt
"});
}

Expand All @@ -2098,11 +2054,9 @@ mod tests {
asm.mov(Opnd::Reg(TEMP_REGS[0]), out);
asm.compile_with_num_regs(&mut cb, 2);

assert_disasm!(cb, "2b0500b16b0500b1e1030baa", {"
0x0: adds x11, x9, #1
0x4: adds x11, x11, #1
0x8: mov x1, x11
assert_disasm!(cb, "200500b1010400b1", {"
0x0: adds x0, x9, #1
0x4: adds x1, x0, #1
"});
}
*/
}
Loading