mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
280 lines
9.1 KiB
C
280 lines
9.1 KiB
C
#include "mruby.h"
|
|
#include "mruby/string.h"
|
|
#include "error.h"
|
|
#include "mruby/numeric.h"
|
|
|
|
#ifndef FALSE
|
|
#define FALSE 0
|
|
#endif
|
|
|
|
#ifndef TRUE
|
|
#define TRUE 1
|
|
#endif
|
|
|
|
void
|
|
ruby_xfree(void *x)
|
|
{
|
|
//if (x)
|
|
// vm_xfree(&mrb_objspace, x);
|
|
}
|
|
|
|
struct RData*
|
|
mrb_data_object_alloc(mrb_state *mrb, struct RClass *klass, void *ptr, const struct mrb_data_type *type)
|
|
{
|
|
struct RData *data;
|
|
|
|
data = mrb_obj_alloc(mrb, MRB_TT_DATA, klass);
|
|
data->data = ptr;
|
|
data->type = type;
|
|
|
|
return data;
|
|
}
|
|
|
|
void *
|
|
mrb_check_datatype(mrb_state *mrb, mrb_value obj, const struct mrb_data_type *type)
|
|
{
|
|
static const char mesg[] = "wrong argument type %s (expected %s)";
|
|
|
|
if (SPECIAL_CONST_P(obj) || (mrb_type(obj) != MRB_TT_DATA)) {
|
|
mrb_check_type(mrb, obj, MRB_TT_DATA);
|
|
}
|
|
if (DATA_TYPE(obj) != type) {
|
|
const char *etype = DATA_TYPE(obj)->struct_name;
|
|
mrb_raise(mrb, E_TYPE_ERROR, mesg, etype, type->struct_name);
|
|
}
|
|
return DATA_PTR(obj);
|
|
}
|
|
|
|
mrb_value
|
|
mrb_lastline_get(mrb_state *mrb)
|
|
{
|
|
//mrb_value *var = mrb_svar(0);
|
|
//if (var) {
|
|
// return *var;
|
|
//}
|
|
//return mrb_nil_value();
|
|
mrb_value *argv;
|
|
int argc;
|
|
mrb_get_args(mrb, "*", &argv, &argc);
|
|
if (argc < 1) {
|
|
return mrb_nil_value();
|
|
}
|
|
else
|
|
{
|
|
return argv[0];
|
|
}
|
|
}
|
|
|
|
mrb_value
|
|
mrb_rescue2(mrb_state *mrb, mrb_value (* b_proc) (ANYARGS), mrb_value *data1,
|
|
mrb_value (* r_proc) (ANYARGS), mrb_value *data2, ...)
|
|
{
|
|
mrb_value result = (*b_proc) (mrb, data1);
|
|
return result;
|
|
}
|
|
|
|
mrb_value
|
|
mrb_rescue(mrb_state *mrb, mrb_value (* b_proc)(ANYARGS), mrb_value *data1,
|
|
mrb_value (* r_proc)(ANYARGS), mrb_value *data2)
|
|
{
|
|
return mrb_rescue2(mrb, b_proc, data1, r_proc, data2, mrb->eStandardError_class,
|
|
mrb_fixnum_value(0));
|
|
}
|
|
/* ------------------------------------------------ */
|
|
/*
|
|
* Calls func(obj, arg, recursive), where recursive is non-zero if the
|
|
* current method is called recursively on obj
|
|
*/
|
|
|
|
mrb_value
|
|
mrb_exec_recursive(mrb_state *mrb, mrb_value (*func) (mrb_state *, mrb_value, mrb_value, int), mrb_value obj, void *arg)
|
|
{
|
|
// return mrb_exec_recursive(mrb, io_puts_ary, line, &out);
|
|
return func(mrb, obj, *(mrb_value*)arg, 0);
|
|
}
|
|
|
|
/*
|
|
* Calls func(obj, arg, recursive), where recursive is non-zero if the
|
|
* current method is called recursively on the ordered pair <obj, paired_obj>
|
|
*/
|
|
|
|
mrb_value
|
|
mrb_exec_recursive_paired(mrb_state *mrb, mrb_value (*func) (mrb_state *, mrb_value, mrb_value, int),
|
|
mrb_value obj, mrb_value paired_obj, void* arg)
|
|
{
|
|
// return mrb_exec_recursive_paired(mrb, recursive_eql, hash1, hash2, mrb_fixnum_value((int)&data));
|
|
return func(mrb, obj, paired_obj, 0);
|
|
}
|
|
|
|
mrb_sym
|
|
mrb_to_id(mrb_state *mrb, mrb_value name)
|
|
{
|
|
mrb_value tmp;
|
|
mrb_sym id;
|
|
|
|
switch (mrb_type(name)) {
|
|
default:
|
|
tmp = mrb_check_string_type(mrb, name);
|
|
if (mrb_nil_p(tmp)) {
|
|
tmp = mrb_inspect(mrb, name);
|
|
mrb_raise(mrb, E_TYPE_ERROR, "%s is not a symbol",
|
|
RSTRING_PTR(tmp));
|
|
}
|
|
name = tmp;
|
|
/* fall through */
|
|
case MRB_TT_STRING:
|
|
name = mrb_str_intern(mrb, name);
|
|
/* fall through */
|
|
case MRB_TT_SYMBOL:
|
|
return SYM2ID(name);
|
|
}
|
|
return id;
|
|
}
|
|
|
|
/*
|
|
* call-seq:
|
|
* proc { |...| block } -> a_proc
|
|
*
|
|
* Equivalent to <code>Proc.new</code>.
|
|
*/
|
|
|
|
mrb_value
|
|
mrb_block_proc(void)
|
|
{
|
|
return mrb_nil_value();//proc_new(mrb_cProc, FALSE);
|
|
}
|
|
|
|
/*
|
|
* Document-method: __id__
|
|
* Document-method: object_id
|
|
*
|
|
* call-seq:
|
|
* obj.__id__ -> fixnum
|
|
* obj.object_id -> fixnum
|
|
*
|
|
* Returns an integer identifier for <i>obj</i>. The same number will
|
|
* be returned on all calls to <code>id</code> for a given object, and
|
|
* no two active objects will share an id.
|
|
* <code>Object#object_id</code> is a different concept from the
|
|
* <code>:name</code> notation, which returns the symbol id of
|
|
* <code>name</code>. Replaces the deprecated <code>Object#id</code>.
|
|
*/
|
|
|
|
/*
|
|
* call-seq:
|
|
* obj.hash -> fixnum
|
|
*
|
|
* Generates a <code>Fixnum</code> hash value for this object. This
|
|
* function must have the property that <code>a.eql?(b)</code> implies
|
|
* <code>a.hash == b.hash</code>. The hash value is used by class
|
|
* <code>Hash</code>. Any hash value that exceeds the capacity of a
|
|
* <code>Fixnum</code> will be truncated before being used.
|
|
*/
|
|
|
|
int
|
|
mrb_obj_id(mrb_value obj)
|
|
{
|
|
/*
|
|
* 32-bit mrb_value space
|
|
* MSB ------------------------ LSB
|
|
* false 00000000000000000000000000000000
|
|
* true 00000000000000000000000000000010
|
|
* nil 00000000000000000000000000000100
|
|
* undef 00000000000000000000000000000110
|
|
* symbol ssssssssssssssssssssssss00001110
|
|
* object oooooooooooooooooooooooooooooo00 = 0 (mod sizeof(RVALUE))
|
|
* fixnum fffffffffffffffffffffffffffffff1
|
|
*
|
|
* object_id space
|
|
* LSB
|
|
* false 00000000000000000000000000000000
|
|
* true 00000000000000000000000000000010
|
|
* nil 00000000000000000000000000000100
|
|
* undef 00000000000000000000000000000110
|
|
* symbol 000SSSSSSSSSSSSSSSSSSSSSSSSSSS0 S...S % A = 4 (S...S = s...s * A + 4)
|
|
* object oooooooooooooooooooooooooooooo0 o...o % A = 0
|
|
* fixnum fffffffffffffffffffffffffffffff1 bignum if required
|
|
*
|
|
* where A = sizeof(RVALUE)/4
|
|
*
|
|
* sizeof(RVALUE) is
|
|
* 20 if 32-bit, double is 4-byte aligned
|
|
* 24 if 32-bit, double is 8-byte aligned
|
|
* 40 if 64-bit
|
|
*/
|
|
/*
|
|
* 128-bit mrb_value space
|
|
* MSB -------- LSB
|
|
* x86 [0,1] [2,3] [4,5] [6,7] [8,9] [A,B] [C,D] [E,F]
|
|
* 7 6 5 4 3 2 1 0
|
|
* 0123456789ABCDEF 0123456789ABCDEF 0123456789ABCDEF 0123456789ABCDEF 0123456789ABCDEF 0123456789ABCDEF 0123456789ABCDEF 0123456789ABCDEF
|
|
* FEDCBA9876543210 FEDCBA9876543210 FEDCBA9876543210 FEDCBA9876543210 FEDCBA9876543210 FEDCBA9876543210 FEDCBA9876543210 FEDCBA9876543210
|
|
* false 0000000000000000 0000000000000000 xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxx00000001 xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx
|
|
* true 0000000000000001 0000000000000000 xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxx00000010 xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx
|
|
* nil 0000000000000001 0000000000000000 xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxx00000001 xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx
|
|
* undef 0000000000000000 0000000000000000 xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxx00000101 xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx
|
|
* symbol ssssssssssssssss ssssssssssssssss xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxx00000100 xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx
|
|
* object oooooooooooooooo oooooooooooooo00 = 0 (mod sizeof(RVALUE))
|
|
(1)fixnum 0000000000000001 0000000000000000 xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxx00000011 xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx
|
|
* float 0000000000000001 0000000000000000 0000000000000000 0000000000000000 xxxxxxxx00000011 xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx
|
|
* <-- mrb_float --> xxxxxxxx00001101 xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx
|
|
*
|
|
* object_id space
|
|
* LSB
|
|
* false 0000000000000000 0000000000000000
|
|
* true 0000000000000000 0000000000000010
|
|
* nil 0000000000000000 0000000000000100
|
|
* undef 0000000000000000 0000000000000110
|
|
* symbol 000SSSSSSSSSSSS SSSSSSSSSSSSSSS0 S...S % A = 4 (S...S = s...s * A + 4)
|
|
* object ooooooooooooooo ooooooooooooooo0 o...o % A = 0
|
|
* fixnum ffffffffffffffff fffffffffffffff1 bignum if required
|
|
*
|
|
* where A = sizeof(RVALUE)/4
|
|
*
|
|
* sizeof(RVALUE) is
|
|
* 20 if 32-bit, double is 4-byte aligned
|
|
* 24 if 32-bit, double is 8-byte aligned
|
|
* 40 if 64-bit
|
|
*/
|
|
/* tt:0_27 */
|
|
switch (mrb_type(obj)) {
|
|
case MRB_TT_FREE:
|
|
return 0; /* not define */
|
|
case MRB_TT_FALSE:
|
|
if (mrb_nil_p(obj))
|
|
return 4;
|
|
return 0;
|
|
case MRB_TT_TRUE:
|
|
return 2;
|
|
case MRB_TT_FIXNUM:
|
|
return mrb_fixnum(obj)*2+1; /* odd number */
|
|
case MRB_TT_SYMBOL:
|
|
return SYM2ID(obj) * 2;
|
|
case MRB_TT_UNDEF:
|
|
return 0; /* not define */
|
|
case MRB_TT_FLOAT:
|
|
return (int)mrb_float(obj)*2; /* even number */
|
|
case MRB_TT_OBJECT:
|
|
case MRB_TT_CLASS:
|
|
case MRB_TT_MODULE:
|
|
case MRB_TT_ICLASS:
|
|
case MRB_TT_SCLASS:
|
|
case MRB_TT_PROC:
|
|
case MRB_TT_ARRAY:
|
|
case MRB_TT_HASH:
|
|
case MRB_TT_STRING:
|
|
case MRB_TT_RANGE:
|
|
case MRB_TT_REGEX:
|
|
case MRB_TT_STRUCT:
|
|
case MRB_TT_EXCEPTION:
|
|
case MRB_TT_MATCH:
|
|
case MRB_TT_FILE:
|
|
case MRB_TT_DATA:
|
|
case MRB_TT_THREAD:
|
|
case MRB_TT_THREADGRP:
|
|
default:
|
|
return mrb_fixnum(obj); /* even number */
|
|
}
|
|
}
|
|
|