482 lines
14 KiB
C
482 lines
14 KiB
C
/*
|
|
* Copyright (C)2005-2017 Haxe Foundation
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
* copy of this software and associated documentation files (the "Software"),
|
|
* to deal in the Software without restriction, including without limitation
|
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
* and/or sell copies of the Software, and to permit persons to whom the
|
|
* Software is furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in
|
|
* all copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
* DEALINGS IN THE SOFTWARE.
|
|
*/
|
|
#ifndef _NEKO_H
|
|
#define _NEKO_H
|
|
|
|
// OS FLAGS
|
|
#if defined(_WIN32)
|
|
# define NEKO_WINDOWS
|
|
#endif
|
|
|
|
#if defined(__APPLE__) || defined(macintosh)
|
|
# define NEKO_MAC
|
|
#endif
|
|
|
|
#if defined(linux) || defined(__linux__)
|
|
# define NEKO_LINUX
|
|
#endif
|
|
|
|
#if defined(__FreeBSD_kernel__)
|
|
# define NEKO_GNUKBSD
|
|
#endif
|
|
|
|
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
|
|
# define NEKO_BSD
|
|
#endif
|
|
|
|
#if defined(__GNU__)
|
|
# define NEKO_HURD
|
|
#endif
|
|
|
|
// COMPILER/PROCESSOR FLAGS
|
|
#if defined(__GNUC__)
|
|
# define NEKO_GCC
|
|
#endif
|
|
|
|
#if defined(_MSC_VER)
|
|
# define NEKO_VCC
|
|
// remove deprecated C API usage warnings
|
|
# pragma warning( disable : 4996 )
|
|
#endif
|
|
|
|
#if defined(__MINGW32__)
|
|
# define NEKO_MINGW
|
|
#endif
|
|
|
|
#if defined(__CYGWIN__)
|
|
# define NEKO_CYGWIN
|
|
#endif
|
|
|
|
#if defined(__i386__) || defined(_WIN32)
|
|
# define NEKO_X86
|
|
#endif
|
|
|
|
#if defined(__ppc__)
|
|
# define NEKO_PPC
|
|
#endif
|
|
|
|
#if defined(_64BITS) || defined(__x86_64__)
|
|
# define NEKO_64BITS
|
|
#endif
|
|
|
|
#if defined(NEKO_LINUX) || defined(NEKO_MAC) || defined(NEKO_BSD) || defined(NEKO_GNUKBSD) || defined(NEKO_HURD) || defined(NEKO_CYGWIN)
|
|
# define NEKO_POSIX
|
|
#endif
|
|
|
|
#if defined(NEKO_GCC)
|
|
# define NEKO_THREADED
|
|
# define NEKO_DIRECT_THREADED
|
|
#endif
|
|
|
|
#ifndef NEKO_NO_THREADS
|
|
# define NEKO_THREADS
|
|
#endif
|
|
|
|
#include <stddef.h>
|
|
#ifndef NEKO_VCC
|
|
# include <stdint.h>
|
|
#endif
|
|
|
|
#define NEKO_XLOCALE_H
|
|
|
|
/* #undef NEKO_BIG_ENDIAN */
|
|
|
|
#ifndef NEKO_BIG_ENDIAN
|
|
# define NEKO_LITTLE_ENDIAN
|
|
#endif
|
|
|
|
/* #undef NEKO_JIT_DISABLE */
|
|
/* #undef NEKO_JIT_DEBUG */
|
|
|
|
#if !defined(NEKO_JIT_DISABLE) && defined(NEKO_X86) && !defined(NEKO_MAC) && !defined(_WIN64)
|
|
#define NEKO_JIT_ENABLE
|
|
#endif
|
|
|
|
#define NEKO_VERSION_MAJOR 2
|
|
#define NEKO_VERSION_MINOR 2
|
|
#define NEKO_VERSION_PATCH 0
|
|
#define NEKO_VERSION 220
|
|
|
|
#define NEKO_MODULE_PATH "/usr/local/lib/neko"
|
|
|
|
typedef intptr_t int_val;
|
|
|
|
typedef enum {
|
|
VAL_INT = 0xFF,
|
|
VAL_NULL = 0,
|
|
VAL_FLOAT = 1,
|
|
VAL_BOOL = 2,
|
|
VAL_STRING = 3,
|
|
VAL_OBJECT = 4,
|
|
VAL_ARRAY = 5,
|
|
VAL_FUNCTION = 6,
|
|
VAL_ABSTRACT = 7,
|
|
VAL_INT32 = 8,
|
|
VAL_PRIMITIVE = 6 | 16,
|
|
VAL_JITFUN = 6 | 32,
|
|
VAL_32_BITS = 0xFFFFFFFF
|
|
} val_type;
|
|
|
|
struct _value {
|
|
val_type t;
|
|
};
|
|
|
|
struct _buffer;
|
|
typedef int field;
|
|
typedef struct { int __zero; } *vkind;
|
|
typedef struct _value *value;
|
|
|
|
typedef struct {
|
|
field id;
|
|
value v;
|
|
} objcell;
|
|
|
|
typedef struct _objtable
|
|
{
|
|
int count;
|
|
objcell *cells;
|
|
} objtable;
|
|
|
|
typedef struct _buffer *buffer;
|
|
typedef double tfloat;
|
|
|
|
typedef void (*finalizer)(value v);
|
|
|
|
#pragma pack(4)
|
|
typedef struct {
|
|
val_type t;
|
|
tfloat f;
|
|
} vfloat;
|
|
|
|
typedef struct {
|
|
val_type t;
|
|
int i;
|
|
} vint32;
|
|
#pragma pack()
|
|
|
|
typedef struct _vobject {
|
|
val_type t;
|
|
objtable table;
|
|
struct _vobject *proto;
|
|
} vobject;
|
|
|
|
typedef struct {
|
|
val_type t;
|
|
int nargs;
|
|
void *addr;
|
|
value env;
|
|
void *module;
|
|
} vfunction;
|
|
|
|
typedef struct {
|
|
val_type t;
|
|
char c;
|
|
} vstring;
|
|
|
|
typedef struct {
|
|
val_type t;
|
|
value ptr;
|
|
} varray;
|
|
|
|
typedef struct {
|
|
val_type t;
|
|
vkind kind;
|
|
void *data;
|
|
} vabstract;
|
|
|
|
typedef struct hcell {
|
|
int hkey;
|
|
value key;
|
|
value val;
|
|
struct hcell *next;
|
|
} hcell;
|
|
|
|
typedef struct {
|
|
hcell **cells;
|
|
int ncells;
|
|
int nitems;
|
|
} vhash;
|
|
|
|
struct _mt_local;
|
|
struct _mt_lock;
|
|
typedef struct _mt_local mt_local;
|
|
typedef struct _mt_lock mt_lock;
|
|
|
|
#define NEKO_TAG_BITS 4
|
|
|
|
#define val_tag(v) (*(val_type*)(v))
|
|
#define val_short_tag(v) (val_tag(v)&((1<<NEKO_TAG_BITS) - 1))
|
|
#define val_is_null(v) ((v) == val_null)
|
|
#define val_is_int(v) ((((int)(int_val)(v)) & 1) != 0)
|
|
#define val_is_any_int(v) (val_is_int(v) || val_tag(v) == VAL_INT32)
|
|
#define val_is_bool(v) ((v) == val_true || (v) == val_false)
|
|
#define val_is_number(v) (val_is_int(v) || val_tag(v) == VAL_FLOAT || val_tag(v) == VAL_INT32)
|
|
#define val_is_float(v) (!val_is_int(v) && val_tag(v) == VAL_FLOAT)
|
|
#define val_is_int32(v) (!val_is_int(v) && val_tag(v) == VAL_INT32)
|
|
#define val_is_string(v) (!val_is_int(v) && val_short_tag(v) == VAL_STRING)
|
|
#define val_is_function(v) (!val_is_int(v) && val_short_tag(v) == VAL_FUNCTION)
|
|
#define val_is_object(v) (!val_is_int(v) && val_tag(v) == VAL_OBJECT)
|
|
#define val_is_array(v) (!val_is_int(v) && val_short_tag(v) == VAL_ARRAY)
|
|
#define val_is_abstract(v) (!val_is_int(v) && val_tag(v) == VAL_ABSTRACT)
|
|
#define val_is_kind(v,t) (val_is_abstract(v) && val_kind(v) == (t))
|
|
#define val_check_kind(v,t) if( !val_is_kind(v,t) ) neko_error();
|
|
#define val_check_function(f,n) if( !val_is_function(f) || (val_fun_nargs(f) != (n) && val_fun_nargs(f) != VAR_ARGS) ) neko_error();
|
|
#define val_check(v,t) if( !val_is_##t(v) ) neko_error();
|
|
#define val_data(v) ((vabstract*)(v))->data
|
|
#define val_kind(v) ((vabstract*)(v))->kind
|
|
|
|
#define val_type(v) (val_is_int(v) ? VAL_INT : val_short_tag(v))
|
|
#define val_int(v) (((int)(int_val)(v)) >> 1)
|
|
#define val_float(v) (CONV_FLOAT ((vfloat*)(v))->f)
|
|
#define val_int32(v) (((vint32*)(v))->i)
|
|
#define val_any_int(v) (val_is_int(v)?val_int(v):val_int32(v))
|
|
#define val_bool(v) ((v) == val_true)
|
|
#define val_number(v) (val_is_int(v)?val_int(v):((val_tag(v)==VAL_FLOAT)?val_float(v):val_int32(v)))
|
|
#define val_hdata(v) ((vhash*)val_data(v))
|
|
#define val_string(v) (&((vstring*)(v))->c)
|
|
#define val_strlen(v) ((signed)(((unsigned)val_tag(v)) >> NEKO_TAG_BITS))
|
|
#define val_set_length(v,l) val_tag(v) = val_short_tag(v) | ((l) << NEKO_TAG_BITS)
|
|
#define val_set_size val_set_length
|
|
|
|
#define val_array_size(v) ((signed)(((unsigned)val_tag(v)) >> NEKO_TAG_BITS))
|
|
#define val_array_ptr(v) (&((varray*)(v))->ptr)
|
|
#define val_fun_nargs(v) ((vfunction*)(v))->nargs
|
|
#define alloc_int(v) ((value)(int_val)((((int)(v)) << 1) | 1))
|
|
#define alloc_bool(b) ((b)?val_true:val_false)
|
|
|
|
#define max_array_size ((1 << (32 - NEKO_TAG_BITS)) - 1)
|
|
#define max_string_size ((1 << (32 - NEKO_TAG_BITS)) - 1)
|
|
#define invalid_comparison 0xFE
|
|
|
|
#undef EXTERN
|
|
#undef EXPORT
|
|
#undef IMPORT
|
|
#if defined(NEKO_VCC) || defined(NEKO_MINGW)
|
|
# define INLINE __inline
|
|
# define EXPORT __declspec( dllexport )
|
|
# define IMPORT __declspec( dllimport )
|
|
#else
|
|
# define INLINE inline
|
|
# define EXPORT
|
|
# define IMPORT
|
|
#endif
|
|
|
|
#if defined(NEKO_SOURCES) || defined(NEKO_STANDALONE)
|
|
# define EXTERN EXPORT
|
|
#else
|
|
# define EXTERN IMPORT
|
|
#endif
|
|
|
|
#define VEXTERN extern EXTERN
|
|
|
|
#ifdef __cplusplus
|
|
# define C_FUNCTION_BEGIN extern "C" {
|
|
# define C_FUNCTION_END };
|
|
#else
|
|
# define C_FUNCTION_BEGIN
|
|
# define C_FUNCTION_END
|
|
# ifndef true
|
|
# define true 1
|
|
# define false 0
|
|
typedef int bool;
|
|
# endif
|
|
#endif
|
|
|
|
// the two upper bits must be either 00 or 11
|
|
#define need_32_bits(i) ( (((unsigned int)(i)) + 0x40000000) & 0x80000000 )
|
|
#define alloc_best_int(i) (need_32_bits(i) ? alloc_int32(i) : alloc_int(i))
|
|
|
|
#define neko_error() return NULL
|
|
#define failure(msg) _neko_failure(alloc_string(msg),__FILE__,__LINE__)
|
|
#define bfailure(buf) _neko_failure(buffer_to_string(buf),__FILE__,__LINE__)
|
|
|
|
#ifndef CONV_FLOAT
|
|
# define CONV_FLOAT
|
|
#endif
|
|
|
|
#ifdef NEKO_POSIX
|
|
# include <errno.h>
|
|
# define POSIX_LABEL(name) name:
|
|
# define HANDLE_EINTR(label) if( errno == EINTR ) goto label
|
|
# define HANDLE_FINTR(f,label) if( ferror(f) && errno == EINTR ) goto label
|
|
#else
|
|
# define POSIX_LABEL(name)
|
|
# define HANDLE_EINTR(label)
|
|
# define HANDLE_FINTR(f,label)
|
|
#endif
|
|
|
|
#define VAR_ARGS (-1)
|
|
#define DEFINE_PRIM_MULT(func) C_FUNCTION_BEGIN EXPORT void *func##__MULT() { return (void*)(&func); } C_FUNCTION_END
|
|
#define DEFINE_PRIM(func,nargs) C_FUNCTION_BEGIN EXPORT void *func##__##nargs() { return (void*)(&func); } C_FUNCTION_END
|
|
#define DEFINE_PRIM_WITH_NAME(func,name,nargs) C_FUNCTION_BEGIN EXPORT void *name##__##nargs() { return (void*)(&func); } C_FUNCTION_END
|
|
#define DEFINE_KIND(name) int_val __kind_##name = 0; vkind name = (vkind)&__kind_##name;
|
|
|
|
#ifdef NEKO_STANDALONE
|
|
# define DEFINE_ENTRY_POINT(name)
|
|
#else
|
|
# define DEFINE_ENTRY_POINT(name) C_FUNCTION_BEGIN void name(); EXPORT void *__neko_entry_point() { return &name; } C_FUNCTION_END
|
|
#endif
|
|
|
|
#ifdef HEADER_IMPORTS
|
|
# define H_EXTERN IMPORT
|
|
#else
|
|
# define H_EXTERN EXPORT
|
|
#endif
|
|
|
|
#define DECLARE_PRIM(func,nargs) C_FUNCTION_BEGIN H_EXTERN void *func##__##nargs(); C_FUNCTION_END
|
|
#define DECLARE_KIND(name) C_FUNCTION_BEGIN H_EXTERN extern vkind name; C_FUNCTION_END
|
|
|
|
#define alloc_int32 neko_alloc_int32
|
|
#define alloc_float neko_alloc_float
|
|
#define alloc_string neko_alloc_string
|
|
#define alloc_empty_string neko_alloc_empty_string
|
|
#define copy_string neko_copy_string
|
|
#define val_this neko_val_this
|
|
#define val_id neko_val_id
|
|
#define val_field neko_val_field
|
|
#define alloc_object neko_alloc_object
|
|
#define alloc_field neko_alloc_field
|
|
#define alloc_array neko_alloc_array
|
|
#define val_call0 neko_val_call0
|
|
#define val_call1 neko_val_call1
|
|
#define val_call2 neko_val_call2
|
|
#define val_call3 neko_val_call3
|
|
#define val_callN neko_val_callN
|
|
#define val_ocall0 neko_val_ocall0
|
|
#define val_ocall1 neko_val_ocall1
|
|
#define val_ocall2 neko_val_ocall2
|
|
#define val_ocallN neko_val_ocallN
|
|
#define val_callEx neko_val_callEx
|
|
#define alloc_root neko_alloc_root
|
|
#define free_root neko_free_root
|
|
#define alloc neko_alloc
|
|
#define alloc_private neko_alloc_private
|
|
#define alloc_abstract neko_alloc_abstract
|
|
#define alloc_function neko_alloc_function
|
|
#define alloc_buffer neko_alloc_buffer
|
|
#define buffer_append neko_buffer_append
|
|
#define buffer_append_sub neko_buffer_append_sub
|
|
#define buffer_append_char neko_buffer_append_char
|
|
#define buffer_length neko_buffer_length
|
|
#define buffer_to_string neko_buffer_to_string
|
|
#define val_buffer neko_val_buffer
|
|
#define val_compare neko_val_compare
|
|
#define val_print neko_val_print
|
|
#define val_gc neko_val_gc
|
|
#define val_throw neko_val_throw
|
|
#define val_rethrow neko_val_rethrow
|
|
#define val_iter_fields neko_val_iter_fields
|
|
#define val_field_name neko_val_field_name
|
|
#define val_hash neko_val_hash
|
|
#define k_hash neko_k_hash
|
|
#define kind_share neko_kind_share
|
|
#define kind_lookup neko_kind_lookup
|
|
|
|
#define alloc_local neko_alloc_local
|
|
#define local_get neko_local_get
|
|
#define local_set neko_local_set
|
|
#define free_local neko_free_local
|
|
#define alloc_lock neko_alloc_lock
|
|
#define lock_acquire neko_lock_acquire
|
|
#define lock_try neko_lock_try
|
|
#define lock_release neko_lock_release
|
|
#define free_lock neko_free_lock
|
|
|
|
C_FUNCTION_BEGIN
|
|
|
|
VEXTERN vkind k_hash;
|
|
|
|
VEXTERN value val_null;
|
|
VEXTERN value val_true;
|
|
VEXTERN value val_false;
|
|
|
|
EXTERN value alloc_float( tfloat t );
|
|
EXTERN value alloc_int32( int i );
|
|
|
|
EXTERN value alloc_string( const char *str );
|
|
EXTERN value alloc_empty_string( unsigned int size );
|
|
EXTERN value copy_string( const char *str, int_val size );
|
|
|
|
EXTERN value val_this();
|
|
EXTERN field val_id( const char *str );
|
|
EXTERN value val_field( value o, field f );
|
|
EXTERN value alloc_object( value o );
|
|
EXTERN void alloc_field( value obj, field f, value v );
|
|
EXTERN void val_iter_fields( value obj, void f( value v, field f, void * ), void *p );
|
|
EXTERN value val_field_name( field f );
|
|
|
|
EXTERN value alloc_array( unsigned int n );
|
|
EXTERN value alloc_abstract( vkind k, void *data );
|
|
|
|
EXTERN value val_call0( value f );
|
|
EXTERN value val_call1( value f, value arg );
|
|
EXTERN value val_call2( value f, value arg1, value arg2 );
|
|
EXTERN value val_call3( value f, value arg1, value arg2, value arg3 );
|
|
EXTERN value val_callN( value f, value *args, int nargs );
|
|
EXTERN value val_ocall0( value o, field f );
|
|
EXTERN value val_ocall1( value o, field f, value arg );
|
|
EXTERN value val_ocall2( value o, field f, value arg1, value arg2 );
|
|
EXTERN value val_ocallN( value o, field f, value *args, int nargs );
|
|
EXTERN value val_callEx( value vthis, value f, value *args, int nargs, value *exc );
|
|
|
|
EXTERN value *alloc_root( unsigned int nvals );
|
|
EXTERN void free_root( value *r );
|
|
EXTERN char *alloc( unsigned int nbytes );
|
|
EXTERN char *alloc_private( unsigned int nbytes );
|
|
EXTERN value alloc_function( void *c_prim, unsigned int nargs, const char *name );
|
|
|
|
EXTERN buffer alloc_buffer( const char *init );
|
|
EXTERN void buffer_append( buffer b, const char *s );
|
|
EXTERN void buffer_append_sub( buffer b, const char *s, int_val len );
|
|
EXTERN void buffer_append_char( buffer b, char c );
|
|
EXTERN value buffer_to_string( buffer b );
|
|
EXTERN int buffer_length( buffer b );
|
|
EXTERN void val_buffer( buffer b, value v );
|
|
|
|
EXTERN int val_compare( value a, value b );
|
|
EXTERN void val_print( value s );
|
|
EXTERN void val_gc( value v, finalizer f );
|
|
EXTERN void val_throw( value v );
|
|
EXTERN void val_rethrow( value v );
|
|
EXTERN int val_hash( value v );
|
|
|
|
EXTERN void kind_share( vkind *k, const char *name );
|
|
EXTERN vkind kind_lookup( const char *name );
|
|
EXTERN void _neko_failure( value msg, const char *file, int line );
|
|
|
|
// MULTITHREADING API
|
|
EXTERN mt_local *alloc_local();
|
|
EXTERN void *local_get( mt_local *l );
|
|
EXTERN void local_set( mt_local *l, void *v );
|
|
EXTERN void free_local( mt_local *l );
|
|
|
|
EXTERN mt_lock *alloc_lock();
|
|
EXTERN void lock_acquire( mt_lock *l );
|
|
EXTERN int lock_try( mt_lock *l );
|
|
EXTERN void lock_release( mt_lock *l );
|
|
EXTERN void free_lock( mt_lock *l );
|
|
|
|
C_FUNCTION_END
|
|
|
|
#endif
|
|
/* ************************************************************************ */
|