view release on metacpan or search on metacpan
libjit/COPYING.LESSER view on Meta::CPAN
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
libjit/ChangeLog view on Meta::CPAN
get rid of bytecode offset compression and method region machinary.
* jit/jit-dump.c, jit/jit-function.c, jit/jit-rules-interp.c
* jit/jit-except.c, jit/jit-unwind.c: adjust where appropriate for
cache API change.
2011-12-18 Aleksey Demakov <ademakov@gmail.com>
* jit/Makefile.am:
* jit/jit-varint.h, jit/jit-varint.c: add new files for varaible
length int encoding with algorithm similar but not identical to one
currently used in jit-cache.c. The new algorithm in certain cases
better compresses unsigned ints.
2011-09-30 Aleksey Demakov <ademakov@gmail.com>
* jit/jit-cache.h, jit/jit-cache.c (_jit_cache_new_region):
function removed.
2011-09-03 Aleksey Demakov <ademakov@gmail.com>
libjit/doc/mangling_rules.txt view on Meta::CPAN
<dtor-function> ::= '_' <joiner> '_' <class-name> <func-params>
<joiner> ::= '.' | '$' # system-dependent joiner
<class-name> ::= <qualified-name>
<qualified-name> ::= <component>
::= 'Q' <digit> <component>+
::= 'Q' '_' <digit>+ '_' <component>+
<component> ::= <digit>+ <identifier> # length-prefixed name
<overload-item> ::= 'R' <type> # reference
::= 'P' <type> # array or pointer type
::= 'O' <type> '_' <type> # offset type
::= 'M' <type> <modifiers> <function-type> # methods
::= <function-type>
::= <builtin-type>
::= <qualified-name>
<type> ::= <modifiers> <overload-item>
libjit/doc/mangling_rules.txt view on Meta::CPAN
::= # empty
::= <substitution>
<template-prefix> ::= <prefix> <template component>
::= <substitution>
<unqualified-name> ::= <operator-name>
::= <special-name>
::= <source-name>
<source-name> ::= </length/ number> <identifier>
<number> ::= [n] </decimal integer/>
<identifier> ::= </unqualified source code identifier>
<special-name> ::= C1 # complete object constructor
::= C2 # base object constructor
::= C3 # complete object allocating constructor
::= D0 # deleting (in-charge) destructor
::= D1 # complete object (in-charge) destructor
libjit/doc/mangling_rules.txt view on Meta::CPAN
::= LZ <name> E # external name
::= X <expression> E # expression
Literal subcase of non-terminal <template-arg>.
"Literal arguments, e.g. "A<42L>", are encoded with their type
and value. Negative integer values are preceded with "n"; for
example, "A<-42L>" becomes "1AILln42EE". The bool value false is
encoded as 0, true as 1. If floating-point arguments are accepted
as an extension, their values should be encoded using a
fixed-length lowercase hexadecimal string corresponding to the
internal representation (IEEE on IA-64), high-order bytes first,
without leading zeroes. For example: "Lfbff000000E" is -1.0f."
<template-template-arg> ::= <name>
::= <substitution>
<array-type> ::= A [</dimension/ number>] _ </element/ type>
::= A <expression> _ </element/ type>
"Array types encode the dimension (number of elements) and the
element type. For variable length arrays, the dimension (but not
the '_' separator) is omitted."
<pointer-to-member-type> ::= M </class/ type> </member/ type>
<template-param> ::= T </parameter/ number> _
<template-template-param> ::= <template-param>
::= <substitution>
MSVC 6.0 name mangling rules (determined by trial and error):
libjit/jit/jit-block.c view on Meta::CPAN
jit_block_ends_in_dead(jit_block_t block)
{
return block->ends_in_dead;
}
/*@
* @deftypefun int jit_block_current_is_dead (jit_function_t @var{func})
* Determine if the current point in the function is dead. That is,
* there are no existing branches or fall-throughs to this point.
* This differs slightly from @code{jit_block_ends_in_dead} in that
* this can skip past zero-length blocks that may not appear to be
* dead to find the dead block at the head of a chain of empty blocks.
* @end deftypefun
@*/
int
jit_block_current_is_dead(jit_function_t func)
{
jit_block_t block = jit_block_previous(func, 0);
return !block || jit_block_ends_in_dead(block) || !jit_block_is_reachable(block);
}
libjit/jit/jit-insn.c view on Meta::CPAN
*
* Let's suppose that we need to add a "store_realtive(z, b, v)" instruction.
* The "find_base_insn()" call will return the instruction "j" and we will be
* able to emit the instruction "store_relative(y, a + b, v)" instead. If "z"
* is not used elsewhere then "j" will be optimized away by the dead code
* elimination pass.
*
* Repetitive use of this procedure for a chain of "add_relative" instructions
* converts it into a series of indpenedent instructions each using the very
* first address in the chain as its base. Therefore regardless of the initial
* chain length it is always enough to make single "find_base_insn()" call to
* get the base address of the entire chain (think induction).
*
* Note that in this situation the second "find_base_insn()" call will return
* the instruction "i" that obtains the base address as the address of a local
* frame variable. This instruction is a candidate for being moved down to
* where the "load_relative" or "store_relative" occurs. This might make it
* easier for the code generator to handle field accesses whitin local
* variables.
*
* The "plast" argument indicates if the found instruction is already the last
libjit/jit/jit-rules-arm.ins view on Meta::CPAN
//Call the function
arm_call(inst, jit_memcpy);
}
JIT_OP_MEMSET: ternary
[any, any, imm, if("$3 <= 0")] -> { }
[reg, imm, imm, if("$3 <= 32"), space("32 + $3 * 4")] -> {
// $1 = pointer to the initial memory location
// $2 = value to be written in memory
// $3 = length in bytes
int disp;
disp = 0;
while($3 >= (disp + 4))
{
//NB: if 0<A<255, then A*0x01010101 = a 32-bit value where each of its four bytes is A.
arm_mov_membase_imm(inst, $1, disp, $2 * 0x01010101, 4, ARM_WORK);
disp += 4;
}
if($3 >= (disp + 2))
{
libjit/jit/jit-rules-arm.ins view on Meta::CPAN
arm_mov_membase_imm(inst, $1, disp, $2, 1, ARM_WORK);
}
}
[reg, reg, imm, if("$3 < 4")] -> {
TODO();
abort();
}
[reg, +reg, imm, scratch reg, if("$3 <= 32 && ($3 % 2) == 0"), space("32 + $3 * 4")] -> {
// $1 = pointer to the initial memory location
// $2 = value to be written in memory
// $3 = length in bytes
// $4 = scratch register
int disp;
arm_mov_reg_reg(inst, $4, $2);
arm_shift_reg_imm8(inst, ARM_SHL, $2, $2, 8);
arm_alu_reg_reg(inst, ARM_ORR, $2, $2, $4);
arm_mov_reg_reg(inst, $4, $2);
arm_shift_reg_imm8(inst, ARM_SHL, $2, $2, 16);
arm_alu_reg_reg(inst, ARM_ORR, $2, $2, $4);
disp = 0;
while($3 >= (disp + 4))
libjit/jit/jit-rules-arm.ins view on Meta::CPAN
}
}
[reg, +reg, imm, scratch reg,
if("$3 <= 32 && ($3 % 2) != 0"), space("32 + $3 * 4")] -> {
TODO();
abort();
}
[reg, reg, reg, clobber("r0", "r1", "r2"), scratch reg] -> {
// $1 = pointer to the initial memory location
// $2 = value to be written in memory
// $3 = length in bytes
// $4 = scratch register
int pointer=$1;
int value=$2;
int length=$3;
int scratch=$4;
/* Move the outgoing parameters in the right registers (if they are not already where they should be */
if (pointer != ARM_R0) {
if(value == ARM_R0)
{
//Prevent the value from being overwritten
arm_mov_reg_reg((inst), scratch, ARM_R0);
value=scratch;
}
else if(length==ARM_R0)
{
//Prevent the length from being overwritten
arm_mov_reg_reg((inst), scratch, ARM_R0);
length=scratch;
}
arm_mov_reg_reg((inst), ARM_R0, pointer);
//The register that contained the pointer is now free
scratch=pointer;
}
if (value != ARM_R1)
{
if (length == ARM_R1)
{
//The length is stored in R1. Prevent it from being overwritten
arm_mov_reg_reg(inst, scratch, length);
length=scratch;
}
//Set param 2
arm_mov_reg_reg((inst), ARM_R1, value);
//The register that contained the value is now free
scratch=value;
}
if(length != ARM_R1)
{
//Param 3 still isn't in place: move it!
arm_mov_reg_reg(inst, ARM_R2, length);
}
arm_call(inst, jit_memset);
}
libjit/jit/jit-util.c view on Meta::CPAN
* @cindex String operations
*
* The following functions are provided to manipulate NULL-terminated
* strings. It is highly recommended that you use these functions in
* preference to system functions, because the corresponding system
* functions are extremely non-portable.
@*/
/*@
* @deftypefun {unsigned int} jit_strlen (const char *@var{str})
* Returns the length of @var{str}.
* @end deftypefun
@*/
unsigned int jit_strlen(const char *str)
{
#ifdef HAVE_STRLEN
return (unsigned int)(strlen(str));
#else
unsigned int len = 0;
while(*str++ != '\0')
{
libjit/jit/jit-varint.c view on Meta::CPAN
/*
* jit-varint.c - Variable length integer encoding.
*
* Copyright (C) 2011 Aleksey Demakov
*
* The libjit library is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation, either version 2.1 of
* the License, or (at your option) any later version.
*
* The libjit library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
libjit/jit/jit-varint.h view on Meta::CPAN
/*
* jit-varint.h - Variable length integer encoding.
*
* Copyright (C) 2011 Aleksey Demakov
*
* The libjit library is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation, either version 2.1 of
* the License, or (at your option) any later version.
*
* The libjit library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
libjit/jitdynamic/jit-cpp-mangle.c view on Meta::CPAN
*/
static void add_string(jit_mangler_t mangler, const char *str)
{
while(*str != '\0')
{
add_ch(mangler, *str++);
}
}
/*
* Add a length-prefixed string to a mangling buffer.
*/
static void add_len_string(jit_mangler_t mangler, const char *str)
{
char buf[32];
sprintf(buf, "%u", jit_strlen(str));
add_string(mangler, buf);
add_string(mangler, str);
}
/*
libjit/jitruby/ext/insns.inc.rpp view on Meta::CPAN
#ruby <<END
V = :value
L = :label_ptr
B = :label
N = :nint
T = :type_t
_ = :void
def incoming_args(arg_types)
num_args = arg_types.length
return (1..num_args).map { |n| ", VALUE arg#{n}" }.join
end
def declaration(name, type)
case type
when V then return "jit_value_t #{name};"
when L then return "jit_label_t * #{name};"
when B then return "jit_label_t * #{name};"
when N then return "jit_nint #{name};"
when T then return "jit_type_t #{name};"
libjit/jitruby/ext/insns.inc.rpp view on Meta::CPAN
def get_value(type, arg, j_arg)
case type
when N then
return "#{j_arg} = NUM2INT(#{arg})"
else
return "Data_Get_Struct(#{arg}, #{jit_type(type)}, #{j_arg})"
end
end
def jit_insn_args(arg_types)
num_args = arg_types.length
arg_list = (1..num_args).map do |n|
case arg_types[n-1]
when B then ", *j_arg#{n}"
else ", j_arg#{n}"
end
end
return arg_list.join
end
def write_insn(name, retval_type, arg_types)
num_args = arg_types.length
an = [?a, ?e, ?i, ?o, ?u].include?(name[0])
puts "/* Generate a#{an} #{name} instruction (see the libjit documentation for more"
puts " * details. */"
puts "static VALUE function_insn_#{name}(VALUE self#{incoming_args(arg_types)})"
puts "{"
puts " jit_function_t function;"
write_declaration('retval', retval_type, 2)
arg_types.each_with_index do |type, n|
write_declaration("j_arg#{n+1}", type, 2)
end
libjit/jitruby/ext/insns.inc.rpp view on Meta::CPAN
]
insns.each do |name, retval_type, *arg_types|
write_insn(name, retval_type, arg_types)
puts
end
puts "static void init_insns()"
puts "{"
insns.each do |name, retval_type, *arg_types|
num_args = arg_types.length
puts " rb_define_method(rb_cFunction, \"insn_#{name}\", function_insn_#{name}, #{num_args});"
end
puts "}"
END
libjit/jitruby/lib/jit/array.rb view on Meta::CPAN
require 'jit'
require 'jit/value'
module JIT
# An abstraction for a fixed-length array type.
#
# Example usage:
#
# array_type = JIT::Array.new(JIT::Type::INT, 4)
#
# JIT::Context.build do |context|
# signature = JIT::Type.create_signature(
# JIT::ABI::CDECL, JIT::Type::INT, [ ])
#
# function = JIT::Function.compile(context, signature) do |f|
# array_instance = array_type.create(f)
# array_instance[0] = f.const(JIT::Type::INT, 42)
# f.insn_return(array_instance[0])
# end
#
# end
#
class Array < JIT::Type
attr_reader :type
attr_reader :length
# Create a new JIT array type.
#
# +type+:: The type of the elements in the array.
# +length+:: The number of elements in the array.
#
def self.new(type, length)
array = self.create_struct([ type ] * length)
array.instance_eval do
@type = type
@length = length
end
return array
end
# Wrap an existing array.
#
# +ptr+:: A pointer to the first element in the array.
#
def wrap(ptr)
return Instance.wrap(self, ptr)
libjit/jitruby/lib/jit/array.rb view on Meta::CPAN
end
# Return the type of the element at the given +index+.
#
# +index+:: The index of the desired element.
#
def type_of(index)
return @type
end
# An abstraction for an instance of a fixed-length array.
#
class Instance < JIT::Value
attr_reader :array_type
attr_reader :type
# A pointer to the first element of the array. Note that this
# differs from +address+, which returns the address of a pointer
# to the array.
attr_reader :ptr
libjit/jitruby/test/test_jit_array.rb view on Meta::CPAN
require 'jit/function'
require 'test/unit'
require 'assertions'
class TestJitArray < Test::Unit::TestCase
include JitAssertions
def test_new_array
a_type = JIT::Array.new(JIT::Type::INT, 12)
assert_equal JIT::Type::INT, a_type.type
assert_equal 12, a_type.length
end
# TODO: wrap
def test_create
p = proc { |f|
a_type = JIT::Array.new(JIT::Type::INT, 4)
a = a_type.create(f)
f.return f.const(JIT::Type::INT, 0)
}
libjit/samples/hellovm.c view on Meta::CPAN
* constant into register, B) output contents of register, C) exit program.
*
* Compile with: gcc hellovm.c -ljit -o hellovm
*
* A valid "Hello VM" bytecode language program, suitable as input file for
* this JIT, can be generated by the following perl script
*
* #!/usr/bin/perl
* open TEST, ">test";
* $bytecode="AHello World!\n\x00BC";
* print TEST "HelloVM\x00", pack('i',length($bytecode)), $bytecode;
*
* A slightly less trivial example can be generated e.g. with
* $bytecode="AHello, \x00BBAWorld!\n\x00BC";
*
* The contents of this file are in the Public Domain.
*/
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
libjit/samples/hellovm.c view on Meta::CPAN
printf("Usage: hellovm program\n");
return 99;
}
if((fd = open(argv[1], O_RDONLY)) < 0)
{
perror(argv[1]);
return 99;
}
/* read filetype identification string and length field */
buf=readbytes(fd, 12);
/* check filetype identification string */
if(jit_strcmp("HelloVM", buf)!=0)
{
fprintf(stderr, "%s is not in HelloVM format.\n", argv[1]);
return 99;
}
/* check length field and read bytecode data */
len=*((int*) (buf+8));
if(len<0)
{
fprintf(stderr, "%s: Invalid length field.\n", argv[1]);
return 99;
}
free(buf);
buf=readbytes(fd, len);
close(fd);
/* Now the fun begins :) */
jit_init();
context = jit_context_create();
jit_context_build_start(context);