From c18e6dde0a46751d795cc2a12b90a8d3d2c948a8 Mon Sep 17 00:00:00 2001 From: Aleksey Demakov Date: Fri, 29 Feb 2008 11:10:41 +0000 Subject: [PATCH] add jump table support to jitplus interface --- ChangeLog | 8 ++++ include/jit/jit-plus.h | 34 +++++++++++++++++ jitplus/Makefile.am | 3 +- jitplus/jit-plus-function.cpp | 17 ++++----- jitplus/jit-plus-jump-table.cpp | 65 +++++++++++++++++++++++++++++++++ 5 files changed, 117 insertions(+), 10 deletions(-) create mode 100644 jitplus/jit-plus-jump-table.cpp diff --git a/ChangeLog b/ChangeLog index 72765b1..733995c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2008-02-29 Aleksey Demakov + + * include/jit/jit-plus.h, jitplus/jit-plus-jump-table.cpp: + * jitplus/jit-plus-function.cpp, jitplus/Makefile.am: add + jit_jump_table class and jit_function::insn_jump_table method, add + jit-plus-jump-table.cpp file, move jit_build_exception class from + jit-plus-function.cpp to jit-plus.h. + 2008-02-26 Aleksey Demakov * use LGPL 2.1 for all the rest - dpas, tools, tests, and doc. diff --git a/include/jit/jit-plus.h b/include/jit/jit-plus.h index 1eacbdc..fa17643 100644 --- a/include/jit/jit-plus.h +++ b/include/jit/jit-plus.h @@ -25,6 +25,15 @@ #ifdef __cplusplus +class jit_build_exception +{ +public: + jit_build_exception(int result) { this->result = result; } + ~jit_build_exception() {} + + int result; +}; + class jit_value { public: @@ -110,6 +119,30 @@ private: jit_label_t label; }; +class jit_jump_table +{ + public: + + jit_jump_table(int size); + ~jit_jump_table(); + + int size() { return num_labels; } + jit_label_t *raw() { return labels; } + + jit_label get(int index); + + void set(int index, jit_label label); + + private: + + jit_label_t *labels; + int num_labels; + + // forbid copying + jit_jump_table(const jit_jump_table&); + jit_jump_table& operator=(const jit_jump_table&); +}; + class jit_context { public: @@ -286,6 +319,7 @@ public: void insn_branch(jit_label& label); void insn_branch_if(const jit_value& value, jit_label& label); void insn_branch_if_not(const jit_value& value, jit_label& label); + void insn_jump_table(const jit_value& value, jit_jump_table& jump_table); jit_value insn_address_of(const jit_value& value1); jit_value insn_address_of_label(jit_label& label); jit_value insn_convert diff --git a/jitplus/Makefile.am b/jitplus/Makefile.am index 82dab60..4a57a1d 100644 --- a/jitplus/Makefile.am +++ b/jitplus/Makefile.am @@ -4,7 +4,8 @@ lib_LTLIBRARIES = libjitplus.la libjitplus_la_SOURCES = \ jit-plus-context.cpp \ jit-plus-function.cpp \ - jit-plus-value.cpp + jit-plus-value.cpp \ + jit-plus-jump-table.cpp AM_CXXFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/include -I. -I$(srcdir) diff --git a/jitplus/jit-plus-function.cpp b/jitplus/jit-plus-function.cpp index cb97e3d..d8116f1 100644 --- a/jitplus/jit-plus-function.cpp +++ b/jitplus/jit-plus-function.cpp @@ -42,15 +42,6 @@ for more information on creating and managing instructions. #define JITPP_MAPPING 20000 -class jit_build_exception -{ -public: - jit_build_exception(int result) { this->result = result; } - ~jit_build_exception() {} - - int result; -}; - jit_type_t const jit_function::end_params = (jit_type_t)0; /*@ @@ -1081,6 +1072,14 @@ void jit_function::insn_branch_if_not(const jit_value& value, jit_label& label) } } +void jit_function::insn_jump_table(const jit_value& value, jit_jump_table& jump_table) +{ + if(!jit_insn_jump_table(func, value.raw(), jump_table.raw(), jump_table.size())) + { + out_of_memory(); + } +} + jit_value jit_function::insn_address_of(const jit_value& value1) { value_wrap(jit_insn_address_of(func, value1.raw())); diff --git a/jitplus/jit-plus-jump-table.cpp b/jitplus/jit-plus-jump-table.cpp new file mode 100644 index 0000000..1d71613 --- /dev/null +++ b/jitplus/jit-plus-jump-table.cpp @@ -0,0 +1,65 @@ +/* + * jit-plus-jump-table.cpp - C++ wrapper for JIT jump tables. + * + * Copyright (C) 2008 Southern Storm Software, Pty Ltd. + * + * This file is part of the libjit library. + * + * 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 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the libjit library. If not, see + * . + */ + +#include + +jit_jump_table::jit_jump_table(int size) +{ + try + { + labels = new jit_label_t[size]; + } + catch(...) + { + throw jit_build_exception(JIT_RESULT_OUT_OF_MEMORY); + } + for (int i = 0; i < size; i++) + { + labels[i] = jit_label_undefined; + } + num_labels = size; +} + +jit_jump_table::~jit_jump_table() +{ + delete [] labels; +} + +jit_label +jit_jump_table::get(int index) +{ + if (index < 0 || index >= num_labels) + { + throw jit_build_exception(JIT_RESULT_COMPILE_ERROR); + } + return jit_label(labels[index]); +} + +void +jit_jump_table::set(int index, jit_label label) +{ + if (index < 0 || index >= num_labels) + { + throw jit_build_exception(JIT_RESULT_COMPILE_ERROR); + } + labels[index] = label.raw(); +} -- 2.47.3