first commit
This commit is contained in:
+215
@@ -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 */
|
||||
+1403
File diff suppressed because it is too large
Load Diff
+300
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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
@@ -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 */
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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 */
|
||||
@@ -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
@@ -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
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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 */
|
||||
Reference in New Issue
Block a user