Commit 8d2880bb authored by Yukihiro Matz Matsumoto's avatar Yukihiro Matz Matsumoto

Merge branch 'pluggable_struct' of https://github.com/mattn/mruby into mattn-pluggable_struct

parents c0e1fc93 99a6de06
......@@ -17,6 +17,9 @@ MRuby::Build.new do |conf|
# Use standard Time class
conf.gem 'mrbgems/mruby-time'
# Use standard Struct class
conf.gem 'mrbgems/mruby-struct'
# Generate binaries
# conf.bins = %w(mrbc mruby mirb)
......
......@@ -45,7 +45,6 @@
/* -DDISABLE_XXXX to drop following features */
//#define DISABLE_SPRINTF /* Kernel.sprintf method */
//#define DISABLE_STRUCT /* Struct class */
//#define DISABLE_STDIO /* use of stdio */
/* -DENABLE_XXXX to enable following features */
......@@ -84,9 +83,6 @@ typedef short mrb_sym;
#ifndef DISABLE_SPRINTF
#define ENABLE_SPRINTF
#endif
#ifndef DISABLE_STRUCT
#define ENABLE_STRUCT
#endif
#ifndef DISABLE_STDIO
#define ENABLE_STDIO
#endif
......
/*
** mruby/struct.h - Struct class
**
** See Copyright Notice in mruby.h
*/
#ifndef MRUBY_STRUCT_H
#define MRUBY_STRUCT_H
#if defined(__cplusplus)
extern "C" {
#endif
struct RStruct {
struct RBasic basic;
long len;
mrb_value *ptr;
};
#define RSTRUCT(st) ((struct RStruct*)((st).value.p))
#define RSTRUCT_LEN(st) ((int)(RSTRUCT(st)->len))
#define RSTRUCT_PTR(st) (RSTRUCT(st)->ptr)
#if defined(__cplusplus)
} /* extern "C" { */
#endif
#endif /* MRUBY_STRUCT_H */
......@@ -29,12 +29,11 @@ enum mrb_vtype {
MRB_TT_HASH, /* 16 */
MRB_TT_STRING, /* 17 */
MRB_TT_RANGE, /* 18 */
MRB_TT_STRUCT, /* 19 */
MRB_TT_EXCEPTION, /* 20 */
MRB_TT_FILE, /* 21 */
MRB_TT_ENV, /* 22 */
MRB_TT_DATA, /* 23 */
MRB_TT_MAXDEFINE /* 24 */
MRB_TT_EXCEPTION, /* 19 */
MRB_TT_FILE, /* 20 */
MRB_TT_ENV, /* 21 */
MRB_TT_DATA, /* 22 */
MRB_TT_MAXDEFINE /* 23 */
};
typedef struct mrb_value {
......@@ -89,12 +88,11 @@ enum mrb_vtype {
MRB_TT_HASH, /* 17 */
MRB_TT_STRING, /* 18 */
MRB_TT_RANGE, /* 19 */
MRB_TT_STRUCT, /* 20 */
MRB_TT_EXCEPTION, /* 21 */
MRB_TT_FILE, /* 22 */
MRB_TT_ENV, /* 23 */
MRB_TT_DATA, /* 24 */
MRB_TT_MAXDEFINE /* 25 */
MRB_TT_EXCEPTION, /* 20 */
MRB_TT_FILE, /* 21 */
MRB_TT_ENV, /* 22 */
MRB_TT_DATA, /* 23 */
MRB_TT_MAXDEFINE /* 24 */
};
#ifdef MRB_ENDIAN_BIG
......
MRuby::Gem::Specification.new('mruby-struct') do |spec|
spec.license = 'MIT'
spec.authors = 'mruby developers'
end
......@@ -4,18 +4,31 @@
** See Copyright Notice in mruby.h
*/
#include "mruby.h"
#ifdef ENABLE_STRUCT
#include <string.h>
#include "error.h"
#include "mruby/struct.h"
#include "mruby/array.h"
#include <stdarg.h>
#include "mruby.h"
#include "mruby/array.h"
#include "mruby/string.h"
#include "mruby/class.h"
#include "mruby/data.h"
#include "mruby/variable.h"
struct RStruct {
struct RBasic basic;
mrb_value values;
};
static void
rstruct_free(mrb_state *mrb, void *ptr)
{
mrb_free(mrb, ptr);
}
static struct mrb_data_type mrb_struct_type = { "mrb_struct", rstruct_free };
#define RSTRUCT(st) ((struct RStruct*)(DATA_PTR(st)))
#define RSTRUCT_LEN(st) ((int)(RARRAY_LEN(RSTRUCT(st)->values)))
#define RSTRUCT_PTR(st) (RARRAY_PTR(RSTRUCT(st)->values))
static struct RClass *
struct_class(mrb_state *mrb)
......@@ -64,7 +77,7 @@ mrb_value
mrb_struct_members(mrb_state *mrb, mrb_value s)
{
mrb_value members = mrb_struct_s_members(mrb, mrb_obj_value(mrb_obj_class(mrb, s)));
if (mrb_type(s) == MRB_TT_STRUCT) {
if (!strcmp(mrb_class_name(mrb, mrb_obj_class(mrb, s)), "Struct")) {
if (RSTRUCT_LEN(s) != RARRAY_LEN(members)) {
mrb_raisef(mrb, E_TYPE_ERROR, "struct size differs (%ld required %ld given)",
RARRAY_LEN(members), RSTRUCT_LEN(s));
......@@ -135,7 +148,7 @@ mrb_struct_getmember(mrb_state *mrb, mrb_value obj, mrb_sym id)
return ptr[i];
}
}
mrb_name_error(mrb, id, "%s is not struct member", mrb_sym2name(mrb, id));
mrb_raisef(mrb, E_NAME_ERROR, "%s is not struct member", mrb_sym2name(mrb, id));
return mrb_nil_value(); /* not reached */
}
......@@ -214,7 +227,7 @@ mrb_struct_set(mrb_state *mrb, mrb_value obj, mrb_value val)
}
}
mrb_name_error(mrb, mid, "`%s' is not a struct member",
mrb_raisef(mrb, E_NAME_ERROR, "`%s' is not a struct member",
mrb_sym2name(mrb, mid));
return mrb_nil_value(); /* not reached */
}
......@@ -259,7 +272,7 @@ make_struct(mrb_state *mrb, mrb_value name, mrb_value members, struct RClass * k
name = mrb_str_to_str(mrb, name);
id = mrb_to_id(mrb, name);
if (!mrb_is_const_id(id)) {
mrb_name_error(mrb, id, "identifier %s needs to be constant", mrb_string_value_ptr(mrb, name));
mrb_raisef(mrb, E_NAME_ERROR, "identifier %s needs to be constant", mrb_string_value_ptr(mrb, name));
}
if (mrb_const_defined_at(mrb, klass, id)) {
mrb_warn("redefining constant Struct::%s", mrb_string_value_ptr(mrb, name));
......@@ -267,7 +280,7 @@ make_struct(mrb_state *mrb, mrb_value name, mrb_value members, struct RClass * k
}
c = mrb_define_class_under(mrb, klass, RSTRING_PTR(name), klass);
}
MRB_SET_INSTANCE_TT(c, MRB_TT_STRUCT);
//MRB_SET_INSTANCE_TT(c, MRB_TT_DATA);
nstr = mrb_obj_value(c);
mrb_iv_set(mrb, nstr, mrb_intern(mrb, "__members__"), members);
......@@ -418,17 +431,22 @@ static mrb_value
mrb_struct_initialize_withArg(mrb_state *mrb, int argc, mrb_value *argv, mrb_value self)
{
struct RClass *klass = mrb_obj_class(mrb, self);
int n;
int i, n;
struct RStruct *st;
n = num_members(mrb, klass);
if (n < argc) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "struct size differs");
}
st = RSTRUCT(self);
st->ptr = (mrb_value *)mrb_calloc(mrb, sizeof(mrb_value), n);
st->len = n;
struct_copy(st->ptr, argv, argc);
st = (struct RStruct *) mrb_malloc(mrb, sizeof(struct RStruct));
DATA_PTR(self) = st;
DATA_TYPE(self) = &mrb_struct_type;
st->values = mrb_ary_new_capa(mrb, n);
for (i = argc; i < n; i++) {
mrb_ary_set(mrb, st->values, i, mrb_nil_value());
}
struct_copy(RARRAY_PTR(st->values), argv, argc);
mrb_iv_set(mrb, self, mrb_intern(mrb, "__values__"), st->values);
return self;
}
......@@ -547,7 +565,7 @@ mrb_struct_aref_id(mrb_state *mrb, mrb_value s, mrb_sym id)
return ptr[i];
}
}
mrb_name_error(mrb, id, "no member '%s' in struct", mrb_sym2name(mrb, id));
mrb_raisef(mrb, E_NAME_ERROR, "no member '%s' in struct", mrb_sym2name(mrb, id));
return mrb_nil_value(); /* not reached */
}
......@@ -619,7 +637,7 @@ mrb_struct_aset_id(mrb_state *mrb, mrb_value s, mrb_sym id, mrb_value val)
return val;
}
}
mrb_name_error(mrb, id, "no member '%s' in struct", mrb_sym2name(mrb, id));
mrb_raisef(mrb, E_NAME_ERROR, "no member '%s' in struct", mrb_sym2name(mrb, id));
return val; /* not reach */
}
......@@ -698,7 +716,7 @@ mrb_struct_equal(mrb_state *mrb, mrb_value s)
mrb_get_args(mrb, "o", &s2);
if (mrb_obj_equal(mrb, s, s2)) return mrb_true_value();
if (mrb_type(s2) != MRB_TT_STRUCT) return mrb_false_value();
if (!strcmp(mrb_class_name(mrb, mrb_obj_class(mrb, s)), "Struct")) return mrb_false_value();
if (mrb_obj_class(mrb, s) != mrb_obj_class(mrb, s2)) return mrb_false_value();
if (RSTRUCT_LEN(s) != RSTRUCT_LEN(s2)) {
mrb_bug("inconsistent struct"); /* should never happen */
......@@ -729,7 +747,7 @@ mrb_struct_eql(mrb_state *mrb, mrb_value s)
mrb_get_args(mrb, "o", &s2);
if (mrb_obj_equal(mrb, s, s2)) return mrb_true_value();
if (mrb_type(s2) != MRB_TT_STRUCT) return mrb_false_value();
if (strcmp(mrb_class_name(mrb, mrb_obj_class(mrb, s2)), "Struct")) return mrb_false_value();
if (mrb_obj_class(mrb, s) != mrb_obj_class(mrb, s2)) return mrb_false_value();
if (RSTRUCT_LEN(s) != RSTRUCT_LEN(s2)) {
mrb_bug("inconsistent struct"); /* should never happen */
......@@ -760,7 +778,7 @@ mrb_struct_eql(mrb_state *mrb, mrb_value s)
* <code>Symbol</code> (such as <code>:name</code>).
*/
void
mrb_init_struct(mrb_state *mrb)
mrb_mruby_struct_gem_init(mrb_state* mrb)
{
struct RClass *st;
st = mrb_define_class(mrb, "Struct", mrb->object_class);
......@@ -778,4 +796,8 @@ mrb_init_struct(mrb_state *mrb)
mrb_define_method(mrb, st, "eql?", mrb_struct_eql, ARGS_REQ(1)); /* 15.2.18.4.12(x) */
}
#endif /* ENABLE_STRUCT */
void
mrb_mruby_struct_gem_final(mrb_state* mrb)
{
}
......@@ -170,7 +170,6 @@ mrb_obj_id(mrb_value obj)
case MRB_TT_ARRAY:
case MRB_TT_HASH:
case MRB_TT_RANGE:
case MRB_TT_STRUCT:
case MRB_TT_EXCEPTION:
case MRB_TT_FILE:
case MRB_TT_DATA:
......
......@@ -11,7 +11,6 @@
#include "mruby/hash.h"
#include "mruby/range.h"
#include <string.h>
#include "mruby/struct.h"
#include "mruby/proc.h"
#include "mruby/data.h"
#include "mruby/variable.h"
......@@ -86,9 +85,6 @@ typedef struct {
struct RArray array;
struct RHash hash;
struct RRange range;
#ifdef ENABLE_STRUCT
struct RStruct strct;
#endif
struct RData data;
struct RProc proc;
} as;
......@@ -455,18 +451,6 @@ gc_mark_children(mrb_state *mrb, struct RBasic *obj)
}
break;
#ifdef ENABLE_STRUCT
case MRB_TT_STRUCT:
{
struct RStruct *s = (struct RStruct*)obj;
long i;
for (i=0; i<s->len; i++){
mrb_gc_mark_value(mrb, s->ptr[i]);
}
}
break;
#endif
default:
break;
}
......@@ -539,12 +523,6 @@ obj_free(mrb_state *mrb, struct RBasic *obj)
mrb_free(mrb, ((struct RRange*)obj)->edges);
break;
#ifdef ENABLE_STRUCT
case MRB_TT_STRUCT:
mrb_free(mrb, ((struct RStruct*)obj)->ptr);
break;
#endif
case MRB_TT_DATA:
{
struct RData *d = (struct RData*)obj;
......@@ -664,15 +642,6 @@ gc_gray_mark(mrb_state *mrb, struct RBasic *obj)
children+=2;
break;
#ifdef ENABLE_STRUCT
case MRB_TT_STRUCT:
{
struct RStruct *s = (struct RStruct*)obj;
children += s->len;
}
break;
#endif
default:
break;
}
......
......@@ -20,7 +20,6 @@ void mrb_init_array(mrb_state*);
void mrb_init_hash(mrb_state*);
void mrb_init_numeric(mrb_state*);
void mrb_init_range(mrb_state*);
void mrb_init_struct(mrb_state*);
void mrb_init_gc(mrb_state*);
void mrb_init_print(mrb_state*);
void mrb_init_math(mrb_state*);
......@@ -48,9 +47,6 @@ mrb_init_core(mrb_state *mrb)
mrb_init_hash(mrb); DONE;
mrb_init_numeric(mrb); DONE;
mrb_init_range(mrb); DONE;
#ifdef ENABLE_STRUCT
mrb_init_struct(mrb); DONE;
#endif
mrb_init_gc(mrb); DONE;
#ifdef ENABLE_STDIO
mrb_init_print(mrb); DONE;
......
......@@ -379,7 +379,6 @@ static const struct types {
{MRB_TT_HASH, "Hash"},
{MRB_TT_STRING, "String"},
{MRB_TT_RANGE, "Range"},
{MRB_TT_STRUCT, "Struct"},
// {MRB_TT_BIGNUM, "Bignum"},
{MRB_TT_FILE, "File"},
{MRB_TT_DATA, "Data"}, /* internal use: wrapped C pointers */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment