Alien-LibJIT

 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);



( run in 0.383 second using v1.01-cache-2.11-cpan-65fba6d93b7 )