mirror of https://github.com/ademakov/libjit
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
329 lines
8.8 KiB
329 lines
8.8 KiB
require 'jit/function'
|
|
require 'jit/value'
|
|
require 'test/unit'
|
|
|
|
class TestJitFunction < Test::Unit::TestCase
|
|
def test_if_false
|
|
function = nil
|
|
JIT::Context.build do |context|
|
|
signature = JIT::Type.create_signature(
|
|
JIT::ABI::CDECL,
|
|
JIT::Type::INT,
|
|
[ JIT::Type::INT ])
|
|
function = JIT::Function.compile(context, signature) do |f|
|
|
result = f.value(JIT::Type::INT)
|
|
result.store f.const(JIT::Type::INT, 1)
|
|
f.if(f.get_param(0)) {
|
|
result.store f.const(JIT::Type::INT, 2)
|
|
} .end
|
|
f.insn_return result
|
|
end
|
|
end
|
|
|
|
assert_equal(1, function.apply(0))
|
|
end
|
|
|
|
def test_if_true
|
|
function = nil
|
|
JIT::Context.build do |context|
|
|
signature = JIT::Type.create_signature(
|
|
JIT::ABI::CDECL,
|
|
JIT::Type::INT,
|
|
[ JIT::Type::INT ])
|
|
function = JIT::Function.compile(context, signature) do |f|
|
|
result = f.value(JIT::Type::INT)
|
|
result.store f.const(JIT::Type::INT, 1)
|
|
f.if(f.get_param(0)) {
|
|
result.store f.const(JIT::Type::INT, 2)
|
|
} .end
|
|
f.insn_return result
|
|
end
|
|
end
|
|
|
|
assert_equal(2, function.apply(1))
|
|
end
|
|
|
|
def test_if_false_else
|
|
function = nil
|
|
JIT::Context.build do |context|
|
|
signature = JIT::Type.create_signature(
|
|
JIT::ABI::CDECL,
|
|
JIT::Type::INT,
|
|
[ JIT::Type::INT ])
|
|
function = JIT::Function.compile(context, signature) do |f|
|
|
result = f.value(JIT::Type::INT)
|
|
result.store f.const(JIT::Type::INT, 1)
|
|
f.if(f.get_param(0)) {
|
|
result.store f.const(JIT::Type::INT, 2)
|
|
} .else {
|
|
result.store f.const(JIT::Type::INT, 3)
|
|
} .end
|
|
f.insn_return result
|
|
end
|
|
end
|
|
|
|
assert_equal(3, function.apply(0))
|
|
end
|
|
|
|
def test_if_true_else
|
|
function = nil
|
|
JIT::Context.build do |context|
|
|
signature = JIT::Type.create_signature(
|
|
JIT::ABI::CDECL,
|
|
JIT::Type::INT,
|
|
[ JIT::Type::INT ])
|
|
function = JIT::Function.compile(context, signature) do |f|
|
|
result = f.value(JIT::Type::INT)
|
|
result.store f.const(JIT::Type::INT, 1)
|
|
f.if(f.get_param(0)) {
|
|
result.store f.const(JIT::Type::INT, 2)
|
|
} .else {
|
|
result.store f.const(JIT::Type::INT, 3)
|
|
} .end
|
|
f.insn_return result
|
|
end
|
|
end
|
|
|
|
assert_equal(2, function.apply(1))
|
|
end
|
|
|
|
def test_if_false_else_if_true_else
|
|
function = nil
|
|
JIT::Context.build do |context|
|
|
signature = JIT::Type.create_signature(
|
|
JIT::ABI::CDECL,
|
|
JIT::Type::INT,
|
|
[ JIT::Type::INT, JIT::Type::INT ])
|
|
function = JIT::Function.compile(context, signature) do |f|
|
|
result = f.value(JIT::Type::INT)
|
|
result.store f.const(JIT::Type::INT, 1)
|
|
f.if(f.get_param(0)) {
|
|
result.store f.const(JIT::Type::INT, 2)
|
|
} .elsif(f.get_param(1)) {
|
|
result.store f.const(JIT::Type::INT, 3)
|
|
} .else {
|
|
result.store f.const(JIT::Type::INT, 4)
|
|
} .end
|
|
f.insn_return result
|
|
end
|
|
end
|
|
|
|
assert_equal(3, function.apply(0, 1))
|
|
end
|
|
|
|
def test_if_true_else_if_false_else
|
|
function = nil
|
|
JIT::Context.build do |context|
|
|
signature = JIT::Type.create_signature(
|
|
JIT::ABI::CDECL,
|
|
JIT::Type::INT,
|
|
[ JIT::Type::INT, JIT::Type::INT ])
|
|
function = JIT::Function.compile(context, signature) do |f|
|
|
result = f.value(JIT::Type::INT)
|
|
result.store f.const(JIT::Type::INT, 1)
|
|
f.if(f.get_param(0)) {
|
|
result.store f.const(JIT::Type::INT, 2)
|
|
} .elsif(f.get_param(1)) {
|
|
result.store f.const(JIT::Type::INT, 3)
|
|
} .else {
|
|
result.store f.const(JIT::Type::INT, 4)
|
|
} .end
|
|
f.insn_return result
|
|
end
|
|
end
|
|
|
|
assert_equal(2, function.apply(1, 0))
|
|
end
|
|
|
|
def test_if_false_else_if_false_else
|
|
function = nil
|
|
JIT::Context.build do |context|
|
|
signature = JIT::Type.create_signature(
|
|
JIT::ABI::CDECL,
|
|
JIT::Type::INT,
|
|
[ JIT::Type::INT, JIT::Type::INT ])
|
|
function = JIT::Function.compile(context, signature) do |f|
|
|
result = f.value(JIT::Type::INT)
|
|
result.store f.const(JIT::Type::INT, 1)
|
|
f.if(f.get_param(0)) {
|
|
result.store f.const(JIT::Type::INT, 2)
|
|
} .elsif(f.get_param(1)) {
|
|
result.store f.const(JIT::Type::INT, 3)
|
|
} .else {
|
|
result.store f.const(JIT::Type::INT, 4)
|
|
} .end
|
|
f.insn_return result
|
|
end
|
|
end
|
|
|
|
assert_equal(4, function.apply(0, 0))
|
|
end
|
|
|
|
def test_while_true_enters_loop
|
|
function = nil
|
|
JIT::Context.build do |context|
|
|
signature = JIT::Type.create_signature(
|
|
JIT::ABI::CDECL,
|
|
JIT::Type::INT,
|
|
[ ])
|
|
function = JIT::Function.compile(context, signature) do |f|
|
|
true_value = f.const(JIT::Type::INT, 1)
|
|
false_value = f.const(JIT::Type::INT, 0)
|
|
f.while{ true_value }.do {
|
|
f.insn_return true_value
|
|
}.end
|
|
f.insn_return false_value
|
|
end
|
|
end
|
|
|
|
assert_equal(1, function.apply)
|
|
end
|
|
|
|
def test_while_true_reenters_loop
|
|
function = nil
|
|
JIT::Context.build do |context|
|
|
signature = JIT::Type.create_signature(
|
|
JIT::ABI::CDECL,
|
|
JIT::Type::INT,
|
|
[ ])
|
|
function = JIT::Function.compile(context, signature) do |f|
|
|
value = f.value(JIT::Type::INT)
|
|
value.store(f.const(JIT::Type::INT, 0))
|
|
f.while{ value < f.const(JIT::Type::INT, 2) }.do {
|
|
value.store(value + f.const(JIT::Type::INT, 1))
|
|
}.end
|
|
f.insn_return value
|
|
end
|
|
end
|
|
|
|
assert_equal(2, function.apply)
|
|
end
|
|
|
|
def test_while_false_does_not_enter_loop
|
|
function = nil
|
|
JIT::Context.build do |context|
|
|
signature = JIT::Type.create_signature(
|
|
JIT::ABI::CDECL,
|
|
JIT::Type::INT,
|
|
[ ])
|
|
function = JIT::Function.compile(context, signature) do |f|
|
|
true_value = f.const(JIT::Type::INT, 1)
|
|
false_value = f.const(JIT::Type::INT, 0)
|
|
f.while{ false_value }.do {
|
|
f.insn_return true_value
|
|
}.end
|
|
f.insn_return false_value
|
|
end
|
|
end
|
|
|
|
assert_equal(0, function.apply)
|
|
end
|
|
|
|
def test_until_false_enters_loop
|
|
function = nil
|
|
JIT::Context.build do |context|
|
|
signature = JIT::Type.create_signature(
|
|
JIT::ABI::CDECL,
|
|
JIT::Type::INT,
|
|
[ ])
|
|
function = JIT::Function.compile(context, signature) do |f|
|
|
true_value = f.const(JIT::Type::INT, 1)
|
|
false_value = f.const(JIT::Type::INT, 0)
|
|
f.until{ false_value }.do {
|
|
f.insn_return true_value
|
|
}.end
|
|
f.insn_return false_value
|
|
end
|
|
end
|
|
|
|
assert_equal(1, function.apply)
|
|
end
|
|
|
|
def test_until_false_reenters_loop
|
|
function = nil
|
|
JIT::Context.build do |context|
|
|
signature = JIT::Type.create_signature(
|
|
JIT::ABI::CDECL,
|
|
JIT::Type::INT,
|
|
[ ])
|
|
function = JIT::Function.compile(context, signature) do |f|
|
|
value = f.value(JIT::Type::INT)
|
|
value.store(f.const(JIT::Type::INT, 0))
|
|
f.until{ value == f.const(JIT::Type::INT, 2) }.do {
|
|
value.store(value + f.const(JIT::Type::INT, 1))
|
|
}.end
|
|
f.insn_return value
|
|
end
|
|
end
|
|
|
|
assert_equal(2, function.apply)
|
|
end
|
|
|
|
def test_until_true_does_not_enter_loop
|
|
function = nil
|
|
JIT::Context.build do |context|
|
|
signature = JIT::Type.create_signature(
|
|
JIT::ABI::CDECL,
|
|
JIT::Type::INT,
|
|
[ ])
|
|
function = JIT::Function.compile(context, signature) do |f|
|
|
true_value = f.const(JIT::Type::INT, 1)
|
|
false_value = f.const(JIT::Type::INT, 0)
|
|
f.until{ true_value }.do {
|
|
f.insn_return true_value
|
|
}.end
|
|
f.insn_return false_value
|
|
end
|
|
end
|
|
|
|
assert_equal(0, function.apply)
|
|
end
|
|
|
|
# TODO: while/break
|
|
# TODO: while/redo
|
|
# TODO: until/break
|
|
# TODO: until/redo
|
|
# TODO: unless
|
|
# TODO: elsunless
|
|
|
|
def test_define_jit_method
|
|
function = nil
|
|
JIT::Context.build do |context|
|
|
signature = JIT::Type.create_signature(
|
|
JIT::ABI::CDECL,
|
|
JIT::Type::OBJECT,
|
|
[ JIT::Type::OBJECT ])
|
|
function = JIT::Function.compile(context, signature) do |f|
|
|
f.insn_return(f.const(JIT::Type::OBJECT, 42))
|
|
end
|
|
end
|
|
|
|
c = Class.new
|
|
c.instance_eval do
|
|
define_jit_method('foo', function)
|
|
end
|
|
|
|
o = c.new
|
|
assert_equal 42, o.foo
|
|
end
|
|
|
|
def test_define_jit_method_non_object_param
|
|
# TODO: should raise an exception
|
|
end
|
|
|
|
# TODO: get_param
|
|
# TODO: insn_call
|
|
# TODO: insn_call_native
|
|
# TODO: insn_return
|
|
# TODO: apply
|
|
# TODO: value
|
|
# TODO: const
|
|
# TODO: optimization_level
|
|
# TODO: optimization_level=
|
|
# TODO: max_optimization_level
|
|
# TODO: dump
|
|
# TODO: to_closure
|
|
# TODO: context
|
|
# TODO: compiled?
|
|
end
|
|
|
|
|