first commit
CI / Build (clang, clang++, ubuntu-22.04, linux, 3.10, master, x86,x86_64) (push) Canceled after 0s
CI / Build (clang, clang++, windows-2022, windows, 3.10, master, x86,x86_64) (push) Canceled after 0s
CI / Release (push) Canceled after 0s

This commit is contained in:
2026-09-13 22:18:11 +01:00
commit 08c03ac533
6701 changed files with 1577314 additions and 0 deletions
+215
View File
@@ -0,0 +1,215 @@
/*
** mrbconf.h - mruby core configuration
**
** See Copyright Notice in mruby.h
*/
#ifndef MRUBYCONF_H
#define MRUBYCONF_H
#include <limits.h>
#include <stdint.h>
/* architecture selection: */
/* specify -DMRB_32BIT or -DMRB_64BIT to override */
#if !defined(MRB_32BIT) && !defined(MRB_64BIT)
#if UINT64_MAX == SIZE_MAX
#define MRB_64BIT
#else
#define MRB_32BIT
#endif
#endif
#if defined(MRB_32BIT) && defined(MRB_64BIT)
#error Cannot build for 32 and 64 bit architecture at the same time
#endif
/* configuration options: */
/* add -DMRB_USE_FLOAT to use float instead of double for floating point numbers */
//#define MRB_USE_FLOAT
/* exclude floating point numbers */
//#define MRB_WITHOUT_FLOAT
/* add -DMRB_METHOD_CACHE to use method cache to improve performance */
//#define MRB_METHOD_CACHE
/* size of the method cache (need to be the power of 2) */
//#define MRB_METHOD_CACHE_SIZE (1<<7)
/* add -DMRB_METHOD_T_STRUCT on machines that use higher bits of pointers */
/* no MRB_METHOD_T_STRUCT requires highest 2 bits of function pointers to be zero */
#ifndef MRB_METHOD_T_STRUCT
// can't use highest 2 bits of function pointers at least on 32bit
// Windows and 32bit Linux.
# ifdef MRB_32BIT
# define MRB_METHOD_T_STRUCT
# endif
#endif
/* add -DMRB_INT32 to use 32bit integer for mrb_int; conflict with MRB_INT64;
Default for 32-bit CPU mode. */
//#define MRB_INT32
/* add -DMRB_INT64 to use 64bit integer for mrb_int; conflict with MRB_INT32;
Default for 64-bit CPU mode. */
//#define MRB_INT64
/* if no specific integer type is chosen */
#if !defined(MRB_INT32) && !defined(MRB_INT64)
# if defined(MRB_64BIT) && !defined(MRB_NAN_BOXING)
/* Use 64bit integers on 64bit architecture (without MRB_NAN_BOXING) */
# define MRB_INT64
# else
/* Otherwise use 32bit integers */
# define MRB_INT32
# endif
#endif
/* define on big endian machines; used by MRB_NAN_BOXING, etc. */
#ifndef MRB_ENDIAN_BIG
# if (defined(BYTE_ORDER) && defined(BIG_ENDIAN) && BYTE_ORDER == BIG_ENDIAN) || \
(defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
# define MRB_ENDIAN_BIG
# endif
#endif
/* represent mrb_value in boxed double; conflict with MRB_USE_FLOAT and MRB_WITHOUT_FLOAT */
//#define MRB_NAN_BOXING
/* represent mrb_value as a word (natural unit of data for the processor) */
//#define MRB_WORD_BOXING
/* string class to handle UTF-8 encoding */
//#define MRB_UTF8_STRING
/* argv max size in mrb_funcall */
//#define MRB_FUNCALL_ARGC_MAX 16
/* number of object per heap page */
//#define MRB_HEAP_PAGE_SIZE 1024
/* if __ehdr_start is available, mruby can reduce memory used by symbols */
//#define MRB_USE_LINK_TIME_RO_DATA_P
/* if MRB_USE_LINK_TIME_RO_DATA_P does not work,
you can try mrb_ro_data_p() that you have implemented yourself in any file;
prototype is `mrb_bool mrb_ro_data_p(const char *ptr)` */
//#define MRB_USE_CUSTOM_RO_DATA_P
/* turn off generational GC by default */
//#define MRB_GC_TURN_OFF_GENERATIONAL
/* default size of khash table bucket */
//#define KHASH_DEFAULT_SIZE 32
/* allocated memory address alignment */
//#define POOL_ALIGNMENT 4
/* page size of memory pool */
//#define POOL_PAGE_SIZE 16000
/* initial minimum size for string buffer */
//#define MRB_STR_BUF_MIN_SIZE 128
/* arena size */
//#define MRB_GC_ARENA_SIZE 100
/* fixed size GC arena */
//#define MRB_GC_FIXED_ARENA
/* state atexit stack size */
//#define MRB_FIXED_STATE_ATEXIT_STACK_SIZE 5
/* fixed size state atexit stack */
//#define MRB_FIXED_STATE_ATEXIT_STACK
/* -DMRB_DISABLE_XXXX to drop following features */
//#define MRB_DISABLE_STDIO /* use of stdio */
/* -DMRB_ENABLE_XXXX to enable following features */
//#define MRB_ENABLE_DEBUG_HOOK /* hooks for debugger */
//#define MRB_ENABLE_ALL_SYMBOLS /* Symbols.all_symbols */
/* end of configuration */
/* define MRB_DISABLE_XXXX from DISABLE_XXX (for compatibility) */
#ifdef DISABLE_STDIO
#define MRB_DISABLE_STDIO
#endif
/* define MRB_ENABLE_XXXX from ENABLE_XXX (for compatibility) */
#ifdef ENABLE_DEBUG
#define MRB_ENABLE_DEBUG_HOOK
#endif
#ifndef MRB_DISABLE_STDIO
# include <stdio.h>
#endif
#ifndef FALSE
# define FALSE 0
#endif
#ifndef TRUE
# define TRUE 1
#endif
/*
** mruby tuning profiles
**/
/* A profile for micro controllers */
#if defined(MRB_CONSTRAINED_BASELINE_PROFILE)
# ifndef KHASH_DEFAULT_SIZE
# define KHASH_DEFAULT_SIZE 16
# endif
# ifndef MRB_STR_BUF_MIN_SIZE
# define MRB_STR_BUF_MIN_SIZE 32
# endif
# ifndef MRB_HEAP_PAGE_SIZE
# define MRB_HEAP_PAGE_SIZE 256
# endif
/* A profile for default mruby */
#elif defined(MRB_BASELINE_PROFILE)
/* A profile for desktop computers or workstations; rich memory! */
#elif defined(MRB_MAIN_PROFILE)
# ifndef MRB_METHOD_CACHE
# define MRB_METHOD_CACHE
# endif
# ifndef MRB_METHOD_CACHE_SIZE
# define MRB_METHOD_CACHE_SIZE (1<<10)
# endif
# ifndef MRB_IV_SEGMENT_SIZE
# define MRB_IV_SEGMENT_SIZE 32
# endif
# ifndef MRB_HEAP_PAGE_SIZE
# define MRB_HEAP_PAGE_SIZE 4096
# endif
/* A profile for server; mruby vm is long life */
#elif defined(MRB_HIGH_PROFILE)
# ifndef MRB_METHOD_CACHE
# define MRB_METHOD_CACHE
# endif
# ifndef MRB_METHOD_CACHE_SIZE
# define MRB_METHOD_CACHE_SIZE (1<<12)
# endif
# ifndef MRB_IV_SEGMENT_SIZE
# define MRB_IV_SEGMENT_SIZE 64
# endif
# ifndef MRB_HEAP_PAGE_SIZE
# define MRB_HEAP_PAGE_SIZE 4096
# endif
#endif
#endif /* MRUBYCONF_H */
File diff suppressed because it is too large Load Diff
+300
View File
@@ -0,0 +1,300 @@
/**
** @file mruby/array.h - Array class
**
** See Copyright Notice in mruby.h
*/
#ifndef MRUBY_ARRAY_H
#define MRUBY_ARRAY_H
#include "common.h"
/*
* Array class
*/
MRB_BEGIN_DECL
typedef struct mrb_shared_array {
int refcnt;
mrb_ssize len;
mrb_value *ptr;
} mrb_shared_array;
#define MRB_ARY_EMBED_LEN_MAX ((mrb_int)(sizeof(void*)*3/sizeof(mrb_value)))
struct RArray {
MRB_OBJECT_HEADER;
union {
struct {
mrb_ssize len;
union {
mrb_ssize capa;
mrb_shared_array *shared;
} aux;
mrb_value *ptr;
} heap;
void *ary[3];
} as;
};
#define mrb_ary_ptr(v) ((struct RArray*)(mrb_ptr(v)))
#define mrb_ary_value(p) mrb_obj_value((void*)(p))
#define RARRAY(v) ((struct RArray*)(mrb_ptr(v)))
#define MRB_ARY_EMBED_MASK 7
#define ARY_EMBED_P(a) ((a)->flags & MRB_ARY_EMBED_MASK)
#define ARY_UNSET_EMBED_FLAG(a) ((a)->flags &= ~(MRB_ARY_EMBED_MASK))
#define ARY_EMBED_LEN(a) ((mrb_int)(((a)->flags & MRB_ARY_EMBED_MASK) - 1))
#define ARY_SET_EMBED_LEN(a,len) ((a)->flags = ((a)->flags&~MRB_ARY_EMBED_MASK) | ((uint32_t)(len) + 1))
#define ARY_EMBED_PTR(a) ((mrb_value*)(&(a)->as.ary))
#define ARY_LEN(a) (ARY_EMBED_P(a)?ARY_EMBED_LEN(a):(a)->as.heap.len)
#define ARY_PTR(a) (ARY_EMBED_P(a)?ARY_EMBED_PTR(a):(a)->as.heap.ptr)
#define RARRAY_LEN(a) ARY_LEN(RARRAY(a))
#define RARRAY_PTR(a) ARY_PTR(RARRAY(a))
#define ARY_SET_LEN(a,n) do {\
if (ARY_EMBED_P(a)) {\
mrb_assert((n) <= MRB_ARY_EMBED_LEN_MAX); \
ARY_SET_EMBED_LEN(a,n);\
}\
else\
(a)->as.heap.len = (n);\
} while (0)
#define ARY_CAPA(a) (ARY_EMBED_P(a)?MRB_ARY_EMBED_LEN_MAX:(a)->as.heap.aux.capa)
#define MRB_ARY_SHARED 256
#define ARY_SHARED_P(a) ((a)->flags & MRB_ARY_SHARED)
#define ARY_SET_SHARED_FLAG(a) ((a)->flags |= MRB_ARY_SHARED)
#define ARY_UNSET_SHARED_FLAG(a) ((a)->flags &= ~MRB_ARY_SHARED)
void mrb_ary_decref(mrb_state*, mrb_shared_array*);
MRB_API void mrb_ary_modify(mrb_state*, struct RArray*);
MRB_API mrb_value mrb_ary_new_capa(mrb_state*, mrb_int);
/*
* Initializes a new array.
*
* Equivalent to:
*
* Array.new
*
* @param mrb The mruby state reference.
* @return The initialized array.
*/
MRB_API mrb_value mrb_ary_new(mrb_state *mrb);
/*
* Initializes a new array with initial values
*
* Equivalent to:
*
* Array[value1, value2, ...]
*
* @param mrb The mruby state reference.
* @param size The numer of values.
* @param vals The actual values.
* @return The initialized array.
*/
MRB_API mrb_value mrb_ary_new_from_values(mrb_state *mrb, mrb_int size, const mrb_value *vals);
/*
* Initializes a new array with two initial values
*
* Equivalent to:
*
* Array[car, cdr]
*
* @param mrb The mruby state reference.
* @param car The first value.
* @param cdr The second value.
* @return The initialized array.
*/
MRB_API mrb_value mrb_assoc_new(mrb_state *mrb, mrb_value car, mrb_value cdr);
/*
* Concatenate two arrays. The target array will be modified
*
* Equivalent to:
* ary.concat(other)
*
* @param mrb The mruby state reference.
* @param self The target array.
* @param other The array that will be concatenated to self.
*/
MRB_API void mrb_ary_concat(mrb_state *mrb, mrb_value self, mrb_value other);
/*
* Create an array from the input. It tries calling to_a on the
* value. If value does not respond to that, it creates a new
* array with just this value.
*
* @param mrb The mruby state reference.
* @param value The value to change into an array.
* @return An array representation of value.
*/
MRB_API mrb_value mrb_ary_splat(mrb_state *mrb, mrb_value value);
/*
* Pushes value into array.
*
* Equivalent to:
*
* ary << value
*
* @param mrb The mruby state reference.
* @param ary The array in which the value will be pushed
* @param value The value to be pushed into array
*/
MRB_API void mrb_ary_push(mrb_state *mrb, mrb_value array, mrb_value value);
/*
* Pops the last element from the array.
*
* Equivalent to:
*
* ary.pop
*
* @param mrb The mruby state reference.
* @param ary The array from which the value will be popped.
* @return The popped value.
*/
MRB_API mrb_value mrb_ary_pop(mrb_state *mrb, mrb_value ary);
/*
* Returns a reference to an element of the array on the given index.
*
* Equivalent to:
*
* ary[n]
*
* @param mrb The mruby state reference.
* @param ary The target array.
* @param n The array index being referenced
* @return The referenced value.
*/
MRB_API mrb_value mrb_ary_ref(mrb_state *mrb, mrb_value ary, mrb_int n);
/*
* Sets a value on an array at the given index
*
* Equivalent to:
*
* ary[n] = val
*
* @param mrb The mruby state reference.
* @param ary The target array.
* @param n The array index being referenced.
* @param val The value being setted.
*/
MRB_API void mrb_ary_set(mrb_state *mrb, mrb_value ary, mrb_int n, mrb_value val);
/*
* Replace the array with another array
*
* Equivalent to:
*
* ary.replace(other)
*
* @param mrb The mruby state reference
* @param self The target array.
* @param other The array to replace it with.
*/
MRB_API void mrb_ary_replace(mrb_state *mrb, mrb_value self, mrb_value other);
MRB_API mrb_value mrb_ensure_array_type(mrb_state *mrb, mrb_value self);
MRB_API mrb_value mrb_check_array_type(mrb_state *mrb, mrb_value self);
/*
* Unshift an element into the array
*
* Equivalent to:
*
* ary.unshift(item)
*
* @param mrb The mruby state reference.
* @param self The target array.
* @param item The item to unshift.
*/
MRB_API mrb_value mrb_ary_unshift(mrb_state *mrb, mrb_value self, mrb_value item);
/*
* Get nth element in the array
*
* Equivalent to:
*
* ary[offset]
*
* @param ary The target array.
* @param offset The element position (negative counts from the tail).
*/
MRB_API mrb_value mrb_ary_entry(mrb_value ary, mrb_int offset);
/*
* Replace subsequence of an array.
*
* Equivalent to:
*
* ary.shift
*
* @param mrb The mruby state reference.
* @param self The array from which the value will be shifted.
* @param head Beginning position of a replacement subsequence.
* @param len Length of a replacement subsequence.
* @param rpl The array of replacement elements.
* It is possible to pass `mrb_undef_value()` instead of an empty array.
* @return The receiver array.
*/
MRB_API mrb_value mrb_ary_splice(mrb_state *mrb, mrb_value self, mrb_int head, mrb_int len, mrb_value rpl);
/*
* Shifts the first element from the array.
*
* Equivalent to:
*
* ary.shift
*
* @param mrb The mruby state reference.
* @param self The array from which the value will be shifted.
* @return The shifted value.
*/
MRB_API mrb_value mrb_ary_shift(mrb_state *mrb, mrb_value self);
/*
* Removes all elements from the array
*
* Equivalent to:
*
* ary.clear
*
* @param mrb The mruby state reference.
* @param self The target array.
* @return self
*/
MRB_API mrb_value mrb_ary_clear(mrb_state *mrb, mrb_value self);
/*
* Join the array elements together in a string
*
* Equivalent to:
*
* ary.join(sep="")
*
* @param mrb The mruby state reference.
* @param ary The target array
* @param sep The separater, can be NULL
*/
MRB_API mrb_value mrb_ary_join(mrb_state *mrb, mrb_value ary, mrb_value sep);
/*
* Update the capacity of the array
*
* @param mrb The mruby state reference.
* @param ary The target array.
* @param new_len The new capacity of the array
*/
MRB_API mrb_value mrb_ary_resize(mrb_state *mrb, mrb_value ary, mrb_int new_len);
/* helper functions */
mrb_value mrb_ary_subseq(mrb_state *mrb, mrb_value ary, mrb_int beg, mrb_int len);
MRB_END_DECL
#endif /* MRUBY_ARRAY_H */
+105
View File
@@ -0,0 +1,105 @@
/**
** @file mruby/boxing_nan.h - nan boxing mrb_value definition
**
** See Copyright Notice in mruby.h
*/
#ifndef MRUBY_BOXING_NAN_H
#define MRUBY_BOXING_NAN_H
#ifdef MRB_USE_FLOAT
# error ---->> MRB_NAN_BOXING and MRB_USE_FLOAT conflict <<----
#endif
#ifdef MRB_WITHOUT_FLOAT
# error ---->> MRB_NAN_BOXING and MRB_WITHOUT_FLOAT conflict <<----
#endif
#ifdef MRB_INT64
# error ---->> MRB_NAN_BOXING and MRB_INT64 conflict <<----
#endif
#define MRB_FIXNUM_SHIFT 0
#define MRB_SYMBOL_SHIFT 0
/* value representation by nan-boxing:
* float : FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF
* object: 111111111111TTTT TTPPPPPPPPPPPPPP PPPPPPPPPPPPPPPP PPPPPPPPPPPPPPPP
* int : 1111111111110001 0000000000000000 IIIIIIIIIIIIIIII IIIIIIIIIIIIIIII
* sym : 1111111111110001 0100000000000000 SSSSSSSSSSSSSSSS SSSSSSSSSSSSSSSS
* In order to get enough bit size to save TT, all pointers are shifted 2 bits
* in the right direction. Also, TTTTTT is the mrb_vtype + 1;
*/
typedef struct mrb_value {
union {
mrb_float f;
union {
void *p;
struct {
MRB_ENDIAN_LOHI(
uint32_t ttt;
,union {
mrb_int i;
mrb_sym sym;
};
)
};
#ifdef MRB_64BIT
struct RCptr *vp;
#endif
} value;
};
} mrb_value;
#define mrb_float_pool(mrb,f) mrb_float_value(mrb,f)
#define mrb_tt(o) ((enum mrb_vtype)(((o).value.ttt & 0xfc000)>>14)-1)
#define mrb_type(o) (enum mrb_vtype)((uint32_t)0xfff00000 < (o).value.ttt ? mrb_tt(o) : MRB_TT_FLOAT)
#define mrb_ptr(o) ((void*)((((uintptr_t)0x3fffffffffff)&((uintptr_t)((o).value.p)))<<2))
#define mrb_float(o) (o).f
#define mrb_fixnum(o) (o).value.i
#define mrb_symbol(o) (o).value.sym
#ifdef MRB_64BIT
MRB_API mrb_value mrb_nan_boxing_cptr_value(struct mrb_state*, void*);
#define mrb_cptr(o) (((struct RCptr*)mrb_ptr(o))->p)
#define BOXNAN_SHIFT_LONG_POINTER(v) (((uintptr_t)(v)>>34)&0x3fff)
#else
#define mrb_cptr(o) ((o).value.p)
#define BOXNAN_SHIFT_LONG_POINTER(v) 0
#endif
#define BOXNAN_SET_VALUE(o, tt, attr, v) do {\
(o).attr = (v);\
(o).value.ttt = 0xfff00000 | (((tt)+1)<<14);\
} while (0)
#define BOXNAN_SET_OBJ_VALUE(o, tt, v) do {\
(o).value.p = (void*)((uintptr_t)(v)>>2);\
(o).value.ttt = (0xfff00000|(((tt)+1)<<14)|BOXNAN_SHIFT_LONG_POINTER(v));\
} while (0)
#define SET_FLOAT_VALUE(mrb,r,v) do { \
if ((v) != (v)) { \
(r).value.ttt = 0x7ff80000; \
(r).value.i = 0; \
} \
else { \
(r).f = v; \
}} while(0)
#define SET_NIL_VALUE(r) BOXNAN_SET_VALUE(r, MRB_TT_FALSE, value.i, 0)
#define SET_FALSE_VALUE(r) BOXNAN_SET_VALUE(r, MRB_TT_FALSE, value.i, 1)
#define SET_TRUE_VALUE(r) BOXNAN_SET_VALUE(r, MRB_TT_TRUE, value.i, 1)
#define SET_BOOL_VALUE(r,b) BOXNAN_SET_VALUE(r, b ? MRB_TT_TRUE : MRB_TT_FALSE, value.i, 1)
#define SET_INT_VALUE(r,n) BOXNAN_SET_VALUE(r, MRB_TT_FIXNUM, value.i, (n))
#define SET_SYM_VALUE(r,v) BOXNAN_SET_VALUE(r, MRB_TT_SYMBOL, value.sym, (v))
#define SET_OBJ_VALUE(r,v) BOXNAN_SET_OBJ_VALUE(r, (((struct RObject*)(v))->tt), (v))
#ifdef MRB_64BIT
#define SET_CPTR_VALUE(mrb,r,v) ((r) = mrb_nan_boxing_cptr_value(mrb, v))
#else
#define SET_CPTR_VALUE(mrb,r,v) BOXNAN_SET_VALUE(r, MRB_TT_CPTR, value.p, v)
#endif
#define SET_UNDEF_VALUE(r) BOXNAN_SET_VALUE(r, MRB_TT_UNDEF, value.i, 0)
#endif /* MRUBY_BOXING_NAN_H */
+58
View File
@@ -0,0 +1,58 @@
/**
** @file mruby/boxing_no.h - unboxed mrb_value definition
**
** See Copyright Notice in mruby.h
*/
#ifndef MRUBY_BOXING_NO_H
#define MRUBY_BOXING_NO_H
#define MRB_FIXNUM_SHIFT 0
#define MRB_SYMBOL_SHIFT 0
union mrb_value_union {
#ifndef MRB_WITHOUT_FLOAT
mrb_float f;
#endif
void *p;
mrb_int i;
mrb_sym sym;
};
typedef struct mrb_value {
union mrb_value_union value;
enum mrb_vtype tt;
} mrb_value;
#ifndef MRB_WITHOUT_FLOAT
#define mrb_float_pool(mrb,f) mrb_float_value(mrb,f)
#endif
#define mrb_ptr(o) (o).value.p
#define mrb_cptr(o) mrb_ptr(o)
#ifndef MRB_WITHOUT_FLOAT
#define mrb_float(o) (o).value.f
#endif
#define mrb_fixnum(o) (o).value.i
#define mrb_symbol(o) (o).value.sym
#define mrb_type(o) (o).tt
#define BOXNIX_SET_VALUE(o, ttt, attr, v) do {\
(o).tt = ttt;\
(o).attr = v;\
} while (0)
#define SET_NIL_VALUE(r) BOXNIX_SET_VALUE(r, MRB_TT_FALSE, value.i, 0)
#define SET_FALSE_VALUE(r) BOXNIX_SET_VALUE(r, MRB_TT_FALSE, value.i, 1)
#define SET_TRUE_VALUE(r) BOXNIX_SET_VALUE(r, MRB_TT_TRUE, value.i, 1)
#define SET_BOOL_VALUE(r,b) BOXNIX_SET_VALUE(r, b ? MRB_TT_TRUE : MRB_TT_FALSE, value.i, 1)
#define SET_INT_VALUE(r,n) BOXNIX_SET_VALUE(r, MRB_TT_FIXNUM, value.i, (n))
#ifndef MRB_WITHOUT_FLOAT
#define SET_FLOAT_VALUE(mrb,r,v) BOXNIX_SET_VALUE(r, MRB_TT_FLOAT, value.f, (v))
#endif
#define SET_SYM_VALUE(r,v) BOXNIX_SET_VALUE(r, MRB_TT_SYMBOL, value.sym, (v))
#define SET_OBJ_VALUE(r,v) BOXNIX_SET_VALUE(r, (((struct RObject*)(v))->tt), value.p, (v))
#define SET_CPTR_VALUE(mrb,r,v) BOXNIX_SET_VALUE(r, MRB_TT_CPTR, value.p, v)
#define SET_UNDEF_VALUE(r) BOXNIX_SET_VALUE(r, MRB_TT_UNDEF, value.i, 0)
#endif /* MRUBY_BOXING_NO_H */
+174
View File
@@ -0,0 +1,174 @@
/**
** @file mruby/boxing_word.h - word boxing mrb_value definition
**
** See Copyright Notice in mruby.h
*/
#ifndef MRUBY_BOXING_WORD_H
#define MRUBY_BOXING_WORD_H
#if defined(MRB_INT64) && !defined(MRB_64BIT)
#error MRB_INT64 cannot be used with MRB_WORD_BOXING in 32-bit mode.
#endif
#ifndef MRB_WITHOUT_FLOAT
struct RFloat {
MRB_OBJECT_HEADER;
mrb_float f;
};
#endif
enum mrb_special_consts {
MRB_Qnil = 0,
MRB_Qfalse = 4,
MRB_Qtrue = 12,
MRB_Qundef = 20,
};
#if defined(MRB_64BIT) && defined(MRB_INT32)
#define MRB_FIXNUM_SHIFT 0
#else
#define MRB_FIXNUM_SHIFT BOXWORD_FIXNUM_SHIFT
#endif
#define MRB_SYMBOL_SHIFT BOXWORD_SYMBOL_SHIFT
#define BOXWORD_FIXNUM_BIT_POS 1
#define BOXWORD_SYMBOL_BIT_POS 2
#define BOXWORD_FIXNUM_SHIFT BOXWORD_FIXNUM_BIT_POS
#ifdef MRB_64BIT
#define BOXWORD_SYMBOL_SHIFT 0
#else
#define BOXWORD_SYMBOL_SHIFT BOXWORD_SYMBOL_BIT_POS
#endif
#define BOXWORD_FIXNUM_FLAG (1 << (BOXWORD_FIXNUM_BIT_POS - 1))
#define BOXWORD_SYMBOL_FLAG (1 << (BOXWORD_SYMBOL_BIT_POS - 1))
#define BOXWORD_FIXNUM_MASK ((1 << BOXWORD_FIXNUM_BIT_POS) - 1)
#define BOXWORD_SYMBOL_MASK ((1 << BOXWORD_SYMBOL_BIT_POS) - 1)
#define BOXWORD_IMMEDIATE_MASK 0x07
#define BOXWORD_SHIFT_VALUE(o,n,t) \
(t)(((long)(o).w) >> BOXWORD_##n##_SHIFT)
#define BOXWORD_SET_SHIFT_VALUE(o,n,v) \
((o).w = (((unsigned long)(v)) << BOXWORD_##n##_SHIFT) | BOXWORD_##n##_FLAG)
#define BOXWORD_SHIFT_VALUE_P(o,n) \
(((o).w & BOXWORD_##n##_MASK) == BOXWORD_##n##_FLAG)
#define BOXWORD_OBJ_TYPE_P(o,n) \
(!mrb_immediate_p(o) && (o).value.bp->tt == MRB_TT_##n)
/*
* mrb_value representation:
*
* nil : ...0000 0000 (all bits are 0)
* false : ...0000 0100 (mrb_fixnum(v) != 0)
* true : ...0000 1100
* undef : ...0001 0100
* fixnum: ...IIII III1
* symbol: ...SSSS SS10 (use only upper 32-bit as symbol value on 64-bit CPU)
* object: ...PPPP P000 (any bits are 1)
*/
typedef union mrb_value {
union {
void *p;
#ifdef MRB_64BIT
/* use struct to avoid bit shift. */
struct {
MRB_ENDIAN_LOHI(
mrb_sym sym;
,uint32_t sym_flag;
)
};
#endif
struct RBasic *bp;
#ifndef MRB_WITHOUT_FLOAT
struct RFloat *fp;
#endif
struct RCptr *vp;
} value;
unsigned long w;
} mrb_value;
MRB_API mrb_value mrb_word_boxing_cptr_value(struct mrb_state*, void*);
#ifndef MRB_WITHOUT_FLOAT
MRB_API mrb_value mrb_word_boxing_float_value(struct mrb_state*, mrb_float);
MRB_API mrb_value mrb_word_boxing_float_pool(struct mrb_state*, mrb_float);
#endif
#ifndef MRB_WITHOUT_FLOAT
#define mrb_float_pool(mrb,f) mrb_word_boxing_float_pool(mrb,f)
#endif
#define mrb_ptr(o) (o).value.p
#define mrb_cptr(o) (o).value.vp->p
#ifndef MRB_WITHOUT_FLOAT
#define mrb_float(o) (o).value.fp->f
#endif
#define mrb_fixnum(o) BOXWORD_SHIFT_VALUE(o, FIXNUM, mrb_int)
#ifdef MRB_64BIT
#define mrb_symbol(o) (o).value.sym
#else
#define mrb_symbol(o) BOXWORD_SHIFT_VALUE(o, SYMBOL, mrb_sym)
#endif
#define mrb_bool(o) (((o).w & ~(unsigned long)MRB_Qfalse) != 0)
#define mrb_immediate_p(o) ((o).w & BOXWORD_IMMEDIATE_MASK || (o).w == MRB_Qnil)
#define mrb_fixnum_p(o) BOXWORD_SHIFT_VALUE_P(o, FIXNUM)
#ifdef MRB_64BIT
#define mrb_symbol_p(o) ((o).value.sym_flag == BOXWORD_SYMBOL_FLAG)
#else
#define mrb_symbol_p(o) BOXWORD_SHIFT_VALUE_P(o, SYMBOL)
#endif
#define mrb_undef_p(o) ((o).w == MRB_Qundef)
#define mrb_nil_p(o) ((o).w == MRB_Qnil)
#define mrb_false_p(o) ((o).w == MRB_Qfalse)
#define mrb_true_p(o) ((o).w == MRB_Qtrue)
#ifndef MRB_WITHOUT_FLOAT
#define mrb_float_p(o) BOXWORD_OBJ_TYPE_P(o, FLOAT)
#endif
#define mrb_array_p(o) BOXWORD_OBJ_TYPE_P(o, ARRAY)
#define mrb_string_p(o) BOXWORD_OBJ_TYPE_P(o, STRING)
#define mrb_hash_p(o) BOXWORD_OBJ_TYPE_P(o, HASH)
#define mrb_cptr_p(o) BOXWORD_OBJ_TYPE_P(o, CPTR)
#define mrb_exception_p(o) BOXWORD_OBJ_TYPE_P(o, EXCEPTION)
#define mrb_free_p(o) BOXWORD_OBJ_TYPE_P(o, FREE)
#define mrb_object_p(o) BOXWORD_OBJ_TYPE_P(o, OBJECT)
#define mrb_class_p(o) BOXWORD_OBJ_TYPE_P(o, CLASS)
#define mrb_module_p(o) BOXWORD_OBJ_TYPE_P(o, MODULE)
#define mrb_iclass_p(o) BOXWORD_OBJ_TYPE_P(o, ICLASS)
#define mrb_sclass_p(o) BOXWORD_OBJ_TYPE_P(o, SCLASS)
#define mrb_proc_p(o) BOXWORD_OBJ_TYPE_P(o, PROC)
#define mrb_range_p(o) BOXWORD_OBJ_TYPE_P(o, RANGE)
#define mrb_env_p(o) BOXWORD_OBJ_TYPE_P(o, ENV)
#define mrb_data_p(o) BOXWORD_OBJ_TYPE_P(o, DATA)
#define mrb_fiber_p(o) BOXWORD_OBJ_TYPE_P(o, FIBER)
#define mrb_istruct_p(o) BOXWORD_OBJ_TYPE_P(o, ISTRUCT)
#define mrb_break_p(o) BOXWORD_OBJ_TYPE_P(o, BREAK)
#ifndef MRB_WITHOUT_FLOAT
#define SET_FLOAT_VALUE(mrb,r,v) ((r) = mrb_word_boxing_float_value(mrb, v))
#endif
#define SET_CPTR_VALUE(mrb,r,v) ((r) = mrb_word_boxing_cptr_value(mrb, v))
#define SET_UNDEF_VALUE(r) ((r).w = MRB_Qundef)
#define SET_NIL_VALUE(r) ((r).w = MRB_Qnil)
#define SET_FALSE_VALUE(r) ((r).w = MRB_Qfalse)
#define SET_TRUE_VALUE(r) ((r).w = MRB_Qtrue)
#define SET_BOOL_VALUE(r,b) ((b) ? SET_TRUE_VALUE(r) : SET_FALSE_VALUE(r))
#define SET_INT_VALUE(r,n) BOXWORD_SET_SHIFT_VALUE(r, FIXNUM, n)
#ifdef MRB_64BIT
#define SET_SYM_VALUE(r,v) ((r).value.sym = v, (r).value.sym_flag = BOXWORD_SYMBOL_FLAG)
#else
#define SET_SYM_VALUE(r,n) BOXWORD_SET_SHIFT_VALUE(r, SYMBOL, n)
#endif
#define SET_OBJ_VALUE(r,v) ((r).value.p = v)
MRB_INLINE enum mrb_vtype
mrb_type(mrb_value o)
{
return !mrb_bool(o) ? MRB_TT_FALSE :
mrb_true_p(o) ? MRB_TT_TRUE :
mrb_fixnum_p(o) ? MRB_TT_FIXNUM :
mrb_symbol_p(o) ? MRB_TT_SYMBOL :
mrb_undef_p(o) ? MRB_TT_UNDEF :
o.value.bp->tt;
}
#endif /* MRUBY_BOXING_WORD_H */
+106
View File
@@ -0,0 +1,106 @@
/**
** @file mruby/class.h - Class class
**
** See Copyright Notice in mruby.h
*/
#ifndef MRUBY_CLASS_H
#define MRUBY_CLASS_H
#include "common.h"
/**
* Class class
*/
MRB_BEGIN_DECL
struct RClass {
MRB_OBJECT_HEADER;
struct iv_tbl *iv;
struct kh_mt *mt;
struct RClass *super;
};
#define mrb_class_ptr(v) ((struct RClass*)(mrb_ptr(v)))
MRB_INLINE struct RClass*
mrb_class(mrb_state *mrb, mrb_value v)
{
switch (mrb_type(v)) {
case MRB_TT_FALSE:
if (mrb_fixnum(v))
return mrb->false_class;
return mrb->nil_class;
case MRB_TT_TRUE:
return mrb->true_class;
case MRB_TT_SYMBOL:
return mrb->symbol_class;
case MRB_TT_FIXNUM:
return mrb->fixnum_class;
#ifndef MRB_WITHOUT_FLOAT
case MRB_TT_FLOAT:
return mrb->float_class;
#endif
case MRB_TT_CPTR:
return mrb->object_class;
case MRB_TT_ENV:
return NULL;
default:
return mrb_obj_ptr(v)->c;
}
}
/* flags:
20: frozen
19: is_prepended
18: is_origin
17: is_inherited (used by method cache)
16: unused
0-15: instance type
*/
#define MRB_FL_CLASS_IS_PREPENDED (1 << 19)
#define MRB_FL_CLASS_IS_ORIGIN (1 << 18)
#define MRB_CLASS_ORIGIN(c) do {\
if ((c)->flags & MRB_FL_CLASS_IS_PREPENDED) {\
(c) = (c)->super;\
while (!((c)->flags & MRB_FL_CLASS_IS_ORIGIN)) {\
(c) = (c)->super;\
}\
}\
} while (0)
#define MRB_FL_CLASS_IS_INHERITED (1 << 17)
#define MRB_INSTANCE_TT_MASK (0xFF)
#define MRB_SET_INSTANCE_TT(c, tt) ((c)->flags = (((c)->flags & ~MRB_INSTANCE_TT_MASK) | (char)(tt)))
#define MRB_INSTANCE_TT(c) (enum mrb_vtype)((c)->flags & MRB_INSTANCE_TT_MASK)
MRB_API struct RClass* mrb_define_class_id(mrb_state*, mrb_sym, struct RClass*);
MRB_API struct RClass* mrb_define_module_id(mrb_state*, mrb_sym);
struct RClass *mrb_vm_define_class(mrb_state*, mrb_value, mrb_value, mrb_sym);
struct RClass *mrb_vm_define_module(mrb_state*, mrb_value, mrb_sym);
MRB_API void mrb_define_method_raw(mrb_state*, struct RClass*, mrb_sym, mrb_method_t);
MRB_API void mrb_define_method_id(mrb_state *mrb, struct RClass *c, mrb_sym mid, mrb_func_t func, mrb_aspec aspec);
MRB_API void mrb_alias_method(mrb_state*, struct RClass *c, mrb_sym a, mrb_sym b);
MRB_API mrb_method_t mrb_method_search_vm(mrb_state*, struct RClass**, mrb_sym);
MRB_API mrb_method_t mrb_method_search(mrb_state*, struct RClass*, mrb_sym);
MRB_API struct RClass* mrb_class_real(struct RClass* cl);
mrb_value mrb_instance_new(mrb_state *mrb, mrb_value cv);
void mrb_class_name_class(mrb_state*, struct RClass*, struct RClass*, mrb_sym);
mrb_bool mrb_const_name_p(mrb_state*, const char*, mrb_int);
mrb_value mrb_class_find_path(mrb_state*, struct RClass*);
mrb_value mrb_mod_to_s(mrb_state*, mrb_value);
void mrb_gc_mark_mt(mrb_state*, struct RClass*);
size_t mrb_gc_mark_mt_size(mrb_state*, struct RClass*);
void mrb_gc_free_mt(mrb_state*, struct RClass*);
#ifdef MRB_METHOD_CACHE
void mrb_mc_clear_by_class(mrb_state *mrb, struct RClass* c);
#else
#define mrb_mc_clear_by_class(mrb,c)
#endif
MRB_END_DECL
#endif /* MRUBY_CLASS_H */
+89
View File
@@ -0,0 +1,89 @@
/**
** @file common.h - mruby common platform definition"
**
** See Copyright Notice in mruby.h
*/
#ifndef MRUBY_COMMON_H
#define MRUBY_COMMON_H
#ifdef __APPLE__
#ifndef __TARGETCONDITIONALS__
#include "TargetConditionals.h"
#endif
#endif
#ifdef __cplusplus
#ifdef MRB_ENABLE_CXX_ABI
#define MRB_BEGIN_DECL
#define MRB_END_DECL
#else
# define MRB_BEGIN_DECL extern "C" {
# define MRB_END_DECL }
#endif
#else
/** Start declarations in C mode */
# define MRB_BEGIN_DECL
/** End declarations in C mode */
# define MRB_END_DECL
#endif
/**
* Shared compiler macros
*/
MRB_BEGIN_DECL
/** Declare a function that never returns. */
#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 201112L
# define mrb_noreturn _Noreturn
#elif defined __GNUC__ && !defined __STRICT_ANSI__
# define mrb_noreturn __attribute__((noreturn))
#elif defined _MSC_VER
# define mrb_noreturn __declspec(noreturn)
#else
# define mrb_noreturn
#endif
/** Mark a function as deprecated. */
#if defined __GNUC__ && !defined __STRICT_ANSI__
# define mrb_deprecated __attribute__((deprecated))
#elif defined _MSC_VER
# define mrb_deprecated __declspec(deprecated)
#else
# define mrb_deprecated
#endif
/** Declare a function as always inlined. */
#if defined _MSC_VER && _MSC_VER < 1900
# ifndef __cplusplus
# define inline __inline
# endif
#endif
#define MRB_INLINE static inline
/** Declare a public MRuby API function. */
#ifndef MRB_API
#if defined(MRB_BUILD_AS_DLL)
#if defined(MRB_CORE) || defined(MRB_LIB)
# define MRB_API __declspec(dllexport)
#else
# define MRB_API __declspec(dllimport)
#endif
#else
# define MRB_API extern
#endif
#endif
/** Declare mingw versions */
#if defined(__MINGW32__) || defined(__MINGW64__)
# include <_mingw.h>
# if defined(__MINGW64_VERSION_MAJOR)
# define MRB_MINGW64_VERSION (__MINGW64_VERSION_MAJOR * 1000 + __MINGW64_VERSION_MINOR)
# elif defined(__MINGW32_MAJOR_VERSION)
# define MRB_MINGW32_VERSION (__MINGW32_MAJOR_VERSION * 1000 + __MINGW32_MINOR_VERSION)
# endif
#endif
MRB_END_DECL
#endif /* MRUBY_COMMON_H */
+204
View File
@@ -0,0 +1,204 @@
/**
** @file mruby/compile.h - mruby parser
**
** See Copyright Notice in mruby.h
*/
#ifndef MRUBY_COMPILE_H
#define MRUBY_COMPILE_H
#include "common.h"
/**
* MRuby Compiler
*/
MRB_BEGIN_DECL
#include <mruby.h>
struct mrb_jmpbuf;
struct mrb_parser_state;
/* load context */
typedef struct mrbc_context {
mrb_sym *syms;
int slen;
char *filename;
uint16_t lineno;
int (*partial_hook)(struct mrb_parser_state*);
void *partial_data;
struct RClass *target_class;
mrb_bool capture_errors:1;
mrb_bool dump_result:1;
mrb_bool no_exec:1;
mrb_bool keep_lv:1;
mrb_bool no_optimize:1;
struct RProc *upper;
size_t parser_nerr;
} mrbc_context;
MRB_API mrbc_context* mrbc_context_new(mrb_state *mrb);
MRB_API void mrbc_context_free(mrb_state *mrb, mrbc_context *cxt);
MRB_API const char *mrbc_filename(mrb_state *mrb, mrbc_context *c, const char *s);
MRB_API void mrbc_partial_hook(mrb_state *mrb, mrbc_context *c, int (*partial_hook)(struct mrb_parser_state*), void*data);
/* AST node structure */
typedef struct mrb_ast_node {
struct mrb_ast_node *car, *cdr;
uint16_t lineno, filename_index;
} mrb_ast_node;
/* lexer states */
enum mrb_lex_state_enum {
EXPR_BEG, /* ignore newline, +/- is a sign. */
EXPR_END, /* newline significant, +/- is an operator. */
EXPR_ENDARG, /* ditto, and unbound braces. */
EXPR_ENDFN, /* ditto, and unbound braces. */
EXPR_ARG, /* newline significant, +/- is an operator. */
EXPR_CMDARG, /* newline significant, +/- is an operator. */
EXPR_MID, /* newline significant, +/- is an operator. */
EXPR_FNAME, /* ignore newline, no reserved words. */
EXPR_DOT, /* right after '.' or '::', no reserved words. */
EXPR_CLASS, /* immediate after 'class', no here document. */
EXPR_VALUE, /* alike EXPR_BEG but label is disallowed. */
EXPR_MAX_STATE
};
/* saved error message */
struct mrb_parser_message {
uint16_t lineno;
int column;
char* message;
};
#define STR_FUNC_PARSING 0x01
#define STR_FUNC_EXPAND 0x02
#define STR_FUNC_REGEXP 0x04
#define STR_FUNC_WORD 0x08
#define STR_FUNC_SYMBOL 0x10
#define STR_FUNC_ARRAY 0x20
#define STR_FUNC_HEREDOC 0x40
#define STR_FUNC_XQUOTE 0x80
enum mrb_string_type {
str_not_parsing = (0),
str_squote = (STR_FUNC_PARSING),
str_dquote = (STR_FUNC_PARSING|STR_FUNC_EXPAND),
str_regexp = (STR_FUNC_PARSING|STR_FUNC_REGEXP|STR_FUNC_EXPAND),
str_sword = (STR_FUNC_PARSING|STR_FUNC_WORD|STR_FUNC_ARRAY),
str_dword = (STR_FUNC_PARSING|STR_FUNC_WORD|STR_FUNC_ARRAY|STR_FUNC_EXPAND),
str_ssym = (STR_FUNC_PARSING|STR_FUNC_SYMBOL),
str_ssymbols = (STR_FUNC_PARSING|STR_FUNC_SYMBOL|STR_FUNC_ARRAY),
str_dsymbols = (STR_FUNC_PARSING|STR_FUNC_SYMBOL|STR_FUNC_ARRAY|STR_FUNC_EXPAND),
str_heredoc = (STR_FUNC_PARSING|STR_FUNC_HEREDOC),
str_xquote = (STR_FUNC_PARSING|STR_FUNC_XQUOTE|STR_FUNC_EXPAND),
};
/* heredoc structure */
struct mrb_parser_heredoc_info {
mrb_bool allow_indent:1;
mrb_bool line_head:1;
enum mrb_string_type type;
const char *term;
int term_len;
mrb_ast_node *doc;
};
#define MRB_PARSER_TOKBUF_MAX (UINT16_MAX-1)
#define MRB_PARSER_TOKBUF_SIZE 256
/* parser structure */
struct mrb_parser_state {
mrb_state *mrb;
struct mrb_pool *pool;
mrb_ast_node *cells;
const char *s, *send;
#ifndef MRB_DISABLE_STDIO
FILE *f;
#endif
mrbc_context *cxt;
mrb_sym filename_sym;
uint16_t lineno;
int column;
enum mrb_lex_state_enum lstate;
mrb_ast_node *lex_strterm; /* (type nest_level beg . end) */
unsigned int cond_stack;
unsigned int cmdarg_stack;
int paren_nest;
int lpar_beg;
int in_def, in_single;
mrb_bool cmd_start:1;
mrb_ast_node *locals;
mrb_ast_node *pb;
char *tokbuf;
char buf[MRB_PARSER_TOKBUF_SIZE];
int tidx;
int tsiz;
mrb_ast_node *all_heredocs; /* list of mrb_parser_heredoc_info* */
mrb_ast_node *heredocs_from_nextline;
mrb_ast_node *parsing_heredoc;
mrb_ast_node *lex_strterm_before_heredoc;
void *ylval;
size_t nerr;
size_t nwarn;
mrb_ast_node *tree;
mrb_bool no_optimize:1;
mrb_bool capture_errors:1;
struct RProc *upper;
struct mrb_parser_message error_buffer[10];
struct mrb_parser_message warn_buffer[10];
mrb_sym* filename_table;
uint16_t filename_table_length;
uint16_t current_filename_index;
struct mrb_jmpbuf* jmp;
mrb_ast_node *nvars;
};
MRB_API struct mrb_parser_state* mrb_parser_new(mrb_state*);
MRB_API void mrb_parser_free(struct mrb_parser_state*);
MRB_API void mrb_parser_parse(struct mrb_parser_state*,mrbc_context*);
MRB_API void mrb_parser_set_filename(struct mrb_parser_state*, char const*);
MRB_API mrb_sym mrb_parser_get_filename(struct mrb_parser_state*, uint16_t idx);
/* utility functions */
#ifndef MRB_DISABLE_STDIO
MRB_API struct mrb_parser_state* mrb_parse_file(mrb_state*,FILE*,mrbc_context*);
#endif
MRB_API struct mrb_parser_state* mrb_parse_string(mrb_state*,const char*,mrbc_context*);
MRB_API struct mrb_parser_state* mrb_parse_nstring(mrb_state*,const char*,size_t,mrbc_context*);
MRB_API struct RProc* mrb_generate_code(mrb_state*, struct mrb_parser_state*);
MRB_API mrb_value mrb_load_exec(mrb_state *mrb, struct mrb_parser_state *p, mrbc_context *c);
/** program load functions
* Please note! Currently due to interactions with the GC calling these functions will
* leak one RProc object per function call.
* To prevent this save the current memory arena before calling and restore the arena
* right after, like so
* int ai = mrb_gc_arena_save(mrb);
* mrb_value status = mrb_load_string(mrb, buffer);
* mrb_gc_arena_restore(mrb, ai);
*/
#ifndef MRB_DISABLE_STDIO
MRB_API mrb_value mrb_load_file(mrb_state*,FILE*);
MRB_API mrb_value mrb_load_file_cxt(mrb_state*,FILE*, mrbc_context *cxt);
#endif
MRB_API mrb_value mrb_load_string(mrb_state *mrb, const char *s);
MRB_API mrb_value mrb_load_nstring(mrb_state *mrb, const char *s, size_t len);
MRB_API mrb_value mrb_load_string_cxt(mrb_state *mrb, const char *s, mrbc_context *cxt);
MRB_API mrb_value mrb_load_nstring_cxt(mrb_state *mrb, const char *s, size_t len, mrbc_context *cxt);
/** @} */
MRB_END_DECL
#endif /* MRUBY_COMPILE_H */
+76
View File
@@ -0,0 +1,76 @@
/**
** @file mruby/data.h - Data class
**
** See Copyright Notice in mruby.h
*/
#ifndef MRUBY_DATA_H
#define MRUBY_DATA_H
#include "common.h"
/**
* Custom C wrapped data.
*
* Defining Ruby wrappers around native objects.
*/
MRB_BEGIN_DECL
/**
* Custom data type description.
*/
typedef struct mrb_data_type {
/** data type name */
const char *struct_name;
/** data type release function pointer */
void (*dfree)(mrb_state *mrb, void*);
} mrb_data_type;
struct RData {
MRB_OBJECT_HEADER;
struct iv_tbl *iv;
const mrb_data_type *type;
void *data;
};
MRB_API struct RData *mrb_data_object_alloc(mrb_state *mrb, struct RClass* klass, void *datap, const mrb_data_type *type);
#define Data_Wrap_Struct(mrb,klass,type,ptr)\
mrb_data_object_alloc(mrb,klass,ptr,type)
#define Data_Make_Struct(mrb,klass,strct,type,sval,data_obj) do { \
(data_obj) = Data_Wrap_Struct(mrb,klass,type,NULL);\
(sval) = (strct *)mrb_malloc(mrb, sizeof(strct)); \
{ static const strct zero = { 0 }; *(sval) = zero; };\
(data_obj)->data = (sval);\
} while (0)
#define RDATA(obj) ((struct RData *)(mrb_ptr(obj)))
#define DATA_PTR(d) (RDATA(d)->data)
#define DATA_TYPE(d) (RDATA(d)->type)
MRB_API void mrb_data_check_type(mrb_state *mrb, mrb_value, const mrb_data_type*);
MRB_API void *mrb_data_get_ptr(mrb_state *mrb, mrb_value, const mrb_data_type*);
#define DATA_GET_PTR(mrb,obj,dtype,type) (type*)mrb_data_get_ptr(mrb,obj,dtype)
MRB_API void *mrb_data_check_get_ptr(mrb_state *mrb, mrb_value, const mrb_data_type*);
#define DATA_CHECK_GET_PTR(mrb,obj,dtype,type) (type*)mrb_data_check_get_ptr(mrb,obj,dtype)
/* obsolete functions and macros */
#define mrb_data_check_and_get(mrb,obj,dtype) mrb_data_get_ptr(mrb,obj,dtype)
#define mrb_get_datatype(mrb,val,type) mrb_data_get_ptr(mrb, val, type)
#define mrb_check_datatype(mrb,val,type) mrb_data_get_ptr(mrb, val, type)
#define Data_Get_Struct(mrb,obj,type,sval) do {\
*(void**)&sval = mrb_data_get_ptr(mrb, obj, type); \
} while (0)
MRB_INLINE void
mrb_data_init(mrb_value v, void *ptr, const mrb_data_type *type)
{
mrb_assert(mrb_data_p(v));
DATA_PTR(v) = ptr;
DATA_TYPE(v) = type;
}
MRB_END_DECL
#endif /* MRUBY_DATA_H */
+66
View File
@@ -0,0 +1,66 @@
/**
** @file mruby/debug.h - mruby debug info
**
** See Copyright Notice in mruby.h
*/
#ifndef MRUBY_DEBUG_H
#define MRUBY_DEBUG_H
#include "common.h"
/**
* MRuby Debugging.
*/
MRB_BEGIN_DECL
typedef enum mrb_debug_line_type {
mrb_debug_line_ary = 0,
mrb_debug_line_flat_map = 1
} mrb_debug_line_type;
typedef struct mrb_irep_debug_info_line {
uint32_t start_pos;
uint16_t line;
} mrb_irep_debug_info_line;
typedef struct mrb_irep_debug_info_file {
uint32_t start_pos;
mrb_sym filename_sym;
uint32_t line_entry_count;
mrb_debug_line_type line_type;
union {
void *ptr;
mrb_irep_debug_info_line *flat_map;
uint16_t *ary;
} lines;
} mrb_irep_debug_info_file;
typedef struct mrb_irep_debug_info {
uint32_t pc_count;
uint16_t flen;
mrb_irep_debug_info_file **files;
} mrb_irep_debug_info;
/*
* get line from irep's debug info and program counter
* @return returns NULL if not found
*/
MRB_API const char *mrb_debug_get_filename(mrb_state *mrb, mrb_irep *irep, ptrdiff_t pc);
/*
* get line from irep's debug info and program counter
* @return returns -1 if not found
*/
MRB_API int32_t mrb_debug_get_line(mrb_state *mrb, mrb_irep *irep, ptrdiff_t pc);
MRB_API mrb_irep_debug_info *mrb_debug_info_alloc(mrb_state *mrb, mrb_irep *irep);
MRB_API mrb_irep_debug_info_file *mrb_debug_info_append_file(
mrb_state *mrb, mrb_irep_debug_info *info,
const char *filename, uint16_t *lines,
uint32_t start_pos, uint32_t end_pos);
MRB_API void mrb_debug_info_free(mrb_state *mrb, mrb_irep_debug_info *d);
MRB_END_DECL
#endif /* MRUBY_DEBUG_H */
+176
View File
@@ -0,0 +1,176 @@
/**
** @file mruby/dump.h - mruby binary dumper (mrbc binary format)
**
** See Copyright Notice in mruby.h
*/
#ifndef MRUBY_DUMP_H
#define MRUBY_DUMP_H
#include <mruby.h>
#include <mruby/irep.h>
#include "common.h"
/**
* Dumping compiled mruby script.
*/
MRB_BEGIN_DECL
#define DUMP_DEBUG_INFO 1
int mrb_dump_irep(mrb_state *mrb, mrb_irep *irep, uint8_t flags, uint8_t **bin, size_t *bin_size);
#ifndef MRB_DISABLE_STDIO
int mrb_dump_irep_binary(mrb_state*, mrb_irep*, uint8_t, FILE*);
int mrb_dump_irep_cfunc(mrb_state *mrb, mrb_irep*, uint8_t flags, FILE *f, const char *initname);
mrb_irep *mrb_read_irep_file(mrb_state*, FILE*);
MRB_API mrb_value mrb_load_irep_file(mrb_state*,FILE*);
MRB_API mrb_value mrb_load_irep_file_cxt(mrb_state*, FILE*, mrbc_context*);
#endif
MRB_API mrb_irep *mrb_read_irep(mrb_state*, const uint8_t*);
MRB_API mrb_irep *mrb_read_irep_buf(mrb_state*, const void*, size_t);
/* dump/load error code
*
* NOTE: MRB_DUMP_GENERAL_FAILURE is caused by
* unspecified issues like malloc failed.
*/
#define MRB_DUMP_OK 0
#define MRB_DUMP_GENERAL_FAILURE (-1)
#define MRB_DUMP_WRITE_FAULT (-2)
#define MRB_DUMP_READ_FAULT (-3)
#define MRB_DUMP_CRC_ERROR (-4)
#define MRB_DUMP_INVALID_FILE_HEADER (-5)
#define MRB_DUMP_INVALID_IREP (-6)
#define MRB_DUMP_INVALID_ARGUMENT (-7)
/* null symbol length */
#define MRB_DUMP_NULL_SYM_LEN 0xFFFF
/* Rite Binary File header */
#define RITE_BINARY_IDENT "RITE"
#define RITE_BINARY_FORMAT_VER "0007"
#define RITE_COMPILER_NAME "MATZ"
#define RITE_COMPILER_VERSION "0000"
#define RITE_VM_VER "0002"
#define RITE_BINARY_EOF "END\0"
#define RITE_SECTION_IREP_IDENT "IREP"
#define RITE_SECTION_DEBUG_IDENT "DBG\0"
#define RITE_SECTION_LV_IDENT "LVAR"
#define MRB_DUMP_DEFAULT_STR_LEN 128
#define MRB_DUMP_ALIGNMENT sizeof(uint32_t)
/* binary header */
struct rite_binary_header {
uint8_t binary_ident[4]; /* Binary Identifier */
uint8_t binary_version[4]; /* Binary Format Version */
uint8_t binary_crc[2]; /* Binary CRC */
uint8_t binary_size[4]; /* Binary Size */
uint8_t compiler_name[4]; /* Compiler name */
uint8_t compiler_version[4];
};
/* section header */
#define RITE_SECTION_HEADER \
uint8_t section_ident[4]; \
uint8_t section_size[4]
struct rite_section_header {
RITE_SECTION_HEADER;
};
struct rite_section_irep_header {
RITE_SECTION_HEADER;
uint8_t rite_version[4]; /* Rite Instruction Specification Version */
};
struct rite_section_debug_header {
RITE_SECTION_HEADER;
};
struct rite_section_lv_header {
RITE_SECTION_HEADER;
};
#define RITE_LV_NULL_MARK UINT16_MAX
struct rite_binary_footer {
RITE_SECTION_HEADER;
};
static inline size_t
uint8_to_bin(uint8_t s, uint8_t *bin)
{
*bin = s;
return sizeof(uint8_t);
}
static inline size_t
uint16_to_bin(uint16_t s, uint8_t *bin)
{
*bin++ = (s >> 8) & 0xff;
*bin = s & 0xff;
return sizeof(uint16_t);
}
static inline size_t
uint32_to_bin(uint32_t l, uint8_t *bin)
{
*bin++ = (l >> 24) & 0xff;
*bin++ = (l >> 16) & 0xff;
*bin++ = (l >> 8) & 0xff;
*bin = l & 0xff;
return sizeof(uint32_t);
}
static inline size_t
uint32l_to_bin(uint32_t l, uint8_t *bin)
{
bin[3] = (l >> 24) & 0xff;
bin[2] = (l >> 16) & 0xff;
bin[1] = (l >> 8) & 0xff;
bin[0] = l & 0xff;
return sizeof(uint32_t);
}
static inline uint32_t
bin_to_uint32(const uint8_t *bin)
{
return (uint32_t)bin[0] << 24 |
(uint32_t)bin[1] << 16 |
(uint32_t)bin[2] << 8 |
(uint32_t)bin[3];
}
static inline uint32_t
bin_to_uint32l(const uint8_t *bin)
{
return (uint32_t)bin[3] << 24 |
(uint32_t)bin[2] << 16 |
(uint32_t)bin[1] << 8 |
(uint32_t)bin[0];
}
static inline uint16_t
bin_to_uint16(const uint8_t *bin)
{
return (uint16_t)bin[0] << 8 |
(uint16_t)bin[1];
}
static inline uint8_t
bin_to_uint8(const uint8_t *bin)
{
return (uint8_t)bin[0];
}
MRB_END_DECL
/** @internal crc.c */
uint16_t
calc_crc_16_ccitt(const uint8_t *src, size_t nbytes, uint16_t crc);
#endif /* MRUBY_DUMP_H */
+103
View File
@@ -0,0 +1,103 @@
/**
** @file mruby/error.h - Exception class
**
** See Copyright Notice in mruby.h
*/
#ifndef MRUBY_ERROR_H
#define MRUBY_ERROR_H
#include "common.h"
/**
* MRuby error handling.
*/
MRB_BEGIN_DECL
struct RException {
MRB_OBJECT_HEADER;
struct iv_tbl *iv;
};
#define mrb_exc_ptr(v) ((struct RException*)mrb_ptr(v))
MRB_API void mrb_sys_fail(mrb_state *mrb, const char *mesg);
MRB_API mrb_value mrb_exc_new_str(mrb_state *mrb, struct RClass* c, mrb_value str);
#define mrb_exc_new_str_lit(mrb, c, lit) mrb_exc_new_str(mrb, c, mrb_str_new_lit(mrb, lit))
MRB_API mrb_value mrb_make_exception(mrb_state *mrb, mrb_int argc, const mrb_value *argv);
MRB_API mrb_value mrb_exc_backtrace(mrb_state *mrb, mrb_value exc);
MRB_API mrb_value mrb_get_backtrace(mrb_state *mrb);
MRB_API mrb_noreturn void mrb_no_method_error(mrb_state *mrb, mrb_sym id, mrb_value args, const char *fmt, ...);
/* declaration for `fail` method */
MRB_API mrb_value mrb_f_raise(mrb_state*, mrb_value);
#if defined(MRB_64BIT) || defined(MRB_USE_FLOAT) || defined(MRB_NAN_BOXING) || defined(MRB_WORD_BOXING)
struct RBreak {
MRB_OBJECT_HEADER;
struct RProc *proc;
mrb_value val;
};
#define mrb_break_value_get(brk) ((brk)->val)
#define mrb_break_value_set(brk, v) ((brk)->val = v)
#else
struct RBreak {
MRB_OBJECT_HEADER;
struct RProc *proc;
union mrb_value_union value;
};
#define RBREAK_VALUE_TT_MASK ((1 << 8) - 1)
static inline mrb_value
mrb_break_value_get(struct RBreak *brk)
{
mrb_value val;
val.value = brk->value;
val.tt = (enum mrb_vtype)(brk->flags & RBREAK_VALUE_TT_MASK);
return val;
}
static inline void
mrb_break_value_set(struct RBreak *brk, mrb_value val)
{
brk->value = val.value;
brk->flags &= ~RBREAK_VALUE_TT_MASK;
brk->flags |= val.tt;
}
#endif /* MRB_64BIT || MRB_USE_FLOAT || MRB_NAN_BOXING || MRB_WORD_BOXING */
#define mrb_break_proc_get(brk) ((brk)->proc)
#define mrb_break_proc_set(brk, p) ((brk)->proc = p)
/**
* Protect
*
* Implemented in the mruby-error mrbgem
*/
MRB_API mrb_value mrb_protect(mrb_state *mrb, mrb_func_t body, mrb_value data, mrb_bool *state);
/**
* Ensure
*
* Implemented in the mruby-error mrbgem
*/
MRB_API mrb_value mrb_ensure(mrb_state *mrb, mrb_func_t body, mrb_value b_data,
mrb_func_t ensure, mrb_value e_data);
/**
* Rescue
*
* Implemented in the mruby-error mrbgem
*/
MRB_API mrb_value mrb_rescue(mrb_state *mrb, mrb_func_t body, mrb_value b_data,
mrb_func_t rescue, mrb_value r_data);
/**
* Rescue exception
*
* Implemented in the mruby-error mrbgem
*/
MRB_API mrb_value mrb_rescue_exceptions(mrb_state *mrb, mrb_func_t body, mrb_value b_data,
mrb_func_t rescue, mrb_value r_data,
mrb_int len, struct RClass **classes);
MRB_END_DECL
#endif /* MRUBY_ERROR_H */
+91
View File
@@ -0,0 +1,91 @@
/**
** @file mruby/gc.h - garbage collector for mruby
**
** See Copyright Notice in mruby.h
*/
#ifndef MRUBY_GC_H
#define MRUBY_GC_H
#include "common.h"
/**
* Uncommon memory management stuffs.
*/
MRB_BEGIN_DECL
struct mrb_state;
#define MRB_EACH_OBJ_OK 0
#define MRB_EACH_OBJ_BREAK 1
typedef int (mrb_each_object_callback)(struct mrb_state *mrb, struct RBasic *obj, void *data);
void mrb_objspace_each_objects(struct mrb_state *mrb, mrb_each_object_callback *callback, void *data);
MRB_API void mrb_free_context(struct mrb_state *mrb, struct mrb_context *c);
#ifndef MRB_GC_ARENA_SIZE
#define MRB_GC_ARENA_SIZE 100
#endif
typedef enum {
MRB_GC_STATE_ROOT = 0,
MRB_GC_STATE_MARK,
MRB_GC_STATE_SWEEP
} mrb_gc_state;
/* Disable MSVC warning "C4200: nonstandard extension used: zero-sized array
* in struct/union" when in C++ mode */
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4200)
#endif
typedef struct mrb_heap_page {
struct RBasic *freelist;
struct mrb_heap_page *prev;
struct mrb_heap_page *next;
struct mrb_heap_page *free_next;
struct mrb_heap_page *free_prev;
mrb_bool old:1;
void *objects[];
} mrb_heap_page;
#ifdef _MSC_VER
#pragma warning(pop)
#endif
typedef struct mrb_gc {
mrb_heap_page *heaps; /* heaps for GC */
mrb_heap_page *sweeps;
mrb_heap_page *free_heaps;
size_t live; /* count of live objects */
#ifdef MRB_GC_FIXED_ARENA
struct RBasic *arena[MRB_GC_ARENA_SIZE]; /* GC protection array */
#else
struct RBasic **arena; /* GC protection array */
int arena_capa;
#endif
int arena_idx;
mrb_gc_state state; /* state of gc */
int current_white_part; /* make white object by white_part */
struct RBasic *gray_list; /* list of gray objects to be traversed incrementally */
struct RBasic *atomic_gray_list; /* list of objects to be traversed atomically */
size_t live_after_mark;
size_t threshold;
int interval_ratio;
int step_ratio;
mrb_bool iterating :1;
mrb_bool disabled :1;
mrb_bool full :1;
mrb_bool generational :1;
mrb_bool out_of_memory :1;
size_t majorgc_old_threshold;
} mrb_gc;
MRB_API mrb_bool
mrb_object_dead_p(struct mrb_state *mrb, struct RBasic *object);
MRB_END_DECL
#endif /* MRUBY_GC_H */
+222
View File
@@ -0,0 +1,222 @@
/**
** @file mruby/hash.h - Hash class
**
** See Copyright Notice in mruby.h
*/
#ifndef MRUBY_HASH_H
#define MRUBY_HASH_H
#include "common.h"
/**
* Hash class
*/
MRB_BEGIN_DECL
struct RHash {
MRB_OBJECT_HEADER;
struct iv_tbl *iv;
struct htable *ht;
};
#define mrb_hash_ptr(v) ((struct RHash*)(mrb_ptr(v)))
#define mrb_hash_value(p) mrb_obj_value((void*)(p))
MRB_API mrb_value mrb_hash_new_capa(mrb_state *mrb, mrb_int capa);
MRB_API mrb_value mrb_ensure_hash_type(mrb_state *mrb, mrb_value hash);
MRB_API mrb_value mrb_check_hash_type(mrb_state *mrb, mrb_value hash);
/*
* Initializes a new hash.
*
* Equivalent to:
*
* Hash.new
*
* @param mrb The mruby state reference.
* @return The initialized hash.
*/
MRB_API mrb_value mrb_hash_new(mrb_state *mrb);
/*
* Sets a keys and values to hashes.
*
* Equivalent to:
*
* hash[key] = val
*
* @param mrb The mruby state reference.
* @param hash The target hash.
* @param key The key to set.
* @param val The value to set.
* @return The value.
*/
MRB_API void mrb_hash_set(mrb_state *mrb, mrb_value hash, mrb_value key, mrb_value val);
/*
* Gets a value from a key. If the key is not found, the default of the
* hash is used.
*
* Equivalent to:
*
* hash[key]
*
* @param mrb The mruby state reference.
* @param hash The target hash.
* @param key The key to get.
* @return The found value.
*/
MRB_API mrb_value mrb_hash_get(mrb_state *mrb, mrb_value hash, mrb_value key);
/*
* Gets a value from a key. If the key is not found, the default parameter is
* used.
*
* Equivalent to:
*
* hash.key?(key) ? hash[key] : def
*
* @param mrb The mruby state reference.
* @param hash The target hash.
* @param key The key to get.
* @param def The default value.
* @return The found value.
*/
MRB_API mrb_value mrb_hash_fetch(mrb_state *mrb, mrb_value hash, mrb_value key, mrb_value def);
/*
* Deletes hash key and value pair.
*
* Equivalent to:
*
* hash.delete(key)
*
* @param mrb The mruby state reference.
* @param hash The target hash.
* @param key The key to delete.
* @return The deleted value. This value is not protected from GC. Use `mrb_gc_protect()` if necessary.
*/
MRB_API mrb_value mrb_hash_delete_key(mrb_state *mrb, mrb_value hash, mrb_value key);
/*
* Gets an array of keys.
*
* Equivalent to:
*
* hash.keys
*
* @param mrb The mruby state reference.
* @param hash The target hash.
* @return An array with the keys of the hash.
*/
MRB_API mrb_value mrb_hash_keys(mrb_state *mrb, mrb_value hash);
/*
* Check if the hash has the key.
*
* Equivalent to:
*
* hash.key?(key)
*
* @param mrb The mruby state reference.
* @param hash The target hash.
* @param key The key to check existence.
* @return True if the hash has the key
*/
MRB_API mrb_bool mrb_hash_key_p(mrb_state *mrb, mrb_value hash, mrb_value key);
/*
* Check if the hash is empty
*
* Equivalent to:
*
* hash.empty?
*
* @param mrb The mruby state reference.
* @param self The target hash.
* @return True if the hash is empty, false otherwise.
*/
MRB_API mrb_bool mrb_hash_empty_p(mrb_state *mrb, mrb_value self);
/*
* Gets an array of values.
*
* Equivalent to:
*
* hash.values
*
* @param mrb The mruby state reference.
* @param hash The target hash.
* @return An array with the values of the hash.
*/
MRB_API mrb_value mrb_hash_values(mrb_state *mrb, mrb_value hash);
/*
* Clears the hash.
*
* Equivalent to:
*
* hash.clear
*
* @param mrb The mruby state reference.
* @param hash The target hash.
* @return The hash
*/
MRB_API mrb_value mrb_hash_clear(mrb_state *mrb, mrb_value hash);
/*
* Get hash size.
*
* Equivalent to:
*
* hash.size
*
* @param mrb The mruby state reference.
* @param hash The target hash.
* @return The hash size.
*/
MRB_API mrb_int mrb_hash_size(mrb_state *mrb, mrb_value hash);
/*
* Copies the hash.
*
*
* @param mrb The mruby state reference.
* @param hash The target hash.
* @return The copy of the hash
*/
MRB_API mrb_value mrb_hash_dup(mrb_state *mrb, mrb_value hash);
/*
* Merges two hashes. The first hash will be modified by the
* second hash.
*
* @param mrb The mruby state reference.
* @param hash1 The target hash.
* @param hash2 Updating hash
*/
MRB_API void mrb_hash_merge(mrb_state *mrb, mrb_value hash1, mrb_value hash2);
/* RHASH_TBL allocates st_table if not available. */
#define RHASH(obj) ((struct RHash*)(mrb_ptr(obj)))
#define RHASH_TBL(h) (RHASH(h)->ht)
#define RHASH_IFNONE(h) mrb_iv_get(mrb, (h), mrb_intern_lit(mrb, "ifnone"))
#define RHASH_PROCDEFAULT(h) RHASH_IFNONE(h)
#define MRB_HASH_DEFAULT 1
#define MRB_HASH_PROC_DEFAULT 2
#define MRB_RHASH_DEFAULT_P(h) (RHASH(h)->flags & MRB_HASH_DEFAULT)
#define MRB_RHASH_PROCDEFAULT_P(h) (RHASH(h)->flags & MRB_HASH_PROC_DEFAULT)
/* GC functions */
void mrb_gc_mark_hash(mrb_state*, struct RHash*);
size_t mrb_gc_mark_hash_size(mrb_state*, struct RHash*);
void mrb_gc_free_hash(mrb_state*, struct RHash*);
/* return non zero to break the loop */
typedef int (mrb_hash_foreach_func)(mrb_state *mrb, mrb_value key, mrb_value val, void *data);
MRB_API void mrb_hash_foreach(mrb_state *mrb, struct RHash *hash, mrb_hash_foreach_func *func, void *p);
MRB_END_DECL
#endif /* MRUBY_HASH_H */
+97
View File
@@ -0,0 +1,97 @@
/**
** @file mruby/irep.h - mrb_irep structure
**
** See Copyright Notice in mruby.h
*/
#ifndef MRUBY_IREP_H
#define MRUBY_IREP_H
#include "common.h"
#include <mruby/compile.h>
/**
* Compiled mruby scripts.
*/
MRB_BEGIN_DECL
enum irep_pool_type {
IREP_TT_STRING,
IREP_TT_FIXNUM,
IREP_TT_FLOAT,
};
struct mrb_locals {
mrb_sym name;
uint16_t r;
};
/* Program data array struct */
typedef struct mrb_irep {
uint16_t nlocals; /* Number of local variables */
uint16_t nregs; /* Number of register variables */
uint8_t flags;
const mrb_code *iseq;
mrb_value *pool;
mrb_sym *syms;
struct mrb_irep **reps;
struct mrb_locals *lv;
/* debug info */
struct mrb_irep_debug_info* debug_info;
uint16_t ilen, plen, slen, rlen;
uint32_t refcnt;
} mrb_irep;
#define MRB_ISEQ_NO_FREE 1
MRB_API mrb_irep *mrb_add_irep(mrb_state *mrb);
/** load mruby bytecode functions
* Please note! Currently due to interactions with the GC calling these functions will
* leak one RProc object per function call.
* To prevent this save the current memory arena before calling and restore the arena
* right after, like so
* int ai = mrb_gc_arena_save(mrb);
* mrb_value status = mrb_load_irep(mrb, buffer);
* mrb_gc_arena_restore(mrb, ai);
*/
/* @param [const uint8_t*] irep code, expected as a literal */
MRB_API mrb_value mrb_load_irep(mrb_state*, const uint8_t*);
/*
* @param [const void*] irep code
* @param [size_t] size of irep buffer. If -1 is given, it is considered unrestricted.
*/
MRB_API mrb_value mrb_load_irep_buf(mrb_state*, const void*, size_t);
/* @param [const uint8_t*] irep code, expected as a literal */
MRB_API mrb_value mrb_load_irep_cxt(mrb_state*, const uint8_t*, mrbc_context*);
/*
* @param [const void*] irep code
* @param [size_t] size of irep buffer. If -1 is given, it is considered unrestricted.
*/
MRB_API mrb_value mrb_load_irep_buf_cxt(mrb_state*, const void*, size_t, mrbc_context*);
void mrb_irep_free(mrb_state*, struct mrb_irep*);
void mrb_irep_incref(mrb_state*, struct mrb_irep*);
void mrb_irep_decref(mrb_state*, struct mrb_irep*);
void mrb_irep_cutref(mrb_state*, struct mrb_irep*);
void mrb_irep_remove_lv(mrb_state *mrb, mrb_irep *irep);
struct mrb_insn_data {
uint8_t insn;
uint16_t a;
uint16_t b;
uint8_t c;
};
struct mrb_insn_data mrb_decode_insn(const mrb_code *pc);
MRB_END_DECL
#endif /* MRUBY_IREP_H */
+50
View File
@@ -0,0 +1,50 @@
/**
** @file mruby/istruct.h - Inline structures
**
** See Copyright Notice in mruby.h
*/
#ifndef MRUBY_ISTRUCT_H
#define MRUBY_ISTRUCT_H
#include "common.h"
#include <string.h>
/**
* Inline structures that fit in RVALUE
*
* They cannot have finalizer, and cannot have instance variables.
*/
MRB_BEGIN_DECL
#define ISTRUCT_DATA_SIZE (sizeof(void*) * 3)
struct RIStruct {
MRB_OBJECT_HEADER;
union {
intptr_t inline_alignment[3];
char inline_data[ISTRUCT_DATA_SIZE];
};
};
#define RISTRUCT(obj) ((struct RIStruct*)(mrb_ptr(obj)))
#define ISTRUCT_PTR(obj) (RISTRUCT(obj)->inline_data)
MRB_INLINE mrb_int mrb_istruct_size()
{
return ISTRUCT_DATA_SIZE;
}
MRB_INLINE void* mrb_istruct_ptr(mrb_value object)
{
return ISTRUCT_PTR(object);
}
MRB_INLINE void mrb_istruct_copy(mrb_value dest, mrb_value src)
{
memcpy(ISTRUCT_PTR(dest), ISTRUCT_PTR(src), ISTRUCT_DATA_SIZE);
}
MRB_END_DECL
#endif /* MRUBY_ISTRUCT_H */
+292
View File
@@ -0,0 +1,292 @@
/**
** @file mruby/khash.h - Hash for mruby
**
** See Copyright Notice in mruby.h
*/
#ifndef MRUBY_KHASH_H
#define MRUBY_KHASH_H
#include <string.h>
#include <mruby.h>
#include "common.h"
/**
* khash definitions used in mruby's hash table.
*/
MRB_BEGIN_DECL
typedef uint32_t khint_t;
typedef khint_t khiter_t;
#ifndef KHASH_DEFAULT_SIZE
# define KHASH_DEFAULT_SIZE 32
#endif
#define KHASH_MIN_SIZE 8
#define UPPER_BOUND(x) ((x)>>2|(x)>>1)
/* extern uint8_t __m[]; */
/* mask for flags */
static const uint8_t __m_empty[] = {0x02, 0x08, 0x20, 0x80};
static const uint8_t __m_del[] = {0x01, 0x04, 0x10, 0x40};
static const uint8_t __m_either[] = {0x03, 0x0c, 0x30, 0xc0};
#define __ac_isempty(ed_flag, i) (ed_flag[(i)/4]&__m_empty[(i)%4])
#define __ac_isdel(ed_flag, i) (ed_flag[(i)/4]&__m_del[(i)%4])
#define __ac_iseither(ed_flag, i) (ed_flag[(i)/4]&__m_either[(i)%4])
#define khash_power2(v) do { \
v--;\
v |= v >> 1;\
v |= v >> 2;\
v |= v >> 4;\
v |= v >> 8;\
v |= v >> 16;\
v++;\
} while (0)
#define khash_mask(h) ((h)->n_buckets-1)
#define khash_upper_bound(h) (UPPER_BOUND((h)->n_buckets))
/* declare struct kh_xxx and kh_xxx_funcs
name: hash name
khkey_t: key data type
khval_t: value data type
kh_is_map: (0: hash set / 1: hash map)
*/
#define KHASH_DECLARE(name, khkey_t, khval_t, kh_is_map) \
typedef struct kh_##name { \
khint_t n_buckets; \
khint_t size; \
khint_t n_occupied; \
uint8_t *ed_flags; \
khkey_t *keys; \
khval_t *vals; \
} kh_##name##_t; \
void kh_alloc_##name(mrb_state *mrb, kh_##name##_t *h); \
kh_##name##_t *kh_init_##name##_size(mrb_state *mrb, khint_t size); \
kh_##name##_t *kh_init_##name(mrb_state *mrb); \
void kh_destroy_##name(mrb_state *mrb, kh_##name##_t *h); \
void kh_clear_##name(mrb_state *mrb, kh_##name##_t *h); \
khint_t kh_get_##name(mrb_state *mrb, kh_##name##_t *h, khkey_t key); \
khint_t kh_put_##name(mrb_state *mrb, kh_##name##_t *h, khkey_t key, int *ret); \
void kh_put_prepare_##name(mrb_state *mrb, kh_##name##_t *h); \
void kh_resize_##name(mrb_state *mrb, kh_##name##_t *h, khint_t new_n_buckets); \
void kh_del_##name(mrb_state *mrb, kh_##name##_t *h, khint_t x); \
kh_##name##_t *kh_copy_##name(mrb_state *mrb, kh_##name##_t *h);
static inline void
kh_fill_flags(uint8_t *p, uint8_t c, size_t len)
{
while (len-- > 0) {
*p++ = c;
}
}
/* define kh_xxx_funcs
name: hash name
khkey_t: key data type
khval_t: value data type
kh_is_map: (0: hash set / 1: hash map)
__hash_func: hash function
__hash_equal: hash comparation function
*/
#define KHASH_DEFINE(name, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \
mrb_noreturn void mrb_raise_nomemory(mrb_state *mrb); \
int kh_alloc_simple_##name(mrb_state *mrb, kh_##name##_t *h) \
{ \
khint_t sz = h->n_buckets; \
size_t len = sizeof(khkey_t) + (kh_is_map ? sizeof(khval_t) : 0); \
uint8_t *p = (uint8_t*)mrb_malloc_simple(mrb, sizeof(uint8_t)*sz/4+len*sz); \
if (!p) { return 1; } \
h->size = h->n_occupied = 0; \
h->keys = (khkey_t *)p; \
h->vals = kh_is_map ? (khval_t *)(p+sizeof(khkey_t)*sz) : NULL; \
h->ed_flags = p+len*sz; \
kh_fill_flags(h->ed_flags, 0xaa, sz/4); \
return 0; \
} \
void kh_alloc_##name(mrb_state *mrb, kh_##name##_t *h) \
{ \
if (kh_alloc_simple_##name(mrb, h)) { \
mrb_raise_nomemory(mrb); \
} \
} \
kh_##name##_t *kh_init_##name##_size(mrb_state *mrb, khint_t size) { \
kh_##name##_t *h = (kh_##name##_t*)mrb_calloc(mrb, 1, sizeof(kh_##name##_t)); \
if (size < KHASH_MIN_SIZE) \
size = KHASH_MIN_SIZE; \
khash_power2(size); \
h->n_buckets = size; \
if (kh_alloc_simple_##name(mrb, h)) { \
mrb_free(mrb, h); \
mrb_raise_nomemory(mrb); \
} \
return h; \
} \
kh_##name##_t *kh_init_##name(mrb_state *mrb) { \
return kh_init_##name##_size(mrb, KHASH_DEFAULT_SIZE); \
} \
void kh_destroy_##name(mrb_state *mrb, kh_##name##_t *h) \
{ \
if (h) { \
mrb_free(mrb, h->keys); \
mrb_free(mrb, h); \
} \
} \
void kh_clear_##name(mrb_state *mrb, kh_##name##_t *h) \
{ \
(void)mrb; \
if (h && h->ed_flags) { \
kh_fill_flags(h->ed_flags, 0xaa, h->n_buckets/4); \
h->size = h->n_occupied = 0; \
} \
} \
khint_t kh_get_##name(mrb_state *mrb, kh_##name##_t *h, khkey_t key) \
{ \
khint_t k = __hash_func(mrb,key) & khash_mask(h), step = 0; \
(void)mrb; \
while (!__ac_isempty(h->ed_flags, k)) { \
if (!__ac_isdel(h->ed_flags, k)) { \
if (__hash_equal(mrb,h->keys[k], key)) return k; \
} \
k = (k+(++step)) & khash_mask(h); \
} \
return kh_end(h); \
} \
void kh_resize_##name(mrb_state *mrb, kh_##name##_t *h, khint_t new_n_buckets) \
{ \
if (new_n_buckets < KHASH_MIN_SIZE) \
new_n_buckets = KHASH_MIN_SIZE; \
khash_power2(new_n_buckets); \
{ \
kh_##name##_t hh; \
uint8_t *old_ed_flags = h->ed_flags; \
khkey_t *old_keys = h->keys; \
khval_t *old_vals = h->vals; \
khint_t old_n_buckets = h->n_buckets; \
khint_t i; \
hh.n_buckets = new_n_buckets; \
kh_alloc_##name(mrb, &hh); \
/* relocate */ \
for (i=0 ; i<old_n_buckets ; i++) { \
if (!__ac_iseither(old_ed_flags, i)) { \
khint_t k = kh_put_##name(mrb, &hh, old_keys[i], NULL); \
if (kh_is_map) kh_value(&hh,k) = old_vals[i]; \
} \
} \
/* copy hh to h */ \
*h = hh; \
mrb_free(mrb, old_keys); \
} \
} \
void kh_put_prepare_##name(mrb_state *mrb, kh_##name##_t *h) \
{ \
if (h->n_occupied >= khash_upper_bound(h)) { \
kh_resize_##name(mrb, h, h->n_buckets*2); \
} \
} \
khint_t kh_put_##name(mrb_state *mrb, kh_##name##_t *h, khkey_t key, int *ret) \
{ \
khint_t k, del_k, step = 0; \
kh_put_prepare_##name(mrb, h); \
k = __hash_func(mrb,key) & khash_mask(h); \
del_k = kh_end(h); \
while (!__ac_isempty(h->ed_flags, k)) { \
if (!__ac_isdel(h->ed_flags, k)) { \
if (__hash_equal(mrb,h->keys[k], key)) { \
if (ret) *ret = 0; \
return k; \
} \
} \
else if (del_k == kh_end(h)) { \
del_k = k; \
} \
k = (k+(++step)) & khash_mask(h); \
} \
if (del_k != kh_end(h)) { \
/* put at del */ \
h->keys[del_k] = key; \
h->ed_flags[del_k/4] &= ~__m_del[del_k%4]; \
h->size++; \
if (ret) *ret = 2; \
return del_k; \
} \
else { \
/* put at empty */ \
h->keys[k] = key; \
h->ed_flags[k/4] &= ~__m_empty[k%4]; \
h->size++; \
h->n_occupied++; \
if (ret) *ret = 1; \
return k; \
} \
} \
void kh_del_##name(mrb_state *mrb, kh_##name##_t *h, khint_t x) \
{ \
(void)mrb; \
mrb_assert(x != h->n_buckets && !__ac_iseither(h->ed_flags, x)); \
h->ed_flags[x/4] |= __m_del[x%4]; \
h->size--; \
} \
kh_##name##_t *kh_copy_##name(mrb_state *mrb, kh_##name##_t *h) \
{ \
kh_##name##_t *h2; \
khiter_t k, k2; \
\
h2 = kh_init_##name(mrb); \
for (k = kh_begin(h); k != kh_end(h); k++) { \
if (kh_exist(h, k)) { \
k2 = kh_put_##name(mrb, h2, kh_key(h, k), NULL); \
if (kh_is_map) kh_value(h2, k2) = kh_value(h, k); \
} \
} \
return h2; \
}
#define khash_t(name) kh_##name##_t
#define kh_init_size(name,mrb,size) kh_init_##name##_size(mrb,size)
#define kh_init(name,mrb) kh_init_##name(mrb)
#define kh_destroy(name, mrb, h) kh_destroy_##name(mrb, h)
#define kh_clear(name, mrb, h) kh_clear_##name(mrb, h)
#define kh_resize(name, mrb, h, s) kh_resize_##name(mrb, h, s)
#define kh_put_prepare(name, mrb, h) kh_put_prepare_##name(mrb, h)
#define kh_put(name, mrb, h, k) kh_put_##name(mrb, h, k, NULL)
#define kh_put2(name, mrb, h, k, r) kh_put_##name(mrb, h, k, r)
#define kh_get(name, mrb, h, k) kh_get_##name(mrb, h, k)
#define kh_del(name, mrb, h, k) kh_del_##name(mrb, h, k)
#define kh_copy(name, mrb, h) kh_copy_##name(mrb, h)
#define kh_exist(h, x) (!__ac_iseither((h)->ed_flags, (x)))
#define kh_key(h, x) ((h)->keys[x])
#define kh_val(h, x) ((h)->vals[x])
#define kh_value(h, x) ((h)->vals[x])
#define kh_begin(h) (khint_t)(0)
#define kh_end(h) ((h)->n_buckets)
#define kh_size(h) ((h)->size)
#define kh_n_buckets(h) ((h)->n_buckets)
#define kh_int_hash_func(mrb,key) (khint_t)((key)^((key)<<2)^((key)>>2))
#define kh_int_hash_equal(mrb,a, b) (a == b)
#define kh_int64_hash_func(mrb,key) (khint_t)((key)>>33^(key)^(key)<<11)
#define kh_int64_hash_equal(mrb,a, b) (a == b)
static inline khint_t __ac_X31_hash_string(const char *s)
{
khint_t h = *s;
if (h) for (++s ; *s; ++s) h = (h << 5) - h + *s;
return h;
}
#define kh_str_hash_func(mrb,key) __ac_X31_hash_string(key)
#define kh_str_hash_equal(mrb,a, b) (strcmp(a, b) == 0)
typedef const char *kh_cstr_t;
MRB_END_DECL
#endif /* MRUBY_KHASH_H */
+196
View File
@@ -0,0 +1,196 @@
/**
** @file mruby/numeric.h - Numeric, Integer, Float, Fixnum class
**
** See Copyright Notice in mruby.h
*/
#ifndef MRUBY_NUMERIC_H
#define MRUBY_NUMERIC_H
#include "common.h"
/**
* Numeric class and it's sub-classes.
*
* Integer, Float and Fixnum
*/
MRB_BEGIN_DECL
#define TYPED_POSFIXABLE(f,t) ((f) <= (t)MRB_INT_MAX)
#define TYPED_NEGFIXABLE(f,t) ((f) >= (t)MRB_INT_MIN)
#define TYPED_FIXABLE(f,t) (TYPED_POSFIXABLE(f,t) && TYPED_NEGFIXABLE(f,t))
#define POSFIXABLE(f) TYPED_POSFIXABLE(f,mrb_int)
#define NEGFIXABLE(f) TYPED_NEGFIXABLE(f,mrb_int)
#define FIXABLE(f) TYPED_FIXABLE(f,mrb_int)
#ifndef MRB_WITHOUT_FLOAT
#ifdef MRB_INT64
#define FIXABLE_FLOAT(f) ((f)>=-9223372036854775808.0 && (f)<9223372036854775808.0)
#else
#define FIXABLE_FLOAT(f) TYPED_FIXABLE(f,mrb_float)
#endif
#endif
#ifndef MRB_WITHOUT_FLOAT
MRB_API mrb_value mrb_flo_to_fixnum(mrb_state *mrb, mrb_value val);
#endif
MRB_API mrb_value mrb_fixnum_to_str(mrb_state *mrb, mrb_value x, mrb_int base);
/* ArgumentError if format string doesn't match /%(\.[0-9]+)?[aAeEfFgG]/ */
#ifndef MRB_WITHOUT_FLOAT
MRB_API mrb_value mrb_float_to_str(mrb_state *mrb, mrb_value x, const char *fmt);
MRB_API int mrb_float_to_cstr(mrb_state *mrb, char *buf, size_t len, const char *fmt, mrb_float f);
MRB_API mrb_float mrb_to_flo(mrb_state *mrb, mrb_value x);
MRB_API mrb_value mrb_int_value(mrb_state *mrb, mrb_float f);
#endif
MRB_API mrb_value mrb_num_plus(mrb_state *mrb, mrb_value x, mrb_value y);
MRB_API mrb_value mrb_num_minus(mrb_state *mrb, mrb_value x, mrb_value y);
MRB_API mrb_value mrb_num_mul(mrb_state *mrb, mrb_value x, mrb_value y);
#ifndef __has_builtin
#define __has_builtin(x) 0
#endif
#if (defined(__GNUC__) && __GNUC__ >= 5) || \
(__has_builtin(__builtin_add_overflow) && \
__has_builtin(__builtin_sub_overflow) && \
__has_builtin(__builtin_mul_overflow))
# define MRB_HAVE_TYPE_GENERIC_CHECKED_ARITHMETIC_BUILTINS
#endif
/*
// Clang 3.8 and 3.9 have problem compiling mruby in 32-bit mode, when MRB_INT64 is set
// because of missing __mulodi4 and similar functions in its runtime. We need to use custom
// implementation for them.
*/
#ifdef MRB_HAVE_TYPE_GENERIC_CHECKED_ARITHMETIC_BUILTINS
#if defined(__clang__) && (__clang_major__ == 3) && (__clang_minor__ >= 8) && \
defined(MRB_32BIT) && defined(MRB_INT64)
#undef MRB_HAVE_TYPE_GENERIC_CHECKED_ARITHMETIC_BUILTINS
#endif
#endif
#ifdef MRB_HAVE_TYPE_GENERIC_CHECKED_ARITHMETIC_BUILTINS
#ifndef MRB_WORD_BOXING
# define WBCHK(x) 0
#else
# define WBCHK(x) !FIXABLE(x)
#endif
static inline mrb_bool
mrb_int_add_overflow(mrb_int augend, mrb_int addend, mrb_int *sum)
{
return __builtin_add_overflow(augend, addend, sum) || WBCHK(*sum);
}
static inline mrb_bool
mrb_int_sub_overflow(mrb_int minuend, mrb_int subtrahend, mrb_int *difference)
{
return __builtin_sub_overflow(minuend, subtrahend, difference) || WBCHK(*difference);
}
static inline mrb_bool
mrb_int_mul_overflow(mrb_int multiplier, mrb_int multiplicand, mrb_int *product)
{
return __builtin_mul_overflow(multiplier, multiplicand, product) || WBCHK(*product);
}
#undef WBCHK
#else
#define MRB_UINT_MAKE2(n) uint ## n ## _t
#define MRB_UINT_MAKE(n) MRB_UINT_MAKE2(n)
#define mrb_uint MRB_UINT_MAKE(MRB_INT_BIT)
#define MRB_INT_OVERFLOW_MASK ((mrb_uint)1 << (MRB_INT_BIT - 1 - MRB_FIXNUM_SHIFT))
static inline mrb_bool
mrb_int_add_overflow(mrb_int augend, mrb_int addend, mrb_int *sum)
{
mrb_uint x = (mrb_uint)augend;
mrb_uint y = (mrb_uint)addend;
mrb_uint z = (mrb_uint)(x + y);
*sum = (mrb_int)z;
return !!(((x ^ z) & (y ^ z)) & MRB_INT_OVERFLOW_MASK);
}
static inline mrb_bool
mrb_int_sub_overflow(mrb_int minuend, mrb_int subtrahend, mrb_int *difference)
{
mrb_uint x = (mrb_uint)minuend;
mrb_uint y = (mrb_uint)subtrahend;
mrb_uint z = (mrb_uint)(x - y);
*difference = (mrb_int)z;
return !!(((x ^ z) & (~y ^ z)) & MRB_INT_OVERFLOW_MASK);
}
static inline mrb_bool
mrb_int_mul_overflow(mrb_int multiplier, mrb_int multiplicand, mrb_int *product)
{
#if MRB_INT_BIT == 32
int64_t n = (int64_t)multiplier * multiplicand;
*product = (mrb_int)n;
return !FIXABLE(n);
#else
if (multiplier > 0) {
if (multiplicand > 0) {
if (multiplier > MRB_INT_MAX / multiplicand) return TRUE;
}
else {
if (multiplicand < MRB_INT_MAX / multiplier) return TRUE;
}
}
else {
if (multiplicand > 0) {
if (multiplier < MRB_INT_MAX / multiplicand) return TRUE;
}
else {
if (multiplier != 0 && multiplicand < MRB_INT_MAX / multiplier) return TRUE;
}
}
*product = multiplier * multiplicand;
return FALSE;
#endif
}
#undef MRB_INT_OVERFLOW_MASK
#undef mrb_uint
#undef MRB_UINT_MAKE
#undef MRB_UINT_MAKE2
#endif
#ifndef MRB_WITHOUT_FLOAT
# include <stdint.h>
# include <float.h>
# define MRB_FLT_RADIX FLT_RADIX
# ifdef MRB_USE_FLOAT
# define MRB_FLT_MANT_DIG FLT_MANT_DIG
# define MRB_FLT_EPSILON FLT_EPSILON
# define MRB_FLT_DIG FLT_DIG
# define MRB_FLT_MIN_EXP FLT_MIN_EXP
# define MRB_FLT_MIN FLT_MIN
# define MRB_FLT_MIN_10_EXP FLT_MIN_10_EXP
# define MRB_FLT_MAX_EXP FLT_MAX_EXP
# define MRB_FLT_MAX FLT_MAX
# define MRB_FLT_MAX_10_EXP FLT_MAX_10_EXP
# else /* not MRB_USE_FLOAT */
# define MRB_FLT_MANT_DIG DBL_MANT_DIG
# define MRB_FLT_EPSILON DBL_EPSILON
# define MRB_FLT_DIG DBL_DIG
# define MRB_FLT_MIN_EXP DBL_MIN_EXP
# define MRB_FLT_MIN DBL_MIN
# define MRB_FLT_MIN_10_EXP DBL_MIN_10_EXP
# define MRB_FLT_MAX_EXP DBL_MAX_EXP
# define MRB_FLT_MAX DBL_MAX
# define MRB_FLT_MAX_10_EXP DBL_MAX_10_EXP
# endif /* MRB_USE_FLOAT */
#endif /* MRB_WITHOUT_FLOAT */
MRB_END_DECL
#endif /* MRUBY_NUMERIC_H */
+43
View File
@@ -0,0 +1,43 @@
/**
** @file mruby/object.h - mruby object definition
**
** See Copyright Notice in mruby.h
*/
#ifndef MRUBY_OBJECT_H
#define MRUBY_OBJECT_H
#define MRB_OBJECT_HEADER \
struct RClass *c; \
struct RBasic *gcnext; \
enum mrb_vtype tt:8; \
uint32_t color:3; \
uint32_t flags:21
#define MRB_FLAG_TEST(obj, flag) ((obj)->flags & (flag))
struct RBasic {
MRB_OBJECT_HEADER;
};
#define mrb_basic_ptr(v) ((struct RBasic*)(mrb_ptr(v)))
#define MRB_FL_OBJ_IS_FROZEN (1 << 20)
#define MRB_FROZEN_P(o) ((o)->flags & MRB_FL_OBJ_IS_FROZEN)
#define MRB_SET_FROZEN_FLAG(o) ((o)->flags |= MRB_FL_OBJ_IS_FROZEN)
#define MRB_UNSET_FROZEN_FLAG(o) ((o)->flags &= ~MRB_FL_OBJ_IS_FROZEN)
#define mrb_frozen_p(o) MRB_FROZEN_P(o)
struct RObject {
MRB_OBJECT_HEADER;
struct iv_tbl *iv;
};
#define mrb_obj_ptr(v) ((struct RObject*)(mrb_ptr(v)))
#define mrb_special_const_p(x) mrb_immediate_p(x)
struct RFiber {
MRB_OBJECT_HEADER;
struct mrb_context *cxt;
};
#endif /* MRUBY_OBJECT_H */
+69
View File
@@ -0,0 +1,69 @@
/**
** @file mruby/opcode.h - RiteVM operation codes
**
** See Copyright Notice in mruby.h
*/
#ifndef MRUBY_OPCODE_H
#define MRUBY_OPCODE_H
enum mrb_insn {
#define OPCODE(x,_) OP_ ## x,
#include "mruby/ops.h"
#undef OPCODE
};
#define OP_L_STRICT 1
#define OP_L_CAPTURE 2
#define OP_L_METHOD OP_L_STRICT
#define OP_L_LAMBDA (OP_L_STRICT|OP_L_CAPTURE)
#define OP_L_BLOCK OP_L_CAPTURE
#define OP_R_NORMAL 0
#define OP_R_BREAK 1
#define OP_R_RETURN 2
#define PEEK_B(pc) (*(pc))
#define PEEK_S(pc) ((pc)[0]<<8|(pc)[1])
#define PEEK_W(pc) ((pc)[0]<<16|(pc)[1]<<8|(pc)[2])
#define READ_B() PEEK_B(pc++)
#define READ_S() (pc+=2, PEEK_S(pc-2))
#define READ_W() (pc+=3, PEEK_W(pc-3))
#define FETCH_Z() /* nothing */
#define FETCH_B() do {a=READ_B();} while (0)
#define FETCH_BB() do {a=READ_B(); b=READ_B();} while (0)
#define FETCH_BBB() do {a=READ_B(); b=READ_B(); c=READ_B();} while (0)
#define FETCH_BS() do {a=READ_B(); b=READ_S();} while (0)
#define FETCH_S() do {a=READ_S();} while (0)
#define FETCH_W() do {a=READ_W();} while (0)
/* with OP_EXT1 (1st 16bit) */
#define FETCH_Z_1() FETCH_Z()
#define FETCH_B_1() FETCH_S()
#define FETCH_BB_1() do {a=READ_S(); b=READ_B();} while (0)
#define FETCH_BBB_1() do {a=READ_S(); b=READ_B(); c=READ_B();} while (0)
#define FETCH_BS_1() do {a=READ_S(); b=READ_S();} while (0)
#define FETCH_S_1() FETCH_S()
#define FETCH_W_1() FETCH_W()
/* with OP_EXT2 (2nd 16bit) */
#define FETCH_Z_2() FETCH_Z()
#define FETCH_B_2() FETCH_B()
#define FETCH_BB_2() do {a=READ_B(); b=READ_S();} while (0)
#define FETCH_BBB_2() do {a=READ_B(); b=READ_S(); c=READ_B();} while (0)
#define FETCH_BS_2() FETCH_BS()
#define FETCH_S_2() FETCH_S()
#define FETCH_W_2() FETCH_W()
/* with OP_EXT3 (1st & 2nd 16bit) */
#define FETCH_Z_3() FETCH_Z()
#define FETCH_B_3() FETCH_B()
#define FETCH_BB_3() do {a=READ_S(); b=READ_S();} while (0)
#define FETCH_BBB_3() do {a=READ_S(); b=READ_S(); c=READ_B();} while (0)
#define FETCH_BS_3() do {a=READ_S(); b=READ_S();} while (0)
#define FETCH_S_3() FETCH_S()
#define FETCH_W_3() FETCH_W()
#endif /* MRUBY_OPCODE_H */
+118
View File
@@ -0,0 +1,118 @@
/* operand types:
+ Z: no operand (Z,Z,Z,Z)
+ B: 8bit (B,S,B,B)
+ BB: 8+8bit (BB,SB,BS,SS)
+ BBB: 8+8+8bit (BBB,SBB,BSB,SSB)
+ BS: 8+16bit (BS,SS,BS,BS)
+ S: 16bit (S,S,S,S)
+ W: 24bit (W,W,W,W)
*/
/*-----------------------------------------------------------------------
operation code operands semantics
------------------------------------------------------------------------*/
OPCODE(NOP, Z) /* no operation */
OPCODE(MOVE, BB) /* R(a) = R(b) */
OPCODE(LOADL, BB) /* R(a) = Pool(b) */
OPCODE(LOADI, BB) /* R(a) = mrb_int(b) */
OPCODE(LOADINEG, BB) /* R(a) = mrb_int(-b) */
OPCODE(LOADI__1, B) /* R(a) = mrb_int(-1) */
OPCODE(LOADI_0, B) /* R(a) = mrb_int(0) */
OPCODE(LOADI_1, B) /* R(a) = mrb_int(1) */
OPCODE(LOADI_2, B) /* R(a) = mrb_int(2) */
OPCODE(LOADI_3, B) /* R(a) = mrb_int(3) */
OPCODE(LOADI_4, B) /* R(a) = mrb_int(4) */
OPCODE(LOADI_5, B) /* R(a) = mrb_int(5) */
OPCODE(LOADI_6, B) /* R(a) = mrb_int(6) */
OPCODE(LOADI_7, B) /* R(a) = mrb_int(7) */
OPCODE(LOADSYM, BB) /* R(a) = Syms(b) */
OPCODE(LOADNIL, B) /* R(a) = nil */
OPCODE(LOADSELF, B) /* R(a) = self */
OPCODE(LOADT, B) /* R(a) = true */
OPCODE(LOADF, B) /* R(a) = false */
OPCODE(GETGV, BB) /* R(a) = getglobal(Syms(b)) */
OPCODE(SETGV, BB) /* setglobal(Syms(b), R(a)) */
OPCODE(GETSV, BB) /* R(a) = Special[Syms(b)] */
OPCODE(SETSV, BB) /* Special[Syms(b)] = R(a) */
OPCODE(GETIV, BB) /* R(a) = ivget(Syms(b)) */
OPCODE(SETIV, BB) /* ivset(Syms(b),R(a)) */
OPCODE(GETCV, BB) /* R(a) = cvget(Syms(b)) */
OPCODE(SETCV, BB) /* cvset(Syms(b),R(a)) */
OPCODE(GETCONST, BB) /* R(a) = constget(Syms(b)) */
OPCODE(SETCONST, BB) /* constset(Syms(b),R(a)) */
OPCODE(GETMCNST, BB) /* R(a) = R(a)::Syms(b) */
OPCODE(SETMCNST, BB) /* R(a+1)::Syms(b) = R(a) */
OPCODE(GETUPVAR, BBB) /* R(a) = uvget(b,c) */
OPCODE(SETUPVAR, BBB) /* uvset(b,c,R(a)) */
OPCODE(JMP, S) /* pc=a */
OPCODE(JMPIF, BS) /* if R(a) pc=b */
OPCODE(JMPNOT, BS) /* if !R(a) pc=b */
OPCODE(JMPNIL, BS) /* if R(a)==nil pc=b */
OPCODE(ONERR, S) /* rescue_push(a) */
OPCODE(EXCEPT, B) /* R(a) = exc */
OPCODE(RESCUE, BB) /* R(b) = R(a).isa?(R(b)) */
OPCODE(POPERR, B) /* a.times{rescue_pop()} */
OPCODE(RAISE, B) /* raise(R(a)) */
OPCODE(EPUSH, B) /* ensure_push(SEQ[a]) */
OPCODE(EPOP, B) /* A.times{ensure_pop().call} */
OPCODE(SENDV, BB) /* R(a) = call(R(a),Syms(b),*R(a+1)) */
OPCODE(SENDVB, BB) /* R(a) = call(R(a),Syms(b),*R(a+1),&R(a+2)) */
OPCODE(SEND, BBB) /* R(a) = call(R(a),Syms(b),R(a+1),...,R(a+c)) */
OPCODE(SENDB, BBB) /* R(a) = call(R(a),Syms(b),R(a+1),...,R(a+c),&R(a+c+1)) */
OPCODE(CALL, Z) /* R(0) = self.call(frame.argc, frame.argv) */
OPCODE(SUPER, BB) /* R(a) = super(R(a+1),... ,R(a+b+1)) */
OPCODE(ARGARY, BS) /* R(a) = argument array (16=m5:r1:m5:d1:lv4) */
OPCODE(ENTER, W) /* arg setup according to flags (23=m5:o5:r1:m5:k5:d1:b1) */
OPCODE(KEY_P, BB) /* R(a) = kdict.key?(Syms(b)) # todo */
OPCODE(KEYEND, Z) /* raise unless kdict.empty? # todo */
OPCODE(KARG, BB) /* R(a) = kdict[Syms(b)]; kdict.delete(Syms(b)) # todo */
OPCODE(RETURN, B) /* return R(a) (normal) */
OPCODE(RETURN_BLK, B) /* return R(a) (in-block return) */
OPCODE(BREAK, B) /* break R(a) */
OPCODE(BLKPUSH, BS) /* R(a) = block (16=m5:r1:m5:d1:lv4) */
OPCODE(ADD, B) /* R(a) = R(a)+R(a+1) */
OPCODE(ADDI, BB) /* R(a) = R(a)+mrb_int(b) */
OPCODE(SUB, B) /* R(a) = R(a)-R(a+1) */
OPCODE(SUBI, BB) /* R(a) = R(a)-mrb_int(b) */
OPCODE(MUL, B) /* R(a) = R(a)*R(a+1) */
OPCODE(DIV, B) /* R(a) = R(a)/R(a+1) */
OPCODE(EQ, B) /* R(a) = R(a)==R(a+1) */
OPCODE(LT, B) /* R(a) = R(a)<R(a+1) */
OPCODE(LE, B) /* R(a) = R(a)<=R(a+1) */
OPCODE(GT, B) /* R(a) = R(a)>R(a+1) */
OPCODE(GE, B) /* R(a) = R(a)>=R(a+1) */
OPCODE(ARRAY, BB) /* R(a) = ary_new(R(a),R(a+1)..R(a+b)) */
OPCODE(ARRAY2, BBB) /* R(a) = ary_new(R(b),R(b+1)..R(b+c)) */
OPCODE(ARYCAT, B) /* ary_cat(R(a),R(a+1)) */
OPCODE(ARYPUSH, B) /* ary_push(R(a),R(a+1)) */
OPCODE(ARYDUP, B) /* R(a) = ary_dup(R(a)) */
OPCODE(AREF, BBB) /* R(a) = R(b)[c] */
OPCODE(ASET, BBB) /* R(a)[c] = R(b) */
OPCODE(APOST, BBB) /* *R(a),R(a+1)..R(a+c) = R(a)[b..] */
OPCODE(INTERN, B) /* R(a) = intern(R(a)) */
OPCODE(STRING, BB) /* R(a) = str_dup(Lit(b)) */
OPCODE(STRCAT, B) /* str_cat(R(a),R(a+1)) */
OPCODE(HASH, BB) /* R(a) = hash_new(R(a),R(a+1)..R(a+b*2-1)) */
OPCODE(HASHADD, BB) /* R(a) = hash_push(R(a),R(a+1)..R(a+b*2)) */
OPCODE(HASHCAT, B) /* R(a) = hash_cat(R(a),R(a+1)) */
OPCODE(LAMBDA, BB) /* R(a) = lambda(SEQ[b],L_LAMBDA) */
OPCODE(BLOCK, BB) /* R(a) = lambda(SEQ[b],L_BLOCK) */
OPCODE(METHOD, BB) /* R(a) = lambda(SEQ[b],L_METHOD) */
OPCODE(RANGE_INC, B) /* R(a) = range_new(R(a),R(a+1),FALSE) */
OPCODE(RANGE_EXC, B) /* R(a) = range_new(R(a),R(a+1),TRUE) */
OPCODE(OCLASS, B) /* R(a) = ::Object */
OPCODE(CLASS, BB) /* R(a) = newclass(R(a),Syms(b),R(a+1)) */
OPCODE(MODULE, BB) /* R(a) = newmodule(R(a),Syms(b)) */
OPCODE(EXEC, BB) /* R(a) = blockexec(R(a),SEQ[b]) */
OPCODE(DEF, BB) /* R(a).newmethod(Syms(b),R(a+1)) */
OPCODE(ALIAS, BB) /* alias_method(target_class,Syms(a),Syms(b)) */
OPCODE(UNDEF, B) /* undef_method(target_class,Syms(a)) */
OPCODE(SCLASS, B) /* R(a) = R(a).singleton_class */
OPCODE(TCLASS, B) /* R(a) = target_class */
OPCODE(DEBUG, BBB) /* print a,b,c */
OPCODE(ERR, B) /* raise(LocalJumpError, Lit(a)) */
OPCODE(EXT1, Z) /* make 1st operand 16bit */
OPCODE(EXT2, Z) /* make 2nd operand 16bit */
OPCODE(EXT3, Z) /* make 1st and 2nd operands 16bit */
OPCODE(STOP, Z) /* stop VM */
OPCODE(LOADI16, BS) /* R(a) = mrb_int(b) */
+142
View File
@@ -0,0 +1,142 @@
/**
** @file mruby/proc.h - Proc class
**
** See Copyright Notice in mruby.h
*/
#ifndef MRUBY_PROC_H
#define MRUBY_PROC_H
#include "common.h"
#include <mruby/irep.h>
/**
* Proc class
*/
MRB_BEGIN_DECL
struct REnv {
MRB_OBJECT_HEADER;
mrb_value *stack;
struct mrb_context *cxt;
mrb_sym mid;
};
/* flags (21bits): 1(close):1(touched):1(heap):8(cioff/bidx):8(stack_len) */
#define MRB_ENV_SET_LEN(e,len) ((e)->flags = (((e)->flags & ~0xff)|((unsigned int)(len) & 0xff)))
#define MRB_ENV_LEN(e) ((mrb_int)((e)->flags & 0xff))
#define MRB_ENV_CLOSED (1<<20)
#define MRB_ENV_TOUCHED (1<<19)
#define MRB_ENV_HEAPED (1<<18)
#define MRB_ENV_CLOSE(e) ((e)->flags |= MRB_ENV_CLOSED)
#define MRB_ENV_TOUCH(e) ((e)->flags |= MRB_ENV_TOUCHED)
#define MRB_ENV_HEAP(e) ((e)->flags |= MRB_ENV_HEAPED)
#define MRB_ENV_HEAP_P(e) ((e)->flags & MRB_ENV_HEAPED)
#define MRB_ENV_ONSTACK_P(e) (((e)->flags & MRB_ENV_CLOSED) == 0)
#define MRB_ENV_BIDX(e) (((e)->flags >> 8) & 0xff)
#define MRB_ENV_SET_BIDX(e,idx) ((e)->flags = (((e)->flags & ~(0xff<<8))|((unsigned int)(idx) & 0xff)<<8))
void mrb_env_unshare(mrb_state*, struct REnv*);
struct RProc {
MRB_OBJECT_HEADER;
union {
mrb_irep *irep;
mrb_func_t func;
} body;
struct RProc *upper;
union {
struct RClass *target_class;
struct REnv *env;
} e;
};
/* aspec access */
#define MRB_ASPEC_REQ(a) (((a) >> 18) & 0x1f)
#define MRB_ASPEC_OPT(a) (((a) >> 13) & 0x1f)
#define MRB_ASPEC_REST(a) (((a) >> 12) & 0x1)
#define MRB_ASPEC_POST(a) (((a) >> 7) & 0x1f)
#define MRB_ASPEC_KEY(a) (((a) >> 2) & 0x1f)
#define MRB_ASPEC_KDICT(a) ((a) & (1<<1))
#define MRB_ASPEC_BLOCK(a) ((a) & 1)
#define MRB_PROC_CFUNC_FL 128
#define MRB_PROC_CFUNC_P(p) (((p)->flags & MRB_PROC_CFUNC_FL) != 0)
#define MRB_PROC_CFUNC(p) (p)->body.func
#define MRB_PROC_STRICT 256
#define MRB_PROC_STRICT_P(p) (((p)->flags & MRB_PROC_STRICT) != 0)
#define MRB_PROC_ORPHAN 512
#define MRB_PROC_ORPHAN_P(p) (((p)->flags & MRB_PROC_ORPHAN) != 0)
#define MRB_PROC_ENVSET 1024
#define MRB_PROC_ENV_P(p) (((p)->flags & MRB_PROC_ENVSET) != 0)
#define MRB_PROC_ENV(p) (MRB_PROC_ENV_P(p) ? (p)->e.env : NULL)
#define MRB_PROC_TARGET_CLASS(p) (MRB_PROC_ENV_P(p) ? (p)->e.env->c : (p)->e.target_class)
#define MRB_PROC_SET_TARGET_CLASS(p,tc) do {\
if (MRB_PROC_ENV_P(p)) {\
(p)->e.env->c = (tc);\
mrb_field_write_barrier(mrb, (struct RBasic*)(p)->e.env, (struct RBasic*)(tc));\
}\
else {\
(p)->e.target_class = (tc);\
mrb_field_write_barrier(mrb, (struct RBasic*)p, (struct RBasic*)(tc));\
}\
} while (0)
#define MRB_PROC_SCOPE 2048
#define MRB_PROC_SCOPE_P(p) (((p)->flags & MRB_PROC_SCOPE) != 0)
#define mrb_proc_ptr(v) ((struct RProc*)(mrb_ptr(v)))
struct RProc *mrb_proc_new(mrb_state*, mrb_irep*);
struct RProc *mrb_closure_new(mrb_state*, mrb_irep*);
MRB_API struct RProc *mrb_proc_new_cfunc(mrb_state*, mrb_func_t);
MRB_API struct RProc *mrb_closure_new_cfunc(mrb_state *mrb, mrb_func_t func, int nlocals);
void mrb_proc_copy(struct RProc *a, struct RProc *b);
mrb_int mrb_proc_arity(const struct RProc *p);
/* implementation of #send method */
mrb_value mrb_f_send(mrb_state *mrb, mrb_value self);
/* following functions are defined in mruby-proc-ext so please include it when using */
MRB_API struct RProc *mrb_proc_new_cfunc_with_env(mrb_state *mrb, mrb_func_t func, mrb_int argc, const mrb_value *argv);
MRB_API mrb_value mrb_proc_cfunc_env_get(mrb_state *mrb, mrb_int idx);
/* old name */
#define mrb_cfunc_env_get(mrb, idx) mrb_proc_cfunc_env_get(mrb, idx)
#define MRB_METHOD_FUNC_FL 1
#define MRB_METHOD_NOARG_FL 2
#ifndef MRB_METHOD_T_STRUCT
#define MRB_METHOD_FUNC_P(m) (((uintptr_t)(m))&MRB_METHOD_FUNC_FL)
#define MRB_METHOD_NOARG_P(m) (((uintptr_t)(m))&MRB_METHOD_NOARG_FL)
#define MRB_METHOD_NOARG_SET(m) ((m)=(mrb_method_t)(((uintptr_t)(m))|MRB_METHOD_NOARG_FL))
#define MRB_METHOD_FUNC(m) ((mrb_func_t)((uintptr_t)(m)>>2))
#define MRB_METHOD_FROM_FUNC(m,fn) ((m)=(mrb_method_t)((((uintptr_t)(fn))<<2)|MRB_METHOD_FUNC_FL))
#define MRB_METHOD_FROM_PROC(m,pr) ((m)=(mrb_method_t)(pr))
#define MRB_METHOD_PROC_P(m) (!MRB_METHOD_FUNC_P(m))
#define MRB_METHOD_PROC(m) ((struct RProc*)(m))
#define MRB_METHOD_UNDEF_P(m) ((m)==0)
#else
#define MRB_METHOD_FUNC_P(m) ((m).flags&MRB_METHOD_FUNC_FL)
#define MRB_METHOD_NOARG_P(m) ((m).flags&MRB_METHOD_NOARG_FL)
#define MRB_METHOD_FUNC(m) ((m).func)
#define MRB_METHOD_NOARG_SET(m) do{(m).flags|=MRB_METHOD_NOARG_FL;}while(0)
#define MRB_METHOD_FROM_FUNC(m,fn) do{(m).flags=MRB_METHOD_FUNC_FL;(m).func=(fn);}while(0)
#define MRB_METHOD_FROM_PROC(m,pr) do{(m).flags=0;(m).proc=(pr);}while(0)
#define MRB_METHOD_PROC_P(m) (!MRB_METHOD_FUNC_P(m))
#define MRB_METHOD_PROC(m) ((m).proc)
#define MRB_METHOD_UNDEF_P(m) ((m).proc==NULL)
#endif /* MRB_METHOD_T_STRUCT */
#define MRB_METHOD_CFUNC_P(m) (MRB_METHOD_FUNC_P(m)?TRUE:(MRB_METHOD_PROC(m)?(MRB_PROC_CFUNC_P(MRB_METHOD_PROC(m))):FALSE))
#define MRB_METHOD_CFUNC(m) (MRB_METHOD_FUNC_P(m)?MRB_METHOD_FUNC(m):((MRB_METHOD_PROC(m)&&MRB_PROC_CFUNC_P(MRB_METHOD_PROC(m)))?MRB_PROC_CFUNC(MRB_METHOD_PROC(m)):NULL))
#include <mruby/khash.h>
KHASH_DECLARE(mt, mrb_sym, mrb_method_t, TRUE)
MRB_END_DECL
#endif /* MRUBY_PROC_H */
+79
View File
@@ -0,0 +1,79 @@
/**
** @file mruby/range.h - Range class
**
** See Copyright Notice in mruby.h
*/
#ifndef MRUBY_RANGE_H
#define MRUBY_RANGE_H
#include "common.h"
/**
* Range class
*/
MRB_BEGIN_DECL
#if defined(MRB_NAN_BOXING) && defined(MRB_64BIT) || defined(MRB_WORD_BOXING)
# define MRB_RANGE_EMBED
#endif
#ifdef MRB_RANGE_EMBED
struct RRange {
MRB_OBJECT_HEADER;
mrb_value beg;
mrb_value end;
mrb_bool excl;
};
# define mrb_gc_free_range(mrb, p) ((void)0)
# define RANGE_BEG(p) ((p)->beg)
# define RANGE_END(p) ((p)->end)
#else
typedef struct mrb_range_edges {
mrb_value beg;
mrb_value end;
} mrb_range_edges;
struct RRange {
MRB_OBJECT_HEADER;
mrb_range_edges *edges;
mrb_bool excl;
};
# define mrb_gc_free_range(mrb, p) mrb_free(mrb, (p)->edges)
# define RANGE_BEG(p) ((p)->edges->beg)
# define RANGE_END(p) ((p)->edges->end)
#endif
#define mrb_range_beg(mrb, r) RANGE_BEG(mrb_range_ptr(mrb, r))
#define mrb_range_end(mrb, r) RANGE_END(mrb_range_ptr(mrb, r))
#define mrb_range_excl_p(mrb, r) RANGE_EXCL(mrb_range_ptr(mrb, r))
#define mrb_range_raw_ptr(r) ((struct RRange*)mrb_ptr(r))
#define mrb_range_value(p) mrb_obj_value((void*)(p))
#define RANGE_EXCL(p) ((p)->excl)
MRB_API struct RRange* mrb_range_ptr(mrb_state *mrb, mrb_value range);
/*
* Initializes a Range.
*
* If the third parameter is FALSE then it includes the last value in the range.
* If the third parameter is TRUE then it excludes the last value in the range.
*
* @param start the beginning value.
* @param end the ending value.
* @param exclude represents the inclusion or exclusion of the last value.
*/
MRB_API mrb_value mrb_range_new(mrb_state *mrb, mrb_value start, mrb_value end, mrb_bool exclude);
enum mrb_range_beg_len {
MRB_RANGE_TYPE_MISMATCH = 0, /* (failure) not range */
MRB_RANGE_OK = 1, /* (success) range */
MRB_RANGE_OUT = 2 /* (failure) out of range */
};
MRB_API enum mrb_range_beg_len mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, mrb_int len, mrb_bool trunc);
mrb_value mrb_get_values_at(mrb_state *mrb, mrb_value obj, mrb_int olen, mrb_int argc, const mrb_value *argv, mrb_value (*func)(mrb_state*, mrb_value, mrb_int));
void mrb_gc_mark_range(mrb_state *mrb, struct RRange *r);
MRB_END_DECL
#endif /* MRUBY_RANGE_H */
+16
View File
@@ -0,0 +1,16 @@
/**
** @file mruby/re.h - Regexp class
**
** See Copyright Notice in mruby.h
*/
#ifndef MRUBY_RE_H
#define MRUBY_RE_H
MRB_BEGIN_DECL
#define REGEXP_CLASS "Regexp"
MRB_END_DECL
#endif /* RE_H */
+474
View File
@@ -0,0 +1,474 @@
/**
** @file mruby/string.h - String class
**
** See Copyright Notice in mruby.h
*/
#ifndef MRUBY_STRING_H
#define MRUBY_STRING_H
#include "common.h"
/**
* String class
*/
MRB_BEGIN_DECL
extern const char mrb_digitmap[];
#define RSTRING_EMBED_LEN_MAX \
((mrb_int)(sizeof(void*) * 3 + sizeof(void*) - 32 / CHAR_BIT - 1))
struct RString {
MRB_OBJECT_HEADER;
union {
struct {
mrb_ssize len;
union {
mrb_ssize capa;
struct mrb_shared_string *shared;
struct RString *fshared;
} aux;
char *ptr;
} heap;
} as;
};
struct RStringEmbed {
MRB_OBJECT_HEADER;
char ary[];
};
#define RSTR_SET_TYPE_FLAG(s, type) (RSTR_UNSET_TYPE_FLAG(s), (s)->flags |= MRB_STR_##type)
#define RSTR_UNSET_TYPE_FLAG(s) ((s)->flags &= ~(MRB_STR_TYPE_MASK|MRB_STR_EMBED_LEN_MASK))
#define RSTR_EMBED_P(s) ((s)->flags & MRB_STR_EMBED)
#define RSTR_SET_EMBED_FLAG(s) ((s)->flags |= MRB_STR_EMBED)
#define RSTR_UNSET_EMBED_FLAG(s) ((s)->flags &= ~(MRB_STR_EMBED|MRB_STR_EMBED_LEN_MASK))
#define RSTR_SET_EMBED_LEN(s, n) do {\
size_t tmp_n = (n);\
(s)->flags &= ~MRB_STR_EMBED_LEN_MASK;\
(s)->flags |= (tmp_n) << MRB_STR_EMBED_LEN_SHIFT;\
} while (0)
#define RSTR_SET_LEN(s, n) do {\
if (RSTR_EMBED_P(s)) {\
RSTR_SET_EMBED_LEN((s),(n));\
}\
else {\
(s)->as.heap.len = (mrb_ssize)(n);\
}\
} while (0)
#define RSTR_EMBED_PTR(s) (((struct RStringEmbed*)(s))->ary)
#define RSTR_EMBED_LEN(s)\
(mrb_int)(((s)->flags & MRB_STR_EMBED_LEN_MASK) >> MRB_STR_EMBED_LEN_SHIFT)
#define RSTR_EMBEDDABLE_P(len) ((len) <= RSTRING_EMBED_LEN_MAX)
#define RSTR_PTR(s) ((RSTR_EMBED_P(s)) ? RSTR_EMBED_PTR(s) : (s)->as.heap.ptr)
#define RSTR_LEN(s) ((RSTR_EMBED_P(s)) ? RSTR_EMBED_LEN(s) : (s)->as.heap.len)
#define RSTR_CAPA(s) (RSTR_EMBED_P(s) ? RSTRING_EMBED_LEN_MAX : (s)->as.heap.aux.capa)
#define RSTR_SHARED_P(s) ((s)->flags & MRB_STR_SHARED)
#define RSTR_SET_SHARED_FLAG(s) ((s)->flags |= MRB_STR_SHARED)
#define RSTR_UNSET_SHARED_FLAG(s) ((s)->flags &= ~MRB_STR_SHARED)
#define RSTR_FSHARED_P(s) ((s)->flags & MRB_STR_FSHARED)
#define RSTR_SET_FSHARED_FLAG(s) ((s)->flags |= MRB_STR_FSHARED)
#define RSTR_UNSET_FSHARED_FLAG(s) ((s)->flags &= ~MRB_STR_FSHARED)
#define RSTR_NOFREE_P(s) ((s)->flags & MRB_STR_NOFREE)
#define RSTR_SET_NOFREE_FLAG(s) ((s)->flags |= MRB_STR_NOFREE)
#define RSTR_UNSET_NOFREE_FLAG(s) ((s)->flags &= ~MRB_STR_NOFREE)
#ifdef MRB_UTF8_STRING
# define RSTR_ASCII_P(s) ((s)->flags & MRB_STR_ASCII)
# define RSTR_SET_ASCII_FLAG(s) ((s)->flags |= MRB_STR_ASCII)
# define RSTR_UNSET_ASCII_FLAG(s) ((s)->flags &= ~MRB_STR_ASCII)
# define RSTR_WRITE_ASCII_FLAG(s, v) (RSTR_UNSET_ASCII_FLAG(s), (s)->flags |= v)
# define RSTR_COPY_ASCII_FLAG(dst, src) RSTR_WRITE_ASCII_FLAG(dst, RSTR_ASCII_P(src))
#else
# define RSTR_ASCII_P(s) (void)0
# define RSTR_SET_ASCII_FLAG(s) (void)0
# define RSTR_UNSET_ASCII_FLAG(s) (void)0
# define RSTR_WRITE_ASCII_FLAG(s, v) (void)0
# define RSTR_COPY_ASCII_FLAG(dst, src) (void)0
#endif
#define RSTR_POOL_P(s) ((s)->flags & MRB_STR_POOL)
#define RSTR_SET_POOL_FLAG(s) ((s)->flags |= MRB_STR_POOL)
/**
* Returns a pointer from a Ruby string
*/
#define mrb_str_ptr(s) ((struct RString*)(mrb_ptr(s)))
#define RSTRING(s) mrb_str_ptr(s)
#define RSTRING_PTR(s) RSTR_PTR(RSTRING(s))
#define RSTRING_EMBED_LEN(s) RSTR_EMBED_LEN(RSTRING(s))
#define RSTRING_LEN(s) RSTR_LEN(RSTRING(s))
#define RSTRING_CAPA(s) RSTR_CAPA(RSTRING(s))
#define RSTRING_END(s) (RSTRING_PTR(s) + RSTRING_LEN(s))
MRB_API mrb_int mrb_str_strlen(mrb_state*, struct RString*);
#define RSTRING_CSTR(mrb,s) mrb_string_cstr(mrb, s)
#define MRB_STR_SHARED 1
#define MRB_STR_FSHARED 2
#define MRB_STR_NOFREE 4
#define MRB_STR_EMBED 8 /* type flags up to here */
#define MRB_STR_POOL 16 /* status flags from here */
#define MRB_STR_ASCII 32
#define MRB_STR_EMBED_LEN_SHIFT 6
#define MRB_STR_EMBED_LEN_BIT 5
#define MRB_STR_EMBED_LEN_MASK (((1 << MRB_STR_EMBED_LEN_BIT) - 1) << MRB_STR_EMBED_LEN_SHIFT)
#define MRB_STR_TYPE_MASK (MRB_STR_POOL - 1)
void mrb_gc_free_str(mrb_state*, struct RString*);
MRB_API void mrb_str_modify(mrb_state *mrb, struct RString *s);
/* mrb_str_modify() with keeping ASCII flag if set */
MRB_API void mrb_str_modify_keep_ascii(mrb_state *mrb, struct RString *s);
/**
* Finds the index of a substring in a string
*/
MRB_API mrb_int mrb_str_index(mrb_state *mrb, mrb_value str, const char *p, mrb_int len, mrb_int offset);
#define mrb_str_index_lit(mrb, str, lit, off) mrb_str_index(mrb, str, lit, mrb_strlen_lit(lit), off);
/**
* Appends self to other. Returns self as a concatenated string.
*
*
* Example:
*
* int
* main(int argc,
* char **argv)
* {
* // Variable declarations.
* mrb_value str1;
* mrb_value str2;
*
* mrb_state *mrb = mrb_open();
* if (!mrb)
* {
* // handle error
* }
*
* // Creates new Ruby strings.
* str1 = mrb_str_new_lit(mrb, "abc");
* str2 = mrb_str_new_lit(mrb, "def");
*
* // Concatenates str2 to str1.
* mrb_str_concat(mrb, str1, str2);
*
* // Prints new Concatenated Ruby string.
* mrb_p(mrb, str1);
*
* mrb_close(mrb);
* return 0;
* }
*
* Result:
*
* => "abcdef"
*
* @param mrb The current mruby state.
* @param self String to concatenate.
* @param other String to append to self.
* @return [mrb_value] Returns a new String appending other to self.
*/
MRB_API void mrb_str_concat(mrb_state *mrb, mrb_value self, mrb_value other);
/**
* Adds two strings together.
*
*
* Example:
*
* int
* main(int argc,
* char **argv)
* {
* // Variable declarations.
* mrb_value a;
* mrb_value b;
* mrb_value c;
*
* mrb_state *mrb = mrb_open();
* if (!mrb)
* {
* // handle error
* }
*
* // Creates two Ruby strings from the passed in C strings.
* a = mrb_str_new_lit(mrb, "abc");
* b = mrb_str_new_lit(mrb, "def");
*
* // Prints both C strings.
* mrb_p(mrb, a);
* mrb_p(mrb, b);
*
* // Concatenates both Ruby strings.
* c = mrb_str_plus(mrb, a, b);
*
* // Prints new Concatenated Ruby string.
* mrb_p(mrb, c);
*
* mrb_close(mrb);
* return 0;
* }
*
*
* Result:
*
* => "abc" # First string
* => "def" # Second string
* => "abcdef" # First & Second concatenated.
*
* @param mrb The current mruby state.
* @param a First string to concatenate.
* @param b Second string to concatenate.
* @return [mrb_value] Returns a new String containing a concatenated to b.
*/
MRB_API mrb_value mrb_str_plus(mrb_state *mrb, mrb_value a, mrb_value b);
/**
* Converts pointer into a Ruby string.
*
* @param mrb The current mruby state.
* @param p The pointer to convert to Ruby string.
* @return [mrb_value] Returns a new Ruby String.
*/
MRB_API mrb_value mrb_ptr_to_str(mrb_state *mrb, void *p);
/**
* Returns an object as a Ruby string.
*
* @param mrb The current mruby state.
* @param obj An object to return as a Ruby string.
* @return [mrb_value] An object as a Ruby string.
*/
MRB_API mrb_value mrb_obj_as_string(mrb_state *mrb, mrb_value obj);
/**
* Resizes the string's length. Returns the amount of characters
* in the specified by len.
*
* Example:
*
* int
* main(int argc,
* char **argv)
* {
* // Variable declaration.
* mrb_value str;
*
* mrb_state *mrb = mrb_open();
* if (!mrb)
* {
* // handle error
* }
* // Creates a new string.
* str = mrb_str_new_lit(mrb, "Hello, world!");
* // Returns 5 characters of
* mrb_str_resize(mrb, str, 5);
* mrb_p(mrb, str);
*
* mrb_close(mrb);
* return 0;
* }
*
* Result:
*
* => "Hello"
*
* @param mrb The current mruby state.
* @param str The Ruby string to resize.
* @param len The length.
* @return [mrb_value] An object as a Ruby string.
*/
MRB_API mrb_value mrb_str_resize(mrb_state *mrb, mrb_value str, mrb_int len);
/**
* Returns a sub string.
*
* Example:
*
* int
* main(int argc,
* char const **argv)
* {
* // Variable declarations.
* mrb_value str1;
* mrb_value str2;
*
* mrb_state *mrb = mrb_open();
* if (!mrb)
* {
* // handle error
* }
* // Creates new string.
* str1 = mrb_str_new_lit(mrb, "Hello, world!");
* // Returns a sub-string within the range of 0..2
* str2 = mrb_str_substr(mrb, str1, 0, 2);
*
* // Prints sub-string.
* mrb_p(mrb, str2);
*
* mrb_close(mrb);
* return 0;
* }
*
* Result:
*
* => "He"
*
* @param mrb The current mruby state.
* @param str Ruby string.
* @param beg The beginning point of the sub-string.
* @param len The end point of the sub-string.
* @return [mrb_value] An object as a Ruby sub-string.
*/
MRB_API mrb_value mrb_str_substr(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len);
/**
* Returns a Ruby string type.
*
*
* @param mrb The current mruby state.
* @param str Ruby string.
* @return [mrb_value] A Ruby string.
*/
MRB_API mrb_value mrb_ensure_string_type(mrb_state *mrb, mrb_value str);
MRB_API mrb_value mrb_check_string_type(mrb_state *mrb, mrb_value str);
/* obsolete: use mrb_ensure_string_type() instead */
MRB_API mrb_value mrb_string_type(mrb_state *mrb, mrb_value str);
MRB_API mrb_value mrb_str_new_capa(mrb_state *mrb, size_t capa);
MRB_API mrb_value mrb_str_buf_new(mrb_state *mrb, size_t capa);
/* NULL terminated C string from mrb_value */
MRB_API const char *mrb_string_cstr(mrb_state *mrb, mrb_value str);
/* NULL terminated C string from mrb_value; `str` will be updated */
MRB_API const char *mrb_string_value_cstr(mrb_state *mrb, mrb_value *str);
/* obslete: use RSTRING_PTR() */
MRB_API const char *mrb_string_value_ptr(mrb_state *mrb, mrb_value str);
/* obslete: use RSTRING_LEN() */
MRB_API mrb_int mrb_string_value_len(mrb_state *mrb, mrb_value str);
/**
* Duplicates a string object.
*
*
* @param mrb The current mruby state.
* @param str Ruby string.
* @return [mrb_value] Duplicated Ruby string.
*/
MRB_API mrb_value mrb_str_dup(mrb_state *mrb, mrb_value str);
/**
* Returns a symbol from a passed in Ruby string.
*
* @param mrb The current mruby state.
* @param self Ruby string.
* @return [mrb_value] A symbol.
*/
MRB_API mrb_value mrb_str_intern(mrb_state *mrb, mrb_value self);
MRB_API mrb_value mrb_str_to_inum(mrb_state *mrb, mrb_value str, mrb_int base, mrb_bool badcheck);
MRB_API mrb_value mrb_cstr_to_inum(mrb_state *mrb, const char *s, mrb_int base, mrb_bool badcheck);
MRB_API double mrb_str_to_dbl(mrb_state *mrb, mrb_value str, mrb_bool badcheck);
MRB_API double mrb_cstr_to_dbl(mrb_state *mrb, const char *s, mrb_bool badcheck);
/**
* Returns a converted string type.
* For type checking, non converting `mrb_to_str` is recommended.
*/
MRB_API mrb_value mrb_str_to_str(mrb_state *mrb, mrb_value str);
/**
* Returns true if the strings match and false if the strings don't match.
*
* @param mrb The current mruby state.
* @param str1 Ruby string to compare.
* @param str2 Ruby string to compare.
* @return [mrb_value] boolean value.
*/
MRB_API mrb_bool mrb_str_equal(mrb_state *mrb, mrb_value str1, mrb_value str2);
/**
* Returns a concatenated string comprised of a Ruby string and a C string.
*
* @param mrb The current mruby state.
* @param str Ruby string.
* @param ptr A C string.
* @param len length of C string.
* @return [mrb_value] A Ruby string.
* @see mrb_str_cat_cstr
*/
MRB_API mrb_value mrb_str_cat(mrb_state *mrb, mrb_value str, const char *ptr, size_t len);
/**
* Returns a concatenated string comprised of a Ruby string and a C string.
*
* @param mrb The current mruby state.
* @param str Ruby string.
* @param ptr A C string.
* @return [mrb_value] A Ruby string.
* @see mrb_str_cat
*/
MRB_API mrb_value mrb_str_cat_cstr(mrb_state *mrb, mrb_value str, const char *ptr);
MRB_API mrb_value mrb_str_cat_str(mrb_state *mrb, mrb_value str, mrb_value str2);
#define mrb_str_cat_lit(mrb, str, lit) mrb_str_cat(mrb, str, lit, mrb_strlen_lit(lit))
/**
* Adds str2 to the end of str1.
*/
MRB_API mrb_value mrb_str_append(mrb_state *mrb, mrb_value str, mrb_value str2);
/**
* Returns 0 if both Ruby strings are equal. Returns a value < 0 if Ruby str1 is less than Ruby str2. Returns a value > 0 if Ruby str2 is greater than Ruby str1.
*/
MRB_API int mrb_str_cmp(mrb_state *mrb, mrb_value str1, mrb_value str2);
/**
* Returns a newly allocated C string from a Ruby string.
* This is an utility function to pass a Ruby string to C library functions.
*
* - Returned string does not contain any NUL characters (but terminator).
* - It raises an ArgumentError exception if Ruby string contains
* NUL characters.
* - Retured string will be freed automatically on next GC.
* - Caller can modify returned string without affecting Ruby string
* (e.g. it can be used for mkstemp(3)).
*
* @param mrb The current mruby state.
* @param str Ruby string. Must be an instance of String.
* @return [char *] A newly allocated C string.
*/
MRB_API char *mrb_str_to_cstr(mrb_state *mrb, mrb_value str);
mrb_value mrb_str_pool(mrb_state *mrb, const char *s, mrb_int len, mrb_bool nofree);
uint32_t mrb_str_hash(mrb_state *mrb, mrb_value str);
mrb_value mrb_str_dump(mrb_state *mrb, mrb_value str);
/**
* Returns a printable version of str, surrounded by quote marks, with special characters escaped.
*/
mrb_value mrb_str_inspect(mrb_state *mrb, mrb_value str);
/* For backward compatibility */
#define mrb_str_cat2(mrb, str, ptr) mrb_str_cat_cstr(mrb, str, ptr)
#define mrb_str_buf_cat(mrb, str, ptr, len) mrb_str_cat(mrb, str, ptr, len)
#define mrb_str_buf_append(mrb, str, str2) mrb_str_cat_str(mrb, str, str2)
mrb_bool mrb_str_beg_len(mrb_int str_len, mrb_int *begp, mrb_int *lenp);
mrb_value mrb_str_byte_subseq(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len);
#ifdef MRB_UTF8_STRING
mrb_int mrb_utf8len(const char *str, const char *end);
mrb_int mrb_utf8_strlen(const char *str, mrb_int byte_len);
#endif
MRB_END_DECL
#endif /* MRUBY_STRING_H */
+55
View File
@@ -0,0 +1,55 @@
/**
** @file mruby/throw.h - mruby exception throwing handler
**
** See Copyright Notice in mruby.h
*/
#ifndef MRB_THROW_H
#define MRB_THROW_H
#if defined(MRB_ENABLE_CXX_ABI)
# if !defined(__cplusplus)
# error Trying to use C++ exception handling in C code
# endif
#endif
#if defined(MRB_ENABLE_CXX_EXCEPTION) && defined(__cplusplus)
#define MRB_TRY(buf) try {
#define MRB_CATCH(buf) } catch(mrb_jmpbuf_impl e) { if (e != (buf)->impl) { throw e; }
#define MRB_END_EXC(buf) }
#define MRB_THROW(buf) throw((buf)->impl)
typedef mrb_int mrb_jmpbuf_impl;
#else
#include <setjmp.h>
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
#define MRB_SETJMP _setjmp
#define MRB_LONGJMP _longjmp
#else
#define MRB_SETJMP setjmp
#define MRB_LONGJMP longjmp
#endif
#define MRB_TRY(buf) if (MRB_SETJMP((buf)->impl) == 0) {
#define MRB_CATCH(buf) } else {
#define MRB_END_EXC(buf) }
#define MRB_THROW(buf) MRB_LONGJMP((buf)->impl, 1);
#define mrb_jmpbuf_impl jmp_buf
#endif
struct mrb_jmpbuf {
mrb_jmpbuf_impl impl;
#if defined(MRB_ENABLE_CXX_EXCEPTION) && defined(__cplusplus)
static mrb_int jmpbuf_id;
mrb_jmpbuf() : impl(jmpbuf_id++) {}
#endif
};
#endif /* MRB_THROW_H */
+390
View File
@@ -0,0 +1,390 @@
/**
** @file mruby/value.h - mruby value definitions
**
** See Copyright Notice in mruby.h
*/
#ifndef MRUBY_VALUE_H
#define MRUBY_VALUE_H
#include "common.h"
/*
* MRuby Value definition functions and macros.
*/
MRB_BEGIN_DECL
/**
* mruby Symbol.
* @class mrb_sym
*
* You can create an mrb_sym by simply using mrb_str_intern() or mrb_intern_cstr()
*/
typedef uint32_t mrb_sym;
/**
* mruby Boolean.
* @class mrb_bool
*
*
* Used internally to represent boolean. Can be TRUE or FALSE.
* Not to be confused with Ruby's boolean classes, which can be
* obtained using mrb_false_value() and mrb_true_value()
*/
typedef uint8_t mrb_bool;
struct mrb_state;
#if defined _MSC_VER && _MSC_VER < 1800
# define PRIo64 "llo"
# define PRId64 "lld"
# define PRIu64 "llu"
# define PRIx64 "llx"
# define PRIo16 "ho"
# define PRId16 "hd"
# define PRIu16 "hu"
# define PRIx16 "hx"
# define PRIo32 "o"
# define PRId32 "d"
# define PRIu32 "u"
# define PRIx32 "x"
#else
# include <inttypes.h>
#endif
#if defined(MRB_INT64)
typedef int64_t mrb_int;
# define MRB_INT_BIT 64
# define MRB_INT_MIN (INT64_MIN>>MRB_FIXNUM_SHIFT)
# define MRB_INT_MAX (INT64_MAX>>MRB_FIXNUM_SHIFT)
# define MRB_PRIo PRIo64
# define MRB_PRId PRId64
# define MRB_PRIx PRIx64
#else
typedef int32_t mrb_int;
# define MRB_INT_BIT 32
# define MRB_INT_MIN (INT32_MIN>>MRB_FIXNUM_SHIFT)
# define MRB_INT_MAX (INT32_MAX>>MRB_FIXNUM_SHIFT)
# define MRB_PRIo PRIo32
# define MRB_PRId PRId32
# define MRB_PRIx PRIx32
#endif
#ifdef MRB_ENDIAN_BIG
# define MRB_ENDIAN_LOHI(a,b) a b
#else
# define MRB_ENDIAN_LOHI(a,b) b a
#endif
#ifndef MRB_WITHOUT_FLOAT
MRB_API double mrb_float_read(const char*, char**);
#ifdef MRB_USE_FLOAT
typedef float mrb_float;
#else
typedef double mrb_float;
#endif
#endif
#if defined _MSC_VER && _MSC_VER < 1900
# include <stdarg.h>
MRB_API int mrb_msvc_vsnprintf(char *s, size_t n, const char *format, va_list arg);
MRB_API int mrb_msvc_snprintf(char *s, size_t n, const char *format, ...);
# define vsnprintf(s, n, format, arg) mrb_msvc_vsnprintf(s, n, format, arg)
# define snprintf(s, n, format, ...) mrb_msvc_snprintf(s, n, format, __VA_ARGS__)
# if _MSC_VER < 1800 && !defined MRB_WITHOUT_FLOAT
# include <float.h>
# define isfinite(n) _finite(n)
# define isnan _isnan
# define isinf(n) (!_finite(n) && !_isnan(n))
# define signbit(n) (_copysign(1.0, (n)) < 0.0)
static const unsigned int IEEE754_INFINITY_BITS_SINGLE = 0x7F800000;
# define INFINITY (*(float *)&IEEE754_INFINITY_BITS_SINGLE)
# define NAN ((float)(INFINITY - INFINITY))
# endif
#endif
enum mrb_vtype {
MRB_TT_FALSE = 0,
MRB_TT_TRUE,
MRB_TT_FLOAT,
MRB_TT_FIXNUM,
MRB_TT_SYMBOL,
MRB_TT_UNDEF,
MRB_TT_CPTR,
MRB_TT_FREE,
MRB_TT_OBJECT,
MRB_TT_CLASS,
MRB_TT_MODULE,
MRB_TT_ICLASS,
MRB_TT_SCLASS,
MRB_TT_PROC,
MRB_TT_ARRAY,
MRB_TT_HASH,
MRB_TT_STRING,
MRB_TT_RANGE,
MRB_TT_EXCEPTION,
MRB_TT_ENV,
MRB_TT_DATA,
MRB_TT_FIBER,
MRB_TT_ISTRUCT,
MRB_TT_BREAK,
MRB_TT_MAXDEFINE
};
#include <mruby/object.h>
#ifdef MRB_DOCUMENTATION_BLOCK
/**
* @abstract
* MRuby value boxing.
*
* Actual implementation depends on configured boxing type.
*
* @see mruby/boxing_no.h Default boxing representation
* @see mruby/boxing_word.h Word representation
* @see mruby/boxing_nan.h Boxed double representation
*/
typedef void mrb_value;
#endif
#if defined(MRB_WORD_BOXING) || (defined(MRB_NAN_BOXING) && defined(MRB_64BIT))
struct RCptr {
MRB_OBJECT_HEADER;
void *p;
};
#endif
#if defined(MRB_NAN_BOXING)
#include "boxing_nan.h"
#elif defined(MRB_WORD_BOXING)
#include "boxing_word.h"
#else
#include "boxing_no.h"
#endif
#define MRB_SYMBOL_BIT (sizeof(mrb_sym) * CHAR_BIT - MRB_SYMBOL_SHIFT)
#define MRB_SYMBOL_MAX (UINT32_MAX >> MRB_SYMBOL_SHIFT)
#if INTPTR_MAX < MRB_INT_MAX
typedef intptr_t mrb_ssize;
# define MRB_SSIZE_MAX (INTPTR_MAX>>MRB_FIXNUM_SHIFT)
#else
typedef mrb_int mrb_ssize;
# define MRB_SSIZE_MAX MRB_INT_MAX
#endif
#ifndef mrb_immediate_p
#define mrb_immediate_p(o) (mrb_type(o) < MRB_TT_FREE)
#endif
#ifndef mrb_fixnum_p
#define mrb_fixnum_p(o) (mrb_type(o) == MRB_TT_FIXNUM)
#endif
#ifndef mrb_symbol_p
#define mrb_symbol_p(o) (mrb_type(o) == MRB_TT_SYMBOL)
#endif
#ifndef mrb_undef_p
#define mrb_undef_p(o) (mrb_type(o) == MRB_TT_UNDEF)
#endif
#ifndef mrb_nil_p
#define mrb_nil_p(o) (mrb_type(o) == MRB_TT_FALSE && !mrb_fixnum(o))
#endif
#ifndef mrb_false_p
#define mrb_false_p(o) (mrb_type(o) == MRB_TT_FALSE && !!mrb_fixnum(o))
#endif
#ifndef mrb_true_p
#define mrb_true_p(o) (mrb_type(o) == MRB_TT_TRUE)
#endif
#ifndef MRB_WITHOUT_FLOAT
#ifndef mrb_float_p
#define mrb_float_p(o) (mrb_type(o) == MRB_TT_FLOAT)
#endif
#endif
#ifndef mrb_array_p
#define mrb_array_p(o) (mrb_type(o) == MRB_TT_ARRAY)
#endif
#ifndef mrb_string_p
#define mrb_string_p(o) (mrb_type(o) == MRB_TT_STRING)
#endif
#ifndef mrb_hash_p
#define mrb_hash_p(o) (mrb_type(o) == MRB_TT_HASH)
#endif
#ifndef mrb_cptr_p
#define mrb_cptr_p(o) (mrb_type(o) == MRB_TT_CPTR)
#endif
#ifndef mrb_exception_p
#define mrb_exception_p(o) (mrb_type(o) == MRB_TT_EXCEPTION)
#endif
#ifndef mrb_free_p
#define mrb_free_p(o) (mrb_type(o) == MRB_TT_FREE)
#endif
#ifndef mrb_object_p
#define mrb_object_p(o) (mrb_type(o) == MRB_TT_OBJECT)
#endif
#ifndef mrb_class_p
#define mrb_class_p(o) (mrb_type(o) == MRB_TT_CLASS)
#endif
#ifndef mrb_module_p
#define mrb_module_p(o) (mrb_type(o) == MRB_TT_MODULE)
#endif
#ifndef mrb_iclass_p
#define mrb_iclass_p(o) (mrb_type(o) == MRB_TT_ICLASS)
#endif
#ifndef mrb_sclass_p
#define mrb_sclass_p(o) (mrb_type(o) == MRB_TT_SCLASS)
#endif
#ifndef mrb_proc_p
#define mrb_proc_p(o) (mrb_type(o) == MRB_TT_PROC)
#endif
#ifndef mrb_range_p
#define mrb_range_p(o) (mrb_type(o) == MRB_TT_RANGE)
#endif
#ifndef mrb_env_p
#define mrb_env_p(o) (mrb_type(o) == MRB_TT_ENV)
#endif
#ifndef mrb_data_p
#define mrb_data_p(o) (mrb_type(o) == MRB_TT_DATA)
#endif
#ifndef mrb_fiber_p
#define mrb_fiber_p(o) (mrb_type(o) == MRB_TT_FIBER)
#endif
#ifndef mrb_istruct_p
#define mrb_istruct_p(o) (mrb_type(o) == MRB_TT_ISTRUCT)
#endif
#ifndef mrb_break_p
#define mrb_break_p(o) (mrb_type(o) == MRB_TT_BREAK)
#endif
#ifndef mrb_bool
#define mrb_bool(o) (mrb_type(o) != MRB_TT_FALSE)
#endif
#define mrb_test(o) mrb_bool(o)
/**
* Returns a float in Ruby.
*
* Takes a float and boxes it into an mrb_value
*/
#ifndef MRB_WITHOUT_FLOAT
MRB_INLINE mrb_value mrb_float_value(struct mrb_state *mrb, mrb_float f)
{
mrb_value v;
(void) mrb;
SET_FLOAT_VALUE(mrb, v, f);
return v;
}
#endif
MRB_INLINE mrb_value
mrb_cptr_value(struct mrb_state *mrb, void *p)
{
mrb_value v;
(void) mrb;
SET_CPTR_VALUE(mrb,v,p);
return v;
}
/**
* Returns a fixnum in Ruby.
*
* Takes an integer and boxes it into an mrb_value
*/
MRB_INLINE mrb_value mrb_fixnum_value(mrb_int i)
{
mrb_value v;
SET_INT_VALUE(v, i);
return v;
}
MRB_INLINE mrb_value
mrb_symbol_value(mrb_sym i)
{
mrb_value v;
SET_SYM_VALUE(v, i);
return v;
}
MRB_INLINE mrb_value
mrb_obj_value(void *p)
{
mrb_value v;
SET_OBJ_VALUE(v, (struct RBasic*)p);
mrb_assert(p == mrb_ptr(v));
mrb_assert(((struct RBasic*)p)->tt == mrb_type(v));
return v;
}
/**
* Get a nil mrb_value object.
*
* @return
* nil mrb_value object reference.
*/
MRB_INLINE mrb_value mrb_nil_value(void)
{
mrb_value v;
SET_NIL_VALUE(v);
return v;
}
/**
* Returns false in Ruby.
*/
MRB_INLINE mrb_value mrb_false_value(void)
{
mrb_value v;
SET_FALSE_VALUE(v);
return v;
}
/**
* Returns true in Ruby.
*/
MRB_INLINE mrb_value mrb_true_value(void)
{
mrb_value v;
SET_TRUE_VALUE(v);
return v;
}
MRB_INLINE mrb_value
mrb_bool_value(mrb_bool boolean)
{
mrb_value v;
SET_BOOL_VALUE(v, boolean);
return v;
}
MRB_INLINE mrb_value
mrb_undef_value(void)
{
mrb_value v;
SET_UNDEF_VALUE(v);
return v;
}
#if defined(MRB_USE_ETEXT_EDATA) && !defined(MRB_USE_LINK_TIME_RO_DATA_P)
# ifdef __GNUC__
# warning MRB_USE_ETEXT_EDATA is deprecated. Define MRB_USE_LINK_TIME_RO_DATA_P instead.
# endif
# define MRB_USE_LINK_TIME_RO_DATA_P
#endif
#if defined(MRB_USE_CUSTOM_RO_DATA_P)
/* If you define `MRB_USE_CUSTOM_RO_DATA_P`, you must implement `mrb_ro_data_p()`. */
mrb_bool mrb_ro_data_p(const char *p);
#elif defined(MRB_USE_LINK_TIME_RO_DATA_P)
extern char __ehdr_start[];
extern char __init_array_start[];
static inline mrb_bool
mrb_ro_data_p(const char *p)
{
return __ehdr_start < p && p < __init_array_start;
}
#else
# define mrb_ro_data_p(p) FALSE
#endif
MRB_END_DECL
#endif /* MRUBY_VALUE_H */
+139
View File
@@ -0,0 +1,139 @@
/**
** @file mruby/variable.h - mruby variables
**
** See Copyright Notice in mruby.h
*/
#ifndef MRUBY_VARIABLE_H
#define MRUBY_VARIABLE_H
#include "common.h"
/**
* Functions to access mruby variables.
*/
MRB_BEGIN_DECL
typedef struct global_variable {
int counter;
mrb_value *data;
mrb_value (*getter)(void);
void (*setter)(void);
/* void (*marker)(); */
/* int block_trace; */
/* struct trace_var *trace; */
} global_variable;
struct global_entry {
global_variable *var;
mrb_sym id;
};
mrb_value mrb_vm_special_get(mrb_state*, mrb_sym);
void mrb_vm_special_set(mrb_state*, mrb_sym, mrb_value);
mrb_value mrb_vm_cv_get(mrb_state*, mrb_sym);
void mrb_vm_cv_set(mrb_state*, mrb_sym, mrb_value);
mrb_value mrb_vm_const_get(mrb_state*, mrb_sym);
void mrb_vm_const_set(mrb_state*, mrb_sym, mrb_value);
MRB_API mrb_value mrb_const_get(mrb_state*, mrb_value, mrb_sym);
MRB_API void mrb_const_set(mrb_state*, mrb_value, mrb_sym, mrb_value);
MRB_API mrb_bool mrb_const_defined(mrb_state*, mrb_value, mrb_sym);
MRB_API void mrb_const_remove(mrb_state*, mrb_value, mrb_sym);
MRB_API mrb_bool mrb_iv_name_sym_p(mrb_state *mrb, mrb_sym sym);
MRB_API void mrb_iv_name_sym_check(mrb_state *mrb, mrb_sym sym);
MRB_API mrb_value mrb_obj_iv_get(mrb_state *mrb, struct RObject *obj, mrb_sym sym);
MRB_API void mrb_obj_iv_set(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v);
MRB_API mrb_bool mrb_obj_iv_defined(mrb_state *mrb, struct RObject *obj, mrb_sym sym);
MRB_API mrb_value mrb_iv_get(mrb_state *mrb, mrb_value obj, mrb_sym sym);
MRB_API void mrb_iv_set(mrb_state *mrb, mrb_value obj, mrb_sym sym, mrb_value v);
MRB_API mrb_bool mrb_iv_defined(mrb_state*, mrb_value, mrb_sym);
MRB_API mrb_value mrb_iv_remove(mrb_state *mrb, mrb_value obj, mrb_sym sym);
MRB_API void mrb_iv_copy(mrb_state *mrb, mrb_value dst, mrb_value src);
MRB_API mrb_bool mrb_const_defined_at(mrb_state *mrb, mrb_value mod, mrb_sym id);
/**
* Get a global variable. Will return nil if the var does not exist
*
* Example:
*
* !!!ruby
* # Ruby style
* var = $value
*
* !!!c
* // C style
* mrb_sym sym = mrb_intern_lit(mrb, "$value");
* mrb_value var = mrb_gv_get(mrb, sym);
*
* @param mrb The mruby state reference
* @param sym The name of the global variable
* @return The value of that global variable. May be nil
*/
MRB_API mrb_value mrb_gv_get(mrb_state *mrb, mrb_sym sym);
/**
* Set a global variable
*
* Example:
*
* !!!ruby
* # Ruby style
* $value = "foo"
*
* !!!c
* // C style
* mrb_sym sym = mrb_intern_lit(mrb, "$value");
* mrb_gv_set(mrb, sym, mrb_str_new_lit("foo"));
*
* @param mrb The mruby state reference
* @param sym The name of the global variable
* @param val The value of the global variable
*/
MRB_API void mrb_gv_set(mrb_state *mrb, mrb_sym sym, mrb_value val);
/**
* Remove a global variable.
*
* Example:
*
* # Ruby style
* $value = nil
*
* // C style
* mrb_sym sym = mrb_intern_lit(mrb, "$value");
* mrb_gv_remove(mrb, sym);
*
* @param mrb The mruby state reference
* @param sym The name of the global variable
*/
MRB_API void mrb_gv_remove(mrb_state *mrb, mrb_sym sym);
MRB_API mrb_value mrb_cv_get(mrb_state *mrb, mrb_value mod, mrb_sym sym);
MRB_API void mrb_mod_cv_set(mrb_state *mrb, struct RClass * c, mrb_sym sym, mrb_value v);
MRB_API void mrb_cv_set(mrb_state *mrb, mrb_value mod, mrb_sym sym, mrb_value v);
MRB_API mrb_bool mrb_cv_defined(mrb_state *mrb, mrb_value mod, mrb_sym sym);
mrb_value mrb_obj_iv_inspect(mrb_state*, struct RObject*);
void mrb_obj_iv_set_force(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v);
mrb_value mrb_mod_constants(mrb_state *mrb, mrb_value mod);
mrb_value mrb_f_global_variables(mrb_state *mrb, mrb_value self);
mrb_value mrb_obj_instance_variables(mrb_state*, mrb_value);
mrb_value mrb_mod_class_variables(mrb_state*, mrb_value);
mrb_value mrb_mod_cv_get(mrb_state *mrb, struct RClass * c, mrb_sym sym);
mrb_bool mrb_mod_cv_defined(mrb_state *mrb, struct RClass * c, mrb_sym sym);
mrb_bool mrb_ident_p(const char *s, mrb_int len);
/* GC functions */
void mrb_gc_mark_gv(mrb_state*);
void mrb_gc_free_gv(mrb_state*);
void mrb_gc_mark_iv(mrb_state*, struct RObject*);
size_t mrb_gc_mark_iv_size(mrb_state*, struct RObject*);
void mrb_gc_free_iv(mrb_state*, struct RObject*);
/* return non zero to break the loop */
typedef int (mrb_iv_foreach_func)(mrb_state*,mrb_sym,mrb_value,void*);
MRB_API void mrb_iv_foreach(mrb_state *mrb, mrb_value obj, mrb_iv_foreach_func *func, void *p);
MRB_END_DECL
#endif /* MRUBY_VARIABLE_H */
+124
View File
@@ -0,0 +1,124 @@
/**
** @file mruby/version.h - mruby version definition
**
** See Copyright Notice in mruby.h
*/
#ifndef MRUBY_VERSION_H
#define MRUBY_VERSION_H
#include "common.h"
/**
* mruby version definition macros
*/
MRB_BEGIN_DECL
/*
* A passed in expression.
*/
#define MRB_STRINGIZE0(expr) #expr
/*
* Passes in an expression to MRB_STRINGIZE0.
*/
#define MRB_STRINGIZE(expr) MRB_STRINGIZE0(expr)
/*
* The version of Ruby used by mruby.
*/
#define MRUBY_RUBY_VERSION "2.0"
/*
* Ruby engine.
*/
#define MRUBY_RUBY_ENGINE "mruby"
/*
* Major release version number.
*/
#define MRUBY_RELEASE_MAJOR 2
/*
* Minor release version number.
*/
#define MRUBY_RELEASE_MINOR 1
/*
* Tiny release version number.
*/
#define MRUBY_RELEASE_TEENY 2
/*
* The mruby version.
*/
#define MRUBY_VERSION MRB_STRINGIZE(MRUBY_RELEASE_MAJOR) "." MRB_STRINGIZE(MRUBY_RELEASE_MINOR) "." MRB_STRINGIZE(MRUBY_RELEASE_TEENY)
/*
* Release number.
*/
#define MRUBY_RELEASE_NO (MRUBY_RELEASE_MAJOR * 100 * 100 + MRUBY_RELEASE_MINOR * 100 + MRUBY_RELEASE_TEENY)
/*
* Release year.
*/
#define MRUBY_RELEASE_YEAR 2020
/*
* Release month.
*/
#define MRUBY_RELEASE_MONTH 8
/*
* Release day.
*/
#define MRUBY_RELEASE_DAY 6
/*
* Release date as a string.
*/
#define MRUBY_RELEASE_DATE \
MRUBY_RELEASE_YEAR_STR "-" \
MRUBY_RELEASE_MONTH_STR "-" \
MRUBY_RELEASE_DAY_STR
#define MRUBY_RELEASE_YEAR_STR MRB_STRINGIZE(MRUBY_RELEASE_YEAR)
#if MRUBY_RELEASE_MONTH < 10
#define MRUBY_RELEASE_MONTH_STR "0" MRB_STRINGIZE(MRUBY_RELEASE_MONTH)
#else
#define MRUBY_RELEASE_MONTH_STR MRB_STRINGIZE(MRUBY_RELEASE_MONTH)
#endif
#if MRUBY_RELEASE_DAY < 10
#define MRUBY_RELEASE_DAY_STR "0" MRB_STRINGIZE(MRUBY_RELEASE_DAY)
#else
#define MRUBY_RELEASE_DAY_STR MRB_STRINGIZE(MRUBY_RELEASE_DAY)
#endif
/*
* The year mruby was first created.
*/
#define MRUBY_BIRTH_YEAR 2010
/*
* MRuby's authors.
*/
#define MRUBY_AUTHOR "mruby developers"
/*
* mruby's version, and release date.
*/
#define MRUBY_DESCRIPTION \
"mruby " MRUBY_VERSION \
" (" MRUBY_RELEASE_DATE ")" \
/*
* mruby's copyright information.
*/
#define MRUBY_COPYRIGHT \
"mruby - Copyright (c) " \
MRB_STRINGIZE(MRUBY_BIRTH_YEAR)"-" \
MRB_STRINGIZE(MRUBY_RELEASE_YEAR)" " \
MRUBY_AUTHOR \
MRB_END_DECL
#endif /* MRUBY_VERSION_H */