├── .gitattributes ├── LICENSE ├── README.md ├── _examples ├── gofunc.go └── mul_add.go ├── block.go ├── context.go ├── func.go ├── go.mod ├── go.sum ├── insn.go ├── internal ├── ccall │ ├── block.go │ ├── callback.c │ ├── ccall.go │ ├── context.go │ ├── func.go │ ├── include │ │ └── jit │ │ │ ├── jit-apply.h │ │ │ ├── jit-arch-arm.h │ │ │ ├── jit-arch-generic.h │ │ │ ├── jit-arch-x86-64.h │ │ │ ├── jit-arch-x86.h │ │ │ ├── jit-arch.h │ │ │ ├── jit-block.h │ │ │ ├── jit-common.h │ │ │ ├── jit-context.h │ │ │ ├── jit-debugger.h │ │ │ ├── jit-defs.h │ │ │ ├── jit-defs.h.in │ │ │ ├── jit-dump.h │ │ │ ├── jit-dynamic.h │ │ │ ├── jit-elf.h │ │ │ ├── jit-except.h │ │ │ ├── jit-function.h │ │ │ ├── jit-init.h │ │ │ ├── jit-insn.h │ │ │ ├── jit-intrinsic.h │ │ │ ├── jit-memory.h │ │ │ ├── jit-meta.h │ │ │ ├── jit-objmodel-private.h │ │ │ ├── jit-objmodel.h │ │ │ ├── jit-opcode-compat.h │ │ │ ├── jit-opcode.h │ │ │ ├── jit-plus.h │ │ │ ├── jit-type.h │ │ │ ├── jit-unwind.h │ │ │ ├── jit-util.h │ │ │ ├── jit-value.h │ │ │ ├── jit-vmem.h │ │ │ ├── jit-walk.h │ │ │ └── jit.h │ ├── insn.go │ ├── jit-alloc.c │ ├── jit-apply-arm.c │ ├── jit-apply-arm.h │ ├── jit-apply-func.h │ ├── jit-apply-rules.h │ ├── jit-apply-x86-64.c │ ├── jit-apply-x86-64.h │ ├── jit-apply-x86.c │ ├── jit-apply-x86.h │ ├── jit-apply.c │ ├── jit-bitset.c │ ├── jit-bitset.h │ ├── jit-block.c │ ├── jit-compile.c │ ├── jit-config.h │ ├── jit-context.c │ ├── jit-cpuid-x86.c │ ├── jit-cpuid-x86.h │ ├── jit-debugger.c │ ├── jit-dump.c │ ├── jit-elf-defs.h │ ├── jit-elf-read.c │ ├── jit-elf-write.c │ ├── jit-except.c │ ├── jit-function.c │ ├── jit-gen-arm.c │ ├── jit-gen-arm.h │ ├── jit-gen-x86-64.h │ ├── jit-gen-x86.h │ ├── jit-init.c │ ├── jit-insn.c │ ├── jit-internal.h │ ├── jit-interp-opcode.c │ ├── jit-interp-opcode.h │ ├── jit-interp-opcodes.ops │ ├── jit-interp.c │ ├── jit-interp.h │ ├── jit-intrinsic.c │ ├── jit-live.c │ ├── jit-memory-cache.c │ ├── jit-memory.c │ ├── jit-meta.c │ ├── jit-objmodel.c │ ├── jit-opcode-apply.c │ ├── jit-opcode.c │ ├── jit-pool.c │ ├── jit-reg-alloc.c │ ├── jit-reg-alloc.h │ ├── jit-reg-class.c │ ├── jit-reg-class.h │ ├── jit-rules-arm.c │ ├── jit-rules-arm.h │ ├── jit-rules-arm.ins │ ├── jit-rules-interp.c │ ├── jit-rules-interp.h │ ├── jit-rules-x86-64.c │ ├── jit-rules-x86-64.h │ ├── jit-rules-x86-64.inc │ ├── jit-rules-x86-64.ins │ ├── jit-rules-x86.c │ ├── jit-rules-x86.h │ ├── jit-rules-x86.ins │ ├── jit-rules.c │ ├── jit-rules.h │ ├── jit-setjmp.h │ ├── jit-signal.c │ ├── jit-symbol.c │ ├── jit-thread.c │ ├── jit-thread.h │ ├── jit-type.c │ ├── jit-unwind.c │ ├── jit-util.c │ ├── jit-value.c │ ├── jit-varint.c │ ├── jit-varint.h │ ├── jit-vmem.c │ ├── jit-walk.c │ ├── label.go │ ├── type.go │ └── value.go └── config.h ├── jit.go ├── label.go ├── type.go └── value.go /.gitattributes: -------------------------------------------------------------------------------- 1 | internal/* linguist-documentation 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Masaaki Goshima 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # go-jit 2 | 3 | [![GoDoc](https://godoc.org/github.com/goccy/go-jit?status.svg)](https://pkg.go.dev/github.com/goccy/go-jit?tab=doc) 4 | 5 | JIT compile library for Go 6 | 7 | # Status 8 | 9 | WIP 10 | 11 | # Synopsis 12 | 13 | ## Basic Operation 14 | 15 | ```go 16 | package main 17 | 18 | import ( 19 | "fmt" 20 | 21 | "github.com/goccy/go-jit" 22 | ) 23 | 24 | // func f(x, y, z int) int { 25 | // temp1 := x * y 26 | // temp2 := temp1 + z 27 | // return temp2 28 | // } 29 | 30 | func main() { 31 | ctx := jit.NewContext() 32 | defer ctx.Close() 33 | f, err := ctx.Build(func(ctx *jit.Context) (*jit.Function, error) { 34 | f := ctx.CreateFunction([]*jit.Type{jit.TypeInt, jit.TypeInt, jit.TypeInt}, jit.TypeInt) 35 | x := f.Param(0) 36 | y := f.Param(1) 37 | z := f.Param(2) 38 | temp1 := f.Mul(x, y) 39 | temp2 := f.Add(temp1, z) 40 | f.Return(temp2) 41 | f.Compile() 42 | return f, nil 43 | }) 44 | if err != nil { 45 | panic(err) 46 | } 47 | fmt.Println("result = ", f.Run(2, 3, 4)) 48 | } 49 | ``` 50 | 51 | ## Call defined Go function during JIT runtime 52 | 53 | ```go 54 | package main 55 | 56 | import ( 57 | "fmt" 58 | 59 | "github.com/goccy/go-jit" 60 | ) 61 | 62 | // func f() int { 63 | // return callback(7, 8) 64 | // } 65 | 66 | func callback(i, j int) int { 67 | fmt.Printf("callback: i = %d j = %d\n", i, j) 68 | return i * j 69 | } 70 | 71 | func main() { 72 | ctx := jit.NewContext() 73 | defer ctx.Close() 74 | f, err := ctx.Build(func(ctx *jit.Context) (*jit.Function, error) { 75 | f := ctx.CreateFunction(nil, jit.TypeInt) 76 | rvalues, err := f.GoCall(callback, []*jit.Value{ 77 | f.CreateIntValue(7), f.CreateIntValue(8), 78 | }) 79 | if err != nil { 80 | return nil, err 81 | } 82 | f.Return(rvalues[0]) 83 | f.Compile() 84 | return f, nil 85 | }) 86 | if err != nil { 87 | panic(err) 88 | } 89 | fmt.Println("result = ", f.Run(nil)) 90 | } 91 | ``` 92 | 93 | # Installation 94 | 95 | ``` 96 | go get github.com/goccy/go-jit 97 | ``` 98 | 99 | -------------------------------------------------------------------------------- /_examples/gofunc.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/goccy/go-jit" 7 | ) 8 | 9 | // func f() int { 10 | // return callback(7, 8) 11 | // } 12 | 13 | func callback(i, j int) int { 14 | fmt.Printf("callback: i = %d j = %d\n", i, j) 15 | return i * j 16 | } 17 | 18 | func main() { 19 | ctx := jit.NewContext() 20 | defer ctx.Close() 21 | f, err := ctx.Build(func(ctx *jit.Context) (*jit.Function, error) { 22 | f := ctx.CreateFunction(nil, jit.TypeInt) 23 | rvalues, err := f.GoCall(callback, []*jit.Value{ 24 | f.CreateIntValue(7), f.CreateIntValue(8), 25 | }) 26 | if err != nil { 27 | return nil, err 28 | } 29 | f.Return(rvalues[0]) 30 | f.Compile() 31 | return f, nil 32 | }) 33 | if err != nil { 34 | panic(err) 35 | } 36 | fmt.Println("result = ", f.Run()) 37 | } 38 | -------------------------------------------------------------------------------- /_examples/mul_add.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/goccy/go-jit" 7 | ) 8 | 9 | // func f(x, y, z int) int { 10 | // temp1 := x * y 11 | // temp2 := temp1 + z 12 | // return temp2 13 | // } 14 | 15 | func main() { 16 | ctx := jit.NewContext() 17 | defer ctx.Close() 18 | f, err := ctx.Build(func(ctx *jit.Context) (*jit.Function, error) { 19 | f := ctx.CreateFunction([]*jit.Type{jit.TypeInt, jit.TypeInt, jit.TypeInt}, jit.TypeInt) 20 | x := f.Param(0) 21 | y := f.Param(1) 22 | z := f.Param(2) 23 | temp1 := f.Mul(x, y) 24 | temp2 := f.Add(temp1, z) 25 | f.Return(temp2) 26 | f.Compile() 27 | return f, nil 28 | }) 29 | if err != nil { 30 | panic(err) 31 | } 32 | fmt.Println("result = ", f.Run(2, 3, 4)) 33 | } 34 | -------------------------------------------------------------------------------- /block.go: -------------------------------------------------------------------------------- 1 | package jit 2 | 3 | import ( 4 | "github.com/goccy/go-jit/internal/ccall" 5 | ) 6 | 7 | type Block struct { 8 | *ccall.Block 9 | } 10 | 11 | func toBlock(c *ccall.Block) *Block { 12 | return &Block{c} 13 | } 14 | 15 | func (b *Block) Function() *Function { 16 | return toFunction(b.Block.Function()) 17 | } 18 | 19 | func (b *Block) Context() *Context { 20 | return toContext(b.Block.Context()) 21 | } 22 | 23 | func (b *Block) Label() *Label { 24 | return toLabel(b.Block.Label()) 25 | } 26 | 27 | func (b *Block) NextLabel(label *Label) *Label { 28 | return toLabel(b.Block.NextLabel(label.Label)) 29 | } 30 | 31 | func (b *Block) IsReachable() bool { 32 | return b.Block.IsReachable() 33 | } 34 | 35 | func (b *Block) EndsInDead() bool { 36 | return b.Block.EndsInDead() 37 | } 38 | -------------------------------------------------------------------------------- /context.go: -------------------------------------------------------------------------------- 1 | package jit 2 | 3 | import ( 4 | "github.com/goccy/go-jit/internal/ccall" 5 | ) 6 | 7 | type Context struct { 8 | *ccall.Context 9 | } 10 | 11 | func NewContext() *Context { 12 | return &Context{ccall.CreateContext()} 13 | } 14 | 15 | func toContext(c *ccall.Context) *Context { 16 | return &Context{c} 17 | } 18 | 19 | func (c *Context) Close() { 20 | c.Destroy() 21 | } 22 | 23 | func (c *Context) Build(cb func(*Context) (*Function, error)) (*Function, error) { 24 | c.BuildStart() 25 | fn, err := cb(c) 26 | if err != nil { 27 | return nil, err 28 | } 29 | c.BuildEnd() 30 | return fn, nil 31 | } 32 | 33 | func (c *Context) CreateFunction(argtypes Types, rtype *Type) *Function { 34 | signature := CreateSignature(argtypes, rtype) 35 | defer signature.Free() 36 | return &Function{c.Context.CreateFunction(signature.Type)} 37 | } 38 | 39 | func (c *Context) CreateNestedFunction(signature *Type, parent *Function) *Function { 40 | return toFunction(c.Context.CreateNestedFunction(signature.Type, parent.Function)) 41 | } 42 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/goccy/go-jit 2 | 3 | go 1.12 4 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goccy/go-jit/ff78d45cf6afba0368028308135daec5edd22bbc/go.sum -------------------------------------------------------------------------------- /insn.go: -------------------------------------------------------------------------------- 1 | package jit 2 | 3 | import ( 4 | "unsafe" 5 | 6 | "github.com/goccy/go-jit/internal/ccall" 7 | ) 8 | 9 | type Instruction struct { 10 | *ccall.Instruction 11 | } 12 | 13 | func toInstruction(c *ccall.Instruction) *Instruction { 14 | return &Instruction{c} 15 | } 16 | 17 | func (i *Instruction) Code() int { 18 | return i.Instruction.Code() 19 | } 20 | 21 | func (i *Instruction) Dest() *Value { 22 | return toValue(i.Instruction.Dest()) 23 | } 24 | 25 | func (i *Instruction) Value1() *Value { 26 | return toValue(i.Instruction.Value1()) 27 | } 28 | 29 | func (i *Instruction) Value2() *Value { 30 | return toValue(i.Instruction.Value2()) 31 | } 32 | 33 | func (i *Instruction) Label() *Label { 34 | return toLabel(i.Instruction.Label()) 35 | } 36 | 37 | func (i *Instruction) Function() *Function { 38 | return toFunction(i.Instruction.Function()) 39 | } 40 | 41 | func (i *Instruction) Native() unsafe.Pointer { 42 | return i.Instruction.Native() 43 | } 44 | 45 | func (i *Instruction) Name() string { 46 | return i.Instruction.Name() 47 | } 48 | 49 | func (i *Instruction) Signature() *Type { 50 | return toType(i.Instruction.Signature()) 51 | } 52 | 53 | func (i *Instruction) DestIsValue() bool { 54 | return i.Instruction.DestIsValue() 55 | } 56 | -------------------------------------------------------------------------------- /internal/ccall/block.go: -------------------------------------------------------------------------------- 1 | package ccall 2 | 3 | /* 4 | #cgo CFLAGS: -I../ 5 | #cgo CFLAGS: -Iinclude 6 | 7 | #include 8 | */ 9 | import "C" 10 | 11 | type Block struct { 12 | c C.jit_block_t 13 | } 14 | 15 | func toBlock(c C.jit_block_t) *Block { 16 | return &Block{c} 17 | } 18 | 19 | func (b *Block) Function() *Function { 20 | return toFunction(C.jit_block_get_function(b.c)) 21 | } 22 | 23 | func (b *Block) Context() *Context { 24 | return toContext(C.jit_block_get_context(b.c)) 25 | } 26 | 27 | func (b *Block) Label() *Label { 28 | return toLabel(C.jit_block_get_label(b.c)) 29 | } 30 | 31 | func (b *Block) NextLabel(label *Label) *Label { 32 | return toLabel(C.jit_block_get_next_label(b.c, label.c)) 33 | } 34 | 35 | func (b *Block) IsReachable() bool { 36 | return int(C.jit_block_is_reachable(b.c)) == 1 37 | } 38 | 39 | func (b *Block) EndsInDead() bool { 40 | return int(C.jit_block_ends_in_dead(b.c)) == 1 41 | } 42 | -------------------------------------------------------------------------------- /internal/ccall/callback.c: -------------------------------------------------------------------------------- 1 | #include "_cgo_export.h" 2 | 3 | extern void crosscall2(void (*fn)(void *, int), void *, int, int); 4 | extern int _cgo_wait_runtime_init_done(); 5 | 6 | void *get_crosscall2addr() { 7 | return crosscall2; 8 | } 9 | 10 | void *get_cgo_wait_runtime_init_done_addr() { 11 | return _cgo_wait_runtime_init_done; 12 | } 13 | 14 | void callbackfn(void *wrapper, void *fn) { 15 | int ctxt = _cgo_wait_runtime_init_done(); 16 | struct { 17 | void *fn; 18 | } __attribute__((__packed__)) a; 19 | a.fn = fn; 20 | crosscall2((void (*)(void *, int))wrapper, &a, sizeof(a), ctxt); 21 | } 22 | -------------------------------------------------------------------------------- /internal/ccall/ccall.go: -------------------------------------------------------------------------------- 1 | package ccall 2 | 3 | /* 4 | #cgo CFLAGS: -I../ 5 | #cgo CFLAGS: -Iinclude 6 | 7 | #include 8 | */ 9 | import "C" 10 | 11 | var ( 12 | JIT_OPTLEVEL_NONE = C.JIT_OPTLEVEL_NONE 13 | JIT_OPTLEVEL_NORMAL = C.JIT_OPTLEVEL_NORMAL 14 | JIT_NO_OFFSET = C.JIT_NO_OFFSET 15 | ) 16 | -------------------------------------------------------------------------------- /internal/ccall/context.go: -------------------------------------------------------------------------------- 1 | package ccall 2 | 3 | /* 4 | #cgo CFLAGS: -I../ 5 | #cgo CFLAGS: -Iinclude 6 | 7 | #include 8 | 9 | extern void *get_crosscall2addr(); 10 | extern void *get_cgo_wait_runtime_init_done_addr(); 11 | */ 12 | import "C" 13 | 14 | var ( 15 | JIT_OPTION_CACHE_LIMIT = C.JIT_OPTION_CACHE_LIMIT 16 | JIT_OPTION_CACHE_PAGE_SIZE = C.JIT_OPTION_CACHE_PAGE_SIZE 17 | JIT_OPTION_PRE_COMPILE = C.JIT_OPTION_PRE_COMPILE 18 | JIT_OPTION_DONT_FOLD = C.JIT_OPTION_DONT_FOLD 19 | JIT_OPTION_POSITION_INDEPENDENT = C.JIT_OPTION_POSITION_INDEPENDENT 20 | JIT_OPTION_CACHE_MAX_PAGE_FACTOR = C.JIT_OPTION_CACHE_MAX_PAGE_FACTOR 21 | ) 22 | 23 | type Context struct { 24 | c C.jit_context_t 25 | crosscall2 *Function 26 | cgo_wait_runtime_init_done *Function 27 | } 28 | 29 | func toContext(c C.jit_context_t) *Context { 30 | return &Context{c: c} 31 | } 32 | 33 | func CreateContext() *Context { 34 | ctx := toContext(C.jit_context_create()) 35 | ctx.crosscall2 = ctx.createCrossCall2() 36 | ctx.cgo_wait_runtime_init_done = ctx.createCgoWaitRuntimeInitDone() 37 | return ctx 38 | } 39 | 40 | func (c *Context) Destroy() { 41 | C.jit_context_destroy(c.c) 42 | } 43 | 44 | func (c *Context) BuildStart() { 45 | C.jit_context_build_start(c.c) 46 | } 47 | 48 | func (c *Context) BuildEnd() { 49 | C.jit_context_build_end(c.c) 50 | } 51 | 52 | func (c *Context) CreateFunction(signature *Type) *Function { 53 | fn := toFunction(C.jit_function_create(c.c, signature.c)) 54 | fn.crosscall2 = c.crosscall2 55 | fn.cgo_wait_runtime_init_done = c.cgo_wait_runtime_init_done 56 | return fn 57 | } 58 | 59 | func (c *Context) CreateNestedFunction(signature *Type, parent *Function) *Function { 60 | return toFunction(C.jit_function_create_nested(c.c, signature.c, parent.c)) 61 | } 62 | 63 | func (c *Context) createCrossCall2() *Function { 64 | sig := CreateSignature([]*Type{TypeVoidPtr, TypeVoidPtr, TypeInt, TypeInt}, nil) 65 | fn := c.CreateFunction(sig) 66 | defer sig.Free() 67 | C.jit_function_setup_entry(fn.c, C.get_crosscall2addr()) 68 | return fn 69 | } 70 | 71 | func (c *Context) createCgoWaitRuntimeInitDone() *Function { 72 | sig := CreateSignature(nil, TypeInt) 73 | fn := c.CreateFunction(sig) 74 | defer sig.Free() 75 | C.jit_function_setup_entry(fn.c, C.get_cgo_wait_runtime_init_done_addr()) 76 | return fn 77 | } 78 | -------------------------------------------------------------------------------- /internal/ccall/include/jit/jit-apply.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-apply.h - Dynamic invocation and closure support functions. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * This file is part of the libjit library. 7 | * 8 | * The libjit library is free software: you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public License 10 | * as published by the Free Software Foundation, either version 2.1 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * The libjit library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with the libjit library. If not, see 20 | * . 21 | */ 22 | 23 | #ifndef _JIT_APPLY_H 24 | #define _JIT_APPLY_H 25 | 26 | #include 27 | 28 | #ifdef __cplusplus 29 | extern "C" { 30 | #endif 31 | 32 | /* 33 | * Prototype for closure functions. 34 | */ 35 | typedef void (*jit_closure_func)(jit_type_t signature, void *result, 36 | void **args, void *user_data); 37 | 38 | /* 39 | * Opaque type for accessing vararg parameters on closures. 40 | */ 41 | typedef struct jit_closure_va_list *jit_closure_va_list_t; 42 | 43 | /* 44 | * External function declarations. 45 | */ 46 | void jit_apply(jit_type_t signature, void *func, 47 | void **args, unsigned int num_fixed_args, 48 | void *return_value); 49 | void jit_apply_raw(jit_type_t signature, void *func, 50 | void *args, void *return_value); 51 | int jit_raw_supported(jit_type_t signature); 52 | 53 | void *jit_closure_create(jit_context_t context, jit_type_t signature, 54 | jit_closure_func func, void *user_data); 55 | 56 | jit_nint jit_closure_va_get_nint(jit_closure_va_list_t va); 57 | jit_nuint jit_closure_va_get_nuint(jit_closure_va_list_t va); 58 | jit_long jit_closure_va_get_long(jit_closure_va_list_t va); 59 | jit_ulong jit_closure_va_get_ulong(jit_closure_va_list_t va); 60 | jit_float32 jit_closure_va_get_float32(jit_closure_va_list_t va); 61 | jit_float64 jit_closure_va_get_float64(jit_closure_va_list_t va); 62 | jit_nfloat jit_closure_va_get_nfloat(jit_closure_va_list_t va); 63 | void *jit_closure_va_get_ptr(jit_closure_va_list_t va); 64 | void jit_closure_va_get_struct(jit_closure_va_list_t va, void *buf, jit_type_t type); 65 | 66 | #ifdef __cplusplus 67 | }; 68 | #endif 69 | 70 | #endif /* _JIT_APPLY_H */ 71 | -------------------------------------------------------------------------------- /internal/ccall/include/jit/jit-arch-arm.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-arch-arm.h - Architecture-specific definitions. 3 | * 4 | * Copyright (C) 2006 Southern Storm Software, Pty Ltd. 5 | * 6 | * The libjit library is free software: you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public License 8 | * as published by the Free Software Foundation, either version 2.1 of 9 | * the License, or (at your option) any later version. 10 | * 11 | * The libjit library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with the libjit library. If not, see 18 | * . 19 | */ 20 | 21 | #ifndef _JIT_ARCH_ARM_H 22 | #define _JIT_ARCH_ARM_H 23 | 24 | /* 25 | * If defined _JIT_ARCH_GET_CURRENT_FRAME() macro assigns the current frame 26 | * pointer to the supplied argument that has to be a void pointer. 27 | */ 28 | #if defined(__GNUC__) 29 | #define _JIT_ARCH_GET_CURRENT_FRAME(f) \ 30 | do { \ 31 | register void *__f asm("fp"); \ 32 | f = __f; \ 33 | } while(0) 34 | #else 35 | #undef _JIT_ARCH_GET_CURRENT_FRAME 36 | #endif 37 | 38 | #endif /* _JIT_ARCH_ARM_H */ 39 | -------------------------------------------------------------------------------- /internal/ccall/include/jit/jit-arch-generic.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-arch-generic.h - Architecture-specific definitions. 3 | * 4 | * Copyright (C) 2006 Southern Storm Software, Pty Ltd. 5 | * 6 | * This file is part of the libjit library. 7 | * 8 | * The libjit library is free software: you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public License 10 | * as published by the Free Software Foundation, either version 2.1 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * The libjit library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with the libjit library. If not, see 20 | * . 21 | */ 22 | 23 | #ifndef _JIT_ARCH_GENERIC_H 24 | #define _JIT_ARCH_GENERIC_H 25 | 26 | /* 27 | * If defined _JIT_ARCH_GET_CURRENT_FRAME() macro assigns the current frame 28 | * pointer to the supplied argument that has to be a void pointer. 29 | */ 30 | #undef _JIT_ARCH_GET_CURRENT_FRAME 31 | 32 | /* 33 | * If defined _JIT_ARCH_GET_NEXT_FRAME() assigns the frame address following 34 | * the frame supplied as second arg to the value supplied as first argument. 35 | */ 36 | #undef _JIT_ARCH_GET_NEXT_FRAME 37 | 38 | /* 39 | * If defined _JIT_ARCH_GET_RETURN_ADDRESS() assigns the return address of 40 | * the frame supplied as second arg to the value supplied as first argument. 41 | */ 42 | #undef _JIT_ARCH_GET_RETURN_ADDRESS 43 | 44 | /* 45 | * If defined _JIT_ARCH_GET_CURRENT_RETURN() assigns the return address of 46 | * the current to the supplied argument. 47 | */ 48 | #define _JIT_ARCH_GET_CURRENT_RETURN 49 | 50 | #endif /* _JIT_ARCH_GENERIC_H */ 51 | -------------------------------------------------------------------------------- /internal/ccall/include/jit/jit-arch-x86-64.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-arch-x86.h - Architecture-specific definitions. 3 | * 4 | * Copyright (C) 2008 Southern Storm Software, Pty Ltd. 5 | * 6 | * The libjit library is free software: you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public License 8 | * as published by the Free Software Foundation, either version 2.1 of 9 | * the License, or (at your option) any later version. 10 | * 11 | * The libjit library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with the libjit library. If not, see 18 | * . 19 | */ 20 | 21 | #ifndef _JIT_ARCH_X86_64_H 22 | #define _JIT_ARCH_X86_64_H 23 | 24 | /* 25 | * The frame header structure for X86_64 26 | */ 27 | typedef struct _jit_arch_frame _jit_arch_frame_t; 28 | struct _jit_arch_frame 29 | { 30 | _jit_arch_frame_t *next_frame; 31 | void *return_address; 32 | }; 33 | 34 | /* 35 | * If defined _JIT_ARCH_GET_CURRENT_FRAME() macro assigns the current frame 36 | * pointer to the supplied argument that has to be a void pointer. 37 | */ 38 | #if defined(__GNUC__) 39 | #define _JIT_ARCH_GET_CURRENT_FRAME(f) \ 40 | do { \ 41 | register void *__f asm("rbp"); \ 42 | f = __f; \ 43 | } while(0) 44 | #elif defined(_MSC_VER) && defined(_M_IX86) 45 | #define _JIT_ARCH_GET_CURRENT_FRAME(f) \ 46 | do { \ 47 | void *__ptr; \ 48 | __asm \ 49 | { \ 50 | __asm mov qword ptr __ptr, rbp \ 51 | } \ 52 | (f) = __ptr; \ 53 | } while(0) 54 | #else 55 | #undef _JIT_ARCH_GET_CURRENT_FRAME 56 | #endif 57 | 58 | /* 59 | * If defined _JIT_ARCH_GET_NEXT_FRAME() assigns the frame address following 60 | * the frame supplied as second arg to the value supplied as first argument. 61 | */ 62 | #define _JIT_ARCH_GET_NEXT_FRAME(n, f) \ 63 | do { \ 64 | (n) = (void *)((f) ? ((_jit_arch_frame_t *)(f))->next_frame : 0); \ 65 | } while(0) 66 | 67 | /* 68 | * If defined _JIT_ARCH_GET_RETURN_ADDRESS() assigns the return address of 69 | * the frame supplied as second arg to the value supplied as first argument. 70 | */ 71 | #define _JIT_ARCH_GET_RETURN_ADDRESS(r, f) \ 72 | do { \ 73 | (r) = (void *)((f) ? ((_jit_arch_frame_t *)(f))->return_address : 0); \ 74 | } while(0) 75 | 76 | /* 77 | * If defined _JIT_ARCH_GET_CURRENT_RETURN() assigns the return address of 78 | * the current to the supplied argument. 79 | */ 80 | #define _JIT_ARCH_GET_CURRENT_RETURN(r) \ 81 | do { \ 82 | void *__frame; \ 83 | _JIT_ARCH_GET_CURRENT_FRAME(__frame); \ 84 | _JIT_ARCH_GET_RETURN_ADDRESS((r), __frame); \ 85 | } while(0) 86 | 87 | #endif /* _JIT_ARCH_X86_64_H */ 88 | -------------------------------------------------------------------------------- /internal/ccall/include/jit/jit-arch-x86.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-arch-x86.h - Architecture-specific definitions. 3 | * 4 | * Copyright (C) 2006 Southern Storm Software, Pty Ltd. 5 | * 6 | * The libjit library is free software: you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public License 8 | * as published by the Free Software Foundation, either version 2.1 of 9 | * the License, or (at your option) any later version. 10 | * 11 | * The libjit library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with the libjit library. If not, see 18 | * . 19 | */ 20 | 21 | #ifndef _JIT_ARCH_X86_H 22 | #define _JIT_ARCH_X86_H 23 | 24 | /* 25 | * If defined _JIT_ARCH_GET_CURRENT_FRAME() macro assigns the current frame 26 | * pointer to the supplied argument that has to be a void pointer. 27 | */ 28 | #if defined(__GNUC__) 29 | #define _JIT_ARCH_GET_CURRENT_FRAME(f) \ 30 | do { \ 31 | register void *__f asm("ebp"); \ 32 | f = __f; \ 33 | } while(0) 34 | #elif defined(_MSC_VER) && defined(_M_IX86) 35 | #define _JIT_ARCH_GET_CURRENT_FRAME(f) \ 36 | do { \ 37 | void *__ptr; \ 38 | __asm \ 39 | { \ 40 | __asm mov dword ptr __ptr, ebp \ 41 | } \ 42 | (f) = __ptr; \ 43 | } while(0) 44 | #else 45 | #undef _JIT_ARCH_GET_CURRENT_FRAME 46 | #endif 47 | 48 | #endif /* _JIT_ARCH_X86_H */ 49 | -------------------------------------------------------------------------------- /internal/ccall/include/jit/jit-arch.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-arch-x86.h - Architecture-specific definitions. 3 | * 4 | * Copyright (C) 2008 Southern Storm Software, Pty Ltd. 5 | * 6 | * The libjit library is free software: you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public License 8 | * as published by the Free Software Foundation, either version 2.1 of 9 | * the License, or (at your option) any later version. 10 | * 11 | * The libjit library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with the libjit library. If not, see 18 | * . 19 | */ 20 | 21 | #ifndef _JIT_ARCH_X86_64_H 22 | #define _JIT_ARCH_X86_64_H 23 | 24 | /* 25 | * The frame header structure for X86_64 26 | */ 27 | typedef struct _jit_arch_frame _jit_arch_frame_t; 28 | struct _jit_arch_frame 29 | { 30 | _jit_arch_frame_t *next_frame; 31 | void *return_address; 32 | }; 33 | 34 | /* 35 | * If defined _JIT_ARCH_GET_CURRENT_FRAME() macro assigns the current frame 36 | * pointer to the supplied argument that has to be a void pointer. 37 | */ 38 | #if defined(__GNUC__) 39 | #define _JIT_ARCH_GET_CURRENT_FRAME(f) \ 40 | do { \ 41 | register void *__f asm("rbp"); \ 42 | f = __f; \ 43 | } while(0) 44 | #elif defined(_MSC_VER) && defined(_M_IX86) 45 | #define _JIT_ARCH_GET_CURRENT_FRAME(f) \ 46 | do { \ 47 | void *__ptr; \ 48 | __asm \ 49 | { \ 50 | __asm mov qword ptr __ptr, rbp \ 51 | } \ 52 | (f) = __ptr; \ 53 | } while(0) 54 | #else 55 | #undef _JIT_ARCH_GET_CURRENT_FRAME 56 | #endif 57 | 58 | /* 59 | * If defined _JIT_ARCH_GET_NEXT_FRAME() assigns the frame address following 60 | * the frame supplied as second arg to the value supplied as first argument. 61 | */ 62 | #define _JIT_ARCH_GET_NEXT_FRAME(n, f) \ 63 | do { \ 64 | (n) = (void *)((f) ? ((_jit_arch_frame_t *)(f))->next_frame : 0); \ 65 | } while(0) 66 | 67 | /* 68 | * If defined _JIT_ARCH_GET_RETURN_ADDRESS() assigns the return address of 69 | * the frame supplied as second arg to the value supplied as first argument. 70 | */ 71 | #define _JIT_ARCH_GET_RETURN_ADDRESS(r, f) \ 72 | do { \ 73 | (r) = (void *)((f) ? ((_jit_arch_frame_t *)(f))->return_address : 0); \ 74 | } while(0) 75 | 76 | /* 77 | * If defined _JIT_ARCH_GET_CURRENT_RETURN() assigns the return address of 78 | * the current to the supplied argument. 79 | */ 80 | #define _JIT_ARCH_GET_CURRENT_RETURN(r) \ 81 | do { \ 82 | void *__frame; \ 83 | _JIT_ARCH_GET_CURRENT_FRAME(__frame); \ 84 | _JIT_ARCH_GET_RETURN_ADDRESS((r), __frame); \ 85 | } while(0) 86 | 87 | #endif /* _JIT_ARCH_X86_64_H */ 88 | -------------------------------------------------------------------------------- /internal/ccall/include/jit/jit-block.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-block.h - Functions for manipulating blocks. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * The libjit library is free software: you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public License 8 | * as published by the Free Software Foundation, either version 2.1 of 9 | * the License, or (at your option) any later version. 10 | * 11 | * The libjit library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with the libjit library. If not, see 18 | * . 19 | */ 20 | 21 | #ifndef _JIT_BLOCK_H 22 | #define _JIT_BLOCK_H 23 | 24 | #include 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | jit_function_t jit_block_get_function(jit_block_t block) JIT_NOTHROW; 31 | jit_context_t jit_block_get_context(jit_block_t block) JIT_NOTHROW; 32 | jit_label_t jit_block_get_label(jit_block_t block) JIT_NOTHROW; 33 | jit_label_t jit_block_get_next_label(jit_block_t block, 34 | jit_label_t label) JIT_NOTHROW; 35 | jit_block_t jit_block_next(jit_function_t func, 36 | jit_block_t previous) JIT_NOTHROW; 37 | jit_block_t jit_block_previous(jit_function_t func, 38 | jit_block_t previous) JIT_NOTHROW; 39 | jit_block_t jit_block_from_label(jit_function_t func, 40 | jit_label_t label) JIT_NOTHROW; 41 | int jit_block_set_meta(jit_block_t block, int type, void *data, 42 | jit_meta_free_func free_data) JIT_NOTHROW; 43 | void *jit_block_get_meta(jit_block_t block, int type) JIT_NOTHROW; 44 | void jit_block_free_meta(jit_block_t block, int type) JIT_NOTHROW; 45 | int jit_block_is_reachable(jit_block_t block) JIT_NOTHROW; 46 | int jit_block_ends_in_dead(jit_block_t block) JIT_NOTHROW; 47 | int jit_block_current_is_dead(jit_function_t func) JIT_NOTHROW; 48 | 49 | #ifdef __cplusplus 50 | }; 51 | #endif 52 | 53 | #endif /* _JIT_BLOCK_H */ 54 | -------------------------------------------------------------------------------- /internal/ccall/include/jit/jit-common.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-common.h - Common type definitions that are used by the JIT. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * The libjit library is free software: you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public License 8 | * as published by the Free Software Foundation, either version 2.1 of 9 | * the License, or (at your option) any later version. 10 | * 11 | * The libjit library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with the libjit library. If not, see 18 | * . 19 | */ 20 | 21 | #ifndef _JIT_COMMON_H 22 | #define _JIT_COMMON_H 23 | 24 | #include 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | /* 31 | * Opaque structure that represents a context. 32 | */ 33 | typedef struct _jit_context *jit_context_t; 34 | 35 | /* 36 | * Opaque structure that represents a function. 37 | */ 38 | typedef struct _jit_function *jit_function_t; 39 | 40 | /* 41 | * Opaque structure that represents a block. 42 | */ 43 | typedef struct _jit_block *jit_block_t; 44 | 45 | /* 46 | * Opaque structure that represents an instruction. 47 | */ 48 | typedef struct _jit_insn *jit_insn_t; 49 | 50 | /* 51 | * Opaque structure that represents a value. 52 | */ 53 | typedef struct _jit_value *jit_value_t; 54 | 55 | /* 56 | * Opaque structure that represents a type descriptor. 57 | */ 58 | typedef struct _jit_type *jit_type_t; 59 | 60 | /* 61 | * Opaque type that represents an exception stack trace. 62 | */ 63 | typedef struct jit_stack_trace *jit_stack_trace_t; 64 | 65 | /* 66 | * Block label identifier. 67 | */ 68 | typedef jit_nuint jit_label_t; 69 | 70 | /* 71 | * Value that represents an undefined label. 72 | */ 73 | #define jit_label_undefined ((jit_label_t)~((jit_uint)0)) 74 | 75 | /* 76 | * Value that represents an undefined offset. 77 | */ 78 | #define JIT_NO_OFFSET (~((unsigned int)0)) 79 | 80 | /* 81 | * Function that is used to free user-supplied metadata. 82 | */ 83 | typedef void (*jit_meta_free_func)(void *data); 84 | 85 | /* 86 | * Function that is used to compile a function on demand. 87 | * Returns zero if the compilation process failed for some reason. 88 | */ 89 | typedef int (*jit_on_demand_func)(jit_function_t func); 90 | 91 | /* 92 | * Function that is used to control on demand compilation. 93 | * Typically, it should take care of the context locking and unlocking, 94 | * calling function's on demand compiler, and final compilation. 95 | */ 96 | typedef void *(*jit_on_demand_driver_func)(jit_function_t func); 97 | 98 | #ifdef __cplusplus 99 | }; 100 | #endif 101 | 102 | #endif /* _JIT_COMMON_H */ 103 | -------------------------------------------------------------------------------- /internal/ccall/include/jit/jit-context.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-context.h - Functions for manipulating JIT contexts. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * The libjit library is free software: you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public License 8 | * as published by the Free Software Foundation, either version 2.1 of 9 | * the License, or (at your option) any later version. 10 | * 11 | * The libjit library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with the libjit library. If not, see 18 | * . 19 | */ 20 | 21 | #ifndef _JIT_CONTEXT_H 22 | #define _JIT_CONTEXT_H 23 | 24 | #include 25 | #include 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | jit_context_t jit_context_create(void) JIT_NOTHROW; 32 | void jit_context_destroy(jit_context_t context) JIT_NOTHROW; 33 | 34 | void jit_context_build_start(jit_context_t context) JIT_NOTHROW; 35 | void jit_context_build_end(jit_context_t context) JIT_NOTHROW; 36 | 37 | void jit_context_set_on_demand_driver( 38 | jit_context_t context, 39 | jit_on_demand_driver_func driver) JIT_NOTHROW; 40 | 41 | void jit_context_set_memory_manager( 42 | jit_context_t context, 43 | jit_memory_manager_t manager) JIT_NOTHROW; 44 | 45 | int jit_context_set_meta 46 | (jit_context_t context, int type, void *data, 47 | jit_meta_free_func free_data) JIT_NOTHROW; 48 | int jit_context_set_meta_numeric 49 | (jit_context_t context, int type, jit_nuint data) JIT_NOTHROW; 50 | void *jit_context_get_meta(jit_context_t context, int type) JIT_NOTHROW; 51 | jit_nuint jit_context_get_meta_numeric 52 | (jit_context_t context, int type) JIT_NOTHROW; 53 | void jit_context_free_meta(jit_context_t context, int type) JIT_NOTHROW; 54 | 55 | /* 56 | * Standard meta values for builtin configurable options. 57 | */ 58 | #define JIT_OPTION_CACHE_LIMIT 10000 59 | #define JIT_OPTION_CACHE_PAGE_SIZE 10001 60 | #define JIT_OPTION_PRE_COMPILE 10002 61 | #define JIT_OPTION_DONT_FOLD 10003 62 | #define JIT_OPTION_POSITION_INDEPENDENT 10004 63 | #define JIT_OPTION_CACHE_MAX_PAGE_FACTOR 10005 64 | 65 | #ifdef __cplusplus 66 | }; 67 | #endif 68 | 69 | #endif /* _JIT_CONTEXT_H */ 70 | -------------------------------------------------------------------------------- /internal/ccall/include/jit/jit-debugger.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-debugger.h - Helper routines for single-step debugging of programs. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * The libjit library is free software: you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public License 8 | * as published by the Free Software Foundation, either version 2.1 of 9 | * the License, or (at your option) any later version. 10 | * 11 | * The libjit library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with the libjit library. If not, see 18 | * . 19 | */ 20 | 21 | #ifndef _JIT_DEBUGGER_H 22 | #define _JIT_DEBUGGER_H 23 | 24 | #include 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | typedef struct jit_debugger *jit_debugger_t; 31 | typedef jit_nint jit_debugger_thread_id_t; 32 | typedef jit_nint jit_debugger_breakpoint_id_t; 33 | 34 | typedef struct jit_debugger_event 35 | { 36 | int type; 37 | jit_debugger_thread_id_t thread; 38 | jit_function_t function; 39 | jit_nint data1; 40 | jit_nint data2; 41 | jit_debugger_breakpoint_id_t id; 42 | jit_stack_trace_t trace; 43 | 44 | } jit_debugger_event_t; 45 | 46 | #define JIT_DEBUGGER_TYPE_QUIT 0 47 | #define JIT_DEBUGGER_TYPE_HARD_BREAKPOINT 1 48 | #define JIT_DEBUGGER_TYPE_SOFT_BREAKPOINT 2 49 | #define JIT_DEBUGGER_TYPE_USER_BREAKPOINT 3 50 | #define JIT_DEBUGGER_TYPE_ATTACH_THREAD 4 51 | #define JIT_DEBUGGER_TYPE_DETACH_THREAD 5 52 | 53 | typedef struct jit_debugger_breakpoint_info 54 | { 55 | int flags; 56 | jit_debugger_thread_id_t thread; 57 | jit_function_t function; 58 | jit_nint data1; 59 | jit_nint data2; 60 | 61 | } *jit_debugger_breakpoint_info_t; 62 | 63 | #define JIT_DEBUGGER_FLAG_THREAD (1 << 0) 64 | #define JIT_DEBUGGER_FLAG_FUNCTION (1 << 1) 65 | #define JIT_DEBUGGER_FLAG_DATA1 (1 << 2) 66 | #define JIT_DEBUGGER_FLAG_DATA2 (1 << 3) 67 | 68 | #define JIT_DEBUGGER_DATA1_FIRST 10000 69 | #define JIT_DEBUGGER_DATA1_LINE 10000 70 | #define JIT_DEBUGGER_DATA1_ENTER 10001 71 | #define JIT_DEBUGGER_DATA1_LEAVE 10002 72 | #define JIT_DEBUGGER_DATA1_THROW 10003 73 | 74 | typedef void (*jit_debugger_hook_func) 75 | (jit_function_t func, jit_nint data1, jit_nint data2); 76 | 77 | int jit_debugging_possible(void) JIT_NOTHROW; 78 | 79 | jit_debugger_t jit_debugger_create(jit_context_t context) JIT_NOTHROW; 80 | void jit_debugger_destroy(jit_debugger_t dbg) JIT_NOTHROW; 81 | 82 | jit_context_t jit_debugger_get_context(jit_debugger_t dbg) JIT_NOTHROW; 83 | jit_debugger_t jit_debugger_from_context(jit_context_t context) JIT_NOTHROW; 84 | 85 | jit_debugger_thread_id_t jit_debugger_get_self(jit_debugger_t dbg) JIT_NOTHROW; 86 | jit_debugger_thread_id_t jit_debugger_get_thread 87 | (jit_debugger_t dbg, const void *native_thread) JIT_NOTHROW; 88 | int jit_debugger_get_native_thread 89 | (jit_debugger_t dbg, jit_debugger_thread_id_t thread, 90 | void *native_thread) JIT_NOTHROW; 91 | void jit_debugger_set_breakable 92 | (jit_debugger_t dbg, const void *native_thread, int flag) JIT_NOTHROW; 93 | 94 | void jit_debugger_attach_self 95 | (jit_debugger_t dbg, int stop_immediately) JIT_NOTHROW; 96 | void jit_debugger_detach_self(jit_debugger_t dbg) JIT_NOTHROW; 97 | 98 | int jit_debugger_wait_event 99 | (jit_debugger_t dbg, jit_debugger_event_t *event, 100 | jit_int timeout) JIT_NOTHROW; 101 | 102 | jit_debugger_breakpoint_id_t jit_debugger_add_breakpoint 103 | (jit_debugger_t dbg, jit_debugger_breakpoint_info_t info) JIT_NOTHROW; 104 | void jit_debugger_remove_breakpoint 105 | (jit_debugger_t dbg, jit_debugger_breakpoint_id_t id) JIT_NOTHROW; 106 | void jit_debugger_remove_all_breakpoints(jit_debugger_t dbg) JIT_NOTHROW; 107 | 108 | int jit_debugger_is_alive 109 | (jit_debugger_t dbg, jit_debugger_thread_id_t thread) JIT_NOTHROW; 110 | int jit_debugger_is_running 111 | (jit_debugger_t dbg, jit_debugger_thread_id_t thread) JIT_NOTHROW; 112 | void jit_debugger_run 113 | (jit_debugger_t dbg, jit_debugger_thread_id_t thread) JIT_NOTHROW; 114 | void jit_debugger_step 115 | (jit_debugger_t dbg, jit_debugger_thread_id_t thread) JIT_NOTHROW; 116 | void jit_debugger_next 117 | (jit_debugger_t dbg, jit_debugger_thread_id_t thread) JIT_NOTHROW; 118 | void jit_debugger_finish 119 | (jit_debugger_t dbg, jit_debugger_thread_id_t thread) JIT_NOTHROW; 120 | 121 | void jit_debugger_break(jit_debugger_t dbg) JIT_NOTHROW; 122 | 123 | void jit_debugger_quit(jit_debugger_t dbg) JIT_NOTHROW; 124 | 125 | jit_debugger_hook_func jit_debugger_set_hook 126 | (jit_context_t context, jit_debugger_hook_func hook); 127 | 128 | #ifdef __cplusplus 129 | }; 130 | #endif 131 | 132 | #endif /* _JIT_DEBUGGER_H */ 133 | -------------------------------------------------------------------------------- /internal/ccall/include/jit/jit-defs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-defs.h - Define the primitive numeric types for use by the JIT. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * The libjit library is free software: you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public License 8 | * as published by the Free Software Foundation, either version 2.1 of 9 | * the License, or (at your option) any later version. 10 | * 11 | * The libjit library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with the libjit library. If not, see 18 | * . 19 | */ 20 | 21 | #ifndef _JIT_DEFS_H 22 | #define _JIT_DEFS_H 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | #ifdef _MSC_VER 29 | #define JIT_EXPORT_DATA extern __declspec(dllimport) 30 | #else 31 | #define JIT_EXPORT_DATA extern 32 | #endif 33 | 34 | 35 | 36 | typedef char jit_sbyte; 37 | typedef unsigned char jit_ubyte; 38 | typedef short jit_short; 39 | typedef unsigned short jit_ushort; 40 | typedef int jit_int; 41 | typedef unsigned int jit_uint; 42 | typedef long jit_nint; 43 | typedef unsigned long jit_nuint; 44 | typedef long jit_long; 45 | typedef unsigned long jit_ulong; 46 | typedef float jit_float32; 47 | typedef double jit_float64; 48 | typedef long double jit_nfloat; 49 | typedef void *jit_ptr; 50 | 51 | #define JIT_NATIVE_INT64 1 52 | 53 | 54 | typedef jit_nuint jit_size_t; 55 | 56 | #if defined(__cplusplus) && defined(__GNUC__) 57 | # define JIT_NOTHROW 58 | #else 59 | # define JIT_NOTHROW 60 | #endif 61 | 62 | #define jit_min_int (((jit_int) 1) << (sizeof(jit_int) * 8 - 1)) 63 | #define jit_max_int ((jit_int) (~jit_min_int)) 64 | #define jit_max_uint ((jit_uint) (~((jit_uint) 0))) 65 | #define jit_min_long (((jit_long) 1) << (sizeof(jit_long) * 8 - 1)) 66 | #define jit_max_long ((jit_long) (~jit_min_long)) 67 | #define jit_max_ulong ((jit_ulong) (~((jit_ulong) 0))) 68 | 69 | #ifdef __cplusplus 70 | }; 71 | #endif 72 | 73 | #endif /* _JIT_DEFS_H */ 74 | -------------------------------------------------------------------------------- /internal/ccall/include/jit/jit-defs.h.in: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-defs.h - Define the primitive numeric types for use by the JIT. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * The libjit library is free software: you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public License 8 | * as published by the Free Software Foundation, either version 2.1 of 9 | * the License, or (at your option) any later version. 10 | * 11 | * The libjit library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with the libjit library. If not, see 18 | * . 19 | */ 20 | 21 | #ifndef _JIT_DEFS_H 22 | #define _JIT_DEFS_H 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | #ifdef _MSC_VER 29 | #define JIT_EXPORT_DATA extern __declspec(dllimport) 30 | #else 31 | #define JIT_EXPORT_DATA extern 32 | #endif 33 | 34 | @JIT_INT64_INCLUDE@ 35 | 36 | typedef @JITINT8@ jit_sbyte; 37 | typedef @JITUINT8@ jit_ubyte; 38 | typedef @JITINT16@ jit_short; 39 | typedef unsigned @JITINT16@ jit_ushort; 40 | typedef @JITINT32@ jit_int; 41 | typedef unsigned @JITINT32@ jit_uint; 42 | typedef @JITNATIVEINT@ jit_nint; 43 | typedef unsigned @JITNATIVEINT@ jit_nuint; 44 | typedef @JITINT64@ jit_long; 45 | typedef unsigned @JITINT64@ jit_ulong; 46 | typedef @JITFLOAT32@ jit_float32; 47 | typedef @JITFLOAT64@ jit_float64; 48 | typedef @JITNATIVEFLOAT@ jit_nfloat; 49 | typedef void *jit_ptr; 50 | 51 | #define @JITNATIVEINTDEFINE@ 1 52 | @JITNFLOATISDOUBLE@ 53 | 54 | typedef jit_nuint jit_size_t; 55 | 56 | #if defined(__cplusplus) && defined(__GNUC__) 57 | # define JIT_NOTHROW @JITTHROWIDIOM@ 58 | #else 59 | # define JIT_NOTHROW 60 | #endif 61 | 62 | #define jit_min_int (((jit_int) 1) << (sizeof(jit_int) * 8 - 1)) 63 | #define jit_max_int ((jit_int) (~jit_min_int)) 64 | #define jit_max_uint ((jit_uint) (~((jit_uint) 0))) 65 | #define jit_min_long (((jit_long) 1) << (sizeof(jit_long) * 8 - 1)) 66 | #define jit_max_long ((jit_long) (~jit_min_long)) 67 | #define jit_max_ulong ((jit_ulong) (~((jit_ulong) 0))) 68 | 69 | #ifdef __cplusplus 70 | }; 71 | #endif 72 | 73 | #endif /* _JIT_DEFS_H */ 74 | -------------------------------------------------------------------------------- /internal/ccall/include/jit/jit-dump.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-dump.h - Functions for dumping JIT structures, for debugging. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * The libjit library is free software: you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public License 8 | * as published by the Free Software Foundation, either version 2.1 of 9 | * the License, or (at your option) any later version. 10 | * 11 | * The libjit library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with the libjit library. If not, see 18 | * . 19 | */ 20 | 21 | #ifndef _JIT_DUMP_H 22 | #define _JIT_DUMP_H 23 | 24 | #include 25 | #include 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | void jit_dump_type(FILE *stream, jit_type_t type) JIT_NOTHROW; 32 | void jit_dump_value 33 | (FILE *stream, jit_function_t func, 34 | jit_value_t value, const char *prefix) JIT_NOTHROW; 35 | void jit_dump_insn 36 | (FILE *stream, jit_function_t func, jit_insn_t insn) JIT_NOTHROW; 37 | void jit_dump_function 38 | (FILE *stream, jit_function_t func, const char *name) JIT_NOTHROW; 39 | 40 | #ifdef __cplusplus 41 | }; 42 | #endif 43 | 44 | #endif /* _JIT_DUMP_H */ 45 | -------------------------------------------------------------------------------- /internal/ccall/include/jit/jit-dynamic.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-dynamic.h - Managing dynamic libraries and cross-language invocation. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * The libjit library is free software: you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public License 8 | * as published by the Free Software Foundation, either version 2.1 of 9 | * the License, or (at your option) any later version. 10 | * 11 | * The libjit library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with the libjit library. If not, see 18 | * . 19 | */ 20 | 21 | #ifndef _JIT_DYNAMIC_H 22 | #define _JIT_DYNAMIC_H 23 | 24 | #include 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | /* 31 | * Dynamic library routines. 32 | */ 33 | typedef void *jit_dynlib_handle_t; 34 | jit_dynlib_handle_t jit_dynlib_open(const char *name) JIT_NOTHROW; 35 | void jit_dynlib_close(jit_dynlib_handle_t handle) JIT_NOTHROW; 36 | void *jit_dynlib_get_symbol 37 | (jit_dynlib_handle_t handle, const char *symbol) JIT_NOTHROW; 38 | const char *jit_dynlib_get_suffix(void) JIT_NOTHROW; 39 | void jit_dynlib_set_debug(int flag) JIT_NOTHROW; 40 | 41 | /* 42 | * C++ name mangling definitions. 43 | */ 44 | #define JIT_MANGLE_PUBLIC 0x0001 45 | #define JIT_MANGLE_PROTECTED 0x0002 46 | #define JIT_MANGLE_PRIVATE 0x0003 47 | #define JIT_MANGLE_STATIC 0x0008 48 | #define JIT_MANGLE_VIRTUAL 0x0010 49 | #define JIT_MANGLE_CONST 0x0020 50 | #define JIT_MANGLE_EXPLICIT_THIS 0x0040 51 | #define JIT_MANGLE_IS_CTOR 0x0080 52 | #define JIT_MANGLE_IS_DTOR 0x0100 53 | #define JIT_MANGLE_BASE 0x0200 54 | char *jit_mangle_global_function 55 | (const char *name, jit_type_t signature, int form) JIT_NOTHROW; 56 | char *jit_mangle_member_function 57 | (const char *class_name, const char *name, 58 | jit_type_t signature, int form, int flags) JIT_NOTHROW; 59 | 60 | #ifdef __cplusplus 61 | }; 62 | #endif 63 | 64 | #endif /* _JIT_DYNAMIC_H */ 65 | -------------------------------------------------------------------------------- /internal/ccall/include/jit/jit-elf.h: -------------------------------------------------------------------------------- 1 | /* 2 | * - Routines to read and write ELF-format binaries. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * The libjit library is free software: you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public License 8 | * as published by the Free Software Foundation, either version 2.1 of 9 | * the License, or (at your option) any later version. 10 | * 11 | * The libjit library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with the libjit library. If not, see 18 | * . 19 | */ 20 | 21 | #ifndef _JIT_ELF_H 22 | #define _JIT_ELF_H 23 | 24 | #include 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | /* 31 | * Opaque types that represent a loaded ELF binary in read or write mode. 32 | */ 33 | typedef struct jit_readelf *jit_readelf_t; 34 | typedef struct jit_writeelf *jit_writeelf_t; 35 | 36 | /* 37 | * Flags for "jit_readelf_open". 38 | */ 39 | #define JIT_READELF_FLAG_FORCE (1 << 0) /* Force file to load */ 40 | #define JIT_READELF_FLAG_DEBUG (1 << 1) /* Print debugging information */ 41 | 42 | /* 43 | * Result codes from "jit_readelf_open". 44 | */ 45 | #define JIT_READELF_OK 0 /* File was opened successfully */ 46 | #define JIT_READELF_CANNOT_OPEN 1 /* Could not open the file */ 47 | #define JIT_READELF_NOT_ELF 2 /* Not an ELF-format binary */ 48 | #define JIT_READELF_WRONG_ARCH 3 /* Wrong architecture for local system */ 49 | #define JIT_READELF_BAD_FORMAT 4 /* ELF file, but badly formatted */ 50 | #define JIT_READELF_MEMORY 5 /* Insufficient memory to load the file */ 51 | 52 | /* 53 | * External function declarations. 54 | */ 55 | int jit_readelf_open 56 | (jit_readelf_t *readelf, const char *filename, int flags) JIT_NOTHROW; 57 | void jit_readelf_close(jit_readelf_t readelf) JIT_NOTHROW; 58 | const char *jit_readelf_get_name(jit_readelf_t readelf) JIT_NOTHROW; 59 | void *jit_readelf_get_symbol 60 | (jit_readelf_t readelf, const char *name) JIT_NOTHROW; 61 | void *jit_readelf_get_section 62 | (jit_readelf_t readelf, const char *name, jit_nuint *size) JIT_NOTHROW; 63 | void *jit_readelf_get_section_by_type 64 | (jit_readelf_t readelf, jit_int type, jit_nuint *size) JIT_NOTHROW; 65 | void *jit_readelf_map_vaddr 66 | (jit_readelf_t readelf, jit_nuint vaddr) JIT_NOTHROW; 67 | unsigned int jit_readelf_num_needed(jit_readelf_t readelf) JIT_NOTHROW; 68 | const char *jit_readelf_get_needed 69 | (jit_readelf_t readelf, unsigned int index) JIT_NOTHROW; 70 | void jit_readelf_add_to_context 71 | (jit_readelf_t readelf, jit_context_t context) JIT_NOTHROW; 72 | int jit_readelf_resolve_all 73 | (jit_context_t context, int print_failures) JIT_NOTHROW; 74 | int jit_readelf_register_symbol 75 | (jit_context_t context, const char *name, 76 | void *value, int after) JIT_NOTHROW; 77 | 78 | jit_writeelf_t jit_writeelf_create(const char *library_name) JIT_NOTHROW; 79 | void jit_writeelf_destroy(jit_writeelf_t writeelf) JIT_NOTHROW; 80 | int jit_writeelf_write 81 | (jit_writeelf_t writeelf, const char *filename) JIT_NOTHROW; 82 | int jit_writeelf_add_function 83 | (jit_writeelf_t writeelf, jit_function_t func, 84 | const char *name) JIT_NOTHROW; 85 | int jit_writeelf_add_needed 86 | (jit_writeelf_t writeelf, const char *library_name) JIT_NOTHROW; 87 | int jit_writeelf_write_section 88 | (jit_writeelf_t writeelf, const char *name, jit_int type, 89 | const void *buf, unsigned int len, int discardable) JIT_NOTHROW; 90 | 91 | #ifdef __cplusplus 92 | }; 93 | #endif 94 | 95 | #endif /* _JIT_ELF_H */ 96 | -------------------------------------------------------------------------------- /internal/ccall/include/jit/jit-except.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-except.h - Exception handling functions. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * The libjit library is free software: you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public License 8 | * as published by the Free Software Foundation, either version 2.1 of 9 | * the License, or (at your option) any later version. 10 | * 11 | * The libjit library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with the libjit library. If not, see 18 | * . 19 | */ 20 | 21 | #ifndef _JIT_EXCEPT_H 22 | #define _JIT_EXCEPT_H 23 | 24 | #include 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | /* 31 | * Builtin exception type codes, and result values for intrinsic functions. 32 | */ 33 | #define JIT_RESULT_OK (1) 34 | #define JIT_RESULT_OVERFLOW (0) 35 | #define JIT_RESULT_ARITHMETIC (-1) 36 | #define JIT_RESULT_DIVISION_BY_ZERO (-2) 37 | #define JIT_RESULT_COMPILE_ERROR (-3) 38 | #define JIT_RESULT_OUT_OF_MEMORY (-4) 39 | #define JIT_RESULT_NULL_REFERENCE (-5) 40 | #define JIT_RESULT_NULL_FUNCTION (-6) 41 | #define JIT_RESULT_CALLED_NESTED (-7) 42 | #define JIT_RESULT_OUT_OF_BOUNDS (-8) 43 | #define JIT_RESULT_UNDEFINED_LABEL (-9) 44 | #define JIT_RESULT_MEMORY_FULL (-10000) 45 | 46 | /* 47 | * Exception handling function for builtin exceptions. 48 | */ 49 | typedef void *(*jit_exception_func)(int exception_type); 50 | 51 | /* 52 | * External function declarations. 53 | */ 54 | void *jit_exception_get_last(void); 55 | void *jit_exception_get_last_and_clear(void); 56 | void jit_exception_set_last(void *object); 57 | void jit_exception_clear_last(void); 58 | void jit_exception_throw(void *object); 59 | void jit_exception_builtin(int exception_type); 60 | jit_exception_func jit_exception_set_handler(jit_exception_func handler); 61 | jit_exception_func jit_exception_get_handler(void); 62 | jit_stack_trace_t jit_exception_get_stack_trace(void); 63 | unsigned int jit_stack_trace_get_size(jit_stack_trace_t trace); 64 | jit_function_t jit_stack_trace_get_function(jit_context_t context, 65 | jit_stack_trace_t trace, 66 | unsigned int posn); 67 | void *jit_stack_trace_get_pc(jit_stack_trace_t trace, unsigned int posn); 68 | unsigned int jit_stack_trace_get_offset(jit_context_t context, 69 | jit_stack_trace_t trace, 70 | unsigned int posn); 71 | void jit_stack_trace_free(jit_stack_trace_t trace); 72 | 73 | #ifdef __cplusplus 74 | }; 75 | #endif 76 | 77 | #endif /* _JIT_EXCEPT_H */ 78 | -------------------------------------------------------------------------------- /internal/ccall/include/jit/jit-function.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-function.h - Functions for manipulating functions blocks. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * The libjit library is free software: you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public License 8 | * as published by the Free Software Foundation, either version 2.1 of 9 | * the License, or (at your option) any later version. 10 | * 11 | * The libjit library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with the libjit library. If not, see 18 | * . 19 | */ 20 | 21 | #ifndef _JIT_FUNCTION_H 22 | #define _JIT_FUNCTION_H 23 | 24 | #include 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | /* Optimization levels */ 31 | #define JIT_OPTLEVEL_NONE 0 32 | #define JIT_OPTLEVEL_NORMAL 1 33 | 34 | jit_function_t jit_function_create 35 | (jit_context_t context, jit_type_t signature) JIT_NOTHROW; 36 | jit_function_t jit_function_create_nested 37 | (jit_context_t context, jit_type_t signature, 38 | jit_function_t parent) JIT_NOTHROW; 39 | void jit_function_abandon(jit_function_t func) JIT_NOTHROW; 40 | jit_context_t jit_function_get_context(jit_function_t func) JIT_NOTHROW; 41 | jit_type_t jit_function_get_signature(jit_function_t func) JIT_NOTHROW; 42 | int jit_function_set_meta 43 | (jit_function_t func, int type, void *data, 44 | jit_meta_free_func free_data, int build_only) JIT_NOTHROW; 45 | void *jit_function_get_meta(jit_function_t func, int type) JIT_NOTHROW; 46 | void jit_function_free_meta(jit_function_t func, int type) JIT_NOTHROW; 47 | jit_function_t jit_function_next 48 | (jit_context_t context, jit_function_t prev) JIT_NOTHROW; 49 | jit_function_t jit_function_previous 50 | (jit_context_t context, jit_function_t prev) JIT_NOTHROW; 51 | jit_block_t jit_function_get_entry(jit_function_t func) JIT_NOTHROW; 52 | jit_block_t jit_function_get_current(jit_function_t func) JIT_NOTHROW; 53 | jit_function_t jit_function_get_nested_parent(jit_function_t func) JIT_NOTHROW; 54 | void jit_function_set_parent_frame(jit_function_t func, 55 | jit_value_t parent_frame) JIT_NOTHROW; 56 | int jit_function_compile(jit_function_t func) JIT_NOTHROW; 57 | int jit_function_is_compiled(jit_function_t func) JIT_NOTHROW; 58 | void jit_function_set_recompilable(jit_function_t func) JIT_NOTHROW; 59 | void jit_function_clear_recompilable(jit_function_t func) JIT_NOTHROW; 60 | int jit_function_is_recompilable(jit_function_t func) JIT_NOTHROW; 61 | int jit_function_compile_entry(jit_function_t func, void **entry_point) JIT_NOTHROW; 62 | void jit_function_setup_entry(jit_function_t func, void *entry_point) JIT_NOTHROW; 63 | void *jit_function_to_closure(jit_function_t func) JIT_NOTHROW; 64 | jit_function_t jit_function_from_closure 65 | (jit_context_t context, void *closure) JIT_NOTHROW; 66 | jit_function_t jit_function_from_pc 67 | (jit_context_t context, void *pc, void **handler) JIT_NOTHROW; 68 | void *jit_function_to_vtable_pointer(jit_function_t func) JIT_NOTHROW; 69 | jit_function_t jit_function_from_vtable_pointer 70 | (jit_context_t context, void *vtable_pointer) JIT_NOTHROW; 71 | void jit_function_set_on_demand_compiler 72 | (jit_function_t func, jit_on_demand_func on_demand) JIT_NOTHROW; 73 | jit_on_demand_func jit_function_get_on_demand_compiler(jit_function_t func) JIT_NOTHROW; 74 | int jit_function_apply 75 | (jit_function_t func, void **args, void *return_area); 76 | int jit_function_apply_vararg 77 | (jit_function_t func, jit_type_t signature, void **args, void *return_area); 78 | void jit_function_set_optimization_level 79 | (jit_function_t func, unsigned int level) JIT_NOTHROW; 80 | unsigned int jit_function_get_optimization_level 81 | (jit_function_t func) JIT_NOTHROW; 82 | unsigned int jit_function_get_max_optimization_level(void) JIT_NOTHROW; 83 | jit_label_t jit_function_reserve_label(jit_function_t func) JIT_NOTHROW; 84 | int jit_function_labels_equal(jit_function_t func, jit_label_t label, jit_label_t label2); 85 | int jit_optimize(jit_function_t func); 86 | int jit_compile(jit_function_t func); 87 | int jit_compile_entry(jit_function_t func, void **entry_point); 88 | 89 | #ifdef __cplusplus 90 | }; 91 | #endif 92 | 93 | #endif /* _JIT_FUNCTION_H */ 94 | -------------------------------------------------------------------------------- /internal/ccall/include/jit/jit-init.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-init.h - Initialization routines for the JIT. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * The libjit library is free software: you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public License 8 | * as published by the Free Software Foundation, either version 2.1 of 9 | * the License, or (at your option) any later version. 10 | * 11 | * The libjit library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with the libjit library. If not, see 18 | * . 19 | */ 20 | 21 | #ifndef _JIT_INIT_H 22 | #define _JIT_INIT_H 23 | 24 | #include 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | void jit_init(void) JIT_NOTHROW; 31 | 32 | int jit_uses_interpreter(void) JIT_NOTHROW; 33 | 34 | int jit_supports_threads(void) JIT_NOTHROW; 35 | 36 | int jit_supports_virtual_memory(void) JIT_NOTHROW; 37 | 38 | int jit_supports_closures(void); 39 | 40 | unsigned int jit_get_closure_size(void); 41 | unsigned int jit_get_closure_alignment(void); 42 | unsigned int jit_get_trampoline_size(void); 43 | unsigned int jit_get_trampoline_alignment(void); 44 | 45 | #ifdef __cplusplus 46 | }; 47 | #endif 48 | 49 | #endif /* _JIT_INIT_H */ 50 | -------------------------------------------------------------------------------- /internal/ccall/include/jit/jit-memory.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-memory.h - Memory management. 3 | * 4 | * Copyright (C) 2012 Aleksey Demakov 5 | * 6 | * The libjit library is free software: you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public License 8 | * as published by the Free Software Foundation, either version 2.1 of 9 | * the License, or (at your option) any later version. 10 | * 11 | * The libjit library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with the libjit library. If not, see 18 | * . 19 | */ 20 | 21 | #ifndef _JIT_MEMORY_H 22 | #define _JIT_MEMORY_H 23 | 24 | #include 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | /* 31 | * Result values for "_jit_cache_start_function" and "_jit_cache_end_function". 32 | */ 33 | #define JIT_MEMORY_OK 0 /* Function is OK */ 34 | #define JIT_MEMORY_RESTART 1 /* Restart is required */ 35 | #define JIT_MEMORY_TOO_BIG 2 /* Function is too big for the cache */ 36 | #define JIT_MEMORY_ERROR 3 /* Other error */ 37 | 38 | typedef void *jit_memory_context_t; 39 | typedef void *jit_function_info_t; 40 | 41 | typedef struct jit_memory_manager const* jit_memory_manager_t; 42 | 43 | struct jit_memory_manager 44 | { 45 | jit_memory_context_t (*create)(jit_context_t context); 46 | void (*destroy)(jit_memory_context_t memctx); 47 | 48 | jit_function_info_t (*find_function_info)(jit_memory_context_t memctx, void *pc); 49 | jit_function_t (*get_function)(jit_memory_context_t memctx, jit_function_info_t info); 50 | void * (*get_function_start)(jit_memory_context_t memctx, jit_function_info_t info); 51 | void * (*get_function_end)(jit_memory_context_t memctx, jit_function_info_t info); 52 | 53 | jit_function_t (*alloc_function)(jit_memory_context_t memctx); 54 | void (*free_function)(jit_memory_context_t memctx, jit_function_t func); 55 | 56 | int (*start_function)(jit_memory_context_t memctx, jit_function_t func); 57 | int (*end_function)(jit_memory_context_t memctx, int result); 58 | int (*extend_limit)(jit_memory_context_t memctx, int count); 59 | 60 | void * (*get_limit)(jit_memory_context_t memctx); 61 | void * (*get_break)(jit_memory_context_t memctx); 62 | void (*set_break)(jit_memory_context_t memctx, void *brk); 63 | 64 | void * (*alloc_trampoline)(jit_memory_context_t memctx); 65 | void (*free_trampoline)(jit_memory_context_t memctx, void *ptr); 66 | 67 | void * (*alloc_closure)(jit_memory_context_t memctx); 68 | void (*free_closure)(jit_memory_context_t memctx, void *ptr); 69 | 70 | void * (*alloc_data)(jit_memory_context_t memctx, jit_size_t size, jit_size_t align); 71 | }; 72 | 73 | jit_memory_manager_t jit_default_memory_manager(void) JIT_NOTHROW; 74 | 75 | #ifdef __cplusplus 76 | } 77 | #endif 78 | 79 | #endif /* _JIT_MEMORY_H */ 80 | -------------------------------------------------------------------------------- /internal/ccall/include/jit/jit-meta.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-meta.h - Manipulate lists of metadata values. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * The libjit library is free software: you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public License 8 | * as published by the Free Software Foundation, either version 2.1 of 9 | * the License, or (at your option) any later version. 10 | * 11 | * The libjit library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with the libjit library. If not, see 18 | * . 19 | */ 20 | 21 | #ifndef _JIT_META_H 22 | #define _JIT_META_H 23 | 24 | #include 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | typedef struct _jit_meta *jit_meta_t; 31 | 32 | int jit_meta_set 33 | (jit_meta_t *list, int type, void *data, 34 | jit_meta_free_func free_data, jit_function_t pool_owner) JIT_NOTHROW; 35 | void *jit_meta_get(jit_meta_t list, int type) JIT_NOTHROW; 36 | void jit_meta_free(jit_meta_t *list, int type) JIT_NOTHROW; 37 | void jit_meta_destroy(jit_meta_t *list) JIT_NOTHROW; 38 | 39 | #ifdef __cplusplus 40 | }; 41 | #endif 42 | 43 | #endif /* _JIT_META_H */ 44 | -------------------------------------------------------------------------------- /internal/ccall/include/jit/jit-objmodel-private.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-objmodel-private.h - Private object model definitions. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * The libjit library is free software: you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public License 8 | * as published by the Free Software Foundation, either version 2.1 of 9 | * the License, or (at your option) any later version. 10 | * 11 | * The libjit library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with the libjit library. If not, see 18 | * . 19 | */ 20 | 21 | #ifndef _JIT_OBJMODEL_PRIVATE_H 22 | #define _JIT_OBJMODEL_PRIVATE_H 23 | 24 | #include 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | /* 31 | * Internal structure of an object model handler. 32 | */ 33 | struct jit_objmodel 34 | { 35 | /* 36 | * Size of this structure, for versioning. 37 | */ 38 | unsigned int size; 39 | 40 | /* 41 | * Reserved fields that can be used by the handler to store its state. 42 | */ 43 | void *reserved0; 44 | void *reserved1; 45 | void *reserved2; 46 | void *reserved3; 47 | 48 | /* 49 | * Operations on object models. 50 | */ 51 | void (*destroy_model)(jit_objmodel_t model); 52 | jitom_class_t (*get_class_by_name)(jit_objmodel_t model, const char *name); 53 | 54 | /* 55 | * Operations on object model classes. 56 | */ 57 | char *(*class_get_name)(jit_objmodel_t model, jitom_class_t klass); 58 | int (*class_get_modifiers)(jit_objmodel_t model, jitom_class_t klass); 59 | jit_type_t (*class_get_type)(jit_objmodel_t model, jitom_class_t klass); 60 | jit_type_t (*class_get_value_type) 61 | (jit_objmodel_t model, jitom_class_t klass); 62 | jitom_class_t (*class_get_primary_super) 63 | (jit_objmodel_t model, jitom_class_t klass); 64 | jitom_class_t *(*class_get_all_supers) 65 | (jit_objmodel_t model, jitom_class_t klass, unsigned int *num); 66 | jitom_class_t *(*class_get_interfaces) 67 | (jit_objmodel_t model, jitom_class_t klass, unsigned int *num); 68 | jitom_field_t *(*class_get_fields) 69 | (jit_objmodel_t model, jitom_class_t klass, unsigned int *num); 70 | jitom_method_t *(*class_get_methods) 71 | (jit_objmodel_t model, jitom_class_t klass, unsigned int *num); 72 | jit_value_t (*class_new) 73 | (jit_objmodel_t model, jitom_class_t klass, 74 | jitom_method_t ctor, jit_function_t func, 75 | jit_value_t *args, unsigned int num_args, int flags); 76 | jit_value_t (*class_new_value) 77 | (jit_objmodel_t model, jitom_class_t klass, 78 | jitom_method_t ctor, jit_function_t func, 79 | jit_value_t *args, unsigned int num_args, int flags); 80 | int (*class_delete) 81 | (jit_objmodel_t model, jitom_class_t klass, jit_value_t obj_value); 82 | int (*class_add_ref) 83 | (jit_objmodel_t model, jitom_class_t klass, jit_value_t obj_value); 84 | 85 | /* 86 | * Operations on object model fields. 87 | */ 88 | char *(*field_get_name) 89 | (jit_objmodel_t model, jitom_class_t klass, jitom_field_t field); 90 | jit_type_t (*field_get_type) 91 | (jit_objmodel_t model, jitom_class_t klass, jitom_field_t field); 92 | int (*field_get_modifiers) 93 | (jit_objmodel_t model, jitom_class_t klass, jitom_field_t field); 94 | jit_value_t (*field_load) 95 | (jit_objmodel_t model, jitom_class_t klass, jitom_field_t field, 96 | jit_function_t func, jit_value_t obj_value); 97 | jit_value_t (*field_load_address) 98 | (jit_objmodel_t model, jitom_class_t klass, jitom_field_t field, 99 | jit_function_t func, jit_value_t obj_value); 100 | int (*field_store) 101 | (jit_objmodel_t model, jitom_class_t klass, jitom_field_t field, 102 | jit_function_t func, jit_value_t obj_value, jit_value_t value); 103 | 104 | /* 105 | * Operations on object model methods. 106 | */ 107 | char *(*method_get_name) 108 | (jit_objmodel_t model, jitom_class_t klass, jitom_method_t method); 109 | jit_type_t (*method_get_type) 110 | (jit_objmodel_t model, jitom_class_t klass, jitom_method_t method); 111 | int (*method_get_modifiers) 112 | (jit_objmodel_t model, jitom_class_t klass, jitom_method_t method); 113 | jit_value_t (*method_invoke) 114 | (jit_objmodel_t model, jitom_class_t klass, jitom_method_t method, 115 | jit_function_t func, jit_value_t *args, 116 | unsigned int num_args, int flags); 117 | jit_value_t (*method_invoke_virtual) 118 | (jit_objmodel_t model, jitom_class_t klass, jitom_method_t method, 119 | jit_function_t func, jit_value_t *args, 120 | unsigned int num_args, int flags); 121 | 122 | }; 123 | 124 | #ifdef __cplusplus 125 | }; 126 | #endif 127 | 128 | #endif /* _JIT_OBJMODEL_PRIVATE_H */ 129 | -------------------------------------------------------------------------------- /internal/ccall/include/jit/jit-opcode-compat.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-opcode-compat.h - Definition of obsolete opcodes for compatibility 3 | * reasons. 4 | * 5 | * Copyright (C) 2011 Southern Storm Software, Pty Ltd. 6 | * 7 | * The libjit library is free software: you can redistribute it and/or 8 | * modify it under the terms of the GNU Lesser General Public License 9 | * as published by the Free Software Foundation, either version 2.1 of 10 | * the License, or (at your option) any later version. 11 | * 12 | * The libjit library is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | * Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public 18 | * License along with the libjit library. If not, see 19 | * . 20 | */ 21 | 22 | #ifndef _JIT_OPCODE_COMPAT_H 23 | #define _JIT_OPCODE_COMPAT_H 24 | 25 | #ifdef __cplusplus 26 | extern "C" { 27 | #endif 28 | 29 | /* 30 | * Some obsolete opcodes that have been removed because they are duplicates 31 | * of other opcodes. 32 | */ 33 | #define JIT_OP_FEQ_INV JIT_OP_FEQ 34 | #define JIT_OP_FNE_INV JIT_OP_FNE 35 | #define JIT_OP_DEQ_INV JIT_OP_DEQ 36 | #define JIT_OP_DNE_INV JIT_OP_DNE 37 | #define JIT_OP_NFEQ_INV JIT_OP_NFEQ 38 | #define JIT_OP_NFNE_INV JIT_OP_NFNE 39 | #define JIT_OP_BR_FEQ_INV JIT_OP_BR_FEQ 40 | #define JIT_OP_BR_FNE_INV JIT_OP_BR_FNE 41 | #define JIT_OP_BR_DEQ_INV JIT_OP_BR_DEQ 42 | #define JIT_OP_BR_DNE_INV JIT_OP_BR_DNE 43 | #define JIT_OP_BR_NFEQ_INV JIT_OP_BR_NFEQ 44 | #define JIT_OP_BR_NFNE_INV JIT_OP_BR_NFNE 45 | 46 | #ifdef __cplusplus 47 | } 48 | #endif 49 | 50 | #endif /* _JIT_VMEM_H */ 51 | -------------------------------------------------------------------------------- /internal/ccall/include/jit/jit-unwind.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-unwind.h - Routines for performing stack unwinding. 3 | * 4 | * Copyright (C) 2008 Southern Storm Software, Pty Ltd. 5 | * 6 | * This file is part of the libjit library. 7 | * 8 | * The libjit library is free software: you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public License 10 | * as published by the Free Software Foundation, either version 2.1 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * The libjit library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with the libjit library. If not, see 20 | * . 21 | */ 22 | 23 | #ifndef _JIT_UNWIND_H 24 | #define _JIT_UNWIND_H 25 | 26 | #include 27 | #include 28 | 29 | #ifdef __cplusplus 30 | extern "C" { 31 | #endif 32 | 33 | typedef struct 34 | { 35 | void *frame; 36 | void *cache; 37 | jit_context_t context; 38 | #ifdef _JIT_ARCH_UNWIND_DATA 39 | _JIT_ARCH_UNWIND_DATA 40 | #endif 41 | } jit_unwind_context_t; 42 | 43 | int jit_unwind_init(jit_unwind_context_t *unwind, jit_context_t context); 44 | void jit_unwind_free(jit_unwind_context_t *unwind); 45 | 46 | int jit_unwind_next(jit_unwind_context_t *unwind); 47 | int jit_unwind_next_pc(jit_unwind_context_t *unwind); 48 | void *jit_unwind_get_pc(jit_unwind_context_t *unwind); 49 | 50 | int jit_unwind_jump(jit_unwind_context_t *unwind, void *pc); 51 | 52 | jit_function_t jit_unwind_get_function(jit_unwind_context_t *unwind); 53 | unsigned int jit_unwind_get_offset(jit_unwind_context_t *unwind); 54 | 55 | #ifdef __cplusplus 56 | }; 57 | #endif 58 | 59 | #endif /* _JIT_UNWIND_H */ 60 | -------------------------------------------------------------------------------- /internal/ccall/include/jit/jit-util.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-util.h - Utility functions. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * The libjit library is free software: you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public License 8 | * as published by the Free Software Foundation, either version 2.1 of 9 | * the License, or (at your option) any later version. 10 | * 11 | * The libjit library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with the libjit library. If not, see 18 | * . 19 | */ 20 | 21 | #ifndef _JIT_UTIL_H 22 | #define _JIT_UTIL_H 23 | 24 | #include 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | /* 31 | * Memory allocation routines. 32 | */ 33 | void *jit_malloc(unsigned int size) JIT_NOTHROW; 34 | void *jit_calloc(unsigned int num, unsigned int size) JIT_NOTHROW; 35 | void *jit_realloc(void *ptr, unsigned int size) JIT_NOTHROW; 36 | void jit_free(void *ptr) JIT_NOTHROW; 37 | 38 | #define jit_new(type) ((type *)jit_malloc(sizeof(type))) 39 | #define jit_cnew(type) ((type *)jit_calloc(1, sizeof(type))) 40 | 41 | /* 42 | * Memory set/copy/compare routines. 43 | */ 44 | void *jit_memset(void *dest, int ch, unsigned int len) JIT_NOTHROW; 45 | void *jit_memcpy(void *dest, const void *src, unsigned int len) JIT_NOTHROW; 46 | void *jit_memmove(void *dest, const void *src, unsigned int len) JIT_NOTHROW; 47 | int jit_memcmp(const void *s1, const void *s2, unsigned int len) JIT_NOTHROW; 48 | void *jit_memchr(const void *str, int ch, unsigned int len) JIT_NOTHROW; 49 | 50 | /* 51 | * String routines. 52 | */ 53 | unsigned int jit_strlen(const char *str) JIT_NOTHROW; 54 | char *jit_strcpy(char *dest, const char *src) JIT_NOTHROW; 55 | char *jit_strcat(char *dest, const char *src) JIT_NOTHROW; 56 | char *jit_strncpy(char *dest, const char *src, unsigned int len) JIT_NOTHROW; 57 | char *jit_strdup(const char *str) JIT_NOTHROW; 58 | char *jit_strndup(const char *str, unsigned int len) JIT_NOTHROW; 59 | int jit_strcmp(const char *str1, const char *str2) JIT_NOTHROW; 60 | int jit_strncmp 61 | (const char *str1, const char *str2, unsigned int len) JIT_NOTHROW; 62 | int jit_stricmp(const char *str1, const char *str2) JIT_NOTHROW; 63 | int jit_strnicmp 64 | (const char *str1, const char *str2, unsigned int len) JIT_NOTHROW; 65 | char *jit_strchr(const char *str, int ch) JIT_NOTHROW; 66 | char *jit_strrchr(const char *str, int ch) JIT_NOTHROW; 67 | int jit_sprintf(char *str, const char *format, ...) JIT_NOTHROW; 68 | int jit_snprintf 69 | (char *str, unsigned int len, const char *format, ...) JIT_NOTHROW; 70 | 71 | #ifdef __cplusplus 72 | }; 73 | #endif 74 | 75 | #endif /* _JIT_UTIL_H */ 76 | -------------------------------------------------------------------------------- /internal/ccall/include/jit/jit-value.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-value.h - Functions for manipulating temporary values. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * The libjit library is free software: you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public License 8 | * as published by the Free Software Foundation, either version 2.1 of 9 | * the License, or (at your option) any later version. 10 | * 11 | * The libjit library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with the libjit library. If not, see 18 | * . 19 | */ 20 | 21 | #ifndef _JIT_VALUE_H 22 | #define _JIT_VALUE_H 23 | 24 | #include 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | /* 31 | * Full struction that can hold a constant of any type. 32 | */ 33 | typedef struct 34 | { 35 | jit_type_t type; 36 | union 37 | { 38 | void *ptr_value; 39 | jit_int int_value; 40 | jit_uint uint_value; 41 | jit_nint nint_value; 42 | jit_nuint nuint_value; 43 | jit_long long_value; 44 | jit_ulong ulong_value; 45 | jit_float32 float32_value; 46 | jit_float64 float64_value; 47 | jit_nfloat nfloat_value; 48 | 49 | } un; 50 | 51 | } jit_constant_t; 52 | 53 | /* 54 | * External function declarations. 55 | */ 56 | jit_value_t jit_value_create(jit_function_t func, jit_type_t type) JIT_NOTHROW; 57 | jit_value_t jit_value_create_nint_constant 58 | (jit_function_t func, jit_type_t type, jit_nint const_value) JIT_NOTHROW; 59 | jit_value_t jit_value_create_long_constant 60 | (jit_function_t func, jit_type_t type, jit_long const_value) JIT_NOTHROW; 61 | jit_value_t jit_value_create_float32_constant 62 | (jit_function_t func, jit_type_t type, 63 | jit_float32 const_value) JIT_NOTHROW; 64 | jit_value_t jit_value_create_float64_constant 65 | (jit_function_t func, jit_type_t type, 66 | jit_float64 const_value) JIT_NOTHROW; 67 | jit_value_t jit_value_create_nfloat_constant 68 | (jit_function_t func, jit_type_t type, 69 | jit_nfloat const_value) JIT_NOTHROW; 70 | jit_value_t jit_value_create_constant 71 | (jit_function_t func, const jit_constant_t *const_value) JIT_NOTHROW; 72 | jit_value_t jit_value_get_param 73 | (jit_function_t func, unsigned int param) JIT_NOTHROW; 74 | jit_value_t jit_value_get_struct_pointer(jit_function_t func) JIT_NOTHROW; 75 | int jit_value_is_temporary(jit_value_t value) JIT_NOTHROW; 76 | int jit_value_is_local(jit_value_t value) JIT_NOTHROW; 77 | int jit_value_is_constant(jit_value_t value) JIT_NOTHROW; 78 | int jit_value_is_parameter(jit_value_t value) JIT_NOTHROW; 79 | void jit_value_ref(jit_function_t func, jit_value_t value) JIT_NOTHROW; 80 | void jit_value_set_volatile(jit_value_t value) JIT_NOTHROW; 81 | int jit_value_is_volatile(jit_value_t value) JIT_NOTHROW; 82 | void jit_value_set_addressable(jit_value_t value) JIT_NOTHROW; 83 | int jit_value_is_addressable(jit_value_t value) JIT_NOTHROW; 84 | jit_type_t jit_value_get_type(jit_value_t value) JIT_NOTHROW; 85 | jit_function_t jit_value_get_function(jit_value_t value) JIT_NOTHROW; 86 | jit_block_t jit_value_get_block(jit_value_t value) JIT_NOTHROW; 87 | jit_context_t jit_value_get_context(jit_value_t value) JIT_NOTHROW; 88 | jit_constant_t jit_value_get_constant(jit_value_t value) JIT_NOTHROW; 89 | jit_nint jit_value_get_nint_constant(jit_value_t value) JIT_NOTHROW; 90 | jit_long jit_value_get_long_constant(jit_value_t value) JIT_NOTHROW; 91 | jit_float32 jit_value_get_float32_constant(jit_value_t value) JIT_NOTHROW; 92 | jit_float64 jit_value_get_float64_constant(jit_value_t value) JIT_NOTHROW; 93 | jit_nfloat jit_value_get_nfloat_constant(jit_value_t value) JIT_NOTHROW; 94 | int jit_value_is_true(jit_value_t value) JIT_NOTHROW; 95 | int jit_constant_convert 96 | (jit_constant_t *result, const jit_constant_t *value, 97 | jit_type_t type, int overflow_check) JIT_NOTHROW; 98 | 99 | #ifdef __cplusplus 100 | }; 101 | #endif 102 | 103 | #endif /* _JIT_VALUE_H */ 104 | -------------------------------------------------------------------------------- /internal/ccall/include/jit/jit-vmem.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-vmem.h - Virtual memory routines. 3 | * 4 | * Copyright (C) 2011 Aleksey Demakov 5 | * 6 | * The libjit library is free software: you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public License 8 | * as published by the Free Software Foundation, either version 2.1 of 9 | * the License, or (at your option) any later version. 10 | * 11 | * The libjit library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with the libjit library. If not, see 18 | * . 19 | */ 20 | 21 | #ifndef _JIT_VMEM_H 22 | #define _JIT_VMEM_H 23 | 24 | #include 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | typedef enum { 31 | JIT_PROT_NONE, 32 | JIT_PROT_READ, 33 | JIT_PROT_READ_WRITE, 34 | JIT_PROT_EXEC_READ, 35 | JIT_PROT_EXEC_READ_WRITE, 36 | } jit_prot_t; 37 | 38 | 39 | void jit_vmem_init(void); 40 | 41 | jit_uint jit_vmem_page_size(void); 42 | jit_nuint jit_vmem_round_up(jit_nuint value); 43 | jit_nuint jit_vmem_round_down(jit_nuint value); 44 | 45 | void *jit_vmem_reserve(jit_uint size); 46 | void *jit_vmem_reserve_committed(jit_uint size, jit_prot_t prot); 47 | int jit_vmem_release(void *addr, jit_uint size); 48 | 49 | int jit_vmem_commit(void *addr, jit_uint size, jit_prot_t prot); 50 | int jit_vmem_decommit(void *addr, jit_uint size); 51 | 52 | int jit_vmem_protect(void *addr, jit_uint size, jit_prot_t prot); 53 | 54 | #ifdef __cplusplus 55 | } 56 | #endif 57 | 58 | #endif /* _JIT_VMEM_H */ 59 | -------------------------------------------------------------------------------- /internal/ccall/include/jit/jit-walk.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-walk.h - Functions for walking stack frames. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * The libjit library is free software: you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public License 8 | * as published by the Free Software Foundation, either version 2.1 of 9 | * the License, or (at your option) any later version. 10 | * 11 | * The libjit library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with the libjit library. If not, see 18 | * . 19 | */ 20 | 21 | #ifndef _JIT_WALK_H 22 | #define _JIT_WALK_H 23 | 24 | #include 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | /* 31 | * Get the frame address for a frame which is "n" levels up the stack. 32 | * A level value of zero indicates the current frame. 33 | */ 34 | void *_jit_get_frame_address(void *start, unsigned int n); 35 | #if defined(__GNUC__) 36 | # define jit_get_frame_address(n) \ 37 | (_jit_get_frame_address(jit_get_current_frame(), (n))) 38 | #else 39 | # define jit_get_frame_address(n) (_jit_get_frame_address(0, (n))) 40 | #endif 41 | 42 | /* 43 | * Get the frame address for the current frame. May be more efficient 44 | * than using "jit_get_frame_address(0)". 45 | * 46 | * Note: some gcc vestions have broken __builtin_frame_address() so use 47 | * _JIT_ARCH_GET_CURRENT_FRAME() if available. 48 | */ 49 | #if defined(__GNUC__) 50 | # define JIT_FAST_GET_CURRENT_FRAME 1 51 | # if defined(_JIT_ARCH_GET_CURRENT_FRAME) 52 | # define jit_get_current_frame() \ 53 | ({ \ 54 | void *address; \ 55 | _JIT_ARCH_GET_CURRENT_FRAME(address); \ 56 | address; \ 57 | }) 58 | # else 59 | # define jit_get_current_frame() (__builtin_frame_address(0)) 60 | # endif 61 | #else 62 | # define JIT_FAST_GET_CURRENT_FRAME 0 63 | # define jit_get_current_frame() (jit_get_frame_address(0)) 64 | #endif 65 | 66 | /* 67 | * Get the next frame up the stack from a specified frame. 68 | * Returns NULL if it isn't possible to retrieve the next frame. 69 | */ 70 | void *_jit_get_next_frame_address(void *frame); 71 | #if defined(__GNUC__) && defined(_JIT_ARCH_GET_NEXT_FRAME) 72 | # define jit_get_next_frame_address(frame) \ 73 | ({ \ 74 | void *address; \ 75 | _JIT_ARCH_GET_NEXT_FRAME(address, (frame)); \ 76 | address; \ 77 | }) 78 | #else 79 | # define jit_get_next_frame_address(frame) \ 80 | (_jit_get_next_frame_address(frame)) 81 | #endif 82 | 83 | /* 84 | * Get the return address for a specific frame. 85 | */ 86 | void *_jit_get_return_address(void *frame, void *frame0, void *return0); 87 | #if defined(__GNUC__) 88 | # if defined(_JIT_ARCH_GET_RETURN_ADDRESS) 89 | # define jit_get_return_address(frame) \ 90 | ({ \ 91 | void *address; \ 92 | _JIT_ARCH_GET_RETURN_ADDRESS(address, (frame)); \ 93 | address; \ 94 | }) 95 | # else 96 | # define jit_get_return_address(frame) \ 97 | (_jit_get_return_address \ 98 | ((frame), \ 99 | __builtin_frame_address(0), \ 100 | __builtin_return_address(0))) 101 | # endif 102 | #else 103 | # define jit_get_return_address(frame) \ 104 | (_jit_get_return_address((frame), 0, 0)) 105 | #endif 106 | 107 | /* 108 | * Get the return address for the current frame. May be more efficient 109 | * than using "jit_get_return_address(0)". 110 | */ 111 | #if defined(__GNUC__) 112 | # if defined(_JIT_ARCH_GET_CURRENT_RETURN) 113 | # define jit_get_current_return() \ 114 | ({ \ 115 | void *address; \ 116 | _JIT_ARCH_GET_CURRENT_RETURN(address); \ 117 | address; \ 118 | }) 119 | # else 120 | # define jit_get_current_return() (__builtin_return_address(0)) 121 | # endif 122 | #else 123 | # define jit_get_current_return() \ 124 | (jit_get_return_address(jit_get_current_frame())) 125 | #endif 126 | 127 | /* 128 | * Declare a stack crawl mark variable. The address of this variable 129 | * can be passed to "jit_frame_contains_crawl_mark" to determine 130 | * if a frame contains the mark. 131 | */ 132 | typedef struct { void * volatile mark; } jit_crawl_mark_t; 133 | #define jit_declare_crawl_mark(name) jit_crawl_mark_t name = {0} 134 | 135 | /* 136 | * Determine if the stack frame just above "frame" contains a 137 | * particular crawl mark. 138 | */ 139 | int jit_frame_contains_crawl_mark(void *frame, jit_crawl_mark_t *mark); 140 | 141 | #ifdef __cplusplus 142 | }; 143 | #endif 144 | 145 | #endif /* _JIT_WALK_H */ 146 | -------------------------------------------------------------------------------- /internal/ccall/include/jit/jit.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit.h - General definitions for JIT back-ends. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * The libjit library is free software: you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public License 8 | * as published by the Free Software Foundation, either version 2.1 of 9 | * the License, or (at your option) any later version. 10 | * 11 | * The libjit library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with the libjit library. If not, see 18 | * . 19 | */ 20 | 21 | #ifndef _JIT_H 22 | #define _JIT_H 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include 49 | #include 50 | #include 51 | 52 | #ifdef __cplusplus 53 | }; 54 | #endif 55 | 56 | #endif /* _JIT_H */ 57 | -------------------------------------------------------------------------------- /internal/ccall/insn.go: -------------------------------------------------------------------------------- 1 | package ccall 2 | 3 | /* 4 | #cgo CFLAGS: -I../ 5 | #cgo CFLAGS: -Iinclude 6 | 7 | #include 8 | */ 9 | import "C" 10 | import "unsafe" 11 | 12 | type Instruction struct { 13 | c C.jit_insn_t 14 | } 15 | 16 | func toInstruction(c C.jit_insn_t) *Instruction { 17 | return &Instruction{c} 18 | } 19 | 20 | func (i *Instruction) Code() int { 21 | return int(C.jit_insn_get_opcode(i.c)) 22 | } 23 | 24 | func (i *Instruction) Dest() *Value { 25 | return toValue(C.jit_insn_get_dest(i.c)) 26 | } 27 | 28 | func (i *Instruction) Value1() *Value { 29 | return toValue(C.jit_insn_get_value1(i.c)) 30 | } 31 | 32 | func (i *Instruction) Value2() *Value { 33 | return toValue(C.jit_insn_get_value2(i.c)) 34 | } 35 | 36 | func (i *Instruction) Label() *Label { 37 | return toLabel(C.jit_insn_get_label(i.c)) 38 | } 39 | 40 | func (i *Instruction) Function() *Function { 41 | return toFunction(C.jit_insn_get_function(i.c)) 42 | } 43 | 44 | func (i *Instruction) Native() unsafe.Pointer { 45 | return C.jit_insn_get_native(i.c) 46 | } 47 | 48 | func (i *Instruction) Name() string { 49 | return C.GoString(C.jit_insn_get_name(i.c)) 50 | } 51 | 52 | func (i *Instruction) Signature() *Type { 53 | return toType(C.jit_insn_get_signature(i.c)) 54 | } 55 | 56 | func (i *Instruction) DestIsValue() bool { 57 | return int(C.jit_insn_dest_is_value(i.c)) == 1 58 | } 59 | -------------------------------------------------------------------------------- /internal/ccall/jit-alloc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-alloc.c - Memory allocation routines. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * This file is part of the libjit library. 7 | * 8 | * The libjit library is free software: you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public License 10 | * as published by the Free Software Foundation, either version 2.1 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * The libjit library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with the libjit library. If not, see 20 | * . 21 | */ 22 | 23 | #include "jit-config.h" 24 | 25 | #ifdef HAVE_STDLIB_H 26 | #include 27 | #endif 28 | #ifndef JIT_WIN32_PLATFORM 29 | #ifdef HAVE_SYS_TYPES_H 30 | #include 31 | #endif 32 | #ifdef HAVE_UNISTD_H 33 | #include 34 | #endif 35 | #ifdef HAVE_SYS_MMAN_H 36 | #include 37 | #endif 38 | #ifdef HAVE_FCNTL_H 39 | #include 40 | #endif 41 | #else /* JIT_WIN32_PLATFORM */ 42 | #include 43 | #include 44 | #endif 45 | #if defined(HAVE_SYS_MMAN_H) && defined(HAVE_MMAP) && defined(HAVE_MUNMAP) 46 | /* 47 | * Make sure that "MAP_ANONYMOUS" is correctly defined, because it 48 | * may not exist on some variants of Unix. 49 | */ 50 | #ifndef MAP_ANONYMOUS 51 | #ifdef MAP_ANON 52 | #define MAP_ANONYMOUS MAP_ANON 53 | #endif 54 | #endif 55 | #ifdef MAP_ANONYMOUS 56 | #define JIT_USE_MMAP 57 | #endif 58 | #endif 59 | 60 | /*@ 61 | * @deftypefun {void *} _jit_malloc_exec (unsigned int @var{size}) 62 | * Allocate a block of memory that is read/write/executable. Such blocks 63 | * are used to store JIT'ed code, function closures, and other trampolines. 64 | * The size should be a multiple of @code{jit_vmem_page_size()}. 65 | * 66 | * This will usually be identical to @code{jit_malloc}. However, 67 | * some systems may need special handling to create executable code 68 | * segments, so this function must be used instead. 69 | * 70 | * You must never mix regular and executable segment allocation. That is, 71 | * do not use @code{jit_free} to free the result of @code{_jit_malloc_exec}. 72 | * @end deftypefun 73 | @*/ 74 | void * 75 | _jit_malloc_exec(unsigned int size) 76 | { 77 | #if defined(JIT_WIN32_PLATFORM) 78 | return VirtualAlloc(NULL, size, 79 | MEM_COMMIT | MEM_RESERVE, 80 | PAGE_EXECUTE_READWRITE); 81 | #elif defined(JIT_USE_MMAP) 82 | void *ptr = mmap(0, size, 83 | PROT_READ | PROT_WRITE | PROT_EXEC, 84 | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 85 | if(ptr == (void *)-1) 86 | { 87 | return (void *)0; 88 | } 89 | return ptr; 90 | #else 91 | return malloc(size); 92 | #endif 93 | } 94 | 95 | /*@ 96 | * @deftypefun void _jit_free_exec (void *@var{ptr}, unsigned int @var{size}) 97 | * Free a block of memory that was previously allocated by 98 | * @code{_jit_malloc_exec}. The @var{size} must be identical to the 99 | * original allocated size, as some systems need to know this information 100 | * to be able to free the block. 101 | * @end deftypefun 102 | @*/ 103 | void 104 | _jit_free_exec(void *ptr, unsigned int size) 105 | { 106 | if(ptr) 107 | { 108 | #if defined(JIT_WIN32_PLATFORM) 109 | VirtualFree(ptr, 0, MEM_RELEASE); 110 | #elif defined(JIT_USE_MMAP) 111 | munmap(ptr, size); 112 | #else 113 | free(ptr); 114 | #endif 115 | } 116 | } 117 | 118 | /*@ 119 | * @deftypefun void _jit_flush_exec (void *@var{ptr}, unsigned int @var{size}) 120 | * Flush the contents of the block at @var{ptr} from the CPU's 121 | * data and instruction caches. This must be used after the code is 122 | * written to an executable code segment, but before the code is 123 | * executed, to prepare it for execution. 124 | * @end deftypefun 125 | @*/ 126 | void 127 | _jit_flush_exec(void *ptr, unsigned int size) 128 | { 129 | 130 | #define ROUND_BEG_PTR(p) \ 131 | ((void *)((((jit_nuint)(p)) / CLSIZE) * CLSIZE)) 132 | #define ROUND_END_PTR(p,s) \ 133 | ((void *)(((((jit_nuint)(p)) + (s) + CLSIZE - 1)/CLSIZE)*CLSIZE)) 134 | 135 | #if defined(__GNUC__) 136 | #if defined(PPC) 137 | 138 | #define CLSIZE 4 139 | /* Flush the CPU cache on PPC platforms */ 140 | register unsigned char *p; 141 | register unsigned char *end; 142 | 143 | /* Flush the data out of the data cache */ 144 | p = ROUND_BEG_PTR (ptr); 145 | end = ROUND_END_PTR (p, size); 146 | while (p < end) 147 | { 148 | __asm__ __volatile__ ("dcbst 0,%0" :: "r"(p)); 149 | p += CLSIZE; 150 | } 151 | __asm__ __volatile__ ("sync"); 152 | 153 | /* Invalidate the cache lines in the instruction cache */ 154 | p = ROUND_BEG_PTR (ptr); 155 | while (p < end) 156 | { 157 | __asm__ __volatile__ ("icbi 0,%0; isync" :: "r"(p)); 158 | p += CLSIZE; 159 | } 160 | __asm__ __volatile__ ("isync"); 161 | 162 | #elif defined(__sparc) 163 | 164 | #define CLSIZE 4 165 | 166 | /* Flush the CPU cache on sparc platforms */ 167 | register unsigned char *p = ROUND_BEG_PTR (ptr); 168 | register unsigned char *end = ROUND_END_PTR (p, size); 169 | __asm__ __volatile__ ("stbar"); 170 | while (p < end) 171 | { 172 | __asm__ __volatile__ ("flush %0" :: "r"(p)); 173 | p += CLSIZE; 174 | } 175 | __asm__ __volatile__ ("nop; nop; nop; nop; nop"); 176 | 177 | #elif (defined(__arm__) || defined(__arm)) && defined(linux) 178 | 179 | /* ARM Linux has a "cacheflush" system call */ 180 | /* R0 = start of range, R1 = end of range, R3 = flags */ 181 | /* flags = 0 indicates data cache, flags = 1 indicates both caches */ 182 | __asm __volatile ("mov r0, %0\n" 183 | "mov r1, %1\n" 184 | "mov r2, %2\n" 185 | "swi 0x9f0002 @ sys_cacheflush" 186 | : /* no outputs */ 187 | : "r" (ptr), 188 | "r" (((int)ptr) + (int)size), 189 | "r" (0) 190 | : "r0", "r1", "r3" ); 191 | 192 | #elif (defined(__ia64) || defined(__ia64__)) && defined(linux) 193 | #define CLSIZE 32 194 | register unsigned char *p = ROUND_BEG_PTR (ptr); 195 | register unsigned char *end = ROUND_END_PTR (p, size); 196 | while(p < end) 197 | { 198 | asm volatile("fc %0" :: "r"(p)); 199 | p += CLSIZE; 200 | } 201 | asm volatile(";;sync.i;;srlz.i;;"); 202 | #endif 203 | #endif /* __GNUC__ */ 204 | } 205 | -------------------------------------------------------------------------------- /internal/ccall/jit-apply-arm.c: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-apply-arm.c - Apply support routines for ARM. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * This file is part of the libjit library. 7 | * 8 | * The libjit library is free software: you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public License 10 | * as published by the Free Software Foundation, either version 2.1 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * The libjit library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with the libjit library. If not, see 20 | * . 21 | */ 22 | 23 | #include "jit-internal.h" 24 | 25 | #if defined(__arm) || defined(__arm__) 26 | 27 | #include "jit-gen-arm.h" 28 | 29 | void _jit_create_closure(unsigned char *buf, void *func, 30 | void *closure, void *_type) 31 | { 32 | arm_inst_buf inst; 33 | 34 | /* Initialize the instruction buffer */ 35 | arm_inst_buf_init(inst, buf, buf + jit_closure_size); 36 | 37 | /* Set up the local stack frame */ 38 | arm_setup_frame(inst, 0); 39 | arm_alu_reg_imm8(inst, ARM_SUB, ARM_SP, ARM_SP, 24); 40 | 41 | /* Create the apply argument block on the stack */ 42 | arm_store_membase(inst, ARM_R0, ARM_FP, -28); 43 | arm_store_membase(inst, ARM_R1, ARM_FP, -24); 44 | arm_store_membase(inst, ARM_R2, ARM_FP, -20); 45 | arm_store_membase(inst, ARM_R3, ARM_FP, -16); 46 | arm_alu_reg_imm(inst, ARM_ADD, ARM_R3, ARM_FP, 4); 47 | arm_store_membase(inst, ARM_R3, ARM_FP, -36); 48 | arm_store_membase(inst, ARM_R0, ARM_FP, -32); 49 | 50 | /* Set up the arguments for calling "func" */ 51 | arm_mov_reg_imm(inst, ARM_R0, (int)(jit_nint)closure); 52 | arm_mov_reg_reg(inst, ARM_R1, ARM_SP); 53 | 54 | /* Call the closure handling function */ 55 | arm_call(inst, func); 56 | 57 | /* Pop the current stack frame and return */ 58 | arm_pop_frame(inst, 0); 59 | } 60 | 61 | void *_jit_create_redirector(unsigned char *buf, void *func, 62 | void *user_data, int abi) 63 | { 64 | arm_inst_buf inst; 65 | 66 | /* Align "buf" on an appropriate boundary */ 67 | if((((jit_nint)buf) % jit_closure_align) != 0) 68 | { 69 | buf += jit_closure_align - (((jit_nint)buf) % jit_closure_align); 70 | } 71 | 72 | /* Initialize the instruction buffer */ 73 | arm_inst_buf_init(inst, buf, buf + jit_redirector_size); 74 | 75 | /* Set up the local stack frame, and save R0-R3 */ 76 | arm_setup_frame(inst, 0x000F); 77 | 78 | /* Set up the arguments for calling "func" */ 79 | arm_mov_reg_imm(inst, ARM_R0, (int)(jit_nint)user_data); 80 | 81 | /* Call the redirector handling function */ 82 | arm_call(inst, func); 83 | 84 | /* Shift the result into R12, because we are about to restore R0 */ 85 | arm_mov_reg_reg(inst, ARM_R12, ARM_R0); 86 | 87 | /* Pop the current stack frame, but don't change PC yet */ 88 | arm_pop_frame_tail(inst, 0x000F); 89 | 90 | /* Jump to the function that the redirector indicated */ 91 | arm_mov_reg_reg(inst, ARM_PC, ARM_R12); 92 | 93 | /* Flush the cache lines that we just wrote */ 94 | _jit_flush_exec(buf, ((unsigned char *)(inst.current)) - buf); 95 | 96 | /* Return the aligned start of the buffer as the entry point */ 97 | return (void *)buf; 98 | } 99 | 100 | /** 101 | * Creates the indirector, that is the trampoline that permits the Just In Time 102 | * compilation of a method the first time that it is executed and its direct execution 103 | * the following times 104 | */ 105 | void *_jit_create_indirector(unsigned char *buf, void **entry) 106 | { 107 | arm_inst_buf inst; 108 | void *start = (void *)buf; 109 | 110 | /* Initialize the instruction buffer */ 111 | arm_inst_buf_init(inst, buf, buf + jit_indirector_size); 112 | 113 | //Load the content of memory at address "entry", that is, the entry point of the function 114 | arm_mov_reg_imm(inst,ARM_WORK,entry); 115 | arm_mov_reg_membase(inst,ARM_WORK,ARM_WORK,0,4); 116 | 117 | /* Jump to the entry point. */ 118 | arm_mov_reg_reg(inst, ARM_PC, ARM_WORK); 119 | 120 | /* Flush the cache lines that we just wrote */ 121 | _jit_flush_exec(buf, ((unsigned char *)(inst.current)) - buf); 122 | 123 | return start; 124 | } 125 | 126 | void _jit_pad_buffer(unsigned char *buf, int len) 127 | { 128 | arm_inst_buf inst; 129 | 130 | /* Initialize the instruction buffer */ 131 | arm_inst_buf_init(inst, buf, buf + len*4); 132 | while(len > 0) 133 | { 134 | /* Traditional arm NOP */ 135 | arm_nop(inst); 136 | --len; 137 | } 138 | 139 | /* Flush the cache lines that we just wrote */ 140 | _jit_flush_exec(buf, ((unsigned char *)(inst.current)) - buf); 141 | } 142 | 143 | #endif /* arm */ 144 | -------------------------------------------------------------------------------- /internal/ccall/jit-apply-arm.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-apply-arm.h - Special definitions for ARM function application. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * This file is part of the libjit library. 7 | * 8 | * The libjit library is free software: you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public License 10 | * as published by the Free Software Foundation, either version 2.1 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * The libjit library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with the libjit library. If not, see 20 | * . 21 | */ 22 | 23 | #ifndef _JIT_APPLY_ARM_H 24 | #define _JIT_APPLY_ARM_H 25 | 26 | /* 27 | * The maximum number of bytes that are needed to represent a closure, 28 | * and the alignment to use for the closure. 29 | */ 30 | #define jit_closure_size 128 31 | #define jit_closure_align 16 32 | 33 | /* 34 | * The number of bytes that are needed for a redirector stub. 35 | * This includes any extra bytes that are needed for alignment. 36 | */ 37 | #define jit_redirector_size 128 38 | 39 | /* 40 | * The number of bytes that are needed for a indirector stub. 41 | * This includes any extra bytes that are needed for alignment. 42 | */ 43 | #define jit_indirector_size 24 44 | 45 | /* 46 | * We should pad unused code space with NOP's. 47 | */ 48 | #define jit_should_pad 1 49 | 50 | /* 51 | * Defines the alignment for the stack pointer at a public interface. 52 | * As of the "Procedure Call Standard for the ARM Architecture" (AAPCS release 2.07) 53 | * SP mod 8 = 0 54 | * must always be true at every public interface (function calls, etc) 55 | */ 56 | #define JIT_SP_ALIGN_PUBLIC 8 57 | 58 | /* 59 | * Redefine jit_builtin_apply in order to correctly align the stack pointer 60 | * to JIT_SP_ALING_PUBLIC bytes before calling __builtin_apply to execute the 61 | * jit-compiled function 62 | */ 63 | #define jit_builtin_apply(func,args,size,return_float,return_buf) \ 64 | do { \ 65 | register void *sp asm("sp"); \ 66 | sp = (void *) (((unsigned) sp) & ~(JIT_SP_ALIGN_PUBLIC - 1)); \ 67 | (return_buf) = __builtin_apply \ 68 | ((void (*)())(func), (args), (size)); \ 69 | } while (0) 70 | 71 | #endif /* _JIT_APPLY_ARM_H */ 72 | -------------------------------------------------------------------------------- /internal/ccall/jit-apply-func.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-apply-func.h - Definition of "__builtin_apply" and friends. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * This file is part of the libjit library. 7 | * 8 | * The libjit library is free software: you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public License 10 | * as published by the Free Software Foundation, either version 2.1 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * The libjit library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with the libjit library. If not, see 20 | * . 21 | */ 22 | 23 | #ifndef _JIT_APPLY_FUNC_H 24 | #define _JIT_APPLY_FUNC_H 25 | 26 | #if defined(__i386) || defined(__i386__) || defined(_M_IX86) 27 | 28 | #include "jit-apply-x86.h" 29 | 30 | #elif defined(__arm) || defined(__arm__) 31 | 32 | #include "jit-apply-arm.h" 33 | 34 | #elif defined(__alpha) || defined(__alpha__) 35 | 36 | #include "jit-apply-alpha.h" 37 | 38 | #elif defined(__x86_64) || defined(__x86_64__) 39 | 40 | #include "jit-apply-x86-64.h" 41 | 42 | #endif 43 | 44 | #if !defined(jit_builtin_apply) 45 | #define jit_builtin_apply(func,args,size,return_float,return_buf) \ 46 | do { \ 47 | (return_buf) = __builtin_apply \ 48 | ((void (*)())(func), (args), (size)); \ 49 | } while (0) 50 | #endif 51 | 52 | #if !defined(jit_builtin_apply_args) 53 | #define jit_builtin_apply_args(type,args) \ 54 | do { \ 55 | (args) = (type)__builtin_apply_args(); \ 56 | } while (0) 57 | #endif 58 | 59 | #if !defined(jit_builtin_return_int) 60 | #define jit_builtin_return_int(return_buf) \ 61 | do { \ 62 | __builtin_return((return_buf)); \ 63 | } while (0) 64 | #endif 65 | 66 | #if !defined(jit_builtin_return_long) 67 | #define jit_builtin_return_long(return_buf) \ 68 | do { \ 69 | __builtin_return((return_buf)); \ 70 | } while (0) 71 | #endif 72 | 73 | #if !defined(jit_builtin_return_float) 74 | #define jit_builtin_return_float(return_buf) \ 75 | do { \ 76 | __builtin_return((return_buf)); \ 77 | } while (0) 78 | #endif 79 | 80 | #if !defined(jit_builtin_return_double) 81 | #define jit_builtin_return_double(return_buf) \ 82 | do { \ 83 | __builtin_return((return_buf)); \ 84 | } while (0) 85 | #endif 86 | 87 | #if !defined(jit_builtin_return_nfloat) 88 | #define jit_builtin_return_nfloat(return_buf) \ 89 | do { \ 90 | __builtin_return((return_buf)); \ 91 | } while (0) 92 | #endif 93 | 94 | /* 95 | * Create a closure for the underlying platform in the given buffer. 96 | * The closure must arrange to call "func" with two arguments: 97 | * "closure" and a pointer to an apply structure. 98 | */ 99 | void _jit_create_closure(unsigned char *buf, void *func, 100 | void *closure, void *type); 101 | 102 | /* 103 | * Create a redirector stub for the underlying platform in the given buffer. 104 | * The redirector arranges to call "func" with the "user_data" argument. 105 | * It is assumed that "func" returns a pointer to the actual function. 106 | * Returns a pointer to the position in "buf" where the redirector starts, 107 | * which may be different than "buf" if alignment occurred. 108 | */ 109 | void *_jit_create_redirector(unsigned char *buf, void *func, 110 | void *user_data, int abi); 111 | 112 | 113 | /* 114 | * Create the indirector for the function. 115 | */ 116 | void *_jit_create_indirector(unsigned char *buf, void **entry); 117 | 118 | /* 119 | * Pad a buffer with NOP instructions. Used to align code. 120 | * This will only be called if "jit_should_pad" is defined. 121 | */ 122 | void _jit_pad_buffer(unsigned char *buf, int len); 123 | 124 | #endif /* _JIT_APPLY_FUNC_H */ 125 | -------------------------------------------------------------------------------- /internal/ccall/jit-apply-x86.c: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-apply-x86.c - Apply support routines for x86. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * This file is part of the libjit library. 7 | * 8 | * The libjit library is free software: you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public License 10 | * as published by the Free Software Foundation, either version 2.1 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * The libjit library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with the libjit library. If not, see 20 | * . 21 | */ 22 | 23 | #include "jit-internal.h" 24 | #include "jit-apply-rules.h" 25 | #include "jit-apply-func.h" 26 | 27 | #if defined(__i386) || defined(__i386__) || defined(_M_IX86) 28 | 29 | #include "jit-gen-x86.h" 30 | 31 | void _jit_create_closure(unsigned char *buf, void *func, 32 | void *closure, void *_type) 33 | { 34 | jit_type_t signature = (jit_type_t)_type; 35 | jit_type_t type; 36 | #if JIT_APPLY_X86_FASTCALL == 1 37 | jit_abi_t abi = jit_type_get_abi(signature); 38 | #endif 39 | unsigned int num_bytes = 0; 40 | int struct_return_offset = 0; 41 | 42 | /* Set up the local stack frame */ 43 | x86_push_reg(buf, X86_EBP); 44 | x86_mov_reg_reg(buf, X86_EBP, X86_ESP, 4); 45 | 46 | /* Create the apply argument block on the stack */ 47 | #if JIT_APPLY_X86_FASTCALL == 1 48 | if(abi == jit_abi_fastcall) 49 | { 50 | x86_push_reg(buf, X86_EDX); 51 | x86_push_reg(buf, X86_ECX); 52 | } 53 | #endif 54 | x86_lea_membase(buf, X86_EAX, X86_EBP, 8); 55 | x86_push_reg(buf, X86_EAX); 56 | 57 | /* Push the arguments for calling "func" */ 58 | x86_mov_reg_reg(buf, X86_EAX, X86_ESP, 4); 59 | x86_push_reg(buf, X86_EAX); 60 | x86_push_imm(buf, (int)closure); 61 | 62 | /* Call the closure handling function */ 63 | x86_call_code(buf, func); 64 | 65 | /* Determine the number of bytes to pop when we return */ 66 | #if JIT_APPLY_X86_FASTCALL == 1 67 | if(abi == jit_abi_stdcall || abi == jit_abi_fastcall) 68 | { 69 | unsigned int word_regs; 70 | unsigned int size; 71 | unsigned int num_params; 72 | unsigned int param; 73 | if(abi == jit_abi_stdcall) 74 | { 75 | word_regs = 0; 76 | } 77 | else 78 | { 79 | word_regs = 2; 80 | } 81 | type = jit_type_normalize(jit_type_get_return(signature)); 82 | if(jit_type_return_via_pointer(type)) 83 | { 84 | if(word_regs > 0) 85 | { 86 | --word_regs; 87 | } 88 | else 89 | { 90 | num_bytes += sizeof(void *); 91 | struct_return_offset = 2 * sizeof(void *); 92 | } 93 | } 94 | num_params = jit_type_num_params(signature); 95 | for(param = 0; param < num_params; ++param) 96 | { 97 | type = jit_type_normalize(jit_type_get_param(signature, param)); 98 | size = jit_type_get_size(type); 99 | if(word_regs > 0) 100 | { 101 | switch(type->kind) 102 | { 103 | case JIT_TYPE_SBYTE: 104 | case JIT_TYPE_UBYTE: 105 | case JIT_TYPE_SHORT: 106 | case JIT_TYPE_USHORT: 107 | case JIT_TYPE_INT: 108 | case JIT_TYPE_UINT: 109 | case JIT_TYPE_NINT: 110 | case JIT_TYPE_NUINT: 111 | case JIT_TYPE_SIGNATURE: 112 | case JIT_TYPE_PTR: 113 | { 114 | --word_regs; 115 | } 116 | continue; 117 | 118 | case JIT_TYPE_LONG: 119 | case JIT_TYPE_ULONG: 120 | { 121 | if(word_regs == 1) 122 | { 123 | num_bytes += sizeof(void *); 124 | } 125 | word_regs = 0; 126 | } 127 | continue; 128 | } 129 | word_regs = 0; 130 | } 131 | num_bytes += (size + sizeof(void *) - 1) & ~(sizeof(void *) - 1); 132 | } 133 | } 134 | else 135 | #endif 136 | { 137 | type = jit_type_normalize(jit_type_get_return(signature)); 138 | if(jit_type_return_via_pointer(type)) 139 | { 140 | #if JIT_APPLY_X86_POP_STRUCT_RETURN == 1 141 | /* Pop the structure return pointer as we return back */ 142 | num_bytes += sizeof(void *); 143 | #endif 144 | struct_return_offset = 2 * sizeof(void *); 145 | } 146 | } 147 | 148 | /* If we are returning a structure via a pointer, then load 149 | the address of the structure into the EAX register */ 150 | if(struct_return_offset != 0) 151 | { 152 | x86_mov_reg_membase(buf, X86_EAX, X86_EBP, struct_return_offset, 4); 153 | } 154 | 155 | /* Pop the current stack frame */ 156 | x86_mov_reg_reg(buf, X86_ESP, X86_EBP, 4); 157 | x86_pop_reg(buf, X86_EBP); 158 | 159 | /* Return from the closure */ 160 | if(num_bytes > 0) 161 | { 162 | x86_ret_imm(buf, num_bytes); 163 | } 164 | else 165 | { 166 | x86_ret(buf); 167 | } 168 | } 169 | 170 | void *_jit_create_redirector(unsigned char *buf, void *func, 171 | void *user_data, int abi) 172 | { 173 | void *start = (void *)buf; 174 | 175 | /* Save the fastcall registers, if necessary */ 176 | #if JIT_APPLY_X86_FASTCALL == 1 177 | if(abi == (int)jit_abi_fastcall) 178 | { 179 | x86_push_reg(buf, X86_EDX); 180 | x86_push_reg(buf, X86_ECX); 181 | } 182 | #endif 183 | 184 | /* Push the user data onto the stack */ 185 | x86_push_imm(buf, (int)user_data); 186 | 187 | /* Call "func" (the pointer result will be in EAX) */ 188 | x86_call_code(buf, func); 189 | 190 | /* Remove the user data from the stack */ 191 | x86_pop_reg(buf, X86_ECX); 192 | 193 | /* Restore the fastcall registers, if necessary */ 194 | #if JIT_APPLY_X86_FASTCALL == 1 195 | if(abi == (int)jit_abi_fastcall) 196 | { 197 | x86_pop_reg(buf, X86_ECX); 198 | x86_pop_reg(buf, X86_EDX); 199 | } 200 | #endif 201 | 202 | /* Jump to the function that the redirector indicated */ 203 | x86_jump_reg(buf, X86_EAX); 204 | 205 | /* Return the start of the buffer as the redirector entry point */ 206 | return start; 207 | } 208 | 209 | void *_jit_create_indirector(unsigned char *buf, void **entry) 210 | { 211 | void *start = (void *)buf; 212 | 213 | /* Jump to the entry point. */ 214 | x86_jump_mem(buf, entry); 215 | 216 | return start; 217 | } 218 | 219 | void _jit_pad_buffer(unsigned char *buf, int len) 220 | { 221 | while(len >= 6) 222 | { 223 | /* "leal 0(%esi), %esi" with 32-bit displacement */ 224 | *buf++ = (unsigned char)0x8D; 225 | x86_address_byte(buf, 2, X86_ESI, X86_ESI); 226 | x86_imm_emit32(buf, 0); 227 | len -= 6; 228 | } 229 | if(len >= 3) 230 | { 231 | /* "leal 0(%esi), %esi" with 8-bit displacement */ 232 | *buf++ = (unsigned char)0x8D; 233 | x86_address_byte(buf, 1, X86_ESI, X86_ESI); 234 | x86_imm_emit8(buf, 0); 235 | len -= 3; 236 | } 237 | if(len == 1) 238 | { 239 | /* Traditional x86 NOP */ 240 | x86_nop(buf); 241 | } 242 | else if(len == 2) 243 | { 244 | /* movl %esi, %esi */ 245 | x86_mov_reg_reg(buf, X86_ESI, X86_ESI, 4); 246 | } 247 | } 248 | 249 | #endif /* x86 */ 250 | -------------------------------------------------------------------------------- /internal/ccall/jit-bitset.c: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-bitset.h - Bitset routines for the JIT. 3 | * 4 | * Copyright (C) 2006 Southern Storm Software, Pty Ltd. 5 | * 6 | * This file is part of the libjit library. 7 | * 8 | * The libjit library is free software: you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public License 10 | * as published by the Free Software Foundation, either version 2.1 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * The libjit library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with the libjit library. If not, see 20 | * . 21 | */ 22 | 23 | #include "jit-internal.h" 24 | #include "jit-bitset.h" 25 | 26 | void 27 | _jit_bitset_init(_jit_bitset_t *bs) 28 | { 29 | bs->size = 0; 30 | bs->bits = 0; 31 | } 32 | 33 | int 34 | _jit_bitset_allocate(_jit_bitset_t *bs, int size) 35 | { 36 | bs->size = size; 37 | if(size > 0) 38 | { 39 | size = (size + _JIT_BITSET_WORD_BITS - 1) / _JIT_BITSET_WORD_BITS; 40 | bs->bits = jit_calloc(size, sizeof(_jit_bitset_word_t)); 41 | if(!bs->bits) 42 | { 43 | jit_free(bs); 44 | return 0; 45 | } 46 | } 47 | else 48 | { 49 | bs->bits = 0; 50 | } 51 | return 1; 52 | } 53 | 54 | int 55 | _jit_bitset_is_allocated(_jit_bitset_t *bs) 56 | { 57 | return (bs->bits != 0); 58 | } 59 | 60 | void 61 | _jit_bitset_free(_jit_bitset_t *bs) 62 | { 63 | if(bs->bits) 64 | { 65 | jit_free(bs->bits); 66 | bs->size = 0; 67 | bs->bits = 0; 68 | } 69 | } 70 | 71 | void 72 | _jit_bitset_set_bit(_jit_bitset_t *bs, int bit) 73 | { 74 | int word; 75 | word = bit / _JIT_BITSET_WORD_BITS; 76 | bit = bit % _JIT_BITSET_WORD_BITS; 77 | bs->bits[word] |= bit; 78 | } 79 | 80 | void 81 | _jit_bitset_clear_bit(_jit_bitset_t *bs, int bit) 82 | { 83 | int word; 84 | word = bit / _JIT_BITSET_WORD_BITS; 85 | bit = bit % _JIT_BITSET_WORD_BITS; 86 | bs->bits[word] &= ~bit; 87 | } 88 | 89 | int 90 | _jit_bitset_test_bit(_jit_bitset_t *bs, int bit) 91 | { 92 | int word; 93 | word = bit / _JIT_BITSET_WORD_BITS; 94 | bit = bit % _JIT_BITSET_WORD_BITS; 95 | return (bs->bits[word] & bit) != 0; 96 | } 97 | 98 | void 99 | _jit_bitset_clear(_jit_bitset_t *bs) 100 | { 101 | int i; 102 | for(i = 0; i < bs->size; i++) 103 | { 104 | bs->bits[i] = 0; 105 | } 106 | } 107 | 108 | int 109 | _jit_bitset_empty(_jit_bitset_t *bs) 110 | { 111 | int i; 112 | for(i = 0; i < bs->size; i++) 113 | { 114 | if(bs->bits[i]) 115 | { 116 | return 0; 117 | } 118 | } 119 | return 1; 120 | } 121 | 122 | void 123 | _jit_bitset_add(_jit_bitset_t *dest, _jit_bitset_t *src) 124 | { 125 | int i; 126 | for(i = 0; i < dest->size; i++) 127 | { 128 | dest->bits[i] |= src->bits[i]; 129 | } 130 | } 131 | 132 | void 133 | _jit_bitset_sub(_jit_bitset_t *dest, _jit_bitset_t *src) 134 | { 135 | int i; 136 | for(i = 0; i < dest->size; i++) 137 | { 138 | dest->bits[i] &= ~src->bits[i]; 139 | } 140 | } 141 | 142 | int 143 | _jit_bitset_copy(_jit_bitset_t *dest, _jit_bitset_t *src) 144 | { 145 | int i; 146 | int changed; 147 | 148 | changed = 0; 149 | for(i = 0; i < dest->size; i++) 150 | { 151 | if(dest->bits[i] != src->bits[i]) 152 | { 153 | dest->bits[i] = src->bits[i]; 154 | changed = 1; 155 | } 156 | } 157 | return changed; 158 | } 159 | 160 | int 161 | _jit_bitset_equal(_jit_bitset_t *bs1, _jit_bitset_t *bs2) 162 | { 163 | int i; 164 | for(i = 0; i < bs1->size; i++) 165 | { 166 | if(bs1->bits[i] != bs2->bits[i]) 167 | { 168 | return 0; 169 | } 170 | } 171 | return 1; 172 | } 173 | -------------------------------------------------------------------------------- /internal/ccall/jit-bitset.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-bitset.h - Bitset routines for the JIT. 3 | * 4 | * Copyright (C) 2006 Southern Storm Software, Pty Ltd. 5 | * 6 | * This file is part of the libjit library. 7 | * 8 | * The libjit library is free software: you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public License 10 | * as published by the Free Software Foundation, either version 2.1 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * The libjit library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with the libjit library. If not, see 20 | * . 21 | */ 22 | 23 | #ifndef _JIT_BITSET_H 24 | #define _JIT_BITSET_H 25 | 26 | #define _JIT_BITSET_WORD_BITS (8 * sizeof(_jit_bitset_word_t)) 27 | 28 | typedef unsigned long _jit_bitset_word_t; 29 | typedef struct _jit_bitset _jit_bitset_t; 30 | 31 | /* TODO: Use less space. Perhaps borrow bitmap from gcc. */ 32 | struct _jit_bitset 33 | { 34 | int size; 35 | _jit_bitset_word_t *bits; 36 | }; 37 | 38 | void _jit_bitset_init(_jit_bitset_t *bs); 39 | int _jit_bitset_allocate(_jit_bitset_t *bs, int size); 40 | int _jit_bitset_is_allocated(_jit_bitset_t *bs); 41 | void _jit_bitset_free(_jit_bitset_t *bs); 42 | void _jit_bitset_set_bit(_jit_bitset_t *bs, int bit); 43 | void _jit_bitset_clear_bit(_jit_bitset_t *bs, int bit); 44 | int _jit_bitset_test_bit(_jit_bitset_t *bs, int bit); 45 | void _jit_bitset_clear(_jit_bitset_t *bs); 46 | int _jit_bitset_empty(_jit_bitset_t *bs); 47 | void _jit_bitset_add(_jit_bitset_t *dest, _jit_bitset_t *src); 48 | void _jit_bitset_sub(_jit_bitset_t *dest, _jit_bitset_t *src); 49 | int _jit_bitset_copy(_jit_bitset_t *dest, _jit_bitset_t *src); 50 | int _jit_bitset_equal(_jit_bitset_t *bs1, _jit_bitset_t *bs2); 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /internal/ccall/jit-config.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-config.h - Configuration macros for the JIT. 3 | * 4 | * Copyright (C) 2011 Southern Storm Software, Pty Ltd. 5 | * 6 | * This file is part of the libjit library. 7 | * 8 | * The libjit library is free software: you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public License 10 | * as published by the Free Software Foundation, either version 2.1 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * The libjit library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with the libjit library. If not, see 20 | * . 21 | */ 22 | 23 | #ifndef _JIT_CONFIG_H 24 | #define _JIT_CONFIG_H 25 | 26 | #include 27 | 28 | /* 29 | * Determine what kind of system we are running on. 30 | */ 31 | #if defined(_WIN32) || defined(WIN32) 32 | # define JIT_WIN32_PLATFORM 1 33 | #elif defined(__APPLE__) && defined(__MACH__) 34 | # define JIT_DARWIN_PLATFORM 1 35 | #elif defined(__linux__) 36 | # define JIT_LINUX_PLATFORM 1 37 | #endif 38 | 39 | /* 40 | * Determine the type of threading library that we are using. 41 | */ 42 | #if defined(HAVE_PTHREAD_H) && defined(HAVE_LIBPTHREAD) 43 | # define JIT_THREADS_SUPPORTED 1 44 | # define JIT_THREADS_PTHREAD 1 45 | #elif defined(JIT_WIN32_PLATFORM) 46 | # define JIT_THREADS_SUPPORTED 1 47 | # define JIT_THREADS_WIN32 1 48 | #else 49 | # define JIT_THREADS_SUPPORTED 0 50 | #endif 51 | 52 | /* 53 | * Determine the type of virtual memory API that we are using. 54 | */ 55 | #if defined(JIT_WIN32_PLATFORM) 56 | # define JIT_VMEM_SUPPORTED 1 57 | # define JIT_VMEM_WIN32 1 58 | #elif defined(HAVE_SYS_MMAN_H) 59 | # define JIT_VMEM_SUPPORTED 1 60 | # define JIT_VMEM_MMAP 1 61 | #else 62 | # define JIT_VMEM_SUPPORTED 0 63 | #endif 64 | 65 | /* 66 | * Determine which backend to use. 67 | */ 68 | #if defined(USE_LIBJIT_INTERPRETER) 69 | # define JIT_BACKEND_INTERP 1 70 | # define JIT_HAVE_BACKEND 1 71 | #elif defined(__alpha) || defined(__alpha__) 72 | # define JIT_BACKEND_ALPHA 1 73 | # define JIT_HAVE_BACKEND 1 74 | #elif defined(__arm) || defined(__arm__) 75 | # define JIT_BACKEND_ARM 1 76 | # define JIT_HAVE_BACKEND 1 77 | #elif defined(__i386) || defined(__i386__) || defined(_M_IX86) 78 | # define JIT_BACKEND_X86 1 79 | # define JIT_HAVE_BACKEND 1 80 | #elif defined(__amd64) || defined(__amd64__) || defined(_x86_64) || defined(_x86_64__) 81 | # define JIT_BACKEND_X86_64 1 82 | # define JIT_HAVE_BACKEND 1 83 | #endif 84 | 85 | /* 86 | * Fallback to interpreter if there is no appropriate native backend. 87 | */ 88 | #if !defined(JIT_HAVE_BACKEND) 89 | # define JIT_BACKEND_INTERP 1 90 | #endif 91 | 92 | /* 93 | #define _JIT_COMPILE_DEBUG 1 94 | #define _JIT_BLOCK_DEBUG 1 95 | */ 96 | 97 | #endif /* _JIT_CONFIG_H */ 98 | 99 | -------------------------------------------------------------------------------- /internal/ccall/jit-cpuid-x86.c: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-cpuid-x86.c - Wrapper for the CPUID instruction. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * This file is part of the libjit library. 7 | * 8 | * The libjit library is free software: you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public License 10 | * as published by the Free Software Foundation, either version 2.1 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * The libjit library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with the libjit library. If not, see 20 | * . 21 | */ 22 | 23 | #include "jit-cpuid-x86.h" 24 | 25 | #if defined(__i386) || defined(__i386__) || defined(_M_IX86) 26 | 27 | /* 28 | * Determine if the "cpuid" instruction is present by twiddling 29 | * bit 21 of the EFLAGS register. 30 | */ 31 | static int cpuid_present(void) 32 | { 33 | #if defined(__GNUC__) 34 | int result; 35 | __asm__ __volatile__ ( 36 | "\tpushfl\n" 37 | "\tpopl %%eax\n" 38 | "\tmovl %%eax, %%ecx\n" 39 | "\tandl $0x200000, %%ecx\n" 40 | "\txorl $0x200000, %%eax\n" 41 | "\tpushl %%eax\n" 42 | "\tpopfl\n" 43 | "\tpushfl\n" 44 | "\tandl $0x200000, %%eax\n" 45 | "\txorl %%ecx, %%eax\n" 46 | "\tmovl %%eax, %0\n" 47 | : "=m" (result) : : "eax", "ecx" 48 | ); 49 | return (result != 0); 50 | #else 51 | return 0; 52 | #endif 53 | } 54 | 55 | /* 56 | * Issue a "cpuid" query and get the result. 57 | */ 58 | static void cpuid_query(unsigned int index, jit_cpuid_x86_t *info) 59 | { 60 | #if defined(__GNUC__) 61 | __asm__ __volatile__ ( 62 | "\tmovl %0, %%eax\n" 63 | "\tpushl %%ebx\n" 64 | "\txorl %%ebx, %%ebx\n" 65 | "\txorl %%ecx, %%ecx\n" 66 | "\txorl %%edx, %%edx\n" 67 | "\t.byte 0x0F\n" /* cpuid, safe against old assemblers */ 68 | "\t.byte 0xA2\n" 69 | "\tmovl %1, %%esi\n" 70 | "\tmovl %%eax, (%%esi)\n" 71 | "\tmovl %%ebx, 4(%%esi)\n" 72 | "\tmovl %%ecx, 8(%%esi)\n" 73 | "\tmovl %%edx, 12(%%esi)\n" 74 | "\tpopl %%ebx\n" 75 | : : "m"(index), "m"(info) : "eax", "ecx", "edx", "esi" 76 | ); 77 | #endif 78 | } 79 | 80 | int _jit_cpuid_x86_get(unsigned int index, jit_cpuid_x86_t *info) 81 | { 82 | /* Determine if this cpu has the "cpuid" instruction */ 83 | if(!cpuid_present()) 84 | { 85 | return 0; 86 | } 87 | 88 | /* Validate the index */ 89 | if((index & 0x80000000) == 0) 90 | { 91 | cpuid_query(0, info); 92 | } 93 | else 94 | { 95 | cpuid_query(0x80000000, info); 96 | } 97 | if(index > info->eax) 98 | { 99 | return 0; 100 | } 101 | 102 | /* Execute the actual requested query */ 103 | cpuid_query(index, info); 104 | return 1; 105 | } 106 | 107 | int _jit_cpuid_x86_has_feature(unsigned int feature) 108 | { 109 | jit_cpuid_x86_t info; 110 | if(!_jit_cpuid_x86_get(JIT_X86CPUID_FEATURES, &info)) 111 | { 112 | return 0; 113 | } 114 | return ((info.edx & feature) != 0); 115 | } 116 | 117 | unsigned int _jit_cpuid_x86_line_size(void) 118 | { 119 | jit_cpuid_x86_t info; 120 | if(!_jit_cpuid_x86_get(JIT_X86CPUID_FEATURES, &info)) 121 | { 122 | return 0; 123 | } 124 | if((info.edx & JIT_X86FEATURE_CLFSH) == 0) 125 | { 126 | return 0; 127 | } 128 | return ((info.ebx & 0x0000FF00) >> 5); 129 | } 130 | 131 | #endif /* i386 */ 132 | -------------------------------------------------------------------------------- /internal/ccall/jit-cpuid-x86.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-cpuid-x86.h - Wrapper for the CPUID instruction. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * This file is part of the libjit library. 7 | * 8 | * The libjit library is free software: you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public License 10 | * as published by the Free Software Foundation, either version 2.1 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * The libjit library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with the libjit library. If not, see 20 | * . 21 | */ 22 | 23 | #ifndef _JIT_CPUID_X86_H 24 | #define _JIT_CPUID_X86_H 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | /* 31 | * Structure that is used to return CPU identification information. 32 | */ 33 | typedef struct 34 | { 35 | unsigned int eax; 36 | unsigned int ebx; 37 | unsigned int ecx; 38 | unsigned int edx; 39 | 40 | } jit_cpuid_x86_t; 41 | 42 | /* 43 | * Indexes for querying cpuid information. 44 | */ 45 | #define JIT_X86CPUID_FEATURES 1 46 | #define JIT_X86CPUID_CACHE_TLB 2 47 | #define JIT_X86CPUID_SERIAL_NUMBER 3 48 | 49 | /* 50 | * Feature information. 51 | */ 52 | #define JIT_X86FEATURE_FPU 0x00000001 53 | #define JIT_X86FEATURE_VME 0x00000002 54 | #define JIT_X86FEATURE_DE 0x00000004 55 | #define JIT_X86FEATURE_PSE 0x00000008 56 | #define JIT_X86FEATURE_TSC 0x00000010 57 | #define JIT_X86FEATURE_MSR 0x00000020 58 | #define JIT_X86FEATURE_PAE 0x00000040 59 | #define JIT_X86FEATURE_MCE 0x00000080 60 | #define JIT_X86FEATURE_CX8 0x00000100 61 | #define JIT_X86FEATURE_APIC 0x00000200 62 | #define JIT_X86FEATURE_RESERVED_1 0x00000400 63 | #define JIT_X86FEATURE_SEP 0x00000800 64 | #define JIT_X86FEATURE_MTRR 0x00001000 65 | #define JIT_X86FEATURE_PGE 0x00002000 66 | #define JIT_X86FEATURE_MCA 0x00004000 67 | #define JIT_X86FEATURE_CMOV 0x00008000 68 | #define JIT_X86FEATURE_PAT 0x00010000 69 | #define JIT_X86FEATURE_PSE36 0x00020000 70 | #define JIT_X86FEATURE_PSN 0x00040000 71 | #define JIT_X86FEATURE_CLFSH 0x00080000 72 | #define JIT_X86FEATURE_RESERVED_2 0x00100000 73 | #define JIT_X86FEATURE_DS 0x00200000 74 | #define JIT_X86FEATURE_ACPI 0x00400000 75 | #define JIT_X86FEATURE_MMX 0x00800000 76 | #define JIT_X86FEATURE_FXSR 0x01000000 77 | #define JIT_X86FEATURE_SSE 0x02000000 78 | #define JIT_X86FEATURE_SSE2 0x04000000 79 | #define JIT_X86FEATURE_SS 0x08000000 80 | #define JIT_X86FEATURE_RESERVED_3 0x10000000 81 | #define JIT_X86FEATURE_TM 0x20000000 82 | #define JIT_X86FEATURE_RESERVED_4 0x40000000 83 | #define JIT_X86FEATURE_RESERVED_5 0x80000000 84 | 85 | /* 86 | * Get CPU identification information. Returns zero if the requested 87 | * information is not available. 88 | */ 89 | int _jit_cpuid_x86_get(unsigned int index, jit_cpuid_x86_t *info); 90 | 91 | /* 92 | * Determine if the CPU has a particular feature. 93 | */ 94 | int _jit_cpuid_x86_has_feature(unsigned int feature); 95 | 96 | /* 97 | * Get the size of the CPU cache line, or zero if flushing is not required. 98 | */ 99 | unsigned int _jit_cpuid_x86_line_size(void); 100 | 101 | #ifdef __cplusplus 102 | }; 103 | #endif 104 | 105 | #endif /* _JIT_CPUID_X86_H */ 106 | -------------------------------------------------------------------------------- /internal/ccall/jit-gen-arm.c: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-gen-arm.c - Machine-dependent definitions for ARM. 3 | * 4 | * Copyright (C) 2003, 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * This file is part of the libjit library. 7 | * 8 | * The libjit library is free software: you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public License 10 | * as published by the Free Software Foundation, either version 2.1 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * The libjit library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with the libjit library. If not, see 20 | * . 21 | */ 22 | 23 | #include "jit-internal.h" 24 | 25 | #if defined(__arm) || defined(__arm__) 26 | 27 | #define arm_execute execute_prefix 28 | #define arm_execute_cc (execute_prefix | (1 << 20)) 29 | #define arm_execute_imm (execute_prefix | (1 << 25)) 30 | 31 | #include "jit-gen-arm.h" 32 | 33 | void _arm_mov_reg_imm 34 | (arm_inst_buf *inst, int reg, int value, int execute_prefix) 35 | { 36 | int bit; 37 | 38 | /* Handle bytes in various positions */ 39 | for(bit = 0; bit <= (32 - 8); bit += 2) 40 | { 41 | if((value & (0xFF << bit)) == value) 42 | { 43 | arm_mov_reg_imm8_rotate 44 | (*inst, reg, ((value >> bit) & 0xFF), (16 - bit / 2) & 0x0F); 45 | return; 46 | } 47 | } 48 | 49 | /* Handle inverted bytes in various positions */ 50 | value = ~value; 51 | for(bit = 0; bit <= (32 - 8); bit += 2) 52 | { 53 | if((value & (0xFF << bit)) == value) 54 | { 55 | arm_alu_reg_imm8_rotate 56 | (*inst, ARM_MVN, reg, 0, 57 | ((value >> bit) & 0xFF), (16 - bit / 2) & 0x0F); 58 | return; 59 | } 60 | } 61 | 62 | /* Build the value the hard way, byte by byte */ 63 | value = ~value; 64 | if((value & 0xFF000000) != 0) 65 | { 66 | arm_mov_reg_imm8_rotate(*inst, reg, ((value >> 24) & 0xFF), 4); 67 | if((value & 0x00FF0000) != 0) 68 | { 69 | arm_alu_reg_imm8_rotate 70 | (*inst, ARM_ADD, reg, reg, ((value >> 16) & 0xFF), 8); 71 | } 72 | if((value & 0x0000FF00) != 0) 73 | { 74 | arm_alu_reg_imm8_rotate 75 | (*inst, ARM_ADD, reg, reg, ((value >> 8) & 0xFF), 12); 76 | } 77 | if((value & 0x000000FF) != 0) 78 | { 79 | arm_alu_reg_imm8(*inst, ARM_ADD, reg, reg, (value & 0xFF)); 80 | } 81 | } 82 | else if((value & 0x00FF0000) != 0) 83 | { 84 | arm_mov_reg_imm8_rotate(*inst, reg, ((value >> 16) & 0xFF), 8); 85 | if((value & 0x0000FF00) != 0) 86 | { 87 | arm_alu_reg_imm8_rotate 88 | (*inst, ARM_ADD, reg, reg, ((value >> 8) & 0xFF), 12); 89 | } 90 | if((value & 0x000000FF) != 0) 91 | { 92 | arm_alu_reg_imm8(*inst, ARM_ADD, reg, reg, (value & 0xFF)); 93 | } 94 | } 95 | else if((value & 0x0000FF00) != 0) 96 | { 97 | arm_mov_reg_imm8_rotate(*inst, reg, ((value >> 8) & 0xFF), 12); 98 | if((value & 0x000000FF) != 0) 99 | { 100 | arm_alu_reg_imm8(*inst, ARM_ADD, reg, reg, (value & 0xFF)); 101 | } 102 | } 103 | else 104 | { 105 | arm_mov_reg_imm8(*inst, reg, (value & 0xFF)); 106 | } 107 | } 108 | 109 | int arm_is_complex_imm(int value) 110 | { 111 | int bit; 112 | int inv_value = ~value; 113 | for(bit = 0; bit <= (32 - 8); bit += 2) 114 | { 115 | if((value & (0xFF << bit)) == value) 116 | { 117 | return 0; 118 | } 119 | if((inv_value & (0xFF << bit)) == inv_value) 120 | { 121 | return 0; 122 | } 123 | } 124 | return 1; 125 | } 126 | 127 | void _arm_alu_reg_imm 128 | (arm_inst_buf *inst, int opc, int dreg, 129 | int sreg, int imm, int saveWork, int execute_prefix) 130 | { 131 | int bit, tempreg; 132 | for(bit = 0; bit <= (32 - 8); bit += 2) 133 | { 134 | if((imm & (0xFF << bit)) == imm) 135 | { 136 | arm_alu_reg_imm8_rotate 137 | (*inst, opc, dreg, sreg, 138 | ((imm >> bit) & 0xFF), (16 - bit / 2) & 0x0F); 139 | return; 140 | } 141 | } 142 | if(saveWork) 143 | { 144 | if(dreg != ARM_R2 && sreg != ARM_R2) 145 | { 146 | tempreg = ARM_R2; 147 | } 148 | else if(dreg != ARM_R3 && sreg != ARM_R3) 149 | { 150 | tempreg = ARM_R3; 151 | } 152 | else 153 | { 154 | tempreg = ARM_R4; 155 | } 156 | arm_push_reg(*inst, tempreg); 157 | } 158 | else 159 | { 160 | tempreg = ARM_WORK; 161 | } 162 | _arm_mov_reg_imm(inst, tempreg, imm, execute_prefix); 163 | arm_alu_reg_reg(*inst, opc, dreg, sreg, tempreg); 164 | if(saveWork) 165 | { 166 | arm_pop_reg(*inst, tempreg); 167 | } 168 | } 169 | 170 | #endif /* arm */ 171 | -------------------------------------------------------------------------------- /internal/ccall/jit-init.c: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-init.c - Initialization routines for the JIT. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * This file is part of the libjit library. 7 | * 8 | * The libjit library is free software: you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public License 10 | * as published by the Free Software Foundation, either version 2.1 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * The libjit library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with the libjit library. If not, see 20 | * . 21 | */ 22 | 23 | #include "jit-internal.h" 24 | #include "jit-rules.h" 25 | 26 | /*@ 27 | * @deftypefun void jit_init (void) 28 | * This is normally the first function that you call when using 29 | * @code{libjit}. It initializes the library and prepares for 30 | * JIT operations. 31 | * 32 | * The @code{jit_context_create} function also calls this, so you can 33 | * avoid using @code{jit_init} if @code{jit_context_create} is the first 34 | * JIT function that you use. 35 | * 36 | * It is safe to initialize the JIT multiple times. Subsequent 37 | * initializations are quietly ignored. 38 | * @end deftypefun 39 | @*/ 40 | void 41 | jit_init(void) 42 | { 43 | static int init_done = 0; 44 | 45 | /* Make sure that the thread subsystem is initialized */ 46 | _jit_thread_init(); 47 | 48 | /* Make sure that the initialization is done only once 49 | (requires the global lock initialized above) */ 50 | jit_mutex_lock(&_jit_global_lock); 51 | if(init_done) 52 | { 53 | goto done; 54 | } 55 | init_done = 1; 56 | 57 | #ifdef JIT_USE_SIGNALS 58 | /* Initialize the signal handlers */ 59 | _jit_signal_init(); 60 | #endif 61 | 62 | /* Initialize the virtual memory system */ 63 | jit_vmem_init(); 64 | 65 | /* Initialize the backend */ 66 | _jit_init_backend(); 67 | 68 | done: 69 | jit_mutex_unlock(&_jit_global_lock); 70 | } 71 | 72 | /*@ 73 | * @deftypefun int jit_uses_interpreter (void) 74 | * Determine if the JIT uses a fall-back interpreter to execute code 75 | * rather than generating and executing native code. This can be 76 | * called prior to @code{jit_init}. 77 | * @end deftypefun 78 | @*/ 79 | int 80 | jit_uses_interpreter(void) 81 | { 82 | #if defined(JIT_BACKEND_INTERP) 83 | return 1; 84 | #else 85 | return 0; 86 | #endif 87 | } 88 | 89 | /*@ 90 | * @deftypefun int jit_supports_threads (void) 91 | * Determine if the JIT supports threads. 92 | * @end deftypefun 93 | @*/ 94 | int 95 | jit_supports_threads(void) 96 | { 97 | return JIT_THREADS_SUPPORTED; 98 | } 99 | 100 | /*@ 101 | * @deftypefun int jit_supports_virtual_memory (void) 102 | * Determine if the JIT supports virtual memory. 103 | * @end deftypefun 104 | @*/ 105 | int 106 | jit_supports_virtual_memory(void) 107 | { 108 | return JIT_VMEM_SUPPORTED; 109 | } 110 | -------------------------------------------------------------------------------- /internal/ccall/jit-interp-opcode.c: -------------------------------------------------------------------------------- 1 | /* Automatically generated from ./jit-interp-opcodes.ops - DO NOT EDIT */ 2 | 3 | /* 4 | * jit-interp-opcode.c - Information about interpreter specific JIT opcodes. 5 | * 6 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 7 | * 8 | * This file is part of the libjit library. 9 | * 10 | * The libjit library is free software: you can redistribute it and/or 11 | * modify it under the terms of the GNU Lesser General Public License 12 | * as published by the Free Software Foundation, either version 2.1 of 13 | * the License, or (at your option) any later version. 14 | * 15 | * The libjit library is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 | * Lesser General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU Lesser General Public 21 | * License along with the libjit library. If not, see 22 | * . 23 | */ 24 | 25 | #include "jit-internal.h" 26 | #include "jit-interp-opcode.h" 27 | #include "jit-rules.h" 28 | 29 | #if defined(JIT_BACKEND_INTERP) 30 | 31 | jit_opcode_info_t const _jit_interp_opcodes[JIT_INTERP_OP_NUM_OPCODES] = { 32 | {"lda_0_sbyte", JIT_OPCODE_NINT_ARG}, 33 | {"lda_0_ubyte", JIT_OPCODE_NINT_ARG}, 34 | {"lda_0_short", JIT_OPCODE_NINT_ARG}, 35 | {"lda_0_ushort", JIT_OPCODE_NINT_ARG}, 36 | {"lda_0_int", JIT_OPCODE_NINT_ARG}, 37 | {"lda_0_long", JIT_OPCODE_NINT_ARG}, 38 | {"lda_0_float32", JIT_OPCODE_NINT_ARG}, 39 | {"lda_0_float64", JIT_OPCODE_NINT_ARG}, 40 | {"lda_0_nfloat", JIT_OPCODE_NINT_ARG}, 41 | {"ldaa_0", JIT_OPCODE_NINT_ARG}, 42 | {"lda_1_sbyte", JIT_OPCODE_NINT_ARG}, 43 | {"lda_1_ubyte", JIT_OPCODE_NINT_ARG}, 44 | {"lda_1_short", JIT_OPCODE_NINT_ARG}, 45 | {"lda_1_ushort", JIT_OPCODE_NINT_ARG}, 46 | {"lda_1_int", JIT_OPCODE_NINT_ARG}, 47 | {"lda_1_long", JIT_OPCODE_NINT_ARG}, 48 | {"lda_1_float32", JIT_OPCODE_NINT_ARG}, 49 | {"lda_1_float64", JIT_OPCODE_NINT_ARG}, 50 | {"lda_1_nfloat", JIT_OPCODE_NINT_ARG}, 51 | {"ldaa_1", JIT_OPCODE_NINT_ARG}, 52 | {"lda_2_sbyte", JIT_OPCODE_NINT_ARG}, 53 | {"lda_2_ubyte", JIT_OPCODE_NINT_ARG}, 54 | {"lda_2_short", JIT_OPCODE_NINT_ARG}, 55 | {"lda_2_ushort", JIT_OPCODE_NINT_ARG}, 56 | {"lda_2_int", JIT_OPCODE_NINT_ARG}, 57 | {"lda_2_long", JIT_OPCODE_NINT_ARG}, 58 | {"lda_2_float32", JIT_OPCODE_NINT_ARG}, 59 | {"lda_2_float64", JIT_OPCODE_NINT_ARG}, 60 | {"lda_2_nfloat", JIT_OPCODE_NINT_ARG}, 61 | {"ldaa_2", JIT_OPCODE_NINT_ARG}, 62 | {"sta_0_byte", JIT_OPCODE_NINT_ARG}, 63 | {"sta_0_short", JIT_OPCODE_NINT_ARG}, 64 | {"sta_0_int", JIT_OPCODE_NINT_ARG}, 65 | {"sta_0_long", JIT_OPCODE_NINT_ARG}, 66 | {"sta_0_float32", JIT_OPCODE_NINT_ARG}, 67 | {"sta_0_float64", JIT_OPCODE_NINT_ARG}, 68 | {"sta_0_nfloat", JIT_OPCODE_NINT_ARG}, 69 | {"ldl_0_sbyte", JIT_OPCODE_NINT_ARG}, 70 | {"ldl_0_ubyte", JIT_OPCODE_NINT_ARG}, 71 | {"ldl_0_short", JIT_OPCODE_NINT_ARG}, 72 | {"ldl_0_ushort", JIT_OPCODE_NINT_ARG}, 73 | {"ldl_0_int", JIT_OPCODE_NINT_ARG}, 74 | {"ldl_0_long", JIT_OPCODE_NINT_ARG}, 75 | {"ldl_0_float32", JIT_OPCODE_NINT_ARG}, 76 | {"ldl_0_float64", JIT_OPCODE_NINT_ARG}, 77 | {"ldl_0_nfloat", JIT_OPCODE_NINT_ARG}, 78 | {"ldla_0", JIT_OPCODE_NINT_ARG}, 79 | {"ldl_1_sbyte", JIT_OPCODE_NINT_ARG}, 80 | {"ldl_1_ubyte", JIT_OPCODE_NINT_ARG}, 81 | {"ldl_1_short", JIT_OPCODE_NINT_ARG}, 82 | {"ldl_1_ushort", JIT_OPCODE_NINT_ARG}, 83 | {"ldl_1_int", JIT_OPCODE_NINT_ARG}, 84 | {"ldl_1_long", JIT_OPCODE_NINT_ARG}, 85 | {"ldl_1_float32", JIT_OPCODE_NINT_ARG}, 86 | {"ldl_1_float64", JIT_OPCODE_NINT_ARG}, 87 | {"ldl_1_nfloat", JIT_OPCODE_NINT_ARG}, 88 | {"ldla_1", JIT_OPCODE_NINT_ARG}, 89 | {"ldl_2_sbyte", JIT_OPCODE_NINT_ARG}, 90 | {"ldl_2_ubyte", JIT_OPCODE_NINT_ARG}, 91 | {"ldl_2_short", JIT_OPCODE_NINT_ARG}, 92 | {"ldl_2_ushort", JIT_OPCODE_NINT_ARG}, 93 | {"ldl_2_int", JIT_OPCODE_NINT_ARG}, 94 | {"ldl_2_long", JIT_OPCODE_NINT_ARG}, 95 | {"ldl_2_float32", JIT_OPCODE_NINT_ARG}, 96 | {"ldl_2_float64", JIT_OPCODE_NINT_ARG}, 97 | {"ldl_2_nfloat", JIT_OPCODE_NINT_ARG}, 98 | {"ldla_2", JIT_OPCODE_NINT_ARG}, 99 | {"stl_0_byte", JIT_OPCODE_NINT_ARG}, 100 | {"stl_0_short", JIT_OPCODE_NINT_ARG}, 101 | {"stl_0_int", JIT_OPCODE_NINT_ARG}, 102 | {"stl_0_long", JIT_OPCODE_NINT_ARG}, 103 | {"stl_0_float32", JIT_OPCODE_NINT_ARG}, 104 | {"stl_0_float64", JIT_OPCODE_NINT_ARG}, 105 | {"stl_0_nfloat", JIT_OPCODE_NINT_ARG}, 106 | {"ldc_0_int", JIT_OPCODE_NINT_ARG}, 107 | {"ldc_1_int", JIT_OPCODE_NINT_ARG}, 108 | {"ldc_2_int", JIT_OPCODE_NINT_ARG}, 109 | {"ldc_0_long", JIT_OPCODE_CONST_LONG}, 110 | {"ldc_1_long", JIT_OPCODE_CONST_LONG}, 111 | {"ldc_2_long", JIT_OPCODE_CONST_LONG}, 112 | {"ldc_0_float32", JIT_OPCODE_CONST_FLOAT32}, 113 | {"ldc_1_float32", JIT_OPCODE_CONST_FLOAT32}, 114 | {"ldc_2_float32", JIT_OPCODE_CONST_FLOAT32}, 115 | {"ldc_0_float64", JIT_OPCODE_CONST_FLOAT64}, 116 | {"ldc_1_float64", JIT_OPCODE_CONST_FLOAT64}, 117 | {"ldc_2_float64", JIT_OPCODE_CONST_FLOAT64}, 118 | {"ldc_0_nfloat", JIT_OPCODE_CONST_NFLOAT}, 119 | {"ldc_1_nfloat", JIT_OPCODE_CONST_NFLOAT}, 120 | {"ldc_2_nfloat", JIT_OPCODE_CONST_NFLOAT}, 121 | {"ldr_0_int", 0}, 122 | {"ldr_0_long", 0}, 123 | {"ldr_0_float32", 0}, 124 | {"ldr_0_float64", 0}, 125 | {"ldr_0_nfloat", 0}, 126 | {"pop", 0}, 127 | {"pop_2", 0}, 128 | {"pop_3", 0}, 129 | {"end_marker", 0} 130 | }; 131 | 132 | #endif /* defined(JIT_BACKEND_INTERP) */ 133 | -------------------------------------------------------------------------------- /internal/ccall/jit-interp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-interp.h - Bytecode interpreter for platforms without native support. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * This file is part of the libjit library. 7 | * 8 | * The libjit library is free software: you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public License 10 | * as published by the Free Software Foundation, either version 2.1 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * The libjit library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with the libjit library. If not, see 20 | * . 21 | */ 22 | 23 | #ifndef _JIT_INTERP_H 24 | #define _JIT_INTERP_H 25 | 26 | #include "jit-internal.h" 27 | #include "jit-apply-rules.h" 28 | #include "jit-interp-opcode.h" 29 | 30 | #ifdef __cplusplus 31 | extern "C" { 32 | #endif 33 | 34 | /* 35 | * Structure of a stack item. 36 | */ 37 | typedef union 38 | { 39 | jit_int int_value; 40 | jit_uint uint_value; 41 | jit_long long_value; 42 | jit_ulong ulong_value; 43 | jit_float32 float32_value; 44 | jit_float64 float64_value; 45 | jit_nfloat nfloat_value; 46 | void *ptr_value; 47 | #if JIT_APPLY_MAX_STRUCT_IN_REG != 0 48 | char struct_value[JIT_APPLY_MAX_STRUCT_IN_REG]; 49 | #endif 50 | 51 | } jit_item; 52 | 53 | /* 54 | * Number of items that make up a struct or union value on the stack. 55 | */ 56 | #define JIT_NUM_ITEMS_IN_STRUCT(size) \ 57 | (((size) + (sizeof(jit_item) - 1)) / sizeof(jit_item)) 58 | 59 | /* 60 | * Information that is prefixed to a function that describes 61 | * its interpretation context. The code starts just after this. 62 | */ 63 | typedef struct jit_function_interp *jit_function_interp_t; 64 | struct jit_function_interp 65 | { 66 | /* The function that this structure is associated with */ 67 | jit_function_t func; 68 | 69 | /* Size of the argument area to allocate, in bytes */ 70 | unsigned int args_size; 71 | 72 | /* Size of the local stack frame to allocate, in bytes */ 73 | unsigned int frame_size; 74 | 75 | /* Size of the working stack area of the frame, in items */ 76 | unsigned int working_area; 77 | }; 78 | 79 | /* 80 | * Get the size of the "jit_function_interp" structure, rounded 81 | * up to a multiple of "void *". 82 | */ 83 | #define jit_function_interp_size \ 84 | ((sizeof(struct jit_function_interp) + sizeof(void *) - 1) & \ 85 | ~(sizeof(void *) - 1)) 86 | 87 | /* 88 | * Get the entry point for a function, from its "jit_function_interp_t" block. 89 | */ 90 | #define jit_function_interp_entry_pc(info) \ 91 | ((void **)(((unsigned char *)(info)) + jit_function_interp_size)) 92 | 93 | #ifdef __cplusplus 94 | }; 95 | #endif 96 | 97 | #endif /* _JIT_INTERP_H */ 98 | -------------------------------------------------------------------------------- /internal/ccall/jit-memory.c: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-memory.c - Memory management. 3 | * 4 | * Copyright (C) 2012 Aleksey Demakov 5 | * 6 | * The libjit library is free software: you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public License 8 | * as published by the Free Software Foundation, either version 2.1 of 9 | * the License, or (at your option) any later version. 10 | * 11 | * The libjit library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with the libjit library. If not, see 18 | * . 19 | */ 20 | 21 | #include "jit-internal.h" 22 | 23 | void 24 | _jit_memory_lock(jit_context_t context) 25 | { 26 | jit_mutex_lock(&context->memory_lock); 27 | } 28 | 29 | void 30 | _jit_memory_unlock(jit_context_t context) 31 | { 32 | jit_mutex_unlock(&context->memory_lock); 33 | } 34 | 35 | int 36 | _jit_memory_ensure(jit_context_t context) 37 | { 38 | if(!context->memory_context) 39 | { 40 | context->memory_context = context->memory_manager->create(context); 41 | } 42 | return (context->memory_context != 0); 43 | } 44 | 45 | void 46 | _jit_memory_destroy(jit_context_t context) 47 | { 48 | if(!context->memory_context) 49 | { 50 | return; 51 | } 52 | context->memory_manager->destroy(context->memory_context); 53 | } 54 | 55 | jit_function_info_t 56 | _jit_memory_find_function_info(jit_context_t context, void *pc) 57 | { 58 | if(!context->memory_context) 59 | { 60 | return 0; 61 | } 62 | /* TODO: read lock? */ 63 | return context->memory_manager->find_function_info(context->memory_context, pc); 64 | } 65 | 66 | jit_function_t 67 | _jit_memory_get_function(jit_context_t context, jit_function_info_t info) 68 | { 69 | /* TODO: read lock? */ 70 | return context->memory_manager->get_function(context->memory_context, info); 71 | } 72 | 73 | void * 74 | _jit_memory_get_function_start(jit_context_t context, jit_function_info_t info) 75 | { 76 | /* TODO: read lock? */ 77 | return context->memory_manager->get_function_start(context->memory_context, info); 78 | } 79 | 80 | void * 81 | _jit_memory_get_function_end(jit_context_t context, jit_function_info_t info) 82 | { 83 | /* TODO: read lock? */ 84 | return context->memory_manager->get_function_end(context->memory_context, info); 85 | } 86 | 87 | jit_function_t 88 | _jit_memory_alloc_function(jit_context_t context) 89 | { 90 | return context->memory_manager->alloc_function(context->memory_context); 91 | } 92 | 93 | void 94 | _jit_memory_free_function(jit_context_t context, jit_function_t func) 95 | { 96 | context->memory_manager->free_function(context->memory_context, func); 97 | } 98 | 99 | int 100 | _jit_memory_start_function(jit_context_t context, jit_function_t func) 101 | { 102 | return context->memory_manager->start_function(context->memory_context, func); 103 | } 104 | 105 | int 106 | _jit_memory_end_function(jit_context_t context, int result) 107 | { 108 | return context->memory_manager->end_function(context->memory_context, result); 109 | } 110 | 111 | int 112 | _jit_memory_extend_limit(jit_context_t context, int count) 113 | { 114 | return context->memory_manager->extend_limit(context->memory_context, count); 115 | } 116 | 117 | void * 118 | _jit_memory_get_limit(jit_context_t context) 119 | { 120 | return context->memory_manager->get_limit(context->memory_context); 121 | } 122 | 123 | void * 124 | _jit_memory_get_break(jit_context_t context) 125 | { 126 | return context->memory_manager->get_break(context->memory_context); 127 | } 128 | 129 | void 130 | _jit_memory_set_break(jit_context_t context, void *brk) 131 | { 132 | context->memory_manager->set_break(context->memory_context, brk); 133 | } 134 | 135 | void * 136 | _jit_memory_alloc_trampoline(jit_context_t context) 137 | { 138 | return context->memory_manager->alloc_trampoline(context->memory_context); 139 | } 140 | 141 | void 142 | _jit_memory_free_trampoline(jit_context_t context, void *ptr) 143 | { 144 | context->memory_manager->free_trampoline(context->memory_context, ptr); 145 | } 146 | 147 | void * 148 | _jit_memory_alloc_closure(jit_context_t context) 149 | { 150 | return context->memory_manager->alloc_closure(context->memory_context); 151 | } 152 | 153 | void 154 | _jit_memory_free_closure(jit_context_t context, void *ptr) 155 | { 156 | context->memory_manager->free_closure(context->memory_context, ptr); 157 | } 158 | 159 | void * 160 | _jit_memory_alloc_data(jit_context_t context, jit_size_t size, jit_size_t align) 161 | { 162 | return context->memory_manager->alloc_data(context->memory_context, size, align); 163 | } 164 | -------------------------------------------------------------------------------- /internal/ccall/jit-meta.c: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-meta.c - Functions for manipulating metadata lists. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * This file is part of the libjit library. 7 | * 8 | * The libjit library is free software: you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public License 10 | * as published by the Free Software Foundation, either version 2.1 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * The libjit library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with the libjit library. If not, see 20 | * . 21 | */ 22 | 23 | #include "jit-internal.h" 24 | 25 | /*@ 26 | 27 | @section Metadata handling 28 | @cindex Metadata handling 29 | @cindex jit-meta.h 30 | 31 | Many of the structures in the @code{libjit} library can have user-supplied 32 | metadata associated with them. Metadata may be used to store dependency 33 | graphs, branch prediction information, or any other information that is 34 | useful to optimizers or code generators. 35 | 36 | Metadata can also be used by higher level user code to store information 37 | about the structures that is specific to the user's virtual machine or 38 | language. 39 | 40 | The library structures have special-purpose metadata routines associated 41 | with them (e.g. @code{jit_function_set_meta}, @code{jit_block_get_meta}). 42 | However, sometimes you may wish to create your own metadata lists and 43 | attach them to your own structures. The functions below enable you 44 | to do this: 45 | 46 | @*/ 47 | 48 | /*@ 49 | * @deftypefun int jit_meta_set (jit_meta_t *@var{list}, int @var{type}, void *@var{data}, jit_meta_free_func @var{free_data}, jit_function_t @var{pool_owner}) 50 | * Set a metadata value on a list. If the @var{type} is already present 51 | * in the list, then its previous value will be freed. The @var{free_func} 52 | * is called when the metadata value is freed with @code{jit_meta_free} 53 | * or @code{jit_meta_destroy}. Returns zero if out of memory. 54 | * 55 | * If @var{pool_owner} is not NULL, then the metadata value will persist 56 | * until the specified function is finished building. Normally you would 57 | * set this to NULL. 58 | * 59 | * Metadata type values of 10000 or greater are reserved for internal use. 60 | * They should never be used by external user code. 61 | * @end deftypefun 62 | @*/ 63 | int jit_meta_set(jit_meta_t *list, int type, void *data, 64 | jit_meta_free_func free_data, jit_function_t pool_owner) 65 | { 66 | jit_meta_t current; 67 | 68 | /* See if we already have this type in the list */ 69 | current = *list; 70 | while(current != 0) 71 | { 72 | if(current->type == type) 73 | { 74 | if(data == current->data) 75 | { 76 | /* The value is unchanged, so don't free the previous value */ 77 | return 1; 78 | } 79 | if(current->free_data) 80 | { 81 | (*(current->free_data))(current->data); 82 | } 83 | current->data = data; 84 | current->free_data = free_data; 85 | return 1; 86 | } 87 | current = current->next; 88 | } 89 | 90 | /* Create a new metadata block and add it to the list */ 91 | if(pool_owner) 92 | { 93 | if((current = jit_memory_pool_alloc 94 | (&(pool_owner->builder->meta_pool), struct _jit_meta)) == 0) 95 | { 96 | return 0; 97 | } 98 | } 99 | else 100 | { 101 | if((current = jit_new(struct _jit_meta)) == 0) 102 | { 103 | return 0; 104 | } 105 | } 106 | current->type = type; 107 | current->data = data; 108 | current->free_data = free_data; 109 | current->next = *list; 110 | current->pool_owner = pool_owner; 111 | *list = current; 112 | return 1; 113 | } 114 | 115 | /*@ 116 | * @deftypefun {void *} jit_meta_get (jit_meta_t @var{list}, int @var{type}) 117 | * Get the value associated with @var{type} in the specified @var{list}. 118 | * Returns NULL if @var{type} is not present. 119 | * @end deftypefun 120 | @*/ 121 | void *jit_meta_get(jit_meta_t list, int type) 122 | { 123 | while(list != 0) 124 | { 125 | if(list->type == type) 126 | { 127 | return list->data; 128 | } 129 | list = list->next; 130 | } 131 | return 0; 132 | } 133 | 134 | /*@ 135 | * @deftypefun void jit_meta_free (jit_meta_t *@var{list}, int @var{type}) 136 | * Free the metadata value in the @var{list} that has the 137 | * specified @var{type}. Does nothing if the @var{type} 138 | * is not present. 139 | * @end deftypefun 140 | @*/ 141 | void jit_meta_free(jit_meta_t *list, int type) 142 | { 143 | jit_meta_t current = *list; 144 | jit_meta_t prev = 0; 145 | while(current != 0) 146 | { 147 | if(current->type == type) 148 | { 149 | if(current->free_data) 150 | { 151 | (*(current->free_data))(current->data); 152 | current->free_data = 0; 153 | } 154 | if(prev) 155 | { 156 | prev->next = current->next; 157 | } 158 | else 159 | { 160 | *list = current->next; 161 | } 162 | if(current->pool_owner) 163 | { 164 | jit_memory_pool_dealloc 165 | (&(current->pool_owner->builder->meta_pool), current); 166 | } 167 | else 168 | { 169 | jit_free(current); 170 | } 171 | return; 172 | } 173 | else 174 | { 175 | prev = current; 176 | current = current->next; 177 | } 178 | } 179 | } 180 | 181 | /*@ 182 | * @deftypefun void jit_meta_destroy (jit_meta_t *@var{list}) 183 | * Destroy all of the metadata values in the specified @var{list}. 184 | * @end deftypefun 185 | @*/ 186 | void jit_meta_destroy(jit_meta_t *list) 187 | { 188 | jit_meta_t current = *list; 189 | jit_meta_t next; 190 | while(current != 0) 191 | { 192 | next = current->next; 193 | if(current->free_data) 194 | { 195 | (*(current->free_data))(current->data); 196 | current->free_data = 0; 197 | } 198 | if(current->pool_owner) 199 | { 200 | jit_memory_pool_dealloc 201 | (&(current->pool_owner->builder->meta_pool), current); 202 | } 203 | else 204 | { 205 | jit_free(current); 206 | } 207 | current = next; 208 | } 209 | } 210 | 211 | void _jit_meta_free_one(void *meta) 212 | { 213 | jit_meta_t current = (jit_meta_t)meta; 214 | if(current->free_data) 215 | { 216 | (*(current->free_data))(current->data); 217 | } 218 | } 219 | -------------------------------------------------------------------------------- /internal/ccall/jit-pool.c: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-pool.c - Functions for managing memory pools. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * This file is part of the libjit library. 7 | * 8 | * The libjit library is free software: you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public License 10 | * as published by the Free Software Foundation, either version 2.1 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * The libjit library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with the libjit library. If not, see 20 | * . 21 | */ 22 | 23 | #include "jit-internal.h" 24 | 25 | void _jit_memory_pool_init(jit_memory_pool *pool, unsigned int elem_size) 26 | { 27 | pool->elem_size = elem_size; 28 | pool->elems_per_block = 4000 / elem_size; 29 | pool->elems_in_last = pool->elems_per_block; 30 | pool->blocks = 0; 31 | pool->free_list = 0; 32 | } 33 | 34 | void _jit_memory_pool_free(jit_memory_pool *pool, jit_meta_free_func func) 35 | { 36 | jit_pool_block_t block; 37 | while(pool->blocks != 0) 38 | { 39 | block = pool->blocks; 40 | pool->blocks = block->next; 41 | if(func) 42 | { 43 | while(pool->elems_in_last > 0) 44 | { 45 | --(pool->elems_in_last); 46 | (*func)(block->data + pool->elems_in_last * pool->elem_size); 47 | } 48 | } 49 | jit_free(block); 50 | pool->elems_in_last = pool->elems_per_block; 51 | } 52 | pool->free_list = 0; 53 | } 54 | 55 | void *_jit_memory_pool_alloc(jit_memory_pool *pool) 56 | { 57 | void *data; 58 | if(pool->free_list) 59 | { 60 | /* Reclaim an item that was previously deallocated */ 61 | data = pool->free_list; 62 | pool->free_list = *((void **)data); 63 | jit_memzero(data, pool->elem_size); 64 | return data; 65 | } 66 | if(pool->elems_in_last >= pool->elems_per_block) 67 | { 68 | data = (void *)jit_calloc(1, sizeof(struct jit_pool_block) + 69 | pool->elem_size * pool->elems_per_block - 1); 70 | if(!data) 71 | { 72 | return 0; 73 | } 74 | ((jit_pool_block_t)data)->next = pool->blocks; 75 | pool->blocks = (jit_pool_block_t)data; 76 | pool->elems_in_last = 0; 77 | } 78 | data = (void *)(pool->blocks->data + 79 | pool->elems_in_last * pool->elem_size); 80 | ++(pool->elems_in_last); 81 | return data; 82 | } 83 | 84 | void _jit_memory_pool_dealloc(jit_memory_pool *pool, void *item) 85 | { 86 | *((void **)item) = pool->free_list; 87 | pool->free_list = item; 88 | } 89 | -------------------------------------------------------------------------------- /internal/ccall/jit-reg-alloc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-reg-alloc.h - Register allocation routines for the JIT. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * This file is part of the libjit library. 7 | * 8 | * The libjit library is free software: you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public License 10 | * as published by the Free Software Foundation, either version 2.1 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * The libjit library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with the libjit library. If not, see 20 | * . 21 | */ 22 | 23 | #ifndef _JIT_REG_ALLOC_H 24 | #define _JIT_REG_ALLOC_H 25 | 26 | #include "jit-rules.h" 27 | #include "jit-reg-class.h" 28 | 29 | #ifdef __cplusplus 30 | extern "C" { 31 | #endif 32 | 33 | /* 34 | * The maximum number of values per instruction. 35 | */ 36 | #define _JIT_REGS_VALUE_MAX 3 37 | 38 | /* 39 | * The maximum number of temporaries per instruction. 40 | */ 41 | #define _JIT_REGS_SCRATCH_MAX 6 42 | 43 | /* 44 | * Flags for _jit_regs_init(). 45 | */ 46 | #define _JIT_REGS_TERNARY 0x0001 47 | #define _JIT_REGS_BRANCH 0x0002 48 | #define _JIT_REGS_COPY 0x0004 49 | #define _JIT_REGS_FREE_DEST 0x0008 50 | #define _JIT_REGS_COMMUTATIVE 0x0010 51 | #define _JIT_REGS_STACK 0x0020 52 | #define _JIT_REGS_X87_ARITH 0x0040 53 | #define _JIT_REGS_REVERSIBLE 0X0080 54 | 55 | /* 56 | * Flags for _jit_regs_init_dest(), _jit_regs_init_value1(), and 57 | * _jit_regs_init_value2(). 58 | */ 59 | #define _JIT_REGS_CLOBBER 0x0001 60 | #define _JIT_REGS_EARLY_CLOBBER 0x0002 61 | 62 | /* 63 | * Flags returned by _jit_regs_select_insn(). 64 | */ 65 | #define _JIT_REGS_NO_POP 0x0001 66 | #define _JIT_REGS_FLIP_ARGS 0x0002 67 | #define _JIT_REGS_REVERSE 0x0004 68 | 69 | /* 70 | * Contains register assignment data for single operand. 71 | */ 72 | typedef struct 73 | { 74 | jit_value_t value; 75 | int reg; 76 | int other_reg; 77 | int stack_reg; 78 | _jit_regclass_t *regclass; 79 | unsigned live : 1; 80 | unsigned used : 1; 81 | unsigned clobber : 1; 82 | unsigned early_clobber : 1; 83 | unsigned duplicate : 1; 84 | unsigned thrash : 1; 85 | unsigned store : 1; 86 | unsigned load : 1; 87 | unsigned copy : 1; 88 | unsigned kill : 1; 89 | 90 | } _jit_regdesc_t; 91 | 92 | /* 93 | * Contains scratch register assignment data. 94 | */ 95 | typedef struct 96 | { 97 | int reg; 98 | _jit_regclass_t *regclass; 99 | 100 | } _jit_scratch_t; 101 | 102 | /* 103 | * Contains register assignment data for instruction. 104 | */ 105 | typedef struct 106 | { 107 | _jit_regdesc_t descs[_JIT_REGS_VALUE_MAX]; 108 | _jit_scratch_t scratch[_JIT_REGS_SCRATCH_MAX]; 109 | int num_scratch; 110 | 111 | unsigned ternary : 1; 112 | unsigned branch : 1; 113 | unsigned copy : 1; 114 | unsigned commutative : 1; 115 | unsigned free_dest : 1; 116 | 117 | #ifdef JIT_REG_STACK 118 | unsigned on_stack : 1; 119 | unsigned x87_arith : 1; 120 | unsigned reversible : 1; 121 | 122 | unsigned no_pop : 1; 123 | unsigned flip_args : 1; 124 | #endif 125 | 126 | /* The input value index that is going to be overwritten 127 | by the destination value. For ordinary binary and unary 128 | opcodes it is equal to 1, for notes and three-address 129 | opcodes it is equal to 0, and for some x87 instructions 130 | it could be equal to 2. */ 131 | int dest_input_index; 132 | 133 | jit_regused_t assigned; 134 | jit_regused_t clobber; 135 | 136 | #ifdef JIT_REG_STACK 137 | int wanted_stack_count; 138 | int loaded_stack_count; 139 | #endif 140 | 141 | } _jit_regs_t; 142 | 143 | int _jit_regs_lookup(char *name); 144 | void _jit_regs_alloc_global(jit_gencode_t gen, jit_function_t func); 145 | void _jit_regs_init_for_block(jit_gencode_t gen); 146 | void _jit_regs_spill_all(jit_gencode_t gen); 147 | void _jit_regs_set_incoming(jit_gencode_t gen, int reg, jit_value_t value); 148 | void _jit_regs_set_outgoing(jit_gencode_t gen, int reg, jit_value_t value); 149 | void _jit_regs_clear_all_outgoing(jit_gencode_t gen); 150 | void _jit_regs_force_out(jit_gencode_t gen, jit_value_t value, int is_dest); 151 | int _jit_regs_load_value(jit_gencode_t gen, jit_value_t value, int destroy, int used_again); 152 | 153 | void _jit_regs_init(jit_gencode_t gen, _jit_regs_t *regs, int flags); 154 | 155 | void _jit_regs_init_dest(_jit_regs_t *regs, jit_insn_t insn, 156 | int flags, _jit_regclass_t *regclass); 157 | void _jit_regs_init_value1(_jit_regs_t *regs, jit_insn_t insn, 158 | int flags, _jit_regclass_t *regclass); 159 | void _jit_regs_init_value2(_jit_regs_t *regs, jit_insn_t insn, 160 | int flags, _jit_regclass_t *regclass); 161 | void _jit_regs_add_scratch(_jit_regs_t *regs, _jit_regclass_t *regclass); 162 | 163 | void _jit_regs_set_dest(jit_gencode_t gen, _jit_regs_t *regs, int reg, int other_reg); 164 | void _jit_regs_set_value1(jit_gencode_t gen, _jit_regs_t *regs, int reg, int other_reg); 165 | void _jit_regs_set_value2(jit_gencode_t gen, _jit_regs_t *regs, int reg, int other_reg); 166 | void _jit_regs_set_scratch(jit_gencode_t gen, _jit_regs_t *regs, int index, int reg); 167 | 168 | void _jit_regs_clobber(_jit_regs_t *regs, int reg); 169 | void _jit_regs_clobber_class(jit_gencode_t gen, _jit_regs_t *regs, _jit_regclass_t *regclass); 170 | void _jit_regs_clobber_all(jit_gencode_t gen, _jit_regs_t *regs); 171 | 172 | void _jit_regs_assign(jit_gencode_t gen, _jit_regs_t *regs); 173 | void _jit_regs_gen(jit_gencode_t gen, _jit_regs_t *regs); 174 | #ifdef JIT_REG_STACK 175 | int _jit_regs_select(_jit_regs_t *regs); 176 | #endif 177 | 178 | void _jit_regs_commit(jit_gencode_t gen, _jit_regs_t *regs); 179 | 180 | int _jit_regs_get_dest(_jit_regs_t *regs); 181 | int _jit_regs_get_value1(_jit_regs_t *regs); 182 | int _jit_regs_get_value2(_jit_regs_t *regs); 183 | int _jit_regs_get_dest_other(_jit_regs_t *regs); 184 | int _jit_regs_get_value1_other(_jit_regs_t *regs); 185 | int _jit_regs_get_value2_other(_jit_regs_t *regs); 186 | int _jit_regs_get_scratch(_jit_regs_t *regs, int index); 187 | 188 | void _jit_regs_begin(jit_gencode_t gen, _jit_regs_t *regs, int space); 189 | 190 | #ifdef __cplusplus 191 | }; 192 | #endif 193 | 194 | #endif /* _JIT_REG_ALLOC_H */ 195 | -------------------------------------------------------------------------------- /internal/ccall/jit-reg-class.c: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-reg-class.c - Register class routines for the JIT. 3 | * 4 | * Copyright (C) 2006 Southern Storm Software, Pty Ltd. 5 | * 6 | * This file is part of the libjit library. 7 | * 8 | * The libjit library is free software: you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public License 10 | * as published by the Free Software Foundation, either version 2.1 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * The libjit library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with the libjit library. If not, see 20 | * . 21 | */ 22 | 23 | #include "jit-internal.h" 24 | #include "jit-reg-class.h" 25 | #include 26 | 27 | _jit_regclass_t * 28 | _jit_regclass_create(const char *name, int flags, int num_regs, ...) 29 | { 30 | _jit_regclass_t *regclass; 31 | va_list args; 32 | int reg; 33 | 34 | regclass = jit_malloc(sizeof(_jit_regclass_t) + sizeof(int) * (num_regs - 1)); 35 | if(!regclass) 36 | { 37 | return 0; 38 | } 39 | regclass->name = name; 40 | regclass->flags = flags; 41 | regclass->num_regs = num_regs; 42 | 43 | va_start(args, num_regs); 44 | for(reg = 0; reg < num_regs; reg++) 45 | { 46 | regclass->regs[reg] = va_arg(args, int); 47 | } 48 | va_end(args); 49 | 50 | return regclass; 51 | } 52 | 53 | _jit_regclass_t * 54 | _jit_regclass_combine(const char *name, int flags, 55 | _jit_regclass_t *class1, 56 | _jit_regclass_t *class2) 57 | { 58 | _jit_regclass_t *regclass; 59 | int num_regs; 60 | 61 | num_regs = class1->num_regs + class2->num_regs; 62 | 63 | regclass = jit_malloc(sizeof(_jit_regclass_t) + sizeof(int) * (num_regs - 1)); 64 | if(!regclass) 65 | { 66 | return 0; 67 | } 68 | regclass->name = name; 69 | regclass->flags = flags; 70 | regclass->num_regs = num_regs; 71 | 72 | jit_memcpy(regclass->regs, class1->regs, sizeof(int) * class1->num_regs); 73 | jit_memcpy(regclass->regs + class1->num_regs, class2->regs, sizeof(int) * class2->num_regs); 74 | 75 | return regclass; 76 | } 77 | 78 | void 79 | _jit_regclass_free(_jit_regclass_t *regclass) 80 | { 81 | jit_free(regclass); 82 | } 83 | -------------------------------------------------------------------------------- /internal/ccall/jit-reg-class.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-reg-class.h - Register class routines for the JIT. 3 | * 4 | * Copyright (C) 2006 Southern Storm Software, Pty Ltd. 5 | * 6 | * This file is part of the libjit library. 7 | * 8 | * The libjit library is free software: you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public License 10 | * as published by the Free Software Foundation, either version 2.1 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * The libjit library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with the libjit library. If not, see 20 | * . 21 | */ 22 | 23 | #ifndef _JIT_REG_CLASS_H 24 | #define _JIT_REG_CLASS_H 25 | 26 | #include "jit-rules.h" 27 | 28 | #ifdef __cplusplus 29 | extern "C" { 30 | #endif 31 | 32 | /* 33 | * Information about a register class. 34 | */ 35 | typedef struct 36 | { 37 | const char *name; /* Name of the register class, for debugging */ 38 | int flags; /* Register flags */ 39 | int num_regs; /* The number of registers in the class */ 40 | int regs[1]; /* JIT_REG_INFO index for each register */ 41 | 42 | } _jit_regclass_t; 43 | 44 | /* Create a register class. */ 45 | _jit_regclass_t *_jit_regclass_create(const char *name, int flags, int num_regs, ...); 46 | 47 | /* Combine two register classes into another one. */ 48 | _jit_regclass_t *_jit_regclass_combine(const char *name, int flags, 49 | _jit_regclass_t *class1, 50 | _jit_regclass_t *class2); 51 | 52 | /* Free a register class. */ 53 | void _jit_regclass_free(_jit_regclass_t *regclass); 54 | 55 | #ifdef __cplusplus 56 | }; 57 | #endif 58 | 59 | #endif /* _JIT_REG_CLASS_H */ 60 | -------------------------------------------------------------------------------- /internal/ccall/jit-rules-interp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-rules-interp.h - Rules that define the interpreter characteristics. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * This file is part of the libjit library. 7 | * 8 | * The libjit library is free software: you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public License 10 | * as published by the Free Software Foundation, either version 2.1 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * The libjit library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with the libjit library. If not, see 20 | * . 21 | */ 22 | 23 | #ifndef _JIT_RULES_INTERP_H 24 | #define _JIT_RULES_INTERP_H 25 | 26 | #include "jit-interp.h" 27 | 28 | #ifdef __cplusplus 29 | extern "C" { 30 | #endif 31 | 32 | /* 33 | * Information about all of the registers, in allocation order. 34 | */ 35 | #define JIT_REG_INFO \ 36 | {"r0", 0, -1, JIT_REG_ALL | JIT_REG_CALL_USED}, \ 37 | {"r1", 1, -1, JIT_REG_ALL | JIT_REG_CALL_USED}, \ 38 | {"r2", 2, -1, JIT_REG_ALL | JIT_REG_CALL_USED}, 39 | #define JIT_NUM_REGS 3 40 | #define JIT_NUM_GLOBAL_REGS 0 41 | 42 | /* 43 | * Define to 1 if we should always load values into registers 44 | * before operating on them. i.e. the CPU does not have reg-mem 45 | * and mem-reg addressing modes. 46 | */ 47 | #define JIT_ALWAYS_REG_REG 1 48 | 49 | /* 50 | * The maximum number of bytes to allocate for the prolog. 51 | * This may be shortened once we know the true prolog size. 52 | */ 53 | #define JIT_PROLOG_SIZE jit_function_interp_size 54 | 55 | /* 56 | * Preferred alignment for the start of functions. 57 | */ 58 | #define JIT_FUNCTION_ALIGNMENT (sizeof(void *)) 59 | 60 | /* 61 | * Define this to 1 if the platform allows reads and writes on 62 | * any byte boundary. Define to 0 if only properly-aligned 63 | * memory accesses are allowed. 64 | */ 65 | #define JIT_ALIGN_OVERRIDES 0 66 | 67 | /* 68 | * Extra state information that is added to the "jit_gencode" structure. 69 | */ 70 | #define jit_extra_gen_state \ 71 | int working_area; \ 72 | int max_working_area; \ 73 | int extra_working_space 74 | #define jit_extra_gen_init(gen) \ 75 | do { \ 76 | (gen)->working_area = 0; \ 77 | (gen)->max_working_area = 0; \ 78 | (gen)->extra_working_space = 0; \ 79 | } while (0) 80 | #define jit_extra_gen_cleanup(gen) do { ; } while (0) 81 | 82 | #ifdef __cplusplus 83 | }; 84 | #endif 85 | 86 | #endif /* _JIT_RULES_INTERP_H */ 87 | -------------------------------------------------------------------------------- /internal/ccall/jit-rules-x86-64.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-rules-x86-64.h - Rules that define the characteristics of the x86_64. 3 | * 4 | * Copyright (C) 2008 Southern Storm Software, Pty Ltd. 5 | * 6 | * This file is part of the libjit library. 7 | * 8 | * The libjit library is free software: you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public License 10 | * as published by the Free Software Foundation, either version 2.1 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * The libjit library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with the libjit library. If not, see 20 | * . 21 | */ 22 | 23 | #ifndef _JIT_RULES_X86_64_H 24 | #define _JIT_RULES_X86_64_H 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | /* 31 | * Information about all of the registers, in allocation order. 32 | */ 33 | #define JIT_REG_X86_64_FLOAT \ 34 | (JIT_REG_FLOAT32 | JIT_REG_FLOAT64 | JIT_REG_NFLOAT) 35 | #define JIT_REG_X86_64_XMM \ 36 | (JIT_REG_FLOAT32 | JIT_REG_FLOAT64) 37 | #define JIT_REG_X86_64_GENERAL \ 38 | (JIT_REG_WORD | JIT_REG_LONG) 39 | #define JIT_REG_INFO \ 40 | {"rax", 0, -1, JIT_REG_X86_64_GENERAL | JIT_REG_CALL_USED}, \ 41 | {"rcx", 1, -1, JIT_REG_X86_64_GENERAL | JIT_REG_CALL_USED}, \ 42 | {"rdx", 2, -1, JIT_REG_X86_64_GENERAL | JIT_REG_CALL_USED}, \ 43 | {"rbx", 3, -1, JIT_REG_X86_64_GENERAL | JIT_REG_GLOBAL}, \ 44 | {"rsi", 6, -1, JIT_REG_X86_64_GENERAL | JIT_REG_CALL_USED}, \ 45 | {"rdi", 7, -1, JIT_REG_X86_64_GENERAL | JIT_REG_CALL_USED}, \ 46 | {"r8", 8, -1, JIT_REG_X86_64_GENERAL | JIT_REG_CALL_USED}, \ 47 | {"r9", 9, -1, JIT_REG_X86_64_GENERAL | JIT_REG_CALL_USED}, \ 48 | {"r10", 10, -1, JIT_REG_X86_64_GENERAL | JIT_REG_CALL_USED}, \ 49 | {"r11", 11, -1, JIT_REG_X86_64_GENERAL | JIT_REG_CALL_USED}, \ 50 | {"r12", 12, -1, JIT_REG_X86_64_GENERAL | JIT_REG_GLOBAL}, \ 51 | {"r13", 13, -1, JIT_REG_X86_64_GENERAL | JIT_REG_GLOBAL}, \ 52 | {"r14", 14, -1, JIT_REG_X86_64_GENERAL | JIT_REG_GLOBAL}, \ 53 | {"r15", 15, -1, JIT_REG_X86_64_GENERAL | JIT_REG_GLOBAL}, \ 54 | {"rbp", 5, -1, JIT_REG_FRAME | JIT_REG_FIXED | JIT_REG_CALL_USED}, \ 55 | {"rsp", 4, -1, JIT_REG_STACK_PTR | JIT_REG_FIXED | JIT_REG_CALL_USED}, \ 56 | {"xmm0", 0, -1, JIT_REG_X86_64_XMM | JIT_REG_CALL_USED}, \ 57 | {"xmm1", 1, -1, JIT_REG_X86_64_XMM | JIT_REG_CALL_USED}, \ 58 | {"xmm2", 2, -1, JIT_REG_X86_64_XMM | JIT_REG_CALL_USED}, \ 59 | {"xmm3", 3, -1, JIT_REG_X86_64_XMM | JIT_REG_CALL_USED}, \ 60 | {"xmm4", 4, -1, JIT_REG_X86_64_XMM | JIT_REG_CALL_USED}, \ 61 | {"xmm5", 5, -1, JIT_REG_X86_64_XMM | JIT_REG_CALL_USED}, \ 62 | {"xmm6", 6, -1, JIT_REG_X86_64_XMM | JIT_REG_CALL_USED}, \ 63 | {"xmm7", 7, -1, JIT_REG_X86_64_XMM | JIT_REG_CALL_USED}, \ 64 | {"xmm8", 8, -1, JIT_REG_X86_64_XMM | JIT_REG_CALL_USED}, \ 65 | {"xmm9", 9, -1, JIT_REG_X86_64_XMM | JIT_REG_CALL_USED}, \ 66 | {"xmm10", 10, -1, JIT_REG_X86_64_XMM | JIT_REG_CALL_USED}, \ 67 | {"xmm11", 11, -1, JIT_REG_X86_64_XMM | JIT_REG_CALL_USED}, \ 68 | {"xmm12", 12, -1, JIT_REG_X86_64_XMM | JIT_REG_CALL_USED}, \ 69 | {"xmm13", 13, -1, JIT_REG_X86_64_XMM | JIT_REG_CALL_USED}, \ 70 | {"xmm14", 14, -1, JIT_REG_X86_64_XMM | JIT_REG_CALL_USED}, \ 71 | {"xmm15", 15, -1, JIT_REG_X86_64_XMM | JIT_REG_CALL_USED}, \ 72 | {"st0", 0, -1, JIT_REG_X86_64_FLOAT | JIT_REG_CALL_USED | JIT_REG_IN_STACK}, \ 73 | {"st1", 1, -1, JIT_REG_X86_64_FLOAT | JIT_REG_CALL_USED | JIT_REG_IN_STACK}, \ 74 | {"st2", 2, -1, JIT_REG_X86_64_FLOAT | JIT_REG_CALL_USED | JIT_REG_IN_STACK}, \ 75 | {"st3", 3, -1, JIT_REG_X86_64_FLOAT | JIT_REG_CALL_USED | JIT_REG_IN_STACK}, \ 76 | {"st4", 4, -1, JIT_REG_X86_64_FLOAT | JIT_REG_CALL_USED | JIT_REG_IN_STACK}, \ 77 | {"st5", 5, -1, JIT_REG_X86_64_FLOAT | JIT_REG_CALL_USED | JIT_REG_IN_STACK}, \ 78 | {"st6", 6, -1, JIT_REG_X86_64_FLOAT | JIT_REG_CALL_USED | JIT_REG_IN_STACK}, \ 79 | {"st7", 7, -1, JIT_REG_X86_64_FLOAT | JIT_REG_CALL_USED | JIT_REG_IN_STACK}, 80 | #define JIT_NUM_REGS 40 81 | #define JIT_NUM_GLOBAL_REGS 5 82 | 83 | #define JIT_REG_STACK 1 84 | #define JIT_REG_STACK_START 32 85 | #define JIT_REG_STACK_END 39 86 | 87 | /* 88 | * Define to 1 if we should always load values into registers 89 | * before operating on them. i.e. the CPU does not have reg-mem 90 | * and mem-reg addressing modes. 91 | */ 92 | #define JIT_ALWAYS_REG_REG 0 93 | 94 | /* 95 | * The maximum number of bytes to allocate for the prolog. 96 | * This may be shortened once we know the true prolog size. 97 | */ 98 | #define JIT_PROLOG_SIZE 64 99 | 100 | /* 101 | * Preferred alignment for the start of functions. 102 | */ 103 | #define JIT_FUNCTION_ALIGNMENT 32 104 | 105 | /* 106 | * Define this to 1 if the platform allows reads and writes on 107 | * any byte boundary. Define to 0 if only properly-aligned 108 | * memory accesses are allowed. 109 | */ 110 | #define JIT_ALIGN_OVERRIDES 1 111 | 112 | /* 113 | * Extra state information that is added to the "jit_gencode" structure. 114 | */ 115 | 116 | #define jit_extra_gen_state \ 117 | void *alloca_fixup 118 | 119 | #define jit_extra_gen_init(gen) \ 120 | do { \ 121 | (gen)->alloca_fixup = 0; \ 122 | } while (0) 123 | 124 | #define jit_extra_gen_cleanup(gen) do { ; } while (0) 125 | 126 | /* 127 | * Parameter passing rules. 128 | */ 129 | #define JIT_INITIAL_STACK_OFFSET (2 * sizeof(void *)) 130 | #define JIT_INITIAL_FRAME_SIZE 0 131 | 132 | /* 133 | * We are using the param area on x86_64 134 | */ 135 | #define JIT_USE_PARAM_AREA 136 | 137 | #ifdef __cplusplus 138 | }; 139 | #endif 140 | 141 | #endif /* _JIT_RULES_X86_64_H */ 142 | -------------------------------------------------------------------------------- /internal/ccall/jit-rules-x86.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-rules-x86.h - Rules that define the characteristics of the x86. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * This file is part of the libjit library. 7 | * 8 | * The libjit library is free software: you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public License 10 | * as published by the Free Software Foundation, either version 2.1 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * The libjit library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with the libjit library. If not, see 20 | * . 21 | */ 22 | 23 | #ifndef _JIT_RULES_X86_H 24 | #define _JIT_RULES_X86_H 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | /* 31 | * Information about all of the registers, in allocation order. 32 | */ 33 | #define JIT_REG_X86_FLOAT \ 34 | (JIT_REG_FLOAT32 | JIT_REG_FLOAT64 | JIT_REG_NFLOAT) 35 | #define JIT_REG_INFO \ 36 | {"eax", 0, 2, JIT_REG_WORD | JIT_REG_LONG | JIT_REG_CALL_USED}, \ 37 | {"ecx", 1, 3, JIT_REG_WORD | JIT_REG_LONG | JIT_REG_CALL_USED}, \ 38 | {"edx", 2, -1, JIT_REG_WORD | JIT_REG_CALL_USED}, \ 39 | {"ebx", 3, -1, JIT_REG_WORD | JIT_REG_GLOBAL}, \ 40 | {"esi", 6, -1, JIT_REG_WORD | JIT_REG_GLOBAL}, \ 41 | {"edi", 7, -1, JIT_REG_WORD | JIT_REG_GLOBAL}, \ 42 | {"ebp", 4, -1, JIT_REG_FRAME | JIT_REG_FIXED}, \ 43 | {"esp", 5, -1, JIT_REG_STACK_PTR | JIT_REG_FIXED | JIT_REG_CALL_USED}, \ 44 | {"st", 0, -1, JIT_REG_X86_FLOAT | JIT_REG_CALL_USED | JIT_REG_IN_STACK}, \ 45 | {"st1", 1, -1, JIT_REG_X86_FLOAT | JIT_REG_CALL_USED | JIT_REG_IN_STACK}, \ 46 | {"st2", 2, -1, JIT_REG_X86_FLOAT | JIT_REG_CALL_USED | JIT_REG_IN_STACK}, \ 47 | {"st3", 3, -1, JIT_REG_X86_FLOAT | JIT_REG_CALL_USED | JIT_REG_IN_STACK}, \ 48 | {"st4", 4, -1, JIT_REG_X86_FLOAT | JIT_REG_CALL_USED | JIT_REG_IN_STACK}, \ 49 | {"st5", 5, -1, JIT_REG_X86_FLOAT | JIT_REG_CALL_USED | JIT_REG_IN_STACK}, \ 50 | {"st6", 6, -1, JIT_REG_X86_FLOAT | JIT_REG_CALL_USED | JIT_REG_IN_STACK}, \ 51 | {"st7", 7, -1, JIT_REG_X86_FLOAT | JIT_REG_CALL_USED | JIT_REG_IN_STACK}, 52 | #define JIT_NUM_REGS 16 53 | #define JIT_NUM_GLOBAL_REGS 3 54 | 55 | #define JIT_REG_STACK 1 56 | #define JIT_REG_STACK_START 8 57 | #define JIT_REG_STACK_END 15 58 | 59 | /* 60 | * Define to 1 if we should always load values into registers 61 | * before operating on them. i.e. the CPU does not have reg-mem 62 | * and mem-reg addressing modes. 63 | */ 64 | #define JIT_ALWAYS_REG_REG 0 65 | 66 | /* 67 | * The maximum number of bytes to allocate for the prolog. 68 | * This may be shortened once we know the true prolog size. 69 | */ 70 | #define JIT_PROLOG_SIZE 32 71 | 72 | /* 73 | * Preferred alignment for the start of functions. 74 | */ 75 | #define JIT_FUNCTION_ALIGNMENT 32 76 | 77 | /* 78 | * Define this to 1 if the platform allows reads and writes on 79 | * any byte boundary. Define to 0 if only properly-aligned 80 | * memory accesses are allowed. 81 | */ 82 | #define JIT_ALIGN_OVERRIDES 1 83 | 84 | /* 85 | * Parameter passing rules. 86 | */ 87 | #define JIT_CDECL_WORD_REG_PARAMS {-1} 88 | #define JIT_FASTCALL_WORD_REG_PARAMS {1, 2, -1} /* ecx, edx */ 89 | #define JIT_MAX_WORD_REG_PARAMS 2 90 | #define JIT_INITIAL_STACK_OFFSET (2 * sizeof(void *)) 91 | #define JIT_INITIAL_FRAME_SIZE 0 92 | 93 | #ifdef __cplusplus 94 | }; 95 | #endif 96 | 97 | #endif /* _JIT_RULES_X86_H */ 98 | -------------------------------------------------------------------------------- /internal/ccall/jit-setjmp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-setjmp.h - Support definitions that use "setjmp" for exceptions. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * This file is part of the libjit library. 7 | * 8 | * The libjit library is free software: you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public License 10 | * as published by the Free Software Foundation, either version 2.1 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * The libjit library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with the libjit library. If not, see 20 | * . 21 | */ 22 | 23 | #ifndef _JIT_SETJMP_H 24 | #define _JIT_SETJMP_H 25 | 26 | #include 27 | 28 | #ifdef __cplusplus 29 | extern "C" { 30 | #endif 31 | 32 | /* 33 | * Jump buffer structure, with link. 34 | */ 35 | typedef struct jit_jmp_buf 36 | { 37 | jmp_buf buf; 38 | jit_backtrace_t trace; 39 | void *catch_pc; 40 | struct jit_jmp_buf *parent; 41 | 42 | } jit_jmp_buf; 43 | #define jit_jmp_catch_pc_offset \ 44 | ((jit_nint)&(((jit_jmp_buf *)0)->catch_pc)) 45 | 46 | /* 47 | * Push a "setjmp" buffer onto the current thread's unwind stck. 48 | */ 49 | void _jit_unwind_push_setjmp(jit_jmp_buf *jbuf); 50 | 51 | /* 52 | * Pop the top-most "setjmp" buffer from the current thread's unwind stack. 53 | */ 54 | void _jit_unwind_pop_setjmp(void); 55 | 56 | /* 57 | * Pop the top-most "setjmp" buffer and rethrow the current exception. 58 | */ 59 | void _jit_unwind_pop_and_rethrow(void); 60 | 61 | #ifdef __cplusplus 62 | }; 63 | #endif 64 | 65 | #endif /* _JIT_SETJMP_H */ 66 | -------------------------------------------------------------------------------- /internal/ccall/jit-signal.c: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-signal.c - Internal management routines to use Operating System 3 | * signals for libjit exceptions handling. 4 | * 5 | * Copyright (C) 2006 Southern Storm Software, Pty Ltd. 6 | * 7 | * This file is part of the libjit library. 8 | * 9 | * The libjit library is free software: you can redistribute it and/or 10 | * modify it under the terms of the GNU Lesser General Public License 11 | * as published by the Free Software Foundation, either version 2.1 of 12 | * the License, or (at your option) any later version. 13 | * 14 | * The libjit library is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * Lesser General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU Lesser General Public 20 | * License along with the libjit library. If not, see 21 | * . 22 | */ 23 | 24 | #include "jit-internal.h" 25 | 26 | #ifdef JIT_USE_SIGNALS 27 | 28 | #include 29 | #include 30 | #include 31 | 32 | /* 33 | * Use SIGSEGV for builtin libjit exception. 34 | */ 35 | static void sigsegv_handler(int signum, siginfo_t *info, void *uap) 36 | { 37 | jit_exception_builtin(JIT_RESULT_NULL_REFERENCE); 38 | } 39 | 40 | /* 41 | * Use SIGFPE for builtin libjit exception. 42 | */ 43 | static void sigfpe_handler(int signum, siginfo_t *info, void *uap) 44 | { 45 | switch(info->si_code) 46 | { 47 | case FPE_INTDIV: 48 | jit_exception_builtin(JIT_RESULT_DIVISION_BY_ZERO); 49 | break; 50 | case FPE_INTOVF: 51 | jit_exception_builtin(JIT_RESULT_OVERFLOW); 52 | break; 53 | case FPE_FLTDIV: 54 | jit_exception_builtin(JIT_RESULT_DIVISION_BY_ZERO); 55 | break; 56 | case FPE_FLTOVF: 57 | jit_exception_builtin(JIT_RESULT_OVERFLOW); 58 | break; 59 | case FPE_FLTUND: 60 | jit_exception_builtin(JIT_RESULT_ARITHMETIC); 61 | break; 62 | case FPE_FLTSUB: 63 | jit_exception_builtin(JIT_RESULT_ARITHMETIC); 64 | break; 65 | default: 66 | jit_exception_builtin(JIT_RESULT_ARITHMETIC); 67 | break; 68 | } 69 | } 70 | 71 | /* 72 | * Initialize signal handlers. 73 | */ 74 | void _jit_signal_init(void) 75 | { 76 | struct sigaction sa_fpe, sa_segv; 77 | 78 | sa_fpe.sa_sigaction = sigfpe_handler; 79 | sigemptyset(&sa_fpe.sa_mask); 80 | sa_fpe.sa_flags = SA_SIGINFO; 81 | if (sigaction(SIGFPE, &sa_fpe, 0)) { 82 | perror("Sigaction SIGFPE"); 83 | exit(1); 84 | } 85 | 86 | sa_segv.sa_sigaction = sigsegv_handler; 87 | sigemptyset(&sa_segv.sa_mask); 88 | sa_segv.sa_flags = SA_SIGINFO; 89 | if (sigaction(SIGSEGV, &sa_segv, 0)) { 90 | perror("Sigaction SIGSEGV"); 91 | exit(1); 92 | } 93 | } 94 | 95 | #endif /* JIT_USE_SIGNALS */ 96 | -------------------------------------------------------------------------------- /internal/ccall/jit-thread.c: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-thread.c - Internal thread management routines for libjit. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * This file is part of the libjit library. 7 | * 8 | * The libjit library is free software: you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public License 10 | * as published by the Free Software Foundation, either version 2.1 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * The libjit library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with the libjit library. If not, see 20 | * . 21 | */ 22 | 23 | #include "jit-internal.h" 24 | 25 | #if TIME_WITH_SYS_TIME 26 | # include 27 | # include 28 | #else 29 | # if HAVE_SYS_TIME_H 30 | # include 31 | # elif !defined(__palmos__) 32 | # include 33 | # endif 34 | #endif 35 | #ifdef HAVE_SYS_TYPES_H 36 | # include 37 | #endif 38 | #include 39 | 40 | /* 41 | * Mutex that synchronizes global data initialization. 42 | */ 43 | jit_mutex_t _jit_global_lock; 44 | 45 | #if defined(JIT_THREADS_PTHREAD) 46 | 47 | /* 48 | * The thread-specific key to use to fetch the control object. 49 | */ 50 | static pthread_key_t control_key; 51 | 52 | /* 53 | * Initialize the pthread support routines. Only called once. 54 | */ 55 | static void init_pthread(void) 56 | { 57 | jit_mutex_create(&_jit_global_lock); 58 | 59 | /* Allocate a thread-specific variable for the JIT's thread 60 | control object, and arrange for it to be freed when the 61 | thread exits or is otherwise terminated */ 62 | pthread_key_create(&control_key, jit_free); 63 | } 64 | 65 | #elif defined(JIT_THREADS_WIN32) 66 | 67 | /* 68 | * The thread-specific key to use to fetch the control object. 69 | */ 70 | static DWORD control_key; 71 | 72 | /* 73 | * Initialize the Win32 thread support routines. Only called once. 74 | */ 75 | static void init_win32_thread(void) 76 | { 77 | jit_mutex_create(&_jit_global_lock); 78 | 79 | control_key = TlsAlloc(); 80 | } 81 | 82 | jit_thread_id_t _jit_thread_self(void) 83 | { 84 | HANDLE new_handle; 85 | DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), 86 | GetCurrentProcess(), &new_handle, 87 | 0, 0, DUPLICATE_SAME_ACCESS); 88 | return new_handle; 89 | } 90 | 91 | #else /* No thread package */ 92 | 93 | /* 94 | * The control object for the only thread in the system. 95 | */ 96 | static void *control_object = 0; 97 | 98 | #endif /* No thread package */ 99 | 100 | void _jit_thread_init(void) 101 | { 102 | #if defined(JIT_THREADS_PTHREAD) 103 | static pthread_once_t once_control = PTHREAD_ONCE_INIT; 104 | pthread_once(&once_control, init_pthread); 105 | #elif defined(JIT_THREADS_WIN32) 106 | static LONG volatile once_control = 0; 107 | switch(InterlockedCompareExchange(&once_control, 1, 0)) 108 | { 109 | case 0: 110 | init_win32_thread(); 111 | InterlockedExchange(&once_control, 2); 112 | break; 113 | case 1: 114 | while(InterlockedCompareExchange(&once_control, 2, 2) != 2) 115 | { 116 | } 117 | break; 118 | } 119 | #endif 120 | } 121 | 122 | static void *get_raw_control(void) 123 | { 124 | _jit_thread_init(); 125 | #if defined(JIT_THREADS_PTHREAD) 126 | return pthread_getspecific(control_key); 127 | #elif defined(JIT_THREADS_WIN32) 128 | return (void *)(TlsGetValue(control_key)); 129 | #else 130 | return control_object; 131 | #endif 132 | } 133 | 134 | static void set_raw_control(void *obj) 135 | { 136 | _jit_thread_init(); 137 | #if defined(JIT_THREADS_PTHREAD) 138 | pthread_setspecific(control_key, obj); 139 | #elif defined(JIT_THREADS_WIN32) 140 | TlsSetValue(control_key, obj); 141 | #else 142 | control_object = obj; 143 | #endif 144 | } 145 | 146 | jit_thread_control_t _jit_thread_get_control(void) 147 | { 148 | jit_thread_control_t control; 149 | control = (jit_thread_control_t)get_raw_control(); 150 | if(!control) 151 | { 152 | control = jit_cnew(struct jit_thread_control); 153 | if(control) 154 | { 155 | set_raw_control(control); 156 | } 157 | } 158 | return control; 159 | } 160 | 161 | jit_thread_id_t _jit_thread_current_id(void) 162 | { 163 | #if defined(JIT_THREADS_PTHREAD) 164 | return pthread_self(); 165 | #elif defined(JIT_THREADS_WIN32) 166 | return GetCurrentThread(); 167 | #else 168 | /* There is only one thread, so lets give it an identifier of 1 */ 169 | return 1; 170 | #endif 171 | } 172 | 173 | int _jit_monitor_wait(jit_monitor_t *mon, jit_int timeout) 174 | { 175 | #if defined(JIT_THREADS_PTHREAD) 176 | if(timeout < 0) 177 | { 178 | pthread_cond_wait(&(mon->_cond), &(mon->_mutex)); 179 | return 1; 180 | } 181 | else 182 | { 183 | struct timeval tv; 184 | struct timespec ts; 185 | int result; 186 | 187 | gettimeofday(&tv, 0); 188 | ts.tv_sec = tv.tv_sec + (long)(timeout / 1000); 189 | ts.tv_nsec = (tv.tv_usec + (long)((timeout % 1000) * 1000)) * 1000L; 190 | if(ts.tv_nsec >= 1000000000L) 191 | { 192 | ++(ts.tv_sec); 193 | ts.tv_nsec -= 1000000000L; 194 | } 195 | 196 | /* Wait until we are signalled or the timeout expires */ 197 | do 198 | { 199 | result = pthread_cond_timedwait(&(mon->_cond), &(mon->_mutex), &ts); 200 | } 201 | while(result == EINTR); 202 | return ((result == 0) ? 1 : 0); 203 | } 204 | #elif defined(JIT_THREADS_WIN32) 205 | DWORD result; 206 | ++(mon->_waiting); 207 | if(timeout >= 0) 208 | { 209 | result = SignalObjectAndWait(mon->_mutex, mon->_cond, (DWORD)timeout, FALSE); 210 | } 211 | else 212 | { 213 | result = SignalObjectAndWait(mon->_mutex, mon->_cond, INFINITE, FALSE); 214 | } 215 | WaitForSingleObject(mon->_mutex, INFINITE); 216 | return (result == WAIT_OBJECT_0); 217 | #else 218 | return 0; 219 | #endif 220 | } 221 | -------------------------------------------------------------------------------- /internal/ccall/jit-thread.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-thread.h - Internal thread management routines for libjit. 3 | * 4 | * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 | * 6 | * This file is part of the libjit library. 7 | * 8 | * The libjit library is free software: you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public License 10 | * as published by the Free Software Foundation, either version 2.1 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * The libjit library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with the libjit library. If not, see 20 | * . 21 | */ 22 | 23 | #ifndef _JIT_THREAD_H 24 | #define _JIT_THREAD_H 25 | 26 | #include 27 | #include "jit-config.h" 28 | 29 | #if defined(JIT_THREADS_PTHREAD) 30 | # include 31 | #elif defined(JIT_THREADS_WIN32) 32 | # include 33 | #endif 34 | 35 | #ifdef __cplusplus 36 | extern "C" { 37 | #endif 38 | 39 | /* 40 | * Type that describes a thread's identifier, and the id comparison function. 41 | */ 42 | #if defined(JIT_THREADS_PTHREAD) 43 | typedef pthread_t jit_thread_id_t; 44 | #define jit_thread_id_equal(x,y) (pthread_equal((x), (y))) 45 | #define jit_thread_self() (pthread_self()) 46 | #define jit_thread_release_self(t) do { ; } while (0) 47 | #elif defined(JIT_THREADS_WIN32) 48 | typedef HANDLE jit_thread_id_t; 49 | #define jit_thread_id_equal(x,y) ((x) == (y)) 50 | jit_thread_id_t _jit_thread_self(void); 51 | #define jit_thread_self() _jit_thread_self() 52 | #define jit_thread_release_self(t) CloseHandle((t)) 53 | #else 54 | typedef int jit_thread_id_t; 55 | #define jit_thread_id_equal(x,y) ((x) == (y)) 56 | #define jit_thread_self() 1 57 | #define jit_thread_release_self(t) do { ; } while (0) 58 | #endif 59 | 60 | /* 61 | * Control information that is associated with a thread. 62 | */ 63 | typedef struct jit_thread_control *jit_thread_control_t; 64 | 65 | /* 66 | * Initialize the thread routines. Ignored if called multiple times. 67 | */ 68 | void _jit_thread_init(void); 69 | 70 | /* 71 | * Get the JIT control object for the current thread. 72 | */ 73 | jit_thread_control_t _jit_thread_get_control(void); 74 | 75 | /* 76 | * Get the identifier for the current thread. 77 | */ 78 | jit_thread_id_t _jit_thread_current_id(void); 79 | 80 | /* 81 | * Define the primitive mutex operations. 82 | */ 83 | #if defined(JIT_THREADS_PTHREAD) 84 | 85 | typedef pthread_mutex_t jit_mutex_t; 86 | #define jit_mutex_create(mutex) (pthread_mutex_init((mutex), 0)) 87 | #define jit_mutex_destroy(mutex) (pthread_mutex_destroy((mutex))) 88 | #define jit_mutex_lock(mutex) (pthread_mutex_lock((mutex))) 89 | #define jit_mutex_unlock(mutex) (pthread_mutex_unlock((mutex))) 90 | 91 | #elif defined(JIT_THREADS_WIN32) 92 | 93 | typedef CRITICAL_SECTION jit_mutex_t; 94 | #define jit_mutex_create(mutex) (InitializeCriticalSection((mutex))) 95 | #define jit_mutex_destroy(mutex) (DeleteCriticalSection((mutex))) 96 | #define jit_mutex_lock(mutex) (EnterCriticalSection((mutex))) 97 | #define jit_mutex_unlock(mutex) (LeaveCriticalSection((mutex))) 98 | 99 | #else 100 | 101 | typedef int jit_mutex_t; 102 | #define jit_mutex_create(mutex) do { ; } while (0) 103 | #define jit_mutex_destroy(mutex) do { ; } while (0) 104 | #define jit_mutex_lock(mutex) do { ; } while (0) 105 | #define jit_mutex_unlock(mutex) do { ; } while (0) 106 | 107 | #endif 108 | 109 | /* 110 | * Mutex that synchronizes global data initialization. 111 | */ 112 | extern jit_mutex_t _jit_global_lock; 113 | 114 | /* 115 | * Define the primitive monitor operations. 116 | */ 117 | 118 | #if defined(JIT_THREADS_PTHREAD) 119 | 120 | typedef struct 121 | { 122 | pthread_mutex_t _mutex; 123 | pthread_cond_t _cond; 124 | 125 | } jit_monitor_t; 126 | #define jit_monitor_create(mon) \ 127 | do { \ 128 | pthread_mutex_init(&((mon)->_mutex), 0); \ 129 | pthread_cond_init(&((mon)->_cond), 0); \ 130 | } while (0) 131 | #define jit_monitor_destroy(mon) \ 132 | do { \ 133 | pthread_cond_destroy(&((mon)->_cond)); \ 134 | pthread_mutex_destroy(&((mon)->_mutex)); \ 135 | } while (0) 136 | #define jit_monitor_lock(mon) \ 137 | do { \ 138 | pthread_mutex_lock(&((mon)->_mutex)); \ 139 | } while (0) 140 | #define jit_monitor_unlock(mon) \ 141 | do { \ 142 | pthread_mutex_unlock(&((mon)->_mutex)); \ 143 | } while (0) 144 | #define jit_monitor_signal(mon) \ 145 | do { \ 146 | pthread_cond_signal(&((mon)->_cond)); \ 147 | } while (0) 148 | #define jit_monitor_signal_all(mon) \ 149 | do { \ 150 | pthread_cond_broadcast(&((mon)->_cond)); \ 151 | } while (0) 152 | 153 | #elif defined(JIT_THREADS_WIN32) 154 | 155 | typedef struct 156 | { 157 | HANDLE _mutex; 158 | HANDLE _cond; 159 | LONG volatile _waiting; 160 | } jit_monitor_t; 161 | #define jit_monitor_create(mon) \ 162 | do { \ 163 | (mon)->_mutex = CreateMutex(NULL, FALSE, NULL); \ 164 | (mon)->_cond = CreateSemaphore(NULL, 0, 0x7FFFFFFF, NULL); \ 165 | (mon)->_waiting = 0; \ 166 | } while (0) 167 | #define jit_monitor_destroy(mon) \ 168 | do { \ 169 | CloseHandle((mon)->_cond); \ 170 | CloseHandle((mon)->_mutex); \ 171 | } while (0) 172 | #define jit_monitor_lock(mon) \ 173 | do { \ 174 | WaitForSingleObject((mon)->_mutex, INFINITE); \ 175 | } while (0) 176 | #define jit_monitor_unlock(mon) \ 177 | do { \ 178 | ReleaseMutex((mon)->_mutex); \ 179 | } while (0) 180 | #define jit_monitor_signal(mon) \ 181 | do { \ 182 | if((mon)->_waiting > 0) \ 183 | { \ 184 | --((mon)->_waiting); \ 185 | ReleaseSemaphore((mon)->_cond, 1, NULL); \ 186 | } \ 187 | } while (0) 188 | #define jit_monitor_signal_all(mon) \ 189 | do { \ 190 | LONG _count = (mon)->_waiting; \ 191 | if(_count > 0) \ 192 | { \ 193 | (mon)->_waiting = 0; \ 194 | ReleaseSemaphore((mon)->_cond, _count, NULL); \ 195 | } \ 196 | } while (0) 197 | 198 | #else 199 | 200 | typedef int jit_monitor_t; 201 | #define jit_monitor_create(mon) do { ; } while (0) 202 | #define jit_monitor_destroy(mon) do { ; } while (0) 203 | #define jit_monitor_lock(mon) do { ; } while (0) 204 | #define jit_monitor_unlock(mon) do { ; } while (0) 205 | #define jit_monitor_signal(mon) do { ; } while (0) 206 | #define jit_monitor_signal_all(mon) do { ; } while (0) 207 | 208 | #endif 209 | int _jit_monitor_wait(jit_monitor_t *mon, jit_int timeout); 210 | #define jit_monitor_wait(mon,timeout) _jit_monitor_wait((mon), (timeout)) 211 | 212 | #ifdef __cplusplus 213 | }; 214 | #endif 215 | 216 | #endif /* _JIT_THREAD_H */ 217 | -------------------------------------------------------------------------------- /internal/ccall/jit-unwind.c: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-unwind.c - Routines for performing stack unwinding. 3 | * 4 | * Copyright (C) 2008 Southern Storm Software, Pty Ltd. 5 | * 6 | * This file is part of the libjit library. 7 | * 8 | * The libjit library is free software: you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public License 10 | * as published by the Free Software Foundation, either version 2.1 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * The libjit library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with the libjit library. If not, see 20 | * . 21 | */ 22 | 23 | #include "jit-internal.h" 24 | #include "jit-rules.h" 25 | #include "jit-apply-rules.h" 26 | #include 27 | #include 28 | 29 | int 30 | jit_unwind_init(jit_unwind_context_t *unwind, jit_context_t context) 31 | { 32 | #if defined(JIT_BACKEND_INTERP) || JIT_APPLY_BROKEN_FRAME_BUILTINS != 0 33 | jit_thread_control_t control; 34 | 35 | control = _jit_thread_get_control(); 36 | if(!control) 37 | { 38 | return 0; 39 | } 40 | 41 | unwind->frame = control->backtrace_head; 42 | #elif JIT_FAST_GET_CURRENT_FRAME != 0 43 | unwind->frame = jit_get_next_frame_address(jit_get_current_frame()); 44 | #else 45 | unwind->frame = jit_get_frame_address(1); 46 | #endif 47 | 48 | unwind->context = context; 49 | unwind->cache = 0; 50 | 51 | #ifdef _JIT_ARCH_UNWIND_INIT 52 | _JIT_ARCH_UNWIND_INIT(unwind); 53 | #endif 54 | 55 | return (unwind->frame != 0); 56 | } 57 | 58 | void 59 | jit_unwind_free(jit_unwind_context_t *unwind) 60 | { 61 | #ifdef _JIT_ARCH_UNWIND_FREE 62 | _JIT_ARCH_UNWIND_FREE(unwind); 63 | #endif 64 | } 65 | 66 | int 67 | jit_unwind_next(jit_unwind_context_t *unwind) 68 | { 69 | #if defined(_JIT_ARCH_UNWIND_NEXT) || defined(_JIT_ARCH_UNWIND_NEXT_PRE) 70 | jit_function_t func; 71 | #endif 72 | 73 | if(!unwind || !unwind->frame) 74 | { 75 | return 0; 76 | } 77 | 78 | unwind->cache = 0; 79 | 80 | #if defined(JIT_BACKEND_INTERP) || JIT_APPLY_BROKEN_FRAME_BUILTINS != 0 81 | unwind->frame = ((jit_backtrace_t) unwind->frame)->parent; 82 | return (unwind->frame != 0); 83 | #else 84 | 85 | #ifdef _JIT_ARCH_UNWIND_NEXT_PRE 86 | func = jit_unwind_get_function(unwind); 87 | if(func) 88 | { 89 | _JIT_ARCH_UNWIND_NEXT_PRE(unwind, func); 90 | } 91 | #endif 92 | 93 | unwind->frame = jit_get_next_frame_address(unwind->frame); 94 | if(!unwind->frame) 95 | { 96 | return 0; 97 | } 98 | 99 | #ifdef _JIT_ARCH_UNWIND_NEXT 100 | func = jit_unwind_get_function(unwind); 101 | if(func) 102 | { 103 | _JIT_ARCH_UNWIND_NEXT(unwind, func); 104 | } 105 | #endif 106 | 107 | return 1; 108 | #endif 109 | } 110 | 111 | int 112 | jit_unwind_next_pc(jit_unwind_context_t *unwind) 113 | { 114 | void *next; 115 | 116 | if(!unwind || !unwind->frame) 117 | { 118 | return 0; 119 | } 120 | 121 | unwind->cache = 0; 122 | 123 | #if defined(JIT_BACKEND_INTERP) || JIT_APPLY_BROKEN_FRAME_BUILTINS != 0 124 | next = ((jit_backtrace_t) unwind->frame)->parent; 125 | #else 126 | next = jit_get_next_frame_address(unwind->frame); 127 | #endif 128 | 129 | if(next <= unwind->frame) 130 | { 131 | unwind->frame = 0; 132 | } 133 | else 134 | { 135 | unwind->frame = next; 136 | } 137 | return (unwind->frame != 0); 138 | } 139 | 140 | void * 141 | jit_unwind_get_pc(jit_unwind_context_t *unwind) 142 | { 143 | if(!unwind || !unwind->frame) 144 | { 145 | return 0; 146 | } 147 | 148 | #if defined(JIT_BACKEND_INTERP) || JIT_APPLY_BROKEN_FRAME_BUILTINS != 0 149 | return ((jit_backtrace_t) unwind->frame)->pc; 150 | #else 151 | return jit_get_return_address(unwind->frame); 152 | #endif 153 | } 154 | 155 | int 156 | jit_unwind_jump(jit_unwind_context_t *unwind, void *pc) 157 | { 158 | #ifdef _JIT_ARCH_UNWIND_JUMP 159 | if(!unwind || !unwind->frame || !pc) 160 | { 161 | return 0; 162 | } 163 | 164 | return _JIT_ARCH_UNWIND_JUMP(unwind, pc); 165 | #else 166 | return 0; 167 | #endif 168 | } 169 | 170 | jit_function_t 171 | jit_unwind_get_function(jit_unwind_context_t *unwind) 172 | { 173 | if(!unwind || !unwind->frame || !unwind->context) 174 | { 175 | return 0; 176 | } 177 | 178 | if(!unwind->cache) 179 | { 180 | void *pc = jit_unwind_get_pc(unwind); 181 | unwind->cache = _jit_memory_find_function_info(unwind->context, pc); 182 | } 183 | 184 | return _jit_memory_get_function(unwind->context, unwind->cache); 185 | } 186 | 187 | unsigned int 188 | jit_unwind_get_offset(jit_unwind_context_t *unwind) 189 | { 190 | void *pc; 191 | jit_function_t func; 192 | 193 | if(!unwind || !unwind->frame || !unwind->context) 194 | { 195 | return JIT_NO_OFFSET; 196 | } 197 | 198 | pc = jit_unwind_get_pc(unwind); 199 | if(!pc) 200 | { 201 | return JIT_NO_OFFSET; 202 | } 203 | 204 | if(!unwind->cache) 205 | { 206 | unwind->cache = _jit_memory_find_function_info(unwind->context, pc); 207 | } 208 | func = _jit_memory_get_function(unwind->context, unwind->cache); 209 | if(!func) 210 | { 211 | return JIT_NO_OFFSET; 212 | } 213 | 214 | return _jit_function_get_bytecode(func, unwind->cache, pc, 0); 215 | } 216 | -------------------------------------------------------------------------------- /internal/ccall/jit-varint.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jit-varint.h - Variable length integer encoding. 3 | * 4 | * Copyright (C) 2011 Aleksey Demakov 5 | * 6 | * The libjit library is free software: you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public License 8 | * as published by the Free Software Foundation, either version 2.1 of 9 | * the License, or (at your option) any later version. 10 | * 11 | * The libjit library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with the libjit library. If not, see 18 | * . 19 | */ 20 | 21 | #ifndef _JIT_VARINT_H 22 | #define _JIT_VARINT_H 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | #define JIT_VARINT_BUFFER_SIZE 500 29 | 30 | typedef struct jit_varint_data *jit_varint_data_t; 31 | struct jit_varint_data 32 | { 33 | jit_varint_data_t next; 34 | unsigned char data[]; 35 | }; 36 | 37 | typedef struct jit_varint_encoder jit_varint_encoder_t; 38 | struct jit_varint_encoder 39 | { 40 | unsigned char buf[JIT_VARINT_BUFFER_SIZE]; 41 | int len; 42 | jit_varint_data_t data; 43 | jit_varint_data_t last; 44 | 45 | }; 46 | 47 | typedef struct jit_varint_decoder jit_varint_decoder_t; 48 | struct jit_varint_decoder 49 | { 50 | jit_varint_data_t data; 51 | int len; 52 | int end; 53 | }; 54 | 55 | void _jit_varint_init_encoder(jit_varint_encoder_t *encoder); 56 | void _jit_varint_init_decoder(jit_varint_decoder_t *decoder, jit_varint_data_t data); 57 | int _jit_varint_encode_end(jit_varint_encoder_t *encoder); 58 | int _jit_varint_encode_uint(jit_varint_encoder_t *encoder, jit_uint value); 59 | jit_varint_data_t _jit_varint_get_data(jit_varint_encoder_t *encoder); 60 | void _jit_varint_free_data(jit_varint_data_t data); 61 | int _jit_varint_decode_end(jit_varint_decoder_t *decoder); 62 | jit_uint _jit_varint_decode_uint(jit_varint_decoder_t *decoder); 63 | 64 | 65 | #ifdef __cplusplus 66 | } 67 | #endif 68 | 69 | #endif /* _JIT_VARINT_H */ 70 | 71 | -------------------------------------------------------------------------------- /internal/ccall/label.go: -------------------------------------------------------------------------------- 1 | package ccall 2 | 3 | /* 4 | #cgo CFLAGS: -I../ 5 | #cgo CFLAGS: -Iinclude 6 | 7 | #include 8 | */ 9 | import "C" 10 | import ( 11 | "reflect" 12 | "unsafe" 13 | ) 14 | 15 | type Label struct { 16 | c C.jit_label_t 17 | } 18 | 19 | var ( 20 | UndefinedLabel = &Label{C.jit_label_undefined} 21 | ) 22 | 23 | type Labels []*Label 24 | 25 | func (l Labels) c() *C.jit_label_t { 26 | clabels := make([]C.jit_label_t, len(l)) 27 | for idx, label := range l { 28 | clabels[idx] = label.c 29 | } 30 | return (*C.jit_label_t)(unsafe.Pointer((*reflect.SliceHeader)(unsafe.Pointer(&clabels)).Data)) 31 | } 32 | 33 | func toLabel(c C.jit_label_t) *Label { 34 | return &Label{c} 35 | } 36 | -------------------------------------------------------------------------------- /internal/ccall/value.go: -------------------------------------------------------------------------------- 1 | package ccall 2 | 3 | /* 4 | #cgo CFLAGS: -I../ 5 | #cgo CFLAGS: -Iinclude 6 | 7 | #include 8 | */ 9 | import "C" 10 | import ( 11 | "reflect" 12 | "unsafe" 13 | ) 14 | 15 | type Value struct { 16 | c C.jit_value_t 17 | } 18 | 19 | type Values []*Value 20 | 21 | func (v Values) c() *C.jit_value_t { 22 | cvalues := make([]C.jit_value_t, len(v)) 23 | for idx, vv := range v { 24 | cvalues[idx] = vv.c 25 | } 26 | return (*C.jit_value_t)(unsafe.Pointer((*reflect.SliceHeader)(unsafe.Pointer(&cvalues)).Data)) 27 | } 28 | 29 | func toValue(c C.jit_value_t) *Value { 30 | return &Value{c} 31 | } 32 | 33 | func (v *Value) IsTemporary() bool { 34 | return int(C.jit_value_is_temporary(v.c)) == 1 35 | } 36 | 37 | func (v *Value) IsLocal() bool { 38 | return int(C.jit_value_is_local(v.c)) == 1 39 | } 40 | 41 | func (v *Value) IsConstant() bool { 42 | return int(C.jit_value_is_constant(v.c)) == 1 43 | } 44 | 45 | func (v *Value) IsParameter() bool { 46 | return int(C.jit_value_is_parameter(v.c)) == 1 47 | } 48 | 49 | func (v *Value) SetVolatile() { 50 | C.jit_value_set_volatile(v.c) 51 | } 52 | 53 | func (v *Value) IsVolatile() bool { 54 | return int(C.jit_value_is_volatile(v.c)) == 1 55 | } 56 | 57 | func (v *Value) SetAddressable() { 58 | C.jit_value_set_addressable(v.c) 59 | } 60 | 61 | func (v *Value) IsAddressable() bool { 62 | return int(C.jit_value_is_addressable(v.c)) == 1 63 | } 64 | 65 | func (v *Value) Type() *Type { 66 | return toType(C.jit_value_get_type(v.c)) 67 | } 68 | 69 | func (v *Value) Function() *Function { 70 | return toFunction(C.jit_value_get_function(v.c)) 71 | } 72 | 73 | func (v *Value) Block() *Block { 74 | return toBlock(C.jit_value_get_block(v.c)) 75 | } 76 | 77 | func (v *Value) Context() *Context { 78 | return toContext(C.jit_value_get_context(v.c)) 79 | } 80 | 81 | //func (v *Value) Constant() *Constant { 82 | // return toConstant(C.jit_value_get_constant(v.c)) 83 | //} 84 | 85 | func (v *Value) Int() int { 86 | return int(C.jit_value_get_nint_constant(v.c)) 87 | } 88 | 89 | func (v *Value) Long() int64 { 90 | return int64(C.jit_value_get_long_constant(v.c)) 91 | } 92 | 93 | func (v *Value) Float32() float32 { 94 | return float32(C.jit_value_get_float32_constant(v.c)) 95 | } 96 | 97 | func (v *Value) Float64() float64 { 98 | return float64(C.jit_value_get_float64_constant(v.c)) 99 | } 100 | 101 | func (v *Value) IsTrue() bool { 102 | return int(C.jit_value_is_true(v.c)) == 1 103 | } 104 | -------------------------------------------------------------------------------- /jit.go: -------------------------------------------------------------------------------- 1 | package jit 2 | 3 | import ( 4 | "github.com/goccy/go-jit/internal/ccall" 5 | ) 6 | 7 | var ( 8 | TypeInt = &Type{ccall.TypeGoInt} 9 | ) 10 | -------------------------------------------------------------------------------- /label.go: -------------------------------------------------------------------------------- 1 | package jit 2 | 3 | import ( 4 | "github.com/goccy/go-jit/internal/ccall" 5 | ) 6 | 7 | type Label struct { 8 | *ccall.Label 9 | } 10 | 11 | type Labels []*Label 12 | 13 | func (l Labels) raw() ccall.Labels { 14 | labels := ccall.Labels{} 15 | for _, ll := range l { 16 | labels = append(labels, ll.Label) 17 | } 18 | return labels 19 | } 20 | 21 | func toLabel(c *ccall.Label) *Label { 22 | return &Label{c} 23 | } 24 | -------------------------------------------------------------------------------- /type.go: -------------------------------------------------------------------------------- 1 | package jit 2 | 3 | import ( 4 | "io" 5 | "unsafe" 6 | 7 | "github.com/goccy/go-jit/internal/ccall" 8 | ) 9 | 10 | type Type struct { 11 | *ccall.Type 12 | } 13 | 14 | type Types []*Type 15 | 16 | func (t Types) raw() ccall.Types { 17 | types := ccall.Types{} 18 | for _, tt := range t { 19 | types = append(types, tt.Type) 20 | } 21 | return types 22 | } 23 | 24 | func toType(raw *ccall.Type) *Type { 25 | return &Type{raw} 26 | } 27 | 28 | func CreateStruct(fields Types, incref int) *Type { 29 | return toType(ccall.CreateStruct(fields.raw(), incref)) 30 | } 31 | 32 | func CreateUnion(fields Types, incref int) *Type { 33 | return toType(ccall.CreateUnion(fields.raw(), incref)) 34 | } 35 | 36 | func CreateSignature(args Types, rtype *Type) *Type { 37 | return toType(ccall.CreateSignature(args.raw(), rtype.Type)) 38 | } 39 | 40 | func BestAlignment() uint { 41 | return ccall.BestAlignment() 42 | } 43 | 44 | func (t *Type) Copy() *Type { 45 | return toType(t.Type.Copy()) 46 | } 47 | 48 | func (t *Type) Free() { 49 | t.Type.Free() 50 | } 51 | 52 | func (t *Type) CreatePointer(incref int) *Type { 53 | return toType(t.Type.CreatePointer(incref)) 54 | } 55 | 56 | func (t *Type) SetSizeAndAlignment(size, alignment int) { 57 | t.Type.SetSizeAndAlignment(size, alignment) 58 | } 59 | 60 | func (t *Type) SetOffset(fieldIndex, offset uint) { 61 | t.Type.SetOffset(fieldIndex, offset) 62 | } 63 | 64 | func (t *Type) Kind() int { 65 | return t.Type.Kind() 66 | } 67 | 68 | func (t *Type) Size() uint { 69 | return t.Type.Size() 70 | } 71 | 72 | func (t *Type) Alignment() uint { 73 | return t.Type.Alignment() 74 | } 75 | 76 | func (t *Type) NumFields() uint { 77 | return t.Type.NumFields() 78 | } 79 | 80 | func (t *Type) Field(index uint) *Type { 81 | return toType(t.Type.Field(index)) 82 | } 83 | 84 | func (t *Type) Offset(index uint) uint { 85 | return t.Type.Offset(index) 86 | } 87 | 88 | func (t *Type) Name(index uint) string { 89 | return t.Type.Name(index) 90 | } 91 | 92 | func (t *Type) FindName(name string) uint { 93 | return t.Type.FindName(name) 94 | } 95 | 96 | func (t *Type) NumParams() uint { 97 | return t.Type.NumParams() 98 | } 99 | 100 | func (t *Type) Return() *Type { 101 | return toType(t.Type.Return()) 102 | } 103 | 104 | func (t *Type) Param(index uint) *Type { 105 | return toType(t.Type.Param(index)) 106 | } 107 | 108 | func (t *Type) Ref() *Type { 109 | return toType(t.Type.Ref()) 110 | } 111 | 112 | func (t *Type) TaggedType() *Type { 113 | return toType(t.Type.TaggedType()) 114 | } 115 | 116 | func (t *Type) SetTaggedType(underlying *Type, incref int) { 117 | t.Type.SetTaggedType(underlying.Type, incref) 118 | } 119 | 120 | func (t *Type) TaggedKind() int { 121 | return t.Type.TaggedKind() 122 | } 123 | 124 | func (t *Type) TaggedData() unsafe.Pointer { 125 | return t.Type.TaggedData() 126 | } 127 | 128 | func (t *Type) IsPrimitive() bool { 129 | return t.Type.IsPrimitive() 130 | } 131 | 132 | func (t *Type) IsStruct() bool { 133 | return t.Type.IsStruct() 134 | } 135 | 136 | func (t *Type) IsUnion() bool { 137 | return t.Type.IsUnion() 138 | } 139 | 140 | func (t *Type) IsSignature() bool { 141 | return t.Type.IsSignature() 142 | } 143 | 144 | func (t *Type) IsPointer() bool { 145 | return t.Type.IsPointer() 146 | } 147 | 148 | func (t *Type) IsTagged() bool { 149 | return t.Type.IsTagged() 150 | } 151 | 152 | func (t *Type) RemoveTags() *Type { 153 | return toType(t.Type.RemoveTags()) 154 | } 155 | 156 | func (t *Type) Normalize() *Type { 157 | return toType(t.Type.Normalize()) 158 | } 159 | 160 | func (t *Type) PromoteInt() *Type { 161 | return toType(t.Type.PromoteInt()) 162 | } 163 | 164 | func (t *Type) ReturnViaPointer() int { 165 | return t.Type.ReturnViaPointer() 166 | } 167 | 168 | func (t *Type) HasTag(kind int) bool { 169 | return t.Type.HasTag(kind) 170 | } 171 | 172 | func (t *Type) Dump(w io.Writer) error { 173 | return t.Type.Dump(w) 174 | } 175 | -------------------------------------------------------------------------------- /value.go: -------------------------------------------------------------------------------- 1 | package jit 2 | 3 | import ( 4 | "github.com/goccy/go-jit/internal/ccall" 5 | ) 6 | 7 | type Value struct { 8 | *ccall.Value 9 | } 10 | 11 | type Values []*Value 12 | 13 | func (v Values) raw() ccall.Values { 14 | values := ccall.Values{} 15 | for _, vv := range v { 16 | values = append(values, vv.Value) 17 | } 18 | return values 19 | } 20 | 21 | func toValues(v ccall.Values) Values { 22 | values := Values{} 23 | for _, vv := range v { 24 | values = append(values, toValue(vv)) 25 | } 26 | return values 27 | } 28 | 29 | func toValue(c *ccall.Value) *Value { 30 | return &Value{c} 31 | } 32 | 33 | func (v *Value) IsTemporary() bool { 34 | return v.Value.IsTemporary() 35 | } 36 | 37 | func (v *Value) IsLocal() bool { 38 | return v.Value.IsLocal() 39 | } 40 | 41 | func (v *Value) IsConstant() bool { 42 | return v.Value.IsConstant() 43 | } 44 | 45 | func (v *Value) IsParameter() bool { 46 | return v.Value.IsParameter() 47 | } 48 | 49 | func (v *Value) SetVolatile() { 50 | v.Value.SetVolatile() 51 | } 52 | 53 | func (v *Value) IsVolatile() bool { 54 | return v.Value.IsVolatile() 55 | } 56 | 57 | func (v *Value) SetAddressable() { 58 | v.Value.SetAddressable() 59 | } 60 | 61 | func (v *Value) IsAddressable() bool { 62 | return v.Value.IsAddressable() 63 | } 64 | 65 | func (v *Value) Type() *Type { 66 | return toType(v.Value.Type()) 67 | } 68 | 69 | func (v *Value) Function() *Function { 70 | return toFunction(v.Value.Function()) 71 | } 72 | 73 | func (v *Value) Block() *Block { 74 | return toBlock(v.Value.Block()) 75 | } 76 | 77 | func (v *Value) Context() *Context { 78 | return toContext(v.Value.Context()) 79 | } 80 | 81 | //func (v *Value) Constant() *Constant { 82 | // return toConstant(C.jit_value_get_constant(v.c)) 83 | //} 84 | 85 | func (v *Value) Int() int { 86 | return v.Value.Int() 87 | } 88 | 89 | func (v *Value) Float32() float32 { 90 | return v.Value.Float32() 91 | } 92 | 93 | func (v *Value) Float64() float64 { 94 | return v.Value.Float64() 95 | } 96 | 97 | func (v *Value) IsTrue() bool { 98 | return v.Value.IsTrue() 99 | } 100 | --------------------------------------------------------------------------------