Updated Xcode project build settings in conformity with 10.8/Xcode 4.4

This commit is contained in:
Paolo Bosetti
2012-08-06 15:02:03 +02:00
113 changed files with 5868 additions and 3555 deletions
+3
View File
@@ -6,3 +6,6 @@ Original Authors "mruby developers" are:
Daniel Bovensiepen
Jon Maken
Bjorn De Meyer
Yuichiro MASUI
Masamitsu MURASE
Masaki Muranaka
+5 -4
View File
@@ -33,12 +33,13 @@ project(mruby C)
# TODO stop polluting source tree with CMakeFiles/ and CMakeCache.txt
# on build location check failure
# Make sure we are not trying to generate in in-tree build unless building
# with a MSVC IDE where it's OK.
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR AND NOT MSVC_IDE)
# with an MSVC or Xcode IDE where it's OK.
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR AND NOT (MSVC_IDE OR XCODE))
message(FATAL_ERROR
"\nIn-source builds are not allowed as CMake would overwrite the "
"Makefiles distributed with mruby. Please change to the 'build' "
"subdirectory and run CMake from there.")
"Makefiles distributed with mruby. Delete any created 'CMakeFiles' "
"subdirectory and 'CMakeCache.txt' file from the current directory, "
"change to the 'build' subdirectory, and re-run CMake from there.")
endif()
if(COMMAND cmake_policy)
+12 -5
View File
@@ -7,12 +7,19 @@ export LL = gcc
export AR = ar
export YACC = bison
DEBUG_MODE = 1
ifeq ($(DEBUG_MODE),1)
CFLAGS = -g -O3
else
CFLAGS = -O3
ifeq ($(strip $(COMPILE_MODE)),)
# default compile option
COMPILE_MODE = debug
endif
ifeq ($(COMPILE_MODE),debug)
CFLAGS = -g -O3
else ifeq ($(COMPILE_MODE),release)
CFLAGS = -O3
else ifeq ($(COMPILE_MODE),small)
CFLAGS = -Os
endif
ALL_CFLAGS = -Wall -Werror-implicit-function-declaration $(CFLAGS)
ifeq ($(OS),Windows_NT)
MAKE_FLAGS = --no-print-directory CC=$(CC) LL=$(LL) ALL_CFLAGS='$(ALL_CFLAGS)'
+315
View File
@@ -0,0 +1,315 @@
# AO render benchmark
# Original program (C) Syoyo Fujita in Javascript (and other languages)
# http://lucille.atso-net.jp/blog/?p=642
# http://lucille.atso-net.jp/blog/?p=711
# Ruby(yarv2llvm) version by Hideki Miura
# mruby version by Hideki Miura
#
IMAGE_WIDTH = 256
IMAGE_HEIGHT = 256
NSUBSAMPLES = 2
NAO_SAMPLES = 8
module Rand
# Use xorshift
@@x = 123456789
@@y = 362436069
@@z = 521288629
@@w = 88675123
BNUM = 1 << 29
BNUMF = BNUM.to_f
def self.rand
x = @@x
t = x ^ ((x & 0xfffff) << 11)
w = @@w
@@x, @@y, @@z = @@y, @@z, w
w = @@w = (w ^ (w >> 19) ^ (t ^ (t >> 8)))
(w % BNUM) / BNUMF
end
end
class Vec
def initialize(x, y, z)
@x = x
@y = y
@z = z
end
def x=(v); @x = v; end
def y=(v); @y = v; end
def z=(v); @z = v; end
def x; @x; end
def y; @y; end
def z; @z; end
def vadd(b)
Vec.new(@x + b.x, @y + b.y, @z + b.z)
end
def vsub(b)
Vec.new(@x - b.x, @y - b.y, @z - b.z)
end
def vcross(b)
Vec.new(@y * b.z - @z * b.y,
@z * b.x - @x * b.z,
@x * b.y - @y * b.x)
end
def vdot(b)
r = @x * b.x + @y * b.y + @z * b.z
r
end
def vlength
Math.sqrt(@x * @x + @y * @y + @z * @z)
end
def vnormalize
len = vlength
v = Vec.new(@x, @y, @z)
if len > 1.0e-17 then
v.x = v.x / len
v.y = v.y / len
v.z = v.z / len
end
v
end
end
class Sphere
def initialize(center, radius)
@center = center
@radius = radius
end
def center; @center; end
def radius; @radius; end
def intersect(ray, isect)
rs = ray.org.vsub(@center)
b = rs.vdot(ray.dir)
c = rs.vdot(rs) - (@radius * @radius)
d = b * b - c
if d > 0.0 then
t = - b - Math.sqrt(d)
if t > 0.0 and t < isect.t then
isect.t = t
isect.hit = true
isect.pl = Vec.new(ray.org.x + ray.dir.x * t,
ray.org.y + ray.dir.y * t,
ray.org.z + ray.dir.z * t)
n = isect.pl.vsub(@center)
isect.n = n.vnormalize
end
end
end
end
class Plane
def initialize(p, n)
@p = p
@n = n
end
def intersect(ray, isect)
d = -@p.vdot(@n)
v = ray.dir.vdot(@n)
v0 = v
if v < 0.0 then
v0 = -v
end
if v0 < 1.0e-17 then
return
end
t = -(ray.org.vdot(@n) + d) / v
if t > 0.0 and t < isect.t then
isect.hit = true
isect.t = t
isect.n = @n
isect.pl = Vec.new(ray.org.x + t * ray.dir.x,
ray.org.y + t * ray.dir.y,
ray.org.z + t * ray.dir.z)
end
end
end
class Ray
def initialize(org, dir)
@org = org
@dir = dir
end
def org; @org; end
def org=(v); @org = v; end
def dir; @dir; end
def dir=(v); @dir = v; end
end
class Isect
def initialize
@t = 10000000.0
@hit = false
@pl = Vec.new(0.0, 0.0, 0.0)
@n = Vec.new(0.0, 0.0, 0.0)
end
def t; @t; end
def t=(v); @t = v; end
def hit; @hit; end
def hit=(v); @hit = v; end
def pl; @pl; end
def pl=(v); @pl = v; end
def n; @n; end
def n=(v); @n = v; end
end
def clamp(f)
i = f * 255.5
if i > 255.0 then
i = 255.0
end
if i < 0.0 then
i = 0.0
end
i.to_i
end
def otherBasis(basis, n)
basis[2] = Vec.new(n.x, n.y, n.z)
basis[1] = Vec.new(0.0, 0.0, 0.0)
if n.x < 0.6 and n.x > -0.6 then
basis[1].x = 1.0
elsif n.y < 0.6 and n.y > -0.6 then
basis[1].y = 1.0
elsif n.z < 0.6 and n.z > -0.6 then
basis[1].z = 1.0
else
basis[1].x = 1.0
end
basis[0] = basis[1].vcross(basis[2])
basis[0] = basis[0].vnormalize
basis[1] = basis[2].vcross(basis[0])
basis[1] = basis[1].vnormalize
end
class Scene
def initialize
@spheres = Array.new
@spheres[0] = Sphere.new(Vec.new(-2.0, 0.0, -3.5), 0.5)
@spheres[1] = Sphere.new(Vec.new(-0.5, 0.0, -3.0), 0.5)
@spheres[2] = Sphere.new(Vec.new(1.0, 0.0, -2.2), 0.5)
@plane = Plane.new(Vec.new(0.0, -0.5, 0.0), Vec.new(0.0, 1.0, 0.0))
end
def ambient_occlusion(isect)
basis = Array.new(3)
otherBasis(basis, isect.n)
ntheta = NAO_SAMPLES
nphi = NAO_SAMPLES
eps = 0.0001
occlusion = 0.0
p0 = Vec.new(isect.pl.x + eps * isect.n.x,
isect.pl.y + eps * isect.n.y,
isect.pl.z + eps * isect.n.z)
nphi.times do |j|
ntheta.times do |i|
r = Rand::rand
phi = 2.0 * 3.14159265 * Rand::rand
x = Math.cos(phi) * Math.sqrt(1.0 - r)
y = Math.sin(phi) * Math.sqrt(1.0 - r)
z = Math.sqrt(r)
rx = x * basis[0].x + y * basis[1].x + z * basis[2].x
ry = x * basis[0].y + y * basis[1].y + z * basis[2].y
rz = x * basis[0].z + y * basis[1].z + z * basis[2].z
raydir = Vec.new(rx, ry, rz)
ray = Ray.new(p0, raydir)
occisect = Isect.new
@spheres[0].intersect(ray, occisect)
@spheres[1].intersect(ray, occisect)
@spheres[2].intersect(ray, occisect)
@plane.intersect(ray, occisect)
if occisect.hit then
occlusion = occlusion + 1.0
else
0.0
end
end
end
occlusion = (ntheta.to_f * nphi.to_f - occlusion) / (ntheta.to_f * nphi.to_f)
Vec.new(occlusion, occlusion, occlusion)
end
def render(w, h, nsubsamples)
cnt = 0
nsf = nsubsamples.to_f
h.times do |y|
w.times do |x|
rad = Vec.new(0.0, 0.0, 0.0)
# Subsmpling
nsubsamples.times do |v|
nsubsamples.times do |u|
cnt = cnt + 1
wf = w.to_f
hf = h.to_f
xf = x.to_f
yf = y.to_f
uf = u.to_f
vf = v.to_f
px = (xf + (uf / nsf) - (wf / 2.0)) / (wf / 2.0)
py = -(yf + (vf / nsf) - (hf / 2.0)) / (hf / 2.0)
eye = Vec.new(px, py, -1.0).vnormalize
ray = Ray.new(Vec.new(0.0, 0.0, 0.0), eye)
isect = Isect.new
@spheres[0].intersect(ray, isect)
@spheres[1].intersect(ray, isect)
@spheres[2].intersect(ray, isect)
@plane.intersect(ray, isect)
if isect.hit then
col = ambient_occlusion(isect)
rad.x = rad.x + col.x
rad.y = rad.y + col.y
rad.z = rad.z + col.z
else
0.0
end
end
end
r = rad.x / (nsf * nsf)
g = rad.y / (nsf * nsf)
b = rad.z / (nsf * nsf)
printf("%c", clamp(r))
printf("%c", clamp(g))
printf("%c", clamp(b))
end
end
end
end
# File.open("ao.ppm", "w") do |fp|
printf("P6\n")
printf("%d %d\n", IMAGE_WIDTH, IMAGE_HEIGHT)
printf("255\n", IMAGE_WIDTH, IMAGE_HEIGHT)
Scene.new.render(IMAGE_WIDTH, IMAGE_HEIGHT, NSUBSAMPLES)
# Scene.new.render(256, 256, 2)
# end
+47
View File
@@ -0,0 +1,47 @@
#from http://www.bagley.org/~doug/shootout/bench/lists/lists.ruby
NUM = 300
SIZE = 10000
def test_lists()
# create a list of integers (Li1) from 1 to SIZE
li1 = (1..SIZE).to_a
# copy the list to li2 (not by individual items)
li2 = li1.dup
# remove each individual item from left side of li2 and
# append to right side of li3 (preserving order)
li3 = Array.new
while (not li2.empty?)
li3.push(li2.shift)
end
# li2 must now be empty
# remove each individual item from right side of li3 and
# append to right side of li2 (reversing list)
while (not li3.empty?)
li2.push(li3.pop)
end
# li3 must now be empty
# reverse li1 in place
li1.reverse!
# check that first item is now SIZE
if li1[0] != SIZE then
p "not SIZE"
0
else
# compare li1 and li2 for equality
if li1 != li2 then
return(0)
else
# return the length of the list
li1.length
end
end
end
i = 0
while i<NUM
i+=1
result = test_lists()
end
result
+13
View File
@@ -0,0 +1,13 @@
# Toolchain file for building with OpenWRT Toolchain for ANY OpenWRT Target.
# Following prequisition are necessary:
# - latest cmake version
# - mruby OpenWRT Package file (not yet in distribution)
# Switch to Cross Compile by setting the system name
SET(CMAKE_SYSTEM_NAME Linux)
# We show CMAKE the compiler, the rest will be guessed by the Toolchain
SET(CMAKE_C_COMPILER "$ENV{OPENWRT_TOOLCHAIN}/bin/$ENV{OPENWRT_TARGETCC}")
# We define an own release flag so that we can adapt the optimal C_FLAGS
SET(CMAKE_C_FLAGS_OPENWRT "$ENV{OPENWRT_TARGETFLAGS}")
@@ -0,0 +1,29 @@
# Sample toolchain file for building for ARM from an Ubuntu Linux system.
#
# Typical usage:
# 1) install cross compiler: `sudo apt-get install gcc-arm-linux-gnueabi`
# 2) cp cmake/Toolchain-Ubuntu-gnueabi.cmake.sample ~/Toolchain-Ubuntu-gnueabi.cmake
# 3) tweak toolchain values as needed
# 4) cd build
# 5) cmake -DCMAKE_TOOLCHAIN_FILE=~/Toolchain-Ubuntu-gnueabi.cmake ..
# name of the target OS on which the built artifacts will run and the
# toolchain prefix. if target is an embedded system without an OS, set
# CMAKE_SYSTEM_NAME to `Generic`
set(CMAKE_SYSTEM_NAME Linux)
set(TOOLCHAIN_PREFIX arm-linux-gnueabi)
# cross compilers to use for C
set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc)
# target environment on the build host system
# set 1st to dir with the cross compiler's C/C++ headers/libs
# set 2nd to dir containing personal cross development headers/libs
set(CMAKE_FIND_ROOT_PATH /usr/${TOOLCHAIN_PREFIX} ~/crossdev/eabi)
# modify default behavior of FIND_XXX() commands to
# search for headers/libs in the target environment and
# search for programs in the build host environment
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
@@ -0,0 +1,29 @@
# Sample toolchain file for building for ARM (w/hw float support) from an Ubuntu Linux system.
#
# Typical usage:
# 1) install cross compiler: `sudo apt-get install gcc-arm-linux-gnueabihf`
# 2) cp cmake/Toolchain-Ubuntu-gnueabihf.cmake.sample ~/Toolchain-Ubuntu-gnueabihf.cmake
# 3) tweak toolchain values as needed
# 4) cd build
# 5) cmake -DCMAKE_TOOLCHAIN_FILE=~/Toolchain-Ubuntu-gnueabihf.cmake ..
# name of the target OS on which the built artifacts will run and the
# toolchain prefix. if target is an embedded system without an OS, set
# CMAKE_SYSTEM_NAME to `Generic`
set(CMAKE_SYSTEM_NAME Linux)
set(TOOLCHAIN_PREFIX arm-linux-gnueabihf)
# cross compilers to use for C
set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc)
# target environment on the build host system
# set 1st to dir with the cross compiler's C/C++ headers/libs
# set 2nd to dir containing personal cross development headers/libs
set(CMAKE_FIND_ROOT_PATH /usr/${TOOLCHAIN_PREFIX} ~/crossdev/eabihf)
# modify default behavior of FIND_XXX() commands to
# search for headers/libs in the target environment and
# search for programs in the build host environment
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+53 -13
View File
@@ -8,7 +8,41 @@
#define MRUBYCONF_H
#include <stdint.h>
#undef MRB_USE_FLOAT
/* configuration options: */
/* add -DMRB_USE_FLOAT to use float instead of double for floating point numbers */
//#define MRB_USE_FLOAT
/* argv max size in mrb_funcall */
//#define MRB_FUNCALL_ARGC_MAX 16
/* number of object per heap page */
//#define MRB_HEAP_PAGE_SIZE 1024
/* initial size for IV khash */
//#define MRB_IV_INITIAL_SIZE 8
/* 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
/* -DDISABLE_XXXX to drop the feature */
#define DISABLE_REGEXP /* regular expression classes */
//#define DISABLE_SPRINTF /* Kernel.sprintf method */
//#define DISABLE_MATH /* Math functions */
//#define DISABLE_TIME /* Time class */
//#define DISABLE_STRUCT /* Struct class */
//#define DISABLE_STDIO /* use of stdio */
#undef HAVE_UNISTD_H /* WINDOWS */
#define HAVE_UNISTD_H /* LINUX */
/* end of configuration */
#ifdef MRB_USE_FLOAT
typedef float mrb_float;
@@ -19,20 +53,26 @@ typedef double mrb_float;
typedef int mrb_int;
typedef intptr_t mrb_sym;
#define readint(p,base) strtol((p),NULL,(base))
#undef INCLUDE_ENCODING /* not use encoding classes (ascii only) */
//#define INCLUDE_ENCODING /* use UTF-8 encoding classes */
#undef INCLUDE_REGEXP /* not use regular expression classes */
//#define INCLUDE_REGEXP /* use regular expression classes */
#ifdef INCLUDE_REGEXP
# define INCLUDE_ENCODING /* Regexp depends Encoding */
/* define ENABLE_XXXX from DISABLE_XXX */
#ifndef DISABLE_REGEXP
#define ENABLE_REGEXP
#endif
#ifndef DISABLE_SPRINTF
#define ENABLE_SPRINTF
#endif
#ifndef DISABLE_MATH
#define ENABLE_MATH
#endif
#ifndef DISABLE_TIME
#define ENABLE_TIME
#endif
#ifndef DISABLE_STRUCT
#define ENABLE_STRUCT
#endif
#ifndef DISABLE_STDIO
#define ENABLE_STDIO
#endif
#undef HAVE_UNISTD_H /* WINDOWS */
#define HAVE_UNISTD_H /* LINUX */
#ifndef FALSE
# define FALSE 0
+23 -31
View File
@@ -60,9 +60,7 @@ enum mrb_vtype {
MRB_TT_FILE, /* 21 */
MRB_TT_ENV, /* 22 */
MRB_TT_DATA, /* 23 */
MRB_TT_THREAD, /* 24 */
MRB_TT_THREADGRP, /* 25 */
MRB_TT_MAXDEFINE /* 26 */
MRB_TT_MAXDEFINE /* 24 */
};
typedef struct mrb_value {
@@ -83,7 +81,7 @@ typedef struct mrb_value {
#define mrb_symbol(o) (o).value.sym
#define mrb_object(o) ((struct RBasic *) (o).value.p)
#define FIXNUM_P(o) ((o).tt == MRB_TT_FIXNUM)
#define UNDEF_P(o) ((o).tt == MRB_TT_UNDEF)
#define mrb_undef_p(o) ((o).tt == MRB_TT_UNDEF)
#include "mruby/object.h"
@@ -147,7 +145,7 @@ mrb_obj_value(void *p)
}
static inline mrb_value
mrb_false_value()
mrb_false_value(void)
{
mrb_value v;
@@ -157,7 +155,7 @@ mrb_false_value()
}
static inline mrb_value
mrb_nil_value()
mrb_nil_value(void)
{
mrb_value v;
@@ -167,7 +165,7 @@ mrb_nil_value()
}
static inline mrb_value
mrb_true_value()
mrb_true_value(void)
{
mrb_value v;
@@ -177,7 +175,7 @@ mrb_true_value()
}
static inline mrb_value
mrb_undef_value()
mrb_undef_value(void)
{
mrb_value v;
@@ -192,7 +190,9 @@ struct mrb_state;
typedef void* (*mrb_allocf) (struct mrb_state *mrb, void*, size_t);
#define MRB_ARENA_SIZE 1024 //256 up kusuda 2011/04/30
#ifndef MRB_ARENA_SIZE
#define MRB_ARENA_SIZE 1024
#endif
#define ruby_debug (mrb_nil_value())
#define ruby_verbose (mrb_nil_value())
@@ -279,7 +279,8 @@ typedef struct mrb_state {
struct RClass *eException_class;
struct RClass *eStandardError_class;
struct RClass *eRuntimeError_class;
void *ud; /* auxiliary data */
} mrb_state;
typedef mrb_value (*mrb_func_t)(mrb_state *mrb, mrb_value);
@@ -295,10 +296,10 @@ void mrb_define_singleton_method(mrb_state*, struct RObject*, const char*, mrb_f
void mrb_define_module_function(mrb_state*, struct RClass*, const char*, mrb_func_t,int);
void mrb_define_const(mrb_state*, struct RClass*, const char *name, mrb_value);
void mrb_undef_method(mrb_state*, struct RClass*, const char*);
void mrb_undef_class_method(mrb_state*, struct RClass*, const char*);
mrb_value mrb_instance_new(mrb_state *mrb, mrb_value cv);
struct RClass * mrb_class_new(mrb_state *mrb, struct RClass *super);
struct RClass * mrb_module_new(mrb_state *mrb);
struct RClass * mrb_class_from_sym(mrb_state *mrb, struct RClass *klass, mrb_sym name);
struct RClass * mrb_class_get(mrb_state *mrb, const char *name);
struct RClass * mrb_class_obj_get(mrb_state *mrb, const char *name);
@@ -329,10 +330,13 @@ struct RClass * mrb_define_module_under(mrb_state *mrb, struct RClass *outer, co
int mrb_get_args(mrb_state *mrb, const char *format, ...);
mrb_value mrb_funcall(mrb_state*, mrb_value, const char*, int,...);
mrb_value mrb_funcall_argv(mrb_state*, mrb_value, const char*, int, mrb_value*);
mrb_value mrb_funcall_with_block(mrb_state*, mrb_value, const char*, int, mrb_value*, mrb_value);
mrb_value mrb_funcall_argv(mrb_state*, mrb_value, mrb_sym, int, mrb_value*);
mrb_value mrb_funcall_with_block(mrb_state*, mrb_value, mrb_sym, int, mrb_value*, mrb_value);
mrb_sym mrb_intern(mrb_state*,const char*);
mrb_sym mrb_intern2(mrb_state*,const char*,int);
mrb_sym mrb_intern_str(mrb_state*,mrb_value);
const char *mrb_sym2name(mrb_state*,mrb_sym);
const char *mrb_sym2name_len(mrb_state*,mrb_sym,int*);
mrb_value mrb_str_format(mrb_state *, int, const mrb_value *, mrb_value);
void *mrb_malloc(mrb_state*, size_t);
@@ -353,8 +357,8 @@ int mrb_checkstack(mrb_state*,int);
mrb_value mrb_top_self(mrb_state *);
mrb_value mrb_run(mrb_state*, struct RProc*, mrb_value);
mrb_value mrb_p(mrb_state*, mrb_value);
int mrb_obj_id(mrb_value obj);
void mrb_p(mrb_state*, mrb_value);
mrb_int mrb_obj_id(mrb_value obj);
mrb_sym mrb_to_id(mrb_state *mrb, mrb_value name);
int mrb_obj_equal(mrb_state*, mrb_value, mrb_value);
@@ -416,13 +420,16 @@ mrb_value mrb_check_funcall(mrb_state *mrb, mrb_value recv, mrb_sym mid, int arg
#define ISXDIGIT(c) (ISASCII(c) && isxdigit((int)(unsigned char)(c)))
#endif
mrb_value mrb_exc_new(mrb_state *mrb, struct RClass *c, const char *ptr, long len);
void mrb_exc_raise(mrb_state *mrb, mrb_value exc);
int mrb_block_given_p(void);
void mrb_raise(mrb_state *mrb, struct RClass *c, const char *fmt, ...);
void rb_raise(struct RClass *c, const char *fmt, ...);
void mrb_warn(const char *fmt, ...);
void mrb_warning(const char *fmt, ...);
void mrb_bug(const char *fmt, ...);
#define E_RUNTIME_ERROR (mrb_class_obj_get(mrb, "RuntimeError"))
#define E_TYPE_ERROR (mrb_class_obj_get(mrb, "TypeError"))
#define E_ARGUMENT_ERROR (mrb_class_obj_get(mrb, "ArgumentError"))
#define E_INDEX_ERROR (mrb_class_obj_get(mrb, "IndexError"))
@@ -431,13 +438,9 @@ void mrb_bug(const char *fmt, ...);
#define E_NOMETHOD_ERROR (mrb_class_obj_get(mrb, "NoMethodError"))
#define E_SCRIPT_ERROR (mrb_class_obj_get(mrb, "ScriptError"))
#define E_SYNTAX_ERROR (mrb_class_obj_get(mrb, "SyntaxError"))
#define E_LOAD_ERROR (mrb_class_obj_get(mrb, "LoadError"))
#define E_SYSTEMCALL_ERROR (mrb_class_obj_get(mrb, "SystemCallError"))
#define E_LOCALJUMP_ERROR (mrb_class_obj_get(mrb, "LocalJumpError"))
#define E_REGEXP_ERROR (mrb_class_obj_get(mrb, "RegexpError"))
#define E_ZERODIVISION_ERROR (mrb_class_obj_get(mrb, "ZeroDivisionError"))
#define E_ENCODING_ERROR (mrb_class_obj_get(mrb, "EncodingError"))
#define E_NOTIMP_ERROR (mrb_class_obj_get(mrb, "NotImplementedError"))
#define E_FLOATDOMAIN_ERROR (mrb_class_obj_get(mrb, "FloatDomainError"))
@@ -462,20 +465,9 @@ NUM2CHR(mrb_value x)
mrb_value mrb_yield(mrb_state *mrb, mrb_value v, mrb_value blk);
mrb_value mrb_yield_argv(mrb_state *mrb, mrb_value b, int argc, mrb_value *argv);
mrb_value mrb_yield_with_self(mrb_state *mrb, mrb_value b, int argc, mrb_value *argv, mrb_value self);
mrb_value mrb_class_new_instance(mrb_state *mrb, int, mrb_value*, struct RClass *);
mrb_value mrb_class_new_instance_m(mrb_state *mrb, mrb_value klass);
mrb_value mrb_exec_recursive(mrb_state *mrb, mrb_value(*)(mrb_state *, mrb_value, mrb_value, int),mrb_value,void *);
#ifndef xmalloc
#define xmalloc malloc
#define xrealloc realloc
#define xcalloc calloc
#define xfree free
#endif
void mrb_garbage_collect(mrb_state *mrb);
void mrb_gc_protect(mrb_state *mrb, mrb_value obj);
mrb_value mrb_to_int(mrb_state *mrb, mrb_value val);
void mrb_check_type(mrb_state *mrb, mrb_value x, enum mrb_vtype t);
+21 -14
View File
@@ -11,11 +11,20 @@
extern "C" {
#endif
struct mrb_shared_array {
int refcnt;
mrb_value *ptr;
int len;
};
struct RArray {
MRUBY_OBJECT_HEADER;
size_t len;
size_t capa;
mrb_value *buf;
int len;
union {
int capa;
struct mrb_shared_array *shared;
} aux;
mrb_value *ptr;
};
#define mrb_ary_ptr(v) ((struct RArray*)((v).value.p))
@@ -23,30 +32,28 @@ struct RArray {
#define RARRAY(v) ((struct RArray*)((v).value.p))
#define RARRAY_LEN(a) (RARRAY(a)->len)
#define RARRAY_PTR(a) (RARRAY(a)->buf)
#define RARRAY_PTR(a) (RARRAY(a)->ptr)
#define MRB_ARY_SHARED 256
mrb_value mrb_ary_new_capa(mrb_state*, size_t);
void mrb_ary_decref(mrb_state*, struct mrb_shared_array*);
mrb_value mrb_ary_new_capa(mrb_state*, int);
mrb_value mrb_ary_new(mrb_state *mrb);
mrb_value mrb_ary_new_elts(mrb_state *mrb, long n, const mrb_value *elts);
mrb_value mrb_ary_new_elts(mrb_state *mrb, int n, const mrb_value *elts);
void mrb_ary_concat(mrb_state*, mrb_value, mrb_value);
mrb_value mrb_ary_splat(mrb_state*, mrb_value);
void mrb_ary_push(mrb_state*, mrb_value, mrb_value);
mrb_value mrb_ary_pop(mrb_state *mrb, mrb_value ary);
mrb_value mrb_ary_new_from_values(mrb_state *mrb, size_t size, mrb_value *vals);
mrb_value mrb_ary_new_from_values(mrb_state *mrb, int size, mrb_value *vals);
mrb_value mrb_ary_aget(mrb_state *mrb, mrb_value self);
mrb_value mrb_ary_ref(mrb_state *mrb, mrb_value ary, mrb_int n);
void mrb_ary_set(mrb_state *mrb, mrb_value ary, mrb_int n, mrb_value val);
int mrb_ary_len(mrb_state *mrb, mrb_value ary);
mrb_value mrb_ary_replace_m(mrb_state *mrb, mrb_value self);
void mrb_ary_replace(mrb_state *mrb, struct RArray *a, mrb_value *argv, size_t len);
void mrb_ary_replace(mrb_state *mrb, mrb_value a, mrb_value b);
mrb_value mrb_check_array_type(mrb_state *mrb, mrb_value self);
mrb_value mrb_ary_unshift(mrb_state *mrb, mrb_value self, mrb_value item);
mrb_value mrb_ary_new4(mrb_state *mrb, long n, const mrb_value *elts);
mrb_value mrb_ary_new4(mrb_state *mrb, int n, const mrb_value *elts);
mrb_value mrb_assoc_new(mrb_state *mrb, mrb_value car, mrb_value cdr);
mrb_value mrb_ary_entry(mrb_value ary, long offset);
void mrb_mem_clear(mrb_value *mem, long size);
mrb_value mrb_ary_tmp_new(mrb_state *mrb, long capa);
mrb_value mrb_ary_sort(mrb_state *mrb, mrb_value ary);
mrb_value mrb_ary_entry(mrb_value ary, int offset);
mrb_value mrb_ary_shift(mrb_state *mrb, mrb_value self);
#if defined(__cplusplus)
+6 -9
View File
@@ -28,7 +28,7 @@ mrb_class(mrb_state *mrb, mrb_value v)
{
switch (mrb_type(v)) {
case MRB_TT_FALSE:
if (v.value.p)
if (v.value.i)
return mrb->false_class;
return mrb->nil_class;
case MRB_TT_TRUE:
@@ -40,14 +40,7 @@ mrb_class(mrb_state *mrb, mrb_value v)
case MRB_TT_FLOAT:
return mrb->float_class;
#ifdef INCLUDE_REGEXP
// case MRB_TT_REGEX:
// return mrb->regex_class;
// case MRB_TT_MATCH:
// return mrb->match_class;
// case MRB_TT_DATA:
// return mrb->encode_class;
#else
#ifdef ENABLE_REGEXP
case MRB_TT_REGEX:
case MRB_TT_MATCH:
mrb_raise(mrb, E_TYPE_ERROR, "type mismatch: %s given",
@@ -78,6 +71,10 @@ struct RClass* mrb_class_real(struct RClass* cl);
void mrb_obj_call_init(mrb_state *mrb, mrb_value obj, int argc, mrb_value *argv);
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*);
#if defined(__cplusplus)
} /* extern "C" { */
#endif
+34 -15
View File
@@ -15,12 +15,27 @@ extern "C" {
#include <stdio.h>
#include <setjmp.h>
/* load context */
typedef struct mrbc_context {
mrb_sym *syms;
int slen;
char *filename;
int lineno;
int capture_errors:1;
int dump_result:1;
int no_exec:1;
} mrbc_context;
mrbc_context* mrbc_context_new(mrb_state *mrb);
void mrbc_context_free(mrb_state *mrb, mrbc_context *cxt);
const char *mrbc_filename(mrb_state *mrb, mrbc_context *c, const char *s);
/* AST node structure */
typedef struct mrb_ast_node {
struct mrb_ast_node *car, *cdr;
} mrb_ast_node;
#include <stdio.h>
/* lexer states */
enum mrb_lex_state_enum {
EXPR_BEG, /* ignore newline, +/- is a sign. */
EXPR_END, /* newline significant, +/- is an operator. */
@@ -36,21 +51,23 @@ enum mrb_lex_state_enum {
EXPR_MAX_STATE
};
/* saved error message */
struct mrb_parser_message {
int lineno;
int column;
char* message;
};
/* parser structure */
struct mrb_parser_state {
mrb_state *mrb;
struct mrb_pool *pool;
mrb_ast_node *cells;
const char *s, *send;
FILE *f;
char *filename;
int lineno;
int column;
const char *filename;
enum mrb_lex_state_enum lstate;
int sterm;
@@ -59,6 +76,8 @@ struct mrb_parser_state {
unsigned int cmdarg_stack;
int paren_nest;
int lpar_beg;
int in_def, in_single, cmd_start;
mrb_ast_node *locals;
mrb_ast_node *pb;
char buf[1024];
@@ -66,9 +85,6 @@ struct mrb_parser_state {
mrb_ast_node *heredoc;
int in_def, in_single, cmd_start;
mrb_ast_node *locals;
void *ylval;
int nerr;
@@ -82,21 +98,24 @@ struct mrb_parser_state {
jmp_buf jmp;
};
/* parser structure */
struct mrb_parser_state* mrb_parser_new(mrb_state*);
void mrb_parser_free(struct mrb_parser_state*);
const char *mrb_parser_filename(struct mrb_parser_state*, const char*);
int mrb_parser_lineno(struct mrb_parser_state*, int);
void mrb_parser_parse(struct mrb_parser_state*);
void mrb_parser_parse(struct mrb_parser_state*,mrbc_context*);
/* utility functions */
struct mrb_parser_state* mrb_parse_file(mrb_state*,FILE*);
struct mrb_parser_state* mrb_parse_string(mrb_state*,const char*);
struct mrb_parser_state* mrb_parse_nstring(mrb_state*,const char*,size_t);
struct mrb_parser_state* mrb_parse_file(mrb_state*,FILE*,mrbc_context*);
struct mrb_parser_state* mrb_parse_string(mrb_state*,const char*,mrbc_context*);
struct mrb_parser_state* mrb_parse_nstring(mrb_state*,const char*,int,mrbc_context*);
int mrb_generate_code(mrb_state*, mrb_ast_node*);
int mrb_compile_file(mrb_state*,FILE*);
int mrb_compile_string(mrb_state*,char*);
int mrb_compile_nstring(mrb_state*,char*,size_t);
/* program load functions */
mrb_value mrb_load_file(mrb_state*,FILE*);
mrb_value mrb_load_string(mrb_state *mrb, const char *s);
mrb_value mrb_load_nstring(mrb_state *mrb, const char *s, int len);
mrb_value mrb_load_file_cxt(mrb_state*,FILE*, mrbc_context *cxt);
mrb_value mrb_load_string_cxt(mrb_state *mrb, const char *s, mrbc_context *cxt);
mrb_value mrb_load_nstring_cxt(mrb_state *mrb, const char *s, int len, mrbc_context *cxt);
#if defined(__cplusplus)
} /* extern "C" { */
+8 -10
View File
@@ -17,27 +17,20 @@ struct RHash {
struct kh_ht *ht;
};
#define mrb_hash_end(h) st_hash_end(h)
#define mrb_hash_uint(h, i) st_hash_uint(h, i)
#define mrb_hash_ptr(v) ((struct RHash*)((v).value.p))
#define mrb_hash_value(p) mrb_obj_value((void*)(p))
mrb_value mrb_hash_new_capa(mrb_state*, size_t);
mrb_value mrb_hash_new(mrb_state *mrb, int capa);
mrb_value mrb_hash_new_capa(mrb_state*, int);
mrb_value mrb_hash_new(mrb_state *mrb);
void mrb_hash_set(mrb_state *mrb, mrb_value hash, mrb_value key, mrb_value val);
mrb_value mrb_hash_get(mrb_state *mrb, mrb_value hash, mrb_value key);
mrb_value mrb_hash_getWithDef(mrb_state *mrb, mrb_value hash, mrb_value vkey, mrb_value def);
mrb_value mrb_hash_delete_key(mrb_state *mrb, mrb_value hash, mrb_value key);
mrb_value mrb_hash_fetch(mrb_state *mrb, mrb_value hash, mrb_value key, mrb_value def);
mrb_value mrb_hash(mrb_state *mrb, mrb_value obj);
mrb_value mrb_check_hash_type(mrb_state *mrb, mrb_value self);
/* RHASH_TBL allocates st_table if not available. */
#define RHASH(obj) ((struct RHash*)((obj).value.p))
#define RHASH_TBL(h) (RHASH(h)->ht)
#define RHASH_SIZE(h) (RHASH_TBL(h)->size)
#define RHASH_EMPTY_P(h) (RHASH_SIZE(h) == 0)
#define RHASH_IFNONE(h) mrb_iv_get(mrb, (h), mrb_intern(mrb, "ifnone"))
#define RHASH_PROCDEFAULT(h) RHASH_IFNONE(h)
struct kh_ht * mrb_hash_tbl(mrb_state *mrb, mrb_value hash);
@@ -47,6 +40,11 @@ struct kh_ht * mrb_hash_tbl(mrb_state *mrb, mrb_value hash);
mrb_value mrb_obj_is_proc(mrb_value proc);
/* GC functions */
void mrb_gc_mark_ht(mrb_state*, struct RHash*);
size_t mrb_gc_mark_ht_size(mrb_state*, struct RHash*);
void mrb_gc_free_ht(mrb_state*, struct RHash*);
#if defined(__cplusplus)
} /* extern "C" { */
#endif
+90 -52
View File
@@ -12,13 +12,16 @@ extern "C" {
#endif
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
typedef uint32_t khint_t;
typedef khint_t khiter_t;
#define INITIAL_HASH_SIZE 32
#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[];
@@ -30,18 +33,24 @@ static const uint8_t __m[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
#define __ac_isempty(e_flag, d_flag, i) (e_flag[(i)/8]&__m[(i)%8])
#define __ac_isdel(e_flag, d_flag, i) (d_flag[(i)/8]&__m[(i)%8])
#define __ac_iseither(e_flag, d_flag, i) (__ac_isempty(e_flag,d_flag,i)||__ac_isdel(e_flag,d_flag,i))
#define khash_power2(v) do { \
v--;\
v |= v >> 1;\
v |= v >> 2;\
v |= v >> 4;\
v |= v >> 8;\
v |= v >> 16;\
v++;\
} while (0);
/* struct kh_xxx
/* declare struct kh_xxx and kh_xxx_funcs
name: ash name
khkey_t: key data type
khval_t: value data type
kh_is_map: (not implemented / not used in RiteVM )
__hash_func: hash function
__hash_equal: hash comparation function
kh_is_map: (not implemented / not used in RiteVM)
*/
#define KHASH_INIT(name, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \
#define KHASH_DECLARE(name, khkey_t, khval_t, kh_is_map) \
typedef struct kh_##name { \
khint_t n_buckets; \
khint_t size; \
@@ -55,7 +64,28 @@ static const uint8_t __m[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
khint_t inc; \
mrb_state *mrb; \
} kh_##name##_t; \
static void kh_alloc_##name(kh_##name##_t *h) \
void kh_alloc_##name(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(kh_##name##_t *h); \
void kh_clear_##name(kh_##name##_t *h); \
khint_t kh_get_##name(kh_##name##_t *h, khkey_t key); \
khint_t kh_put_##name(kh_##name##_t *h, khkey_t key); \
void kh_resize_##name(kh_##name##_t *h, khint_t new_n_buckets); \
void kh_del_##name(kh_##name##_t *h, khint_t x); \
kh_##name##_t *kh_copy_##name(mrb_state *mrb, kh_##name##_t *h);
/* define kh_xxx_funcs
name: ash name
khkey_t: key data type
khval_t: value data type
kh_is_map: (not implemented / not used in RiteVM)
__hash_func: hash function
__hash_equal: hash comparation function
*/
#define KHASH_DEFINE(name, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \
void kh_alloc_##name(kh_##name##_t *h) \
{ \
khint_t sz = h->n_buckets; \
h->size = h->n_occupied = 0; \
@@ -69,52 +99,53 @@ static const uint8_t __m[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
h->mask = sz-1; \
h->inc = sz/2-1; \
} \
static inline kh_##name##_t *kh_init_##name(mrb_state *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)); \
h->n_buckets = INITIAL_HASH_SIZE; \
if (size < KHASH_MIN_SIZE) \
size = KHASH_MIN_SIZE; \
khash_power2(size); \
h->n_buckets = size; \
h->mrb = mrb; \
kh_alloc_##name(h); \
return h; \
} \
static inline void kh_destroy_##name(kh_##name##_t *h) \
kh_##name##_t *kh_init_##name(mrb_state *mrb){ \
return kh_init_##name##_size(mrb, KHASH_DEFAULT_SIZE); \
} \
void kh_destroy_##name(kh_##name##_t *h) \
{ \
if( h ){ \
if (h) { \
mrb_free(h->mrb, h->keys); \
mrb_free(h->mrb, h->vals); \
mrb_free(h->mrb, h->e_flags); \
mrb_free(h->mrb, h); \
} \
} \
static inline void kh_clear_##name(kh_##name##_t *h) \
void kh_clear_##name(kh_##name##_t *h) \
{ \
if( h && h->e_flags ){ \
if (h && h->e_flags) { \
memset(h->e_flags, 0xff, h->n_buckets/8*sizeof(uint8_t)); \
memset(h->d_flags, 0x00, h->n_buckets/8*sizeof(uint8_t)); \
h->size = h->n_occupied = 0; \
} \
} \
static inline khint_t kh_get_##name(kh_##name##_t *h, khkey_t key) \
khint_t kh_get_##name(kh_##name##_t *h, khkey_t key) \
{ \
khint_t k = __hash_func(h->mrb,key) & (h->mask); \
while( !__ac_isempty(h->e_flags, h->d_flags, k) ){ \
if( !__ac_isdel(h->e_flags, h->d_flags, k) ){ \
if( __hash_equal(h->mrb,h->keys[k], key) ) return k; \
while (!__ac_isempty(h->e_flags, h->d_flags, k)) { \
if (!__ac_isdel(h->e_flags, h->d_flags, k)) { \
if (__hash_equal(h->mrb,h->keys[k], key)) return k; \
} \
k = (k+h->inc) & (h->mask); \
} \
return h->n_buckets; \
} \
static inline khint_t kh_put_##name(kh_##name##_t *h, khkey_t key); \
static void kh_resize_##name(kh_##name##_t *h, khint_t new_n_buckets) \
void kh_resize_##name(kh_##name##_t *h, khint_t new_n_buckets) \
{ \
if( new_n_buckets<INITIAL_HASH_SIZE ){ \
new_n_buckets = INITIAL_HASH_SIZE; \
} else { \
khint_t limit = new_n_buckets; \
new_n_buckets = INITIAL_HASH_SIZE; \
while( new_n_buckets < limit ) new_n_buckets *= 2; \
} \
{ \
if (new_n_buckets < KHASH_MIN_SIZE) \
new_n_buckets = KHASH_MIN_SIZE; \
khash_power2(new_n_buckets); \
{ \
uint8_t *old_e_flags = h->e_flags; \
khkey_t *old_keys = h->keys; \
khval_t *old_vals = h->vals; \
@@ -123,32 +154,35 @@ static const uint8_t __m[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
h->n_buckets = new_n_buckets; \
kh_alloc_##name(h); \
/* relocate */ \
for( i=0 ; i<old_n_buckets ; i++ ){ \
if( !__ac_isempty(old_e_flags, old_d_flags, i) ){ \
khint_t k = kh_put_##name(h, old_keys[i]); \
kh_value(h,k) = old_vals[i]; \
} \
for (i=0 ; i<old_n_buckets ; i++) { \
if (!__ac_isempty(old_e_flags, old_d_flags, i)) { \
khint_t k = kh_put_##name(h, old_keys[i]); \
kh_value(h,k) = old_vals[i]; \
} \
} \
mrb_free(h->mrb, old_e_flags); \
mrb_free(h->mrb, old_keys); \
mrb_free(h->mrb, old_vals); \
} \
} \
static inline khint_t kh_put_##name(kh_##name##_t *h, khkey_t key) \
khint_t kh_put_##name(kh_##name##_t *h, khkey_t key) \
{ \
khint_t k; \
if( h->n_occupied >= h->upper_bound ){ \
if (h->n_occupied >= h->upper_bound) { \
kh_resize_##name(h, h->n_buckets*2); \
} \
k = __hash_func(h->mrb,key) & (h->mask); \
while( !__ac_iseither(h->e_flags, h->d_flags, k) ){ \
if( __hash_equal(h->mrb,h->keys[k], key) ) break; \
while (!__ac_iseither(h->e_flags, h->d_flags, k)) { \
if (__hash_equal(h->mrb,h->keys[k], key)) break; \
k = (k+h->inc) & (h->mask); \
} \
if( __ac_isempty(h->e_flags, h->d_flags, k) ) { \
if (__ac_isempty(h->e_flags, h->d_flags, k)) { \
/* put at empty */ \
h->keys[k] = key; \
h->e_flags[k/8] &= ~__m[k%8]; \
h->size++; \
h->n_occupied++; \
} else if( __ac_isdel(h->e_flags, h->d_flags, k) ) { \
} else if (__ac_isdel(h->e_flags, h->d_flags, k)) { \
/* put at del */ \
h->keys[k] = key; \
h->d_flags[k/8] &= ~__m[k%8]; \
@@ -156,22 +190,30 @@ static const uint8_t __m[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
} \
return k; \
} \
static inline void kh_del_##name(kh_##name##_t *h, khint_t x) \
void kh_del_##name(kh_##name##_t *h, khint_t x) \
{ \
h->d_flags[x/8] |= __m[x%8]; \
h->size--; \
} \
static inline void kh_debug_##name(kh_##name##_t *h) \
kh_##name##_t *kh_copy_##name(mrb_state *mrb, kh_##name##_t *h) \
{ \
khint_t i; \
printf("idx:e_flag:d_flag\n"); \
for( i=0 ; i<h->n_buckets/8 ; i++ ){ \
printf("%4d:%02X:%02X\n", i, h->e_flags[i], h->d_flags[i]); \
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(h2, kh_key(h, k)); \
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, h) kh_destroy_##name(h)
#define kh_clear(name, h) kh_clear_##name(h)
@@ -179,7 +221,7 @@ static const uint8_t __m[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
#define kh_put(name, h, k) kh_put_##name(h, k)
#define kh_get(name, h, k) kh_get_##name(h, k)
#define kh_del(name, h, k) kh_del_##name(h, k)
#define kh_debug(name, h) kh_debug_##name(h)
#define kh_copy(name, mrb, h) kh_copy_##name(mrb, h)
#define kh_exist(h, x) (!__ac_iseither((h)->e_flags, (h)->d_flags, (x)))
#define kh_key(h, x) ((h)->keys[x])
@@ -203,11 +245,7 @@ static inline khint_t __ac_X31_hash_string(const char *s)
#define kh_str_hash_func(mrb,key) __ac_X31_hash_string(key)
#define kh_str_hash_equal(mrb,a, b) (strcmp(a, b) == 0)
#define KHASH_MAP_INIT_INT(name, khval_t) \
KHASH_INIT(name, uint32_t, khval_t, 1, kh_int_hash_func, kh_int_hash_equal)
typedef const char *kh_cstr_t;
#define KHASH_MAP_INIT_STR(name, khval_t) \
KHASH_INIT(name, kh_cstr_t, khval_t, 1, kh_str_hash_func, kh_str_hash_equal)
#if defined(__cplusplus)
} /* extern "C" { */
+5 -2
View File
@@ -13,15 +13,18 @@ extern "C" {
#include <limits.h>
#define RSHIFT(x,y) ((x)>>(int)(y))
#define POSFIXABLE(f) ((f) <= INT_MAX)
#define NEGFIXABLE(f) ((f) >= INT_MIN)
#define FIXABLE(f) (POSFIXABLE(f) && NEGFIXABLE(f))
mrb_value mrb_flt2big(mrb_state *mrb, mrb_float d);
void mrb_num_zerodiv(mrb_state *mrb);
mrb_value mrb_fix2str(mrb_state *mrb, mrb_value x, int base);
mrb_value mrb_fixnum_plus(mrb_state *mrb, mrb_value x, mrb_value y);
mrb_value mrb_fixnum_minus(mrb_state *mrb, mrb_value x, mrb_value y);
mrb_value mrb_fixnum_mul(mrb_state *mrb, mrb_value x, mrb_value y);
mrb_value mrb_num_div(mrb_state *mrb, mrb_value x, mrb_value y);
#if defined(__cplusplus)
} /* extern "C" { */
#endif
+1 -1
View File
@@ -13,7 +13,7 @@ extern "C" {
#define MRUBY_OBJECT_HEADER \
enum mrb_vtype tt:8; \
int color:3;\
unsigned int color:3;\
unsigned int flags:21;\
struct RClass *c;\
struct RBasic *gcnext
+4
View File
@@ -49,6 +49,10 @@ struct RProc {
struct RProc *mrb_proc_new(mrb_state*, mrb_irep*);
struct RProc *mrb_proc_new_cfunc(mrb_state*, mrb_func_t);
struct RProc *mrb_closure_new(mrb_state*, mrb_irep*);
void mrb_proc_copy(struct RProc *a, struct RProc *b);
#include "mruby/khash.h"
KHASH_DECLARE(mt, mrb_sym, struct RProc*, 1);
#if defined(__cplusplus)
} /* extern "C" { */
+11 -14
View File
@@ -25,34 +25,33 @@ extern "C" {
extern const char mrb_digitmap[];
struct mrb_shared_string {
int refcnt;
char *ptr;
int len;
};
struct RString {
MRUBY_OBJECT_HEADER;
int len;
union {
int capa;
struct RString *shared;
struct mrb_shared_string *shared;
} aux;
char *buf;
char *ptr;
};
#define mrb_str_ptr(s) ((struct RString*)((s).value.p))
#define RSTRING(s) ((struct RString*)((s).value.p))
#define RSTRING_PTR(s) (RSTRING(s)->buf)
#define RSTRING_PTR(s) (RSTRING(s)->ptr)
#define RSTRING_LEN(s) (RSTRING(s)->len)
#define RSTRING_CAPA(s) (RSTRING(s)->aux.capa)
#define RSTRING_END(s) (RSTRING(s)->buf + RSTRING(s)->len)
#define RSTRING_END(s) (RSTRING(s)->ptr + RSTRING(s)->len)
#define MRB_STR_SHARED 256
#define MRB_STR_SHARED_P(s) (FL_ALL(s, MRB_STR_SHARED))
#define MRB_STR_NOCAPA (MRB_STR_SHARED)
#define MRB_STR_NOCAPA_P(s) (FL_ANY(s, MRB_STR_NOCAPA))
#define MRB_STR_UNSET_NOCAPA(s) do {\
FL_UNSET(s, MRB_STR_NOCAPA);\
} while (0)
void mrb_str_decref(mrb_state*, struct mrb_shared_string*);
mrb_value mrb_str_literal(mrb_state*, mrb_value);
void mrb_str_concat(mrb_state*, mrb_value, mrb_value);
mrb_value mrb_obj_to_str(mrb_state*, mrb_value);
mrb_value mrb_str_plus(mrb_state*, mrb_value, mrb_value);
mrb_value mrb_obj_as_string(mrb_state *mrb, mrb_value obj);
mrb_value mrb_str_resize(mrb_state *mrb, mrb_value str, int len); /* mrb_str_resize */
@@ -78,8 +77,6 @@ int mrb_str_hash_cmp(mrb_state *mrb, mrb_value str1, mrb_value str2);
mrb_value mrb_str_buf_append(mrb_state *mrb, mrb_value str, mrb_value str2);
mrb_value mrb_str_inspect(mrb_state *mrb, mrb_value str);
int mrb_str_equal(mrb_state *mrb, mrb_value str1, mrb_value str2);
mrb_value * mrb_svar(mrb_int cnt);
mrb_value mrb_str_drop_bytes(mrb_state *mrb, mrb_value str, long len);
mrb_value mrb_str_dump(mrb_state *mrb, mrb_value str);
mrb_value mrb_str_cat(mrb_state *mrb, mrb_value str, const char *ptr, long len);
mrb_value mrb_str_append(mrb_state *mrb, mrb_value str, mrb_value str2);
-3
View File
@@ -20,9 +20,6 @@ struct RStruct {
#define RSTRUCT_LEN(st) ((int)(RSTRUCT(st)->len))
#define RSTRUCT_PTR(st) (RSTRUCT(st)->ptr)
mrb_value mrb_yield_values(int n, ...);
mrb_value mrb_mod_module_eval(mrb_state *mrb, int argc, mrb_value *argv, mrb_value mod);
#if defined(__cplusplus)
} /* extern "C" { */
#endif
+16 -4
View File
@@ -14,12 +14,13 @@ extern "C" {
typedef struct global_variable {
int counter;
mrb_value *data;
mrb_value (*getter)();
void (*setter)();
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;
@@ -41,12 +42,23 @@ mrb_value mrb_obj_iv_get(mrb_state*, struct RObject*, mrb_sym);
void mrb_obj_iv_set(mrb_state*, struct RObject*, mrb_sym, mrb_value);
const char * mrb_class2name(mrb_state *mrb, struct RClass* klass);
mrb_value mrb_iv_get(mrb_state *mrb, mrb_value obj, mrb_sym sym);
void mrb_iv_set(mrb_state *mrb, mrb_value obj, mrb_sym sym, mrb_value v); /* mrb_iv_set */
void mrb_copy_generic_ivar(mrb_value clone, mrb_value obj);
void mrb_iv_set(mrb_state *mrb, mrb_value obj, mrb_sym sym, mrb_value v);
mrb_value mrb_iv_remove(mrb_state *mrb, mrb_value obj, mrb_sym sym);
int mrb_const_defined_at(mrb_state *mrb, struct RClass *klass, mrb_sym id);
mrb_value mrb_f_global_variables(mrb_state *mrb, mrb_value self);
mrb_value mrb_gv_get(mrb_state *mrb, mrb_sym sym);
void mrb_gv_set(mrb_state *mrb, mrb_sym sym, mrb_value val);
mrb_value mrb_obj_instance_variables(mrb_state*, mrb_value);
/* 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*);
#include "mruby/khash.h"
KHASH_DECLARE(iv, mrb_sym, mrb_value, 1)
#if defined(__cplusplus)
} /* extern "C" { */
+12 -5
View File
@@ -18,12 +18,19 @@ LIBR := ../lib/libmruby.a
# libraries, includes
INCLUDES = -I../src -I../include
DEBUG_MODE = 1
ifeq ($(DEBUG_MODE),1)
CFLAGS = -g
else
CFLAGS = -O3
ifeq ($(strip $(COMPILE_MODE)),)
# default compile option
COMPILE_MODE = debug
endif
ifeq ($(COMPILE_MODE),debug)
CFLAGS = -g -O3
else ifeq ($(COMPILE_MODE),release)
CFLAGS = -O3
else ifeq ($(COMPILE_MODE),small)
CFLAGS = -Os
endif
ALL_CFLAGS = -Wall -Werror-implicit-function-declaration $(CFLAGS)
ifeq ($(OS),Windows_NT)
MAKE_FLAGS = CC=$(CC) LL=$(LL) ALL_CFLAGS="$(ALL_CFLAGS)"
+26
View File
@@ -0,0 +1,26 @@
class Module
# 15.2.2.4.13
def attr_reader(*names)
names.each{|name|
name2 = ('@'+name.to_s).intern
define_method(name){self.instance_variable_get(name2)}
}
end
# 15.2.2.4.14
def attr_writer(*names)
names.each{|name|
name2 = ('@'+name.to_s).intern
name = (name.to_s+"=").intern
define_method(name){|v|self.instance_variable_set(name2,v)}
}
end
# 15.2.2.4.12
def attr_accessor(*names)
attr_reader(*names)
attr_writer(*names)
end
# 15.2.2.4.11
def attr(name)
attr_reader(name)
end
end
+50
View File
@@ -12,3 +12,53 @@ class Exception
self.new(*args, &block)
end
end
# ISO 15.2.24
class ArgumentError < StandardError
end
# ISO 15.2.25
class LocalJumpError < StandardError
end
# ISO 15.2.26
class RangeError < StandardError
end
class FloatDomainError < RangeError
end
# ISO 15.2.26
class RegexpError < StandardError
end
# ISO 15.2.29
class TypeError < StandardError
end
# ISO 15.2.31
class NameError < StandardError
end
# ISO 15.2.32
class NoMethodError < NameError
end
# ISO 15.2.33
class IndexError < StandardError
end
class KeyError < IndexError
end
# ISO 15.2.37
class ScriptError < Exception
end
# ISO 15.2.38
class SyntaxError < ScriptError
end
class NotImplementedError < ScriptError
end
+56
View File
@@ -80,6 +80,62 @@ class Hash
end
h
end
# 1.8/1.9 Hash#reject! returns Hash; ISO says nothing.
def reject!(&b)
keys = []
self.each_key{|k|
v = self[k]
if b.call(k, v)
keys.push(k)
end
}
return nil if keys.size == 0
keys.each{|k|
self.delete(k)
}
self
end
# 1.8/1.9 Hash#reject returns Hash; ISO says nothing.
def reject(&b)
h = {}
self.each_key{|k|
v = self[k]
unless b.call(k, v)
h[k] = v
end
}
h
end
# 1.9 Hash#select! returns Hash; ISO says nothing.
def select!(&b)
keys = []
self.each_key{|k|
v = self[k]
unless b.call(k, v)
keys.push(k)
end
}
return nil if keys.size == 0
keys.each{|k|
self.delete(k)
}
self
end
# 1.9 Hash#select returns Hash; ISO says nothing.
def select(&b)
h = {}
self.each_key{|k|
v = self[k]
if b.call(k, v)
h[k] = v
end
}
h
end
end
##
+6 -30
View File
@@ -3,17 +3,6 @@
#
# ISO 15.3.1
module Kernel
##
# Takes the given block, create a lambda
# out of it and +call+ it.
#
# ISO 15.3.1.2.6
def self.lambda(&block)
### *** TODO *** ###
block # dummy
end
##
# Calls the given block repetitively.
#
@@ -24,27 +13,14 @@ module Kernel
end
end
##
# Alias for +send+.
#
# ISO 15.3.1.3.4
#def __send__(symbol, *args, &block)
### *** TODO *** ###
#end
# 15.3.1.3.18
def instance_eval(string=nil, &block)
### *** TODO *** ###
raise "Not implemented yet"
# 15.3.1.2.3
def self.eval(s)
raise NotImplementedError.new("eval not implemented")
end
##
# Alias for +Kernel.lambda+.
#
# ISO 15.3.1.3.27
def lambda(&block)
### *** TODO *** ###
block # dummy
# 15.3.1.3.12
def eval(s)
Kernel.eval(s)
end
##
+68 -39
View File
@@ -3,47 +3,76 @@
#
# ISO 15.3.1
module Kernel
##
# Invoke method +print+ on STDOUT and passing +*args+
#
# ISO 15.3.1.2.10
def print(*args)
i = 0
len = args.size
while i < len
__printstr__ args[i].to_s
i += 1
unless Kernel.respond_to?(:__printstr__)
def print(*a)
raise NotImplementedError.new('print not available')
end
end
##
# Invoke method +puts+ on STDOUT and passing +*args*+
#
# ISO 15.3.1.2.11
def puts(*args)
i = 0
len = args.size
while i < len
__printstr__ args[i].to_s
__printstr__ "\n"
i += 1
def puts(*a)
raise NotImplementedError.new('puts not available')
end
__printstr__ "\n" if len == 0
end
##
# Print human readable object description
#
# ISO 15.3.1.3.34
def p(*args)
i = 0
len = args.size
while i < len
__printstr__ args[i].inspect
__printstr__ "\n"
i += 1
def p(*a)
raise NotImplementedError.new('p not available')
end
def printf(*args)
raise NotImplementedError.new('printf not available')
end
else
unless Kernel.respond_to?(:sprintf)
def printf(*args)
raise NotImplementedError.new('printf not available')
end
def sprintf(*args)
raise NotImplementedError.new('sprintf not available')
end
end
##
# Invoke method +print+ on STDOUT and passing +*args+
#
# ISO 15.3.1.2.10
def print(*args)
i = 0
len = args.size
while i < len
__printstr__ args[i].to_s
i += 1
end
end
##
# Invoke method +puts+ on STDOUT and passing +*args*+
#
# ISO 15.3.1.2.11
def puts(*args)
i = 0
len = args.size
while i < len
__printstr__ args[i].to_s
__printstr__ "\n"
i += 1
end
__printstr__ "\n" if len == 0
nil
end
##
# Print human readable object description
#
# ISO 15.3.1.3.34
def p(*args)
i = 0
len = args.size
while i < len
__printstr__ args[i].inspect
__printstr__ "\n"
i += 1
end
args[0]
end
def printf(*args)
__printstr__(sprintf(*args))
end
args[0]
end
end
+16 -7
View File
@@ -33,12 +33,15 @@ class String
end
### *** TODO *** ###
unless Object.const_defined?(:Regexp)
raise NotImplementedError, "gsub not available (yet)"
end
end
##
# Replace all matches of +pattern+ with +replacement+.
# Call block (if given) for each match and replace
# +pattern+ with the value of the block. Modify
# +pattern+ with the value of the block. Modify
# +self+ with the final value.
#
# ISO 15.2.10.5.19
@@ -56,15 +59,18 @@ class String
# Calls the given block for each match of +pattern+
# If no block is given return an array with all
# matches of +pattern+.
#
#
# ISO 15.2.10.5.32
def scan(reg, &block)
### *** TODO *** ###
unless Object.const_defined?(:Regexp)
raise NotImplementedError, "scan not available (yet)"
end
end
##
# Replace only the first match of +pattern+ with
# +replacement+. Call block (if given) for each
# Replace only the first match of +pattern+ with
# +replacement+. Call block (if given) for each
# match and replace +pattern+ with the value of the
# block. Return the final value.
#
@@ -75,12 +81,15 @@ class String
end
### *** TODO *** ###
unless Object.const_defined?(:Regexp)
raise NotImplementedError, "sub not available (yet)"
end
end
##
# Replace only the first match of +pattern+ with
# +replacement+. Call block (if given) for each
# match and replace +pattern+ with the value of the
# Replace only the first match of +pattern+ with
# +replacement+. Call block (if given) for each
# match and replace +pattern+ with the value of the
# block. Modify +self+ with the final value.
#
# ISO 15.2.10.5.37
+41 -37
View File
@@ -2,45 +2,49 @@
# Struct
#
# ISO 15.2.18
class Struct
##
# Calls the given block for each element of +self+
# and pass the respective element.
#
# ISO 15.2.18.4.4
def each(&block)
self.class.members.each{|field|
block.call(self[field])
}
self
end
if Object.const_defined?(:Struct)
class Struct
##
# Calls the given block for each element of +self+
# and pass the name and value of the respectiev
# element.
#
# ISO 15.2.18.4.5
def each_pair(&block)
self.class.members.each{|field|
block.call(field.to_sym, self[field])
}
self
end
##
# Calls the given block for each element of +self+
# and pass the respective element.
#
# ISO 15.2.18.4.4
def each(&block)
self.class.members.each{|field|
block.call(self[field])
}
self
end
##
# Calls the given block for each element of +self+
# and returns an array with all elements of which
# block is not false.
#
# ISO 15.2.18.4.7
def select(&block)
ary = []
self.class.members.each{|field|
val = self[field]
ary.push(val) if block.call(val)
}
ary
##
# Calls the given block for each element of +self+
# and pass the name and value of the respectiev
# element.
#
# ISO 15.2.18.4.5
def each_pair(&block)
self.class.members.each{|field|
block.call(field.to_sym, self[field])
}
self
end
##
# Calls the given block for each element of +self+
# and returns an array with all elements of which
# block is not false.
#
# ISO 15.2.18.4.7
def select(&block)
ary = []
self.class.members.each{|field|
val = self[field]
ary.push(val) if block.call(val)
}
ary
end
end
end
-9
View File
@@ -1,9 +0,0 @@
//
// hello_mruby.c
// mruby
//
// Created by Paolo Bosetti on 5/22/12.
// Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//
#include <stdio.h>
+12 -5
View File
@@ -19,12 +19,19 @@ OBJS := $(OBJ1) $(OBJ2) $(OBJ3)
# libraries, includes
INCLUDES = -I$(BASEDIR) -I$(BASEDIR)/../include
DEBUG_MODE = 1
ifeq ($(DEBUG_MODE),1)
CFLAGS = -g -O3
else
CFLAGS = -O3
ifeq ($(strip $(COMPILE_MODE)),)
# default compile option
COMPILE_MODE = debug
endif
ifeq ($(COMPILE_MODE),debug)
CFLAGS = -g -O3
else ifeq ($(COMPILE_MODE),release)
CFLAGS = -O3
else ifeq ($(COMPILE_MODE),small)
CFLAGS = -Os
endif
ALL_CFLAGS = -Wall -Werror-implicit-function-declaration $(CFLAGS)
+311 -197
View File
@@ -10,15 +10,14 @@
#include "mruby/string.h"
#include "mruby/class.h"
//#define ARY_DEFAULT_LEN 16
#define ARY_DEFAULT_LEN 4
#define ARY_SHRINK_RATIO 5 /* must be larger than 2 */
#ifdef LONG_MAX
# define ARY_MAX_SIZE (LONG_MAX / sizeof(mrb_value))
#ifdef INT_MAX
# define ARY_MAX_SIZE (INT_MAX / sizeof(mrb_value))
#endif
static inline mrb_value
ary_elt(mrb_value ary, long offset)
ary_elt(mrb_value ary, int offset)
{
if (RARRAY_LEN(ary) == 0) return mrb_nil_value();
if (offset < 0 || RARRAY_LEN(ary) <= offset) {
@@ -28,12 +27,12 @@ ary_elt(mrb_value ary, long offset)
}
static struct RArray*
ary_new_capa(mrb_state *mrb, size_t capa)
ary_new_capa(mrb_state *mrb, int capa)
{
struct RArray *a;
size_t blen;
int blen;
#ifdef LONG_MAX
#ifdef INT_MAX
if (capa > ARY_MAX_SIZE) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "ary size too big");
}
@@ -47,16 +46,15 @@ ary_new_capa(mrb_state *mrb, size_t capa)
}
a = (struct RArray*)mrb_obj_alloc(mrb, MRB_TT_ARRAY, mrb->array_class);
a->buf = mrb_malloc(mrb, blen);
memset(a->buf, 0, blen);
a->capa = capa;
a->ptr = (mrb_value *)mrb_calloc(mrb, blen, 1);
a->aux.capa = capa;
a->len = 0;
return a;
}
mrb_value
mrb_ary_new_capa(mrb_state *mrb, size_t capa)
mrb_ary_new_capa(mrb_state *mrb, int capa)
{
struct RArray *a = ary_new_capa(mrb, capa);
return mrb_obj_value(a);
@@ -69,14 +67,14 @@ mrb_ary_new(mrb_state *mrb)
}
mrb_value
mrb_ary_new_from_values(mrb_state *mrb, size_t size, mrb_value *vals)
mrb_ary_new_from_values(mrb_state *mrb, int size, mrb_value *vals)
{
mrb_value ary;
struct RArray *a;
ary = mrb_ary_new_capa(mrb, size);
a = mrb_ary_ptr(ary);
memcpy(a->buf, vals, sizeof(mrb_value)*size);
memcpy(a->ptr, vals, sizeof(mrb_value)*size);
a->len = size;
return ary;
@@ -91,22 +89,70 @@ mrb_assoc_new(mrb_state *mrb, mrb_value car, mrb_value cdr)
return mrb_ary_new_from_values(mrb, 2, arv);
}
void
ary_fill_with_nil(mrb_value *buf, size_t size)
static void
ary_fill_with_nil(mrb_value *ptr, int size)
{
mrb_value nil = mrb_nil_value();
while((int)(size--)) {
*buf++ = nil;
*ptr++ = nil;
}
}
void
mrb_ary_expand_capa(mrb_state *mrb, struct RArray *a, size_t len)
static void
ary_modify(mrb_state *mrb, struct RArray *a)
{
size_t capa = a->capa;
if (a->flags & MRB_ARY_SHARED) {
struct mrb_shared_array *shared = a->aux.shared;
#ifdef LONG_MAX
if (shared->refcnt == 1 && a->ptr == shared->ptr) {
a->ptr = shared->ptr;
a->aux.capa = a->len;
mrb_free(mrb, shared);
}
else {
mrb_value *ptr, *p;
int len;
p = a->ptr;
len = a->len * sizeof(mrb_value);
ptr = (mrb_value *)mrb_malloc(mrb, len);
if (p) {
memcpy(ptr, p, len);
}
a->ptr = ptr;
a->aux.capa = a->len;
mrb_ary_decref(mrb, shared);
}
a->flags &= ~MRB_ARY_SHARED;
}
}
static void
ary_make_shared(mrb_state *mrb, struct RArray *a)
{
if (!(a->flags & MRB_ARY_SHARED)) {
struct mrb_shared_array *shared = (struct mrb_shared_array *)mrb_malloc(mrb, sizeof(struct mrb_shared_array));
shared->refcnt = 1;
if (a->aux.capa > a->len) {
a->ptr = shared->ptr = (mrb_value *)mrb_realloc(mrb, a->ptr, sizeof(mrb_value)*a->len+1);
}
else {
shared->ptr = a->ptr;
}
shared->len = a->len;
a->aux.shared = shared;
a->flags |= MRB_ARY_SHARED;
}
}
static void
ary_expand_capa(mrb_state *mrb, struct RArray *a, int len)
{
int capa = a->aux.capa;
#ifdef INT_MAX
if (len > ARY_MAX_SIZE) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big");
}
@@ -121,20 +167,20 @@ mrb_ary_expand_capa(mrb_state *mrb, struct RArray *a, size_t len)
}
}
#ifdef LONG_MAX
#ifdef INT_MAX
if (capa > ARY_MAX_SIZE) capa = ARY_MAX_SIZE; /* len <= capa <= ARY_MAX_SIZE */
#endif
if (capa > a->capa) {
a->capa = capa;
a->buf = mrb_realloc(mrb, a->buf, sizeof(mrb_value)*capa);
if (capa > a->aux.capa) {
a->aux.capa = capa;
a->ptr = (mrb_value *)mrb_realloc(mrb, a->ptr, sizeof(mrb_value)*capa);
}
}
void
mrb_ary_shrink_capa(mrb_state *mrb, struct RArray *a)
static void
ary_shrink_capa(mrb_state *mrb, struct RArray *a)
{
size_t capa = a->capa;
int capa = a->aux.capa;
if (capa < ARY_DEFAULT_LEN * 2) return;
if (capa <= a->len * ARY_SHRINK_RATIO) return;
@@ -147,9 +193,9 @@ mrb_ary_shrink_capa(mrb_state *mrb, struct RArray *a)
}
} while(capa > a->len * ARY_SHRINK_RATIO);
if (capa > a->len && capa < a->capa) {
a->capa = capa;
a->buf = mrb_realloc(mrb, a->buf, sizeof(mrb_value)*capa);
if (capa > a->len && capa < a->aux.capa) {
a->aux.capa = capa;
a->ptr = (mrb_value *)mrb_realloc(mrb, a->ptr, sizeof(mrb_value)*capa);
}
}
@@ -160,29 +206,37 @@ mrb_ary_s_create(mrb_state *mrb, mrb_value self)
int len;
mrb_get_args(mrb, "*", &vals, &len);
return mrb_ary_new_from_values(mrb, (size_t)len, vals);
return mrb_ary_new_from_values(mrb, (int)len, vals);
}
static void
ary_concat(mrb_state *mrb, struct RArray *a, mrb_value *ptr, int blen)
{
int len = a->len + blen;
ary_modify(mrb, a);
if (a->aux.capa < len) ary_expand_capa(mrb, a, len);
memcpy(a->ptr+a->len, ptr, sizeof(mrb_value)*blen);
mrb_write_barrier(mrb, (struct RBasic*)a);
a->len = len;
}
void
mrb_ary_concat(mrb_state *mrb, mrb_value self, mrb_value other)
{
struct RArray *a1 = mrb_ary_ptr(self);
struct RArray *a2 = mrb_ary_ptr(other);
size_t len = a1->len + a2->len;
if (a1->capa < len) mrb_ary_expand_capa(mrb, a1, len);
memcpy(a1->buf+a1->len, a2->buf, sizeof(mrb_value)*a2->len);
mrb_write_barrier(mrb, (struct RBasic*)a1);
a1->len = len;
ary_concat(mrb, mrb_ary_ptr(self), a2->ptr, a2->len);
}
mrb_value
mrb_ary_concat_m(mrb_state *mrb, mrb_value self)
{
mrb_value other;
mrb_value *ptr;
int blen;
mrb_get_args(mrb, "A", &other);
mrb_ary_concat(mrb, self, other);
mrb_get_args(mrb, "a", &ptr, &blen);
ary_concat(mrb, mrb_ary_ptr(self), ptr, blen);
return self;
}
@@ -191,15 +245,16 @@ mrb_ary_plus(mrb_state *mrb, mrb_value self)
{
struct RArray *a1 = mrb_ary_ptr(self);
struct RArray *a2;
mrb_value other;
mrb_value ary;
mrb_value *ptr;
int blen;
mrb_get_args(mrb, "A", &other);
ary = mrb_ary_new_capa(mrb, a1->len + RARRAY_LEN(other));
mrb_get_args(mrb, "a", &ptr, &blen);
ary = mrb_ary_new_capa(mrb, a1->len + blen);
a2 = mrb_ary_ptr(ary);
memcpy(a2->buf, a1->buf, sizeof(mrb_value)*a1->len);
memcpy(a2->buf + a1->len, RARRAY_PTR(other), sizeof(mrb_value)*RARRAY_LEN(other));
a2->len = a1->len + RARRAY_LEN(other);
memcpy(a2->ptr, a1->ptr, sizeof(mrb_value)*a1->len);
memcpy(a2->ptr + a1->len, ptr, sizeof(mrb_value)*blen);
a2->len = a1->len + blen;
return ary;
}
@@ -228,12 +283,12 @@ mrb_ary_cmp(mrb_state *mrb, mrb_value ary1)
mrb_value ary2;
struct RArray *a1, *a2;
mrb_value r = mrb_nil_value();
long i, len;
int i, len;
mrb_get_args(mrb, "o", &ary2);
if (mrb_type(ary2) != MRB_TT_ARRAY) return mrb_nil_value();
a1 = RARRAY(ary1); a2 = RARRAY(ary2);
if (a1->len == a2->len && a1->buf == a2->buf) return mrb_fixnum_value(0);
if (a1->len == a2->len && a1->ptr == a2->ptr) return mrb_fixnum_value(0);
else {
len = RARRAY_LEN(ary1);
if (len > RARRAY_LEN(ary2)) {
@@ -248,22 +303,32 @@ mrb_ary_cmp(mrb_state *mrb, mrb_value ary1)
return mrb_fixnum_value((len == 0)? 0: (len > 0)? 1: -1);
}
void
mrb_ary_replace(mrb_state *mrb, struct RArray *a, mrb_value *argv, size_t len)
static void
ary_replace(mrb_state *mrb, struct RArray *a, mrb_value *argv, int len)
{
if (a->capa < len) mrb_ary_expand_capa(mrb, a, len);
memcpy(a->buf, argv, sizeof(mrb_value)*len);
ary_modify(mrb, a);
if (a->aux.capa < len)
ary_expand_capa(mrb, a, len);
memcpy(a->ptr, argv, sizeof(mrb_value)*len);
mrb_write_barrier(mrb, (struct RBasic*)a);
a->len = len;
}
void
mrb_ary_replace(mrb_state *mrb, mrb_value self, mrb_value other)
{
struct RArray *a2 = mrb_ary_ptr(other);
ary_replace(mrb, mrb_ary_ptr(self), a2->ptr, a2->len);
}
mrb_value
mrb_ary_replace_m(mrb_state *mrb, mrb_value self)
{
mrb_value other;
mrb_get_args(mrb, "o", &other);
mrb_ary_replace(mrb, mrb_ary_ptr(self), RARRAY_PTR(other), RARRAY_LEN(other));
mrb_get_args(mrb, "A", &other);
mrb_ary_replace(mrb, self, other);
return self;
}
@@ -274,9 +339,8 @@ mrb_ary_times(mrb_state *mrb, mrb_value self)
struct RArray *a1 = mrb_ary_ptr(self);
struct RArray *a2;
mrb_value ary;
mrb_value *buf;
mrb_value *ptr;
mrb_int times;
//size_t len;
mrb_get_args(mrb, "i", &times);
if (times < 0) {
@@ -286,38 +350,32 @@ mrb_ary_times(mrb_state *mrb, mrb_value self)
ary = mrb_ary_new_capa(mrb, a1->len * times);
a2 = mrb_ary_ptr(ary);
buf = a2->buf;
ptr = a2->ptr;
while(times--) {
memcpy(buf, a1->buf, sizeof(mrb_value)*(a1->len));
buf += a1->len;
memcpy(ptr, a1->ptr, sizeof(mrb_value)*(a1->len));
ptr += a1->len;
a2->len += a1->len;
}
return ary;
}
static void
ary_reverse(struct RArray *a)
{
mrb_value *p1, *p2;
p1 = a->buf;
p2 = a->buf + a->len - 1;
while(p1 < p2) {
mrb_value tmp = *p1;
*p1++ = *p2;
*p2-- = tmp;
}
}
mrb_value
mrb_ary_reverse_bang(mrb_state *mrb, mrb_value self)
{
struct RArray *a = mrb_ary_ptr(self);
if (a->len > 1) {
ary_reverse(a);
mrb_value *p1, *p2;
p1 = a->ptr;
p2 = a->ptr + a->len - 1;
while(p1 < p2) {
mrb_value tmp = *p1;
*p1++ = *p2;
*p2-- = tmp;
}
}
return self;
}
@@ -325,33 +383,41 @@ mrb_ary_reverse_bang(mrb_state *mrb, mrb_value self)
mrb_value
mrb_ary_reverse(mrb_state *mrb, mrb_value self)
{
struct RArray *a = mrb_ary_ptr(self);
struct RArray *a = mrb_ary_ptr(self), *b;
mrb_value ary;
ary = mrb_ary_new_capa(mrb, a->len);
b = mrb_ary_ptr(ary);
if (a->len > 0) {
mrb_ary_replace(mrb, mrb_ary_ptr(ary), a->buf, a->len);
ary_reverse(mrb_ary_ptr(ary));
mrb_value *p1, *p2, *e;
p1 = a->ptr;
e = p1 + a->len;
p2 = b->ptr + a->len - 1;
while(p1 < e) {
*p2-- = *p1++;
}
b->len = a->len;
}
return ary;
}
mrb_value
mrb_ary_new4(mrb_state *mrb, long n, const mrb_value *elts)
mrb_ary_new4(mrb_state *mrb, int n, const mrb_value *elts)
{
mrb_value ary;
ary = mrb_ary_new_capa(mrb, n);//mrb_ary_new2(n);
ary = mrb_ary_new_capa(mrb, n);
if (n > 0 && elts) {
memcpy(RARRAY_PTR(ary), elts, sizeof(mrb_value)*n);
RARRAY_LEN(ary) = n; //ARY_SET_LEN(ary, n);
RARRAY_LEN(ary) = n;
}
return ary;
}
mrb_value
mrb_ary_new_elts(mrb_state *mrb, long n, const mrb_value *elts)
mrb_ary_new_elts(mrb_state *mrb, int n, const mrb_value *elts)
{
return mrb_ary_new4(mrb, n, elts);
}
@@ -361,21 +427,13 @@ mrb_ary_push(mrb_state *mrb, mrb_value ary, mrb_value elem) /* mrb_ary_push */
{
struct RArray *a = mrb_ary_ptr(ary);
if (a->len == a->capa) mrb_ary_expand_capa(mrb, a, a->len + 1);
a->buf[a->len++] = elem;
ary_modify(mrb, a);
if (a->len == a->aux.capa)
ary_expand_capa(mrb, a, a->len + 1);
a->ptr[a->len++] = elem;
mrb_write_barrier(mrb, (struct RBasic*)a);
}
mrb_value
mrb_ary_pop(mrb_state *mrb, mrb_value ary)
{
struct RArray *a = mrb_ary_ptr(ary);
if (a->len == 0) return mrb_nil_value();
return a->buf[--a->len];
}
mrb_value
mrb_ary_push_m(mrb_state *mrb, mrb_value self)
{
@@ -391,30 +449,45 @@ mrb_ary_push_m(mrb_state *mrb, mrb_value self)
}
mrb_value
mrb_ary_pop_m(mrb_state *mrb, mrb_value self)
mrb_ary_pop(mrb_state *mrb, mrb_value ary)
{
struct RArray *a = mrb_ary_ptr(self);
struct RArray *a = mrb_ary_ptr(ary);
return ((a->len == 0)? mrb_nil_value(): mrb_ary_pop(mrb, self));
if (a->len == 0) return mrb_nil_value();
return a->ptr[--a->len];
}
#define ARY_SHIFT_SHARED_MIN 10
mrb_value
mrb_ary_shift(mrb_state *mrb, mrb_value self)
{
struct RArray *a = mrb_ary_ptr(self);
mrb_value *buf = a->buf;
size_t size = a->len;
mrb_value val;
if (size == 0) return mrb_nil_value();
val = *buf;
while((int)(--size)) {
*buf = *(buf+1);
++buf;
if (a->len == 0) return mrb_nil_value();
if (a->flags & MRB_ARY_SHARED) {
L_SHIFT:
val = a->ptr[0];
a->ptr++;
a->len--;
return val;
}
--a->len;
if (a->len > ARY_SHIFT_SHARED_MIN) {
ary_make_shared(mrb, a);
goto L_SHIFT;
}
else {
mrb_value *ptr = a->ptr;
int size = a->len;
val = *ptr;
while((int)(--size)) {
*ptr = *(ptr+1);
++ptr;
}
--a->len;
}
return val;
}
@@ -427,10 +500,20 @@ mrb_ary_unshift(mrb_state *mrb, mrb_value self, mrb_value item)
{
struct RArray *a = mrb_ary_ptr(self);
if (a->capa < a->len + 1) mrb_ary_expand_capa(mrb, a, a->len + 1);
memmove(a->buf + 1, a->buf, sizeof(mrb_value)*a->len);
memcpy(a->buf, &item, sizeof(mrb_value));
a->len += 1;
if ((a->flags & MRB_ARY_SHARED)
&& a->aux.shared->refcnt == 1 /* shared only referenced from this array */
&& a->ptr - a->aux.shared->ptr >= 1) /* there's room for unshifted item */ {
a->ptr--;
a->ptr[0] = item;
}
else {
ary_modify(mrb, a);
if (a->aux.capa < a->len + 1)
ary_expand_capa(mrb, a, a->len + 1);
memmove(a->ptr + 1, a->ptr, sizeof(mrb_value)*a->len);
a->ptr[0] = item;
}
a->len++;
mrb_write_barrier(mrb, (struct RBasic*)a);
return self;
@@ -444,10 +527,19 @@ mrb_ary_unshift_m(mrb_state *mrb, mrb_value self)
int len;
mrb_get_args(mrb, "*", &vals, &len);
if (len == 0) return self;
if (a->capa < a->len + len) mrb_ary_expand_capa(mrb, a, a->len + len);
memmove(a->buf + len, a->buf, sizeof(mrb_value)*a->len);
memcpy(a->buf, vals, sizeof(mrb_value)*len);
if ((a->flags & MRB_ARY_SHARED)
&& a->aux.shared->refcnt == 1 /* shared only referenced from this array */
&& a->ptr - a->aux.shared->ptr >= len) /* there's room for unshifted item */ {
a->ptr -= len;
}
else {
ary_modify(mrb, a);
if (len == 0) return self;
if (a->aux.capa < a->len + len)
ary_expand_capa(mrb, a, a->len + len);
memmove(a->ptr + len, a->ptr, sizeof(mrb_value)*a->len);
}
memcpy(a->ptr, vals, sizeof(mrb_value)*len);
a->len += len;
mrb_write_barrier(mrb, (struct RBasic*)a);
@@ -461,9 +553,9 @@ mrb_ary_ref(mrb_state *mrb, mrb_value ary, mrb_int n)
/* range check */
if (n < 0) n += a->len;
if (n < 0 || a->len <= (size_t)n) return mrb_nil_value();
if (n < 0 || a->len <= (int)n) return mrb_nil_value();
return a->buf[n];
return a->ptr[n];
}
void
@@ -471,18 +563,22 @@ mrb_ary_set(mrb_state *mrb, mrb_value ary, mrb_int n, mrb_value val) /* rb_ary_s
{
struct RArray *a = mrb_ary_ptr(ary);
ary_modify(mrb, a);
/* range check */
if (n < 0) n += a->len;
if (n < 0) {
mrb_raise(mrb, E_INDEX_ERROR, "index %ld out of array", n - a->len);
n += a->len;
if (n < 0) {
mrb_raise(mrb, E_INDEX_ERROR, "index %ld out of array", n - a->len);
}
}
if (a->len <= (size_t)n) {
if (a->capa <= (size_t)n) mrb_ary_expand_capa(mrb, a, n + 1);
ary_fill_with_nil(a->buf + a->len, n + 1 - a->len);
if (a->len <= (int)n) {
if (a->aux.capa <= (int)n)
ary_expand_capa(mrb, a, n + 1);
ary_fill_with_nil(a->ptr + a->len, n + 1 - a->len);
a->len = n + 1;
}
a->buf[n] = val;
a->ptr[n] = val;
mrb_write_barrier(mrb, (struct RBasic*)a);
}
@@ -491,14 +587,17 @@ mrb_ary_splice(mrb_state *mrb, mrb_value ary, mrb_int head, mrb_int len, mrb_val
{
struct RArray *a = mrb_ary_ptr(ary);
mrb_int tail;
size_t size;
int size;
mrb_value *argv;
int i, argc;
ary_modify(mrb, a);
/* range check */
if (head < 0) head += a->len;
if (head < 0) {
mrb_raise(mrb, E_INDEX_ERROR, "index is out of array");
head += a->len;
if (head < 0) {
mrb_raise(mrb, E_INDEX_ERROR, "index is out of array");
}
}
tail = head + len;
@@ -515,17 +614,18 @@ mrb_ary_splice(mrb_state *mrb, mrb_value ary, mrb_int head, mrb_int len, mrb_val
if (tail < a->len) size += a->len - tail;
if (size > a->capa) mrb_ary_expand_capa(mrb, a, size);
if (size > a->aux.capa)
ary_expand_capa(mrb, a, size);
if (head > a->len) {
ary_fill_with_nil(a->buf + a->len, (size_t)(head - a->len));
ary_fill_with_nil(a->ptr + a->len, (int)(head - a->len));
}
else if (head < a->len) {
memmove(a->buf + head + argc, a->buf + tail, sizeof(mrb_value)*(a->len - tail));
memmove(a->ptr + head + argc, a->ptr + tail, sizeof(mrb_value)*(a->len - tail));
}
for(i = 0; i < argc; i++) {
*(a->buf + head + i) = *(argv + i);
*(a->ptr + head + i) = *(argv + i);
}
a->len = size;
@@ -539,6 +639,32 @@ mrb_ary_alen(mrb_state *mrb, mrb_value ary)
return RARRAY_LEN(ary);
}
void
mrb_ary_decref(mrb_state *mrb, struct mrb_shared_array *shared)
{
shared->refcnt--;
if (shared->refcnt == 0) {
mrb_free(mrb, shared->ptr);
mrb_free(mrb, shared);
}
}
static mrb_value
ary_subseq(mrb_state *mrb, struct RArray *a, int beg, int len)
{
struct RArray *b;
ary_make_shared(mrb, a);
b = (struct RArray*)mrb_obj_alloc(mrb, MRB_TT_ARRAY, mrb->array_class);
b->ptr = a->ptr + beg;
b->len = len;
b->aux.shared = a->aux.shared;
b->aux.shared->refcnt++;
b->flags |= MRB_ARY_SHARED;
return mrb_obj_value(b);
}
mrb_value
mrb_ary_aget(mrb_state *mrb, mrb_value self)
{
@@ -556,13 +682,13 @@ mrb_ary_aget(mrb_state *mrb, mrb_value self)
if (mrb_type(argv[0]) != MRB_TT_FIXNUM) {
mrb_raise(mrb, E_TYPE_ERROR, "expected Fixnum");
}
len = mrb_fixnum(argv[0]);
if (index < 0) index += a->len;
if (index < 0 || a->len < (size_t)index) return mrb_nil_value();
if ((len = mrb_fixnum(argv[0])) < 0) return mrb_nil_value();
if (a->len == (size_t)index) return mrb_ary_new(mrb);
if ((size_t)len > a->len - index) len = a->len - index;
return mrb_ary_new_from_values(mrb, len, a->buf + index);
if (index < 0 || a->len < (int)index) return mrb_nil_value();
len = mrb_fixnum(argv[0]);
if (len < 0) return mrb_nil_value();
if (a->len == (int)index) return mrb_ary_new(mrb);
if ((int)len > a->len - index) len = a->len - index;
return ary_subseq(mrb, a, index, len);
default:
mrb_raise(mrb, E_ARGUMENT_ERROR, "wrong number of arguments");
@@ -606,24 +732,25 @@ mrb_ary_delete_at(mrb_state *mrb, mrb_value self)
struct RArray *a = mrb_ary_ptr(self);
mrb_int index;
mrb_value val;
mrb_value *buf;
size_t len;
mrb_value *ptr;
int len;
mrb_get_args(mrb, "i", &index);
if (index < 0) index += a->len;
if (index < 0 || a->len <= (size_t)index) return mrb_nil_value();
if (index < 0 || a->len <= (int)index) return mrb_nil_value();
val = a->buf[index];
ary_modify(mrb, a);
val = a->ptr[index];
buf = a->buf + index;
ptr = a->ptr + index;
len = a->len - index;
while((int)(--len)) {
*buf = *(buf+1);
++buf;
*ptr = *(ptr+1);
++ptr;
}
--a->len;
mrb_ary_shrink_capa(mrb, a);
ary_shrink_capa(mrb, a);
return val;
}
@@ -632,30 +759,27 @@ mrb_value
mrb_ary_first(mrb_state *mrb, mrb_value self)
{
struct RArray *a = mrb_ary_ptr(self);
//mrb_value ary;
size_t size;
mrb_value *vals;
int len;
int size;
mrb_get_args(mrb, "*", &vals, &len);
if (len > 1) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "wrong number of arguments");
if (mrb_get_args(mrb, "|i", &size) == 0) {
return (a->len > 0)? a->ptr[0]: mrb_nil_value();
}
if (size < 0) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "negative array size");
}
if (len == 0) return (a->len > 0)? a->buf[0]: mrb_nil_value();
/* len == 1 */
size = mrb_fixnum(*vals);
if (size > a->len) size = a->len;
return mrb_ary_new_from_values(mrb, size, a->buf);
if (a->flags & MRB_ARY_SHARED) {
return ary_subseq(mrb, a, 0, size);
}
return mrb_ary_new_from_values(mrb, size, a->ptr);
}
mrb_value
mrb_ary_last(mrb_state *mrb, mrb_value self)
{
struct RArray *a = mrb_ary_ptr(self);
//mrb_value ary;
size_t size;
int size;
mrb_value *vals;
int len;
@@ -664,19 +788,25 @@ mrb_ary_last(mrb_state *mrb, mrb_value self)
mrb_raise(mrb, E_ARGUMENT_ERROR, "wrong number of arguments");
}
if (len == 0) return (a->len > 0)? a->buf[a->len - 1]: mrb_nil_value();
if (len == 0) return (a->len > 0)? a->ptr[a->len - 1]: mrb_nil_value();
/* len == 1 */
size = mrb_fixnum(*vals);
if (size < 0) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "negative array size");
}
if (size > a->len) size = a->len;
return mrb_ary_new_from_values(mrb, size, a->buf + a->len - size);
if ((a->flags & MRB_ARY_SHARED) || size > ARY_DEFAULT_LEN) {
return ary_subseq(mrb, a, a->len - size, size);
}
return mrb_ary_new_from_values(mrb, size, a->ptr + a->len - size);
}
mrb_value
mrb_ary_index_m(mrb_state *mrb, mrb_value self)
{
mrb_value obj;
long i;
int i;
mrb_get_args(mrb, "o", &obj);
for (i = 0; i < RARRAY_LEN(self); i++) {
@@ -691,7 +821,7 @@ mrb_value
mrb_ary_rindex_m(mrb_state *mrb, mrb_value self)
{
mrb_value obj;
long i;
int i;
mrb_get_args(mrb, "o", &obj);
for (i = RARRAY_LEN(self) - 1; i >= 0; i--) {
@@ -727,7 +857,8 @@ mrb_ary_clear(mrb_state *mrb, mrb_value self)
struct RArray *a = mrb_ary_ptr(self);
a->len = 0;
mrb_ary_shrink_capa(mrb, a);
ary_modify(mrb, a);
ary_shrink_capa(mrb, a);
return self;
}
@@ -747,7 +878,7 @@ mrb_check_array_type(mrb_state *mrb, mrb_value ary)
}
mrb_value
mrb_ary_entry(mrb_value ary, long offset)
mrb_ary_entry(mrb_value ary, int offset)
{
if (offset < 0) {
offset += RARRAY_LEN(ary);
@@ -755,58 +886,43 @@ mrb_ary_entry(mrb_value ary, long offset)
return ary_elt(ary, offset);
}
void
mrb_mem_clear(mrb_value *mem, long size)
{
while (size--) {
*mem++ = mrb_nil_value();
}
}
mrb_value
mrb_ary_tmp_new(mrb_state *mrb, long capa)
{
return mrb_ary_new_capa(mrb, capa);//ary_new(0, capa);
}
static mrb_value
inspect_ary(mrb_state *mrb, mrb_value ary, mrb_value list)
{
long i;
int i;
mrb_value s, arystr;
char *head = "[";
char *sep = ", ";
char *tail = "]";
char head[] = { '[' };
char sep[] = { ',', ' ' };
char tail[] = { ']' };
/* check recursive */
for(i=0; i<RARRAY_LEN(list); i++) {
if (mrb_obj_equal(mrb, ary, RARRAY_PTR(list)[i])) {
return mrb_str_new2(mrb, "[...]");
return mrb_str_new(mrb, "[...]", 5);
}
}
mrb_ary_push(mrb, list, ary);
arystr = mrb_str_buf_new(mrb, 64);
mrb_str_buf_cat(mrb, arystr, head, strlen(head));
mrb_str_buf_cat(mrb, arystr, head, sizeof(head));
for(i=0; i<RARRAY_LEN(ary); i++) {
int ai = mrb_gc_arena_save(mrb);
if (i > 0) {
mrb_str_buf_cat(mrb, arystr, sep, strlen(sep));
mrb_str_buf_cat(mrb, arystr, sep, sizeof(sep));
}
if (mrb_type(RARRAY_PTR(ary)[i]) == MRB_TT_ARRAY) {
s = inspect_ary(mrb, RARRAY_PTR(ary)[i], list);
} else {
s = mrb_inspect(mrb, RARRAY_PTR(ary)[i]);
}
//mrb_str_buf_append(mrb, arystr, s);
mrb_str_buf_cat(mrb, arystr, RSTRING_PTR(s), RSTRING_LEN(s));
mrb_gc_arena_restore(mrb, ai);
}
mrb_str_buf_cat(mrb, arystr, tail, strlen(tail));
mrb_str_buf_cat(mrb, arystr, tail, sizeof(tail));
mrb_ary_pop(mrb, list);
return arystr;
@@ -824,7 +940,7 @@ inspect_ary(mrb_state *mrb, mrb_value ary, mrb_value list)
static mrb_value
mrb_ary_inspect(mrb_state *mrb, mrb_value ary)
{
if (RARRAY_LEN(ary) == 0) return mrb_str_new2(mrb, "[]");
if (RARRAY_LEN(ary) == 0) return mrb_str_new(mrb, "[]", 2);
#if 0 /* THREAD */
return mrb_exec_recursive(inspect_ary_r, ary, 0);
#else
@@ -835,7 +951,7 @@ mrb_ary_inspect(mrb_state *mrb, mrb_value ary)
static mrb_value
join_ary(mrb_state *mrb, mrb_value ary, mrb_value sep, mrb_value list)
{
long i;
int i;
mrb_value result, val, tmp;
/* check recursive */
@@ -851,7 +967,6 @@ join_ary(mrb_state *mrb, mrb_value ary, mrb_value sep, mrb_value list)
for(i=0; i<RARRAY_LEN(ary); i++) {
if (i > 0 && !mrb_nil_p(sep)) {
//mrb_str_buf_append(mrb, result, sep); // segv (encoding error?)
mrb_str_buf_cat(mrb, result, RSTRING_PTR(sep), RSTRING_LEN(sep));
}
@@ -864,7 +979,6 @@ join_ary(mrb_state *mrb, mrb_value ary, mrb_value sep, mrb_value list)
case MRB_TT_STRING:
str_join:
//mrb_str_buf_append(mrb, result, val);
mrb_str_buf_cat(mrb, result, RSTRING_PTR(val), RSTRING_LEN(val));
break;
@@ -898,7 +1012,7 @@ mrb_ary_join(mrb_state *mrb, mrb_value ary, mrb_value sep)
/*
* call-seq:
* ary.join(sep=nil) -> str
* ary.join(sep="") -> str
*
* Returns a string created by converting each element of the array to
* a string, separated by <i>sep</i>.
@@ -912,7 +1026,7 @@ mrb_ary_join_m(mrb_state *mrb, mrb_value ary)
{
mrb_value sep = mrb_nil_value();
mrb_get_args(mrb, "|o", &sep);
mrb_get_args(mrb, "|S", &sep);
return mrb_ary_join(mrb, ary, sep);
}
@@ -951,7 +1065,7 @@ mrb_ary_equal(mrb_state *mrb, mrb_value ary1)
}
if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) return mrb_false_value();
else {
long i;
int i;
for (i=0; i<RARRAY_LEN(ary1); i++) {
if (!mrb_equal(mrb, ary_elt(ary1, i), ary_elt(ary2, i)))
@@ -980,7 +1094,7 @@ mrb_ary_eql(mrb_state *mrb, mrb_value ary1)
if (mrb_type(ary2) != MRB_TT_ARRAY) return mrb_false_value();
if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) return mrb_false_value();
else {
long i;
int i;
for (i=0; i<RARRAY_LEN(ary1); i++) {
if (!mrb_eql(mrb, ary_elt(ary1, i), ary_elt(ary2, i)))
@@ -1010,13 +1124,13 @@ mrb_init_array(mrb_state *mrb)
mrb_define_method(mrb, a, "concat", mrb_ary_concat_m, ARGS_REQ(1)); /* 15.2.12.5.8 */
mrb_define_method(mrb, a, "delete_at", mrb_ary_delete_at, ARGS_REQ(1)); /* 15.2.12.5.9 */
mrb_define_method(mrb, a, "empty?", mrb_ary_empty_p, ARGS_NONE()); /* 15.2.12.5.12 */
mrb_define_method(mrb, a, "first", mrb_ary_first, ARGS_ANY()); /* 15.2.12.5.13 */
mrb_define_method(mrb, a, "first", mrb_ary_first, ARGS_OPT(1)); /* 15.2.12.5.13 */
mrb_define_method(mrb, a, "index", mrb_ary_index_m, ARGS_REQ(1)); /* 15.2.12.5.14 */
mrb_define_method(mrb, a, "initialize_copy", mrb_ary_replace_m, ARGS_REQ(1)); /* 15.2.12.5.16 */
mrb_define_method(mrb, a, "join", mrb_ary_join_m, ARGS_ANY()); /* 15.2.12.5.17 */
mrb_define_method(mrb, a, "last", mrb_ary_last, ARGS_ANY()); /* 15.2.12.5.18 */
mrb_define_method(mrb, a, "length", mrb_ary_size, ARGS_NONE()); /* 15.2.12.5.19 */
mrb_define_method(mrb, a, "pop", mrb_ary_pop_m, ARGS_NONE()); /* 15.2.12.5.21 */
mrb_define_method(mrb, a, "pop", mrb_ary_pop, ARGS_NONE()); /* 15.2.12.5.21 */
mrb_define_method(mrb, a, "push", mrb_ary_push_m, ARGS_ANY()); /* 15.2.12.5.22 */
mrb_define_method(mrb, a, "replace", mrb_ary_replace_m, ARGS_REQ(1)); /* 15.2.12.5.23 */
mrb_define_method(mrb, a, "reverse", mrb_ary_reverse, ARGS_NONE()); /* 15.2.12.5.24 */
@@ -1031,5 +1145,5 @@ mrb_init_array(mrb_state *mrb)
mrb_define_alias(mrb, a, "to_s", "inspect"); /* 15.2.12.5.32 (x) */
mrb_define_method(mrb, a, "==", mrb_ary_equal, ARGS_REQ(1)); /* 15.2.12.5.33 (x) */
mrb_define_method(mrb, a, "eql?", mrb_ary_eql, ARGS_REQ(1)); /* 15.2.12.5.34 (x) */
mrb_define_method(mrb, a, "<=>", mrb_ary_cmp, ARGS_REQ(1)); /* 15.2.12.5.36 (x) */
mrb_define_method(mrb, a, "<=>", mrb_ary_cmp, ARGS_REQ(1)); /* 15.2.12.5.36 (x) */
}
+27 -24
View File
@@ -10,7 +10,6 @@
#include "mruby/irep.h"
#include "mruby/string.h"
#include "re.h"
#define MRB_CDUMP_LINE_LEN 128
@@ -45,7 +44,7 @@ str_format_len(mrb_value str)
char *src;
for (src = RSTRING_PTR(str); src < RSTRING_END(str);) {
for (src = RSTRING_PTR(str); src < RSTRING_END(str); src++) {
switch (*src) {
case 0x07:/* BEL */ /* fall through */
case 0x08:/* BS */ /* fall through */
@@ -58,11 +57,11 @@ str_format_len(mrb_value str)
case 0x27:/* ' */ /* fall through */
case 0x3F:/* ? */ /* fall through */
case 0x5C:/* \ */ /* fall through */
dump_len += 2; src += 2;
dump_len += 2;
break;
default:
dump_len++; src++;
dump_len++;
break;
}
}
@@ -73,22 +72,23 @@ str_format_len(mrb_value str)
static char*
str_to_format(mrb_value str, char *buf)
{
char *src, *dst;
char *src;
char *dst;
for (src = RSTRING_PTR(str), dst = buf; src < RSTRING_END(str);) {
for (src = RSTRING_PTR(str), dst = buf; src < RSTRING_END(str); src++) {
switch (*src) {
case 0x07:/* BEL */ memcpy(dst, "\\a", 2); dst+=2; src+=2; break;
case 0x08:/* BS */ memcpy(dst, "\\b", 2); dst+=2; src+=2; break;
case 0x09:/* HT */ memcpy(dst, "\\t", 2); dst+=2; src+=2; break;
case 0x0A:/* LF */ memcpy(dst, "\\n", 2); dst+=2; src+=2; break;
case 0x0B:/* VT */ memcpy(dst, "\\v", 2); dst+=2; src+=2; break;
case 0x0C:/* FF */ memcpy(dst, "\\f", 2); dst+=2; src+=2; break;
case 0x0D:/* CR */ memcpy(dst, "\\r", 2); dst+=2; src+=2; break;
case 0x22:/* " */ memcpy(dst, "\\\"", 2); dst+=2; src+=2; break;
case 0x27:/* ' */ memcpy(dst, "\\\'", 2); dst+=2; src+=2; break;
case 0x3F:/* ? */ memcpy(dst, "\\\?", 2); dst+=2; src+=2; break;
case 0x5C:/* \ */ memcpy(dst, "\\\\", 2); dst+=2; src+=2; break;
default: *dst++ = *src++; break;
case 0x07:/* BEL */ *dst++ = '\\'; *dst++ = 'a'; break;
case 0x08:/* BS */ *dst++ = '\\'; *dst++ = 'b'; break;
case 0x09:/* HT */ *dst++ = '\\'; *dst++ = 't'; break;
case 0x0A:/* LF */ *dst++ = '\\'; *dst++ = 'n'; break;
case 0x0B:/* VT */ *dst++ = '\\'; *dst++ = 'v'; break;
case 0x0C:/* FF */ *dst++ = '\\'; *dst++ = 'f'; break;
case 0x0D:/* CR */ *dst++ = '\\'; *dst++ = 'r'; break;
case 0x22:/* " */ *dst++ = '\\'; *dst++ = '\"'; break;
case 0x27:/* ' */ *dst++ = '\\'; *dst++ = '\''; break;
case 0x3F:/* ? */ *dst++ = '\\'; *dst++ = '\?'; break;
case 0x5C:/* \ */ *dst++ = '\\'; *dst++ = '\\'; break;
default: *dst++ = *src; break;
}
}
@@ -107,10 +107,11 @@ make_cdump_irep(mrb_state *mrb, int irep_no, FILE *f)
return -1;
buf_len = MRB_CDUMP_LINE_LEN;
if ((buf = mrb_malloc(mrb, buf_len)) == 0 ) {
if ((buf = (char *)mrb_malloc(mrb, buf_len)) == 0 ) {
return MRB_CDUMP_GENERAL_FAILURE;
}
SOURCE_CODE0 (" ai = mrb->arena_idx;");
SOURCE_CODE0 (" irep = mrb->irep[idx] = mrb_malloc(mrb, sizeof(mrb_irep));");
SOURCE_CODE0 (" irep->idx = idx++;");
SOURCE_CODE (" irep->flags = %d | MRB_ISEQ_NOFREE;", irep->flags);
@@ -137,11 +138,13 @@ make_cdump_irep(mrb_state *mrb, int irep_no, FILE *f)
switch (irep->pool[n].tt) {
case MRB_TT_FLOAT:
SOURCE_CODE(" irep->pool[%d] = mrb_float_value(%.16e);", n, irep->pool[n].value.f); break;
case MRB_TT_STRING:
case MRB_TT_FIXNUM:
SOURCE_CODE(" irep->pool[%d] = mrb_fixnum_value(%d);", n, irep->pool[n].value.i); break;
case MRB_TT_STRING:
str_len = str_format_len(irep->pool[n]) + 1;
if ( str_len > buf_len ) {
buf_len = str_len;
if ((buf = mrb_realloc(mrb, buf, buf_len)) == 0 ) {
if ((buf = (char *)mrb_realloc(mrb, buf, buf_len)) == 0 ) {
return MRB_CDUMP_GENERAL_FAILURE;
}
}
@@ -154,6 +157,8 @@ make_cdump_irep(mrb_state *mrb, int irep_no, FILE *f)
}
else
SOURCE_CODE0 (" irep->pool = NULL;");
SOURCE_CODE0 (" mrb->irep_len = idx;");
SOURCE_CODE0 (" mrb->arena_idx = ai;");
SOURCE_CODE0("");
return MRB_CDUMP_OK;
}
@@ -184,6 +189,7 @@ mrb_cdump_irep(mrb_state *mrb, int n, FILE *f,const char *initname)
SOURCE_CODE0("{");
SOURCE_CODE0(" int n = mrb->irep_len;");
SOURCE_CODE0(" int idx = n;");
SOURCE_CODE0(" int ai;");
SOURCE_CODE0(" mrb_irep *irep;");
SOURCE_CODE0("");
SOURCE_CODE (" mrb_add_irep(mrb, idx+%d);", irep_num);
@@ -193,9 +199,6 @@ mrb_cdump_irep(mrb_state *mrb, int n, FILE *f,const char *initname)
return -1;
}
SOURCE_CODE0(" mrb->irep_len = idx;");
SOURCE_CODE0("");
SOURCE_CODE0(" extern mrb_value mrb_top_self(mrb_state *mrb);");
SOURCE_CODE0(" mrb_run(mrb, mrb_proc_new(mrb, mrb->irep[n]), mrb_top_self(mrb));");
SOURCE_CODE0("}");
+408 -154
View File
@@ -15,10 +15,8 @@
#include "mruby/array.h"
#include "error.h"
#include "mruby/khash.h"
KHASH_MAP_INIT_INT(mt, struct RProc*);
KHASH_MAP_INIT_INT(iv, mrb_value);
KHASH_DEFINE(iv, mrb_sym, mrb_value, 1, kh_int_hash_func, kh_int_hash_equal);
KHASH_DEFINE(mt, mrb_sym, struct RProc*, 1, kh_int_hash_func, kh_int_hash_equal);
typedef struct fc_result {
mrb_sym name;
@@ -28,9 +26,6 @@ typedef struct fc_result {
struct fc_result *prev;
} fcresult_t;
int kiv_lookup(khash_t(iv) *table, mrb_sym key, mrb_value *value);
extern struct kh_iv *mrb_class_tbl;
void
mrb_gc_mark_mt(mrb_state *mrb, struct RClass *c)
{
@@ -42,7 +37,7 @@ mrb_gc_mark_mt(mrb_state *mrb, struct RClass *c)
if (kh_exist(h, k)){
struct RProc *m = kh_value(h, k);
if (m) {
paint_black(m);
mrb_gc_mark(mrb, (struct RBasic*)m);
}
}
}
@@ -120,7 +115,6 @@ mrb_define_module_id(mrb_state *mrb, mrb_sym name)
{
struct RClass *m = mrb_module_new(mrb);
m->mt = kh_init(mt, mrb);
mrb_obj_iv_set(mrb, (struct RObject*)mrb->object_class,
name, mrb_obj_value(m));
mrb_name_class(mrb, m, name);
@@ -193,34 +187,60 @@ mrb_define_class(mrb_state *mrb, const char *name, struct RClass *super)
struct RClass*
mrb_vm_define_class(mrb_state *mrb, mrb_value outer, mrb_value super, mrb_sym id)
{
struct RClass *c = 0;
struct RClass *c, *s;
if (mrb_const_defined(mrb, outer, id)) {
mrb_value v = mrb_const_get(mrb, outer, id);
mrb_check_type(mrb, v, MRB_TT_CLASS);
c = mrb_class_ptr(v);
if (!mrb_nil_p(super) && (c->tt != MRB_TT_CLASS || c->super != mrb_class_ptr(super))) {
c = 0;
}
}
if (!c) {
struct RClass *s = 0;
if (!mrb_nil_p(super)) {
mrb_check_type(mrb, super, MRB_TT_CLASS);
s = mrb_class_ptr(super);
if (mrb_type(super) != MRB_TT_CLASS) {
mrb_raise(mrb, E_TYPE_ERROR, "superclass must be a Class (%s given)", mrb_obj_classname(mrb, super));
}
if (!c->super || mrb_class_ptr(super) != mrb_class_real(c->super)) {
mrb_raise(mrb, E_TYPE_ERROR, "superclass mismatch for class %s", mrb_sym2name(mrb, id));
}
}
if (!s) {
s = mrb->object_class;
}
c = mrb_class_new(mrb, s);
setup_class(mrb, outer, c, id);
mrb_funcall(mrb, mrb_obj_value(s), "inherited", 1, mrb_obj_value(c));
return c;
}
if (!mrb_nil_p(super)) {
if (mrb_type(super) != MRB_TT_CLASS) {
mrb_raise(mrb, E_TYPE_ERROR, "superclass must be a Class (%s given)", mrb_obj_classname(mrb, super));
}
s = mrb_class_ptr(super);
}
else {
s = mrb->object_class;
}
c = mrb_class_new(mrb, s);
setup_class(mrb, outer, c, id);
mrb_funcall(mrb, mrb_obj_value(s), "inherited", 1, mrb_obj_value(c));
return c;
}
static struct RClass *
class_from_sym(mrb_state *mrb, struct RClass *klass, mrb_sym id)
{
mrb_value c = mrb_const_get(mrb, mrb_obj_value(klass), id);
if (c.tt != MRB_TT_MODULE && c.tt != MRB_TT_CLASS) {
mrb_raise(mrb, E_TYPE_ERROR, "%s is not a class/module", mrb_sym2name(mrb, id));
}
return mrb_class_ptr(c);
}
struct RClass *
mrb_class_get(mrb_state *mrb, const char *name)
{
return class_from_sym(mrb, mrb->object_class, mrb_intern(mrb, name));
}
/*!
* Defines a class under the namespace of \a outer.
* \param outer a class which contains the new class.
@@ -244,10 +264,7 @@ mrb_define_class_under(mrb_state *mrb, struct RClass *outer, const char *name, s
mrb_sym id = mrb_intern(mrb, name);
if (mrb_const_defined_at(mrb, outer, id)) {
c = mrb_class_from_sym(mrb, outer, id);
if (c->tt != MRB_TT_CLASS) {
mrb_raise(mrb, E_TYPE_ERROR, "%s is not a class", mrb_sym2name(mrb, id));
}
c = class_from_sym(mrb, outer, id);
if (mrb_class_real(c->super) != super) {
mrb_name_error(mrb, id, "%s is already defined", mrb_sym2name(mrb, id));
}
@@ -259,7 +276,6 @@ mrb_define_class_under(mrb_state *mrb, struct RClass *outer, const char *name, s
}
c = mrb_class_new(mrb, super);
setup_class(mrb, mrb_obj_value(outer), c, id);
mrb_const_set(mrb, mrb_obj_value(outer), id, mrb_obj_value(c));
return c;
}
@@ -271,15 +287,11 @@ mrb_define_module_under(mrb_state *mrb, struct RClass *outer, const char *name)
mrb_sym id = mrb_intern(mrb, name);
if (mrb_const_defined_at(mrb, outer, id)) {
c = mrb_class_from_sym(mrb, outer, id);
if (c->tt != MRB_TT_MODULE) {
mrb_raise(mrb, E_TYPE_ERROR, "%s is not a module", mrb_sym2name(mrb, id));
}
c = class_from_sym(mrb, outer, id);
return c;
}
c = mrb_module_new(mrb);
setup_class(mrb, mrb_obj_value(outer), c, id);
mrb_const_set(mrb, mrb_obj_value(outer), id, mrb_obj_value(c));
return c;
}
@@ -316,10 +328,12 @@ mrb_define_method_vm(mrb_state *mrb, struct RClass *c, mrb_sym name, mrb_value b
{
khash_t(mt) *h = c->mt;
khiter_t k;
struct RProc *p;
if (!h) h = c->mt = kh_init(mt, mrb);
k = kh_put(mt, h, name);
kh_value(h, k) = mrb_proc_ptr(body);
p = mrb_proc_ptr(body);
kh_value(h, k) = p;
}
static mrb_value
@@ -370,6 +384,7 @@ to_hash(mrb_state *mrb, mrb_value val)
a: Array [mrb_value*,int]
f: Float [mrb_float]
i: Integer [mrb_int]
n: Symbol [mrb_sym]
&: Block [mrb_value]
*: rest argument [mrb_value*,int]
|: optional
@@ -389,15 +404,14 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
struct RArray *a = mrb_ary_ptr(mrb->stack[1]);
argc = a->len;
sp = a->buf;
sp = a->ptr;
}
while ((c = *format++)) {
switch (c) {
case '|': case '*': case '&':
break;
default:
if (argc <= i) {
if (opt) continue;
if (argc <= i && !opt) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "wrong number of arguments");
}
}
@@ -408,8 +422,10 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
mrb_value *p;
p = va_arg(ap, mrb_value*);
*p = *sp;
i++; sp++;
if (i < argc) {
*p = *sp++;
i++;
}
}
break;
case 'S':
@@ -417,8 +433,10 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
mrb_value *p;
p = va_arg(ap, mrb_value*);
*p = to_str(mrb, *sp);
i++; sp++;
if (i < argc) {
*p = to_str(mrb, *sp++);
i++;
}
}
break;
case 'A':
@@ -426,8 +444,10 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
mrb_value *p;
p = va_arg(ap, mrb_value*);
*p = to_ary(mrb, *sp);
i++; sp++;
if (i < argc) {
*p = to_ary(mrb, *sp++);
i++;
}
}
break;
case 'H':
@@ -435,8 +455,10 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
mrb_value *p;
p = va_arg(ap, mrb_value*);
*p = to_hash(mrb, *sp);
i++; sp++;
if (i < argc) {
*p = to_hash(mrb, *sp++);
i++;
}
}
break;
case 's':
@@ -446,13 +468,15 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
char **ps = 0;
int *pl = 0;
ss = to_str(mrb, *sp);
s = mrb_str_ptr(ss);
ps = va_arg(ap, char**);
*ps = s->buf;
pl = va_arg(ap, int*);
*pl = s->len;
i++; sp++;
if (i < argc) {
ss = to_str(mrb, *sp++);
s = mrb_str_ptr(ss);
*ps = s->ptr;
*pl = s->len;
i++;
}
}
break;
case 'z':
@@ -461,14 +485,16 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
struct RString *s;
char **ps;
ss = to_str(mrb, *sp);
s = mrb_str_ptr(ss);
if (strlen(s->buf) != s->len) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "String contains NUL");
}
ps = va_arg(ap, char**);
*ps = s->buf;
i++; sp++;
if (i < argc) {
ss = to_str(mrb, *sp++);
s = mrb_str_ptr(ss);
if (strlen(s->ptr) != s->len) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "String contains NUL");
}
*ps = s->ptr;
i++;
}
}
break;
case 'a':
@@ -478,13 +504,15 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
mrb_value **pb;
int *pl;
aa = to_ary(mrb, *sp);
a = mrb_ary_ptr(aa);
pb = va_arg(ap, mrb_value**);
*pb = a->buf;
pl = va_arg(ap, int*);
*pl = a->len;
i++; sp++;
if (i < argc) {
aa = to_ary(mrb, *sp++);
a = mrb_ary_ptr(aa);
*pb = a->ptr;
*pl = a->len;
i++;
}
}
break;
case 'f':
@@ -492,26 +520,29 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
mrb_float *p;
p = va_arg(ap, mrb_float*);
switch (sp->tt) {
case MRB_TT_FLOAT:
*p = mrb_float(*sp);
break;
case MRB_TT_FIXNUM:
*p = (mrb_float)mrb_fixnum(*sp);
break;
case MRB_TT_FALSE:
*p = 0.0;
break;
default:
{
mrb_value tmp;
if (i < argc) {
switch (sp->tt) {
case MRB_TT_FLOAT:
*p = mrb_float(*sp);
break;
case MRB_TT_FIXNUM:
*p = (mrb_float)mrb_fixnum(*sp);
break;
case MRB_TT_FALSE:
*p = 0.0;
break;
default:
{
mrb_value tmp;
tmp = mrb_convert_type(mrb, *sp, MRB_TT_FLOAT, "Float", "to_f");
*p = mrb_float(tmp);
tmp = mrb_convert_type(mrb, *sp, MRB_TT_FLOAT, "Float", "to_f");
*p = mrb_float(tmp);
}
break;
}
break;
}
i++; sp++;
sp++;
i++;
}
}
break;
case 'i':
@@ -519,37 +550,69 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
mrb_int *p;
p = va_arg(ap, mrb_int*);
switch (sp->tt) {
case MRB_TT_FIXNUM:
*p = mrb_fixnum(*sp);
break;
case MRB_TT_FLOAT:
*p = (mrb_int)mrb_float(*sp);
break;
case MRB_TT_FALSE:
*p = 0;
break;
default:
{
mrb_value tmp;
if (i < argc) {
switch (sp->tt) {
case MRB_TT_FIXNUM:
*p = mrb_fixnum(*sp);
break;
case MRB_TT_FLOAT:
{
mrb_float f = mrb_float(*sp);
tmp = mrb_convert_type(mrb, *sp, MRB_TT_FIXNUM, "Integer", "to_int");
*p = mrb_fixnum(tmp);
if (!FIXABLE(f)) {
mrb_raise(mrb, E_RANGE_ERROR, "float too big for int");
}
*p = (mrb_int)f;
}
break;
case MRB_TT_FALSE:
*p = 0;
break;
default:
{
mrb_value tmp;
tmp = mrb_convert_type(mrb, *sp, MRB_TT_FIXNUM, "Integer", "to_int");
*p = mrb_fixnum(tmp);
}
break;
}
break;
}
i++; sp++;
sp++;
i++;
}
}
break;
case 'n':
{
mrb_sym *symp;
symp = va_arg(ap, mrb_sym*);
if (i < argc) {
mrb_value ss;
ss = *sp++;
if (mrb_type(ss) == MRB_TT_SYMBOL) {
*symp = mrb_symbol(ss);
}
else {
*symp = mrb_intern_str(mrb, to_str(mrb, ss));
}
i++;
}
}
break;
case '&':
{
mrb_value *p, *bp = mrb->stack + 1;
mrb_value *p, *bp;
p = va_arg(ap, mrb_value*);
if (mrb->ci->argc > 0) {
bp += mrb->ci->argc;
if (mrb->ci->argc < 0) {
bp = mrb->stack + 2;
}
else {
bp = mrb->stack + mrb->ci->argc + 1;
}
*p = *bp;
}
break;
@@ -579,6 +642,9 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
}
}
break;
default:
mrb_raise(mrb, E_ARGUMENT_ERROR, "invalide argument specifier %c", c);
break;
}
}
if (!c && argc > i) {
@@ -603,28 +669,120 @@ boot_defclass(mrb_state *mrb, struct RClass *super)
void
mrb_include_module(mrb_state *mrb, struct RClass *c, struct RClass *m)
{
struct RClass *ic;
struct RClass *ins_pos;
ic = (struct RClass*)mrb_obj_alloc(mrb, MRB_TT_ICLASS, mrb->class_class);
ic->c = m;
ic->mt = m->mt;
ic->iv = m->iv;
ic->super = c->super;
c->super = ic;
mrb_field_write_barrier(mrb, (struct RBasic*)c, (struct RBasic*)ic);
ins_pos = c;
while (m) {
struct RClass *p = c, *ic;
int superclass_seen = 0;
while(p) {
if (c != p && p->tt == MRB_TT_CLASS) {
superclass_seen = 1;
}
else if (p->mt == m->mt){
if (p->tt == MRB_TT_ICLASS && !superclass_seen) {
ins_pos = p;
}
goto skip;
}
p = p->super;
}
ic = (struct RClass*)mrb_obj_alloc(mrb, MRB_TT_ICLASS, mrb->class_class);
if (m->tt == MRB_TT_ICLASS) {
ic->c = m->c;
}
else {
ic->c = m;
}
ic->mt = m->mt;
ic->iv = m->iv;
ic->super = ins_pos->super;
ins_pos->super = ic;
mrb_field_write_barrier(mrb, (struct RBasic*)ins_pos, (struct RBasic*)ic);
ins_pos = ic;
skip:
m = m->super;
}
}
static mrb_value
mrb_mod_append_features(mrb_state *mrb, mrb_value mod)
{
mrb_value klass;
mrb_check_type(mrb, mod, MRB_TT_MODULE);
mrb_get_args(mrb, "o", &klass);
mrb_include_module(mrb, mrb_class_ptr(klass), mrb_class_ptr(mod));
return mod;
}
static mrb_value
mrb_mod_include(mrb_state *mrb, mrb_value klass)
{
mrb_value mod;
mrb_value *argv;
int argc, i;
mrb_get_args(mrb, "*", &argv, &argc);
for (i=0; i<argc; i++) {
mrb_check_type(mrb, argv[i], MRB_TT_MODULE);
}
while (argc--) {
mrb_funcall(mrb, argv[argc], "append_features", 1, klass);
mrb_funcall(mrb, argv[argc], "included", 1, klass);
}
return klass;
}
static mrb_value
mrb_mod_ancestors(mrb_state *mrb, mrb_value self)
{
mrb_value result;
struct RClass *c = mrb_class_ptr(self);
result = mrb_ary_new(mrb);
while (c) {
if (c->tt == MRB_TT_ICLASS) {
mrb_ary_push(mrb, result, mrb_obj_value(c->c));
}
else {
mrb_ary_push(mrb, result, mrb_obj_value(c));
}
c = c->super;
}
return result;
}
static mrb_value
mrb_mod_extend_object(mrb_state *mrb, mrb_value mod)
{
mrb_value obj;
mrb_get_args(mrb, "o", &mod);
mrb_check_type(mrb, mod, MRB_TT_MODULE);
mrb_include_module(mrb, mrb_class_ptr(klass), mrb_class_ptr(mod));
mrb_get_args(mrb, "o", &obj);
mrb_include_module(mrb, mrb_class_ptr(mrb_singleton_class(mrb, obj)), mrb_class_ptr(mod));
return mod;
}
static mrb_value
mrb_mod_included_modules(mrb_state *mrb, mrb_value self)
{
mrb_value result;
struct RClass *c = mrb_class_ptr(self);
result = mrb_ary_new(mrb);
while (c) {
if (c->tt == MRB_TT_ICLASS) {
mrb_ary_push(mrb, result, mrb_obj_value(c->c));
}
c = c->super;
}
return result;
}
static struct RClass *
mrb_singleton_class_ptr(mrb_state *mrb, struct RClass *c)
{
@@ -648,11 +806,16 @@ mrb_singleton_class(mrb_state *mrb, mrb_value v)
switch (mrb_type(v)) {
case MRB_TT_FALSE:
if (mrb_nil_p(v))
return mrb_obj_value(mrb->nil_class);
return mrb_obj_value(mrb->false_class);
case MRB_TT_TRUE:
return mrb_obj_value(mrb->true_class);
case MRB_TT_SYMBOL:
case MRB_TT_FIXNUM:
case MRB_TT_FLOAT:
return mrb_nil_value(); /* should raise TypeError */
mrb_raise(mrb, E_TYPE_ERROR, "can't define singleton");
return mrb_nil_value(); /* not reached */
default:
break;
}
@@ -662,15 +825,16 @@ mrb_singleton_class(mrb_state *mrb, mrb_value v)
}
void
mrb_define_class_method(mrb_state *mrb, struct RClass *c, const char *name, mrb_func_t func, int aspec)
mrb_define_singleton_method(mrb_state *mrb, struct RObject *o, const char *name, mrb_func_t func, int aspec)
{
mrb_define_method_id(mrb, c->c, mrb_intern(mrb, name), func, aspec);
o->c = mrb_singleton_class_ptr(mrb, o->c);
mrb_define_method_id(mrb, o->c, mrb_intern(mrb, name), func, aspec);
}
void
mrb_define_singleton_method(mrb_state *mrb, struct RObject *o, const char *name, mrb_func_t func, int aspec)
mrb_define_class_method(mrb_state *mrb, struct RClass *c, const char *name, mrb_func_t func, int aspec)
{
mrb_define_method_id(mrb, mrb_singleton_class_ptr(mrb, o->c), mrb_intern(mrb, name), func, aspec);
mrb_define_singleton_method(mrb, (struct RObject*)c, name, func, aspec);
}
void
@@ -716,34 +880,48 @@ mrb_method_search(mrb_state *mrb, struct RClass* c, mrb_sym mid)
return m;
}
#ifndef MRB_FUNCALL_ARGC_MAX
#define MRB_FUNCALL_ARGC_MAX 16
#endif
mrb_value
mrb_funcall(mrb_state *mrb, mrb_value self, const char *name, int argc,...)
mrb_funcall(mrb_state *mrb, mrb_value self, const char *name, int argc, ...)
{
mrb_value args[16];
mrb_sym mid = mrb_intern(mrb, name);
va_list ap;
int i;
if (argc == 0) {
for (i=0; i<5; i++) {
args[i] = mrb_nil_value();
}
return mrb_funcall_argv(mrb, self, mid, 0, 0);
}
else if (argc == 1) {
mrb_value v;
va_start(ap, argc);
v = va_arg(ap, mrb_value);
va_end(ap);
return mrb_funcall_argv(mrb, self, mid, 1, &v);
}
else {
mrb_value argv[MRB_FUNCALL_ARGC_MAX];
if (argc > MRB_FUNCALL_ARGC_MAX) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "Too long arguments. (limit=%d)", MRB_FUNCALL_ARGC_MAX);
}
va_start(ap, argc);
// assert(argc < 16);
for (i=0; i<argc; i++) {
args[i] = va_arg(ap, mrb_value);
for (i = 0; i < argc; i++) {
argv[i] = va_arg(ap, mrb_value);
}
va_end(ap);
return mrb_funcall_argv(mrb, self, mid, argc, argv);
}
return mrb_funcall_argv(mrb, self, name, argc, args);
}
void
mrb_obj_call_init(mrb_state *mrb, mrb_value obj, int argc, mrb_value *argv)
{
mrb_funcall_argv(mrb, obj, "initialize", argc, argv);
mrb_funcall_argv(mrb, obj, mrb_intern(mrb, "initialize"), argc, argv);
}
/*
@@ -782,7 +960,7 @@ mrb_class_new_instance_m(mrb_state *mrb, mrb_value klass)
c = (struct RClass*)mrb_obj_alloc(mrb, k->tt, k);
c->super = k;
obj = mrb_obj_value(c);
mrb_funcall_with_block(mrb, obj, "initialize", argc, argv, blk);
mrb_funcall_with_block(mrb, obj, mrb_intern(mrb, "initialize"), argc, argv, blk);
return obj;
}
@@ -801,11 +979,39 @@ mrb_instance_new(mrb_state *mrb, mrb_value cv)
o = (struct RObject*)mrb_obj_alloc(mrb, ttype, c);
obj = mrb_obj_value(o);
mrb_get_args(mrb, "*&", &argv, &argc, &blk);
mrb_funcall_with_block(mrb, obj, "initialize", argc, argv, blk);
mrb_funcall_with_block(mrb, obj, mrb_intern(mrb, "initialize"), argc, argv, blk);
return obj;
}
mrb_value
mrb_class_new_class(mrb_state *mrb, mrb_value cv)
{
mrb_value super;
struct RClass *new_class;
if (mrb_get_args(mrb, "|o", &super) == 0) {
super = mrb_obj_value(mrb->object_class);
}
new_class = mrb_class_new(mrb, mrb_class_ptr(super));
return mrb_obj_value(new_class);
}
mrb_value
mrb_class_superclass(mrb_state *mrb, mrb_value klass)
{
struct RClass *c;
mrb_value superclass;
c = mrb_class_ptr(klass);
if (c->super)
superclass = mrb_obj_value(mrb_class_real(c->super));
else
superclass = mrb_nil_value();
return superclass;
}
static mrb_value
mrb_bob_init(mrb_state *mrb, mrb_value cv)
{
@@ -878,8 +1084,14 @@ mrb_obj_respond_to(struct RClass* c, mrb_sym mid)
if (h) {
k = kh_get(mt, h, mid);
if (k != kh_end(h))
return 1; /* exist method */
if (k != kh_end(h)) {
if (kh_value(h, k)) {
return 1; /* exist method */
}
else {
return 0;
}
}
}
c = c->super;
}
@@ -896,6 +1108,8 @@ mrb_value
mrb_class_path(mrb_state *mrb, struct RClass *c)
{
mrb_value path;
const char *name;
int len;
path = mrb_obj_iv_get(mrb, (struct RObject*)c, mrb_intern(mrb, "__classpath__"));
if (mrb_nil_p(path)) {
@@ -903,14 +1117,16 @@ mrb_class_path(mrb_state *mrb, struct RClass *c)
mrb_sym sym = class_sym(mrb, c, outer);
if (outer && outer != mrb->object_class) {
mrb_value base = mrb_class_path(mrb, outer);
path = mrb_str_plus(mrb, base, mrb_str_new_cstr(mrb, "::"));
mrb_str_concat(mrb, path, mrb_str_new_cstr(mrb, mrb_sym2name(mrb, sym)));
path = mrb_str_plus(mrb, base, mrb_str_new(mrb, "::", 2));
name = mrb_sym2name_len(mrb, sym, &len);
mrb_str_concat(mrb, path, mrb_str_new(mrb, name, len));
}
else if (sym == 0) {
return mrb_nil_value();
}
else {
path = mrb_str_new_cstr(mrb, mrb_sym2name(mrb, sym));
name = mrb_sym2name_len(mrb, sym, &len);
path = mrb_str_new(mrb, name, len);
}
mrb_obj_iv_set(mrb, (struct RObject*)c, mrb_intern(mrb, "__classpath__"), path);
}
@@ -931,7 +1147,7 @@ mrb_class_name(mrb_state *mrb, struct RClass* c)
{
mrb_value path = mrb_class_path(mrb, c);
if (mrb_nil_p(path)) return 0;
return mrb_str_ptr(path)->buf;
return mrb_str_ptr(path)->ptr;
}
const char*
@@ -976,6 +1192,9 @@ mrb_class_new(mrb_state *mrb, struct RClass *super)
mrb_check_inheritable(mrb, super);
}
c = boot_defclass(mrb, super);
if (super){
MRB_SET_INSTANCE_TT(c, MRB_INSTANCE_TT(super));
}
make_metaclass(mrb, c);
return c;
@@ -988,6 +1207,7 @@ struct RClass *
mrb_module_new(mrb_state *mrb)
{
struct RClass *m = (struct RClass*)mrb_obj_alloc(mrb, MRB_TT_MODULE, mrb->module_class);
m->mt = kh_init(mt, mrb);
return m;
}
@@ -1044,9 +1264,8 @@ mrb_define_alias(mrb_state *mrb, struct RClass *klass, const char *name1, const
static mrb_value
mrb_mod_to_s(mrb_state *mrb, mrb_value klass)
{
//if (FL_TEST(klass, FL_SINGLETON)) {
if (mrb_type(klass) == MRB_TT_SCLASS) {
mrb_value s = mrb_str_new_cstr(mrb, "#<");
mrb_value s = mrb_str_new(mrb, "#<", 2);
mrb_value v = mrb_iv_get(mrb, klass, mrb_intern(mrb, "__attached__"));
mrb_str_cat2(mrb, s, "Class:");
@@ -1065,25 +1284,25 @@ mrb_mod_to_s(mrb_state *mrb, mrb_value klass)
}
else {
struct RClass *c = mrb_class_ptr(klass);
const char *cn = mrb_class_name(mrb, c);
const char *cn = mrb_class_name(mrb, c);
if (!cn) {
char buf[256];
int n = 0;
switch (mrb_type(klass)) {
case MRB_TT_CLASS:
snprintf(buf, 256, "#<Class:%p>", c);
n = snprintf(buf, sizeof(buf), "#<Class:%p>", c);
break;
case MRB_TT_MODULE:
snprintf(buf, 256, "#<Module:%p>", c);
n = snprintf(buf, sizeof(buf), "#<Module:%p>", c);
break;
default:
break;
}
return mrb_str_dup(mrb, mrb_str_new_cstr(mrb, buf));
return mrb_str_dup(mrb, mrb_str_new(mrb, buf, n));
}
else {
return mrb_str_dup(mrb, mrb_str_new_cstr(mrb, cn));
@@ -1119,6 +1338,12 @@ mrb_undef_method(mrb_state *mrb, struct RClass *c, const char *name)
undef_method(mrb, c, mrb_intern(mrb, name));
}
void
mrb_undef_class_method(mrb_state *mrb, struct RClass *c, const char *name)
{
mrb_undef_method(mrb, mrb_class_ptr(mrb_singleton_class(mrb, mrb_obj_value(c))), name);
}
mrb_value
mrb_mod_undef(mrb_state *mrb, mrb_value mod)
{
@@ -1134,11 +1359,29 @@ mrb_mod_undef(mrb_state *mrb, mrb_value mod)
return mrb_nil_value();
}
static mrb_value
mod_define_method(mrb_state *mrb, mrb_value self)
{
struct RClass *c = mrb_class_ptr(self);
struct RProc *p;
mrb_sym mid;
mrb_value blk;
mrb_get_args(mrb, "n&", &mid, &blk);
if (mrb_nil_p(blk)) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given");
}
p = (struct RProc*)mrb_obj_alloc(mrb, MRB_TT_PROC, mrb->proc_class);
mrb_proc_copy(p, mrb_proc_ptr(blk));
mrb_define_method_raw(mrb, c, mid, p);
return blk;
}
static mrb_sym
mrb_sym_value(mrb_state *mrb, mrb_value val)
{
if(val.tt == MRB_TT_STRING) {
return mrb_intern(mrb, RSTRING_PTR(val));
return mrb_intern_str(mrb, val);
}
else if(val.tt != MRB_TT_SYMBOL) {
mrb_value obj = mrb_funcall(mrb, val, "inspect", 0);
@@ -1225,17 +1468,28 @@ mrb_init_class(mrb_state *mrb)
MRB_SET_INSTANCE_TT(cls, MRB_TT_CLASS);
mrb_define_method(mrb, bob, "initialize", mrb_bob_init, ARGS_NONE());
mrb_define_method(mrb, bob, "!", mrb_bob_not, ARGS_NONE());
mrb_define_method(mrb, bob, "method_missing", mrb_bob_missing, ARGS_ANY()); /* 15.3.1.3.30 */
mrb_define_method(mrb, cls, "new", mrb_instance_new, ARGS_ANY());
mrb_define_method(mrb, bob, "method_missing", mrb_bob_missing, ARGS_ANY()); /* 15.3.1.3.30 */
mrb_define_class_method(mrb, cls, "new", mrb_class_new_class, ARGS_ANY());
mrb_define_method(mrb, cls, "superclass", mrb_class_superclass, ARGS_NONE()); /* 15.2.3.3.4 */
mrb_define_method(mrb, cls, "new", mrb_instance_new, ARGS_ANY()); /* 15.2.3.3.3 */
mrb_define_method(mrb, cls, "inherited", mrb_bob_init, ARGS_REQ(1));
mrb_define_method(mrb, mod, "include", mrb_mod_include, ARGS_REQ(1));
mrb_define_method(mrb, mod, "extend_object", mrb_mod_extend_object, ARGS_REQ(1)); /* 15.2.2.4.25 */
mrb_define_method(mrb, mod, "extended", mrb_bob_init, ARGS_REQ(1)); /* 15.2.2.4.26 */
mrb_define_method(mrb, mod, "include", mrb_mod_include, ARGS_ANY()); /* 15.2.2.4.27 */
mrb_define_method(mrb, mod, "append_features", mrb_mod_append_features, ARGS_REQ(1)); /* 15.2.2.4.10 */
mrb_define_method(mrb, mod, "included", mrb_bob_init, ARGS_REQ(1)); /* 15.2.2.4.29 */
mrb_define_method(mrb, mod, "included_modules", mrb_mod_included_modules, ARGS_NONE()); /* 15.2.2.4.30 */
mrb_define_method(mrb, mod, "to_s", mrb_mod_to_s, ARGS_NONE());
mrb_define_method(mrb, mod, "alias_method", mrb_mod_alias, ARGS_ANY());
mrb_define_method(mrb, mod, "undef_method", mrb_mod_undef, ARGS_ANY());
mrb_define_method(mrb, mod, "const_defined?", mrb_mod_const_defined, ARGS_REQ(1));
mrb_define_method(mrb, mod, "const_get", mrb_mod_const_get, ARGS_REQ(1));
mrb_define_method(mrb, mod, "const_set", mrb_mod_const_set, ARGS_REQ(2));
mrb_define_method(mrb, mod, "alias_method", mrb_mod_alias, ARGS_ANY()); /* 15.2.2.4.8 */
mrb_define_method(mrb, mod, "ancestors", mrb_mod_ancestors, ARGS_NONE()); /* 15.2.2.4.9 */
mrb_define_method(mrb, mod, "undef_method", mrb_mod_undef, ARGS_ANY()); /* 15.2.2.4.41 */
mrb_define_method(mrb, mod, "const_defined?", mrb_mod_const_defined, ARGS_REQ(1)); /* 15.2.2.4.20 */
mrb_define_method(mrb, mod, "const_get", mrb_mod_const_get, ARGS_REQ(1)); /* 15.2.2.4.21 */
mrb_define_method(mrb, mod, "const_set", mrb_mod_const_set, ARGS_REQ(2)); /* 15.2.2.4.23 */
mrb_define_method(mrb, mod, "define_method", mod_define_method, ARGS_REQ(1));
mrb_define_method(mrb, mod, "===", mrb_mod_eqq, ARGS_REQ(1));
mrb_undef_method(mrb, cls, "append_features");
mrb_undef_method(mrb, cls, "extend_object");
}
+329 -150
View File
@@ -10,12 +10,13 @@
#include "mruby.h"
#include "mruby/string.h"
#include "mruby/irep.h"
#include "mruby/proc.h"
#include "mruby/compile.h"
#include "mruby/numeric.h"
#include "opcode.h"
#include "node.h"
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
typedef mrb_ast_node node;
typedef struct mrb_parser_state parser_state;
@@ -47,7 +48,8 @@ typedef struct scope {
int sp;
int pc;
int lastlabel;
int ainfo;
int ainfo:15;
int mscope:1;
struct loopinfo *loop;
int ensure_level;
@@ -89,7 +91,9 @@ codegen_error(codegen_scope *s, const char *message)
s = s->prev;
}
mrb_pool_close(s->mpool);
#ifdef ENABLE_STDIO
fprintf(stderr, "codegen error: %s\n", message);
#endif
longjmp(s->jmp, 1);
}
@@ -132,7 +136,7 @@ genop(codegen_scope *s, mrb_code i)
{
if (s->pc == s->icapa) {
s->icapa *= 2;
s->iseq = codegen_realloc(s, s->iseq, sizeof(mrb_code)*s->icapa);
s->iseq = (mrb_code *)codegen_realloc(s, s->iseq, sizeof(mrb_code)*s->icapa);
}
s->iseq[s->pc] = i;
s->pc++;
@@ -141,7 +145,7 @@ genop(codegen_scope *s, mrb_code i)
static void
genop_peep(codegen_scope *s, mrb_code i, int val)
{
// peephole optimization
/* peephole optimization */
if (!val && s->lastlabel != s->pc && s->pc > 0) {
mrb_code i0 = s->iseq[s->pc-1];
int c1 = GET_OPCODE(i);
@@ -152,9 +156,13 @@ genop_peep(codegen_scope *s, mrb_code i, int val)
switch (c0) {
case OP_MOVE:
if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i) == GETARG_B(i0) && GETARG_A(i) >= s->nlocals) {
// skip swapping OP_MOVE
/* skip swapping OP_MOVE */
return;
}
if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i0) >= s->nlocals) {
s->iseq[s->pc-1] = MKOP_AB(OP_MOVE, GETARG_A(i), GETARG_B(i0));
return;
}
break;
case OP_LOADI:
if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i0) >= s->nlocals) {
@@ -180,7 +188,6 @@ genop_peep(codegen_scope *s, mrb_code i, int val)
case OP_GETSPECIAL:
case OP_LOADL:
case OP_STRING:
case OP_GETMCNST:
if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i0) >= s->nlocals) {
s->iseq[s->pc-1] = MKOP_ABx(c0, GETARG_A(i), GETARG_Bx(i0));
return;
@@ -202,29 +209,27 @@ genop_peep(codegen_scope *s, mrb_code i, int val)
return;
}
break;
default:
break;
}
break;
case OP_SETIV:
case OP_SETCV:
case OP_SETCONST:
case OP_SETMCNST:
switch (c0) {
case OP_MOVE:
if (c0 == OP_MOVE) {
if (GETARG_A(i) == GETARG_A(i0)) {
s->iseq[s->pc-1] = MKOP_ABx(c1, GETARG_B(i0), GETARG_Bx(i));
return;
}
break;
}
break;
case OP_SETUPVAR:
switch (c0) {
case OP_MOVE:
if (c0 == OP_MOVE) {
if (GETARG_A(i) == GETARG_A(i0)) {
s->iseq[s->pc-1] = MKOP_ABC(c1, GETARG_B(i0), GETARG_B(i), GETARG_C(i));
return;
}
break;
}
break;
case OP_EPOP:
@@ -239,6 +244,52 @@ genop_peep(codegen_scope *s, mrb_code i, int val)
return;
}
break;
case OP_RETURN:
switch (c0) {
case OP_MOVE:
s->iseq[s->pc-1] = MKOP_AB(OP_RETURN, GETARG_B(i0), OP_R_NORMAL);
return;
case OP_LOADI:
s->iseq[s->pc-1] = MKOP_AsBx(OP_LOADI, 0, GETARG_sBx(i0));
genop(s, MKOP_AB(OP_RETURN, 0, OP_R_NORMAL));
return;
case OP_ARRAY:
case OP_HASH:
case OP_RANGE:
case OP_AREF:
case OP_GETUPVAR:
s->iseq[s->pc-1] = MKOP_ABC(c0, 0, GETARG_B(i0), GETARG_C(i0));
genop(s, MKOP_AB(OP_RETURN, 0, OP_R_NORMAL));
return;
case OP_LOADSYM:
case OP_GETGLOBAL:
case OP_GETIV:
case OP_GETCV:
case OP_GETCONST:
case OP_GETSPECIAL:
case OP_LOADL:
case OP_STRING:
s->iseq[s->pc-1] = MKOP_ABx(c0, 0, GETARG_Bx(i0));
genop(s, MKOP_AB(OP_RETURN, 0, OP_R_NORMAL));
return;
case OP_SCLASS:
s->iseq[s->pc-1] = MKOP_AB(c0, GETARG_A(i), GETARG_B(i0));
genop(s, MKOP_AB(OP_RETURN, 0, OP_R_NORMAL));
return;
case OP_LOADNIL:
case OP_LOADSELF:
case OP_LOADT:
case OP_LOADF:
case OP_OCLASS:
s->iseq[s->pc-1] = MKOP_A(c0, 0);
genop(s, MKOP_AB(OP_RETURN, 0, OP_R_NORMAL));
return;
default:
break;
}
break;
default:
break;
}
}
genop(s, i);
@@ -265,7 +316,9 @@ dispatch(codegen_scope *s, int pc)
case OP_ONERR:
break;
default:
#ifdef ENABLE_STDIO
fprintf(stderr, "bug: dispatch on non JMP op\n");
#endif
scope_error(s);
}
s->iseq[pc] = MKOP_AsBx(c, GETARG_A(i), diff);
@@ -297,21 +350,10 @@ push_(codegen_scope *s)
s->sp++;
nregs_update;
}
#if 0
static void
push_n_(codegen_scope *s, int n)
{
if (s->sp + n > 511) {
codegen_error(s, "too complex expression");
}
s->sp += n;
nregs_update;
}
#endif
#define push() push_(s)
#define push_n(n) push_n_(s, n)
#define pop() (s->sp--)
#define pop_(s) ((s)->sp--)
#define pop() pop_(s)
#define pop_n(n) (s->sp-=(n))
#define cursp() (s->sp)
@@ -321,11 +363,11 @@ new_lit(codegen_scope *s, mrb_value val)
int i;
for (i=0; i<s->plen; i++) {
if (memcmp(&s->pool[i], &val, sizeof(mrb_value)) == 0) return i;
if (mrb_obj_equal(s->mrb, s->pool[i], val)) return i;
}
if (s->plen == s->pcapa) {
s->pcapa *= 2;
s->pool = codegen_realloc(s, s->pool, sizeof(mrb_value)*s->pcapa);
s->pool = (mrb_value *)codegen_realloc(s, s->pool, sizeof(mrb_value)*s->pcapa);
}
s->pool[s->plen] = val;
return s->plen++;
@@ -359,7 +401,7 @@ new_sym(codegen_scope *s, mrb_sym sym)
if (s->syms[i] == sym) return i;
}
if (s->slen > 125 && s->slen < 256) {
s->syms = codegen_realloc(s, s->syms, sizeof(mrb_sym)*65536);
s->syms = (mrb_sym *)codegen_realloc(s, s->syms, sizeof(mrb_sym)*65536);
memset(s->syms+s->slen, 0, sizeof(mrb_sym)*(256-s->slen));
s->slen = 256;
}
@@ -429,7 +471,7 @@ for_body(codegen_scope *s, node *tree)
pop();
c = s->iseq[s->pc-1];
if (GET_OPCODE(c) != OP_RETURN || GETARG_B(c) != OP_R_NORMAL || s->pc == s->lastlabel) {
genop(s, MKOP_AB(OP_RETURN, cursp(), OP_R_NORMAL));
genop_peep(s, MKOP_AB(OP_RETURN, cursp(), OP_R_NORMAL), NOVAL);
}
loop_pop(s, NOVAL);
scope_finish(s, idx);
@@ -448,6 +490,7 @@ lambda_body(codegen_scope *s, node *tree, int blk)
s = scope_new(s->mrb, s, tree->car);
idx = s->idx;
s->mscope = !blk;
if (blk) {
struct loopinfo *lp = loop_push(s, LOOP_BLOCK);
@@ -484,10 +527,10 @@ lambda_body(codegen_scope *s, node *tree, int blk)
pos = new_label(s);
for (i=0; i<oa; i++) {
new_label(s);
genop(s, MKOP_Ax(OP_JMP, 0));
genop(s, MKOP_sBx(OP_JMP, 0));
}
if (oa > 0) {
genop(s, MKOP_Ax(OP_JMP, 0));
genop(s, MKOP_sBx(OP_JMP, 0));
}
opt = tree->car->cdr->car;
i = 0;
@@ -510,7 +553,13 @@ lambda_body(codegen_scope *s, node *tree, int blk)
pop();
c = s->iseq[s->pc-1];
if (GET_OPCODE(c) != OP_RETURN || GETARG_B(c) != OP_R_NORMAL || s->pc == s->lastlabel) {
genop(s, MKOP_AB(OP_RETURN, cursp(), OP_R_NORMAL));
if (s->nregs == 0) {
genop(s, MKOP_A(OP_LOADNIL, 0));
genop(s, MKOP_AB(OP_RETURN, 0, OP_R_NORMAL));
}
else {
genop_peep(s, MKOP_AB(OP_RETURN, cursp(), OP_R_NORMAL), NOVAL);
}
}
if (blk) {
loop_pop(s, NOVAL);
@@ -526,13 +575,19 @@ scope_body(codegen_scope *s, node *tree)
codegen_scope *scope = scope_new(s->mrb, s, tree->car);
int idx = scope->idx;
codegen(scope, tree->cdr, VAL);
if (!s->iseq) {
codegen(scope, tree->cdr, VAL);
genop(scope, MKOP_A(OP_STOP, 0));
}
else {
codegen(scope, tree->cdr, VAL);
genop(scope, MKOP_AB(OP_RETURN, scope->sp, OP_R_NORMAL));
pop_(scope);
if (scope->nregs == 0) {
genop(scope, MKOP_A(OP_LOADNIL, 0));
genop(scope, MKOP_AB(OP_RETURN, 0, OP_R_NORMAL));
}
else {
genop_peep(scope, MKOP_AB(OP_RETURN, scope->sp, OP_R_NORMAL), NOVAL);
}
}
scope_finish(scope, idx);
@@ -552,16 +607,17 @@ nosplat(node *t)
static mrb_sym
attrsym(codegen_scope *s, mrb_sym a)
{
const char *name = mrb_sym2name(s->mrb, a);
const char *name;
int len;
char *name2;
size_t len = strlen(name);
name2 = codegen_palloc(s, len+1);
strcpy(name2, name);
name = mrb_sym2name_len(s->mrb, a, &len);
name2 = (char *)codegen_palloc(s, len+1);
memcpy(name2, name, len);
name2[len] = '=';
name2[len+1] = '\0';
return mrb_intern(s->mrb, name2);
return mrb_intern2(s->mrb, name2, len+1);
}
static int
@@ -607,7 +663,7 @@ gen_call(codegen_scope *s, node *tree, mrb_sym name, int sp, int val)
{
mrb_sym sym = name ? name : (mrb_sym)tree->cdr->car;
int idx;
int n = 0, noop = 0, sendv = 0;
int n = 0, noop = 0, sendv = 0, blk = 0;
codegen(s, tree->car, VAL); /* receiver */
idx = new_msym(s, sym);
@@ -637,31 +693,44 @@ gen_call(codegen_scope *s, node *tree, mrb_sym name, int sp, int val)
pop();
}
else {
genop(s, MKOP_A(OP_LOADNIL, cursp()));
blk = cursp();
}
pop_n(n+1);
{
const char *name = mrb_sym2name(s->mrb, sym);
int len;
const char *name = mrb_sym2name_len(s->mrb, sym, &len);
if (!noop && name[0] == '+' && strlen(name) == 1) {
if (!noop && len == 1 && name[0] == '+') {
genop(s, MKOP_ABC(OP_ADD, cursp(), idx, n));
}
else if (!noop && name[0] == '-' && strlen(name) == 1) {
else if (!noop && len == 1 && name[0] == '-') {
genop(s, MKOP_ABC(OP_SUB, cursp(), idx, n));
}
else if (!noop && name[0] == '<' && strlen(name) == 1) {
else if (!noop && len == 1 && name[0] == '*') {
genop(s, MKOP_ABC(OP_MUL, cursp(), idx, n));
}
else if (!noop && len == 1 && name[0] == '/') {
genop(s, MKOP_ABC(OP_DIV, cursp(), idx, n));
}
else if (!noop && len == 1 && name[0] == '<') {
genop(s, MKOP_ABC(OP_LT, cursp(), idx, n));
}
else if (!noop && name[0] == '<' && strlen(name) == 2 && name[1] == '=') {
else if (!noop && len == 2 && name[0] == '<' && name[1] == '=') {
genop(s, MKOP_ABC(OP_LE, cursp(), idx, n));
}
else if (!noop && name[0] == '>' && strlen(name) == 1) {
else if (!noop && len == 1 && name[0] == '>') {
genop(s, MKOP_ABC(OP_GT, cursp(), idx, n));
}
else if (!noop && name[0] == '>' && strlen(name) == 2 && name[1] == '=') {
else if (!noop && len == 2 && name[0] == '>' && name[1] == '=') {
genop(s, MKOP_ABC(OP_GE, cursp(), idx, n));
}
else if (!noop && len == 2 && name[0] == '=' && name[1] == '=') {
genop(s, MKOP_ABC(OP_EQ, cursp(), idx, n));
}
else {
if (blk > 0) { /* no block */
genop(s, MKOP_A(OP_LOADNIL, blk));
}
if (sendv) n = CALL_MAXARGS;
genop(s, MKOP_ABC(OP_SEND, cursp(), idx, n));
}
@@ -735,7 +804,9 @@ gen_assignment(codegen_scope *s, node *node, int sp, int val)
break;
default:
#ifdef ENABLE_STDIO
printf("unknown lhs %d\n", type);
#endif
break;
}
if (val) push();
@@ -795,6 +866,32 @@ raise_error(codegen_scope *s, const char *msg)
genop(s, MKOP_ABx(OP_ERR, 0, idx));
}
static double
readint_float(codegen_scope *s, const char *p, int base)
{
const char *e = p + strlen(p);
double f = 0;
int n;
if (*p == '+') p++;
while (p < e) {
char c = *p;
c = tolower((unsigned char)c);
for (n=0; n<base; n++) {
if (mrb_digitmap[n] == c) {
f *= base;
f += n;
break;
}
}
if (n == base) {
codegen_error(s, "malformed readint input");
}
p++;
}
return f;
}
static void
codegen(codegen_scope *s, node *tree, int val)
{
@@ -838,28 +935,34 @@ codegen(codegen_scope *s, node *tree, int val)
push();
while (n2) {
node *n3 = n2->car;
node *n4 = n3->car;
if (pos1) dispatch(s, pos1);
if (n3->car) {
node *n4 = n3->car;
pos2 = 0;
while (n4) {
pos2 = 0;
do {
if (n4) {
codegen(s, n4->car, VAL);
genop(s, MKOP_AB(OP_MOVE, cursp(), exc));
}
else {
genop(s, MKOP_ABx(OP_GETCONST, cursp(), new_msym(s, mrb_intern(s->mrb, "StandardError"))));
push();
genop(s, MKOP_A(OP_LOADNIL, cursp()));
pop(); pop();
genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern(s->mrb, "===")), 1));
tmp = new_label(s);
genop(s, MKOP_AsBx(OP_JMPIF, cursp(), pos2));
pos2 = tmp;
}
genop(s, MKOP_AB(OP_MOVE, cursp(), exc));
push();
genop(s, MKOP_A(OP_LOADNIL, cursp()));
pop(); pop();
genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern(s->mrb, "===")), 1));
tmp = new_label(s);
genop(s, MKOP_AsBx(OP_JMPIF, cursp(), pos2));
pos2 = tmp;
if (n4) {
n4 = n4->cdr;
}
pos1 = new_label(s);
genop(s, MKOP_Bx(OP_JMP, 0));
dispatch_linked(s, pos2);
}
} while (n4);
pos1 = new_label(s);
genop(s, MKOP_sBx(OP_JMP, 0));
dispatch_linked(s, pos2);
pop();
if (n3->cdr->car) {
gen_assignment(s, n3->cdr->car, exc, NOVAL);
@@ -868,7 +971,7 @@ codegen(codegen_scope *s, node *tree, int val)
codegen(s, n3->cdr->cdr->car, val);
}
tmp = new_label(s);
genop(s, MKOP_AsBx(OP_JMP, cursp(), exend));
genop(s, MKOP_sBx(OP_JMP, exend));
exend = tmp;
n2 = n2->cdr;
push();
@@ -878,6 +981,7 @@ codegen(codegen_scope *s, node *tree, int val)
genop(s, MKOP_A(OP_RAISE, exc));
}
}
pop();
tree = tree->cdr;
dispatch(s, noexc);
genop(s, MKOP_A(OP_POPERR, 1));
@@ -983,13 +1087,14 @@ codegen(codegen_scope *s, node *tree, int val)
struct loopinfo *lp = loop_push(s, LOOP_NORMAL);
lp->pc1 = new_label(s);
genop(s, MKOP_sBx(OP_JMP, 0));
lp->pc2 = new_label(s);
codegen(s, tree->cdr, NOVAL);
dispatch(s, lp->pc1);
codegen(s, tree->car, VAL);
pop();
lp->pc2 = new_label(s);
genop(s, MKOP_AsBx(OP_JMPNOT, cursp(), 0));
codegen(s, tree->cdr, NOVAL);
genop(s, MKOP_sBx(OP_JMP, lp->pc1 - s->pc));
dispatch(s, lp->pc2);
genop(s, MKOP_AsBx(OP_JMPIF, cursp(), lp->pc2 - s->pc));
loop_pop(s, val);
}
break;
@@ -999,13 +1104,14 @@ codegen(codegen_scope *s, node *tree, int val)
struct loopinfo *lp = loop_push(s, LOOP_NORMAL);
lp->pc1 = new_label(s);
genop(s, MKOP_sBx(OP_JMP, 0));
lp->pc2 = new_label(s);
codegen(s, tree->cdr, NOVAL);
dispatch(s, lp->pc1);
codegen(s, tree->car, VAL);
pop();
lp->pc2 = new_label(s);
genop(s, MKOP_AsBx(OP_JMPIF, cursp(), 0));
codegen(s, tree->cdr, NOVAL);
genop(s, MKOP_sBx(OP_JMP, lp->pc1 - s->pc));
dispatch(s, lp->pc2);
genop(s, MKOP_AsBx(OP_JMPNOT, cursp(), lp->pc2 - s->pc));
loop_pop(s, val);
}
break;
@@ -1046,21 +1152,23 @@ codegen(codegen_scope *s, node *tree, int val)
}
if (tree->car->car) {
pos1 = new_label(s);
genop(s, MKOP_AsBx(OP_JMP, cursp(), 0));
genop(s, MKOP_sBx(OP_JMP, 0));
dispatch_linked(s, pos2);
}
pop(); pop();
pop();
codegen(s, tree->car->cdr, val);
pop();
tmp = new_label(s);
genop(s, MKOP_AsBx(OP_JMP, cursp(), pos3));
genop(s, MKOP_sBx(OP_JMP, pos3));
pos3 = tmp;
if (pos1) dispatch(s, pos1);
tree = tree->cdr;
push(); push();
push();
}
pop();
if (pos3) dispatch_linked(s, pos3);
genop(s, MKOP_A(OP_LOADNIL, cursp()));
if (val) push();
if (pos3) dispatch_linked(s, pos3);
}
break;
@@ -1227,12 +1335,14 @@ codegen(codegen_scope *s, node *tree, int val)
case NODE_OP_ASGN:
{
mrb_sym sym = (mrb_sym)tree->cdr->car;
const char *name = mrb_sym2name(s->mrb, sym);
int idx;
int len;
const char *name = mrb_sym2name_len(s->mrb, sym, &len);
int idx, blk = 0;
codegen(s, tree->car, VAL);
if ((name[0] == '|' && strlen(name) == 2 && name[1] == '|') ||
(name[0] == '&' && strlen(name) == 2 && name[1] == '&')) {
if (len == 2 &&
((name[0] == '|' && name[1] == '|') ||
(name[0] == '&' && name[1] == '&'))) {
int pos;
pop();
@@ -1245,29 +1355,32 @@ codegen(codegen_scope *s, node *tree, int val)
break;
}
codegen(s, tree->cdr->cdr->car, VAL);
genop(s, MKOP_A(OP_LOADNIL, cursp()));
blk = cursp();
pop(); pop();
idx = new_msym(s, sym);
if (name[0] == '+' && strlen(name) == 1) {
if (len == 1 && name[0] == '+') {
genop(s, MKOP_ABC(OP_ADD, cursp(), idx, 1));
}
else if (name[0] == '-' && strlen(name) == 1) {
else if (len == 1 && name[0] == '-') {
genop(s, MKOP_ABC(OP_SUB, cursp(), idx, 1));
}
else if (name[0] == '<' && strlen(name) == 1) {
else if (len == 1 && name[0] == '<') {
genop(s, MKOP_ABC(OP_LT, cursp(), idx, 1));
}
else if (name[0] == '<' && strlen(name) == 2 && name[1] == '=') {
else if (len == 2 && name[0] == '<' && name[1] == '=') {
genop(s, MKOP_ABC(OP_LE, cursp(), idx, 1));
}
else if (name[0] == '>' && strlen(name) == 1) {
else if (len == 1 && name[0] == '>') {
genop(s, MKOP_ABC(OP_GT, cursp(), idx, 1));
}
else if (name[0] == '>' && strlen(name) == 2 && name[1] == '=') {
else if (len == 2 && name[0] == '>' && name[1] == '=') {
genop(s, MKOP_ABC(OP_GE, cursp(), idx, 1));
}
else {
if (blk > 0) {
genop(s, MKOP_A(OP_LOADNIL, blk));
}
genop(s, MKOP_ABC(OP_SEND, cursp(), idx, 1));
}
}
@@ -1276,16 +1389,18 @@ codegen(codegen_scope *s, node *tree, int val)
case NODE_SUPER:
{
int n = 0;
int n = 0, noop = 0, sendv = 0;
push();
push(); /* room for receiver */
if (tree) {
node *args = tree->car;
while (args) {
codegen(s, args->car, VAL);
n++;
args = args->cdr;
}
if (args) {
n = gen_values(s, args);
if (n < 0) {
n = noop = sendv = 1;
push();
}
}
}
if (tree && tree->cdr) {
codegen(s, tree->cdr, VAL);
@@ -1295,6 +1410,7 @@ codegen(codegen_scope *s, node *tree, int val)
genop(s, MKOP_A(OP_LOADNIL, cursp()));
}
pop_n(n+1);
if (sendv) n = CALL_MAXARGS;
genop(s, MKOP_ABC(OP_SUPER, cursp(), 0, n));
if (val) push();
}
@@ -1305,14 +1421,19 @@ codegen(codegen_scope *s, node *tree, int val)
codegen_scope *s2 = s;
int lv = 0, ainfo = 0;
while (s2->ainfo < 0) {
push(); /* room for receiver */
while (!s2->mscope) {
lv++;
s2 = s2->prev;
if (!s2) break;
}
if (s2) ainfo = s2->ainfo;
push();
genop(s, MKOP_ABx(OP_ARGARY, cursp(), (ainfo<<4)|(lv & 0xf)));
if (tree && tree->cdr) {
push();
codegen(s, tree->cdr, VAL);
pop_n(2);
}
pop();
genop(s, MKOP_ABC(OP_SUPER, cursp(), 0, CALL_MAXARGS));
if (val) push();
@@ -1326,7 +1447,7 @@ codegen(codegen_scope *s, node *tree, int val)
genop(s, MKOP_AB(OP_RETURN, cursp(), OP_R_RETURN));
}
else {
genop(s, MKOP_AB(OP_RETURN, cursp(), OP_R_NORMAL));
genop_peep(s, MKOP_AB(OP_RETURN, cursp(), OP_R_NORMAL), NOVAL);
}
break;
@@ -1336,7 +1457,7 @@ codegen(codegen_scope *s, node *tree, int val)
int lv = 0, ainfo = 0;
int n = 0, sendv = 0;
while (s2->ainfo < 0) {
while (!s2->mscope) {
lv++;
s2 = s2->prev;
if (!s2) break;
@@ -1378,7 +1499,7 @@ codegen(codegen_scope *s, node *tree, int val)
else {
codegen(s, tree, VAL);
pop();
genop(s, MKOP_AB(OP_RETURN, cursp(), OP_R_NORMAL));
genop_peep(s, MKOP_AB(OP_RETURN, cursp(), OP_R_NORMAL), NOVAL);
}
if (val) push();
break;
@@ -1498,10 +1619,11 @@ codegen(codegen_scope *s, node *tree, int val)
case NODE_BACK_REF:
{
char buf[4];
int len;
int sym;
snprintf(buf, 3, "$%c", (int)(intptr_t)tree);
sym = new_sym(s, mrb_intern(s->mrb, buf));
len = snprintf(buf, sizeof(buf), "$%c", (int)(intptr_t)tree);
sym = new_sym(s, mrb_intern2(s->mrb, buf, len));
genop(s, MKOP_ABx(OP_GETGLOBAL, cursp(), sym));
push();
}
@@ -1510,10 +1632,11 @@ codegen(codegen_scope *s, node *tree, int val)
case NODE_NTH_REF:
{
char buf[4];
int len;
int sym;
snprintf(buf, 3, "$%d", (int)(intptr_t)tree);
sym = new_sym(s, mrb_intern(s->mrb, buf));
len = snprintf(buf, sizeof(buf), "$%d", (int)(intptr_t)tree);
sym = new_sym(s, mrb_intern2(s->mrb, buf, len));
genop(s, MKOP_ABx(OP_GETGLOBAL, cursp(), sym));
push();
}
@@ -1531,17 +1654,27 @@ codegen(codegen_scope *s, node *tree, int val)
if (val) {
char *p = (char*)tree->car;
int base = (intptr_t)tree->cdr->car;
int i = readint(p, base);
double f;
mrb_int i;
mrb_code co;
if (i < MAXARG_sBx && i > -MAXARG_sBx) {
co = MKOP_AsBx(OP_LOADI, cursp(), i);
f = readint_float(s, p, base);
if (!FIXABLE(f)) {
int off = new_lit(s, mrb_float_value(f));
genop(s, MKOP_ABx(OP_LOADL, cursp(), off));
}
else {
int off = new_lit(s, mrb_fixnum_value(i));
co = MKOP_ABx(OP_LOADL, cursp(), off);
i = (mrb_int)f;
if (i < MAXARG_sBx && i > -MAXARG_sBx) {
co = MKOP_AsBx(OP_LOADI, cursp(), i);
}
else {
int off = new_lit(s, mrb_fixnum_value(i));
co = MKOP_ABx(OP_LOADL, cursp(), off);
}
genop(s, co);
}
genop(s, co);
push();
}
break;
@@ -1577,18 +1710,27 @@ codegen(codegen_scope *s, node *tree, int val)
{
char *p = (char*)tree->car;
int base = (intptr_t)tree->cdr->car;
int i = readint(p, base);
mrb_float f;
mrb_int i;
mrb_code co;
i = -i;
if (i < MAXARG_sBx && i > -MAXARG_sBx) {
co = MKOP_AsBx(OP_LOADI, cursp(), i);
}
else {
int off = new_lit(s, mrb_fixnum_value(i));
co = MKOP_ABx(OP_LOADL, cursp(), off);
}
genop(s, co);
f = readint_float(s, p, base);
if (!FIXABLE(f)) {
int off = new_lit(s, mrb_float_value(-f));
genop(s, MKOP_ABx(OP_LOADL, cursp(), off));
}
else {
i = (mrb_int)-f;
if (i < MAXARG_sBx && i > -MAXARG_sBx) {
co = MKOP_AsBx(OP_LOADI, cursp(), i);
}
else {
int off = new_lit(s, mrb_fixnum_value(i));
co = MKOP_ABx(OP_LOADL, cursp(), off);
}
genop(s, co);
}
push();
}
break;
@@ -1654,6 +1796,15 @@ codegen(codegen_scope *s, node *tree, int val)
}
break;
case NODE_DSYM:
codegen(s, tree, val);
if (val) {
pop();
genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern(s->mrb, "intern")), 0));
push();
}
break;
case NODE_SELF:
if (val) {
genop(s, MKOP_A(OP_LOADSELF, cursp()));
@@ -1843,7 +1994,7 @@ static codegen_scope*
scope_new(mrb_state *mrb, codegen_scope *prev, node *lv)
{
mrb_pool *pool = mrb_pool_open(mrb);
codegen_scope *p = mrb_pool_alloc(pool, sizeof(codegen_scope));
codegen_scope *p = (codegen_scope *)mrb_pool_alloc(pool, sizeof(codegen_scope));
if (!p) return 0;
memset(p, 0, sizeof(codegen_scope));
@@ -1852,15 +2003,16 @@ scope_new(mrb_state *mrb, codegen_scope *prev, node *lv)
if (!prev) return p;
p->prev = prev;
p->ainfo = -1;
p->mscope = 0;
p->mrb = prev->mrb;
p->icapa = 1024;
p->iseq = mrb_malloc(mrb, sizeof(mrb_code)*p->icapa);
p->iseq = (mrb_code *)mrb_malloc(mrb, sizeof(mrb_code)*p->icapa);
p->pcapa = 32;
p->pool = mrb_malloc(mrb, sizeof(mrb_value)*p->pcapa);
p->pool = (mrb_value *)mrb_malloc(mrb, sizeof(mrb_value)*p->pcapa);
p->syms = mrb_malloc(mrb, sizeof(mrb_sym)*256);
p->syms = (mrb_sym *)mrb_malloc(mrb, sizeof(mrb_sym)*256);
p->lv = lv;
p->sp += node_len(lv)+2;
@@ -1879,20 +2031,20 @@ scope_finish(codegen_scope *s, int idx)
mrb_irep *irep;
mrb_add_irep(mrb, idx);
irep = mrb->irep[idx] = mrb_malloc(mrb, sizeof(mrb_irep));
irep = mrb->irep[idx] = (mrb_irep *)mrb_malloc(mrb, sizeof(mrb_irep));
irep->idx = idx;
irep->flags = 0;
if (s->iseq) {
irep->iseq = codegen_realloc(s, s->iseq, sizeof(mrb_code)*s->pc);
irep->iseq = (mrb_code *)codegen_realloc(s, s->iseq, sizeof(mrb_code)*s->pc);
irep->ilen = s->pc;
}
if (s->pool) {
irep->pool = codegen_realloc(s, s->pool, sizeof(mrb_value)*s->plen);
irep->pool = (mrb_value *)codegen_realloc(s, s->pool, sizeof(mrb_value)*s->plen);
irep->plen = s->plen;
}
if (s->syms) {
irep->syms = codegen_realloc(s, s->syms, sizeof(mrb_sym)*s->slen);
irep->syms = (mrb_sym *)codegen_realloc(s, s->syms, sizeof(mrb_sym)*s->slen);
irep->slen = s->slen;
}
@@ -1906,7 +2058,7 @@ scope_finish(codegen_scope *s, int idx)
static struct loopinfo*
loop_push(codegen_scope *s, enum looptype t)
{
struct loopinfo *p = codegen_palloc(s, sizeof(struct loopinfo));
struct loopinfo *p = (struct loopinfo *)codegen_palloc(s, sizeof(struct loopinfo));
p->type = t;
p->pc1 = p->pc2 = p->pc3 = 0;
@@ -1971,6 +2123,7 @@ loop_pop(codegen_scope *s, int val)
static void
codedump(mrb_state *mrb, int n)
{
#ifdef ENABLE_STDIO
mrb_irep *irep = mrb->irep[n];
int i;
mrb_code c;
@@ -1995,7 +2148,7 @@ codedump(mrb_state *mrb, int n)
printf("OP_LOADI\tR%d\t%d\n", GETARG_A(c), GETARG_sBx(c));
break;
case OP_LOADSYM:
printf("OP_LOADSYM\tR%d\t'%s'\n", GETARG_A(c),
printf("OP_LOADSYM\tR%d\t:%s\n", GETARG_A(c),
mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)]));
break;
case OP_LOADNIL:
@@ -2011,20 +2164,20 @@ codedump(mrb_state *mrb, int n)
printf("OP_LOADF\tR%d\n", GETARG_A(c));
break;
case OP_GETGLOBAL:
printf("OP_GETGLOBAL\tR%d\t'%s'\n", GETARG_A(c),
printf("OP_GETGLOBAL\tR%d\t:%s\n", GETARG_A(c),
mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)]));
break;
case OP_SETGLOBAL:
printf("OP_SETGLOBAL\t'%s'\tR%d\n",
printf("OP_SETGLOBAL\t:%s\tR%d\n",
mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)]),
GETARG_A(c));
break;
case OP_GETCONST:
printf("OP_GETCONST\tR%d\t'%s'\n", GETARG_A(c),
printf("OP_GETCONST\tR%d\t:%s\n", GETARG_A(c),
mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)]));
break;
case OP_SETCONST:
printf("OP_SETCONST\t'%s'\tR%d\n",
printf("OP_SETCONST\t:%s\tR%d\n",
mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)]),
GETARG_A(c));
break;
@@ -2073,7 +2226,12 @@ codedump(mrb_state *mrb, int n)
printf("OP_JMPNOT\tR%d\t%03d\n", GETARG_A(c), i+GETARG_sBx(c));
break;
case OP_SEND:
printf("OP_SEND\tR%d\t'%s'\t%d\n", GETARG_A(c),
printf("OP_SEND\tR%d\t:%s\t%d\n", GETARG_A(c),
mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
GETARG_C(c));
break;
case OP_TAILCALL:
printf("OP_TAILCALL\tR%d\t:%s\t%d\n", GETARG_A(c),
mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
GETARG_C(c));
break;
@@ -2128,37 +2286,52 @@ codedump(mrb_state *mrb, int n)
printf("OP_RANGE\tR%d\tR%d\t%d\n", GETARG_A(c), GETARG_B(c), GETARG_C(c));
break;
case OP_METHOD:
printf("OP_METHOD\tR%d\t'%s'\n", GETARG_A(c),
printf("OP_METHOD\tR%d\t:%s\n", GETARG_A(c),
mrb_sym2name(mrb, irep->syms[GETARG_B(c)]));
break;
case OP_ADD:
printf("OP_ADD\tR%d\t'%s'\t%d\n", GETARG_A(c),
printf("OP_ADD\tR%d\t:%s\t%d\n", GETARG_A(c),
mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
GETARG_C(c));
break;
case OP_SUB:
printf("OP_SUB\tR%d\t'%s'\t%d\n", GETARG_A(c),
printf("OP_SUB\tR%d\t:%s\t%d\n", GETARG_A(c),
mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
GETARG_C(c));
break;
case OP_MUL:
printf("OP_MUL\tR%d\t:%s\t%d\n", GETARG_A(c),
mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
GETARG_C(c));
break;
case OP_DIV:
printf("OP_DIV\tR%d\t:%s\t%d\n", GETARG_A(c),
mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
GETARG_C(c));
break;
case OP_LT:
printf("OP_LT\tR%d\t'%s'\t%d\n", GETARG_A(c),
printf("OP_LT\tR%d\t:%s\t%d\n", GETARG_A(c),
mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
GETARG_C(c));
break;
case OP_LE:
printf("OP_LE\tR%d\t'%s'\t%d\n", GETARG_A(c),
printf("OP_LE\tR%d\t:%s\t%d\n", GETARG_A(c),
mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
GETARG_C(c));
break;
case OP_GT:
printf("OP_GT\tR%d\t'%s'\t%d\n", GETARG_A(c),
printf("OP_GT\tR%d\t:%s\t%d\n", GETARG_A(c),
mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
GETARG_C(c));
break;
case OP_GE:
printf("OP_GE\tR%d\t'%s'\t%d\n", GETARG_A(c),
printf("OP_GE\tR%d\t:%s\t%d\n", GETARG_A(c),
mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
GETARG_C(c));
break;
case OP_EQ:
printf("OP_EQ\tR%d\t:%s\t%d\n", GETARG_A(c),
mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
GETARG_C(c));
break;
@@ -2183,7 +2356,12 @@ codedump(mrb_state *mrb, int n)
printf("OP_APOST\tR%d\t%d\t%d\n", GETARG_A(c), GETARG_B(c), GETARG_C(c));
break;
case OP_STRING:
printf("OP_STRING\tR%d\t'%s'\n", GETARG_A(c), RSTRING_PTR(irep->pool[GETARG_Bx(c)]));
{
mrb_value s = irep->pool[GETARG_Bx(c)];
s = mrb_str_dump(mrb, s);
printf("OP_STRING\tR%d\t%s\n", GETARG_A(c), RSTRING_PTR(s));
}
break;
case OP_STRCAT:
printf("OP_STRCAT\tR%d\tR%d\n", GETARG_A(c), GETARG_B(c));
@@ -2196,11 +2374,11 @@ codedump(mrb_state *mrb, int n)
printf("OP_OCLASS\tR%d\n", GETARG_A(c));
break;
case OP_CLASS:
printf("OP_CLASS\tR%d\t'%s'\n", GETARG_A(c),
printf("OP_CLASS\tR%d\t:%s\n", GETARG_A(c),
mrb_sym2name(mrb, irep->syms[GETARG_B(c)]));
break;
case OP_MODULE:
printf("OP_MODULE\tR%d\t'%s'\n", GETARG_A(c),
printf("OP_MODULE\tR%d\t:%s\n", GETARG_A(c),
mrb_sym2name(mrb, irep->syms[GETARG_B(c)]));
break;
case OP_EXEC:
@@ -2213,7 +2391,7 @@ codedump(mrb_state *mrb, int n)
printf("OP_TCLASS\tR%d\n", GETARG_A(c));
break;
case OP_ERR:
printf("OP_ERR\t:L(%d)\n", GETARG_Bx(c));
printf("OP_ERR\tL(%d)\n", GETARG_Bx(c));
break;
case OP_EPUSH:
printf("OP_EPUSH\t:I(%d)\n", n+GETARG_Bx(c));
@@ -2241,6 +2419,7 @@ codedump(mrb_state *mrb, int n)
}
}
printf("\n");
#endif
}
void
-35
View File
@@ -5,41 +5,6 @@
*/
#include "mruby.h"
#include "mruby/string.h"
#include "mruby/numeric.h"
void
mrb_cmperr(mrb_state *mrb, mrb_value x, mrb_value y)
{
const char *classname;
if (SPECIAL_CONST_P(y)) {
y = mrb_inspect(mrb, y);
classname = mrb_string_value_ptr(mrb, y);
}
else {
classname = mrb_obj_classname(mrb, y);
}
mrb_raise(mrb, E_ARGUMENT_ERROR, "comparison of %s with %s failed",
mrb_obj_classname(mrb, x), classname);
}
int
mrb_cmpint(mrb_state *mrb, mrb_value val, mrb_value a, mrb_value b)
{
if (mrb_nil_p(val)) {
mrb_cmperr(mrb, a, b);
}
if (FIXNUM_P(val)) {
long l = mrb_fixnum(val);
if (l > 0) return 1;
if (l < 0) return -1;
return 0;
}
if (mrb_test(mrb_funcall(mrb, val, ">", 1, mrb_fixnum_value(0)))) return 1;
if (mrb_test(mrb_funcall(mrb, val, "<", 1, mrb_fixnum_value(0)))) return -1;
return 0;
}
void
mrb_init_comparable(mrb_state *mrb)
+33 -26
View File
@@ -8,7 +8,7 @@
#include "mruby/dump.h"
#include "mruby/string.h"
#ifdef INCLUDE_REGEXP
#ifdef ENABLE_REGEXP
#include "re.h"
#endif
#include "mruby/irep.h"
@@ -222,22 +222,23 @@ get_pool_block_size(mrb_state *mrb, mrb_irep *irep, int type)
for (pool_no = 0; pool_no < irep->plen; pool_no++) {
uint16_t nlen =0;
int len;
switch (irep->pool[pool_no].tt) {
case MRB_TT_FIXNUM:
sprintf( buf, "%d", irep->pool[pool_no].value.i);
size += strlen(buf);
len = sprintf( buf, "%d", irep->pool[pool_no].value.i);
size += (uint32_t)len;
break;
case MRB_TT_FLOAT:
sprintf( buf, "%.16e", irep->pool[pool_no].value.f);
size += strlen(buf);
len = sprintf( buf, "%.16e", irep->pool[pool_no].value.f);
size += (uint32_t)len;
break;
case MRB_TT_STRING:
str = mrb_string_value( mrb, &irep->pool[pool_no]);
nlen = str_dump_len(RSTRING_PTR(str), RSTRING_LEN(str), type);
size += nlen;
break;
#ifdef INCLUDE_REGEXP
#ifdef ENABLE_REGEXP
case MRB_TT_REGEX:
str = mrb_reg_to_s(mrb, irep->pool[pool_no]);
nlen = str_dump_len(RSTRING_PTR(str), RSTRING_LEN(str), type);
@@ -268,8 +269,10 @@ get_syms_block_size(mrb_state *mrb, mrb_irep *irep, int type)
size += DUMP_SIZE(MRB_DUMP_SIZE_OF_SHORT, type); /* snl(n) */
if (irep->syms[sym_no] != 0) {
name = mrb_sym2name(mrb, irep->syms[sym_no]);
nlen = str_dump_len((char*)name, strlen(name), type);
int len;
name = mrb_sym2name_len(mrb, irep->syms[sym_no], &len);
nlen = str_dump_len((char*)name, len, type);
size += nlen; /* sn(n) */
}
}
@@ -329,9 +332,10 @@ write_pool_block(mrb_state *mrb, mrb_irep *irep, char *buf, int type)
char *buf_top = buf;
char *char_buf;
uint16_t buf_size =0;
int len;
buf_size = MRB_DUMP_DEFAULT_STR_LEN;
if ((char_buf = mrb_malloc(mrb, buf_size)) == 0)
if ((char_buf = (char *)mrb_malloc(mrb, buf_size)) == 0)
goto error_exit;
buf += uint32_dump((uint32_t)irep->plen, buf, type); /* number of pool */
@@ -356,14 +360,14 @@ write_pool_block(mrb_state *mrb, mrb_irep *irep, char *buf, int type)
nlen = str_dump_len(RSTRING_PTR(str), RSTRING_LEN(str), type);
if ( nlen > buf_size - 1) {
buf_size = nlen + 1;
if ((char_buf = mrb_realloc(mrb, char_buf, buf_size)) == 0)
if ((char_buf = (char *)mrb_realloc(mrb, char_buf, buf_size)) == 0)
goto error_exit;
memset(char_buf, 0, buf_size);
}
str_dump(RSTRING_PTR(str), char_buf, RSTRING_LEN(str), type);
break;
#ifdef INCLUDE_REGEXP
#ifdef ENABLE_REGEXP
case MRB_TT_REGEX:
str = mrb_reg_to_s(mrb, irep->pool[pool_no]);
nlen = str_dump_len(RSTRING_PTR(str), RSTRING_LEN(str), type);
@@ -382,10 +386,12 @@ write_pool_block(mrb_state *mrb, mrb_irep *irep, char *buf, int type)
continue;
}
buf += uint16_dump((uint16_t)strlen(char_buf), buf, type); /* data length */
len = strlen(char_buf);
memcpy(buf, char_buf, strlen(char_buf));
buf += strlen(char_buf);
buf += uint16_dump((uint16_t)len, buf, type); /* data length */
memcpy(buf, char_buf, len);
buf += len;
}
error_exit:
@@ -403,7 +409,7 @@ write_syms_block(mrb_state *mrb, mrb_irep *irep, char *buf, int type)
uint16_t buf_size =0;
buf_size = MRB_DUMP_DEFAULT_STR_LEN;
if ((char_buf = mrb_malloc(mrb, buf_size)) == 0)
if ((char_buf = (char *)mrb_malloc(mrb, buf_size)) == 0)
goto error_exit;
buf += uint32_dump((uint32_t)irep->slen, buf, type); /* number of symbol */
@@ -413,15 +419,17 @@ write_syms_block(mrb_state *mrb, mrb_irep *irep, char *buf, int type)
uint16_t nlen =0;
if (irep->syms[sym_no] != 0) {
name = mrb_sym2name(mrb, irep->syms[sym_no]);
nlen = str_dump_len((char*)name, strlen(name), type);
int len;
name = mrb_sym2name_len(mrb, irep->syms[sym_no], &len);
nlen = str_dump_len((char*)name, len, type);
if ( nlen > buf_size - 1) {
buf_size = nlen + 1;
if ((char_buf = mrb_realloc(mrb, char_buf, buf_size)) == 0)
if ((char_buf = (char *)mrb_realloc(mrb, char_buf, buf_size)) == 0)
goto error_exit;
}
memset(char_buf, 0, buf_size);
str_dump((char*)name, char_buf, strlen(name), type);
str_dump((char*)name, char_buf, len, type);
buf += uint16_dump(nlen, buf, type); /* length of symbol name */
memcpy(buf, char_buf, nlen); /* symbol name */
@@ -453,11 +461,10 @@ calc_crc_section(mrb_state *mrb, mrb_irep *irep, uint16_t *crc, int section)
default: return MRB_DUMP_GENERAL_FAILURE;
}
if ((buf = mrb_malloc(mrb, buf_size)) == 0)
if ((buf = (char *)mrb_calloc(mrb, 1, buf_size)) == 0)
return MRB_DUMP_GENERAL_FAILURE;
buf_top = buf;
memset(buf, 0, buf_size);
switch (section) {
case DUMP_IREP_HEADER: buf += write_irep_header(mrb, irep, buf, type); break;
@@ -591,13 +598,13 @@ dump_irep_record(mrb_state *mrb, int irep_no, FILE* fp, uint32_t *rlen)
if (irep_record_size == 0)
return MRB_DUMP_GENERAL_FAILURE;
if ((buf = mrb_malloc(mrb, irep_record_size)) == 0)
if ((buf = (char *)mrb_calloc(mrb, 1, irep_record_size)) == 0)
return MRB_DUMP_GENERAL_FAILURE;
memset( buf, 0, irep_record_size);
if ((rc = write_irep_record(mrb, irep_no, buf, rlen, DUMP_TYPE_HEX)) != MRB_DUMP_OK)
if ((rc = write_irep_record(mrb, irep_no, buf, rlen, DUMP_TYPE_HEX)) != MRB_DUMP_OK) {
rc = MRB_DUMP_GENERAL_FAILURE;
goto error_exit;
}
if (fwrite(buf, irep_record_size, 1, fp) != 1)
@@ -683,7 +690,7 @@ mrb_bdump_irep(mrb_state *mrb, int n, FILE *f,const char *initname)
buf_size += get_irep_record_size(mrb, irep_no, DUMP_TYPE_BIN);
buf_size += MRB_DUMP_SIZE_OF_LONG; /* end of file */
if ((buf = mrb_malloc(mrb, buf_size)) == 0)
if ((buf = (char *)mrb_malloc(mrb, buf_size)) == 0)
return MRB_DUMP_GENERAL_FAILURE;
rc = mrb_write_irep(mrb, n, buf);
+50 -137
View File
@@ -6,28 +6,15 @@
#include "mruby.h"
#include <stdarg.h>
#include <string.h>
#include <stdio.h>
#include <setjmp.h>
#include "error.h"
#include "opcode.h"
#include "mruby/irep.h"
#include "mruby/proc.h"
#include "mruby/numeric.h"
#include "mruby/variable.h"
#include "mruby/string.h"
#include "mruby/class.h"
#define warn_printf printf
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
mrb_value
mrb_exc_new(mrb_state *mrb, struct RClass *c, const char *ptr, long len)
{
@@ -42,7 +29,6 @@ mrb_exc_new3(mrb_state *mrb, struct RClass* c, mrb_value str)
return mrb_funcall(mrb, mrb_obj_value(c), "new", 1, str);
}
//mrb_value make_exception(mrb_state *mrb, int argc, mrb_value *argv, int isstr);
/*
* call-seq:
* Exception.new(msg = nil) -> exception
@@ -79,14 +65,14 @@ static mrb_value
exc_exception(mrb_state *mrb, mrb_value self)
{
mrb_value exc;
mrb_value *argv;
mrb_value a;
int argc;
mrb_get_args(mrb, "*", &argv, &argc);
argc = mrb_get_args(mrb, "|o", &a);
if (argc == 0) return self;
if (argc == 1 && mrb_obj_equal(mrb, self, argv[0])) return self;
if (mrb_obj_equal(mrb, self, a)) return self;
exc = mrb_obj_clone(mrb, self);
exc_initialize(mrb, exc);
mrb_iv_set(mrb, exc, mrb_intern(mrb, "mesg"), a);
return exc;
}
@@ -134,20 +120,15 @@ exc_message(mrb_state *mrb, mrb_value exc)
static mrb_value
exc_inspect(mrb_state *mrb, mrb_value exc)
{
mrb_value str, klass;
mrb_value str;
klass = mrb_str_new2(mrb, mrb_obj_classname(mrb, exc));
str = mrb_str_new2(mrb, mrb_obj_classname(mrb, exc));
exc = mrb_obj_as_string(mrb, exc);
if (RSTRING_LEN(exc) == 0) {
return klass;
if (RSTRING_LEN(exc) > 0) {
mrb_str_cat2(mrb, str, ": ");
mrb_str_append(mrb, str, exc);
}
str = mrb_str_new2(mrb, "#<");
mrb_str_append(mrb, str, klass);
mrb_str_cat2(mrb, str, ": ");
mrb_str_append(mrb, str, exc);
mrb_str_cat2(mrb, str, ">");
return str;
}
@@ -163,7 +144,7 @@ exc_equal(mrb_state *mrb, mrb_value exc)
if (mrb_obj_equal(mrb, exc, obj)) return mrb_true_value();
if (mrb_obj_class(mrb, exc) != mrb_obj_class(mrb, obj)) {
if ( mrb_respond_to(mrb, obj, mrb_intern(mrb, "message")) ) {
if (mrb_respond_to(mrb, obj, mrb_intern(mrb, "message"))) {
mesg = mrb_funcall(mrb, obj, "message", 0);
}
else
@@ -185,25 +166,20 @@ mrb_exc_raise(mrb_state *mrb, mrb_value exc)
longjmp(*(jmp_buf*)mrb->jmp, 1);
}
void
mrb_raise_va(mrb_state *mrb, struct RClass *c, const char *fmt, va_list args)
{
char buf[256];
vsnprintf(buf, 256, fmt, args);
mrb_exc_raise(mrb, mrb_exc_new(mrb, c, buf, strlen(buf)));
}
void
mrb_raise(mrb_state *mrb, struct RClass *c, const char *fmt, ...)
{
va_list args;
char buf[256];
int n;
va_start(args, fmt);
vsnprintf(buf, 256, fmt, args);
n = vsnprintf(buf, sizeof(buf), fmt, args);
va_end(args);
mrb_exc_raise(mrb, mrb_exc_new(mrb, c, buf, strlen(buf)));
if (n < 0) {
n = 0;
}
mrb_exc_raise(mrb, mrb_exc_new(mrb, c, buf, n));
}
void
@@ -212,51 +188,44 @@ mrb_name_error(mrb_state *mrb, mrb_sym id, const char *fmt, ...)
mrb_value exc, argv[2];
va_list args;
char buf[256];
int n;
va_start(args, fmt);
//argv[0] = mrb_vsprintf(fmt, args);
vsnprintf(buf, 256, fmt, args);
argv[0] = mrb_str_new(mrb, buf, strlen(buf));
n = vsnprintf(buf, sizeof(buf), fmt, args);
va_end(args);
argv[1] = mrb_str_new_cstr(mrb, mrb_sym2name(mrb, id));
exc = mrb_class_new_instance(mrb, 2, argv, E_NAME_ERROR);
if (n < 0) {
n = 0;
}
argv[0] = mrb_str_new(mrb, buf, n);
argv[1] = mrb_symbol_value(id); /* ignore now */
exc = mrb_class_new_instance(mrb, 1, argv, E_NAME_ERROR);
mrb_exc_raise(mrb, exc);
}
mrb_value
mrb_sprintf(mrb_state *mrb, const char *fmt, ...)
{
va_list args;
char buf[256];
int n;
va_start(args, fmt);
vsnprintf(buf, 256, fmt, args);
n = vsnprintf(buf, sizeof(buf), fmt, args);
va_end(args);
return mrb_str_new(mrb, buf, strlen(buf));
if (n < 0) {
n = 0;
}
return mrb_str_new(mrb, buf, n);
}
void
mrb_warn(const char *fmt, ...)
{
va_list args;
char buf[256];
va_start(args, fmt);
snprintf(buf, 256, "warning: %s", fmt);
printf(buf, args);
va_end(args);
}
void
mrb_warning(const char *fmt, ...)
{
va_list args;
char buf[256];
va_start(args, fmt);
snprintf(buf, 256, "warning: %s", fmt);
printf(buf, args);
printf("warning: ");
vprintf(fmt, args);
va_end(args);
}
@@ -264,12 +233,12 @@ void
mrb_bug(const char *fmt, ...)
{
va_list args;
char buf[256];
va_start(args, fmt);
snprintf(buf, 256, "bug: %s", fmt);
printf(buf, args);
printf("bug: ");
vprintf(fmt, args);
va_end(args);
exit(EXIT_FAILURE);
}
static const char *
@@ -304,28 +273,6 @@ sysexit_status(mrb_state *mrb, mrb_value err)
return mrb_fixnum(st);
}
void
error_pos(void)
{
#if 0
const char *sourcefile = mrb_sourcefile();
int sourceline = mrb_sourceline();
if (sourcefile) {
if (sourceline == 0) {
warn_printf("%s", sourcefile);
}
else if (mrb_frame_callee()) {
warn_printf("%s:%d:in `%s'", sourcefile, sourceline,
mrb_sym2name(mrb, mrb_frame_callee()));
}
else {
warn_printf("%s:%d", sourcefile, sourceline);
}
}
#endif
}
static void
set_backtrace(mrb_state *mrb, mrb_value info, mrb_value bt)
{
@@ -348,7 +295,7 @@ make_exception(mrb_state *mrb, int argc, mrb_value *argv, int isstr)
if (isstr) {
mesg = mrb_check_string_type(mrb, argv[0]);
if (!mrb_nil_p(mesg)) {
mesg = mrb_exc_new3(mrb, mrb->eRuntimeError_class, mesg);
mesg = mrb_exc_new3(mrb, E_RUNTIME_ERROR, mesg);
break;
}
}
@@ -359,20 +306,15 @@ make_exception(mrb_state *mrb, int argc, mrb_value *argv, int isstr)
case 3:
n = 1;
exception_call:
//if (argv[0] == sysstack_error) return argv[0];
//CONST_ID(mrb, exception, "exception");
//mesg = mrb_check_funcall(mrb, argv[0], exception, n, argv+1);
//if (mrb_nil_p(mesg)) {
// /* undef */
// mrb_raise(mrb, E_TYPE_ERROR, "exception class/object expected");
//}
if (mrb_respond_to(mrb, argv[0], mrb_intern(mrb, "exception"))) {
mesg = mrb_funcall(mrb, argv[0], "exception", n, argv+1);
}
else {
/* undef */
mrb_raise(mrb, E_TYPE_ERROR, "exception class/object expected");
{
mrb_sym exc = mrb_intern(mrb, "exception");
if (mrb_respond_to(mrb, argv[0], exc)) {
mesg = mrb_funcall_argv(mrb, argv[0], exc, n, argv+1);
}
else {
/* undef */
mrb_raise(mrb, E_TYPE_ERROR, "exception class/object expected");
}
}
break;
@@ -399,16 +341,13 @@ mrb_make_exception(mrb_state *mrb, int argc, mrb_value *argv)
void
mrb_sys_fail(mrb_state *mrb, const char *mesg)
{
mrb_raise(mrb, mrb->eRuntimeError_class, "%s", mesg);
mrb_raise(mrb, E_RUNTIME_ERROR, "%s", mesg);
}
void
mrb_init_exception(mrb_state *mrb)
{
struct RClass *e;
struct RClass *eIndexError;
struct RClass *eRangeError;
struct RClass *eNameError;
mrb->eException_class = e = mrb_define_class(mrb, "Exception", mrb->object_class); /* 15.2.22 */
mrb_define_class_method(mrb, e, "exception", mrb_instance_new, ARGS_ANY());
@@ -419,32 +358,6 @@ mrb_init_exception(mrb_state *mrb)
mrb_define_method(mrb, e, "message", exc_message, ARGS_NONE());
mrb_define_method(mrb, e, "inspect", exc_inspect, ARGS_NONE());
mrb->eStandardError_class = mrb_define_class(mrb, "StandardError", mrb->eException_class); /* 15.2.23 */
mrb->eRuntimeError_class = mrb_define_class(mrb, "RuntimeError", mrb->eStandardError_class); /* 15.2.28 */
mrb_define_class(mrb, "TypeError", mrb->eStandardError_class); /* 15.2.29 */
mrb_define_class(mrb, "ArgumentError", mrb->eStandardError_class); /* 15.2.24 */
eIndexError = mrb_define_class(mrb, "IndexError", mrb->eStandardError_class); /* 15.2.33 */
eRangeError = mrb_define_class(mrb, "RangeError", mrb->eStandardError_class); /* 15.2.26 */
eNameError = mrb_define_class(mrb, "NameError", mrb->eStandardError_class); /* 15.2.31 */
mrb_define_class(mrb, "NoMethodError", eNameError); /* 15.2.32 */
// eScriptError = mrb_define_class(mrb, "ScriptError", mrb->eException_class); /* 15.2.37 */
// mrb_define_class(mrb, "SyntaxError", eScriptError); /* 15.2.38 */
// mrb_define_class(mrb, "LoadError", eScriptError); /* 15.2.39 */
// mrb_define_class(mrb, "NotImplementedError", eScriptError_class);
// mrb_define_class(mrb, "SystemCallError", mrb->eStandardError_class); /* 15.2.36 */
mrb_define_class(mrb, "LocalJumpError", mrb->eStandardError_class); /* 15.2.25 */
#ifdef INCLUDE_REGEX
mrb_define_class(mrb, "RegexpError", mrb->eStandardError_class); /* 15.2.27 */
#endif
#ifdef INCLUDE_ENCODING
mrb_define_class(mrb, "EncodingError", mrb->eStandardError_class);
#endif
// mrb_define_class(mrb, "ZeroDivisionError", mrb->eStandardError_class); /* 15.2.30 */
mrb_define_class(mrb, "FloatDomainError", eRangeError);
mrb_define_class(mrb, "KeyError", eIndexError);
mrb->eStandardError_class = mrb_define_class(mrb, "StandardError", mrb->eException_class); /* 15.2.23 */
mrb_define_class(mrb, "RuntimeError", mrb->eStandardError_class); /* 15.2.28 */
}
-3
View File
@@ -12,13 +12,10 @@ struct RException {
};
void mrb_sys_fail(mrb_state *mrb, const char *mesg);
void mrb_exc_raise(mrb_state *mrb, mrb_value mesg);
void mrb_bug_errno(const char*, int);
int sysexit_status(mrb_state *mrb, mrb_value err);
void error_pos(void);
mrb_value mrb_exc_new3(mrb_state *mrb, struct RClass* c, mrb_value str);
mrb_value make_exception(mrb_state *mrb, int argc, mrb_value *argv, int isstr);
mrb_value mrb_exc_new(mrb_state *mrb, struct RClass *c, const char *ptr, long len);
mrb_value mrb_make_exception(mrb_state *mrb, int argc, mrb_value *argv);
mrb_value mrb_sprintf(mrb_state *mrb, const char *fmt, ...);
void mrb_name_error(mrb_state *mrb, mrb_sym id, const char *fmt, ...);
+54 -162
View File
@@ -10,14 +10,6 @@
#include "mruby/numeric.h"
#include "mruby/data.h"
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
struct RData*
mrb_data_object_alloc(mrb_state *mrb, struct RClass *klass, void *ptr, const struct mrb_data_type *type)
{
@@ -60,11 +52,6 @@ mrb_check_datatype(mrb_state *mrb, mrb_value obj, const struct mrb_data_type *ty
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;
@@ -78,21 +65,6 @@ mrb_lastline_get(mrb_state *mrb)
}
}
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
@@ -111,14 +83,6 @@ mrb_exec_recursive(mrb_state *mrb, mrb_value (*func) (mrb_state *, mrb_value, mr
* 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)
{
@@ -157,136 +121,64 @@ 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>.
*/
static mrb_int
float_id(mrb_float f)
{
const char *p = (const char*)&f;
int len = sizeof(f);
mrb_int id = 0;
/*
* 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.
*/
while (len--) {
id = id*65599 + *p;
p++;
}
id = id + (id>>5);
int
return id;
}
mrb_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 */
mrb_int tt = obj.tt;
#define MakeID2(p,t) (((intptr_t)(p))^(t))
#define MakeID(p) MakeID2(p,tt)
switch (tt) {
case MRB_TT_FREE:
case MRB_TT_UNDEF:
return MakeID(0); /* not define */
case MRB_TT_FALSE:
if (mrb_nil_p(obj))
return MakeID(1);
return MakeID(0);
case MRB_TT_TRUE:
return MakeID(1);
case MRB_TT_SYMBOL:
return MakeID(SYM2ID(obj));
case MRB_TT_FIXNUM:
return MakeID2(float_id((mrb_float)mrb_fixnum(obj)), MRB_TT_FLOAT);
case MRB_TT_FLOAT:
return MakeID(float_id(mrb_float(obj)));
case MRB_TT_STRING:
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_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:
default:
return MakeID(obj.value.p);
}
}
+110 -37
View File
@@ -11,13 +11,15 @@
#include "mruby/string.h"
#include "mruby/hash.h"
#include "mruby/range.h"
#include "mruby/khash.h"
#include <string.h>
#include <stdio.h>
#include "mruby/struct.h"
#include "mruby/proc.h"
#include "mruby/data.h"
#include "mruby/numeric.h"
#include "mruby/variable.h"
#ifndef SIZE_MAX
#include <limits.h> // for SIZE_MAX
#endif
/*
= Tri-color Incremental Garbage Collection
@@ -70,13 +72,38 @@
*/
#ifdef INCLUDE_REGEXP
#ifdef ENABLE_REGEXP
#include "re.h"
#endif
#include "gc.h"
struct free_obj {
MRUBY_OBJECT_HEADER;
struct RBasic *next;
};
typedef struct {
union {
struct free_obj free;
struct RBasic basic;
struct RObject object;
struct RClass klass;
struct RString string;
struct RArray array;
struct RHash hash;
struct RRange range;
#ifdef ENABLE_STRUCT
struct RStruct structdata;
#endif
struct RProc procdata;
#ifdef ENABLE_REGEXP
struct RMatch match;
struct RRegexp regexp;
#endif
} as;
} RVALUE;
#ifdef GC_PROFILE
#include <stdio.h>
#include <sys/time.h>
static double program_invoke_time = 0;
@@ -121,25 +148,40 @@ gettimeofday_time(void)
#define GC_STEP_SIZE 1024
void*
mrb_realloc(mrb_state *mrb, void *p, size_t len)
{
return (mrb->allocf)(mrb, p, len);
void *p2;
p2 = (mrb->allocf)(mrb, p, len);
if (!p2 && len > 0 && mrb->heaps) {
mrb_garbage_collect(mrb);
p2 = (mrb->allocf)(mrb, p, len);
}
return p2;
}
void*
mrb_malloc(mrb_state *mrb, size_t len)
{
return (mrb->allocf)(mrb, 0, len);
return mrb_realloc(mrb, 0, len);
}
void*
mrb_calloc(mrb_state *mrb, size_t nelem, size_t len)
{
void *p = (mrb->allocf)(mrb, 0, nelem*len);
void *p = NULL;
size_t size;
if (nelem <= SIZE_MAX / len) {
size = nelem * len;
p = mrb_realloc(mrb, 0, size);
if (p && size > 0)
memset(p, 0, size);
}
memset(p, 0, nelem*len);
return p;
}
@@ -149,7 +191,9 @@ mrb_free(mrb_state *mrb, void *p)
return (mrb->allocf)(mrb, p, 0);
}
#define HEAP_PAGE_SIZE 1024
#ifndef MRB_HEAP_PAGE_SIZE
#define MRB_HEAP_PAGE_SIZE 1024
#endif
struct heap_page {
struct RBasic *freelist;
@@ -157,7 +201,7 @@ struct heap_page {
struct heap_page *next;
struct heap_page *free_next;
struct heap_page *free_prev;
RVALUE objects[HEAP_PAGE_SIZE];
RVALUE objects[MRB_HEAP_PAGE_SIZE];
};
static void
@@ -208,13 +252,11 @@ unlink_free_heap_page(mrb_state *mrb, struct heap_page *page)
static void
add_heap(mrb_state *mrb)
{
struct heap_page *page = mrb_malloc(mrb, sizeof(struct heap_page));
struct heap_page *page = (struct heap_page *)mrb_calloc(mrb, 1, sizeof(struct heap_page));
RVALUE *p, *e;
struct RBasic *prev = NULL;
memset(page, 0, sizeof(struct heap_page));
for (p = page->objects, e=p+HEAP_PAGE_SIZE; p<e; p++) {
for (p = page->objects, e=p+MRB_HEAP_PAGE_SIZE; p<e; p++) {
p->as.free.tt = MRB_TT_FREE;
p->as.free.next = prev;
prev = &p->as.basic;
@@ -248,7 +290,7 @@ gc_protect(mrb_state *mrb, struct RBasic *p)
if (mrb->arena_idx > MRB_ARENA_SIZE) {
/* arena overflow error */
mrb->arena_idx = MRB_ARENA_SIZE - 4; /* force room in arena */
mrb_raise(mrb, mrb->eRuntimeError_class, "arena overflow error");
mrb_raise(mrb, E_RUNTIME_ERROR, "arena overflow error");
}
mrb->arena[mrb->arena_idx++] = p;
}
@@ -316,8 +358,8 @@ gc_mark_children(mrb_state *mrb, struct RBasic *obj)
break;
case MRB_TT_CLASS:
case MRB_TT_SCLASS:
case MRB_TT_MODULE:
case MRB_TT_SCLASS:
{
struct RClass *c = (struct RClass*)obj;
@@ -361,7 +403,7 @@ gc_mark_children(mrb_state *mrb, struct RBasic *obj)
size_t i, e;
for (i=0,e=a->len; i<e; i++) {
mrb_gc_mark_value(mrb, a->buf[i]);
mrb_gc_mark_value(mrb, a->ptr[i]);
}
}
break;
@@ -372,13 +414,6 @@ gc_mark_children(mrb_state *mrb, struct RBasic *obj)
break;
case MRB_TT_STRING:
{
struct RString *s = (struct RString*)obj;
if (s->flags & MRB_STR_SHARED) {
mrb_gc_mark(mrb, (struct RBasic*)s->aux.shared);
}
}
break;
case MRB_TT_RANGE:
@@ -390,7 +425,7 @@ gc_mark_children(mrb_state *mrb, struct RBasic *obj)
}
break;
#ifdef INCLUDE_REGEXP
#ifdef ENABLE_REGEXP
case MRB_TT_MATCH:
{
struct RMatch *m = (struct RMatch*)obj;
@@ -408,6 +443,18 @@ gc_mark_children(mrb_state *mrb, struct RBasic *obj)
break;
#endif
#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;
}
@@ -458,7 +505,10 @@ obj_free(mrb_state *mrb, struct RBasic *obj)
break;
case MRB_TT_ARRAY:
mrb_free(mrb, ((struct RArray*)obj)->buf);
if (obj->flags & MRB_ARY_SHARED)
mrb_ary_decref(mrb, ((struct RArray*)obj)->aux.shared);
else
mrb_free(mrb, ((struct RArray*)obj)->ptr);
break;
case MRB_TT_HASH:
@@ -467,20 +517,29 @@ obj_free(mrb_state *mrb, struct RBasic *obj)
break;
case MRB_TT_STRING:
if (!(obj->flags & MRB_STR_SHARED))
mrb_free(mrb, ((struct RString*)obj)->buf);
if (obj->flags & MRB_STR_SHARED)
mrb_str_decref(mrb, ((struct RString*)obj)->aux.shared);
else
mrb_free(mrb, ((struct RString*)obj)->ptr);
break;
case MRB_TT_RANGE:
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;
if (d->type->dfree) {
d->type->dfree(mrb, d->data);
}
mrb_gc_free_iv(mrb, (struct RObject*)obj);
}
break;
@@ -504,10 +563,14 @@ root_scan_phase(mrb_state *mrb)
for (i=0,e=mrb->arena_idx; i<e; i++) {
mrb_gc_mark(mrb, mrb->arena[i]);
}
/* mark class hierarchy */
mrb_gc_mark(mrb, (struct RBasic*)mrb->object_class);
/* mark exception */
mrb_gc_mark(mrb, (struct RBasic*)mrb->exc);
/* mark stack */
e = mrb->stack - mrb->stbase;
if (mrb->ci) e += mrb->ci->nregs;
if (mrb->stbase + e > mrb->stend) e = mrb->stend - mrb->stbase;
for (i=0; i<e; i++) {
mrb_gc_mark_value(mrb, mrb->stbase[i]);
}
@@ -560,6 +623,7 @@ gc_gray_mark(mrb_state *mrb, struct RBasic *obj)
break;
case MRB_TT_OBJECT:
case MRB_TT_DATA:
children += mrb_gc_mark_iv_size(mrb, (struct RObject*)obj);
break;
@@ -584,7 +648,7 @@ gc_gray_mark(mrb_state *mrb, struct RBasic *obj)
children+=2;
break;
#ifdef INCLUDE_REGEXP
#ifdef ENABLE_REGEXP
case MRB_TT_MATCH:
children+=2;
break;
@@ -593,6 +657,15 @@ gc_gray_mark(mrb_state *mrb, struct RBasic *obj)
break;
#endif
#ifdef ENABLE_STRUCT
case MRB_TT_STRUCT:
{
struct RStruct *s = (struct RStruct*)obj;
children += s->len;
}
break;
#endif
default:
break;
}
@@ -642,7 +715,7 @@ incremental_sweep_phase(mrb_state *mrb, size_t limit)
while (page && (tried_sweep < limit)) {
RVALUE *p = page->objects;
RVALUE *e = p + HEAP_PAGE_SIZE;
RVALUE *e = p + MRB_HEAP_PAGE_SIZE;
size_t freed = 0;
int dead_slot = 1;
int full = (page->freelist == NULL);
@@ -664,7 +737,7 @@ incremental_sweep_phase(mrb_state *mrb, size_t limit)
}
/* free dead slot */
if (dead_slot && freed < HEAP_PAGE_SIZE) {
if (dead_slot && freed < MRB_HEAP_PAGE_SIZE) {
struct heap_page *next = page->next;
unlink_heap_page(mrb, page);
@@ -678,7 +751,7 @@ incremental_sweep_phase(mrb_state *mrb, size_t limit)
}
page = page->next;
}
tried_sweep += HEAP_PAGE_SIZE;
tried_sweep += MRB_HEAP_PAGE_SIZE;
mrb->live -= freed;
mrb->gc_live_after_mark -= freed;
}
@@ -1092,7 +1165,7 @@ test_incremental_gc(void)
page = mrb->heaps;
while (page) {
RVALUE *p = page->objects;
RVALUE *e = p + HEAP_PAGE_SIZE;
RVALUE *e = p + MRB_HEAP_PAGE_SIZE;
while (p<e) {
if (is_black(&p->as.basic)) {
live++;
@@ -1103,7 +1176,7 @@ test_incremental_gc(void)
p++;
}
page = page->next;
total += HEAP_PAGE_SIZE;
total += MRB_HEAP_PAGE_SIZE;
}
gc_assert(mrb->gray_list == NULL);
@@ -1138,7 +1211,7 @@ test_incremental_sweep_phase(void)
gc_assert(mrb->heaps->next->next == NULL);
gc_assert(mrb->free_heaps->next->next == NULL);
incremental_sweep_phase(mrb, HEAP_PAGE_SIZE*3);
incremental_sweep_phase(mrb, MRB_HEAP_PAGE_SIZE*3);
gc_assert(mrb->heaps->next == NULL);
gc_assert(mrb->heaps == mrb->free_heaps);
-54
View File
@@ -1,54 +0,0 @@
/*
** gc.h - garbage collector for RiteVM
**
** See Copyright Notice in mruby.h
*/
#ifndef MRUBY_GC_H
#define MRUBY_GC_H
#if defined(__cplusplus)
extern "C" {
#endif
struct free_obj {
MRUBY_OBJECT_HEADER;
struct RBasic *next;
};
typedef struct {
union {
struct free_obj free;
struct RBasic basic;
struct RObject object;
struct RClass klass;
struct RString string;
struct RArray array;
struct RHash hash;
struct RRange range;
struct RStruct structdata;
struct RProc procdata;
#ifdef INCLUDE_REGEXP
struct RMatch match;
struct RRegexp regexp;
#endif
} as;
} RVALUE;
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*);
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*);
void mrb_gc_mark_ht(mrb_state*, struct RHash*);
size_t mrb_gc_mark_ht_size(mrb_state*, struct RHash*);
void mrb_gc_free_ht(mrb_state*, struct RHash*);
#if defined(__cplusplus)
} /* extern "C" { */
#endif
#endif /* MRUBY_GC_H */
+54 -52
View File
@@ -11,8 +11,6 @@
#include "mruby/array.h"
#include "mruby/string.h"
#include "mruby/variable.h"
#include <string.h>
#include <stdio.h>
static inline khint_t
mrb_hash_ht_hash_func(mrb_state *mrb, mrb_value key)
@@ -31,15 +29,8 @@ mrb_hash_ht_hash_equal(mrb_state *mrb, mrb_value a, mrb_value b)
return mrb_eql(mrb, a, b);
}
KHASH_INIT(ht, mrb_value, mrb_value, 1, mrb_hash_ht_hash_func, mrb_hash_ht_hash_equal);
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
KHASH_DECLARE(ht, mrb_value, mrb_value, 1);
KHASH_DEFINE (ht, mrb_value, mrb_value, 1, mrb_hash_ht_hash_func, mrb_hash_ht_hash_equal);
static void mrb_hash_modify(mrb_state *mrb, mrb_value hash);
@@ -60,6 +51,7 @@ mrb_gc_mark_ht(mrb_state *mrb, struct RHash *hash)
khiter_t k;
khash_t(ht) *h = hash->ht;
if (!h) return;
for (k = kh_begin(h); k != kh_end(h); k++)
if (kh_exist(h, k)) {
mrb_gc_mark_value(mrb, kh_key(h, k));
@@ -70,43 +62,48 @@ mrb_gc_mark_ht(mrb_state *mrb, struct RHash *hash)
size_t
mrb_gc_mark_ht_size(mrb_state *mrb, struct RHash *hash)
{
if (!hash->ht) return 0;
return kh_size(hash->ht)*2;
}
void
mrb_gc_free_ht(mrb_state *mrb, struct RHash *hash)
{
kh_destroy(ht, hash->ht);
if (hash->ht) kh_destroy(ht, hash->ht);
}
mrb_value
mrb_hash_new_capa(mrb_state *mrb, size_t capa)
mrb_hash_new_capa(mrb_state *mrb, int capa)
{
struct RHash *h;
h = (struct RHash*)mrb_obj_alloc(mrb, MRB_TT_HASH, mrb->hash_class);
h->ht = kh_init(ht, mrb);
kh_resize(ht, h->ht, capa);
if (capa > 0) {
kh_resize(ht, h->ht, capa);
}
h->iv = 0;
return mrb_obj_value(h);
}
mrb_value
mrb_hash_new(mrb_state *mrb, int capa)
mrb_hash_new(mrb_state *mrb)
{
return mrb_hash_new_capa(mrb, capa);
return mrb_hash_new_capa(mrb, 0);
}
mrb_value
mrb_hash_get(mrb_state *mrb, mrb_value hash, mrb_value key) /* mrb_hash_aref */ /* mrb_hash_lookup */
mrb_hash_get(mrb_state *mrb, mrb_value hash, mrb_value key)
{
khash_t(ht) *h = RHASH_TBL(hash);
khiter_t k;
k = kh_get(ht, h, key);
if (k != kh_end(h))
return kh_value(h, k);
if (h) {
k = kh_get(ht, h, key);
if (k != kh_end(h))
return kh_value(h, k);
}
/* not found */
if (MRB_RHASH_PROCDEFAULT_P(hash)) {
@@ -116,13 +113,13 @@ mrb_hash_get(mrb_state *mrb, mrb_value hash, mrb_value key) /* mrb_hash_aref */
}
mrb_value
mrb_hash_getWithDef(mrb_state *mrb, mrb_value hash, mrb_value vkey, mrb_value def) /* mrb_hash_lookup2 */
mrb_hash_fetch(mrb_state *mrb, mrb_value hash, mrb_value key, mrb_value def)
{
khash_t(ht) *h = RHASH_TBL(hash);
khiter_t k;
if (h) {
k = kh_get(ht, h, vkey);
k = kh_get(ht, h, key);
if (k != kh_end(h))
return kh_value(h, k);
}
@@ -140,6 +137,7 @@ mrb_hash_set(mrb_state *mrb, mrb_value hash, mrb_value key, mrb_value val) /* mr
mrb_hash_modify(mrb, hash);
h = RHASH_TBL(hash);
if (!h) h = RHASH_TBL(hash) = kh_init(ht, mrb);
k = kh_get(ht, h, key);
if (k == kh_end(h)) {
/* expand */
@@ -165,11 +163,11 @@ mrb_hash_dup(mrb_state *mrb, mrb_value hash)
khash_t(ht) *h, *ret_h;
khiter_t k, ret_k;
h = RHASH_TBL(hash);
ret = (struct RHash*)mrb_obj_alloc(mrb, MRB_TT_HASH, mrb->hash_class);
ret->ht = kh_init(ht, mrb);
if (!RHASH_EMPTY_P(hash)) {
h = RHASH_TBL(hash);
if (kh_size(h) > 0) {
ret_h = ret->ht;
for (k = kh_begin(h); k != kh_end(h); k++) {
@@ -194,7 +192,7 @@ mrb_hash_tbl(mrb_state *mrb, mrb_value hash)
{
khash_t(ht) *h = RHASH_TBL(hash);
if (!RHASH_TBL(hash)) {
if (!h) {
RHASH_TBL(hash) = kh_init(ht, mrb);
}
return h;
@@ -330,16 +328,10 @@ mrb_hash_aget(mrb_state *mrb, mrb_value self)
return mrb_hash_get(mrb, self, key);
}
mrb_value
mrb_hash_lookup2(mrb_state *mrb, mrb_value hash, mrb_value key, mrb_value def)
{
return mrb_hash_getWithDef(mrb, hash, key, def);
}
mrb_value
mrb_hash_lookup(mrb_state *mrb, mrb_value hash, mrb_value key)
{
return mrb_hash_lookup2(mrb, hash, key, mrb_nil_value());
return mrb_hash_get(mrb, hash, key);
}
/*
@@ -496,7 +488,7 @@ mrb_hash_set_default_proc(mrb_state *mrb, mrb_value hash)
return ifnone;
}
mrb_value
static mrb_value
mrb_hash_delete_key(mrb_state *mrb, mrb_value hash, mrb_value key)
{
khash_t(ht) *h = RHASH_TBL(hash);
@@ -576,7 +568,9 @@ mrb_hash_shift(mrb_state *mrb, mrb_value hash)
if (!kh_exist(h,k)) continue;
delKey = kh_key(h,k);
mrb_gc_protect(mrb, delKey);
delVal = mrb_hash_delete_key(mrb, hash, delKey);
mrb_gc_protect(mrb, delVal);
return mrb_assoc_new(mrb, delKey, delVal);
}
@@ -700,7 +694,7 @@ mrb_hash_clear(mrb_state *mrb, mrb_value hash)
{
khash_t(ht) *h = RHASH_TBL(hash);
kh_clear(ht, h);
if (h) kh_clear(ht, h);
return hash;
}
@@ -817,13 +811,12 @@ static mrb_value
mrb_hash_empty_p(mrb_state *mrb, mrb_value self)
{
khash_t(ht) *h = RHASH_TBL(self);
khiter_t k;
if (h) {
for (k = kh_begin(h); k != kh_end(h); k++)
if (kh_exist(h, k))
return mrb_false_value();
if (kh_size(h) == 0)
return mrb_true_value();
}
return mrb_true_value();
return mrb_false_value();
}
/* 15.2.13.4.11 */
@@ -896,9 +889,9 @@ inspect_hash(mrb_state *mrb, mrb_value hash, int recur)
khash_t(ht) *h = RHASH_TBL(hash);
khiter_t k;
if (recur) return mrb_str_new_cstr(mrb, "{...}");
if (recur) return mrb_str_new(mrb, "{...}", 5);
str = mrb_str_new_cstr(mrb, "{");
str = mrb_str_new(mrb, "{", 1);
if (h && kh_size(h) > 0) {
for (k = kh_begin(h); k != kh_end(h); k++) {
int ai;
@@ -911,14 +904,14 @@ inspect_hash(mrb_state *mrb, mrb_value hash, int recur)
str2 = mrb_inspect(mrb, kh_key(h,k));
mrb_str_append(mrb, str, str2);
mrb_str_buf_cat(mrb, str, "=>", strlen("=>"));
mrb_str_buf_cat(mrb, str, "=>", 2);
str2 = mrb_inspect(mrb, kh_value(h,k));
mrb_str_append(mrb, str, str2);
mrb_gc_arena_restore(mrb, ai);
}
}
mrb_str_buf_cat(mrb, str, "}", strlen("}"));//mrb_str_buf_cat2(str, "}");
mrb_str_buf_cat(mrb, str, "}", 1);
return str;
}
@@ -938,8 +931,10 @@ inspect_hash(mrb_state *mrb, mrb_value hash, int recur)
static mrb_value
mrb_hash_inspect(mrb_state *mrb, mrb_value hash)
{
if (RHASH_EMPTY_P(hash))
return mrb_str_new_cstr(mrb, "{}");
khash_t(ht) *h = RHASH_TBL(hash);
if (!h || kh_size(h) == 0)
return mrb_str_new(mrb, "{}", 2);
return inspect_hash(mrb, hash, 0);
}
@@ -1106,6 +1101,8 @@ mrb_hash_has_value(mrb_state *mrb, mrb_value hash)
static mrb_value
hash_equal(mrb_state *mrb, mrb_value hash1, mrb_value hash2, int eql)
{
khash_t(ht) *h1, *h2;
if (mrb_obj_equal(mrb, hash1, hash2)) return mrb_true_value();
if (mrb_type(hash2) != MRB_TT_HASH) {
if (!mrb_respond_to(mrb, hash2, mrb_intern(mrb, "to_hash"))) {
@@ -1116,10 +1113,15 @@ hash_equal(mrb_state *mrb, mrb_value hash1, mrb_value hash2, int eql)
else
return mrb_fixnum_value(mrb_equal(mrb, hash2, hash1));
}
if (RHASH_SIZE(hash1) != RHASH_SIZE(hash2)) return mrb_false_value();
h1 = RHASH_TBL(hash1);
h2 = RHASH_TBL(hash2);
if (!h2) {
if (!h2) return mrb_true_value();
return mrb_false_value();
}
if (!h2) return mrb_false_value();
if (kh_size(h1) != kh_size(h2)) return mrb_false_value();
else {
khash_t(ht) *h1 = RHASH_TBL(hash1);
khash_t(ht) *h2 = RHASH_TBL(hash2);
khiter_t k1, k2;
mrb_value key;
@@ -1337,9 +1339,9 @@ mrb_init_hash(mrb_state *mrb)
mrb_define_method(mrb, h, "default_proc", mrb_hash_default_proc,ARGS_NONE()); /* 15.2.13.4.7 */
mrb_define_method(mrb, h, "default_proc=", mrb_hash_set_default_proc,ARGS_REQ(1)); /* 15.2.13.4.7 */
mrb_define_method(mrb, h, "__delete", mrb_hash_delete, ARGS_REQ(1)); /* core of 15.2.13.4.8 */
//mrb_define_method(mrb, h, "each", mrb_hash_each_pair, ARGS_NONE()); /* 15.2.13.4.9 */ /* move to mrblib\hash.rb */
//mrb_define_method(mrb, h, "each_key", mrb_hash_each_key, ARGS_NONE()); /* 15.2.13.4.10 */ /* move to mrblib\hash.rb */
//mrb_define_method(mrb, h, "each_value", mrb_hash_each_value, ARGS_NONE()); /* 15.2.13.4.11 */ /* move to mrblib\hash.rb */
// "each" 15.2.13.4.9 move to mrblib/hash.rb
// "each_key" 15.2.13.4.10 move to mrblib/hash.rb
// "each_value" 15.2.13.4.11 move to mrblib/hash.rb
mrb_define_method(mrb, h, "empty?", mrb_hash_empty_p, ARGS_NONE()); /* 15.2.13.4.12 */
mrb_define_method(mrb, h, "has_key?", mrb_hash_has_key, ARGS_REQ(1)); /* 15.2.13.4.13 */
mrb_define_method(mrb, h, "has_value?", mrb_hash_has_value, ARGS_REQ(1)); /* 15.2.13.4.14 */
@@ -1350,7 +1352,7 @@ mrb_init_hash(mrb_state *mrb)
mrb_define_method(mrb, h, "keys", mrb_hash_keys, ARGS_NONE()); /* 15.2.13.4.19 */
mrb_define_method(mrb, h, "length", mrb_hash_size_m, ARGS_NONE()); /* 15.2.13.4.20 */
mrb_define_method(mrb, h, "member?", mrb_hash_has_key, ARGS_REQ(1)); /* 15.2.13.4.21 */
//mrb_define_method(mrb, h, "merge", mrb_hash_merge, ARGS_REQ(1)); /* 15.2.13.4.22 */ /* move to mrblib\hash.rb */
// "merge" 15.2.13.4.22 move to mrblib/hash.rb
mrb_define_method(mrb, h, "replace", mrb_hash_replace, ARGS_REQ(1)); /* 15.2.13.4.23 */
mrb_define_method(mrb, h, "shift", mrb_hash_shift, ARGS_NONE()); /* 15.2.13.4.24 */
mrb_define_method(mrb, h, "size", mrb_hash_size_m, ARGS_NONE()); /* 15.2.13.4.25 */
+12 -4
View File
@@ -8,7 +8,7 @@
void mrb_init_class(mrb_state*);
void mrb_init_symtbl(mrb_state*);
void mrb_init_symbols(mrb_state*);
void mrb_init_symbol(mrb_state*);
void mrb_init_object(mrb_state*);
void mrb_init_kernel(mrb_state*);
void mrb_init_enumerable(mrb_state*);
@@ -42,22 +42,30 @@ mrb_init_core(mrb_state *mrb)
mrb_init_comparable(mrb);
mrb_init_enumerable(mrb);
mrb_init_symbols(mrb);
mrb_init_symbol(mrb);
mrb_init_exception(mrb);
mrb_init_proc(mrb);
mrb_init_string(mrb);
mrb_init_array(mrb);
mrb_init_hash(mrb);
mrb_init_numeric(mrb);
mrb_init_range(mrb);
#ifdef ENABLE_STRUCT
mrb_init_struct(mrb);
#endif
mrb_init_gc(mrb);
#ifdef INCLUDE_REGEXP
#ifdef ENABLE_REGEXP
mrb_init_regexp(mrb);
#endif
mrb_init_exception(mrb);
#ifdef ENABLE_STDIO
mrb_init_print(mrb);
#endif
#ifdef ENABLE_TIME
mrb_init_time(mrb);
#endif
#ifdef ENABLE_MATH
mrb_init_math(mrb);
#endif
mrb_init_mrblib(mrb);
+106 -374
View File
@@ -6,18 +6,10 @@
#include "mruby.h"
#include "mruby/string.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "mruby/proc.h"
#include "mruby/range.h"
#include "mruby/array.h"
#include "mruby/hash.h"
#include "mruby/class.h"
#include "mruby/struct.h"
#include "mruby/variable.h"
#include "mruby/khash.h"
#include "error.h"
typedef enum {
@@ -34,22 +26,6 @@ typedef enum {
NOEX_RESPONDS = 0x80
} mrb_method_flag_t;
#ifdef INCLUDE_REGEXP
#include "re.h"
#include "regint.h"
#endif
KHASH_MAP_INIT_INT(mt, struct RProc*);
KHASH_MAP_INIT_INT(iv, mrb_value);
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
struct obj_ivar_tag {
mrb_value obj;
int (*func)(mrb_sym key, mrb_value val, void * arg);
@@ -96,9 +72,6 @@ inspect_obj(mrb_state *mrb, mrb_value obj, mrb_value str, int recur)
int
mrb_obj_basic_to_s_p(mrb_state *mrb, mrb_value obj)
{
//const mrb_method_entry_t *me = mrb_method_entry(CLASS_OF(obj), mrb_intern("to_s"));
//if (me && me->def && me->def->type == VM_METHOD_TYPE_CFUNC &&
//me->def->body.cfunc.func == mrb_any_to_s)
struct RProc *me = mrb_method_search(mrb, mrb_class(mrb, obj), mrb_intern(mrb, "to_s"));
if (me && MRB_PROC_CFUNC_P(me) && (me->body.func == mrb_any_to_s))
return 1;
@@ -135,7 +108,7 @@ mrb_obj_inspect(mrb_state *mrb, mrb_value obj)
return mrb_any_to_s(mrb, obj);
}
else if (mrb_nil_p(obj)) {
return mrb_str_new_cstr(mrb, "nil");
return mrb_str_new(mrb, "nil", 3);
}
return mrb_funcall(mrb, obj, "to_s", 0, 0);
}
@@ -191,7 +164,7 @@ mrb_obj_not_equal_m(mrb_state *mrb, mrb_value self)
mrb_value arg;
mrb_get_args(mrb, "o", &arg);
if (mrb_obj_equal(mrb, self, arg)) {
if (mrb_equal(mrb, self, arg)) {
return mrb_false_value();
}
else {
@@ -225,14 +198,19 @@ mrb_equal_m(mrb_state *mrb, mrb_value self)
/* 15.3.1.3.3 */
/* 15.3.1.3.33 */
/*
* call-seq:
* obj.hash -> fixnum
* Document-method: __id__
* Document-method: object_id
*
* 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.
* 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>.
*/
static mrb_value
mrb_obj_id_m(mrb_state *mrb, mrb_value self)
@@ -262,17 +240,12 @@ mrb_obj_id_m(mrb_state *mrb, mrb_value self)
static mrb_value
mrb_f_send(mrb_state *mrb, mrb_value self)
{
mrb_value name, block, *argv;
mrb_sym name;
mrb_value block, *argv;
int argc;
mrb_get_args(mrb, "o*&", &name, &argv, &argc, &block);
return mrb_funcall_with_block(mrb,self, mrb_string_value_ptr(mrb, name), argc, argv, block);
}
static mrb_value
mrb_f_block_given_p(void)
{
return mrb_false_value(); /* dummy */
mrb_get_args(mrb, "n*&", &name, &argv, &argc, &block);
return mrb_funcall_with_block(mrb,self, name, argc, argv, block);
}
/* 15.3.1.2.2 */
@@ -302,7 +275,17 @@ mrb_f_block_given_p(void)
static mrb_value
mrb_f_block_given_p_m(mrb_state *mrb, mrb_value self)
{
return mrb_f_block_given_p();
mrb_callinfo *ci = mrb->ci;
mrb_value *bp;
bp = mrb->stbase + ci->stackidx + 1;
ci--;
if (ci <= mrb->cibase) return mrb_false_value();
if (ci->argc > 0) {
bp += ci->argc;
}
if (mrb_nil_p(*bp)) return mrb_false_value();
return mrb_true_value();
}
/* 15.3.1.3.7 */
@@ -328,56 +311,48 @@ mrb_singleton_class_clone(mrb_state *mrb, mrb_value obj)
{
struct RClass *klass = RBASIC(obj)->c;
//if (!FL_TEST(klass, FL_SINGLETON))
//return klass;
if (klass->tt != MRB_TT_SCLASS)
return klass;
else {
//struct clone_method_data data;
/* copy singleton(unnamed) class */
//VALUE clone = class_alloc(RBASIC(klass)->flags, 0);
/* copy singleton(unnamed) class */
struct RClass *clone = (struct RClass*)mrb_obj_alloc(mrb, klass->tt, mrb->class_class);
//clone->super = objklass->super;
if ((mrb_type(obj) == MRB_TT_CLASS) ||
(mrb_type(obj) == MRB_TT_SCLASS)) { /* BUILTIN_TYPE(obj) == T_CLASS */
clone->c = clone;
}
else {
clone->c = mrb_singleton_class_clone(mrb, mrb_obj_value(klass));
}
if ((mrb_type(obj) == MRB_TT_CLASS) ||
(mrb_type(obj) == MRB_TT_SCLASS)) { /* BUILTIN_TYPE(obj) == T_CLASS */
clone->c = clone;
}
else {
clone->c = mrb_singleton_class_clone(mrb, mrb_obj_value(klass));
}
clone->super = klass->super;
if (klass->iv) {
clone->iv = klass->iv;
}
clone->mt = kh_init(mt, mrb);
clone->tt = MRB_TT_SCLASS;
return clone;
clone->super = klass->super;
if (klass->iv) {
clone->iv = klass->iv;
}
if (klass->mt) {
clone->mt = kh_copy(mt, mrb, klass->mt);
}
else {
clone->mt = kh_init(mt, mrb);
}
clone->tt = MRB_TT_SCLASS;
return clone;
}
}
static void
init_copy(mrb_state *mrb, mrb_value dest, mrb_value obj)
{
//if (OBJ_FROZEN(dest)) {
// rb_raise(rb_eTypeError, "[bug] frozen object (%s) allocated", rb_obj_classname(dest));
//}
//RBASIC(dest)->flags &= ~(T_MASK|FL_EXIVAR);
//RBASIC(dest)->flags |= RBASIC(obj)->flags & (T_MASK|FL_EXIVAR|FL_TAINT);
//if (FL_TEST(obj, FL_EXIVAR)) {
// mrb_copy_generic_ivar(dest, obj);
//}
//mrb_gc_copy_finalizer(dest, obj);
switch (mrb_type(obj)) {
case MRB_TT_OBJECT:
case MRB_TT_CLASS:
case MRB_TT_MODULE:
if (ROBJECT(dest)->iv) {
kh_destroy(iv, ROBJECT(dest)->iv);
ROBJECT(dest)->iv = 0;
}
if (ROBJECT(obj)->iv) {
ROBJECT(dest)->iv = ROBJECT(obj)->iv;
ROBJECT(dest)->iv = kh_copy(iv, mrb, ROBJECT(obj)->iv);
}
break;
@@ -424,8 +399,6 @@ mrb_obj_clone(mrb_state *mrb, mrb_value self)
clone = (struct RObject*)mrb_obj_alloc(mrb, self.tt, mrb_obj_class(mrb, self));
clone->c = mrb_singleton_class_clone(mrb, self);
init_copy(mrb, mrb_obj_value(clone), self);
//1-9-2 no bug mrb_funcall(mrb, clone, "initialize_clone", 1, self);
//RBASIC(clone)->flags |= RBASIC(obj)->flags & FL_FREEZE;
return mrb_obj_value(clone);
}
@@ -459,47 +432,12 @@ mrb_obj_dup(mrb_state *mrb, mrb_value obj)
mrb_raise(mrb, E_TYPE_ERROR, "can't dup %s", mrb_obj_classname(mrb, obj));
}
p = mrb_obj_alloc(mrb, mrb_type(obj), mrb_obj_class(mrb, obj));
//init_copy(dup, obj);
dup = mrb_obj_value(p);
mrb_funcall(mrb, dup, "initialize_copy", 1, obj);
init_copy(mrb, dup, obj);
return dup;
}
/* 15.3.1.2.3 */
/* 15.3.1.3.12 */
/*
* call-seq:
* eval(string [, binding [, filename [,lineno]]]) -> obj
*
* Evaluates the Ruby expression(s) in <em>string</em>. If
* <em>binding</em> is given, which must be a <code>Binding</code>
* object, the evaluation is performed in its context. If the
* optional <em>filename</em> and <em>lineno</em> parameters are
* present, they will be used when reporting syntax errors.
*
* def getBinding(str)
* return binding
* end
* str = "hello"
* eval "str + ' Fred'" #=> "hello Fred"
* eval "str + ' Fred'", getBinding("bye") #=> "bye Fred"
*/
mrb_value
mrb_f_eval(int argc, mrb_value *argv, mrb_value self)
{
return mrb_false_value(); /* dummy */
}
mrb_value
mrb_f_eval_m(mrb_state *mrb, mrb_value self)
{
mrb_value *argv;
int argc;
mrb_get_args(mrb, "*", &argv, &argc);
return mrb_f_eval(argc, argv, self);
}
static mrb_value
mrb_obj_extend(mrb_state *mrb, int argc, mrb_value *argv, mrb_value obj)
{
@@ -509,7 +447,6 @@ mrb_obj_extend(mrb_state *mrb, int argc, mrb_value *argv, mrb_value obj)
mrb_raise(mrb, E_ARGUMENT_ERROR, "wrong number of arguments (at least 1)");
}
for (i = 0; i < argc; i++) {
//Check_Type(argv[i], T_MODULE);
mrb_check_type(mrb, argv[i], MRB_TT_MODULE);
}
while (argc--) {
@@ -554,20 +491,17 @@ mrb_obj_extend_m(mrb_state *mrb, mrb_value self)
return mrb_obj_extend(mrb, argc, argv, self);
}
/* 15.3.1.2.4 */
/* 15.3.1.3.14 */
/* 15.3.1.3.15 */
/*
* call-seq:
* global_variables -> array
* obj.hash -> fixnum
*
* Returns an array of the names of global variables.
*
* global_variables.grep /std/ #=> [:$stdin, :$stdout, :$stderr]
* 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.
*/
//mrb_value
//mrb_f_global_variables(mrb_state *mrb, mrb_value self)
/* 15.3.1.3.15 */
mrb_value
mrb_obj_hash(mrb_state *mrb, mrb_value self)
{
@@ -588,15 +522,15 @@ mrb_obj_init_copy(mrb_state *mrb, mrb_value self)
return self;
}
mrb_value mrb_yield_internal(mrb_state *mrb, mrb_value b, int argc, mrb_value *argv, mrb_value self, struct RClass *c);
/* 15.3.1.3.18 */
/*
* call-seq:
* obj.instance_eval(string [, filename [, lineno]] ) -> obj
* obj.instance_eval {| | block } -> obj
*
* Evaluates a string containing Ruby source code, or the given block,
* within the context of the receiver (_obj_). In order to set the
* context, the variable +self+ is set to _obj_ while
* Evaluates the given block,within the context of the receiver (_obj_).
* In order to set the context, the variable +self+ is set to _obj_ while
* the code is executing, giving the code access to _obj_'s
* instance variables. In the version of <code>instance_eval</code>
* that takes a +String+, the optional second and third
@@ -614,10 +548,24 @@ mrb_obj_init_copy(mrb_state *mrb, mrb_value self)
mrb_value
mrb_obj_instance_eval(mrb_state *mrb, mrb_value self)
{
mrb_value b;
mrb_value a, b;
mrb_value cv;
struct RClass *c;
mrb_get_args(mrb, "&", &b);
return mrb_yield_with_self(mrb, b, 0, 0, self);
if (mrb_get_args(mrb, "|S&", &a, &b) == 1) {
mrb_raise(mrb, E_NOTIMP_ERROR, "instance_eval with string not implemented");
}
switch (mrb_type(self)) {
case MRB_TT_SYMBOL:
case MRB_TT_FIXNUM:
case MRB_TT_FLOAT:
c = 0;
break;
default:
cv = mrb_singleton_class(mrb, self);
c = mrb_class_ptr(cv);
}
return mrb_yield_internal(mrb, b, 0, 0, self, c);
}
int
@@ -755,46 +703,6 @@ mrb_obj_ivar_set(mrb_state *mrb, mrb_value self)
return val;
}
/* 15.3.1.3.23 */
/*
* call-seq:
* obj.instance_variables -> array
*
* Returns an array of instance variable names for the receiver. Note
* that simply defining an accessor does not create the corresponding
* instance variable.
*
* class Fred
* attr_accessor :a1
* def initialize
* @iv = 3
* end
* end
* Fred.new.instance_variables #=> [:@iv]
*/
mrb_value
mrb_obj_instance_variables(mrb_state *mrb, mrb_value self)
{
mrb_value ary;
kh_iv_t *h = RCLASS_IV_TBL(self);
khint_t i;
const char* p;
ary = mrb_ary_new(mrb);
if (h) {
for (i=0;i<kh_end(h);i++) {
if (kh_exist(h, i)) {
p = mrb_sym2name(mrb, kh_key(h,i));
if (*p == '@') {
if (mrb_type(kh_value(h, i)) != MRB_TT_UNDEF)
mrb_ary_push(mrb, ary, mrb_str_new_cstr(mrb, p));
}
}
}
}
return ary;
}
/* 15.3.1.3.24 */
/* 15.3.1.3.26 */
/*
@@ -836,71 +744,6 @@ mrb_obj_is_kind_of_m(mrb_state *mrb, mrb_value self)
}
}
/* 15.3.1.2.6 */
/* 15.3.1.3.27 */
/*
* call-seq:
* lambda { |...| block } -> a_proc
*
* Equivalent to <code>Proc.new</code>, except the resulting Proc objects
* check the number of parameters passed when called.
*/
mrb_value
proc_lambda(mrb_state *mrb, mrb_value self)
{
//return mrb_block_lambda();
return mrb_nil_value(); /* dummy */
}
/* 15.3.1.2.7 */
/* 15.3.1.3.28 */
/*
* call-seq:
* local_variables -> array
*
* Returns the names of the current local variables.
*
* fred = 1
* for i in 1..10
* # ...
* end
* local_variables #=> [:fred, :i]
*/
mrb_value
mrb_f_local_variables(mrb_state *mrb, mrb_value self)
{
mrb_value ary;
ary = mrb_ary_new(mrb);
return ary; /* dummy */
}
/* 15.3.1.2.8 */
/* 15.3.1.3.29 */
/*
* call-seq:
* loop { block }
* loop -> an_enumerator
*
* Repeatedly executes the block.
*
* If no block is given, an enumerator is returned instead.
*
* loop do
* print "Input: "
* line = gets
* break if !line or line =~ /^qQ/
* # ...
* end
*
* StopIteration raised in the block breaks the loop.
*/
mrb_value
mrb_f_loop(mrb_state *mrb, mrb_value self)
{
return mrb_nil_value(); /* dummy */
}
static void
method_entry_loop(mrb_state *mrb, struct RClass* klass, mrb_value ary)
{
@@ -958,7 +801,6 @@ mrb_obj_singleton_methods(mrb_state *mrb, int argc, mrb_value *argv, mrb_value o
recur = mrb_true_value();
}
else {
//mrb_scan_args(argc, argv, "01", &recur);
recur = argv[0];
}
klass = mrb_class(mrb, obj);
@@ -987,7 +829,6 @@ retry:
else {
mrb_value recur;
//mrb_scan_args(argc, argv, "1", &recur);
recur = argv[0];
if (mrb_test(recur)) {
argc = 0;
@@ -1022,7 +863,7 @@ mrb_obj_methods_m(mrb_state *mrb, mrb_value self)
int argc;
mrb_get_args(mrb, "*", &argv, &argc);
return mrb_obj_methods(mrb, argc, argv, self, 0); /* everything but private */
return mrb_obj_methods(mrb, argc, argv, self, (mrb_method_flag_t)0); /* everything but private */
}
/* 15.3.1.3.32 */
@@ -1039,31 +880,6 @@ mrb_false(mrb_state *mrb, mrb_value self)
return mrb_false_value();
}
/* 15.3.1.2.10 */
/* 15.3.1.3.35 */
/*
* call-seq:
* print(obj, ...) -> nil
*
* Prints each object in turn to <code>$stdout</code>. If the output
* field separator (<code>$,</code>) is not +nil+, its
* contents will appear between each field. If the output record
* separator (<code>$\\</code>) is not +nil+, it will be
* appended to the output. If no arguments are given, prints
* <code>$_</code>. Objects that aren't strings will be converted by
* calling their <code>to_s</code> method.
*
* print "cat", [1,2,3], 99, "\n"
* $, = ", "
* $\ = "\n"
* print "cat", [1,2,3], 99
*
* <em>produces:</em>
*
* cat12399
* cat, 1, 2, 3, 99
*/
/* 15.3.1.3.36 */
/*
* call-seq:
@@ -1121,37 +937,15 @@ mrb_obj_public_methods(mrb_state *mrb, mrb_value self)
return mrb_obj_methods(mrb, argc, argv, self, NOEX_PUBLIC); /* public attribute not define */
}
/* 15.3.1.2.11 */
/* 15.3.1.3.39 */
/*
* call-seq:
* puts(obj, ...) -> nil
*
* Equivalent to
*
* $stdout.puts(obj, ...)
*/
static mrb_value
get_errinfo(mrb_state *mrb)
{
//return get_thread_errinfo(GET_THREAD());
return mrb_str_new_cstr(mrb, "error!!"); /* dummy */
}
/* 15.3.1.2.12 */
/* 15.3.1.3.40 */
/*
* call-seq:
* raise
* raise(string)
* raise(exception [, string [, array]])
* fail
* fail(string)
* fail(exception [, string [, array]])
* raise(exception [, string])
*
* With no arguments, raises the exception in <code>$!</code> or raises
* a <code>RuntimeError</code> if <code>$!</code> is +nil+.
* With no arguments, raises a <code>RuntimeError</code>
* With a single +String+ argument, raises a
* +RuntimeError+ with the string as a message. Otherwise,
* the first parameter should be the name of an +Exception+
@@ -1167,19 +961,24 @@ get_errinfo(mrb_state *mrb)
mrb_value
mrb_f_raise(mrb_state *mrb, mrb_value self)
{
mrb_value err;
mrb_value *argv;
mrb_value a[2];
int argc;
mrb_get_args(mrb, "*", &argv, &argc);
if (argc == 0) {
err = get_errinfo(mrb);
if (!mrb_nil_p(err)) {
argc = 1;
argv[0] = err;
}
argc = mrb_get_args(mrb, "|oo", &a[0], &a[1]);
switch (argc) {
case 0:
mrb_raise(mrb, E_RUNTIME_ERROR, "");
break;
case 1:
a[1] = mrb_check_string_type(mrb, a[0]);
if (!mrb_nil_p(a[1])) {
argc = 2;
a[0] = mrb_obj_value(E_RUNTIME_ERROR);
}
/* fall through */
default:
mrb_exc_raise(mrb, mrb_make_exception(mrb, argc, a));
}
mrb_exc_raise(mrb, mrb_make_exception(mrb, argc, argv));
return mrb_nil_value(); /* not reached */
}
@@ -1209,79 +1008,20 @@ mrb_value
mrb_obj_remove_instance_variable(mrb_state *mrb, mrb_value self)
{
mrb_sym sym;
mrb_value name;
khash_t(iv) *h;
khiter_t k;
mrb_value val;
mrb_value Qundef = mrb_undef_value();
mrb_get_args(mrb, "o", &name);
sym = mrb_to_id(mrb, name);
//if (OBJ_FROZEN(obj)) mrb_error_frozen("object");
//if (!mrb_is_instance_id(id)) {
// mrb_name_error(mrb, id, "`%s' is not allowed as an instance variable name", mrb_sym2name(mrb, id));
//}
switch (mrb_type(self)) {
case MRB_TT_OBJECT:
case MRB_TT_CLASS:
case MRB_TT_MODULE:
if (!mrb_obj_ptr(self)->iv) break;
h = mrb_obj_ptr(self)->iv;
if (!h) break;
k = kh_get(iv, h, sym);
if (k != kh_end(h)) {
val = kh_value(h, k);
if (!mrb_obj_equal(mrb, val, Qundef)) {
kh_value(h, k) = Qundef;
return val;
}
}
break;
default:
break;
mrb_get_args(mrb, "n", &sym);
val = mrb_iv_remove(mrb, self, sym);
if (mrb_undef_p(val)) {
mrb_name_error(mrb, sym, "instance variable %s not defined", mrb_sym2name(mrb, sym));
}
mrb_name_error(mrb, sym, "instance variable %s not defined", mrb_sym2name(mrb, sym));
return mrb_nil_value(); /* not reached */
return val;
}
/* 15.3.1.2.13 */
/* 15.3.1.3.42 */
/*
* call-seq:
* require(string) -> true or false
*
* Ruby tries to load the library named _string_, returning
* +true+ if successful. If the filename does not resolve to
* an absolute path, it will be searched for in the directories listed
* in <code>$:</code>. If the file has the extension ``.rb'', it is
* loaded as a source file; if the extension is ``.so'', ``.o'', or
* ``.dll'', or whatever the default shared library extension is on
* the current platform, Ruby loads the shared library as a Ruby
* extension. Otherwise, Ruby tries adding ``.rb'', ``.so'', and so on
* to the name. The name of the loaded feature is added to the array in
* <code>$"</code>. A feature will not be loaded if its name already
* appears in <code>$"</code>. The file name is converted to an absolute
* path, so ``<code>require 'a'; require './a'</code>'' will not load
* <code>a.rb</code> twice.
*
* require "my-library.rb"
* require "db-driver"
*/
mrb_value
mrb_f_require(mrb_state *mrb, mrb_value self)
{
mrb_value fname;
mrb_get_args(mrb, "o", &fname);
return mrb_nil_value(); /* dummy */
}
static inline int
basic_obj_respond_to(mrb_state *mrb, mrb_value obj, mrb_sym id, int pub)
{
return mrb_respond_to(mrb, obj, id);
//return TRUE;
}
/* 15.3.1.3.43 */
/*
@@ -1308,7 +1048,6 @@ obj_respond_to(mrb_state *mrb, mrb_value self)
mrb_sym id;
mrb_get_args(mrb, "*", &argv, &argc);
//mrb_scan_args(argc, argv, "11", &mid, &priv);
mid = argv[0];
if (argc > 1) priv = argv[1];
else priv = mrb_nil_value();
@@ -1370,15 +1109,10 @@ mrb_init_kernel(mrb_state *mrb)
krn = mrb->kernel_module = mrb_define_module(mrb, "Kernel");
mrb_define_class_method(mrb, krn, "block_given?", mrb_f_block_given_p_m, ARGS_NONE()); /* 15.3.1.2.2 */
mrb_define_class_method(mrb, krn, "eval", mrb_f_eval_m, ARGS_ANY()); /* 15.3.1.2.3 */
mrb_define_class_method(mrb, krn, "global_variables", mrb_f_global_variables, ARGS_NONE()); /* 15.3.1.2.4 */
mrb_define_class_method(mrb, krn, "iterator?", mrb_f_block_given_p_m, ARGS_NONE()); /* 15.3.1.2.5 */
mrb_define_class_method(mrb, krn, "lambda", proc_lambda, ARGS_NONE()); /* 15.3.1.2.6 */
mrb_define_class_method(mrb, krn, "local_variables", mrb_f_local_variables, ARGS_NONE()); /* 15.3.1.2.7 */
mrb_define_class_method(mrb, krn, "loop", mrb_f_loop, ARGS_NONE()); /* 15.3.1.2.8 */
; /* 15.3.1.2.11 */
mrb_define_class_method(mrb, krn, "raise", mrb_f_raise, ARGS_ANY()); /* 15.3.1.2.12 */
mrb_define_class_method(mrb, krn, "require", mrb_f_require, ARGS_REQ(1)); /* 15.3.1.2.13 */
mrb_define_method(mrb, krn, "singleton_class", mrb_singleton_class, ARGS_NONE());
@@ -1393,7 +1127,6 @@ mrb_init_kernel(mrb_state *mrb)
mrb_define_method(mrb, krn, "dup", mrb_obj_dup, ARGS_NONE()); /* 15.3.1.3.9 */
mrb_define_method(mrb, krn, "eql?", mrb_obj_equal_m, ARGS_REQ(1)); /* 15.3.1.3.10 */
mrb_define_method(mrb, krn, "equal?", mrb_obj_equal_m, ARGS_REQ(1)); /* 15.3.1.3.11 */
mrb_define_method(mrb, krn, "eval", mrb_f_eval_m, ARGS_ANY()); /* 15.3.1.3.12 */
mrb_define_method(mrb, krn, "extend", mrb_obj_extend_m, ARGS_ANY()); /* 15.3.1.3.13 */
mrb_define_method(mrb, krn, "global_variables", mrb_f_global_variables, ARGS_NONE()); /* 15.3.1.3.14 */
mrb_define_method(mrb, krn, "hash", mrb_obj_hash, ARGS_NONE()); /* 15.3.1.3.15 */
@@ -1408,9 +1141,6 @@ mrb_init_kernel(mrb_state *mrb)
mrb_define_method(mrb, krn, "is_a?", mrb_obj_is_kind_of_m, ARGS_REQ(1)); /* 15.3.1.3.24 */
mrb_define_method(mrb, krn, "iterator?", mrb_f_block_given_p_m, ARGS_NONE()); /* 15.3.1.3.25 */
mrb_define_method(mrb, krn, "kind_of?", mrb_obj_is_kind_of_m, ARGS_REQ(1)); /* 15.3.1.3.26 */
mrb_define_method(mrb, krn, "lambda", proc_lambda, ARGS_NONE()); /* 15.3.1.3.27 */
mrb_define_method(mrb, krn, "local_variables", mrb_f_local_variables, ARGS_NONE()); /* 15.3.1.3.28 */
mrb_define_method(mrb, krn, "loop", mrb_f_loop, ARGS_NONE()); /* 15.3.1.3.29 */
mrb_define_method(mrb, krn, "methods", mrb_obj_methods_m, ARGS_ANY()); /* 15.3.1.3.31 */
mrb_define_method(mrb, krn, "nil?", mrb_false, ARGS_NONE()); /* 15.3.1.3.32 */
mrb_define_method(mrb, krn, "object_id", mrb_obj_id_m, ARGS_NONE()); /* 15.3.1.3.33 */
@@ -1419,14 +1149,16 @@ mrb_init_kernel(mrb_state *mrb)
mrb_define_method(mrb, krn, "public_methods", mrb_obj_public_methods, ARGS_ANY()); /* 15.3.1.3.38 */
mrb_define_method(mrb, krn, "raise", mrb_f_raise, ARGS_ANY()); /* 15.3.1.3.40 */
mrb_define_method(mrb, krn, "remove_instance_variable", mrb_obj_remove_instance_variable,ARGS_REQ(1)); /* 15.3.1.3.41 */
mrb_define_method(mrb, krn, "require", mrb_f_require, ARGS_REQ(1)); /* 15.3.1.3.42 */
mrb_define_method(mrb, krn, "respond_to?", obj_respond_to, ARGS_ANY()); /* 15.3.1.3.43 */
mrb_define_method(mrb, krn, "send", mrb_f_send, ARGS_ANY()); /* 15.3.1.3.44 */
mrb_define_method(mrb, krn, "__send__", mrb_f_send, ARGS_ANY()); /* 15.3.1.3.4 */
mrb_define_method(mrb, krn, "singleton_methods", mrb_obj_singleton_methods_m, ARGS_ANY()); /* 15.3.1.3.45 */
mrb_define_method(mrb, krn, "to_s", mrb_any_to_s, ARGS_NONE()); /* 15.3.1.3.46 */
#ifdef ENABLE_SPRINTF
mrb_define_method(mrb, krn, "sprintf", mrb_f_sprintf, ARGS_ANY()); /* in sprintf.c */
mrb_define_method(mrb, krn, "format", mrb_f_sprintf, ARGS_ANY()); /* in sprintf.c */
#endif
mrb_include_module(mrb, mrb->object_class, mrb->kernel_module);
}
+30 -34
View File
@@ -8,19 +8,11 @@
#include "mruby/dump.h"
#include "mruby/string.h"
#ifdef INCLUDE_REGEXP
#ifdef ENABLE_REGEXP
#include "re.h"
#endif
#include "mruby/irep.h"
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
typedef struct _RiteFILE
{
FILE* fp;
@@ -151,7 +143,7 @@ load_rite_irep_record(mrb_state *mrb, RiteFILE* rfp, unsigned char* dst, uint32_
uint16_t buf_size =0;
buf_size = MRB_DUMP_DEFAULT_STR_LEN;
if ((char_buf = mrb_malloc(mrb, buf_size)) == 0)
if ((char_buf = (char *)mrb_malloc(mrb, buf_size)) == 0)
goto error_exit;
pStart = dst;
@@ -200,7 +192,7 @@ load_rite_irep_record(mrb_state *mrb, RiteFILE* rfp, unsigned char* dst, uint32_
if ( pdl > buf_size - 1) {
buf_size = pdl + 1;
if ((char_buf = mrb_realloc(mrb, char_buf, buf_size)) == 0)
if ((char_buf = (char *)mrb_realloc(mrb, char_buf, buf_size)) == 0)
goto error_exit;
}
memset(char_buf, '\0', buf_size);
@@ -227,7 +219,7 @@ load_rite_irep_record(mrb_state *mrb, RiteFILE* rfp, unsigned char* dst, uint32_
if ( snl > buf_size - 1) {
buf_size = snl + 1;
if ((char_buf = mrb_realloc(mrb, char_buf, buf_size)) == 0)
if ((char_buf = (char *)mrb_realloc(mrb, char_buf, buf_size)) == 0)
goto error_exit;
}
memset(char_buf, '\0', buf_size);
@@ -256,12 +248,12 @@ mrb_load_irep(mrb_state *mrb, FILE* fp)
unsigned char hex8[8], hcrc[4];
unsigned char *dst, *rite_dst = NULL;
rite_binary_header bin_header;
RiteFILE ritefp, *rfp;
RiteFILE ritefp = { 0 };
RiteFILE *rfp;
if ((mrb == NULL) || (fp == NULL)) {
return MRB_DUMP_INVALID_ARGUMENT;
}
memset(&ritefp, 0, sizeof(ritefp));
ritefp.fp = fp;
rfp = &ritefp;
@@ -270,7 +262,7 @@ mrb_load_irep(mrb_state *mrb, FILE* fp)
return ret;
len = sizeof(rite_binary_header) + bin_to_uint32(bin_header.rbds);
if ((rite_dst = mrb_malloc(mrb, len)) == NULL)
if ((rite_dst = (unsigned char *)mrb_malloc(mrb, len)) == NULL)
return MRB_DUMP_GENERAL_FAILURE;
dst = rite_dst;
@@ -339,7 +331,7 @@ read_rite_irep_record(mrb_state *mrb, unsigned char *src, mrb_irep *irep, uint32
int ai = mrb_gc_arena_save(mrb);
recordStart = src;
buf = mrb_malloc(mrb, bufsize);
buf = (char *)mrb_malloc(mrb, bufsize);
if (buf == NULL) {
ret = MRB_DUMP_INVALID_IREP;
goto error_exit;
@@ -367,7 +359,7 @@ read_rite_irep_record(mrb_state *mrb, unsigned char *src, mrb_irep *irep, uint32
irep->ilen = bin_to_uint32(src); //iseq length
src += MRB_DUMP_SIZE_OF_LONG;
if (irep->ilen > 0) {
if ((irep->iseq = mrb_malloc(mrb, sizeof(mrb_code) * irep->ilen)) == NULL) {
if ((irep->iseq = (mrb_code *)mrb_malloc(mrb, sizeof(mrb_code) * irep->ilen)) == NULL) {
ret = MRB_DUMP_GENERAL_FAILURE;
goto error_exit;
}
@@ -388,7 +380,7 @@ read_rite_irep_record(mrb_state *mrb, unsigned char *src, mrb_irep *irep, uint32
irep->plen = bin_to_uint32(src); //pool length
src += MRB_DUMP_SIZE_OF_LONG;
if (irep->plen > 0) {
irep->pool = mrb_malloc(mrb, sizeof(mrb_value) * irep->plen);
irep->pool = (mrb_value *)mrb_malloc(mrb, sizeof(mrb_value) * irep->plen);
if (irep->pool == NULL) {
ret = MRB_DUMP_INVALID_IREP;
goto error_exit;
@@ -402,7 +394,7 @@ read_rite_irep_record(mrb_state *mrb, unsigned char *src, mrb_irep *irep, uint32
if (pdl > bufsize - 1) {
mrb_free(mrb, buf);
bufsize = pdl + 1;
if ((buf = mrb_malloc(mrb, bufsize)) == NULL) {
if ((buf = (char *)mrb_malloc(mrb, bufsize)) == NULL) {
ret = MRB_DUMP_GENERAL_FAILURE;
goto error_exit;
}
@@ -413,7 +405,7 @@ read_rite_irep_record(mrb_state *mrb, unsigned char *src, mrb_irep *irep, uint32
switch (tt) { //pool data
case MRB_TT_FIXNUM:
fix_num = readint(buf, 10);
fix_num = strtol(buf, NULL, 10);
irep->pool[i] = mrb_fixnum_value(fix_num);
break;
@@ -426,7 +418,7 @@ read_rite_irep_record(mrb_state *mrb, unsigned char *src, mrb_irep *irep, uint32
irep->pool[i] = mrb_str_new(mrb, buf, pdl);
break;
#ifdef INCLUDE_REGEXP
#ifdef ENABLE_REGEXP
case MRB_TT_REGEX:
str = mrb_str_new(mrb, buf, pdl);
irep->pool[i] = mrb_reg_quote(mrb, str);
@@ -451,7 +443,7 @@ read_rite_irep_record(mrb_state *mrb, unsigned char *src, mrb_irep *irep, uint32
irep->slen = bin_to_uint32(src); //syms length
src += MRB_DUMP_SIZE_OF_LONG;
if (irep->slen > 0) {
if ((irep->syms = mrb_malloc(mrb, sizeof(mrb_sym) * irep->slen)) == NULL) {
if ((irep->syms = (mrb_sym *)mrb_malloc(mrb, sizeof(mrb_sym) * irep->slen)) == NULL) {
ret = MRB_DUMP_INVALID_IREP;
goto error_exit;
}
@@ -469,7 +461,7 @@ read_rite_irep_record(mrb_state *mrb, unsigned char *src, mrb_irep *irep, uint32
if (snl > bufsize - 1) {
mrb_free(mrb, buf);
bufsize = snl + 1;
if ((buf = mrb_malloc(mrb, bufsize)) == NULL) {
if ((buf = (char *)mrb_malloc(mrb, bufsize)) == NULL) {
ret = MRB_DUMP_GENERAL_FAILURE;
goto error_exit;
}
@@ -477,7 +469,7 @@ read_rite_irep_record(mrb_state *mrb, unsigned char *src, mrb_irep *irep, uint32
memcpy(buf, src, snl); //symbol name
src += snl;
buf[snl] = '\0';
irep->syms[i] = mrb_intern(mrb, buf);
irep->syms[i] = mrb_intern2(mrb, buf, snl);
}
}
crc = calc_crc_16_ccitt((unsigned char*)pStart, src - pStart); //Calculate CRC
@@ -517,7 +509,7 @@ mrb_read_irep(mrb_state *mrb, const char *bin)
mrb_add_irep(mrb, sirep + nirep);
for (n=0,i=sirep; n<nirep; n++,i++) {
if ((mrb->irep[i] = mrb_malloc(mrb, sizeof(mrb_irep))) == NULL) {
if ((mrb->irep[i] = (mrb_irep *)mrb_malloc(mrb, sizeof(mrb_irep))) == NULL) {
ret = MRB_DUMP_GENERAL_FAILURE;
goto error_exit;
}
@@ -616,13 +608,11 @@ static char*
hex_to_str(char *hex, char *str, uint16_t *str_len)
{
char *src, *dst;
uint16_t hex_len = strlen(hex);
int escape = 0;
*str_len = 0;
for (src = hex, dst = str; hex_len > 0; (*str_len)++, hex_len--) {
if (*src == '\\' && hex_len > 1) {
src++; hex_len--;
for (src = hex, dst = str; *src != '\0'; src++) {
if (escape) {
switch(*src) {
case 'a': *dst++ = '\a'/* BEL */; break;
case 'b': *dst++ = '\b'/* BS */; break;
@@ -637,12 +627,18 @@ hex_to_str(char *hex, char *str, uint16_t *str_len)
case '\\': *dst++ = *src; break;
default:break;
}
src++;
escape = 0;
} else {
*dst++ = *src++;
if (*src == '\\') {
escape = 1;
} else {
escape = 0;
*dst++ = *src;
}
}
if (!escape) {
(*str_len)++;
}
}
return str;
}
+74 -45
View File
@@ -5,15 +5,19 @@
*/
#include "mruby.h"
#include "mruby/array.h"
#ifdef ENABLE_MATH
#include <math.h>
#define domain_error(msg) \
mrb_raise(mrb, E_RANGE_ERROR, "Numerical argument is out of domain - " #msg);
#define MATH_TOLERANCE 1E-12
/* math functions not provided under Microsoft Visual C++ */
#ifdef _MSC_VER
#define MATH_TOLERANCE 1E-12
#define asinh(x) log(x + sqrt(pow(x,2.0) + 1))
#define acosh(x) log(x + sqrt(pow(x,2.0) - 1))
#define atanh(x) (log(1+x) - log(1-x))/2.0
@@ -85,10 +89,6 @@ erfc(double x)
#endif
mrb_value
mrb_assoc_new(mrb_state *mrb, mrb_value car, mrb_value cdr);
/*
TRIGONOMETRIC FUNCTIONS
*/
@@ -410,11 +410,14 @@ math_exp(mrb_state *mrb, mrb_value obj)
static mrb_value
math_log(mrb_state *mrb, mrb_value obj)
{
mrb_float x;
mrb_float x, base;
int argc;
mrb_get_args(mrb, "f", &x);
argc = mrb_get_args(mrb, "f|f", &x, &base);
x = log(x);
if (argc == 2) {
x /= log(base);
}
return mrb_float_value(x);
}
@@ -463,6 +466,25 @@ math_log10(mrb_state *mrb, mrb_value obj)
return mrb_float_value(x);
}
/*
* call-seq:
* Math.sqrt(numeric) -> float
*
* Returns the square root of <i>numeric</i>.
*
*/
static mrb_value
math_sqrt(mrb_state *mrb, mrb_value obj)
{
mrb_float x;
mrb_get_args(mrb, "f", &x);
x = sqrt(x);
return mrb_float_value(x);
}
/*
* call-seq:
* Math.cbrt(numeric) -> float
@@ -612,47 +634,54 @@ mrb_init_math(mrb_state *mrb)
struct RClass *mrb_math;
mrb_math = mrb_define_module(mrb, "Math");
mrb_define_const(mrb, mrb_math, "TOLERANCE", mrb_float_value(MATH_TOLERANCE));
#ifdef M_PI
mrb_define_const(mrb, mrb_math, "PI", mrb_float_value(M_PI));
#else
mrb_define_const(mrb, mrb_math, "PI", mrb_float_value(atan(1.0)*4.0));
#endif
#ifdef M_PI
mrb_define_const(mrb, mrb_math, "PI", mrb_float_value(M_PI));
#else
mrb_define_const(mrb, mrb_math, "PI", mrb_float_value(atan(1.0)*4.0));
#endif
#ifdef M_E
mrb_define_const(mrb, mrb_math, "E", mrb_float_value(M_E));
#else
mrb_define_const(mrb, mrb_math, "E", mrb_float_value(exp(1.0)));
#endif
#ifdef M_E
mrb_define_const(mrb, mrb_math, "E", mrb_float_value(M_E));
#else
mrb_define_const(mrb, mrb_math, "E", mrb_float_value(exp(1.0)));
#endif
#ifdef MRB_USE_FLOAT
mrb_define_const(mrb, mrb_math, "TOLERANCE", mrb_float_value(1e-5));
#else
mrb_define_const(mrb, mrb_math, "TOLERANCE", mrb_float_value(1e-12));
#endif
mrb_define_module_function(mrb, mrb_math, "sin", math_sin, ARGS_REQ(1));
mrb_define_module_function(mrb, mrb_math, "cos", math_cos, ARGS_REQ(1));
mrb_define_module_function(mrb, mrb_math, "tan", math_tan, ARGS_REQ(1));
mrb_define_module_function(mrb, mrb_math, "asin", math_asin, ARGS_REQ(1));
mrb_define_module_function(mrb, mrb_math, "acos", math_acos, ARGS_REQ(1));
mrb_define_module_function(mrb, mrb_math, "atan", math_atan, ARGS_REQ(1));
mrb_define_module_function(mrb, mrb_math, "atan2", math_atan2, ARGS_REQ(2));
mrb_define_module_function(mrb, mrb_math, "sin", math_sin, 1);
mrb_define_module_function(mrb, mrb_math, "cos", math_cos, 1);
mrb_define_module_function(mrb, mrb_math, "tan", math_tan, 1);
mrb_define_module_function(mrb, mrb_math, "sinh", math_sinh, ARGS_REQ(1));
mrb_define_module_function(mrb, mrb_math, "cosh", math_cosh, ARGS_REQ(1));
mrb_define_module_function(mrb, mrb_math, "tanh", math_tanh, ARGS_REQ(1));
mrb_define_module_function(mrb, mrb_math, "asin", math_asin, 1);
mrb_define_module_function(mrb, mrb_math, "acos", math_acos, 1);
mrb_define_module_function(mrb, mrb_math, "atan", math_atan, 1);
mrb_define_module_function(mrb, mrb_math, "atan2", math_atan2, 2);
mrb_define_module_function(mrb, mrb_math, "sinh", math_sinh, 1);
mrb_define_module_function(mrb, mrb_math, "cosh", math_cosh, 1);
mrb_define_module_function(mrb, mrb_math, "tanh", math_tanh, 1);
mrb_define_module_function(mrb, mrb_math, "asinh", math_asinh, ARGS_REQ(1));
mrb_define_module_function(mrb, mrb_math, "acosh", math_acosh, ARGS_REQ(1));
mrb_define_module_function(mrb, mrb_math, "atanh", math_atanh, ARGS_REQ(1));
mrb_define_module_function(mrb, mrb_math, "asinh", math_asinh, 1);
mrb_define_module_function(mrb, mrb_math, "acosh", math_acosh, 1);
mrb_define_module_function(mrb, mrb_math, "atanh", math_atanh, 1);
mrb_define_module_function(mrb, mrb_math, "exp", math_exp, ARGS_REQ(1));
mrb_define_module_function(mrb, mrb_math, "log", math_log, ARGS_REQ(1)|ARGS_OPT(1));
mrb_define_module_function(mrb, mrb_math, "log2", math_log2, ARGS_REQ(1));
mrb_define_module_function(mrb, mrb_math, "log10", math_log10, ARGS_REQ(1));
mrb_define_module_function(mrb, mrb_math, "sqrt", math_sqrt, ARGS_REQ(1));
mrb_define_module_function(mrb, mrb_math, "cbrt", math_cbrt, ARGS_REQ(1));
mrb_define_module_function(mrb, mrb_math, "exp", math_exp, 1);
mrb_define_module_function(mrb, mrb_math, "log", math_log, -1);
mrb_define_module_function(mrb, mrb_math, "log2", math_log2, 1);
mrb_define_module_function(mrb, mrb_math, "log10", math_log10, 1);
mrb_define_module_function(mrb, mrb_math, "cbrt", math_cbrt, 1);
mrb_define_module_function(mrb, mrb_math, "frexp", math_frexp, ARGS_REQ(1));
mrb_define_module_function(mrb, mrb_math, "ldexp", math_ldexp, ARGS_REQ(2));
mrb_define_module_function(mrb, mrb_math, "frexp", math_frexp, 1);
mrb_define_module_function(mrb, mrb_math, "ldexp", math_ldexp, 2);
mrb_define_module_function(mrb, mrb_math, "hypot", math_hypot, ARGS_REQ(2));
mrb_define_module_function(mrb, mrb_math, "hypot", math_hypot, 2);
mrb_define_module_function(mrb, mrb_math, "erf", math_erf, 1);
mrb_define_module_function(mrb, mrb_math, "erfc", math_erfc, 1);
mrb_define_module_function(mrb, mrb_math, "erf", math_erf, ARGS_REQ(1));
mrb_define_module_function(mrb, mrb_math, "erfc", math_erfc, ARGS_REQ(1));
}
#endif /* ENABLE_MATH */
-26
View File
@@ -103,29 +103,3 @@ enum node_type {
NODE_ATTRASGN,
NODE_LAST
};
typedef struct RNode {
unsigned long flags;
char *nd_file;
union {
struct RNode *node;
mrb_sym id;
mrb_value value;
//mrb_value (*cfunc)((ARGS_ANY()));
mrb_sym *tbl;
} u1;
union {
struct RNode *node;
mrb_sym id;
long argc;
mrb_value value;
} u2;
union {
struct RNode *node;
mrb_sym id;
long state;
struct global_entry *entry;
long cnt;
mrb_value value;
} u3;
} NODE;
+161 -144
View File
@@ -8,13 +8,10 @@
#include "mruby/numeric.h"
#include "mruby/string.h"
#include "mruby/array.h"
#include <string.h>
#include "mruby/class.h"
#include "mruby/variable.h"
#include <ctype.h>
#include <math.h>
#include <stdio.h>
#include <assert.h>
#if defined(__FreeBSD__) && __FreeBSD__ < 4
#include <floatingpoint.h>
@@ -28,7 +25,7 @@
#include <ieeefp.h>
#endif
#define SIGNED_VALUE intptr_t
#define RSHIFT(x,y) ((x)>>(int)(y))
#ifdef MRB_USE_FLOAT
#define floor(f) floorf(f)
@@ -118,6 +115,12 @@ num_pow(mrb_state *mrb, mrb_value x)
* result.
*/
mrb_value
mrb_num_div(mrb_state *mrb, mrb_value x, mrb_value y)
{
return mrb_float_value(mrb_to_flo(mrb, x) / mrb_to_flo(mrb, y));
}
/* 15.2.9.3.19(x) */
/*
* call-seq:
@@ -180,29 +183,25 @@ static mrb_value
flo_to_s(mrb_state *mrb, mrb_value flt)
{
char buf[32];
int n;
mrb_float value = mrb_float(flt);
char *p, *e;
if (isinf(value))
return mrb_str_new2(mrb, value < 0 ? "-Infinity" : "Infinity");
else if(isnan(value))
return mrb_str_new2(mrb, "NaN");
if (isinf(value)) {
static const char s[2][5] = { "-inf", "inf" };
static const int n[] = { 4, 3 };
int idx;
idx = (value < 0) ? 0 : 1;
return mrb_str_new(mrb, s[idx], n[idx]);
} else if(isnan(value))
return mrb_str_new(mrb, "NaN", 3);
sprintf(buf, "%#.15g", value); /* ensure to print decimal point */
if (!(e = strchr(buf, 'e'))) {
e = buf + strlen(buf);
}
if (!ISDIGIT(e[-1])) { /* reformat if ended with decimal point (ex 111111111111111.) */
sprintf(buf, "%#.14e", value);
if (!(e = strchr(buf, 'e'))) {
e = buf + strlen(buf);
}
}
p = e;
while (p[-1]=='0' && ISDIGIT(p[-2]))
p--;
memmove(p, e, strlen(e)+1);
return mrb_str_new2(mrb, buf);
#ifdef MRB_USE_FLOAT
n = sprintf(buf, "%.7g", value);
#else
n = sprintf(buf, "%.14g", value);
#endif
assert(n >= 0);
return mrb_str_new(mrb, buf, n);
}
/* 15.2.9.3.2 */
@@ -404,7 +403,7 @@ flo_to_f(mrb_state *mrb, mrb_value num)
*/
static mrb_value
flo_is_infinite_p(mrb_state *mrb, mrb_value num)
flo_infinite_p(mrb_state *mrb, mrb_value num)
{
mrb_float value = mrb_float(num);
@@ -426,7 +425,7 @@ flo_is_infinite_p(mrb_state *mrb, mrb_value num)
*/
static mrb_value
flo_is_finite_p(mrb_state *mrb, mrb_value num)
flo_finite_p(mrb_state *mrb, mrb_value num)
{
mrb_float value = mrb_float(num);
@@ -516,21 +515,13 @@ flo_ceil(mrb_state *mrb, mrb_value num)
*/
static mrb_value
flo_round(mrb_state *mrb, /*int argc, mrb_value *argv,*/ mrb_value num)
flo_round(mrb_state *mrb, mrb_value num)
{
mrb_value nd;
mrb_float number, f;
double number, f;
int ndigits = 0, i;
mrb_value *argv;
int argc;
mrb_get_args(mrb, "*", &argv, &argc);
if (argc == 1) {
nd = argv[0];
ndigits = mrb_fixnum(nd);
}
number = mrb_float(num);
mrb_get_args(mrb, "|i", &ndigits);
number = mrb_float(num);
f = 1.0;
i = abs(ndigits);
while (--i >= 0)
@@ -540,7 +531,7 @@ flo_round(mrb_state *mrb, /*int argc, mrb_value *argv,*/ mrb_value num)
if (ndigits < 0) number = 0;
}
else {
mrb_float d;
double d;
if (ndigits < 0) number /= f;
else number *= f;
@@ -558,7 +549,6 @@ flo_round(mrb_state *mrb, /*int argc, mrb_value *argv,*/ mrb_value num)
if (ndigits < 0) number *= f;
else number /= f;
}
if (ndigits > 0) return mrb_float_value(number);
return mrb_fixnum_value((mrb_int)number);
}
@@ -691,9 +681,31 @@ int_succ(mrb_state *mrb, mrb_value num)
return mrb_funcall(mrb, num, "+", 1, mrb_fixnum_value(1));
}
#define SQRT_LONG_MAX ((SIGNED_VALUE)1<<((sizeof(mrb_int)*CHAR_BIT-1)/2))
#define SQRT_INT_MAX ((mrb_int)1<<((sizeof(mrb_int)*CHAR_BIT-1)/2))
/*tests if N*N would overflow*/
#define FIT_SQRT_LONG(n) (((n)<SQRT_LONG_MAX)&&((n)>=-SQRT_LONG_MAX))
#define FIT_SQRT_INT(n) (((n)<SQRT_INT_MAX)&&((n)>=-SQRT_INT_MAX))
mrb_value
mrb_fixnum_mul(mrb_state *mrb, mrb_value x, mrb_value y)
{
mrb_int a;
a = mrb_fixnum(x);
if (a == 0) return x;
if (FIXNUM_P(y)) {
mrb_int b, c;
b = mrb_fixnum(y);
if (FIT_SQRT_INT(a) && FIT_SQRT_INT(b))
return mrb_fixnum_value(a*b);
c = a * b;
if (c/a != b) {
return mrb_float_value((mrb_float)a*(mrb_float)b);
}
return mrb_fixnum_value(c);;
}
return mrb_float_value((mrb_float)a * mrb_to_flo(mrb, y));
}
/* 15.2.8.3.3 */
/*
@@ -709,27 +721,8 @@ static mrb_value
fix_mul(mrb_state *mrb, mrb_value x)
{
mrb_value y;
mrb_int a;
mrb_get_args(mrb, "o", &y);
a = mrb_fixnum(x);
if (FIXNUM_P(y)) {
mrb_int b, c;
mrb_value r;
b = mrb_fixnum(y);
if (FIT_SQRT_LONG(a) && FIT_SQRT_LONG(b))
return mrb_fixnum_value(a*b);
c = a * b;
r = mrb_fixnum_value(c);
if (a == 0) return x;
if (mrb_fixnum(r) != c || c/a != b) {
r = mrb_float_value((mrb_float)a*(mrb_float)b);
}
return r;
}
return mrb_float_value((mrb_float)a * mrb_to_flo(mrb, y));
return mrb_fixnum_mul(mrb, x, y);
}
static void
@@ -772,12 +765,11 @@ static mrb_value
fix_mod(mrb_state *mrb, mrb_value x)
{
mrb_value y;
mrb_int a;
mrb_int a, b;
mrb_get_args(mrb, "o", &y);
a = mrb_fixnum(x);
if (FIXNUM_P(y)) {
if (FIXNUM_P(y) && (b=mrb_fixnum(y)) != 0) {
mrb_int mod;
fixdivmod(mrb, a, mrb_fixnum(y), 0, &mod);
@@ -942,8 +934,28 @@ fix_xor(mrb_state *mrb, mrb_value x)
return mrb_fixnum_value(val);
}
static mrb_value fix_lshift(mrb_state *mrb, mrb_int, unsigned long);
static mrb_value fix_rshift(mrb_int, unsigned long);
static mrb_value
lshift(mrb_state *mrb, mrb_int val, unsigned long width)
{
if (width > (sizeof(mrb_int)*CHAR_BIT-1)
|| ((unsigned long)abs(val))>>(sizeof(mrb_int)*CHAR_BIT-1-width) > 0) {
mrb_raise(mrb, E_RANGE_ERROR, "width(%d) > (%d:sizeof(mrb_int)*CHAR_BIT-1)", width,
sizeof(mrb_int)*CHAR_BIT-1);
}
val = val << width;
return mrb_fixnum_value(val);
}
static mrb_value
rshift(mrb_int val, unsigned long i)
{
if (i >= sizeof(mrb_int)*CHAR_BIT-1) {
if (val < 0) return mrb_fixnum_value(-1);
return mrb_fixnum_value(0);
}
val = RSHIFT(val, i);
return mrb_fixnum_value(val);
}
/* 15.2.8.3.12 */
/*
@@ -954,7 +966,7 @@ static mrb_value fix_rshift(mrb_int, unsigned long);
*/
static mrb_value
mrb_fix_lshift(mrb_state *mrb, mrb_value x)
fix_lshift(mrb_state *mrb, mrb_value x)
{
mrb_value y;
mrb_int val, width;
@@ -964,20 +976,8 @@ mrb_fix_lshift(mrb_state *mrb, mrb_value x)
y = bit_coerce(mrb, y);
width = mrb_fixnum(y);
if (width < 0)
return fix_rshift(val, (unsigned long)-width);
return fix_lshift(mrb, val, width);
}
static mrb_value
fix_lshift(mrb_state *mrb, mrb_int val, unsigned long width)
{
if (width > (sizeof(mrb_int)*CHAR_BIT-1)
|| ((unsigned long)abs(val))>>(sizeof(mrb_int)*CHAR_BIT-1-width) > 0) {
mrb_raise(mrb, E_RANGE_ERROR, "width(%d) > (%d:sizeof(mrb_int)*CHAR_BIT-1)", width,
sizeof(mrb_int)*CHAR_BIT-1);
}
val = val << width;
return mrb_fixnum_value(val);
return rshift(val, (unsigned long)-width);
return lshift(mrb, val, width);
}
/* 15.2.8.3.13 */
@@ -989,7 +989,7 @@ fix_lshift(mrb_state *mrb, mrb_int val, unsigned long width)
*/
static mrb_value
mrb_fix_rshift(mrb_state *mrb, mrb_value x)
fix_rshift(mrb_state *mrb, mrb_value x)
{
mrb_value y;
mrb_int i, val;
@@ -1000,19 +1000,8 @@ mrb_fix_rshift(mrb_state *mrb, mrb_value x)
i = mrb_fixnum(y);
if (i == 0) return x;
if (i < 0)
return fix_lshift(mrb, val, (unsigned long)-i);
return fix_rshift(val, i);
}
static mrb_value
fix_rshift(mrb_int val, unsigned long i)
{
if (i >= sizeof(mrb_int)*CHAR_BIT-1) {
if (val < 0) return mrb_fixnum_value(-1);
return mrb_fixnum_value(0);
}
val = RSHIFT(val, i);
return mrb_fixnum_value(val);
return lshift(mrb, val, (unsigned long)-i);
return rshift(val, i);
}
/* 15.2.8.3.23 */
@@ -1066,7 +1055,28 @@ flt2big(mrb_state *mrb, mrb_float d)
mrb_value
mrb_flt2big(mrb_state *mrb, mrb_float d)
{
return mrb_fixnum_value(flt2big(mrb, d));
return mrb_fixnum_value(flt2big(mrb, d));
}
mrb_value
mrb_fixnum_plus(mrb_state *mrb, mrb_value x, mrb_value y)
{
mrb_int a;
a = mrb_fixnum(x);
if (a == 0) return y;
if (FIXNUM_P(y)) {
mrb_int b, c;
b = mrb_fixnum(y);
c = a + b;
if (((a < 0) ^ (b < 0)) == 0 && (a < 0) != (c < 0)) {
/* integer overflow */
return mrb_float_value((mrb_float)a + (mrb_float)b);
}
return mrb_fixnum_value(c);
}
return mrb_float_value((mrb_float)a + mrb_to_flo(mrb, y));
}
/* 15.2.8.3.1 */
@@ -1079,15 +1089,32 @@ mrb_flt2big(mrb_state *mrb, mrb_float d)
* result.
*/
static mrb_value
mrb_fixnum_plus(mrb_state *mrb, mrb_value self)
fix_plus(mrb_state *mrb, mrb_value self)
{
mrb_int x, y;
mrb_value other;
x = mrb_fixnum(self);
mrb_get_args(mrb, "i", &y);
mrb_get_args(mrb, "o", &other);
return mrb_fixnum_plus(mrb, self, other);
}
DEBUG(printf("%d + %d = %d\n", x, y, x+y));
return mrb_fixnum_value(x + y);
mrb_value
mrb_fixnum_minus(mrb_state *mrb, mrb_value x, mrb_value y)
{
mrb_int a;
a = mrb_fixnum(x);
if (FIXNUM_P(y)) {
mrb_int b, c;
b = mrb_fixnum(y);
c = a - b;
if (((a < 0) ^ (b < 0)) != 0 && (a < 0) != (c < 0)) {
/* integer overflow */
return mrb_float_value((mrb_float)a - (mrb_float)b);
}
return mrb_fixnum_value(c);
}
return mrb_float_value((mrb_float)a - mrb_to_flo(mrb, y));
}
/* 15.2.8.3.2 */
@@ -1101,15 +1128,12 @@ mrb_fixnum_plus(mrb_state *mrb, mrb_value self)
* result.
*/
static mrb_value
mrb_fixnum_minus(mrb_state *mrb, mrb_value self)
fix_minus(mrb_state *mrb, mrb_value self)
{
mrb_int x, y;
mrb_value other;
x = mrb_fixnum(self);
mrb_get_args(mrb, "i", &y);
DEBUG(printf("%d - %d = %d\n", x, y, x-y));
return mrb_fixnum_value(x - y);
mrb_get_args(mrb, "o", &other);
return mrb_fixnum_minus(mrb, self, other);
}
/* 15.2.8.3.29 (x) */
@@ -1132,16 +1156,23 @@ mrb_fix2str(mrb_state *mrb, mrb_value x, int base)
mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid radix %d", base);
}
if (val == 0) {
return mrb_str_new2(mrb, "0");
return mrb_str_new(mrb, "0", 1);
}
if (val < 0) {
val = -val;
neg = 1;
}
*--b = '\0';
do {
*--b = mrb_digitmap[(int)(val % base)];
} while (val /= base);
if (neg && val < 0) {
do {
*--b = mrb_digitmap[abs(val % base)];
} while (val /= base);
}
else {
do {
*--b = mrb_digitmap[(int)(val % base)];
} while (val /= base);
}
if (neg) {
*--b = '-';
}
@@ -1149,19 +1180,6 @@ mrb_fix2str(mrb_state *mrb, mrb_value x, int base)
return mrb_str_new2(mrb, b);
}
mrb_value
mrb_fix_to_s(mrb_state *mrb, mrb_value self, int argc, mrb_value *argv)
{
int base;
if (argc == 0) base = 10;
else {
mrb_get_args(mrb, "i", &base);
}
return mrb_fix2str(mrb, self, base);
}
/* 15.2.8.3.25 */
/*
* call-seq:
@@ -1179,13 +1197,12 @@ mrb_fix_to_s(mrb_state *mrb, mrb_value self, int argc, mrb_value *argv)
*
*/
static mrb_value
mrb_fixnum_to_s(mrb_state *mrb, mrb_value self) /* fix_to_s */
fix_to_s(mrb_state *mrb, mrb_value self)
{
mrb_value *argv;
int argc;
mrb_int base = 10;
mrb_get_args(mrb, "*", &argv, &argc);
return mrb_fix_to_s(mrb, self, argc, argv);
mrb_get_args(mrb, "|i", &base);
return mrb_fix2str(mrb, self, base);
}
/* 15.2.9.3.6 */
@@ -1236,7 +1253,7 @@ num_cmp(mrb_state *mrb, mrb_value self)
* and <code>other</code>.
*/
static mrb_value
mrb_float_plus(mrb_state *mrb, mrb_value self)
flo_plus(mrb_state *mrb, mrb_value self)
{
mrb_float x, y;
@@ -1266,9 +1283,9 @@ mrb_init_numeric(mrb_state *mrb)
integer = mrb_define_class(mrb, "Integer", numeric);
fixnum = mrb->fixnum_class = mrb_define_class(mrb, "Fixnum", integer);
mrb_undef_method(mrb, fixnum, "new");
mrb_define_method(mrb, fixnum, "+", mrb_fixnum_plus, ARGS_REQ(1)); /* 15.2.8.3.1 */
mrb_define_method(mrb, fixnum, "-", mrb_fixnum_minus, ARGS_REQ(1)); /* 15.2.8.3.2 */
mrb_undef_class_method(mrb, fixnum, "new");
mrb_define_method(mrb, fixnum, "+", fix_plus, ARGS_REQ(1)); /* 15.2.8.3.1 */
mrb_define_method(mrb, fixnum, "-", fix_minus, ARGS_REQ(1)); /* 15.2.8.3.2 */
mrb_define_method(mrb, fixnum, "-@", fix_uminus, ARGS_REQ(1)); /* 15.2.7.4.2 */
mrb_define_method(mrb, fixnum, "*", fix_mul, ARGS_REQ(1)); /* 15.2.8.3.3 */
mrb_define_method(mrb, fixnum, "%", fix_mod, ARGS_REQ(1)); /* 15.2.8.3.5 */
@@ -1277,8 +1294,8 @@ mrb_init_numeric(mrb_state *mrb)
mrb_define_method(mrb, fixnum, "&", fix_and, ARGS_REQ(1)); /* 15.2.8.3.9 */
mrb_define_method(mrb, fixnum, "|", fix_or, ARGS_REQ(1)); /* 15.2.8.3.10 */
mrb_define_method(mrb, fixnum, "^", fix_xor, ARGS_REQ(1)); /* 15.2.8.3.11 */
mrb_define_method(mrb, fixnum, "<<", mrb_fix_lshift, ARGS_REQ(1)); /* 15.2.8.3.12 */
mrb_define_method(mrb, fixnum, ">>", mrb_fix_rshift, ARGS_REQ(1)); /* 15.2.8.3.13 */
mrb_define_method(mrb, fixnum, "<<", fix_lshift, ARGS_REQ(1)); /* 15.2.8.3.12 */
mrb_define_method(mrb, fixnum, ">>", fix_rshift, ARGS_REQ(1)); /* 15.2.8.3.13 */
mrb_define_method(mrb, fixnum, "ceil", int_to_i, ARGS_NONE()); /* 15.2.8.3.14 */
mrb_define_method(mrb, fixnum, "eql?", num_eql, ARGS_REQ(1)); /* 15.2.8.3.16 */
mrb_define_method(mrb, fixnum, "floor", num_floor, ARGS_NONE()); /* 15.2.8.3.17 */
@@ -1288,22 +1305,22 @@ mrb_init_numeric(mrb_state *mrb)
mrb_define_method(mrb, fixnum, "succ", fix_succ, ARGS_NONE()); /* 15.2.8.3.21 */
mrb_define_method(mrb, fixnum, "to_f", fix_to_f, ARGS_NONE()); /* 15.2.8.3.23 */
mrb_define_method(mrb, fixnum, "to_i", int_to_i, ARGS_NONE()); /* 15.2.8.3.24 */
mrb_define_method(mrb, fixnum, "to_s", mrb_fixnum_to_s, ARGS_NONE()); /* 15.2.8.3.25 */
mrb_define_method(mrb, fixnum, "to_s", fix_to_s, ARGS_NONE()); /* 15.2.8.3.25 */
mrb_define_method(mrb, fixnum, "truncate", int_to_i, ARGS_NONE()); /* 15.2.8.3.26 */
mrb_define_method(mrb, fixnum, "divmod", fix_divmod, ARGS_REQ(1)); /* 15.2.8.3.30 (x) */
/* Float Class */
fl = mrb->float_class = mrb_define_class(mrb, "Float", numeric);
mrb_undef_method(mrb, fl, "new");
mrb_define_method(mrb, fl, "+", mrb_float_plus, ARGS_REQ(1)); /* 15.2.9.3.1 */
mrb_undef_class_method(mrb, fl, "new");
mrb_define_method(mrb, fl, "+", flo_plus, ARGS_REQ(1)); /* 15.2.9.3.1 */
mrb_define_method(mrb, fl, "-", flo_minus, ARGS_REQ(1)); /* 15.2.9.3.2 */
mrb_define_method(mrb, fl, "*", flo_mul, ARGS_REQ(1)); /* 15.2.9.3.3 */
mrb_define_method(mrb, fl, "%", flo_mod, ARGS_REQ(1)); /* 15.2.9.3.5 */
mrb_define_method(mrb, fl, "==", flo_eq, ARGS_REQ(1)); /* 15.2.9.3.7 */
mrb_define_method(mrb, fl, "ceil", flo_ceil, ARGS_NONE()); /* 15.2.9.3.8 */
mrb_define_method(mrb, fl, "finite?", flo_is_finite_p, ARGS_NONE()); /* 15.2.9.3.9 */
mrb_define_method(mrb, fl, "finite?", flo_finite_p, ARGS_NONE()); /* 15.2.9.3.9 */
mrb_define_method(mrb, fl, "floor", flo_floor, ARGS_NONE()); /* 15.2.9.3.10 */
mrb_define_method(mrb, fl, "infinite?", flo_is_infinite_p,ARGS_NONE()); /* 15.2.9.3.11 */
mrb_define_method(mrb, fl, "infinite?", flo_infinite_p, ARGS_NONE()); /* 15.2.9.3.11 */
mrb_define_method(mrb, fl, "round", flo_round, ARGS_ANY()); /* 15.2.9.3.12 */
mrb_define_method(mrb, fl, "to_f", flo_to_f, ARGS_NONE()); /* 15.2.9.3.13 */
mrb_define_method(mrb, fl, "to_i", flo_truncate, ARGS_NONE()); /* 15.2.9.3.14 */
+14 -37
View File
@@ -11,14 +11,6 @@
#include "mruby/class.h"
#include "mruby/numeric.h"
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
int
mrb_obj_eq(mrb_state *mrb, mrb_value v1, mrb_value v2)
{
@@ -159,7 +151,7 @@ true_xor(mrb_state *mrb, mrb_value obj)
static mrb_value
true_to_s(mrb_state *mrb, mrb_value obj)
{
return mrb_str_new_cstr(mrb, "true");
return mrb_str_new(mrb, "true", 4);
}
/* 15.2.5.3.4 */
@@ -272,7 +264,7 @@ false_or(mrb_state *mrb, mrb_value obj)
static mrb_value
false_to_s(mrb_state *mrb, mrb_value obj)
{
return mrb_str_new_cstr(mrb, "false");
return mrb_str_new(mrb, "false", 5);
}
void
@@ -283,7 +275,7 @@ mrb_init_object(mrb_state *mrb)
struct RClass *f;
n = mrb->nil_class = mrb_define_class(mrb, "NilClass", mrb->object_class);
mrb_undef_method(mrb, n, "new");
mrb_undef_class_method(mrb, n, "new");
mrb_define_method(mrb, n, "&", false_and, ARGS_REQ(1)); /* 15.2.4.3.1 */
mrb_define_method(mrb, n, "^", false_xor, ARGS_REQ(1)); /* 15.2.4.3.2 */
mrb_define_method(mrb, n, "|", false_or, ARGS_REQ(1)); /* 15.2.4.3.3 */
@@ -291,14 +283,14 @@ mrb_init_object(mrb_state *mrb)
mrb_define_method(mrb, n, "to_s", nil_to_s, ARGS_NONE()); /* 15.2.4.3.5 */
t = mrb->true_class = mrb_define_class(mrb, "TrueClass", mrb->object_class);
mrb_undef_method(mrb, n, "new");
mrb_undef_class_method(mrb, t, "new");
mrb_define_method(mrb, t, "&", true_and, ARGS_REQ(1)); /* 15.2.5.3.1 */
mrb_define_method(mrb, t, "^", true_xor, ARGS_REQ(1)); /* 15.2.5.3.2 */
mrb_define_method(mrb, t, "to_s", true_to_s, ARGS_NONE()); /* 15.2.5.3.3 */
mrb_define_method(mrb, t, "|", true_or, ARGS_REQ(1)); /* 15.2.5.3.4 */
f = mrb->false_class = mrb_define_class(mrb, "FalseClass", mrb->object_class);
mrb_undef_method(mrb, n, "new");
mrb_undef_class_method(mrb, f, "new");
mrb_define_method(mrb, f, "&", false_and, ARGS_REQ(1)); /* 15.2.6.3.1 */
mrb_define_method(mrb, f, "^", false_xor, ARGS_REQ(1)); /* 15.2.6.3.2 */
mrb_define_method(mrb, f, "to_s", false_to_s, ARGS_NONE()); /* 15.2.6.3.3 */
@@ -325,7 +317,7 @@ convert_type(mrb_state *mrb, mrb_value val, const char *tname, const char *metho
return mrb_nil_value();
}
}
return mrb_funcall(mrb, val, method, 0);
return mrb_funcall_argv(mrb, val, m, 0, 0);
}
mrb_value
@@ -335,8 +327,7 @@ mrb_check_to_integer(mrb_state *mrb, mrb_value val, const char *method)
if (mrb_type(val) == MRB_TT_FIXNUM) return val;
v = convert_type(mrb, val, "Integer", method, FALSE);
if (mrb_nil_p(v)) return (v);
if (!mrb_obj_is_kind_of(mrb, v, mrb_obj_class(mrb, v))) {
if (mrb_nil_p(v) || mrb_type(v) != MRB_TT_FIXNUM) {
return mrb_nil_value();
}
return v;
@@ -350,8 +341,8 @@ mrb_convert_type(mrb_state *mrb, mrb_value val, mrb_int type, const char *tname,
if (mrb_type(val) == type) return val;
v = convert_type(mrb, val, tname, method, 1/*Qtrue*/);
if (mrb_type(v) != type) {
mrb_raise(mrb, E_TYPE_ERROR, "%s#%s should return %s",
mrb_obj_classname(mrb, val), method, tname);
mrb_raise(mrb, E_TYPE_ERROR, "%s cannot be converted to %s by #%s",
mrb_obj_classname(mrb, val), tname, method);
}
return v;
}
@@ -361,14 +352,9 @@ mrb_check_convert_type(mrb_state *mrb, mrb_value val, mrb_int type, const char *
{
mrb_value v;
/* always convert T_DATA */
if (mrb_type(val) == type && type != MRB_TT_DATA) return val;
v = convert_type(mrb, val, tname, method, 0/*Qfalse*/);
if (mrb_nil_p(v)) return mrb_nil_value();
if (mrb_type(v) != type) {
mrb_raise(mrb, E_TYPE_ERROR, "%s#%s should return %s",
mrb_obj_classname(mrb, val), method, tname);
}
if (mrb_nil_p(v) || mrb_type(v) != type) return mrb_nil_value();
return v;
}
@@ -411,11 +397,6 @@ mrb_check_type(mrb_state *mrb, mrb_value x, enum mrb_vtype t)
struct RString *s;
int xt;
/*if (x == Qundef) {
//mrb_bug("undef leaked to the Ruby space");
printf ("undef leaked to the Ruby space\n");
}*/
xt = mrb_type(x);
if ((xt != t) || (xt == MRB_TT_DATA)) {
while (type->type < MRB_TT_MAXDEFINE) {
@@ -433,18 +414,17 @@ mrb_check_type(mrb_state *mrb, mrb_value x, enum mrb_vtype t)
}
else if (mrb_special_const_p(x)) {
s = mrb_str_ptr(mrb_obj_as_string(mrb, x));
etype = s->buf;
etype = s->ptr;
}
else {
etype = mrb_obj_classname(mrb, x);
}
mrb_raise(mrb, E_TYPE_ERROR, "wrong argument type %s (expected %s)",
etype, type->name);
etype, type->name);
}
type++;
}
/*mrb_bug("unknown type 0x%x", t);*/
printf ("unknown type 0x%x (0x%x given)", t, mrb_type(x));
mrb_raise(mrb, E_TYPE_ERROR, "unknown type 0x%x (0x%x given)", t, mrb_type(x));
}
}
@@ -470,9 +450,7 @@ mrb_any_to_s(mrb_state *mrb, mrb_value obj)
len = strlen(cname)+6+16;
str = mrb_str_new(mrb, 0, len); /* 6:tags 16:addr */
s = mrb_str_ptr(str);
// snprintf(RSTRING(str)->ptr, len+1, "#<%s:0x%lx>", cname, obj);
sprintf(s->buf, "#<%s:0x%lx>", cname, (unsigned long)(obj.value.p));
s->len = strlen(s->buf);
s->len = sprintf(s->ptr, "#<%s:0x%lx>", cname, (unsigned long)(obj.value.p));
return str;
}
@@ -532,7 +510,6 @@ mrb_to_integer(mrb_state *mrb, mrb_value val, const char *method)
mrb_value v;
if (FIXNUM_P(val)) return val;
//if (TYPE(val) == T_BIGNUM) return val;
v = convert_type(mrb, val, "Integer", method, TRUE);
if (!mrb_obj_is_kind_of(mrb, v, mrb->fixnum_class)) {
const char *cname = mrb_obj_classname(mrb, val);
+9 -9
View File
@@ -14,15 +14,15 @@
/* OP:A:Bx = 7:9:16 */
/* OP:Ax = 7:25 */
#define GET_OPCODE(i) (((mrb_code)(i)) & 0x7f)
#define GETARG_A(i) ((((mrb_code)(i)) >> 23) & 0x1ff)
#define GETARG_B(i) ((((mrb_code)(i)) >> 14) & 0x1ff)
#define GETARG_C(i) ((((mrb_code)(i)) >> 7) & 0x7f)
#define GETARG_Bx(i) ((((mrb_code)(i)) >> 7) & 0xffff)
#define GETARG_sBx(i) (GETARG_Bx(i)-MAXARG_sBx)
#define GETARG_Ax(i) ((((mrb_code)(i)) >> 7) & 0x1ffffff)
#define GETARG_UNPACK_b(i,n1,n2) ((((mrb_code)(i)) >> (7+n2)) & (((1<<n1)-1)))
#define GETARG_UNPACK_c(i,n1,n2) ((((mrb_code)(i)) >> 7) & (((1<<n2)-1)))
#define GET_OPCODE(i) ((int)(((mrb_code)(i)) & 0x7f))
#define GETARG_A(i) ((int)((((mrb_code)(i)) >> 23) & 0x1ff))
#define GETARG_B(i) ((int)((((mrb_code)(i)) >> 14) & 0x1ff))
#define GETARG_C(i) ((int)((((mrb_code)(i)) >> 7) & 0x7f))
#define GETARG_Bx(i) ((int)((((mrb_code)(i)) >> 7) & 0xffff))
#define GETARG_sBx(i) ((int)(GETARG_Bx(i)-MAXARG_sBx))
#define GETARG_Ax(i) ((int)((((mrb_code)(i)) >> 7) & 0x1ffffff))
#define GETARG_UNPACK_b(i,n1,n2) ((int)((((mrb_code)(i)) >> (7+n2)) & (((1<<n1)-1))))
#define GETARG_UNPACK_c(i,n1,n2) ((int)((((mrb_code)(i)) >> 7) & (((1<<n2)-1))))
#define GETARG_b(i) GETARG_UNPACK_b(i,14,2)
#define GETARG_c(i) GETARG_UNPACK_c(i,14,2)
+350 -211
View File
File diff suppressed because it is too large Load Diff
+16 -7
View File
@@ -8,6 +8,18 @@
#include <stddef.h>
#include <string.h>
/* configuration section */
/* allocated memory address should be multiple of POOL_ALIGNMENT */
/* or undef it if alignment does not matter */
#ifndef POOL_ALIGNMENT
#define POOL_ALIGNMENT 4
#endif
/* page size of memory pool */
#ifndef POOL_PAGE_SIZE
#define POOL_PAGE_SIZE 16000
#endif
/* end of configuration section */
struct mrb_pool_page {
struct mrb_pool_page *next;
size_t offset;
@@ -23,16 +35,13 @@ struct mrb_pool {
#undef TEST_POOL
#ifdef TEST_POOL
#include <stdio.h>
#define mrb_malloc(m,s) malloc(s)
#define mrb_free(m,p) free(p)
#endif
#define POOL_PAGE_SIZE 16000
#ifdef ALLOC_ALIGN
# define ALIGN_PADDING(x) ((x % ALLOC_ALIGN) ? ALLOC_ALIGN - (x % ALLOC_ALIGN) : 0)
#ifdef POOL_ALIGNMENT
# define ALIGN_PADDING(x) ((-x) & (POOL_ALIGNMENT - 1))
#else
# define ALIGN_PADDING(x) (0)
#endif
@@ -40,7 +49,7 @@ struct mrb_pool {
mrb_pool*
mrb_pool_open(mrb_state *mrb)
{
mrb_pool *pool = mrb_malloc(mrb, sizeof(mrb_pool));
mrb_pool *pool = (mrb_pool *)mrb_malloc(mrb, sizeof(mrb_pool));
if (pool) {
pool->mrb = mrb;
@@ -72,7 +81,7 @@ page_alloc(mrb_pool *pool, size_t len)
if (len < POOL_PAGE_SIZE)
len = POOL_PAGE_SIZE;
page = mrb_malloc(pool->mrb, sizeof(struct mrb_pool_page)+len-1);
page = (struct mrb_pool_page *)mrb_malloc(pool->mrb, sizeof(struct mrb_pool_page)+len-1);
if (page) {
page->offset = 0;
page->len = len;
+22 -10
View File
@@ -5,35 +5,31 @@
*/
#include "mruby.h"
#ifdef ENABLE_STDIO
#include "mruby/string.h"
#include <stdio.h>
mrb_value
static void
printstr(mrb_state *mrb, mrb_value obj)
{
struct RString *str;
char *s;
size_t len;
int len;
if (mrb_type(obj) == MRB_TT_STRING) {
str = mrb_str_ptr(obj);
s = str->buf;
s = str->ptr;
len = str->len;
while (len--) {
putc(*s, stdout);
s++;
}
fwrite(s, len, 1, stdout);
}
return obj;
}
mrb_value
void
mrb_p(mrb_state *mrb, mrb_value obj)
{
obj = mrb_funcall(mrb, obj, "inspect", 0);
printstr(mrb, obj);
putc('\n', stdout);
return obj;
}
/* 15.3.1.2.9 */
@@ -71,3 +67,19 @@ mrb_show_copyright(mrb_state *mrb)
{
printf("mruby - Copyright (c) 2010-2012 mruby developers\n");
}
#else
void
mrb_p(mrb_state *mrb, mrb_value obj)
{
}
void
mrb_show_version(mrb_state *mrb)
{
}
void
mrb_show_copyright(mrb_state *mrb)
{
}
#endif
+62 -8
View File
@@ -6,7 +6,6 @@
#include "mruby.h"
#include "mruby/proc.h"
#include "mruby/array.h"
#include "mruby/class.h"
#include "opcode.h"
@@ -16,8 +15,8 @@ mrb_proc_new(mrb_state *mrb, mrb_irep *irep)
struct RProc *p;
p = (struct RProc*)mrb_obj_alloc(mrb, MRB_TT_PROC, mrb->proc_class);
p->body.irep = irep;
p->target_class = (mrb->ci) ? mrb->ci->target_class : 0;
p->body.irep = irep;
p->env = 0;
return p;
@@ -56,20 +55,41 @@ mrb_proc_new_cfunc(mrb_state *mrb, mrb_func_t func)
return p;
}
void
mrb_proc_copy(struct RProc *a, struct RProc *b)
{
a->flags = b->flags;
a->body = b->body;
a->target_class = b->target_class;
a->env = b->env;
}
static mrb_value
mrb_proc_initialize(mrb_state *mrb, mrb_value self)
{
mrb_value blk;
mrb_get_args(mrb, "&", &blk);
if (!mrb_nil_p(blk)) {
*mrb_proc_ptr(self) = *mrb_proc_ptr(blk);
}
else {
if (mrb_nil_p(blk)) {
/* Calling Proc.new without a block is not implemented yet */
mrb_raise(mrb, E_ARGUMENT_ERROR, "tried to create Proc object without a block");
}
else {
mrb_proc_copy(mrb_proc_ptr(self), mrb_proc_ptr(blk));
}
return self;
}
static mrb_value
mrb_proc_init_copy(mrb_state *mrb, mrb_value self)
{
mrb_value proc;
mrb_get_args(mrb, "o", &proc);
if (mrb_type(proc) != MRB_TT_PROC) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "not a proc");
}
mrb_proc_copy(mrb_proc_ptr(self), mrb_proc_ptr(proc));
return self;
}
@@ -91,12 +111,41 @@ mrb_proc_iseq(mrb_state *mrb, struct RProc *p)
return p->body.irep->iseq;
}
/* 15.3.1.2.6 */
/* 15.3.1.3.27 */
/*
* call-seq:
* lambda { |...| block } -> a_proc
*
* Equivalent to <code>Proc.new</code>, except the resulting Proc objects
* check the number of parameters passed when called.
*/
static mrb_value
proc_lambda(mrb_state *mrb, mrb_value self)
{
mrb_value blk;
struct RProc *p;
mrb_get_args(mrb, "&", &blk);
if (mrb_nil_p(blk)) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "tried to create Proc object without a block");
}
p = mrb_proc_ptr(blk);
if (!MRB_PROC_STRICT_P(p)) {
struct RProc *p2 = (struct RProc*)mrb_obj_alloc(mrb, MRB_TT_PROC, p->c);
mrb_proc_copy(p2, p);
p2->flags |= MRB_PROC_STRICT;
return mrb_obj_value(p2);
}
return blk;
}
void
mrb_init_proc(mrb_state *mrb)
{
struct RProc *m;
mrb_code *call_iseq = mrb_malloc(mrb, sizeof(mrb_code));
mrb_irep *call_irep = mrb_calloc(mrb, sizeof(mrb_irep), 1);
mrb_code *call_iseq = (mrb_code *)mrb_malloc(mrb, sizeof(mrb_code));
mrb_irep *call_irep = (mrb_irep *)mrb_calloc(mrb, sizeof(mrb_irep), 1);
if ( call_iseq == NULL || call_irep == NULL )
return;
@@ -108,10 +157,15 @@ mrb_init_proc(mrb_state *mrb)
call_irep->ilen = 1;
mrb->proc_class = mrb_define_class(mrb, "Proc", mrb->object_class);
MRB_SET_INSTANCE_TT(mrb->proc_class, MRB_TT_PROC);
mrb_define_method(mrb, mrb->proc_class, "initialize", mrb_proc_initialize, ARGS_NONE());
mrb_define_method(mrb, mrb->proc_class, "initialize_copy", mrb_proc_init_copy, ARGS_REQ(1));
m = mrb_proc_new(mrb, call_irep);
mrb_define_method_raw(mrb, mrb->proc_class, mrb_intern(mrb, "call"), m);
mrb_define_method_raw(mrb, mrb->proc_class, mrb_intern(mrb, "[]"), m);
mrb_define_class_method(mrb, mrb->kernel_module, "lambda", proc_lambda, ARGS_NONE()); /* 15.3.1.2.6 */
mrb_define_method(mrb, mrb->kernel_module, "lambda", proc_lambda, ARGS_NONE()); /* 15.3.1.3.27 */
}
+52 -92
View File
@@ -7,30 +7,35 @@
#include "mruby.h"
#include "mruby/class.h"
#include "mruby/range.h"
#include "mruby/variable.h"
#include "error.h"
#include "mruby/numeric.h"
#include "mruby/string.h"
#include <stdio.h>
#include <string.h>
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
#ifndef OTHER
#define OTHER 2
#endif
#define RANGE_CLASS (mrb_class_obj_get(mrb, "Range"))
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);
static void
range_check(mrb_state *mrb, mrb_value a, mrb_value b)
{
mrb_value ans;
int ta;
int tb;
ta = mrb_type(a);
tb = mrb_type(b);
if ((ta == MRB_TT_FIXNUM || ta == MRB_TT_FLOAT) &&
(tb == MRB_TT_FIXNUM || tb == MRB_TT_FLOAT)) {
return;
}
ans = mrb_funcall(mrb, a, "<=>", 1, b);
if (mrb_nil_p(ans)) {
/* can not be compared */
mrb_raise(mrb, E_ARGUMENT_ERROR, "bad value for range");
}
}
mrb_value
mrb_range_new(mrb_state *mrb, mrb_value beg, mrb_value end, int excl)
@@ -38,7 +43,8 @@ mrb_range_new(mrb_state *mrb, mrb_value beg, mrb_value end, int excl)
struct RRange *r;
r = (struct RRange*)mrb_obj_alloc(mrb, MRB_TT_RANGE, RANGE_CLASS);
r->edges = mrb_malloc(mrb, sizeof(struct mrb_range_edges));
r->edges = (struct mrb_range_edges *)mrb_malloc(mrb, sizeof(struct mrb_range_edges));
range_check(mrb, beg, end);
r->edges->beg = beg;
r->edges->end = end;
r->excl = excl;
@@ -93,41 +99,12 @@ mrb_range_excl(mrb_state *mrb, mrb_value range)
return r->excl ? mrb_true_value() : mrb_false_value();
}
/*
* call-seq:
* beg end
* args[0] <= args[1] => true
* args[0] > args[1] => false
*/
static int
range_check(mrb_state *mrb, mrb_value *args)
{
mrb_value ans = mrb_funcall(mrb, args[0], "<=>", 1, args[1]);
/* beg end
ans :args[0] < args[1] => -1
args[0] = args[1] => 0
args[0] > args[1] => +1 */
if (mrb_nil_p(ans)) return FALSE;
//if (mrb_obj_equal(mrb, ans, mrb_fixnum_value(1))) return FALSE;
if (mrb_fixnum(ans) == 1) return FALSE;
return TRUE;
}
static void
range_init(mrb_state *mrb, mrb_value range, mrb_value beg, mrb_value end, mrb_int exclude_end)
{
mrb_value args[2];
struct RRange *r = mrb_range_ptr(range);
if ((mrb_type(beg) != MRB_TT_FIXNUM) || (mrb_type(end) != MRB_TT_FIXNUM)) {
args[0] = beg;
args[1] = end;
/* eroor.c v = mrb_rescue(range_check, (mrb_value)args, range_failed, 0);
if (mrb_nil_p(v)) range_failed(); */
if (!range_check(mrb, args)) {
printf("range_failed()\n");
}
}
range_check(mrb, beg, end);
r->excl = exclude_end;
r->edges->beg = beg;
r->edges->end = end;
@@ -179,7 +156,6 @@ mrb_range_eq(mrb_state *mrb, mrb_value range)
if (mrb_obj_equal(mrb, range, obj)) return mrb_true_value();
/* same class? */
// if (!rb_obj_is_instance_of(obj, rb_obj_class(range)))
if (!mrb_obj_is_instance_of(mrb, obj, mrb_obj_class(mrb, range)))
return mrb_false_value();
@@ -198,55 +174,41 @@ mrb_range_eq(mrb_state *mrb, mrb_value range)
static int
r_le(mrb_state *mrb, mrb_value a, mrb_value b)
{
//int c;
mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b); /* compare result */
/* output :a < b => -1, a = b => 0, a > b => +1 */
if (mrb_nil_p(r)) return FALSE;
if (mrb_type(r) == MRB_TT_FIXNUM) {
int c = mrb_fixnum(r);
if (c == 0 || c == -1) return TRUE;
}
/* mrb_value -> int */
//c = mrb_cmpint(mrb, r, a, b);
//if (c == 0) return TRUE;
//if (c < 0) return TRUE;
//return FALSE;
if (mrb_obj_equal(mrb, r, mrb_fixnum_value(0))) return TRUE;
if (mrb_obj_equal(mrb, r, mrb_fixnum_value(-1))) return TRUE;
return FALSE;
}
static int
r_gt(mrb_state *mrb, mrb_value a, mrb_value b)
{
//int c;
mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b);
/* output :a < b => -1, a = b => 0, a > b => +1 */
if (mrb_nil_p(r)) return FALSE;
if (mrb_type(r) == MRB_TT_FIXNUM) {
if (mrb_fixnum(r) == 1) return TRUE;
}
/* mrb_value -> int */
//c = mrb_cmpint(mrb, r);
//if (c > 0) return TRUE;
//return FALSE;
if (mrb_obj_equal(mrb, r, mrb_fixnum_value(1))) return TRUE;
return FALSE;
}
static int
r_ge(mrb_state *mrb, mrb_value a, mrb_value b)
{
//int c;
mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b); /* compare result */
/* output :a < b => -1, a = b => 0, a > b => +1 */
if (mrb_nil_p(r)) return FALSE;
if (mrb_type(r) == MRB_TT_FIXNUM) {
int c = mrb_fixnum(r);
if (c == 0 || c == 1) return TRUE;
}
/* mrb_value -> int */
//c = mrb_cmpint(mrb, r);
//if (c == 0) return TRUE;
//if (c > 0) return TRUE;
//return FALSE;
if (mrb_obj_equal(mrb, r, mrb_fixnum_value(0))) return TRUE;
if (mrb_obj_equal(mrb, r, mrb_fixnum_value(1))) return TRUE;
return FALSE;
}
@@ -370,7 +332,12 @@ inspect_range(mrb_state *mrb, mrb_value range, mrb_value dummy, int recur)
struct RRange *r = mrb_range_ptr(range);
if (recur) {
return mrb_str_new2(mrb, r->excl ? "(... ... ...)" : "(... .. ...)");
static const char s[2][14] = { "(... ... ...)", "(... .. ...)" };
static const int n[] = { 13, 12 };
int idx;
idx = (r->excl) ? 0 : 1;
return mrb_str_new(mrb, s[idx], n[idx]);
}
str = mrb_inspect(mrb, r->edges->beg);
str2 = mrb_inspect(mrb, r->edges->end);
@@ -397,23 +364,6 @@ range_inspect(mrb_state *mrb, mrb_value range)
return inspect_range(mrb, range, range, 0);
}
static mrb_value
recursive_eql(mrb_state *mrb, mrb_value range, mrb_value obj, int recur)
{
struct RRange *r = mrb_range_ptr(range);
struct RRange *o = mrb_range_ptr(obj);
if (recur) return mrb_true_value(); /* Subtle! */
if (!mrb_eql(mrb, r->edges->beg, o->edges->beg))
return mrb_false_value();
if (!mrb_eql(mrb, r->edges->end, o->edges->end))
return mrb_false_value();
if (r->excl != o->excl)
return mrb_false_value();
return mrb_true_value();
}
/* 15.2.14.4.14(x) */
/*
* call-seq:
@@ -433,13 +383,24 @@ static mrb_value
range_eql(mrb_state *mrb, mrb_value range)
{
mrb_value obj;
struct RRange *r, *o;
mrb_get_args(mrb, "o", &obj);
if (mrb_obj_equal(mrb, range, obj))
return mrb_true_value();
if (!mrb_obj_is_kind_of(mrb, obj, RANGE_CLASS))
return mrb_false_value();
return mrb_exec_recursive_paired(mrb, recursive_eql, range, obj, &obj);
r = mrb_range_ptr(range);
if (obj.tt != MRB_TT_RANGE) return mrb_false_value();
o = mrb_range_ptr(obj);
if (!mrb_eql(mrb, r->edges->beg, o->edges->beg))
return mrb_false_value();
if (!mrb_eql(mrb, r->edges->end, o->edges->end))
return mrb_false_value();
if (r->excl != o->excl)
return mrb_false_value();
return mrb_true_value();
}
/* 15.2.14.4.15(x) */
@@ -451,7 +412,6 @@ range_initialize_copy(mrb_state *mrb, mrb_value copy)
mrb_get_args(mrb, "o", &src);
if (mrb_obj_equal(mrb, copy, src)) return copy;
//mrb_check_frozen(copy);
if (!mrb_obj_is_instance_of(mrb, src, mrb_obj_class(mrb, copy))) {
mrb_raise(mrb, E_TYPE_ERROR, "wrong argument class");
}
+24 -32
View File
@@ -13,7 +13,7 @@
#include "regint.h"
#include "mruby/class.h"
#include "error.h"
#ifdef INCLUDE_REGEXP
#ifdef ENABLE_REGEXP
#define REGEX_CLASS (mrb_class_obj_get(mrb, "Regexp"))
#define MATCH_CLASS (mrb_class_obj_get(mrb, "MatchData"))
@@ -26,14 +26,6 @@
#define MKARG_B(c) (((c) & 0xff) << 16)
#define MKARG_C(c) (((c) & 0xff) << 8)
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
#define ARG_REG_OPTION_MASK \
(ONIG_OPTION_IGNORECASE|ONIG_OPTION_MULTILINE|ONIG_OPTION_EXTEND)
#define ARG_ENCODING_FIXED 16
@@ -84,7 +76,7 @@ mrb_reg_s_new_instance(mrb_state *mrb, /*int argc, mrb_value *argv, */mrb_value
re->ptr = 0;
re->src = 0;
re->usecnt = 0;
return mrb_funcall_argv(mrb, mrb_obj_value(re), "initialize", argc, argv);
return mrb_funcall_argv(mrb, mrb_obj_value(re), mrb_intern(mrb, "initialize"), argc, argv);
}
mrb_value
@@ -362,17 +354,17 @@ mrb_reg_options(mrb_state *mrb, mrb_value re)
static mrb_value
mrb_reg_desc(mrb_state *mrb, const char *s, long len, mrb_value re)
{
mrb_value str = mrb_str_new_cstr(mrb, "/");//mrb_str_buf_new2("/");
mrb_value str = mrb_str_new(mrb, "/", 1);
mrb_reg_expr_str(mrb, str, s, len);
mrb_str_buf_cat(mrb, str, "/", strlen("/"));
mrb_str_buf_cat(mrb, str, "/", 1);
if (re.tt) {
char opts[4];
mrb_reg_check(mrb, re);
if (*option_to_str(opts, RREGEXP(re)->ptr->options))
mrb_str_buf_cat(mrb, str, opts, strlen(opts));//mrb_str_buf_cat2(str, opts);
if (RBASIC(re)->flags & REG_ENCODING_NONE)
mrb_str_buf_cat(mrb, str, "n", strlen("n"));//mrb_str_buf_cat2(str, "n");
mrb_str_buf_cat(mrb, str, "n", 1);
}
return str;
@@ -1696,9 +1688,10 @@ mrb_reg_expr_str(mrb_state *mrb, mrb_value str, const char *s, long len)
}
else if (!ISSPACE(c)) {
char b[8];
int n;
snprintf(b, sizeof(b), "\\x%02X", c);
mrb_str_buf_cat(mrb, str, b, 4);
n = snprintf(b, sizeof(b), "\\x%02X", c);
mrb_str_buf_cat(mrb, str, b, n);
}
else {
mrb_str_buf_cat(mrb, str, p, 1);
@@ -1736,7 +1729,7 @@ mrb_reg_to_s(mrb_state *mrb, mrb_value re)
const int embeddable = ONIG_OPTION_MULTILINE|ONIG_OPTION_IGNORECASE|ONIG_OPTION_EXTEND;
long len;
const UChar* ptr;
mrb_value str = mrb_str_new_cstr(mrb, "(?");
mrb_value str = mrb_str_new(mrb, "(?", 2);
char optbuf[5];
mrb_encoding *enc = mrb_enc_get(mrb, re);
@@ -1804,9 +1797,9 @@ again:
mrb_str_buf_cat(mrb, str, optbuf, strlen(optbuf));
}
mrb_str_buf_cat(mrb, str, ":", strlen(":"));
mrb_str_buf_cat(mrb, str, ":", 1);
mrb_reg_expr_str(mrb, str, (char*)ptr, len);
mrb_str_buf_cat(mrb, str, ")", strlen(")"));
mrb_str_buf_cat(mrb, str, ")", 1);
return str;
}
@@ -1926,30 +1919,29 @@ mrb_match_inspect(mrb_state *mrb, mrb_value match)
onig_foreach_name(regexp->ptr,
match_inspect_name_iter, names);
str = mrb_str_new_cstr(mrb, "#<");//mrb_str_buf_new2("#<");
mrb_str_buf_cat(mrb, str, cname, strlen(cname));//mrb_str_buf_cat2(str, cname);
str = mrb_str_new(mrb, "#<", 2);
mrb_str_buf_cat(mrb, str, cname, strlen(cname));
for (i = 0; i < num_regs; i++) {
char buf[sizeof(num_regs)*3+1];
mrb_value v;
mrb_str_buf_cat(mrb, str, " ", strlen(" "));//mrb_str_buf_cat2(str, " ");
mrb_str_buf_cat(mrb, str, " ", 1);
if (0 < i) {
if (names[i].name)
mrb_str_buf_cat(mrb, str, (const char*)names[i].name, names[i].len);
else {
//mrb_str_catf(mrb, str, "%d", i);
sprintf(buf, "%d", i);
mrb_str_buf_cat(mrb, str, (const char*)buf, strlen(buf));
int n = sprintf(buf, "%d", i);
mrb_str_buf_cat(mrb, str, (const char*)buf, n);
}
mrb_str_buf_cat(mrb, str, ":", strlen(":"));//mrb_str_buf_cat2(str, ":");
mrb_str_buf_cat(mrb, str, ":", 1);
}
v = mrb_reg_nth_match(mrb, i, match);
if (mrb_nil_p(v))
mrb_str_buf_cat(mrb, str, "nil", strlen("nil"));//mrb_str_buf_cat2(str, "nil");
mrb_str_buf_cat(mrb, str, "nil", 3);
else
mrb_str_buf_append(mrb, str, mrb_str_inspect(mrb, v));
}
mrb_str_buf_cat(mrb, str, ">", strlen(">"));//mrb_str_buf_cat2(str, ">");
mrb_str_buf_cat(mrb, str, ">", 1);
return str;
}
@@ -2049,7 +2041,7 @@ mrb_init_regexp(mrb_state *mrb)
mrb_define_const(mrb, s, "FIXEDENCODING", mrb_fixnum_value(ARG_ENCODING_FIXED));
s = mrb_define_class(mrb, "MatchData", mrb->object_class);
//mrb_undef_method(CLASS_OF(rb_cMatch), "new");
//mrb_undef_class_method(CLASS_OF(rb_cMatch), "new");
mrb_define_method(mrb, s, "[]", mrb_match_aref, ARGS_ANY()); /* 15.2.16.3.1 */
mrb_define_method(mrb, s, "begin", mrb_match_begin, ARGS_REQ(1)); /* 15.2.16.3.2 */
@@ -2151,7 +2143,7 @@ mrb_reg_regsub(mrb_state *mrb, mrb_value str, mrb_value src, struct re_registers
break;
}
else {
mrb_raise(mrb, mrb->eRuntimeError_class, "invalid group name reference format");
mrb_raise(mrb, E_RUNTIME_ERROR, "invalid group name reference format");
}
}
@@ -2318,7 +2310,7 @@ mrb_backref_set(mrb_state *mrb, mrb_value val)
{
vm_svar_set(mrb, 1, val);
}
#endif //INCLUDE_REGEXP
#endif //ENABLE_REGEXP
#ifdef INCLUDE_ENCODING
static inline long
@@ -2421,7 +2413,7 @@ mrb_memsearch(mrb_state *mrb, const void *x0, int m, const void *y0, int n, mrb_
}
#endif //INCLUDE_ENCODING
#ifdef INCLUDE_REGEXP
#ifdef ENABLE_REGEXP
mrb_value
mrb_reg_init_str(mrb_state *mrb, mrb_value re, mrb_value s, int options)
{
@@ -2469,7 +2461,7 @@ re_adjust_startpos(struct re_pattern_buffer *bufp, const char *string, int size,
}*/
return startpos;
}
#endif //INCLUDE_REGEXP
#endif //ENABLE_REGEXP
#ifdef INCLUDE_ENCODING
static const unsigned char mbctab_ascii[] = {
+1
View File
@@ -13,6 +13,7 @@
#include "node.h"
#include "regex.h"
#include "encoding.h"
#include "st.h"
#define BEG(no) regs->beg[no]
#define END(no) regs->end[no]
+4 -4
View File
@@ -30,7 +30,7 @@
#include "mruby.h"
#include <string.h>
#include "regparse.h"
#ifdef INCLUDE_REGEXP
#ifdef ENABLE_REGEXP
OnigCaseFoldType OnigDefaultCaseFoldFlag = ONIGENC_CASE_FOLD_MIN;
@@ -5628,7 +5628,7 @@ onig_end(void)
THREAD_SYSTEM_END;
return 0;
}
#endif //INCLUDE_REGEXP
#endif //ENABLE_REGEXP
#ifdef INCLUDE_ENCODING
extern int
@@ -5653,7 +5653,7 @@ onig_is_in_code_range(const UChar* p, OnigCodePoint code)
}
#endif //INCLUDE_ENCODING
#ifdef INCLUDE_REGEXP
#ifdef ENABLE_REGEXP
extern int
onig_is_code_in_cc_len(int elen, OnigCodePoint code, CClassNode* cc)
{
@@ -6285,4 +6285,4 @@ print_tree(FILE* f, Node* node)
print_indent_tree(f, node, 0);
}
#endif
#endif //INCLUDE_REGEXP
#endif //ENABLE_REGEXP
-8
View File
@@ -32,14 +32,6 @@
#include <string.h>
#include "regint.h"
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
OnigEncoding OnigEncDefaultCharEncoding = ONIG_ENCODING_INIT_DEFAULT;
extern int
+2 -2
View File
@@ -28,7 +28,7 @@
*/
#include "mruby.h"
#ifdef INCLUDE_REGEXP
#ifdef ENABLE_REGEXP
#include <string.h>
#include "regint.h"
#include <stdio.h> /* for vsnprintf() */
@@ -372,4 +372,4 @@ onig_snprintf_with_pattern(UChar buf[], int bufsize, OnigEncoding enc,
pat, pat_end, fmt, args);
va_end(args);
}
#endif //INCLUDE_REGEXP
#endif //ENABLE_REGEXP
+2 -2
View File
@@ -28,7 +28,7 @@
*/
#include "mruby.h"
#ifdef INCLUDE_REGEXP
#ifdef ENABLE_REGEXP
#include <string.h>
#include "regint.h"
@@ -3754,4 +3754,4 @@ onig_copy_encoding(OnigEncoding to, OnigEncoding from)
{
*to = *from;
}
#endif //INCLUDE_REGEXP
#endif //ENABLE_REGEXP
+4 -4
View File
@@ -32,7 +32,7 @@
#include <string.h>
#include "regparse.h"
#include <stdarg.h>
#ifdef INCLUDE_REGEXP
#ifdef ENABLE_REGEXP
#define WARN_BUFSIZE 256
@@ -298,7 +298,7 @@ strcat_capa_from_static(UChar* dest, UChar* dest_end,
onig_strcpy(r + (dest_end - dest), src, src_end);
return r;
}
#endif //INCLUDE_REGEXP
#endif //ENABLE_REGEXP
#ifdef INCLUDE_ENCODING
#ifdef USE_ST_LIBRARY
@@ -393,7 +393,7 @@ onig_st_insert_strend(hash_table_type* table, const UChar* str_key,
#endif /* USE_ST_LIBRARY */
#endif //INCLUDE_ENCODING
#ifdef INCLUDE_REGEXP
#ifdef ENABLE_REGEXP
#ifdef USE_NAMED_GROUP
#define INIT_NAME_BACKREFS_ALLOC_NUM 8
@@ -5597,4 +5597,4 @@ onig_scan_env_set_error_string(ScanEnv* env, int ecode ARG_UNUSED,
env->error = arg;
env->error_end = arg_end;
}
#endif //INCLUDE_REGEXP
#endif //ENABLE_REGEXP
+28 -24
View File
@@ -5,6 +5,9 @@
*/
#include "mruby.h"
#ifdef ENABLE_SPRINTF
#include <stdio.h>
#include <string.h>
#include "encoding.h"
@@ -12,7 +15,6 @@
#include "mruby/hash.h"
#include "mruby/numeric.h"
#include <math.h>
#include <stdarg.h>
#include <ctype.h>
#ifdef HAVE_IEEEFP_H
@@ -86,7 +88,7 @@ mrb_fix2binstr(mrb_state *mrb, mrb_value x, int base)
val &= 0x3ff;
if (val == 0) {
return mrb_str_new2(mrb, "0");
return mrb_str_new(mrb, "0", 1);
}
*--b = '\0';
do {
@@ -142,7 +144,7 @@ mrb_fix2binstr(mrb_state *mrb, mrb_value x, int base)
blen += (l);\
} while (0)
#define GETARG() (!UNDEF_P(nextvalue) ? nextvalue : \
#define GETARG() (!mrb_undef_p(nextvalue) ? nextvalue : \
posarg == -1 ? \
(mrb_raise(mrb, E_ARGUMENT_ERROR, "unnumbered(%d) mixed with numbered", nextarg), mrb_undef_value()) : \
posarg == -2 ? \
@@ -165,7 +167,7 @@ mrb_fix2binstr(mrb_state *mrb, mrb_value x, int base)
(mrb_raise(mrb, E_ARGUMENT_ERROR, "named%.*s after unnumbered(%d)", (len), (name), posarg), mrb_undef_value()) : \
posarg == -1 ? \
(mrb_raise(mrb, E_ARGUMENT_ERROR, "named%.*s after numbered", (len), (name)), mrb_undef_value()) : \
(posarg = -2, mrb_hash_getWithDef(mrb, get_hash(mrb, &hash, argc, argv), id, mrb_undef_value())))
(posarg = -2, mrb_hash_fetch(mrb, get_hash(mrb, &hash, argc, argv), id, mrb_undef_value())))
#define GETNUM(n, val) \
for (; p < end && ISDIGIT(*p); p++) {\
@@ -198,7 +200,7 @@ get_hash(mrb_state *mrb, mrb_value *hash, int argc, const mrb_value *argv)
{
mrb_value tmp;
if (!UNDEF_P(*hash)) return *hash;
if (!mrb_undef_p(*hash)) return *hash;
if (argc != 2) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "one hash required");
}
@@ -493,7 +495,7 @@ mrb_str_format(mrb_state *mrb, int argc, const mrb_value *argv, mrb_value fmt)
char *buf;
long blen, bsiz;
mrb_value result;
int n;
int width, prec, flags = FNONE;
int nextarg = 1;
int posarg = 0;
@@ -530,7 +532,6 @@ mrb_str_format(mrb_state *mrb, int argc, const mrb_value *argv, mrb_value fmt)
for (; p < end; p++) {
const char *t;
int n;
mrb_sym id = 0;
for (t = p; t < end && *t != '%'; t++) ;
@@ -584,7 +585,7 @@ retry:
n = 0;
GETNUM(n, width);
if (*p == '$') {
if (!UNDEF_P(nextvalue)) {
if (!mrb_undef_p(nextvalue)) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "value given twice - %d$", n);
}
nextvalue = GETPOSARG(n);
@@ -610,9 +611,9 @@ retry:
(int)(p - start + 1), start, mrb_sym2name(mrb, id));
}
symname = mrb_str_new(mrb, start + 1, p - start - 1);
id = mrb_intern(mrb, RSTRING_PTR(symname));
id = mrb_intern_str(mrb, symname);
nextvalue = GETNAMEARG(mrb_symbol_value(id), start, (int)(p - start + 1));
if (UNDEF_P(nextvalue)) {
if (mrb_undef_p(nextvalue)) {
mrb_raise(mrb, E_KEY_ERROR, "key%.*s not found", (int)(p - start + 1), start);
}
if (term == '}') goto format_s;
@@ -666,7 +667,6 @@ retry:
mrb_value val = GETARG();
mrb_value tmp;
unsigned int c;
int n;
tmp = mrb_check_string_type(mrb, val);
if (!mrb_nil_p(tmp)) {
@@ -981,6 +981,7 @@ bin_retry:
fval = mrb_float(mrb_Float(mrb, val));
if (isnan(fval) || isinf(fval)) {
const char *expr;
const int elen = 3;
if (isnan(fval)) {
expr = "NaN";
@@ -988,14 +989,14 @@ bin_retry:
else {
expr = "Inf";
}
need = (int)strlen(expr);
need = elen;
if ((!isnan(fval) && fval < 0.0) || (flags & FPLUS))
need++;
if ((flags & FWIDTH) && need < width)
need = width;
CHECK(need + 1);
snprintf(&buf[blen], need + 1, "%*s", need, "");
n = snprintf(&buf[blen], need + 1, "%*s", need, "");
if (flags & FMINUS) {
if (!isnan(fval) && fval < 0.0)
buf[blen++] = '-';
@@ -1003,17 +1004,16 @@ bin_retry:
buf[blen++] = '+';
else if (flags & FSPACE)
blen++;
memcpy(&buf[blen], expr, strlen(expr));
memcpy(&buf[blen], expr, elen);
}
else {
if (!isnan(fval) && fval < 0.0)
buf[blen + need - strlen(expr) - 1] = '-';
buf[blen + need - elen - 1] = '-';
else if (flags & FPLUS)
buf[blen + need - strlen(expr) - 1] = '+';
buf[blen + need - elen - 1] = '+';
else if ((flags & FSPACE) && need > width)
blen++;
memcpy(&buf[blen + need - strlen(expr)], expr,
strlen(expr));
memcpy(&buf[blen + need - elen], expr, elen);
}
blen += strlen(&buf[blen]);
break;
@@ -1033,8 +1033,8 @@ bin_retry:
need += 20;
CHECK(need);
snprintf(&buf[blen], need, fbuf, fval);
blen += strlen(&buf[blen]);
n = snprintf(&buf[blen], need, fbuf, fval);
blen += n;
}
break;
}
@@ -1058,6 +1058,8 @@ static void
fmt_setup(char *buf, size_t size, int c, int flags, int width, int prec)
{
char *end = buf + size;
int n;
*buf++ = '%';
if (flags & FSHARP) *buf++ = '#';
if (flags & FPLUS) *buf++ = '+';
@@ -1066,15 +1068,17 @@ fmt_setup(char *buf, size_t size, int c, int flags, int width, int prec)
if (flags & FSPACE) *buf++ = ' ';
if (flags & FWIDTH) {
snprintf(buf, end - buf, "%d", width);
buf += strlen(buf);
n = snprintf(buf, end - buf, "%d", width);
buf += n;
}
if (flags & FPREC) {
snprintf(buf, end - buf, ".%d", prec);
buf += strlen(buf);
n = snprintf(buf, end - buf, ".%d", prec);
buf += n;
}
*buf++ = c;
*buf = '\0';
}
#endif /* ENABLE_SPRINTF */
+6 -6
View File
@@ -24,21 +24,21 @@
static int numcmp(long, long);
static st_index_t numhash(long);
static struct st_hash_type type_numhash = {
numcmp,
numhash,
(int (*)(ANYARGS))numcmp,
(st_index_t (*)(ANYARGS))numhash,
};
/* extern int strcmp(const char *, const char *); */
static st_index_t strhash(const char*);
static struct st_hash_type type_strhash = {
strcmp,
strhash,
(int (*)(ANYARGS))strcmp,
(st_index_t (*)(ANYARGS))strhash,
};
static st_index_t strcasehash(st_data_t);
static const struct st_hash_type type_strcasehash = {
st_strcasecmp,
strcasehash,
(int (*)(ANYARGS))st_strcasecmp,
(st_index_t (*)(ANYARGS))strcasehash,
};
static void rehash(st_table*);
+4 -3
View File
@@ -15,7 +15,8 @@ void mrb_init_ext(mrb_state*);
mrb_state*
mrb_open_allocf(mrb_allocf f)
{
mrb_state *mrb = (f)(NULL, NULL, sizeof(mrb_state));
mrb_state *mrb = (mrb_state *)(f)(NULL, NULL, sizeof(mrb_state));
if (mrb == NULL) return NULL;
memset(mrb, 0, sizeof(mrb_state));
mrb->allocf = f;
@@ -75,14 +76,14 @@ mrb_add_irep(mrb_state *mrb, int idx)
int max = 256;
if (idx > max) max = idx+1;
mrb->irep = mrb_malloc(mrb, sizeof(mrb_irep*)*max);
mrb->irep = (mrb_irep **)mrb_calloc(mrb, max, sizeof(mrb_irep*));
mrb->irep_capa = max;
}
else if (mrb->irep_capa <= idx) {
while (mrb->irep_capa <= idx) {
mrb->irep_capa *= 2;
}
mrb->irep = mrb_realloc(mrb, mrb->irep, sizeof(mrb_irep)*mrb->irep_capa);
mrb->irep = (mrb_irep **)mrb_realloc(mrb, mrb->irep, sizeof(mrb_irep*)*mrb->irep_capa);
}
}
+262 -250
View File
File diff suppressed because it is too large Load Diff
+92 -126
View File
@@ -5,6 +5,7 @@
*/
#include "mruby.h"
#ifdef ENABLE_STRUCT
#include <string.h>
#include "error.h"
#include "mruby/struct.h"
@@ -12,21 +13,13 @@
#include <stdarg.h>
//#include "defines.h"
#ifdef INCLUDE_REGEXP
#ifdef ENABLE_REGEXP
#include "encoding.h"
#endif
mrb_sym rb_frame_this_func(mrb_state *mrb);
mrb_sym mrb_frame_callee(mrb_state *mrb);
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);
#include "mruby/numeric.h"
#include "mruby/hash.h"
#include "mruby/string.h"
#include "mruby/class.h"
#include "mruby/variable.h"
#include "mruby/range.h"
#include "error.h"
//#include "defines.h"
#define mrb_long2int(n) ((int)(n))
@@ -45,8 +38,6 @@ struct_ivar_get(mrb_state *mrb, mrb_value c, mrb_sym id)
mrb_value ans;
for (;;) {
//if (mrb_ivar_defined(c, id))
// return mrb_iv_get(mrb, c, id);
ans = mrb_iv_get(mrb, c, id);
if (!mrb_nil_p(ans)) return ans;
kclass = RCLASS_SUPER(c);
@@ -96,7 +87,7 @@ mrb_struct_s_members_m(mrb_state *mrb, mrb_value klass)
mrb_value *p, *pend;
members = mrb_struct_s_members(mrb, klass);
ary = mrb_ary_new_capa(mrb, RARRAY_LEN(members));//mrb_ary_new2(RARRAY_LEN(members));
ary = mrb_ary_new_capa(mrb, RARRAY_LEN(members));
p = RARRAY_PTR(members); pend = p + RARRAY_LEN(members);
while (p < pend) {
mrb_ary_push(mrb, ary, *p);
@@ -134,7 +125,7 @@ mrb_struct_getmember(mrb_state *mrb, mrb_value obj, mrb_sym id)
ptr = RSTRUCT_PTR(obj);
members = mrb_struct_members(mrb, obj);
ptr_members = RARRAY_PTR(members);
slot = mrb_str_new_cstr(mrb, mrb_sym2name(mrb, id));
slot = mrb_symbol_value(id);
len = RARRAY_LEN(members);
for (i=0; i<len; i++) {
if (mrb_obj_equal(mrb, ptr_members[i], slot)) {
@@ -148,8 +139,7 @@ mrb_struct_getmember(mrb_state *mrb, mrb_value obj, mrb_sym id)
static mrb_value
mrb_struct_ref(mrb_state *mrb, mrb_value obj)
{
//return mrb_struct_getmember(mrb, obj, rb_frame_this_func(mrb));
return mrb_nil_value();
return mrb_struct_getmember(mrb, obj, mrb->ci->mid);
}
static mrb_value mrb_struct_ref0(mrb_state* mrb, mrb_value obj) {return RSTRUCT_PTR(obj)[0];}
@@ -186,33 +176,60 @@ mrb_struct_modify(mrb_value s)
}
mrb_sym
mrb_id_attrset(mrb_sym id)
mrb_id_attrset(mrb_state *mrb, mrb_sym id)
{
//id &= ~ID_SCOPE_MASK;
//id |= ID_ATTRSET;
return id;
const char *name;
char *buf;
int len;
mrb_sym mid;
name = mrb_sym2name_len(mrb, id, &len);
buf = (char *)mrb_malloc(mrb, len+2);
memcpy(buf, name, len);
buf[len] = '=';
buf[len+1] = '\0';
mid = mrb_intern2(mrb, buf, len+1);
mrb_free(mrb, buf);
return mid;
}
static mrb_value
mrb_struct_set(mrb_state *mrb, mrb_value obj, mrb_value val)
{
mrb_value members, slot, *ptr, *ptr_members;
long i, len;
const char *name;
int i, len;
mrb_sym mid;
mrb_value members, slot, *ptr, *ptr_members;
members = mrb_struct_members(mrb, obj);
ptr_members = RARRAY_PTR(members);
len = RARRAY_LEN(members);
mrb_struct_modify(obj);
ptr = RSTRUCT_PTR(obj);
for (i=0; i<len; i++) {
slot = ptr_members[i];
if (mrb_id_attrset(SYM2ID(slot)) == 0/*rb_frame_this_func(mrb)*/) {
return ptr[i] = val;
}
/* get base id */
name = mrb_sym2name_len(mrb, mrb->ci->mid, &len);
mid = mrb_intern2(mrb, name, len-1); /* omit last "=" */
members = mrb_struct_members(mrb, obj);
ptr_members = RARRAY_PTR(members);
len = RARRAY_LEN(members);
mrb_struct_modify(obj);
ptr = RSTRUCT_PTR(obj);
for (i=0; i<len; i++) {
slot = ptr_members[i];
if (SYM2ID(slot) == mid) {
return ptr[i] = val;
}
mrb_name_error(mrb, 0/*rb_frame_this_func(mrb)*/, "`%s' is not a struct member",
mrb_sym2name(mrb, 0/*rb_frame_this_func(mrb)*/));
return mrb_nil_value(); /* not reached */
}
mrb_name_error(mrb, mid, "`%s' is not a struct member",
mrb_sym2name(mrb, mid));
return mrb_nil_value(); /* not reached */
}
static mrb_value
mrb_struct_set_m(mrb_state *mrb, mrb_value obj)
{
mrb_value val;
mrb_get_args(mrb, "o", &val);
return mrb_struct_set(mrb, obj, val);
}
#define is_notop_id(id) (id)//((id)>tLAST_TOKEN)
@@ -241,19 +258,15 @@ make_struct(mrb_state *mrb, mrb_value name, mrb_value members, struct RClass * k
//OBJ_FREEZE(members);
if (mrb_nil_p(name)) {
c = mrb_class_new(mrb, klass);
//mrb_make_metaclass(nstr, RBASIC(klass)->c);
//mrb_class_inherited(klass, nstr);
}
else {
/* old style: should we warn? */
name = mrb_str_to_str(mrb, name);
id = mrb_to_id(mrb, name);
if (!mrb_is_const_id(id)) {
//mrb_name_error(id, "identifier %s needs to be constant", StringValuePtr(name));
mrb_name_error(mrb, id, "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", StringValuePtr(name));
mrb_warn("redefining constant Struct::%s", mrb_string_value_ptr(mrb, name));
//?rb_mod_remove_const(klass, mrb_sym2name(mrb, id));
}
@@ -263,8 +276,8 @@ make_struct(mrb_state *mrb, mrb_value name, mrb_value members, struct RClass * k
nstr = mrb_obj_value(c);
mrb_iv_set(mrb, nstr, mrb_intern(mrb, "__members__"), members);
mrb_define_class_method(mrb, c, "new", mrb_class_new_instance_m, ARGS_ANY());
mrb_define_class_method(mrb, c, "[]", mrb_class_new_instance_m, ARGS_ANY());
mrb_define_class_method(mrb, c, "new", mrb_instance_new, ARGS_ANY());
mrb_define_class_method(mrb, c, "[]", mrb_instance_new, ARGS_ANY());
mrb_define_class_method(mrb, c, "members", mrb_struct_s_members_m, ARGS_NONE());
//RSTRUCT(nstr)->basic.c->super = c->c;
ptr_members = RARRAY_PTR(members);
@@ -273,12 +286,12 @@ make_struct(mrb_state *mrb, mrb_value name, mrb_value members, struct RClass * k
mrb_sym id = SYM2ID(ptr_members[i]);
if (mrb_is_local_id(id) || mrb_is_const_id(id)) {
if (i < N_REF_FUNC) {
mrb_define_method_id(mrb, c, id, (mrb_func_t)ref_func[i], 0);
mrb_define_method_id(mrb, c, id, ref_func[i], ARGS_NONE());
}
else {
mrb_define_method_id(mrb, c, id, mrb_struct_ref, 0);
mrb_define_method_id(mrb, c, id, mrb_struct_ref, ARGS_NONE());
}
mrb_define_method_id(mrb, c, mrb_id_attrset(id), (mrb_func_t)mrb_struct_set, 1);
mrb_define_method_id(mrb, c, mrb_id_attrset(mrb, id), mrb_struct_set_m, ARGS_REQ(1));
}
}
@@ -299,7 +312,7 @@ mrb_struct_define(mrb_state *mrb, const char *name, ...)
va_start(ar, name);
while ((mem = va_arg(ar, char*)) != 0) {
mrb_sym slot = mrb_intern(mrb, mem);
mrb_ary_push(mrb, ary, mrb_str_new_cstr(mrb, mrb_sym2name(mrb, slot)));
mrb_ary_push(mrb, ary, mrb_symbol_value(slot));
}
va_end(ar);
@@ -354,33 +367,31 @@ mrb_struct_s_def(mrb_state *mrb, mrb_value klass)
name = mrb_nil_value();
rest = mrb_nil_value();
mrb_get_args(mrb, "&*", &b, &argv, &argc);
mrb_get_args(mrb, "*&", &argv, &argc, &b);
if (argc > 0) name = argv[0];
if (argc > 1) rest = argv[1];
//mrb_scan_args(argc, argv, "1*", &name, &rest);
if (mrb_type(rest) == MRB_TT_ARRAY) {
if (!mrb_nil_p(name) && SYMBOL_P(name)) {
/* 1stArgument:symbol -> name=nil rest=argv[0]-[n] */
mrb_ary_unshift(mrb, rest, name);
name = mrb_nil_value();
}
for (i=0; i<RARRAY_LEN(rest); i++) {
id = mrb_to_id(mrb, RARRAY_PTR(rest)[i]);
RARRAY_PTR(rest)[i] = mrb_str_new_cstr(mrb, mrb_sym2name(mrb, id));
}
}
else {
pargv = &argv[1];
argcnt = argc-1;
if (!mrb_nil_p(name) && SYMBOL_P(name)) {
/* 1stArgument:symbol -> name=nil rest=argv[0]-[n] */
//mrb_ary_unshift(mrb, rest, name);
name = mrb_nil_value();
pargv = &argv[0];
argcnt++;
}
rest = mrb_ary_new_from_values(mrb, argcnt, pargv);
}
for (i=0; i<RARRAY_LEN(rest); i++) {
id = mrb_to_id(mrb, RARRAY_PTR(rest)[i]);
RARRAY_PTR(rest)[i] = mrb_symbol_value(id);
}
st = make_struct(mrb, name, rest, struct_class(mrb));
if (!mrb_nil_p(b)) {
mrb_funcall(mrb, b, "call", 1, &st);
@@ -389,7 +400,7 @@ mrb_struct_s_def(mrb_state *mrb, mrb_value klass)
return st;
}
static long
static int
num_members(mrb_state *mrb, struct RClass *klass)
{
mrb_value members;
@@ -407,7 +418,7 @@ 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);
long n;
int n;
struct RStruct *st;
mrb_struct_modify(self);
@@ -416,12 +427,10 @@ mrb_struct_initialize_withArg(mrb_state *mrb, int argc, mrb_value *argv, mrb_val
mrb_raise(mrb, E_ARGUMENT_ERROR, "struct size differs");
}
st = RSTRUCT(self);
st->ptr = malloc(sizeof(mrb_value)*argc);
st->ptr = (mrb_value *)mrb_calloc(mrb, sizeof(mrb_value), n);
st->len = n;
memcpy(st->ptr, argv, sizeof(mrb_value)*argc);
//if (n > argc) {
// mrb_mem_clear(RSTRUCT_PTR(self)+argc, n-argc);
//}
return self;
}
@@ -438,41 +447,14 @@ mrb_struct_initialize_m(mrb_state *mrb, /*int argc, mrb_value *argv,*/ mrb_value
mrb_value
mrb_struct_initialize(mrb_state *mrb, mrb_value self, mrb_value values)
{
return mrb_struct_initialize_withArg(mrb, RARRAY_LEN/*INT*/(values), RARRAY_PTR(values), self);
}
mrb_value
mrb_struct_alloc(mrb_state *mrb, mrb_value klass, mrb_value values)
{
return mrb_class_new_instance(mrb, RARRAY_LEN(values), RARRAY_PTR(values), mrb_class(mrb, klass));
}
mrb_value
mrb_struct_new(mrb_state *mrb, struct RClass *klass, ...)
{
mrb_value tmpargs[N_REF_FUNC], *mem = tmpargs;
int size, i;
va_list args;
size = mrb_long2int(num_members(mrb, klass));
if (size > numberof(tmpargs)) {
tmpargs[0] = mrb_ary_tmp_new(mrb, size);
mem = RARRAY_PTR(tmpargs[0]);
}
va_start(args, klass);
for (i=0; i<size; i++) {
mem[i] = va_arg(args, mrb_value);
}
va_end(args);
return mrb_class_new_instance(mrb, size, mem, klass);
return mrb_struct_initialize_withArg(mrb, RARRAY_LEN(values), RARRAY_PTR(values), self);
}
static mrb_value
inspect_struct(mrb_state *mrb, mrb_value s, mrb_value dummy, int recur)
{
const char *cn = mrb_class_name(mrb, mrb_obj_class(mrb, s));
mrb_value members, str = mrb_str_new2(mrb, "#<struct ");
mrb_value members, str = mrb_str_new(mrb, "#<struct ", 9);
mrb_value *ptr, *ptr_members;
long i, len;
@@ -500,8 +482,11 @@ inspect_struct(mrb_state *mrb, mrb_value s, mrb_value dummy, int recur)
slot = ptr_members[i];
id = SYM2ID(slot);
if (mrb_is_local_id(id) || mrb_is_const_id(id)) {
//mrb_str_append(str, mrb_id2str(id));
mrb_str_append(mrb, str, mrb_str_new_cstr(mrb, mrb_sym2name(mrb, id)));
const char *name;
int len;
name = mrb_sym2name_len(mrb, id, &len);
mrb_str_append(mrb, str, mrb_str_new(mrb, name, len));
}
else {
mrb_str_append(mrb, str, mrb_inspect(mrb, slot));
@@ -537,7 +522,6 @@ mrb_struct_init_copy(mrb_state *mrb, mrb_value copy)
mrb_get_args(mrb, "o", &s);
if (mrb_obj_equal(mrb, copy, s)) return copy;
//mrb_check_frozen(copy);
if (!mrb_obj_is_instance_of(mrb, s, mrb_obj_class(mrb, copy))) {
mrb_raise(mrb, E_TYPE_ERROR, "wrong argument class");
}
@@ -690,22 +674,6 @@ mrb_struct_aset(mrb_state *mrb, mrb_value s)
return RSTRUCT_PTR(s)[i] = val;
}
static mrb_value
recursive_equal(mrb_state *mrb, mrb_value s, mrb_value s2, int recur)
{
mrb_value *ptr, *ptr2;
long i, len;
if (recur) return mrb_true_value(); /* Subtle! */
ptr = RSTRUCT_PTR(s);
ptr2 = RSTRUCT_PTR(s2);
len = RSTRUCT_LEN(s);
for (i=0; i<len; i++) {
if (!mrb_equal(mrb, ptr[i], ptr2[i])) return mrb_false_value();
}
return mrb_true_value();
}
/* 15.2.18.4.1 */
/*
* call-seq:
@@ -728,6 +696,8 @@ static mrb_value
mrb_struct_equal(mrb_state *mrb, mrb_value s)
{
mrb_value s2;
mrb_value *ptr, *ptr2;
long i, len;
mrb_get_args(mrb, "o", &s2);
if (mrb_obj_equal(mrb, s, s2)) return mrb_true_value();
@@ -736,24 +706,13 @@ mrb_struct_equal(mrb_state *mrb, mrb_value s)
if (RSTRUCT_LEN(s) != RSTRUCT_LEN(s2)) {
mrb_bug("inconsistent struct"); /* should never happen */
}
return mrb_exec_recursive_paired(mrb, recursive_equal, s, s2, (void*)0);
}
static mrb_value
recursive_eql(mrb_state *mrb, mrb_value s, mrb_value s2, int recur)
{
mrb_value *ptr, *ptr2;
long i, len;
if (recur) return mrb_true_value(); /* Subtle! */
ptr = RSTRUCT_PTR(s);
ptr2 = RSTRUCT_PTR(s2);
len = RSTRUCT_LEN(s);
for (i=0; i<len; i++) {
if (!mrb_eql(mrb, ptr[i], ptr2[i])) return mrb_false_value();
}
return mrb_true_value();
ptr = RSTRUCT_PTR(s);
ptr2 = RSTRUCT_PTR(s2);
len = RSTRUCT_LEN(s);
for (i=0; i<len; i++) {
if (!mrb_equal(mrb, ptr[i], ptr2[i])) return mrb_false_value();
}
return mrb_true_value();
}
/* 15.2.18.4.12(x) */
@@ -768,6 +727,8 @@ static mrb_value
mrb_struct_eql(mrb_state *mrb, mrb_value s)
{
mrb_value s2;
mrb_value *ptr, *ptr2;
long i, len;
mrb_get_args(mrb, "o", &s2);
if (mrb_obj_equal(mrb, s, s2)) return mrb_true_value();
@@ -777,7 +738,13 @@ mrb_struct_eql(mrb_state *mrb, mrb_value s)
mrb_bug("inconsistent struct"); /* should never happen */
}
return mrb_exec_recursive_paired(mrb, recursive_eql, s, s2, (void*)0);
ptr = RSTRUCT_PTR(s);
ptr2 = RSTRUCT_PTR(s2);
len = RSTRUCT_LEN(s);
for (i=0; i<len; i++) {
if (!mrb_eql(mrb, ptr[i], ptr2[i])) return mrb_false_value();
}
return mrb_true_value();
}
/*
@@ -800,9 +767,7 @@ mrb_init_struct(mrb_state *mrb)
{
struct RClass *st;
st = mrb_define_class(mrb, "Struct", mrb->object_class);
//mrb_include_module(mrb_cStruct, rb_mEnumerable);
//mrb_undef_alloc_func(mrb_cStruct);
mrb_define_class_method(mrb, st, "new", mrb_struct_s_def, ARGS_ANY()); /* 15.2.18.3.1 */
mrb_define_method(mrb, st, "==", mrb_struct_equal, ARGS_REQ(1)); /* 15.2.18.4.1 */
@@ -816,3 +781,4 @@ 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 */
+134 -45
View File
@@ -8,68 +8,99 @@
#include "mruby/khash.h"
#include <string.h>
#include <stdarg.h>
#include <string.h>
#include "mruby/string.h"
#include <ctype.h>
#include "mruby/class.h"
#include "mruby/variable.h"
#include <stdio.h>
/* ------------------------------------------------------ */
KHASH_INIT(s2n, mrb_sym, const char*, 1, kh_int_hash_func, kh_int_hash_equal)
KHASH_MAP_INIT_STR(n2s, mrb_sym);
typedef struct symbol_name {
int len;
const char *name;
} symbol_name;
static inline khint_t
sym_hash_func(mrb_state *mrb, const symbol_name s)
{
khint_t h = 0;
size_t i;
const char *p = s.name;
for (i=0; i<s.len; i++) {
h = (h << 5) - h + *p++;
}
return h;
}
#define sym_hash_equal(mrb,a, b) (a.len == b.len && memcmp(a.name, b.name, a.len) == 0)
KHASH_DECLARE(n2s, symbol_name, mrb_sym, 1)
KHASH_DEFINE (n2s, symbol_name, mrb_sym, 1, sym_hash_func, sym_hash_equal)
/* ------------------------------------------------------ */
mrb_sym
mrb_intern(mrb_state *mrb, const char *name)
mrb_intern2(mrb_state *mrb, const char *name, int len)
{
khash_t(n2s) *h = mrb->name2sym;
khash_t(s2n) *rh = mrb->sym2name;
symbol_name sname;
khiter_t k;
size_t len;
char *p;
mrb_sym sym;
char *p;
k = kh_get(n2s, h, name);
sname.len = len;
sname.name = name;
k = kh_get(n2s, h, sname);
if (k != kh_end(h))
return kh_value(h, k);
sym = ++mrb->symidx;
len = strlen(name);
p = mrb_malloc(mrb, len+1);
p = (char *)mrb_malloc(mrb, len+1);
memcpy(p, name, len);
p[len] = 0;
k = kh_put(n2s, h, p);
sname.name = (const char*)p;
k = kh_put(n2s, h, sname);
kh_value(h, k) = sym;
k = kh_put(s2n, rh, sym);
kh_value(rh, k) = p;
return sym;
}
const char*
mrb_sym2name(mrb_state *mrb, mrb_sym sym)
mrb_sym
mrb_intern(mrb_state *mrb, const char *name)
{
khash_t(s2n) *h = mrb->sym2name;
khiter_t k;
return mrb_intern2(mrb, name, strlen(name));
}
k = kh_get(s2n, h, sym);
if (k == kh_end(h)) {
return NULL; /* missing */
mrb_sym
mrb_intern_str(mrb_state *mrb, mrb_value str)
{
return mrb_intern2(mrb, RSTRING_PTR(str), RSTRING_LEN(str));
}
const char*
mrb_sym2name_len(mrb_state *mrb, mrb_sym sym, int *lenp)
{
khash_t(n2s) *h = mrb->name2sym;
khiter_t k;
symbol_name sname;
for (k = kh_begin(h); k != kh_end(h); k++) {
if (kh_exist(h, k)) {
if (kh_value(h, k) == sym) break;
}
}
return kh_value(h, k);
if (k == kh_end(h)) {
*lenp = 0;
return NULL; /* missing */
}
sname = kh_key(h, k);
*lenp = sname.len;
return sname.name;
}
void
mrb_free_symtbls(mrb_state *mrb)
{
khash_t(s2n) *h = mrb->sym2name;
khash_t(n2s) *h = mrb->name2sym;
khiter_t k;
for (k = kh_begin(h); k != kh_end(h); ++k)
if (kh_exist(h, k)) mrb_free(mrb, (char*)kh_value(h, k));
kh_destroy(s2n,mrb->sym2name);
for (k = kh_begin(h); k != kh_end(h); k++)
if (kh_exist(h, k)) mrb_free(mrb, (char*)kh_key(h, k).name);
kh_destroy(n2s,mrb->name2sym);
}
@@ -77,7 +108,6 @@ void
mrb_init_symtbl(mrb_state *mrb)
{
mrb->name2sym = kh_init(n2s, mrb);
mrb->sym2name = kh_init(s2n, mrb);
}
/**********************************************************************
@@ -148,8 +178,11 @@ mrb_value
mrb_sym_to_s(mrb_state *mrb, mrb_value sym)
{
mrb_sym id = SYM2ID(sym);
const char *p;
int len;
return mrb_str_new_cstr(mrb, mrb_sym2name(mrb, id));
p = mrb_sym2name_len(mrb, id, &len);
return mrb_str_new(mrb, p, len);
}
/* 15.2.11.3.4 */
@@ -188,8 +221,7 @@ sym_to_sym(mrb_state *mrb, mrb_value sym)
#define is_identchar(c) (SIGN_EXTEND_CHAR(c)!=-1&&(ISALNUM(c) || (c) == '_'))
static int
is_special_global_name(m)
const char *m;
is_special_global_name(const char* m)
{
switch (*m) {
case '~': case '*': case '$': case '?': case '!': case '@':
@@ -240,6 +272,7 @@ symname_p(const char *name)
case '>':
switch (*++m) {
case '>': case '=': ++m; break;
default: break;
}
break;
@@ -254,12 +287,20 @@ symname_p(const char *name)
case '*':
if (*++m == '*') ++m;
break;
case '!':
if (*++m == '=') ++m;
break;
case '+': case '-':
if (*++m == '@') ++m;
break;
case '|':
if (*++m == '|') ++m;
break;
case '&':
if (*++m == '&') ++m;
break;
case '|': case '^': case '&': case '/': case '%': case '~': case '`':
case '^': case '/': case '%': case '~': case '`':
++m;
break;
@@ -275,7 +316,8 @@ id:
while (is_identchar(*m)) m += 1;
if (localid) {
switch (*m) {
case '!': case '?': case '=': ++m;
case '!': case '?': case '=': ++m;
default: break;
}
}
break;
@@ -288,22 +330,69 @@ sym_inspect(mrb_state *mrb, mrb_value sym)
{
mrb_value str;
const char *name;
int len;
mrb_sym id = SYM2ID(sym);
name = mrb_sym2name(mrb, id); //mrb_id2name(id);
str = mrb_str_new(mrb, 0, strlen(name)+1);
RSTRING(str)->buf[0] = ':';
strcpy(RSTRING(str)->buf+1, name);
if (!symname_p(name)) {
name = mrb_sym2name_len(mrb, id, &len);
str = mrb_str_new(mrb, 0, len+1);
RSTRING(str)->ptr[0] = ':';
memcpy(RSTRING(str)->ptr+1, name, len);
if (!symname_p(name) || strlen(name) != len) {
str = mrb_str_dump(mrb, str);
strncpy(RSTRING(str)->buf, ":\"", 2);
memcpy(RSTRING(str)->ptr, ":\"", 2);
}
return str;
}
const char*
mrb_sym2name(mrb_state *mrb, mrb_sym sym)
{
int len;
const char *name = mrb_sym2name_len(mrb, sym, &len);
if (!name) return NULL;
if (symname_p(name) && strlen(name) == len) {
return name;
}
else {
mrb_value str = mrb_str_dump(mrb, mrb_str_new(mrb, name, len));
return RSTRING(str)->ptr;
}
}
#define lesser(a,b) (((a)>(b))?(b):(a))
static mrb_value
sym_cmp(mrb_state *mrb, mrb_value s1)
{
mrb_value s2;
mrb_sym sym1, sym2;
mrb_get_args(mrb, "o", &s2);
if (mrb_type(s2) != MRB_TT_SYMBOL) return mrb_nil_value();
sym1 = mrb_symbol(s1);
sym2 = mrb_symbol(s2);
if (sym1 == sym2) return mrb_fixnum_value(0);
else {
const char *p1, *p2;
int len, len1, len2, retval;
p1 = mrb_sym2name_len(mrb, sym1, &len1);
p2 = mrb_sym2name_len(mrb, sym2, &len2);
len = lesser(len1, len2);
retval = memcmp(p1, p2, len);
if (retval == 0) {
if (len1 == len2) return mrb_fixnum_value(0);
if (len1 > len2) return mrb_fixnum_value(1);
return mrb_fixnum_value(-1);
}
if (retval > 0) return mrb_fixnum_value(1);
return mrb_fixnum_value(-1);
}
}
void
mrb_init_symbols(mrb_state *mrb)
mrb_init_symbol(mrb_state *mrb)
{
struct RClass *sym;
@@ -313,6 +402,6 @@ mrb_init_symbols(mrb_state *mrb)
mrb_define_method(mrb, sym, "id2name", mrb_sym_to_s, ARGS_NONE()); /* 15.2.11.3.2 */
mrb_define_method(mrb, sym, "to_s", mrb_sym_to_s, ARGS_NONE()); /* 15.2.11.3.3 */
mrb_define_method(mrb, sym, "to_sym", sym_to_sym, ARGS_NONE()); /* 15.2.11.3.4 */
mrb_define_method(mrb, sym, "inspect", sym_inspect, ARGS_NONE()); /* 15.2.11.3.5(x) */
mrb_define_method(mrb, sym, "<=>", sym_cmp, ARGS_REQ(1));
}
+173 -109
View File
@@ -6,6 +6,7 @@
#include "mruby.h"
#ifdef ENABLE_TIME
#include <string.h>
#include <stdio.h>
#include <time.h>
@@ -136,13 +137,13 @@ mrb_time_update_datetime(struct mrb_time *self)
{
struct tm *aid;
if(self->timezone == MRB_TIMEZONE_UTC) {
if (self->timezone == MRB_TIMEZONE_UTC) {
aid = gmtime_r(&self->sec, &self->datetime);
}
else {
aid = localtime_r(&self->sec, &self->datetime);
}
if(!aid) return NULL;
if (!aid) return NULL;
#ifdef NO_GMTIME_R
self->datetime = *aid; // copy data
#endif
@@ -159,13 +160,21 @@ mrb_time_wrap(mrb_state *mrb, struct RClass *tc, struct mrb_time *tm)
/* Allocates a mrb_time object and initializes it. */
static struct mrb_time*
mrb_time_alloc(mrb_state *mrb, mrb_float seconds, enum mrb_timezone timezone)
mrb_time_alloc(mrb_state *mrb, double sec, double usec, enum mrb_timezone timezone)
{
struct mrb_time *tm;
tm = mrb_malloc(mrb, sizeof(struct mrb_time));
tm->sec = (time_t)seconds;
tm->usec = (seconds - tm->sec) * 1.0e6;
tm = (struct mrb_time *)mrb_malloc(mrb, sizeof(struct mrb_time));
tm->sec = (time_t)sec;
tm->usec = (sec - tm->sec) * 1.0e6 + usec;
while (tm->usec < 0) {
tm->sec--;
tm->usec += 1.0e6;
}
while (tm->usec > 1.0e6) {
tm->sec++;
tm->usec -= 1.0e6;
}
tm->timezone = timezone;
mrb_time_update_datetime(tm);
@@ -173,9 +182,9 @@ mrb_time_alloc(mrb_state *mrb, mrb_float seconds, enum mrb_timezone timezone)
}
static mrb_value
mrb_time_make(mrb_state *mrb, struct RClass *c, mrb_float seconds, enum mrb_timezone timezone)
mrb_time_make(mrb_state *mrb, struct RClass *c, double sec, double usec, enum mrb_timezone timezone)
{
return mrb_time_wrap(mrb, c, mrb_time_alloc(mrb, seconds, timezone));
return mrb_time_wrap(mrb, c, mrb_time_alloc(mrb, sec, usec, timezone));
}
static struct mrb_time*
@@ -183,7 +192,7 @@ current_mrb_time(mrb_state *mrb)
{
struct mrb_time *tm;
tm = mrb_malloc(mrb, sizeof(*tm));
tm = (struct mrb_time *)mrb_malloc(mrb, sizeof(*tm));
#ifdef NO_GETTIMEOFDAY
{
static time_t last_sec = 0, last_usec = 0;
@@ -226,10 +235,10 @@ mrb_time_now(mrb_state *mrb, mrb_value self)
static mrb_value
mrb_time_at(mrb_state *mrb, mrb_value self)
{
mrb_float f;
mrb_float f, f2 = 0;
mrb_get_args(mrb, "f", &f);
return mrb_time_make(mrb, mrb_class_ptr(self), f, MRB_TIMEZONE_LOCAL);
mrb_get_args(mrb, "f|f", &f, &f2);
return mrb_time_make(mrb, mrb_class_ptr(self), f, f2, MRB_TIMEZONE_LOCAL);
}
static struct mrb_time*
@@ -238,9 +247,8 @@ time_mktime(mrb_state *mrb, mrb_int ayear, mrb_int amonth, mrb_int aday,
enum mrb_timezone timezone)
{
time_t nowsecs;
struct tm nowtime;
struct tm nowtime = { 0 };
memset(&nowtime, 0, sizeof(struct tm));
nowtime.tm_year = (int)ayear - 1900;
nowtime.tm_mon = (int)amonth - 1;
nowtime.tm_mday = (int)aday;
@@ -258,7 +266,7 @@ time_mktime(mrb_state *mrb, mrb_int ayear, mrb_int amonth, mrb_int aday,
mrb_raise(mrb, E_ARGUMENT_ERROR, "Not a valid time.");
}
return mrb_time_alloc(mrb, nowsecs+ausec/10e6, timezone);
return mrb_time_alloc(mrb, nowsecs, ausec, timezone);
}
/* 15.2.19.6.2 */
@@ -296,8 +304,8 @@ mrb_time_eq(mrb_state *mrb, mrb_value self)
struct mrb_time *tm1, *tm2;
mrb_get_args(mrb, "o", &other);
tm1 = mrb_get_datatype(mrb, self, &mrb_time_type);
tm2 = mrb_get_datatype(mrb, other, &mrb_time_type);
tm1 = (struct mrb_time *)mrb_get_datatype(mrb, self, &mrb_time_type);
tm2 = (struct mrb_time *)mrb_get_datatype(mrb, other, &mrb_time_type);
if (!tm1 || !tm2) return mrb_false_value();
if (tm1->sec == tm2->sec && tm1->usec == tm2->usec) {
return mrb_true_value();
@@ -312,8 +320,8 @@ mrb_time_cmp(mrb_state *mrb, mrb_value self)
struct mrb_time *tm1, *tm2;
mrb_get_args(mrb, "o", &other);
tm1 = mrb_get_datatype(mrb, self, &mrb_time_type);
tm2 = mrb_get_datatype(mrb, other, &mrb_time_type);
tm1 = (struct mrb_time *)mrb_get_datatype(mrb, self, &mrb_time_type);
tm2 = (struct mrb_time *)mrb_get_datatype(mrb, other, &mrb_time_type);
if (!tm1 || !tm2) return mrb_nil_value();
if (tm1->sec > tm2->sec) {
return mrb_fixnum_value(1);
@@ -338,25 +346,32 @@ mrb_time_plus(mrb_state *mrb, mrb_value self)
struct mrb_time *tm;
mrb_get_args(mrb, "f", &f);
tm = mrb_get_datatype(mrb, self, &mrb_time_type);
if(!tm) return mrb_nil_value();
f += tm->sec;
f += (mrb_float)tm->usec / 1.0e6;
return mrb_time_make(mrb, mrb_obj_class(mrb, self), f, tm->timezone);
tm = (struct mrb_time *)mrb_get_datatype(mrb, self, &mrb_time_type);
if (!tm) return mrb_nil_value();
return mrb_time_make(mrb, mrb_obj_class(mrb, self), (double)tm->sec+f, tm->usec, tm->timezone);
}
static mrb_value
mrb_time_minus(mrb_state *mrb, mrb_value self)
{
mrb_float f;
struct mrb_time *tm;
mrb_value other;
struct mrb_time *tm, *tm2;
mrb_get_args(mrb, "f", &f);
tm = mrb_get_datatype(mrb, self, &mrb_time_type);
if(!tm) return mrb_nil_value();
f -= tm->sec;
f -= (mrb_float)tm->usec / 1.0e6;
return mrb_time_make(mrb, mrb_obj_class(mrb, self), f, tm->timezone);
mrb_get_args(mrb, "o", &other);
tm = (struct mrb_time *)mrb_get_datatype(mrb, self, &mrb_time_type);
if (!tm) return mrb_nil_value();
tm2 = (struct mrb_time *)mrb_get_datatype(mrb, other, &mrb_time_type);
if (tm2) {
f = (mrb_float)(tm->sec - tm2->sec)
+ (mrb_float)(tm->usec - tm2->usec) / 1.0e6;
return mrb_float_value(f);
}
else {
mrb_get_args(mrb, "f", &f);
return mrb_time_make(mrb, mrb_obj_class(mrb, self), (double)tm->sec-f, tm->usec, tm->timezone);
}
}
/* 15.2.19.7.30 */
@@ -366,8 +381,8 @@ mrb_time_wday(mrb_state *mrb, mrb_value self)
{
struct mrb_time *tm;
tm = mrb_get_datatype(mrb, self, &mrb_time_type);
if(!tm) return mrb_nil_value();
tm = (struct mrb_time *)mrb_get_datatype(mrb, self, &mrb_time_type);
if (!tm) return mrb_nil_value();
return mrb_fixnum_value(tm->datetime.tm_wday);
}
@@ -378,8 +393,8 @@ mrb_time_yday(mrb_state *mrb, mrb_value self)
{
struct mrb_time *tm;
tm = mrb_check_datatype(mrb, self, &mrb_time_type);
if(!tm) return mrb_nil_value();
tm = (struct mrb_time *)mrb_check_datatype(mrb, self, &mrb_time_type);
if (!tm) return mrb_nil_value();
return mrb_fixnum_value(tm->datetime.tm_yday);
}
@@ -390,8 +405,8 @@ mrb_time_year(mrb_state *mrb, mrb_value self)
{
struct mrb_time *tm;
tm = mrb_get_datatype(mrb, self, &mrb_time_type);
if(!tm) return mrb_nil_value();
tm = (struct mrb_time *)mrb_get_datatype(mrb, self, &mrb_time_type);
if (!tm) return mrb_nil_value();
return mrb_fixnum_value(tm->datetime.tm_year + 1900);
}
@@ -402,10 +417,10 @@ mrb_time_zone(mrb_state *mrb, mrb_value self)
{
struct mrb_time *tm;
tm = mrb_get_datatype(mrb, self, &mrb_time_type);
if(!tm) return mrb_nil_value();
if(tm->timezone <= MRB_TIMEZONE_NONE) return mrb_nil_value();
if(tm->timezone >= MRB_TIMEZONE_LAST) return mrb_nil_value();
tm = (struct mrb_time *)mrb_get_datatype(mrb, self, &mrb_time_type);
if (!tm) return mrb_nil_value();
if (tm->timezone <= MRB_TIMEZONE_NONE) return mrb_nil_value();
if (tm->timezone >= MRB_TIMEZONE_LAST) return mrb_nil_value();
return mrb_str_new_cstr(mrb, timezone_names[tm->timezone]);
}
@@ -417,16 +432,17 @@ mrb_time_asctime(mrb_state *mrb, mrb_value self)
struct mrb_time *tm;
struct tm *d;
char buf[256];
int len;
tm = mrb_get_datatype(mrb, self, &mrb_time_type);
if(!tm) return mrb_nil_value();
tm = (struct mrb_time *)mrb_get_datatype(mrb, self, &mrb_time_type);
if (!tm) return mrb_nil_value();
d = &tm->datetime;
snprintf(buf, 256, "%s %s %02d %02d:%02d:%02d %s%d",
wday_names[d->tm_wday], mon_names[d->tm_mon], d->tm_mday,
d->tm_hour, d->tm_min, d->tm_sec,
tm->timezone == MRB_TIMEZONE_UTC ? "UTC " : "",
d->tm_year + 1900);
return mrb_str_new_cstr(mrb, buf);
len = snprintf(buf, sizeof(buf), "%s %s %02d %02d:%02d:%02d %s%d",
wday_names[d->tm_wday], mon_names[d->tm_mon], d->tm_mday,
d->tm_hour, d->tm_min, d->tm_sec,
tm->timezone == MRB_TIMEZONE_UTC ? "UTC " : "",
d->tm_year + 1900);
return mrb_str_new(mrb, buf, len);
}
/* 15.2.19.7.6 */
@@ -436,8 +452,8 @@ mrb_time_day(mrb_state *mrb, mrb_value self)
{
struct mrb_time *tm;
tm = mrb_get_datatype(mrb, self, &mrb_time_type);
if(!tm) return mrb_nil_value();
tm = (struct mrb_time *)mrb_get_datatype(mrb, self, &mrb_time_type);
if (!tm) return mrb_nil_value();
return mrb_fixnum_value(tm->datetime.tm_mday);
}
@@ -449,11 +465,44 @@ mrb_time_dstp(mrb_state *mrb, mrb_value self)
{
struct mrb_time *tm;
tm = mrb_get_datatype(mrb, self, &mrb_time_type);
if(!tm) return mrb_nil_value();
tm = (struct mrb_time *)mrb_get_datatype(mrb, self, &mrb_time_type);
if (!tm) return mrb_nil_value();
return mrb_bool_value(tm->datetime.tm_isdst);
}
/* 15.2.19.7.8 */
/* 15.2.19.7.10 */
/* Returns the Time object of the UTC(GMT) timezone. */
static mrb_value
mrb_time_getutc(mrb_state *mrb, mrb_value self)
{
struct mrb_time *tm, *tm2;
tm = (struct mrb_time *)mrb_get_datatype(mrb, self, &mrb_time_type);
if (!tm) return self;
tm2 = (struct mrb_time *)mrb_malloc(mrb, sizeof(*tm));
*tm2 = *tm;
tm2->timezone = MRB_TIMEZONE_UTC;
mrb_time_update_datetime(tm2);
return mrb_time_wrap(mrb, mrb_obj_class(mrb, self), tm2);
}
/* 15.2.19.7.9 */
/* Returns the Time object of the LOCAL timezone. */
static mrb_value
mrb_time_getlocal(mrb_state *mrb, mrb_value self)
{
struct mrb_time *tm, *tm2;
tm = (struct mrb_time *)mrb_get_datatype(mrb, self, &mrb_time_type);
if (!tm) return self;
tm2 = (struct mrb_time *)mrb_malloc(mrb, sizeof(*tm));
*tm2 = *tm;
tm2->timezone = MRB_TIMEZONE_LOCAL;
mrb_time_update_datetime(tm2);
return mrb_time_wrap(mrb, mrb_obj_class(mrb, self), tm2);
}
/* 15.2.19.7.15 */
/* Returns hour of time. */
static mrb_value
@@ -461,8 +510,8 @@ mrb_time_hour(mrb_state *mrb, mrb_value self)
{
struct mrb_time *tm;
tm = mrb_get_datatype(mrb, self, &mrb_time_type);
if(!tm) return mrb_nil_value();
tm = (struct mrb_time *)mrb_get_datatype(mrb, self, &mrb_time_type);
if (!tm) return mrb_nil_value();
return mrb_fixnum_value(tm->datetime.tm_hour);
}
@@ -473,18 +522,20 @@ mrb_time_initialize(mrb_state *mrb, mrb_value self)
{
mrb_int ayear = 0, amonth = 1, aday = 1, ahour = 0,
amin = 0, asec = 0, ausec = 0;
int n;
struct mrb_time *tm;
tm = mrb_get_datatype(mrb, self, &mrb_time_type);
tm = (struct mrb_time *)mrb_get_datatype(mrb, self, &mrb_time_type);
if (tm) {
mrb_time_free(mrb, tm);
}
if (mrb->ci->argc == 0) {
n = mrb_get_args(mrb, "|iiiiiii",
&ayear, &amonth, &aday, &ahour, &amin, &asec, &ausec);
if (n == 0) {
tm = current_mrb_time(mrb);
}
else {
mrb_get_args(mrb, "iiiiiii",
&ayear, &amonth, &aday, &ahour, &amin, &asec, &ausec);
tm = time_mktime(mrb, ayear, amonth, aday, ahour, amin, asec, ausec, MRB_TIMEZONE_LOCAL);
}
DATA_PTR(self) = tm;
@@ -519,8 +570,8 @@ mrb_time_localtime(mrb_state *mrb, mrb_value self)
{
struct mrb_time *tm;
tm = mrb_get_datatype(mrb, self, &mrb_time_type);
if(!tm) return self;
tm = (struct mrb_time *)mrb_get_datatype(mrb, self, &mrb_time_type);
if (!tm) return self;
tm->timezone = MRB_TIMEZONE_LOCAL;
mrb_time_update_datetime(tm);
return self;
@@ -533,8 +584,8 @@ mrb_time_mday(mrb_state *mrb, mrb_value self)
{
struct mrb_time *tm;
tm = mrb_get_datatype(mrb, self, &mrb_time_type);
if(!tm) return mrb_nil_value();
tm = (struct mrb_time *)mrb_get_datatype(mrb, self, &mrb_time_type);
if (!tm) return mrb_nil_value();
return mrb_fixnum_value(tm->datetime.tm_mday);
}
@@ -545,8 +596,8 @@ mrb_time_min(mrb_state *mrb, mrb_value self)
{
struct mrb_time *tm;
tm = mrb_get_datatype(mrb, self, &mrb_time_type);
if(!tm) return mrb_nil_value();
tm = (struct mrb_time *)mrb_get_datatype(mrb, self, &mrb_time_type);
if (!tm) return mrb_nil_value();
return mrb_fixnum_value(tm->datetime.tm_min);
}
@@ -557,8 +608,8 @@ mrb_time_mon(mrb_state *mrb, mrb_value self)
{
struct mrb_time *tm;
tm = mrb_get_datatype(mrb, self, &mrb_time_type);
if(!tm) return mrb_nil_value();
tm = (struct mrb_time *)mrb_get_datatype(mrb, self, &mrb_time_type);
if (!tm) return mrb_nil_value();
return mrb_fixnum_value(tm->datetime.tm_mon + 1);
}
@@ -569,8 +620,8 @@ mrb_time_sec(mrb_state *mrb, mrb_value self)
{
struct mrb_time *tm;
tm = mrb_get_datatype(mrb, self, &mrb_time_type);
if(!tm) return mrb_nil_value();
tm = (struct mrb_time *)mrb_get_datatype(mrb, self, &mrb_time_type);
if (!tm) return mrb_nil_value();
return mrb_fixnum_value(tm->datetime.tm_sec);
}
@@ -582,8 +633,8 @@ mrb_time_to_f(mrb_state *mrb, mrb_value self)
{
struct mrb_time *tm;
tm = mrb_get_datatype(mrb, self, &mrb_time_type);
if(!tm) return mrb_nil_value();
tm = (struct mrb_time *)mrb_get_datatype(mrb, self, &mrb_time_type);
if (!tm) return mrb_nil_value();
return mrb_float_value((mrb_float)tm->sec + (mrb_float)tm->usec/1.0e6);
}
@@ -594,8 +645,8 @@ mrb_time_to_i(mrb_state *mrb, mrb_value self)
{
struct mrb_time *tm;
tm = mrb_get_datatype(mrb, self, &mrb_time_type);
if(!tm) return mrb_nil_value();
tm = (struct mrb_time *)mrb_get_datatype(mrb, self, &mrb_time_type);
if (!tm) return mrb_nil_value();
return mrb_fixnum_value(tm->sec);
}
@@ -606,8 +657,8 @@ mrb_time_usec(mrb_state *mrb, mrb_value self)
{
struct mrb_time *tm;
tm = mrb_get_datatype(mrb, self, &mrb_time_type);
if(!tm) return mrb_nil_value();
tm = (struct mrb_time *)mrb_get_datatype(mrb, self, &mrb_time_type);
if (!tm) return mrb_nil_value();
return mrb_fixnum_value(tm->usec);
}
@@ -618,7 +669,7 @@ mrb_time_utc(mrb_state *mrb, mrb_value self)
{
struct mrb_time *tm;
tm = mrb_get_datatype(mrb, self, &mrb_time_type);
tm = (struct mrb_time *)mrb_get_datatype(mrb, self, &mrb_time_type);
if (tm) {
tm->timezone = MRB_TIMEZONE_UTC;
mrb_time_update_datetime(tm);
@@ -632,8 +683,8 @@ static mrb_value
mrb_time_utcp(mrb_state *mrb, mrb_value self)
{
struct mrb_time *tm;
tm = mrb_get_datatype(mrb, self, &mrb_time_type);
if(!tm) return mrb_nil_value();
tm = (struct mrb_time *)mrb_get_datatype(mrb, self, &mrb_time_type);
if (!tm) return mrb_nil_value();
return mrb_bool_value(tm->timezone == MRB_TIMEZONE_UTC);
}
@@ -647,41 +698,54 @@ mrb_init_time(mrb_state *mrb)
tc = mrb_define_class(mrb, "Time", mrb->object_class);
MRB_SET_INSTANCE_TT(tc, MRB_TT_DATA);
mrb_include_module(mrb, tc, mrb_class_get(mrb, "Comparable"));
mrb_define_class_method(mrb, tc, "now", mrb_time_now, ARGS_NONE());
mrb_define_class_method(mrb, tc, "at", mrb_time_at, ARGS_ANY());
mrb_define_class_method(mrb, tc, "gm", mrb_time_gm, ARGS_REQ(1)|ARGS_OPT(6));
mrb_define_class_method(mrb, tc, "local", mrb_time_local, ARGS_REQ(1)|ARGS_OPT(6));
mrb_define_class_method(mrb, tc, "at", mrb_time_at, ARGS_ANY()); /* 15.2.19.6.1 */
mrb_define_class_method(mrb, tc, "gm", mrb_time_gm, ARGS_REQ(1)|ARGS_OPT(6)); /* 15.2.19.6.2 */
mrb_define_class_method(mrb, tc, "local", mrb_time_local, ARGS_REQ(1)|ARGS_OPT(6)); /* 15.2.19.6.3 */
mrb_define_class_method(mrb, tc, "mktime", mrb_time_local, ARGS_REQ(1)|ARGS_OPT(6));/* 15.2.19.6.4 */
mrb_define_class_method(mrb, tc, "now", mrb_time_now, ARGS_NONE()); /* 15.2.19.6.5 */
mrb_define_class_method(mrb, tc, "utc", mrb_time_gm, ARGS_REQ(1)|ARGS_OPT(6)); /* 15.2.19.6.6 */
mrb_define_method(mrb, tc, "==" , mrb_time_eq , ARGS_REQ(1));
mrb_define_method(mrb, tc, "<=>" , mrb_time_cmp , ARGS_REQ(1));
mrb_define_method(mrb, tc, "+" , mrb_time_plus , ARGS_REQ(1));
mrb_define_method(mrb, tc, "-" , mrb_time_minus , ARGS_REQ(1));
mrb_define_method(mrb, tc, "<=>" , mrb_time_cmp , ARGS_REQ(1)); /* 15.2.19.7.1 */
mrb_define_method(mrb, tc, "+" , mrb_time_plus , ARGS_REQ(1)); /* 15.2.19.7.2 */
mrb_define_method(mrb, tc, "-" , mrb_time_minus , ARGS_REQ(1)); /* 15.2.19.7.3 */
mrb_define_method(mrb, tc, "to_s" , mrb_time_asctime, ARGS_NONE());
mrb_define_method(mrb, tc, "asctime", mrb_time_asctime, ARGS_NONE());
mrb_define_method(mrb, tc, "ctime" , mrb_time_asctime, ARGS_NONE());
mrb_define_method(mrb, tc, "day" , mrb_time_day , ARGS_NONE());
mrb_define_method(mrb, tc, "dst?" , mrb_time_dstp , ARGS_NONE());
mrb_define_method(mrb, tc, "gmt?" , mrb_time_utcp , ARGS_NONE());
mrb_define_method(mrb, tc, "gmtime" , mrb_time_utc , ARGS_NONE());
mrb_define_method(mrb, tc, "hour" , mrb_time_hour, ARGS_NONE());
mrb_define_method(mrb, tc, "localtime", mrb_time_localtime, ARGS_NONE());
mrb_define_method(mrb, tc, "mday" , mrb_time_mday, ARGS_NONE());
mrb_define_method(mrb, tc, "min" , mrb_time_min, ARGS_NONE());
mrb_define_method(mrb, tc, "asctime", mrb_time_asctime, ARGS_NONE()); /* 15.2.19.7.4 */
mrb_define_method(mrb, tc, "ctime" , mrb_time_asctime, ARGS_NONE()); /* 15.2.19.7.5 */
mrb_define_method(mrb, tc, "day" , mrb_time_day , ARGS_NONE()); /* 15.2.19.7.6 */
mrb_define_method(mrb, tc, "dst?" , mrb_time_dstp , ARGS_NONE()); /* 15.2.19.7.7 */
mrb_define_method(mrb, tc, "getgm" , mrb_time_getutc , ARGS_NONE()); /* 15.2.19.7.8 */
mrb_define_method(mrb, tc, "getlocal",mrb_time_getlocal,ARGS_NONE()); /* 15.2.19.7.9 */
mrb_define_method(mrb, tc, "getutc" , mrb_time_getutc , ARGS_NONE()); /* 15.2.19.7.10 */
mrb_define_method(mrb, tc, "gmt?" , mrb_time_utcp , ARGS_NONE()); /* 15.2.19.7.11 */
mrb_define_method(mrb, tc, "gmtime" , mrb_time_utc , ARGS_NONE()); /* 15.2.19.7.13 */
mrb_define_method(mrb, tc, "hour" , mrb_time_hour, ARGS_NONE()); /* 15.2.19.7.15 */
mrb_define_method(mrb, tc, "localtime", mrb_time_localtime, ARGS_NONE()); /* 15.2.19.7.18 */
mrb_define_method(mrb, tc, "mday" , mrb_time_mday, ARGS_NONE()); /* 15.2.19.7.19 */
mrb_define_method(mrb, tc, "min" , mrb_time_min, ARGS_NONE()); /* 15.2.19.7.20 */
mrb_define_method(mrb, tc, "mon" , mrb_time_mon, ARGS_NONE());
mrb_define_method(mrb, tc, "month", mrb_time_mon, ARGS_NONE());
mrb_define_method(mrb, tc, "mon" , mrb_time_mon, ARGS_NONE()); /* 15.2.19.7.21 */
mrb_define_method(mrb, tc, "month", mrb_time_mon, ARGS_NONE()); /* 15.2.19.7.22 */
mrb_define_method(mrb, tc, "sec" , mrb_time_sec, ARGS_NONE());
mrb_define_method(mrb, tc, "to_i", mrb_time_to_i, ARGS_NONE());
mrb_define_method(mrb, tc, "to_f", mrb_time_to_f, ARGS_NONE());
mrb_define_method(mrb, tc, "usec", mrb_time_usec, ARGS_NONE());
mrb_define_method(mrb, tc, "utc" , mrb_time_utc, ARGS_NONE());
mrb_define_method(mrb, tc, "utc?", mrb_time_utcp, ARGS_NONE());
mrb_define_method(mrb, tc, "wday", mrb_time_wday, ARGS_NONE());
mrb_define_method(mrb, tc, "yday", mrb_time_yday, ARGS_NONE());
mrb_define_method(mrb, tc, "year", mrb_time_year, ARGS_NONE());
mrb_define_method(mrb, tc, "zone", mrb_time_zone, ARGS_NONE());
mrb_define_method(mrb, tc, "sec" , mrb_time_sec, ARGS_NONE()); /* 15.2.19.7.23 */
mrb_define_method(mrb, tc, "to_i", mrb_time_to_i, ARGS_NONE()); /* 15.2.19.7.25 */
mrb_define_method(mrb, tc, "to_f", mrb_time_to_f, ARGS_NONE()); /* 15.2.19.7.24 */
mrb_define_method(mrb, tc, "usec", mrb_time_usec, ARGS_NONE()); /* 15.2.19.7.26 */
mrb_define_method(mrb, tc, "utc" , mrb_time_utc, ARGS_NONE()); /* 15.2.19.7.27 */
mrb_define_method(mrb, tc, "utc?", mrb_time_utcp, ARGS_NONE()); /* 15.2.19.7.28 */
mrb_define_method(mrb, tc, "wday", mrb_time_wday, ARGS_NONE()); /* 15.2.19.7.30 */
mrb_define_method(mrb, tc, "yday", mrb_time_yday, ARGS_NONE()); /* 15.2.19.7.31 */
mrb_define_method(mrb, tc, "year", mrb_time_year, ARGS_NONE()); /* 15.2.19.7.32 */
mrb_define_method(mrb, tc, "zone", mrb_time_zone, ARGS_NONE()); /* 15.2.19.7.33 */
mrb_define_method(mrb, tc, "initialize", mrb_time_initialize, ARGS_REQ(1));
mrb_define_method(mrb, tc, "initialize_copy", mrb_time_initialize_copy, ARGS_REQ(1));
mrb_define_method(mrb, tc, "initialize", mrb_time_initialize, ARGS_REQ(1)); /* 15.2.19.7.16 */
mrb_define_method(mrb, tc, "initialize_copy", mrb_time_initialize_copy, ARGS_REQ(1)); /* 15.2.19.7.17 */
/*
methods not available:
gmt_offset(15.2.19.7.12)
gmtoff(15.2.19.7.14)
utc_offset(15.2.19.7.29)
*/
}
#endif
+121 -67
View File
@@ -4,29 +4,20 @@
** See Copyright Notice in mruby.h
*/
#include <stdio.h>
#include "mruby.h"
#include "mruby/class.h"
#include "mruby/khash.h"
#include "mruby/variable.h"
#include "mruby/string.h"
#include "mruby/range.h"
#include "error.h"
#include "mruby/array.h"
#include "mruby/proc.h"
#ifdef INCLUDE_REGEXP
#ifdef ENABLE_REGEXP
#include "re.h"
#include "st.h"
#endif
KHASH_MAP_INIT_INT(iv, mrb_value);
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#ifndef MRB_IV_INITIAL_SIZE
#define MRB_IV_INITIAL_SIZE 8
#endif
static void
@@ -104,10 +95,28 @@ mrb_obj_iv_get(mrb_state *mrb, struct RObject *obj, mrb_sym sym)
return ivget(mrb, obj->iv, sym);
}
static int
obj_iv_p(mrb_value obj)
{
switch (mrb_type(obj)) {
case MRB_TT_OBJECT:
case MRB_TT_CLASS:
case MRB_TT_MODULE:
case MRB_TT_HASH:
case MRB_TT_DATA:
return TRUE;
default:
return FALSE;
}
}
mrb_value
mrb_iv_get(mrb_state *mrb, mrb_value obj, mrb_sym sym)
{
return mrb_obj_iv_get(mrb, mrb_obj_ptr(obj), sym);
if (obj_iv_p(obj)) {
return mrb_obj_iv_get(mrb, mrb_obj_ptr(obj), sym);
}
return mrb_nil_value();
}
static void
@@ -125,7 +134,7 @@ mrb_obj_iv_set(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v)
khash_t(iv) *h;
if (!obj->iv) {
h = obj->iv = kh_init(iv, mrb);
h = obj->iv = kh_init_size(iv, mrb, MRB_IV_INITIAL_SIZE);
}
else {
h = obj->iv;
@@ -137,7 +146,30 @@ mrb_obj_iv_set(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v)
void
mrb_iv_set(mrb_state *mrb, mrb_value obj, mrb_sym sym, mrb_value v) /* mrb_ivar_set */
{
mrb_obj_iv_set(mrb, mrb_obj_ptr(obj), sym, v);
if (obj_iv_p(obj)) {
mrb_obj_iv_set(mrb, mrb_obj_ptr(obj), sym, v);
}
}
mrb_value
mrb_iv_remove(mrb_state *mrb, mrb_value obj, mrb_sym sym)
{
mrb_value val;
if (obj_iv_p(obj)) {
khash_t(iv) *h = mrb_obj_ptr(obj)->iv;
khiter_t k;
if (h) {
k = kh_get(iv, h, sym);
if (k != kh_end(h)) {
val = kh_value(h, k);
kh_del(iv, h, k);
return val;
}
}
}
return mrb_undef_value();
}
mrb_value
@@ -154,11 +186,56 @@ mrb_vm_iv_set(mrb_state *mrb, mrb_sym sym, mrb_value v)
mrb_iv_set(mrb, mrb->stack[0], sym, v);
}
/* 15.3.1.3.23 */
/*
* call-seq:
* obj.instance_variables -> array
*
* Returns an array of instance variable names for the receiver. Note
* that simply defining an accessor does not create the corresponding
* instance variable.
*
* class Fred
* attr_accessor :a1
* def initialize
* @iv = 3
* end
* end
* Fred.new.instance_variables #=> [:@iv]
*/
mrb_value
mrb_obj_instance_variables(mrb_state *mrb, mrb_value self)
{
mrb_value ary;
kh_iv_t *h;
khint_t i;
int len;
const char* p;
ary = mrb_ary_new(mrb);
if (obj_iv_p(self)) {
h = ROBJECT_IVPTR(self);
if (h) {
for (i=0;i<kh_end(h);i++) {
if (kh_exist(h, i)) {
p = mrb_sym2name_len(mrb, kh_key(h,i), &len);
if (len > 1 && *p == '@') {
if (mrb_type(kh_value(h, i)) != MRB_TT_UNDEF)
mrb_ary_push(mrb, ary, mrb_str_new(mrb, p, len));
}
}
}
}
}
return ary;
}
mrb_value
mrb_vm_cv_get(mrb_state *mrb, mrb_sym sym)
{
struct RClass *c = mrb->ci->target_class;
struct RClass *c = mrb->ci->proc->target_class;
if (!c) c = mrb->ci->target_class;
while (c) {
if (c->iv) {
khash_t(iv) *h = c->iv;
@@ -175,10 +252,11 @@ mrb_vm_cv_get(mrb_state *mrb, mrb_sym sym)
void
mrb_vm_cv_set(mrb_state *mrb, mrb_sym sym, mrb_value v)
{
struct RClass *c = mrb->ci->target_class;
struct RClass *c = mrb->ci->proc->target_class;
khash_t(iv) *h;
khiter_t k;
if (!c) c = mrb->ci->target_class;
while (c) {
if (c->iv) {
h = c->iv;
@@ -186,7 +264,7 @@ mrb_vm_cv_set(mrb_state *mrb, mrb_sym sym, mrb_value v)
if (k != kh_end(h)) {
k = kh_put(iv, h, sym);
kh_value(h, k) = v;
return;
return;
}
}
c = c->super;
@@ -194,7 +272,7 @@ mrb_vm_cv_set(mrb_state *mrb, mrb_sym sym, mrb_value v)
c = mrb->ci->target_class;
h = c->iv;
if (!h) {
c->iv = h = kh_init(iv, mrb);
c->iv = h = kh_init_size(iv, mrb, MRB_IV_INITIAL_SIZE);
}
k = kh_put(iv, h, sym);
kh_value(h, k) = v;
@@ -233,26 +311,10 @@ const_get(mrb_state *mrb, struct RClass *base, mrb_sym sym)
struct RClass *c = base;
khash_t(iv) *h;
khiter_t k;
int retry = 0;
mrb_sym cm;
if (c->iv) {
h = c->iv;
k = kh_get(iv, h, sym);
if (k != kh_end(h)) {
return kh_value(h, k);
}
}
for (;;) {
c = mrb_class_outer_module(mrb, c);
if (!c) break;
if (c->iv) {
h = c->iv;
k = kh_get(iv, h, sym);
if (k != kh_end(h)) {
return kh_value(h, k);
}
}
}
c = base->super;
L_RETRY:
while (c) {
if (c->iv) {
h = c->iv;
@@ -263,16 +325,20 @@ const_get(mrb_state *mrb, struct RClass *base, mrb_sym sym)
}
c = c->super;
}
if (!c) {
if (!retry && base->tt == MRB_TT_MODULE) {
c = mrb->object_class;
retry = 1;
goto L_RETRY;
}
if (mrb_respond_to(mrb, mrb_obj_value(c), mrb_intern(mrb, "const_missing"))) {
mrb_value argv = mrb_symbol_value(sym);
return mrb_funcall_argv(mrb, mrb_obj_value(c), "const_missing", 1, &argv);
c = base;
cm = mrb_intern(mrb, "const_missing");
while (c) {
if (mrb_respond_to(mrb, mrb_obj_value(c), cm)) {
mrb_value name = mrb_symbol_value(sym);
return mrb_funcall(mrb, mrb_obj_value(c), "const_missing", 1, name);
}
c = c->super;
}
mrb_raise(mrb, E_NAME_ERROR, "uninitialized constant %s",
mrb_sym2name(mrb, sym));
/* not reached */
@@ -289,7 +355,10 @@ mrb_const_get(mrb_state *mrb, mrb_value mod, mrb_sym sym)
mrb_value
mrb_vm_const_get(mrb_state *mrb, mrb_sym sym)
{
return const_get(mrb, mrb->ci->target_class, sym);
struct RClass *c = mrb->ci->proc->target_class;
if (!c) c = mrb->ci->target_class;
return const_get(mrb, c, sym);
}
void
@@ -302,7 +371,10 @@ mrb_const_set(mrb_state *mrb, mrb_value mod, mrb_sym sym, mrb_value v)
void
mrb_vm_const_set(mrb_state *mrb, mrb_sym sym, mrb_value v)
{
mrb_obj_iv_set(mrb, (struct RObject*)mrb->ci->target_class, sym, v);
struct RClass *c = mrb->ci->proc->target_class;
if (!c) c = mrb->ci->target_class;
mrb_obj_iv_set(mrb, (struct RObject*)c, sym, v);
}
void
@@ -394,16 +466,12 @@ mrb_st_lookup(struct kh_iv *table, mrb_sym id, khiter_t *value)
}
}
int
static int
kiv_lookup(khash_t(iv)* table, mrb_sym key, mrb_value *value)
{
khash_t(iv) *h=table;
khiter_t k;
// you must check(iv==0), before you call this function.
//if (!obj->iv) {
// return 0;
//}
k = kh_get(iv, h, key);
if (k != kh_end(h)) {
*value = kh_value(h, k);
@@ -442,23 +510,9 @@ mrb_const_defined_at(mrb_state *mrb, struct RClass *klass, mrb_sym id)
return mrb_const_defined_0(mrb, klass, id, TRUE, FALSE);
}
struct RClass *
mrb_class_from_sym(mrb_state *mrb, struct RClass *klass, mrb_sym id)
{
mrb_value c = const_get(mrb, klass, id);
return mrb_class_ptr(c);
}
struct RClass *
mrb_class_get(mrb_state *mrb, const char *name)
{
return mrb_class_from_sym(mrb, mrb->object_class, mrb_intern(mrb, name));
}
mrb_value
mrb_attr_get(mrb_state *mrb, mrb_value obj, mrb_sym id)
{
//return ivar_get(obj, id, FALSE);
return mrb_iv_get(mrb, obj, id);
}
+180 -104
View File
@@ -28,25 +28,41 @@ static void
stack_init(mrb_state *mrb)
{
/* assert(mrb->stack == NULL); */
mrb->stbase = mrb_malloc(mrb, sizeof(mrb_value) * STACK_INIT_SIZE);
memset(mrb->stbase, 0, sizeof(mrb_value) * STACK_INIT_SIZE);
mrb->stbase = (mrb_value *)mrb_calloc(mrb, STACK_INIT_SIZE, sizeof(mrb_value));
mrb->stend = mrb->stbase + STACK_INIT_SIZE;
mrb->stack = mrb->stbase;
/* assert(mrb->ci == NULL); */
mrb->cibase = mrb_malloc(mrb, sizeof(mrb_callinfo)*CALLINFO_INIT_SIZE);
mrb->cibase = (mrb_callinfo *)mrb_calloc(mrb, CALLINFO_INIT_SIZE, sizeof(mrb_callinfo));
mrb->ciend = mrb->cibase + CALLINFO_INIT_SIZE;
mrb->ci = mrb->cibase;
memset(mrb->ci, 0, sizeof(mrb_callinfo));
mrb->ci->target_class = mrb->object_class;
}
static void
envadjust(mrb_state *mrb, mrb_value *oldbase, mrb_value *newbase)
{
mrb_callinfo *ci = mrb->cibase;
while (ci <= mrb->ci) {
struct REnv *e = ci->env;
if (e && e->cioff >= 0) {
int off = e->stack - oldbase;
e->stack = newbase + off;
}
ci++;
}
}
static void
stack_extend(mrb_state *mrb, int room, int keep)
{
int size, off;
if (mrb->stack + room > mrb->stend) {
if (mrb->stack + room >= mrb->stend) {
mrb_value *oldbase = mrb->stbase;
size = mrb->stend - mrb->stbase;
off = mrb->stack - mrb->stbase;
@@ -54,9 +70,10 @@ stack_extend(mrb_state *mrb, int room, int keep)
size *= 2;
else
size += room;
mrb->stbase = mrb_realloc(mrb, mrb->stbase, sizeof(mrb_value) * size);
mrb->stbase = (mrb_value *)mrb_realloc(mrb, mrb->stbase, sizeof(mrb_value) * size);
mrb->stack = mrb->stbase + off;
mrb->stend = mrb->stbase + size;
envadjust(mrb, oldbase, mrb->stbase);
}
if (room > keep) {
memset(mrb->stack+keep, 0, sizeof(mrb_value) * (room-keep));
@@ -75,8 +92,8 @@ uvenv(mrb_state *mrb, int up)
{
struct REnv *e = mrb->ci->proc->env;
if (!e) return 0;
while (up--) {
if (!e) return 0;
e = (struct REnv*)e->c;
}
return e;
@@ -104,19 +121,18 @@ uvset(mrb_state *mrb, int up, int idx, mrb_value v)
static mrb_callinfo*
cipush(mrb_state *mrb)
{
size_t nregs = mrb->ci->nregs;
int eidx = mrb->ci->eidx;
int ridx = mrb->ci->ridx;
if (mrb->ci + 1 == mrb->ciend) {
size_t size = mrb->ci - mrb->cibase;
mrb->cibase = mrb_realloc(mrb, mrb->cibase, sizeof(mrb_callinfo)*size*2);
mrb->cibase = (mrb_callinfo *)mrb_realloc(mrb, mrb->cibase, sizeof(mrb_callinfo)*size*2);
mrb->ci = mrb->cibase + size;
mrb->ciend = mrb->cibase + size * 2;
}
mrb->ci++;
mrb->ci->nregs = nregs;
mrb->ci->nregs = 2;
mrb->ci->eidx = eidx;
mrb->ci->ridx = ridx;
mrb->ci->env = 0;
@@ -129,7 +145,7 @@ cipop(mrb_state *mrb)
if (mrb->ci->env) {
struct REnv *e = mrb->ci->env;
int len = (int)e->flags;
mrb_value *p = mrb_malloc(mrb, sizeof(mrb_value)*len);
mrb_value *p = (mrb_value *)mrb_malloc(mrb, sizeof(mrb_value)*len);
e->cioff = -1;
memcpy(p, e->stack, sizeof(mrb_value)*len);
@@ -145,6 +161,7 @@ ecall(mrb_state *mrb, int i)
struct RProc *p;
mrb_callinfo *ci;
mrb_value *self = mrb->stack;
struct RObject *exc;
p = mrb->ensure[i];
ci = cipush(mrb);
@@ -156,20 +173,24 @@ ecall(mrb_state *mrb, int i)
ci->nregs = p->body.irep->nregs;
ci->target_class = p->target_class;
mrb->stack = mrb->stack + ci[-1].nregs;
exc = mrb->exc; mrb->exc = 0;
mrb_run(mrb, p, *self);
if (!mrb->exc) mrb->exc = exc;
}
mrb_value
mrb_funcall_with_block(mrb_state *mrb, mrb_value self, const char *name, int argc, mrb_value *argv, mrb_value blk)
mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, int argc, mrb_value *argv, mrb_value blk)
{
struct RProc *p;
struct RClass *c;
mrb_sym mid = mrb_intern(mrb, name);
mrb_sym undef = 0;
mrb_callinfo *ci;
int n = mrb->ci->nregs;
mrb_value val;
if (argc < 0) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "negative argc for funcall (%d)", argc);
}
c = mrb_class(mrb, self);
p = mrb_method_search_vm(mrb, &c, mid);
if (!p) {
@@ -200,7 +221,10 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, const char *name, int arg
mrb->stack[argc+1] = blk;
if (MRB_PROC_CFUNC_P(p)) {
int ai = mrb->arena_idx;
val = p->body.func(mrb, self);
mrb->arena_idx = ai;
mrb_gc_protect(mrb, val);
mrb->stack = mrb->stbase + ci->stackidx;
cipop(mrb);
}
@@ -211,13 +235,13 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, const char *name, int arg
}
mrb_value
mrb_funcall_argv(mrb_state *mrb, mrb_value self, const char *name, int argc, mrb_value *argv)
mrb_funcall_argv(mrb_state *mrb, mrb_value self, mrb_sym mid, int argc, mrb_value *argv)
{
return mrb_funcall_with_block(mrb, self, name, argc, argv, mrb_nil_value());
return mrb_funcall_with_block(mrb, self, mid, argc, argv, mrb_nil_value());
}
mrb_value
mrb_yield_with_self(mrb_state *mrb, mrb_value b, int argc, mrb_value *argv, mrb_value self)
mrb_yield_internal(mrb_state *mrb, mrb_value b, int argc, mrb_value *argv, mrb_value self, struct RClass *c)
{
struct RProc *p;
mrb_sym mid = mrb->ci->mid;
@@ -231,7 +255,7 @@ mrb_yield_with_self(mrb_state *mrb, mrb_value b, int argc, mrb_value *argv, mrb_
ci->proc = p;
ci->stackidx = mrb->stack - mrb->stbase;
ci->argc = argc;
ci->target_class = p->target_class;
ci->target_class = c;
ci->nregs = argc + 2;
ci->acc = -1;
mrb->stack = mrb->stack + n;
@@ -257,23 +281,28 @@ mrb_yield_with_self(mrb_state *mrb, mrb_value b, int argc, mrb_value *argv, mrb_
mrb_value
mrb_yield_argv(mrb_state *mrb, mrb_value b, int argc, mrb_value *argv)
{
return mrb_yield_with_self(mrb, b, argc, argv, mrb->stack[0]);
struct RProc *p = mrb_proc_ptr(b);
return mrb_yield_internal(mrb, b, argc, argv, mrb->stack[0], p->target_class);
}
mrb_value
mrb_yield(mrb_state *mrb, mrb_value b, mrb_value v)
{
return mrb_yield_with_self(mrb, b, 1, &v, mrb->stack[0]);
struct RProc *p = mrb_proc_ptr(b);
return mrb_yield_internal(mrb, b, 1, &v, mrb->stack[0], p->target_class);
}
static void
localjump_error(mrb_state *mrb, const char *kind)
{
char buf[256];
int len;
mrb_value exc;
snprintf(buf, 256, "unexpected %s", kind);
exc = mrb_exc_new(mrb, E_LOCALJUMP_ERROR, buf, strlen(buf));
len = snprintf(buf, sizeof(buf), "unexpected %s", kind);
exc = mrb_exc_new(mrb, E_LOCALJUMP_ERROR, buf, len);
mrb->exc = (struct RObject*)mrb_object(exc);
}
@@ -281,18 +310,19 @@ static void
argnum_error(mrb_state *mrb, int num)
{
char buf[256];
int len;
mrb_value exc;
if (mrb->ci->mid) {
snprintf(buf, 256, "'%s': wrong number of arguments (%d for %d)",
mrb_sym2name(mrb, mrb->ci->mid),
mrb->ci->argc, num);
len = snprintf(buf, sizeof(buf), "'%s': wrong number of arguments (%d for %d)",
mrb_sym2name(mrb, mrb->ci->mid),
mrb->ci->argc, num);
}
else {
snprintf(buf, 256, "wrong number of arguments (%d for %d)",
mrb->ci->argc, num);
len = snprintf(buf, sizeof(buf), "wrong number of arguments (%d for %d)",
mrb->ci->argc, num);
}
exc = mrb_exc_new(mrb, E_ARGUMENT_ERROR, buf, strlen(buf));
exc = mrb_exc_new(mrb, E_ARGUMENT_ERROR, buf, len);
mrb->exc = (struct RObject*)mrb_object(exc);
}
@@ -337,20 +367,20 @@ argnum_error(mrb_state *mrb, int num)
#ifndef DIRECT_THREADED
#define INIT_DISPACTH for (;;) { i = *pc; switch (GET_OPCODE(i)) {
#define INIT_DISPATCH for (;;) { i = *pc; switch (GET_OPCODE(i)) {
#define CASE(op) case op:
#define NEXT mrb->arena_idx = ai; pc++; break
#define NEXT pc++; break
#define JUMP break
#define END_DISPACTH }}
#define END_DISPATCH }}
#else
#define INIT_DISPACTH JUMP; return mrb_nil_value();
#define INIT_DISPATCH JUMP; return mrb_nil_value();
#define CASE(op) L_ ## op:
#define NEXT mrb->arena_idx = ai; i=*++pc; goto *optable[GET_OPCODE(i)]
#define NEXT i=*++pc; goto *optable[GET_OPCODE(i)]
#define JUMP i=*pc; goto *optable[GET_OPCODE(i)]
#define END_DISPACTH
#define END_DISPATCH
#endif
@@ -370,8 +400,8 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
mrb_value *regs = NULL;
mrb_code i;
int ai = mrb->arena_idx;
jmp_buf *prev_jmp = (jmp_buf *)mrb->jmp;
jmp_buf c_jmp;
jmp_buf *prev_jmp = NULL;
#ifdef DIRECT_THREADED
static void *optable[] = {
@@ -400,7 +430,6 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
if (setjmp(c_jmp) == 0) {
prev_jmp = mrb->jmp;
mrb->jmp = &c_jmp;
}
else {
@@ -413,7 +442,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
mrb->ci->nregs = irep->nregs + 2;
regs = mrb->stack;
INIT_DISPACTH {
INIT_DISPATCH {
CASE(OP_NOP) {
/* do nothing */
NEXT;
@@ -453,14 +482,6 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
NEXT;
}
CASE(OP_LOADNIL) {
/* A B R(A) := nil */
int a = GETARG_A(i);
SET_NIL_VALUE(regs[a]);
NEXT;
}
CASE(OP_LOADSELF) {
/* A R(A) := self */
regs[GETARG_A(i)] = mrb->stack[0];
@@ -596,7 +617,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
if (mrb->rsize <= mrb->ci->ridx) {
if (mrb->rsize == 0) mrb->rsize = 16;
else mrb->rsize *= 2;
mrb->rescue = mrb_realloc(mrb, mrb->rescue, sizeof(mrb_code*) * mrb->rsize);
mrb->rescue = (mrb_code **)mrb_realloc(mrb, mrb->rescue, sizeof(mrb_code*) * mrb->rsize);
}
mrb->rescue[mrb->ci->ridx++] = pc + GETARG_sBx(i);
NEXT;
@@ -633,9 +654,10 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
if (mrb->esize <= mrb->ci->eidx) {
if (mrb->esize == 0) mrb->esize = 16;
else mrb->esize *= 2;
mrb->ensure = mrb_realloc(mrb, mrb->ensure, sizeof(struct RProc*) * mrb->esize);
mrb->ensure = (struct RProc **)mrb_realloc(mrb, mrb->ensure, sizeof(struct RProc*) * mrb->esize);
}
mrb->ensure[mrb->ci->eidx++] = p;
mrb->arena_idx = ai;
NEXT;
}
@@ -647,6 +669,15 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
for (n=0; n<a; n++) {
ecall(mrb, --mrb->ci->eidx);
}
mrb->arena_idx = ai;
NEXT;
}
CASE(OP_LOADNIL) {
/* A B R(A) := nil */
int a = GETARG_A(i);
SET_NIL_VALUE(regs[a]);
NEXT;
}
@@ -686,25 +717,29 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
ci->stackidx = mrb->stack - mrb->stbase;
ci->argc = n;
if (ci->argc == CALL_MAXARGS) ci->argc = -1;
ci->target_class = m->target_class;
ci->target_class = c;
ci->pc = pc + 1;
ci->acc = a;
/* prepare stack */
mrb->stack += a;
if (MRB_PROC_CFUNC_P(m)) {
if (n == CALL_MAXARGS) {
ci->nregs = 3;
}
else {
ci->nregs = n + 2;
}
mrb->stack[0] = m->body.func(mrb, recv);
mrb->arena_idx = ai;
if (mrb->exc) goto L_RAISE;
/* pop stackpos */
mrb->stack = mrb->stbase + ci->stackidx;
regs = mrb->stack = mrb->stbase + ci->stackidx;
cipop(mrb);
NEXT;
}
else {
/* fill callinfo */
ci->acc = a;
/* setup environment for calling method */
proc = mrb->ci->proc = m;
irep = m->body.irep;
@@ -766,6 +801,10 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
/* setup environment for calling method */
proc = m;
irep = m->body.irep;
if (!irep) {
mrb->stack[0] = mrb_nil_value();
goto L_RETURN;
}
pool = irep->pool;
syms = irep->syms;
ci->nregs = irep->nregs;
@@ -793,10 +832,9 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
int n = GETARG_C(i);
recv = regs[0];
c = mrb->ci->proc->target_class->super;
c = mrb->ci->target_class->super;
m = mrb_method_search_vm(mrb, &c, mid);
if (!m) {
c = mrb->ci->proc->target_class;
mid = mrb_intern(mrb, "method_missing");
m = mrb_method_search_vm(mrb, &c, mid);
if (n == CALL_MAXARGS) {
@@ -828,7 +866,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
mrb->arena_idx = ai;
if (mrb->exc) goto L_RAISE;
/* pop stackpos */
mrb->stack = mrb->stbase + ci->stackidx;
regs = mrb->stack = mrb->stbase + ci->stackidx;
cipop(mrb);
NEXT;
}
@@ -867,6 +905,13 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
if (lv == 0) stack = regs + 1;
else {
struct REnv *e = uvenv(mrb, lv-1);
if (!e) {
mrb_value exc;
static const char m[] = "super called outside of method";
exc = mrb_exc_new(mrb, E_NOMETHOD_ERROR, m, sizeof(m) - 1);
mrb->exc = (struct RObject*)mrb_object(exc);
goto L_RAISE;
}
stack = e->stack + 1;
}
if (r == 0) {
@@ -880,21 +925,22 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
if (stack[m1].tt == MRB_TT_ARRAY) {
struct RArray *ary = mrb_ary_ptr(stack[m1]);
pp = ary->buf;
pp = ary->ptr;
len = ary->len;
}
regs[a] = mrb_ary_new_capa(mrb, m1+len+m2);
rest = mrb_ary_ptr(regs[a]);
memcpy(rest->buf, stack, sizeof(mrb_value)*m1);
memcpy(rest->ptr, stack, sizeof(mrb_value)*m1);
if (len > 0) {
memcpy(rest->buf+m1, pp, sizeof(mrb_value)*len);
memcpy(rest->ptr+m1, pp, sizeof(mrb_value)*len);
}
if (m2 > 0) {
memcpy(rest->buf+m1+len, stack+m1+1, sizeof(mrb_value)*m2);
memcpy(rest->ptr+m1+len, stack+m1+1, sizeof(mrb_value)*m2);
}
rest->len = m1+len+m2;
}
regs[a+1] = stack[m1+r+m2];
mrb->arena_idx = ai;
NEXT;
}
@@ -914,12 +960,13 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
int argc = mrb->ci->argc;
mrb_value *argv = regs+1;
int len = m1 + o + r + m2;
mrb_value *blk = &argv[argc < 0 ? 1 : argc];
if (argc < 0) {
struct RArray *ary = mrb_ary_ptr(regs[1]);
argv = ary->buf;
argv = ary->ptr;
argc = ary->len;
regs[len+2] = regs[1]; /* save argary in register */
mrb_gc_protect(mrb, regs[1]);
}
if (mrb->ci->proc && MRB_PROC_STRICT_P(mrb->ci->proc)) {
if (argc >= 0) {
@@ -931,17 +978,19 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
}
else if (len > 1 && argc == 1 && argv[0].tt == MRB_TT_ARRAY) {
argc = mrb_ary_ptr(argv[0])->len;
argv = mrb_ary_ptr(argv[0])->buf;
argv = mrb_ary_ptr(argv[0])->ptr;
}
mrb->ci->argc = len;
if (argc < len) {
regs[len+1] = argv[argc]; /* move block */
regs[len+1] = *blk; /* move block */
memmove(&regs[1], argv, sizeof(mrb_value)*(argc-m2)); /* m1 + o */
memmove(&regs[len-m2+1], &argv[argc-m2], sizeof(mrb_value)*m2); /* m2 */
if (r) { /* r */
regs[m1+o+1] = mrb_ary_new_capa(mrb, 0);
}
pc += argc - m1 - m2 + 1;
if (o == 0) pc++;
else
pc += argc - m1 - m2 + 1;
}
else {
memmove(&regs[1], argv, sizeof(mrb_value)*(m1+o)); /* m1 + o */
@@ -949,7 +998,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
regs[m1+o+1] = mrb_ary_new_elts(mrb, argc-m1-o-m2, argv+m1+o);
}
memmove(&regs[m1+o+r+1], &argv[argc-m2], sizeof(mrb_value)*m2);
regs[len+1] = argv[argc]; /* move block */
regs[len+1] = *blk; /* move block */
pc += o + 1;
}
JUMP;
@@ -972,16 +1021,25 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
L_RETURN:
if (mrb->exc) {
mrb_callinfo *ci;
int eidx;
L_RAISE:
ci = mrb->ci;
eidx = mrb->ci->eidx;
if (ci == mrb->cibase) goto L_STOP;
while (ci[0].ridx == ci[-1].ridx) {
cipop(mrb);
ci = mrb->ci;
if (ci->acc < 0) {
mrb->jmp = prev_jmp;
longjmp(*(jmp_buf*)mrb->jmp, 1);
}
while (eidx > mrb->ci->eidx) {
ecall(mrb, --eidx);
}
if (ci == mrb->cibase) {
if (ci->ridx == 0) {
mrb->stack = mrb->stbase;
regs = mrb->stack = mrb->stbase;
goto L_STOP;
}
break;
@@ -1076,7 +1134,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
/* replace callinfo */
mrb->ci = ci = &mrb->ci[-1];
ci = mrb->ci;
ci->mid = mid;
ci->target_class = m->target_class;
ci->argc = n;
@@ -1120,6 +1178,10 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
if (lv == 0) stack = regs + 1;
else {
struct REnv *e = uvenv(mrb, lv-1);
if (!e) {
localjump_error(mrb, "yield");
goto L_RAISE;
}
stack = e->stack + 1;
}
regs[a] = stack[m1+r+m2];
@@ -1131,12 +1193,12 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
regs[a].value.v1 = regs[a].value.v1 op regs[a+1].value.v2;\
} while(0)
#define OP_MATH(op) do {\
#define OP_MATH(op,iop,s) do {\
int a = GETARG_A(i);\
/* need to check if - is overridden */\
/* need to check if op is overridden */\
switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) {\
case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM):\
OP_MATH_BODY(op,i,i); \
regs[a] = iop(mrb, regs[a], regs[a+1]);\
break;\
case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT):\
{\
@@ -1151,7 +1213,9 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT):\
OP_MATH_BODY(op,f,f);\
break;\
s\
default:\
SET_NIL_VALUE(regs[a+2]);\
i = MKOP_ABC(OP_SEND, a, GETARG_B(i), GETARG_C(i));\
goto L_SEND;\
}\
@@ -1159,50 +1223,29 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
CASE(OP_ADD) {
/* A B C R(A) := R(A)+R(A+1) (Syms[B]=:+,C=1)*/
int a = GETARG_A(i);
switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) {
case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM):
OP_MATH_BODY(+,i,i);
break;
case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT):
{
mrb_int x = regs[a].value.i;
mrb_float y = regs[a+1].value.f;
SET_FLOAT_VALUE(regs[a], (mrb_float)x + y);
}
break;
case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM):
OP_MATH_BODY(+,f,i);
break;
case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT):
OP_MATH_BODY(+,f,f);
break;
OP_MATH(+,mrb_fixnum_plus,
case TYPES2(MRB_TT_STRING,MRB_TT_STRING):
regs[a] = mrb_str_plus(mrb, regs[a], regs[a+1]);
break;
default:
i = MKOP_ABC(OP_SEND, a, GETARG_B(i), GETARG_C(i));
goto L_SEND;
}
break;);
mrb->arena_idx = ai;
NEXT;
}
CASE(OP_SUB) {
/* A B C R(A) := R(A)-R(A+1) (Syms[B]=:-,C=1)*/
OP_MATH(-);
OP_MATH(-,mrb_fixnum_minus,;);
NEXT;
}
CASE(OP_MUL) {
/* A B C R(A) := R(A)*R(A+1) (Syms[B]=:*,C=1)*/
OP_MATH(*);
OP_MATH(*,mrb_fixnum_mul,;);
NEXT;
}
CASE(OP_DIV) {
/* A B C R(A) := R(A)/R(A+1) (Syms[B]=:/,C=1)*/
OP_MATH(/);
OP_MATH(/,mrb_num_div,;);
NEXT;
}
@@ -1219,6 +1262,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
regs[a].value.f += GETARG_C(i);
break;
default:
SET_NIL_VALUE(regs[a+2]);
SET_INT_VALUE(regs[a+1], GETARG_C(i));
i = MKOP_ABC(OP_SEND, a, GETARG_B(i), 1);
goto L_SEND;
@@ -1239,6 +1283,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
regs[a].value.f -= GETARG_C(i);
break;
default:
SET_NIL_VALUE(regs[a+2]);
SET_INT_VALUE(regs[a+1], GETARG_C(i));
i = MKOP_ABC(OP_SEND, a, GETARG_B(i), 1);
goto L_SEND;
@@ -1272,6 +1317,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
OP_CMP_BODY(op,f,f);\
break;\
default:\
SET_NIL_VALUE(regs[a+2]);\
i = MKOP_ABC(OP_SEND, a, GETARG_B(i), GETARG_C(i));\
goto L_SEND;\
}\
@@ -1317,6 +1363,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
mrb_ary_push(mrb, ary, regs[b++]);
}
regs[GETARG_A(i)] = ary;
mrb->arena_idx = ai;
NEXT;
}
@@ -1324,6 +1371,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
/* A B mrb_ary_concat(R(A),R(B)) */
mrb_ary_concat(mrb, regs[GETARG_A(i)],
mrb_ary_splat(mrb, regs[GETARG_B(i)]));
mrb->arena_idx = ai;
NEXT;
}
@@ -1379,15 +1427,15 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
int i;
if (len > pre + post) {
regs[a++] = mrb_ary_new_elts(mrb, len - pre - post, ary->buf+pre);
regs[a++] = mrb_ary_new_elts(mrb, len - pre - post, ary->ptr+pre);
while (post--) {
regs[a++] = ary->buf[len-post-1];
regs[a++] = ary->ptr[len-post-1];
}
}
else {
regs[a++] = mrb_ary_new_capa(mrb, 0);
for (i=0; i+pre<len; i++) {
regs[a+i] = ary->buf[pre+i];
regs[a+i] = ary->ptr[pre+i];
}
while (i < post) {
SET_NIL_VALUE(regs[a+i]);
@@ -1395,12 +1443,14 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
}
}
}
mrb->arena_idx = ai;
NEXT;
}
CASE(OP_STRING) {
/* A Bx R(A) := str_new(Lit(Bx)) */
regs[GETARG_A(i)] = mrb_str_literal(mrb, pool[GETARG_Bx(i)]);
mrb->arena_idx = ai;
NEXT;
}
@@ -1422,6 +1472,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
b+=2;
}
regs[GETARG_A(i)] = hash;
mrb->arena_idx = ai;
NEXT;
}
@@ -1438,6 +1489,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
}
if (c & OP_L_STRICT) p->flags |= MRB_PROC_STRICT;
regs[GETARG_A(i)] = mrb_obj_value(p);
mrb->arena_idx = ai;
NEXT;
}
@@ -1461,6 +1513,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
}
c = mrb_vm_define_class(mrb, base, super, id);
regs[a] = mrb_obj_value(c);
mrb->arena_idx = ai;
NEXT;
}
@@ -1477,6 +1530,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
}
c = mrb_vm_define_module(mrb, base, id);
regs[a] = mrb_obj_value(c);
mrb->arena_idx = ai;
NEXT;
}
@@ -1494,7 +1548,10 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
ci->mid = 0;
ci->stackidx = mrb->stack - mrb->stbase;
ci->argc = 0;
ci->target_class = mrb_class_ptr(regs[GETARG_A(i)]);
ci->target_class = mrb_class_ptr(recv);
/* prepare stack */
mrb->stack += a;
p = mrb_proc_new(mrb, mrb->irep[irep->idx+GETARG_Bx(i)]);
p->target_class = ci->target_class;
@@ -1510,12 +1567,11 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
NEXT;
}
else {
/* setup environment for calling method */
irep = p->body.irep;
pool = irep->pool;
syms = irep->syms;
mrb->stack += a;
stack_extend(mrb, irep->nregs, 1);
ci->nregs = irep->nregs;
regs = mrb->stack;
pc = irep->iseq;
JUMP;
@@ -1528,17 +1584,25 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
struct RClass *c = mrb_class_ptr(regs[a]);
mrb_define_method_vm(mrb, c, syms[GETARG_B(i)], regs[a+1]);
mrb->arena_idx = ai;
NEXT;
}
CASE(OP_SCLASS) {
/* A B R(A) := R(B).singleton_class */
regs[GETARG_A(i)] = mrb_singleton_class(mrb, regs[GETARG_B(i)]);
mrb->arena_idx = ai;
NEXT;
}
CASE(OP_TCLASS) {
/* A B R(A) := target_class */
if (!mrb->ci->target_class) {
static const char msg[] = "no target class or module";
mrb_value exc = mrb_exc_new(mrb, E_TYPE_ERROR, msg, sizeof(msg) - 1);
mrb->exc = (struct RObject*)mrb_object(exc);
goto L_RAISE;
}
regs[GETARG_A(i)] = mrb_obj_value(mrb->ci->target_class);
NEXT;
}
@@ -1547,18 +1611,30 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
/* A B C R(A) := range_new(R(B),R(B+1),C) */
int b = GETARG_B(i);
regs[GETARG_A(i)] = mrb_range_new(mrb, regs[b], regs[b+1], GETARG_C(i));
mrb->arena_idx = ai;
NEXT;
}
CASE(OP_DEBUG) {
/* A debug print R(A),R(B),R(C) */
#ifdef ENABLE_STDIO
printf("OP_DEBUG %d %d %d\n", GETARG_A(i), GETARG_B(i), GETARG_C(i));
#else
abort();
#endif
NEXT;
}
CASE(OP_STOP) {
/* stop VM */
L_STOP:
{
int n = mrb->ci->eidx;
while (n--) {
ecall(mrb, n);
}
}
mrb->jmp = prev_jmp;
if (mrb->exc) {
return mrb_obj_value(mrb->exc);
@@ -1569,11 +1645,11 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
CASE(OP_ERR) {
/* Bx raise RuntimeError with message Lit(Bx) */
mrb_value msg = pool[GETARG_Bx(i)];
mrb_value exc = mrb_exc_new3(mrb, mrb->eRuntimeError_class, msg);
mrb_value exc = mrb_exc_new3(mrb, E_RUNTIME_ERROR, msg);
mrb->exc = (struct RObject*)mrb_object(exc);
goto L_RAISE;
}
}
END_DISPACTH;
END_DISPATCH;
}
+12 -5
View File
@@ -20,12 +20,19 @@ OBJS := driver.o $(MLIB)
LIBS = -lm
INCLUDES = -I$(BASEDIR)/../src -I$(BASEDIR)/../include
DEBUG_MODE = 1
ifeq ($(DEBUG_MODE),1)
CFLAGS = -g
else
CFLAGS = -O3
ifeq ($(strip $(COMPILE_MODE)),)
# default compile option
COMPILE_MODE = debug
endif
ifeq ($(COMPILE_MODE),debug)
CFLAGS = -g -O3
else ifeq ($(COMPILE_MODE),release)
CFLAGS = -O3
else ifeq ($(COMPILE_MODE),small)
CFLAGS = -Os
endif
ALL_CFLAGS = -Wall -Werror-implicit-function-declaration $(CFLAGS)
ifeq ($(OS),Windows_NT)
MAKE_FLAGS = CC=$(CC) LL=$(LL) ALL_CFLAGS="$(ALL_CFLAGS)"
+10 -3
View File
@@ -2,6 +2,7 @@ $ok_test = 0
$ko_test = 0
$kill_test = 0
$asserts = []
$test_start = Time.now if Object.const_defined?(:Time)
##
# Print the assertion in a readable way
@@ -32,7 +33,7 @@ def assert(str = 'Assertion failed', iso = '')
$ok_test += 1
print('.')
end
rescue => e
rescue Exception => e
$asserts.push(['Error: ', str, iso, e])
$kill_test += 1
print('X')
@@ -68,18 +69,24 @@ def report()
print('Crash: ')
print($kill_test)
print("\n")
if Object.const_defined?(:Time)
print(' Time: ')
print(Time.now - $test_start)
print(" seconds\n")
end
end
##
# Performs fuzzy check for equality on methods returning floats
# on the basis of the Math::TOLERANCE constant.
def check_float(a, b)
tolerance = Math::TOLERANCE
a = a.to_f
b = b.to_f
if a.finite? and b.finite?
(a-b).abs < Math::TOLERANCE
(a-b).abs < tolerance
else
true
end
end
+24 -15
View File
@@ -11,6 +11,7 @@
#include <mruby/proc.h>
#include <mruby/data.h>
#include <mruby/compile.h>
#include <mruby/variable.h>
void
mrb_init_mrbtest(mrb_state *);
@@ -23,39 +24,47 @@ void print_hint(void)
printf("Thanks :)\n\n");
}
static int
check_error(mrb_state *mrb)
{
/* Error check */
/* $ko_test and $kill_test should be 0 */
mrb_value ko_test = mrb_gv_get(mrb, mrb_intern(mrb, "$ko_test"));
mrb_value kill_test = mrb_gv_get(mrb, mrb_intern(mrb, "$kill_test"));
return FIXNUM_P(ko_test) && mrb_fixnum(ko_test) == 0 && FIXNUM_P(kill_test) && mrb_fixnum(kill_test) == 0;
}
int
main(void)
{
struct mrb_parser_state *parser;
mrb_state *mrb;
mrb_value return_value;
int byte_code;
const char *prog = "report()";
int ret = EXIT_SUCCESS;
print_hint();
/* new interpreter instance */
mrb = mrb_open();
if (mrb == NULL) {
fprintf(stderr, "Invalid mrb_state, exiting test driver");
return EXIT_FAILURE;
}
mrb_init_mrbtest(mrb);
parser = mrb_parse_nstring(mrb, prog, strlen(prog));
/* generate bytecode */
byte_code = mrb_generate_code(mrb, parser->tree);
/* evaluate the bytecode */
return_value = mrb_run(mrb,
/* pass a proc for evaulation */
mrb_proc_new(mrb, mrb->irep[byte_code]),
mrb_top_self(mrb));
/* evaluate the test */
return_value = mrb_load_string(mrb, prog);
/* did an exception occur? */
if (mrb->exc) {
mrb_p(mrb, return_value);
mrb->exc = 0;
ret = EXIT_FAILURE;
}
else {
/* no */
else if (!check_error(mrb)) {
ret = EXIT_FAILURE;
}
mrb_close(mrb);
return 0;
return ret;
}
+5
View File
@@ -13,3 +13,8 @@ assert('ArgumentError', '15.2.24') do
ArgumentError.class == Class and e2.class == ArgumentError
end
assert('ArgumentError superclass', '15.2.24.2') do
ArgumentError.superclass == StandardError
end
+66 -3
View File
@@ -5,6 +5,10 @@ assert('Array', '15.2.12') do
Array.class == Class
end
assert('Array superclass', '15.2.12.2') do
Array.superclass == Object
end
assert('Array.[]', '15.2.12.4.1') do
Array.[](1,2,3) == [1, 2, 3]
end
@@ -61,6 +65,7 @@ assert('Array#[]=', '15.2.12.5.5') do
end
[1,2,3].[]=(1,4) == [1, 4, 3] and
[1,2,3].[]=(1,2,3) == [1, 3] and
e2.class == ArgumentError and
e3.class == ArgumentError
end
@@ -113,7 +118,24 @@ assert('Array#first', '15.2.12.5.13') do
a = []
b = [1,2,3]
a.first == nil and b.first == 1
e2 = nil
e3 = nil
begin
# this will cause an exception due to the wrong argument
[1,2,3].first(-1)
rescue => e1
e2 = e1
end
begin
# this will cause an exception due to the wrong argument
[1,2,3].first(1,2)
rescue => e1
e3 = e1
end
a.first == nil and b.first == 1 and b.first(0) == [] and
b.first(1) == [1] and b.first(4) == [1,2,3] and
e2.class == ArgumentError and e3.class == ArgumentError
end
assert('Array#index', '15.2.12.5.14') do
@@ -148,7 +170,15 @@ end
assert('Array#last', '15.2.12.5.18') do
a = [1,2,3]
a.last == 3 and [].last == nil
e2 = nil
begin
# this will cause an exception due to the wrong argument
[1,2,3].last(-1)
rescue => e1
e2 = e1
end
a.last == 3 and [].last == nil and e2.class == ArgumentError
end
assert('Array#length', '15.2.12.5.19') do
@@ -218,7 +248,9 @@ assert('Array#size', '15.2.12.5.28') do
end
assert('Array#slice', '15.2.12.5.29') do
[1,2,3].[](1) == 2
a = "12345".slice(1, 3)
b = a.slice(0)
"#{b}:" == "2:" and [1,2,3].[](1) == 2
end
assert('Array#unshift', '15.2.12.5.30') do
@@ -228,4 +260,35 @@ assert('Array#unshift', '15.2.12.5.30') do
a == [1,2,3] and b == [1,2,3]
end
assert('Array#to_s', '15.2.12.5.31') do
a = [2, 3, 4, 5]
r1 = a.to_s
r2 = a.inspect
r1 == r2 and r1 == "[2, 3, 4, 5]"
end
assert('Array#==', '15.2.12.5.33') do
r1 = [ "a", "c" ] == [ "a", "c", 7 ] #=> false
r2 = [ "a", "c", 7 ] == [ "a", "c", 7 ] #=> true
r3 = [ "a", "c", 7 ] == [ "a", "d", "f" ] #=> false
r1 == false and r2 == true and r3 == false
end
assert('Array#<=>', '15.2.12.5.36') do
r1 = [ "a", "a", "c" ] <=> [ "a", "b", "c" ] #=> -1
r2 = [ 1, 2, 3, 4, 5, 6 ] <=> [ 1, 2 ] #=> +1
r1 == -1 and r2 == +1
end
# Not ISO specified
assert("Array (Shared Array Corruption)") do
a = [ "a", "b", "c", "d", "e", "f" ]
b = a.slice(1, 3)
a.clear
b.clear
end
+11
View File
@@ -0,0 +1,11 @@
##
# BasicObject
assert('BasicObject') do
BasicObject.class == Class
end
assert('BasicObject superclass') do
BasicObject.superclass == nil
end
+6 -6
View File
@@ -62,11 +62,11 @@ end
assert('BS Block 7') do
ans = []
for m in 1..3
for n in 1..3
for n in 2..4
a = [m, n]
ans << a
end
end == 1..3
end == (1..3)
end
assert('BS Block 8') do
@@ -322,28 +322,28 @@ assert('BS Block [ruby-dev:31147]') do
def m
yield
end
m{|&b| b}.inspect == 'nil'
m{|&b| b} == nil
end
assert('BS Block [ruby-dev:31160]') do
def m()
yield
end
m {|(v,(*))|}.inspect == 'nil'
m {|(v,(*))|} == nil
end
assert('BS Block 31') do
def m()
yield
end
m {|((*))|}.inspect == 'nil'
m {|((*))|} == nil
end
assert('BS Block [ruby-dev:31440]') do
def m
yield [0]
end
m{|v, &b| v}.inspect == '[0]'
m{|v, &b| v} == [0]
end
assert('BS Block 32') do
+100 -15
View File
@@ -5,39 +5,124 @@ assert('Class', '15.2.3') do
Class.class == Class
end
assert('Class superclass', '15.2.3.2') do
Class.superclass == Module
end
assert('Class#new', '15.2.3.3.3') do
# at the moment no exception on singleton class
#e1 = nil
#begin
# class1 = e1.singleton_class.new
#rescue => e1
# e2 = e1
#end
class TestClass
def initialize args, &block
@result = if not args.nil? and block.nil?
# only arguments
:only_args
elsif not args.nil? and not block.nil?
# args and block is given
:args_and_block
else
# this should never happen
:broken
end
end
def result; @result; end
end
TestClass.new(:arg).result == :only_args
# with block doesn't work yet
end
assert('Class#superclass', '15.2.3.3.4') do
class SubClass < String; end
SubClass.superclass == String
end
# Not ISO specified
assert('Class 1') do
class C; end
C.class == Class
class C1; end
C1.class == Class
end
assert('Class 2') do
class C; end
C.new.class == C
class C2; end
C2.new.class == C2
end
assert('Class 3') do
class C; end
C.new.class.class == Class
class C3; end
C3.new.class.class == Class
end
assert('Class 4') do
class A; end
class C < A; end
C.class == Class
class C4_A; end
class C4 < C4_A; end
C4.class == Class
end
assert('Class 5') do
class A; end
class C < A; end
C.new.class == C
class C5_A; end
class C5 < C5_A; end
C5.new.class == C5
end
assert('Class 6') do
class A; end
class C < A; end
C.new.class.class == Class
class C6_A; end
class C6 < C6_A; end
C6.new.class.class == Class
end
assert('Class 7') do
class C7_A; end
class C7_B; end
class C7 < C7_A; end
error = false
begin
# Different superclass.
class C7 < C7_B; end
rescue TypeError
error = true
end
error
end
assert('Class 8') do
class C8_A; end
class C8; end # superclass is Object
error = false
begin
# Different superclass.
class C8 < C8_A; end
rescue TypeError
error = true
end
error
end
assert('Class 9') do
Class9Const = "a"
error = false
begin
class Class9Const; end
rescue TypeError
error = true
end
error
end
assert('Class Module 1') do
+56
View File
@@ -0,0 +1,56 @@
assert('<', '15.3.3.2.1') do
class Foo
include Comparable
def <=>(x)
0
end
end
(Foo.new < Foo.new) == false
end
assert('<=', '15.3.3.2.2') do
class Foo
include Comparable
def <=>(x)
0
end
end
(Foo.new <= Foo.new) == true
end
assert('==', '15.3.3.2.3') do
class Foo
include Comparable
def <=>(x)
0
end
end
(Foo.new == Foo.new) == true
end
assert('>', '15.3.3.2.4') do
class Foo
include Comparable
def <=>(x)
0
end
end
(Foo.new > Foo.new) == false
end
assert('>=', '15.3.3.2.5') do
class Foo
include Comparable
def <=>(x)
0
end
end
(Foo.new >= Foo.new) == true
end
+61 -1
View File
@@ -5,6 +5,10 @@ assert('Exception', '15.2.22') do
Exception.class == Class
end
assert('Exception superclass', '15.2.22.2') do
Exception.superclass == Object
end
assert('Exception.exception', '15.2.22.4.1') do
e = Exception.exception('a')
@@ -20,7 +24,7 @@ end
assert('Exception#message', '15.2.22.5.2') do
e = Exception.exception('a')
e.message == 'a'
end
@@ -37,6 +41,26 @@ assert('Exception.exception', '15.2.22.4.1') do
e.message == 'a'
end
assert('ScriptError', '15.2.37') do
begin
raise ScriptError.new
rescue ScriptError
true
else
false
end
end
assert('SyntaxError', '15.2.38') do
begin
raise SyntaxError.new
rescue SyntaxError
true
else
false
end
end
# Not ISO specified
assert('Exception 1') do
@@ -193,3 +217,39 @@ assert('Exception 10') do
7+7
end == 12
end
assert('Exception 11') do
a = :ok
begin
begin
raise Exception
rescue
a = :ng
end
rescue Exception
end
a == :ok
end
assert('Exception 12') do
a = :ok
begin
raise Exception rescue a = :ng
rescue Exception
end
a == :ok
end
assert('Exception 13') do
a = :ng
begin
raise StandardError
rescue TypeError, ArgumentError
a = :ng
rescue
a = :ok
else
a = :ng
end
a == :ok
end
+8 -4
View File
@@ -5,22 +5,26 @@ assert('FalseClass', '15.2.6') do
FalseClass.class == Class
end
assert('FalseClass superclass', '15.2.6.2') do
FalseClass.superclass == Object
end
assert('FalseClass false', '15.2.6.1') do
not false
end
assert('FalseClass#&', '15.2.6.3.1') do
not FalseClass.new.&(true) and not FalseClass.new.&(false)
not false.&(true) and not false.&(false)
end
assert('FalseClass#^', '15.2.6.3.2') do
FalseClass.new.^(true) and not FalseClass.new.^(false)
false.^(true) and not false.^(false)
end
assert('FalseClass#to_s', '15.2.6.3.3') do
FalseClass.new.to_s == 'false'
false.to_s == 'false'
end
assert('FalseClass#|', '15.2.6.3.4') do
FalseClass.new.|(true) and not FalseClass.new.|(false)
false.|(true) and not false.|(false)
end
+41 -19
View File
@@ -5,6 +5,10 @@ assert('Float', '15.2.9') do
Float.class == Class
end
assert('Float superclass', '15.2.9.2') do
Float.superclass == Numeric
end
assert('Float#+', '15.2.9.3.1') do
a = 3.123456788 + 0.000000001
b = 3.123456789 + 1
@@ -22,11 +26,11 @@ assert('Float#-', '15.2.9.3.2') do
end
assert('Float#*', '15.2.9.3.3') do
a = 3.123456789 * 3.123456789
b = 3.123456789 * 1
a = 3.125 * 3.125
b = 3.125 * 1
check_float(a, 9.75598231275019) and
check_float(b, 3.123456789)
check_float(a, 9.765625) and
check_float(b, 3.125)
end
assert('Float#/', '15.2.9.3.4') do
@@ -38,19 +42,19 @@ assert('Float#/', '15.2.9.3.4') do
end
assert('Float#%', '15.2.9.3.5') do
a = 3.123456789 % 3.123456789
b = 3.123456789 % 1
a = 3.125 % 3.125
b = 3.125 % 1
check_float(a, 0.0) and
check_float(b, 0.123456789)
check_float(b, 0.125)
end
assert('Float#<=>', '15.2.9.3.6') do
a = 3.123456789 <=> 3.123456788
b = 3.123456789 <=> 3.123456789
c = 3.123456789 <=> 3.123456790
a2 = 3.123456789 <=> 3
c2 = 3.123456789 <=> 4
a = 3.125 <=> 3.123
b = 3.125 <=> 3.125
c = 3.125 <=> 3.126
a2 = 3.125 <=> 3
c2 = 3.125 <=> 4
a == 1 and b == 0 and c == -1 and
a2 == 1 and c2 == -1
@@ -61,7 +65,11 @@ assert('Float#==', '15.2.9.3.7') do
end
assert('Float#ceil', '15.2.9.3.8') do
3.123456789.ceil == 4
a = 3.123456789.ceil
b = 3.0.ceil
c = -3.123456789.ceil
d = -3.0.ceil
a == 4 and b == 3 and c == -3 and d == -3
end
assert('Float#finite?', '15.2.9.3.9') do
@@ -70,20 +78,34 @@ assert('Float#finite?', '15.2.9.3.9') do
end
assert('Float#floor', '15.2.9.3.10') do
3.123456789.floor == 3
a = 3.123456789.floor
b = 3.0.floor
c = -3.123456789.floor
d = -3.0.floor
a == 3 and b == 3 and c == -4 and d == -3
end
assert('Float#infinite?', '15.2.9.3.11') do
not 3.123456789.infinite? and
(1.0 / 0.0).infinite?
a = 3.123456789.infinite?
b = (1.0 / 0.0).infinite?
c = (-1.0 / 0.0).infinite?
a == nil and b == 1 and c == -1
end
assert('Float#round', '15.2.9.3.12') do
a = 3.123456789.round
b = 3.5.round
c = 3.499999999.round
c = 3.4999.round
d = (-3.123456789).round
e = (-3.5).round
f = 12345.67.round(-1)
g = 3.423456789.round(0)
h = 3.423456789.round(1)
i = 3.423456789.round(3)
a == 3 and b == 4 and c == 3
a == 3 and b == 4 and c == 3 and d == -3 and e == -4 and
f == 12350 and g == 3 and h == 3.4 and i == 3.423
end
assert('Float#to_f', '15.2.9.3.13') do
@@ -97,5 +119,5 @@ assert('Float#to_i', '15.2.9.3.14') do
end
assert('Float#truncate', '15.2.9.3.15') do
3.123456789.truncate == 3
3.123456789.truncate == 3 and -3.1.truncate == -3
end
+43
View File
@@ -5,6 +5,10 @@ assert('Hash', '15.2.13') do
Hash.class == Class
end
assert('Hash superclass', '15.2.13.2') do
Hash.superclass == Object
end
assert('Hash#==', '15.2.13.4.1') do
({ 'abc' => 'abc' } == { 'abc' => 'abc' }) and
not ({ 'abc' => 'abc' } == { 'cba' => 'cba' })
@@ -224,3 +228,42 @@ assert('Hash#values', '15.2.13.4.28') do
a.values == ['abc_value']
end
# Not ISO specified
assert('Hash#reject') do
h = {:one => 1, :two => 2, :three => 3, :four => 4}
ret = h.reject do |k,v|
v % 2 == 0
end
ret == {:one => 1, :three => 3} and
h == {:one => 1, :two => 2, :three => 3, :four => 4}
end
assert('Hash#reject!') do
h = {:one => 1, :two => 2, :three => 3, :four => 4}
ret = h.reject! do |k,v|
v % 2 == 0
end
ret == {:one => 1, :three => 3} and
h == {:one => 1, :three => 3}
end
assert('Hash#select') do
h = {:one => 1, :two => 2, :three => 3, :four => 4}
ret = h.select do |k,v|
v % 2 == 0
end
ret == {:two => 2, :four => 4} and
h == {:one => 1, :two => 2, :three => 3, :four => 4}
end
assert('Hash#select!') do
h = {:one => 1, :two => 2, :three => 3, :four => 4}
ret = h.select! do |k,v|
v % 2 == 0
end
ret == {:two => 2, :four => 4} and
h == {:two => 2, :four => 4}
end
+5
View File
@@ -4,3 +4,8 @@
assert('IndexError', '15.2.33') do
IndexError.class == Class
end
assert('IndexError superclass', '15.2.33.2') do
IndexError.superclass == StandardError
end
+4
View File
@@ -5,6 +5,10 @@ assert('Integer', '15.2.8') do
Integer.class == Class
end
assert('Integer superclass', '15.2.8.2') do
Integer.superclass == Numeric
end
assert('Integer#+', '15.2.8.3.1') do
a = 1+1
b = 1+1.0
+236 -25
View File
@@ -6,7 +6,21 @@ assert('Kernel', '15.3.1') do
end
assert('Kernel.block_given?', '15.3.1.2.2') do
Kernel.block_given? == false
def bg_try(&b)
if Kernel.block_given?
yield
else
"no block"
end
end
(Kernel.block_given? == false) and
# test without block
(bg_try == "no block") and
# test with block
((bg_try { "block" }) == "block") and
# test with block
((bg_try do "block" end) == "block")
end
assert('Kernel.global_variables', '15.3.1.2.4') do
@@ -22,12 +36,15 @@ assert('Kernel.lambda', '15.3.1.2.6') do
true
end
l.call and l.class == Proc
m = Kernel.lambda(&l)
l.call and l.class == Proc and m.call and m.class == Proc
end
assert('Kernel.local_variables', '15.3.1.2.7') do
Kernel.local_variables.class == Array
end
# Not implemented at the moment
#assert('Kernel.local_variables', '15.3.1.2.7') do
# Kernel.local_variables.class == Array
#end
assert('Kernel.loop', '15.3.1.2.8') do
i = 0
@@ -55,28 +72,182 @@ assert('Kernel.puts', '15.3.1.2.11') do
true
end
# TODO fails at the moment without arguments
assert('Kernel.raise', '15.3.1.2.12') do
e_list = []
begin
raise RuntimeError.new
Kernel.raise
rescue => e
e_list << e
end
e_list[0].class == RuntimeError
begin
Kernel.raise RuntimeError.new
rescue => e
e_list << e
end
# result without argument
e_list[0].class == RuntimeError and
# result with RuntimeError argument
e_list[1].class == RuntimeError
end
assert('Kernel#hash', '15.3.1.2.15') do
assert('Kernel#__id__', '15.3.1.3.3') do
__id__.class == Fixnum
end
assert('Kernel#__send__', '15.3.1.3.4') do
# test with block
l = __send__(:lambda) do
true
end
l.call and l.class == Proc and
# test with argument
__send__(:respond_to?, :nil?) and
# test without argument and without block
__send__(:public_methods).class == Array
end
assert('Kernel#block_given?', '15.3.1.3.6') do
def bg_try(&b)
if block_given?
yield
else
"no block"
end
end
(block_given? == false) and
(bg_try == "no block") and
((bg_try { "block" }) == "block") and
((bg_try do "block" end) == "block")
end
assert('Kernel#class', '15.3.1.3.7') do
Kernel.class == Module
end
assert('Kernel#clone', '15.3.1.3.8') do
class KernelCloneTest
def initialize
@v = 0
end
def get
@v
end
def set(v)
@v = v
end
end
a = KernelCloneTest.new
a.set(1)
b = a.clone
def a.test
end
a.set(2)
c = a.clone
a.get == 2 and b.get == 1 and c.get == 2 &&
a.respond_to?(:test) == true and
b.respond_to?(:test) == false and
c.respond_to?(:test) == true
end
assert('Kernel#dup', '15.3.1.3.9') do
class KernelDupTest
def initialize
@v = 0
end
def get
@v
end
def set(v)
@v = v
end
end
a = KernelDupTest.new
a.set(1)
b = a.dup
def a.test
end
a.set(2)
c = a.dup
a.get == 2 and b.get == 1 and c.get == 2 and
a.respond_to?(:test) == true and
b.respond_to?(:test) == false and
c.respond_to?(:test) == false
end
assert('Kernel#extend', '15.3.1.3.13') do
class Test4ExtendClass
end
module Test4ExtendModule
def test_method; end
end
a = Test4ExtendClass.new
a.extend(Test4ExtendModule)
b = Test4ExtendClass.new
a.respond_to?(:test_method) == true && b.respond_to?(:test_method) == false
end
assert('Kernel#global_variables', '15.3.1.3.14') do
global_variables.class == Array
end
assert('Kernel#hash', '15.3.1.3.15') do
hash == hash
end
assert('Kernel#local_variables', '15.3.1.2.28') do
local_variables.class == Array
assert('Kernel#inspect', '15.3.1.3.17') do
inspect.class == String
end
assert('Kernel#loop', '15.3.1.2.29') do
assert('Kernel#instance_variables', '15.3.1.3.23') do
instance_variables.class == Array
end
assert('Kernel#is_a?', '15.3.1.3.24') do
is_a?(Kernel) and not is_a?(Array)
end
assert('Kernel#iterator?', '15.3.1.3.25') do
iterator? == false
end
assert('Kernel#kind_of?', '15.3.1.3.26') do
kind_of?(Kernel) and not kind_of?(Array)
end
assert('Kernel#lambda', '15.3.1.3.27') do
l = lambda do
true
end
m = lambda(&l)
l.call and l.class == Proc and m.call and m.class == Proc
end
# Not implemented yet
#assert('Kernel#local_variables', '15.3.1.3.28') do
# local_variables.class == Array
#end
assert('Kernel#loop', '15.3.1.3.29') do
i = 0
loop do
@@ -87,38 +258,78 @@ assert('Kernel#loop', '15.3.1.2.29') do
i == 100
end
assert('Kernel#methods', '15.3.1.2.31') do
assert('Kernel#methods', '15.3.1.3.31') do
methods.class == Array
end
assert('Kernel#nil?', '15.3.1.2.32') do
# TODO why is Kernel nil ????
nil? == true
assert('Kernel#nil?', '15.3.1.3.32') do
nil.nil? == true
end
assert('Kernel#private_methods', '15.3.1.2.36') do
private_methods.class == Array
assert('Kernel#object_id', '15.3.1.3.33') do
object_id.class == Fixnum
end
assert('Kernel#protected_methods', '15.3.1.2.37') do
assert('Kernel#private_methods', '15.3.1.3.36') do
private_methods.class == Array
end
assert('Kernel#protected_methods', '15.3.1.3.37') do
protected_methods.class == Array
end
assert('Kernel#public_methods', '15.3.1.2.38') do
assert('Kernel#public_methods', '15.3.1.3.38') do
public_methods.class == Array
end
assert('Kernel#respond_to?', '15.3.1.2.43') do
respond_to? :nil?
assert('Kernel#raise', '15.3.1.3.40') do
e_list = []
begin
raise
rescue => e
e_list << e
end
begin
raise RuntimeError.new
rescue => e
e_list << e
end
# result without argument
e_list[0].class == RuntimeError and
# result with RuntimeError argument
e_list[1].class == RuntimeError
end
# TODO at the moment doesn't comply to ISO assert('Kernel#send', '15.3.1.2.44') do
assert('Kernel#respond_to?', '15.3.1.3.43') do
class Test4RespondTo
def test_method; end
undef test_method
end
assert('Kernel#singleton_methods', '15.3.1.2.45') do
respond_to?(:nil?) and Test4RespondTo.new.respond_to?(:test_method) == false
end
assert('Kernel#send', '15.3.1.3.44') do
# test with block
l = send(:lambda) do
true
end
l.call and l.class == Proc and
# test with argument
send(:respond_to?, :nil?) and
# test without argument and without block
send(:public_methods).class == Array
end
assert('Kernel#singleton_methods', '15.3.1.3.45') do
singleton_methods.class == Array
end
assert('Kernel#to_s', '15.3.1.2.46') do
assert('Kernel#to_s', '15.3.1.3.46') do
# TODO looks strange..
to_s == ''
end
+109 -97
View File
@@ -1,105 +1,117 @@
##
# Math Test
assert('Math.sin 0') do
check_float(Math.sin(0), 0)
end
assert('Math.sin PI/2') do
check_float(Math.sin(Math::PI / 2), 1)
end
assert('Fundamental trig identities') do
result = true
N = 15
N.times do |i|
a = Math::PI / N * i
ca = Math::PI / 2 - a
s = Math.sin(a)
c = Math.cos(a)
t = Math.tan(a)
result &= check_float(s, Math.cos(ca))
result &= check_float(t, 1 / Math.tan(ca))
result &= check_float(s ** 2 + c ** 2, 1)
result &= check_float(t ** 2 + 1, (1/c) ** 2)
result &= check_float((1/t) ** 2 + 1, (1/s) ** 2)
if Object.const_defined?(:Math)
assert('Math.sin 0') do
check_float(Math.sin(0), 0)
end
result
end
assert('Math.erf 0') do
check_float(Math.erf(0), 0)
end
assert('Math.exp 0') do
check_float(Math.exp(0), 1.0)
end
assert('Math.exp 1') do
check_float(Math.exp(1), 2.718281828459045)
end
assert('Math.exp 1.5') do
check_float(Math.exp(1.5), 4.4816890703380645)
end
assert('Math.log 1') do
check_float(Math.log(1), 0)
end
assert('Math.log E') do
check_float(Math.log(Math::E), 1.0)
end
assert('Math.log E**3') do
check_float(Math.log(Math::E**3), 3.0)
end
assert('Math.log2 1') do
check_float(Math.log2(1), 0.0)
end
assert('Math.log2 2') do
check_float(Math.log2(2), 1.0)
end
assert('Math.log10 1') do
check_float(Math.log10(1), 0.0)
end
assert('Math.log10 10') do
check_float(Math.log10(10), 1.0)
end
assert('Math.log10 10**100') do
check_float(Math.log10(10**100), 100.0)
end
assert('Math.cbrt') do
num = [-2.0, -1.0, 0.0, 1.0, 2.0]
cub = [-8, -1, 0, 1, 8]
result = true
cub.each_with_index do |v,i|
result &= check_float(Math.cbrt(v), num[i])
assert('Math.sin PI/2') do
check_float(Math.sin(Math::PI / 2), 1)
end
assert('Fundamental trig identities') do
result = true
N = 13
N.times do |i|
a = Math::PI / N * i
ca = Math::PI / 2 - a
s = Math.sin(a)
c = Math.cos(a)
t = Math.tan(a)
result &= check_float(s, Math.cos(ca))
result &= check_float(t, 1 / Math.tan(ca))
result &= check_float(s ** 2 + c ** 2, 1)
result &= check_float(t ** 2 + 1, (1/c) ** 2)
result &= check_float((1/t) ** 2 + 1, (1/s) ** 2)
end
result
end
assert('Math.erf 0') do
check_float(Math.erf(0), 0)
end
assert('Math.exp 0') do
check_float(Math.exp(0), 1.0)
end
assert('Math.exp 1') do
check_float(Math.exp(1), 2.718281828459045)
end
assert('Math.exp 1.5') do
check_float(Math.exp(1.5), 4.4816890703380645)
end
assert('Math.log 1') do
check_float(Math.log(1), 0)
end
assert('Math.log E') do
check_float(Math.log(Math::E), 1.0)
end
assert('Math.log E**3') do
check_float(Math.log(Math::E**3), 3.0)
end
assert('Math.log2 1') do
check_float(Math.log2(1), 0.0)
end
assert('Math.log2 2') do
check_float(Math.log2(2), 1.0)
end
assert('Math.log10 1') do
check_float(Math.log10(1), 0.0)
end
assert('Math.log10 10') do
check_float(Math.log10(10), 1.0)
end
assert('Math.log10 10**100') do
check_float(Math.log10(10**100), 100.0)
end
assert('Math.sqrt') do
num = [0.0, 1.0, 2.0, 3.0, 4.0]
sqr = [0, 1, 4, 9, 16]
result = true
sqr.each_with_index do |v,i|
result &= check_float(Math.sqrt(v), num[i])
end
result
end
assert('Math.cbrt') do
num = [-2.0, -1.0, 0.0, 1.0, 2.0]
cub = [-8, -1, 0, 1, 8]
result = true
cub.each_with_index do |v,i|
result &= check_float(Math.cbrt(v), num[i])
end
result
end
assert('Math.hypot') do
check_float(Math.hypot(3, 4), 5.0)
end
assert('Math.frexp 1234') do
n = 1234
fraction, exponent = Math.frexp(n)
check_float(Math.ldexp(fraction, exponent), n)
end
assert('Math.erf 1') do
check_float(Math.erf(1), 0.842700792949715)
end
assert('Math.erfc 1') do
check_float(Math.erfc(1), 0.157299207050285)
end
result
end
assert('Math.hypot') do
check_float(Math.hypot(3, 4), 5.0)
end
assert('Math.frexp 1234') do
n = 1234
fraction, exponent = Math.frexp(n)
check_float(Math.ldexp(fraction, exponent), n)
end
assert('Math.erf 1') do
check_float(Math.erf(1), 0.842700792949715)
end
assert('Math.erfc 1') do
check_float(Math.erfc(1), 0.157299207050285)
end
+99 -2
View File
@@ -5,6 +5,103 @@ assert('Module', '15.2.2') do
Module.class == Class
end
# TODO not implemented ATM assert('Module.constants', '15.2.2') do
assert('Module superclass', '15.2.2.2') do
Module.superclass == Object
end
# TODO not implemented ATM assert('Module.nesting', '15.2.2') do
# TODO not implemented ATM assert('Module.constants', '15.2.2.3.1') do
# TODO not implemented ATM assert('Module.nesting', '15.2.2.3.2') do
assert('Module#ancestors', '15.2.2.4.9') do
r = String.ancestors
r.class == Array and r.include?(String) and r.include?(Object)
end
assert('Module#append_features', '15.2.2.4.10') do
module Test4AppendFeatures
def self.append_features(mod)
Test4AppendFeatures2.const_set(:Const4AppendFeatures2, mod)
end
end
module Test4AppendFeatures2
include Test4AppendFeatures
end
Test4AppendFeatures2.const_get(:Const4AppendFeatures2) == Test4AppendFeatures2
end
assert('Module#const_defined?', '15.2.2.4.20') do
module Test4ConstDefined
Const4Test4ConstDefined = true
end
Test4ConstDefined.const_defined?(:Const4Test4ConstDefined) and
not Test4ConstDefined.const_defined?(:NotExisting)
end
assert('Module#const_get', '15.2.2.4.21') do
module Test4ConstGet
Const4Test4ConstGet = 42
end
Test4ConstGet.const_get(:Const4Test4ConstGet) == 42
end
assert('Module.const_missing', '15.2.2.4.22') do
e1 = nil
module Test4ConstMissing
def self.const_missing(sym)
42 # the answer to everything
end
end
Test4ConstMissing.const_get(:ConstDoesntExist) == 42
end
assert('Module#const_get', '15.2.2.4.23') do
module Test4ConstSet
Const4Test4ConstSet = 42
end
Test4ConstSet.const_set(:Const4Test4ConstSet, 23)
Test4ConstSet.const_get(:Const4Test4ConstSet) == 23
end
assert('Module#include', '15.2.2.4.27') do
module Test4Include
Const4Include = 42
end
module Test4Include2
include Test4Include
end
Test4Include2.const_get(:Const4Include) == 42
end
assert('Module#included', '15.2.2.4.29') do
module Test4Included
Const4Included = 42
def self.included mod
Test4Included.const_set(:Const4Included2, mod)
end
end
module Test4Included2
include Test4Included
end
Test4Included2.const_get(:Const4Included) == 42 and
Test4Included2.const_get(:Const4Included2) == Test4Included2
end
assert('Module#included_modules', '15.2.2.4.30') do
module Test4includedModules
end
module Test4includedModules2
include Test4includedModules
end
r = Test4includedModules2.included_modules
r.class == Array and r.include?(Test4includedModules)
end
+4
View File
@@ -5,6 +5,10 @@ assert('NameError', '15.2.31') do
NameError.class == Class
end
assert('NameError superclass', '15.2.31.2') do
NameError.superclass == StandardError
end
# TODO 15.2.31.2.1 NameError#name
assert('NameError#initialize', '15.2.31.2.2') do
+5
View File
@@ -11,3 +11,8 @@ assert('NoMethodError', '15.2.32') do
NoMethodError.class == Class and e2.class == NoMethodError
end
assert('NoMethodError superclass', '15.2.32.2') do
NoMethodError.superclass == NameError
end
+4
View File
@@ -5,6 +5,10 @@ assert('Numeric', '15.2.7') do
Numeric.class == Class
end
assert('Numeric superclass', '15.2.7.2') do
Numeric.superclass == Object
end
assert('Numeric#+@', '15.2.7.4.1') do
+1 == +1
end
+5
View File
@@ -4,3 +4,8 @@
assert('Object', '15.2.1') do
Object.class == Class
end
assert('Object superclass', '15.2.1.2') do
Object.superclass == BasicObject
end
+4
View File
@@ -5,6 +5,10 @@ assert('Proc', '15.2.17') do
Proc.class == Class
end
assert('Proc superclass', '15.2.17.2') do
Proc.superclass == Object
end
assert('Proc.new', '15.2.17.3.1') do
a = nil
+4
View File
@@ -5,6 +5,10 @@ assert('Range', '15.2.14') do
Range.class == Class
end
assert('Range superclass', '15.2.14.2') do
Range.superclass == Object
end
assert('Range#==', '15.2.14.4.1') do
(1..10) == (1..10) and not (1..10) == (1..100)
end
+5
View File
@@ -4,3 +4,8 @@
assert('RangeError', '15.2.26') do
RangeError.class == Class
end
assert('RangeError superclass', '15.2.26.2') do
RangeError.superclass == StandardError
end
+5
View File
@@ -4,3 +4,8 @@
assert('StandardError', '15.2.23') do
StandardError.class == Class
end
assert('StandardError superclass', '15.2.23.2') do
StandardError.superclass == Exception
end
+20 -4
View File
@@ -5,6 +5,10 @@ assert('String', '15.2.10') do
String.class == Class
end
assert('String superclass', '15.2.10.2') do
String.superclass == Object
end
assert('String#*', '15.2.10.5.1') do
'a' * 5 == 'aaaaa'
end
@@ -252,6 +256,9 @@ assert('String#slice', '15.2.10.5.34') do
d1 = 'abc'.slice(0, 0)
e1 = 'abc'.slice(1, 2)
# slice of shared string
e11 = e1.slice(0)
# args is RegExp
# TODO SEGFAULT ATM
@@ -261,16 +268,17 @@ assert('String#slice', '15.2.10.5.34') do
a == 'a' and b == 'c' and c == nil and d == nil and
a1 == nil and b1 == nil and c1 == nil and d1 == '' and
e1 == 'bc' and
e1 == 'bc' and e11 == 'b' and
a3 == 'bc' and b3 == nil
end
# TODO Broken ATM
assert('String#split', '15.2.10.5.35') do
# without RegExp behavior is actually unspecified
a = 'abc abc abc'.split
a == ['abc', 'abc', 'abc']
'abc abc abc'.split == ['abc', 'abc', 'abc'] and
'a,b,c,,d'.split(',') == ["a", "b", "c", "", "d"] and
'abc abc abc'.split(nil) == ['abc', 'abc', 'abc'] and
'abc'.split("") == ['a', 'b', 'c']
end
# TODO ATM broken assert('String#sub', '15.2.10.5.36') do
@@ -319,3 +327,11 @@ assert('String#upcase!', '15.2.10.5.43') do
a == 'ABC'
end
# Not ISO specified
assert('String interpolation (mrb_str_concat for shared strings)') do
a = "A" * 32
"#{a}:" == "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA:"
end
+67 -2
View File
@@ -1,6 +1,71 @@
##
# Struct ISO Test
assert('Struct', '15.2.18') do
Struct.class == Class
if Object.const_defined?(:Struct)
assert('Struct', '15.2.18') do
Struct.class == Class
end
assert('Struct superclass', '15.2.18.2') do
Struct.superclass == Object
end
assert('Struct.new', '15.2.18.3.1') do
c = Struct.new(:m1, :m2)
c.superclass == Struct and
c.members == [:m1,:m2]
end
assert('Struct#==', '15.2.18.4.1') do
c = Struct.new(:m1, :m2)
cc1 = c.new(1,2)
cc2 = c.new(1,2)
cc1 == cc2
end
assert('Struct#[]', '15.2.18.4.2') do
c = Struct.new(:m1, :m2)
cc = c.new(1,2)
cc[:m1] == 1 and cc["m2"] == 2
end
assert('Struct#[]=', '15.2.18.4.3') do
c = Struct.new(:m1, :m2)
cc = c.new(1,2)
cc[:m1] = 3
cc[:m1] == 3
end
assert('Struct#each', '15.2.18.4.4') do
c = Struct.new(:m1, :m2)
cc = c.new(1,2)
a = []
cc.each{|x|
a << x
}
a[0] == 1 and a[1] == 2
end
assert('Struct#each_pair', '15.2.18.4.5') do
c = Struct.new(:m1, :m2)
cc = c.new(1,2)
a = []
cc.each_pair{|k,v|
a << [k,v]
}
a[0] == [:m1, 1] and a[1] == [:m2, 2]
end
assert('Struct#members', '15.2.18.4.6') do
c = Struct.new(:m1, :m2)
cc = c.new(1,2)
cc.members == [:m1,:m2]
end
assert('Struct#select', '15.2.18.4.7') do
c = Struct.new(:m1, :m2)
cc = c.new(1,2)
cc.select{|v| v % 2 == 0} == [2]
end
end

Some files were not shown because too many files have changed in this diff Show More