mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
Merge master.
This commit is contained in:
+35
-39
@@ -5,51 +5,59 @@ on: [push, pull_request]
|
||||
jobs:
|
||||
Ubuntu-1604:
|
||||
runs-on: ubuntu-16.04
|
||||
env:
|
||||
MRUBY_CONFIG: travis_config.rb
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: apt
|
||||
run: sudo apt install ruby gperf
|
||||
- name: build and test
|
||||
run: rake -m -j4 all test
|
||||
env:
|
||||
MRUBY_CONFIG: travis_config.rb
|
||||
- name: build
|
||||
run: rake -m
|
||||
- name: test
|
||||
run: rake test
|
||||
|
||||
Ubuntu-1804-gcc:
|
||||
runs-on: ubuntu-18.04
|
||||
env:
|
||||
MRUBY_CONFIG: travis_config.rb
|
||||
CC: gcc
|
||||
CXX: g++
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: apt
|
||||
run: sudo apt install ruby gperf gcc g++
|
||||
- name: build and test
|
||||
run: rake -m -j4 all test
|
||||
env:
|
||||
MRUBY_CONFIG: travis_config.rb
|
||||
CC: gcc
|
||||
CXX: g++
|
||||
- name: build
|
||||
run: rake -m
|
||||
- name: test
|
||||
run: rake test
|
||||
|
||||
Ubuntu-1804-clang:
|
||||
runs-on: ubuntu-18.04
|
||||
env:
|
||||
MRUBY_CONFIG: travis_config.rb
|
||||
CC: clang
|
||||
CXX: clang++
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: apt
|
||||
run: sudo apt install ruby gperf
|
||||
- name: build and test
|
||||
run: rake -m -j4 all test
|
||||
env:
|
||||
MRUBY_CONFIG: travis_config.rb
|
||||
CC: clang
|
||||
CXX: clang++
|
||||
- name: build
|
||||
run: rake -m
|
||||
- name: test
|
||||
run: rake test
|
||||
|
||||
macOS:
|
||||
runs-on: macos-latest
|
||||
env:
|
||||
MRUBY_CONFIG: travis_config.rb
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: brew
|
||||
run: brew install ruby gperf
|
||||
- name: build and test
|
||||
run: rake -m -j4 all test
|
||||
env:
|
||||
MRUBY_CONFIG: travis_config.rb
|
||||
- name: build
|
||||
run: rake -m
|
||||
- name: test
|
||||
run: rake test
|
||||
|
||||
Windows-MinGW:
|
||||
runs-on: windows-latest
|
||||
@@ -57,8 +65,8 @@ jobs:
|
||||
- uses: actions/checkout@v1
|
||||
- name: chocolatey
|
||||
run: choco install -y ruby gperf
|
||||
- name: build and test
|
||||
run: rake -E '$stdout.sync=true' -j4 test
|
||||
- name: build
|
||||
run: rake -E 'STDOUT.sync=true' test
|
||||
env:
|
||||
MRUBY_CONFIG: travis_config.rb
|
||||
CFLAGS: -g -O1 -Wall -Wundef
|
||||
@@ -82,25 +90,13 @@ jobs:
|
||||
- name: Set ENV
|
||||
run: |
|
||||
echo '::set-env name=PATH::C:\tools\cygwin\bin;C:\tools\cygwin\usr\bin'
|
||||
- name: build and test
|
||||
- name: build
|
||||
shell: cmd
|
||||
run: C:\tools\cygwin\bin\ruby.exe /usr/bin/rake -m -j4 -E 'STDOUT.sync=true' test
|
||||
run: C:\tools\cygwin\bin\ruby.exe /usr/bin/rake -E 'STDOUT.sync=true' -m
|
||||
env:
|
||||
MRUBY_CONFIG: travis_config.rb
|
||||
|
||||
Windows-VC:
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: chocolatey
|
||||
run: choco install -y ruby gperf
|
||||
- name: build and test
|
||||
- name: test
|
||||
shell: cmd
|
||||
run: |
|
||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
|
||||
rake -E "STDOUT.sync=true" -m -j4 test
|
||||
run: C:\tools\cygwin\bin\ruby.exe /usr/bin/rake -E 'STDOUT.sync=true' test
|
||||
env:
|
||||
MRUBY_CONFIG: appveyor_config.rb
|
||||
# TODO(take-cheeze): Re-enable /O2
|
||||
CFLAGS: "/c /nologo /W3 /we4013 /Zi /MD /D_CRT_SECURE_NO_WARNINGS"
|
||||
CXXFLAGS: "/c /nologo /W3 /Zi /MD /EHs /D_CRT_SECURE_NO_WARNINGS"
|
||||
MRUBY_CONFIG: travis_config.rb
|
||||
|
||||
@@ -43,3 +43,4 @@ of this list.
|
||||
YAMAMOTO Masaya
|
||||
KOBAYASHI Shuji
|
||||
RIZAL Reckordp
|
||||
Rory O'Connell
|
||||
|
||||
+29
-24
@@ -1,39 +1,44 @@
|
||||
version: "{build}"
|
||||
|
||||
os: Visual Studio 2017
|
||||
|
||||
shallow_clone: true
|
||||
|
||||
environment:
|
||||
matrix:
|
||||
# Visual Studio 2017 64bit
|
||||
- visualcpp: C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat
|
||||
- job_name: Visual Studio 2019 64bit
|
||||
visualcpp: C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat
|
||||
appveyor_build_worker_image: Visual Studio 2019
|
||||
|
||||
# Visual Studio 2017 32bit
|
||||
- visualcpp: C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat
|
||||
- job_name: Visual Studio 2019 32bit
|
||||
visualcpp: C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars32.bat
|
||||
appveyor_build_worker_image: Visual Studio 2019
|
||||
|
||||
- job_name: Visual Studio 2017 64bit
|
||||
visualcpp: C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat
|
||||
appveyor_build_worker_image: Visual Studio 2017
|
||||
|
||||
- job_name: Visual Studio 2017 32bit
|
||||
visualcpp: C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars32.bat
|
||||
appveyor_build_worker_image: Visual Studio 2017
|
||||
|
||||
- job_name: Visual Studio 2015 64bit
|
||||
visualcpp: C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat
|
||||
appveyor_build_worker_image: Visual Studio 2015
|
||||
machine: x86_amd64
|
||||
|
||||
- job_name: Visual Studio 2015 32bit
|
||||
visualcpp: C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat
|
||||
appveyor_build_worker_image: Visual Studio 2015
|
||||
machine: x86
|
||||
|
||||
# Visual Studio 2015 64bit
|
||||
- visualcpp: C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat
|
||||
machine: amd64
|
||||
|
||||
# Visual Studio 2015 32bit
|
||||
- visualcpp: C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat
|
||||
machine: x86
|
||||
|
||||
# Visual Studio 2013 64bit
|
||||
- visualcpp: C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat
|
||||
machine: amd64
|
||||
|
||||
|
||||
init:
|
||||
- call "%visualcpp%" %machine%
|
||||
# For using Rubyinstaller's Ruby 2.4 64bit
|
||||
- set PATH=C:\Ruby24-x64\bin;%PATH%
|
||||
# For using Rubyins4aller's Ruby 2.6 64bit
|
||||
# 2.6 is the highest supported Ruby version across all historical
|
||||
# Visual Studio AppVeyor images. Ruby 2.7 is only on the 2019 image.
|
||||
- set PATH=C:\Ruby26-x64\bin;%PATH%
|
||||
- ruby --version
|
||||
|
||||
|
||||
build_script:
|
||||
- set MRUBY_CONFIG=appveyor_config.rb
|
||||
- rake -m
|
||||
- rake -E $stdout.sync=true test
|
||||
- rake -m -j4
|
||||
- rake -E STDOUT.sync=true test
|
||||
|
||||
@@ -21,6 +21,7 @@ struct mrb_state;
|
||||
#define MRB_EACH_OBJ_BREAK 1
|
||||
typedef int (mrb_each_object_callback)(struct mrb_state *mrb, struct RBasic *obj, void *data);
|
||||
void mrb_objspace_each_objects(struct mrb_state *mrb, mrb_each_object_callback *callback, void *data);
|
||||
mrb_int mrb_objspace_page_slot_size(void);
|
||||
MRB_API void mrb_free_context(struct mrb_state *mrb, struct mrb_context *c);
|
||||
|
||||
#ifndef MRB_GC_ARENA_SIZE
|
||||
|
||||
@@ -23,6 +23,7 @@ struct RHash {
|
||||
#define mrb_hash_ptr(v) ((struct RHash*)(mrb_ptr(v)))
|
||||
#define mrb_hash_value(p) mrb_obj_value((void*)(p))
|
||||
|
||||
mrb_int mrb_os_memsize_of_hash_table(mrb_value obj);
|
||||
MRB_API mrb_value mrb_hash_new_capa(mrb_state *mrb, mrb_int capa);
|
||||
MRB_API mrb_value mrb_ensure_hash_type(mrb_state *mrb, mrb_value hash);
|
||||
MRB_API mrb_value mrb_check_hash_type(mrb_state *mrb, mrb_value hash);
|
||||
|
||||
+5
-13
@@ -61,7 +61,6 @@ static const uint8_t __m_either[] = {0x03, 0x0c, 0x30, 0xc0};
|
||||
typedef struct kh_##name { \
|
||||
khint_t n_buckets; \
|
||||
khint_t size; \
|
||||
khint_t n_occupied; \
|
||||
uint8_t *ed_flags; \
|
||||
khkey_t *keys; \
|
||||
khval_t *vals; \
|
||||
@@ -73,7 +72,6 @@ static const uint8_t __m_either[] = {0x03, 0x0c, 0x30, 0xc0};
|
||||
void kh_clear_##name(mrb_state *mrb, kh_##name##_t *h); \
|
||||
khint_t kh_get_##name(mrb_state *mrb, kh_##name##_t *h, khkey_t key); \
|
||||
khint_t kh_put_##name(mrb_state *mrb, kh_##name##_t *h, khkey_t key, int *ret); \
|
||||
void kh_put_prepare_##name(mrb_state *mrb, kh_##name##_t *h); \
|
||||
void kh_resize_##name(mrb_state *mrb, kh_##name##_t *h, khint_t new_n_buckets); \
|
||||
void kh_del_##name(mrb_state *mrb, kh_##name##_t *h, khint_t x); \
|
||||
kh_##name##_t *kh_copy_##name(mrb_state *mrb, kh_##name##_t *h);
|
||||
@@ -103,7 +101,7 @@ kh_fill_flags(uint8_t *p, uint8_t c, size_t len)
|
||||
size_t len = sizeof(khkey_t) + (kh_is_map ? sizeof(khval_t) : 0); \
|
||||
uint8_t *p = (uint8_t*)mrb_malloc_simple(mrb, sizeof(uint8_t)*sz/4+len*sz); \
|
||||
if (!p) { return 1; } \
|
||||
h->size = h->n_occupied = 0; \
|
||||
h->size = 0; \
|
||||
h->keys = (khkey_t *)p; \
|
||||
h->vals = kh_is_map ? (khval_t *)(p+sizeof(khkey_t)*sz) : NULL; \
|
||||
h->ed_flags = p+len*sz; \
|
||||
@@ -143,7 +141,7 @@ kh_fill_flags(uint8_t *p, uint8_t c, size_t len)
|
||||
(void)mrb; \
|
||||
if (h && h->ed_flags) { \
|
||||
kh_fill_flags(h->ed_flags, 0xaa, h->n_buckets/4); \
|
||||
h->size = h->n_occupied = 0; \
|
||||
h->size = 0; \
|
||||
} \
|
||||
} \
|
||||
khint_t kh_get_##name(mrb_state *mrb, kh_##name##_t *h, khkey_t key) \
|
||||
@@ -184,16 +182,12 @@ kh_fill_flags(uint8_t *p, uint8_t c, size_t len)
|
||||
mrb_free(mrb, old_keys); \
|
||||
} \
|
||||
} \
|
||||
void kh_put_prepare_##name(mrb_state *mrb, kh_##name##_t *h) \
|
||||
{ \
|
||||
if (h->n_occupied >= khash_upper_bound(h)) { \
|
||||
kh_resize_##name(mrb, h, h->n_buckets*2); \
|
||||
} \
|
||||
} \
|
||||
khint_t kh_put_##name(mrb_state *mrb, kh_##name##_t *h, khkey_t key, int *ret) \
|
||||
{ \
|
||||
khint_t k, del_k, step = 0; \
|
||||
kh_put_prepare_##name(mrb, h); \
|
||||
if (h->size >= khash_upper_bound(h)) { \
|
||||
kh_resize_##name(mrb, h, h->n_buckets*2); \
|
||||
} \
|
||||
k = __hash_func(mrb,key) & khash_mask(h); \
|
||||
del_k = kh_end(h); \
|
||||
while (!__ac_isempty(h->ed_flags, k)) { \
|
||||
@@ -221,7 +215,6 @@ kh_fill_flags(uint8_t *p, uint8_t c, size_t len)
|
||||
h->keys[k] = key; \
|
||||
h->ed_flags[k/4] &= ~__m_empty[k%4]; \
|
||||
h->size++; \
|
||||
h->n_occupied++; \
|
||||
if (ret) *ret = 1; \
|
||||
return k; \
|
||||
} \
|
||||
@@ -256,7 +249,6 @@ kh_fill_flags(uint8_t *p, uint8_t c, size_t len)
|
||||
#define kh_destroy(name, mrb, h) kh_destroy_##name(mrb, h)
|
||||
#define kh_clear(name, mrb, h) kh_clear_##name(mrb, h)
|
||||
#define kh_resize(name, mrb, h, s) kh_resize_##name(mrb, h, s)
|
||||
#define kh_put_prepare(name, mrb, h) kh_put_prepare_##name(mrb, h)
|
||||
#define kh_put(name, mrb, h, k) kh_put_##name(mrb, h, k, NULL)
|
||||
#define kh_put2(name, mrb, h, k, r) kh_put_##name(mrb, h, k, r)
|
||||
#define kh_get(name, mrb, h, k) kh_get_##name(mrb, h, k)
|
||||
|
||||
@@ -35,6 +35,7 @@ mrb_value mrb_vm_cv_get(mrb_state*, mrb_sym);
|
||||
void mrb_vm_cv_set(mrb_state*, mrb_sym, mrb_value);
|
||||
mrb_value mrb_vm_const_get(mrb_state*, mrb_sym);
|
||||
void mrb_vm_const_set(mrb_state*, mrb_sym, mrb_value);
|
||||
mrb_int mrb_obj_iv_tbl_memsize(mrb_state*, mrb_value);
|
||||
MRB_API mrb_value mrb_const_get(mrb_state*, mrb_value, mrb_sym);
|
||||
MRB_API void mrb_const_set(mrb_state*, mrb_value, mrb_sym, mrb_value);
|
||||
MRB_API mrb_bool mrb_const_defined(mrb_state*, mrb_value, mrb_sym);
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
#include <winsock.h>
|
||||
#include <io.h>
|
||||
#include <basetsd.h>
|
||||
#define open _open
|
||||
#define close _close
|
||||
#define dup _dup
|
||||
@@ -32,6 +33,10 @@
|
||||
typedef long fsuseconds_t;
|
||||
typedef int fmode_t;
|
||||
typedef int mrb_io_read_write_size;
|
||||
#if !defined(_SSIZE_T_) && !defined(_SSIZE_T_DEFINED) && \
|
||||
!defined(__have_typedef_ssize_t)
|
||||
typedef SSIZE_T ssize_t;
|
||||
#endif
|
||||
|
||||
#ifndef O_TMPFILE
|
||||
#define O_TMPFILE O_TEMPORARY
|
||||
|
||||
@@ -2,6 +2,14 @@
|
||||
#include <mruby/gc.h>
|
||||
#include <mruby/hash.h>
|
||||
#include <mruby/class.h>
|
||||
#include <mruby/object.h>
|
||||
#include <mruby/numeric.h>
|
||||
#include <mruby/string.h>
|
||||
#include <mruby/array.h>
|
||||
#include <mruby/variable.h>
|
||||
#include <mruby/proc.h>
|
||||
#include <mruby/value.h>
|
||||
#include <mruby/range.h>
|
||||
|
||||
struct os_count_struct {
|
||||
mrb_int total;
|
||||
@@ -92,6 +100,7 @@ os_count_objects(mrb_state *mrb, mrb_value self)
|
||||
COUNT_TYPE(T_ENV);
|
||||
COUNT_TYPE(T_DATA);
|
||||
COUNT_TYPE(T_FIBER);
|
||||
COUNT_TYPE(T_ISTRUCT);
|
||||
#undef COUNT_TYPE
|
||||
default:
|
||||
type = mrb_fixnum_value(i); break;
|
||||
@@ -104,9 +113,9 @@ os_count_objects(mrb_state *mrb, mrb_value self)
|
||||
}
|
||||
|
||||
struct os_each_object_data {
|
||||
mrb_value block;
|
||||
struct RClass *target_module;
|
||||
mrb_int count;
|
||||
mrb_value block;
|
||||
};
|
||||
|
||||
static int
|
||||
@@ -121,8 +130,8 @@ os_each_object_cb(mrb_state *mrb, struct RBasic *obj, void *ud)
|
||||
|
||||
/* filter internal objects */
|
||||
switch (obj->tt) {
|
||||
case MRB_TT_ENV:
|
||||
case MRB_TT_ICLASS:
|
||||
case MRB_TT_FREE: case MRB_TT_ENV:
|
||||
case MRB_TT_BREAK: case MRB_TT_ICLASS:
|
||||
return MRB_EACH_OBJ_OK;
|
||||
default:
|
||||
break;
|
||||
@@ -158,12 +167,8 @@ os_each_object_cb(mrb_state *mrb, struct RBasic *obj, void *ud)
|
||||
static mrb_value
|
||||
os_each_object(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
mrb_value cls = mrb_nil_value();
|
||||
struct os_each_object_data d;
|
||||
mrb_get_args(mrb, "&!|C", &d.block, &cls);
|
||||
|
||||
d.target_module = mrb_nil_p(cls) ? NULL : mrb_class_ptr(cls);
|
||||
d.count = 0;
|
||||
struct os_each_object_data d = {0};
|
||||
mrb_get_args(mrb, "&!|c", &d.block, &d.target_module);
|
||||
mrb_objspace_each_objects(mrb, os_each_object_cb, &d);
|
||||
return mrb_fixnum_value(d.count);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
MRuby::Gem::Specification.new('mruby-os-memsize') do |spec|
|
||||
spec.license = 'MIT'
|
||||
spec.author = 'mruby developers'
|
||||
spec.summary = 'ObjectSpace memsize_of method'
|
||||
|
||||
spec.add_dependency('mruby-objectspace')
|
||||
spec.add_test_dependency('mruby-metaprog')
|
||||
spec.add_test_dependency('mruby-method')
|
||||
spec.add_test_dependency('mruby-fiber')
|
||||
end
|
||||
@@ -0,0 +1,242 @@
|
||||
#include <mruby.h>
|
||||
#include <mruby/gc.h>
|
||||
#include <mruby/hash.h>
|
||||
#include <mruby/class.h>
|
||||
#include <mruby/object.h>
|
||||
#include <mruby/numeric.h>
|
||||
#include <mruby/string.h>
|
||||
#include <mruby/array.h>
|
||||
#include <mruby/variable.h>
|
||||
#include <mruby/proc.h>
|
||||
#include <mruby/value.h>
|
||||
#include <mruby/range.h>
|
||||
|
||||
static mrb_int
|
||||
os_memsize_of_ivars(mrb_state* mrb, mrb_value obj)
|
||||
{
|
||||
return mrb_obj_iv_tbl_memsize(mrb, obj);
|
||||
}
|
||||
|
||||
static mrb_int
|
||||
os_memsize_of_irep(mrb_state* state, const struct mrb_irep *irep)
|
||||
{
|
||||
mrb_int size, i;
|
||||
size = (irep->slen * sizeof(mrb_sym)) +
|
||||
(irep->plen * sizeof(mrb_code)) +
|
||||
(irep->ilen * sizeof(mrb_code));
|
||||
|
||||
for(i = 0; i < irep->rlen; i++) {
|
||||
size += os_memsize_of_irep(state, irep->reps[i]);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
static mrb_int
|
||||
os_memsize_of_method(mrb_state* mrb, mrb_value method_obj)
|
||||
{
|
||||
mrb_int size;
|
||||
mrb_value proc_value = mrb_obj_iv_get(mrb, mrb_obj_ptr(method_obj),
|
||||
mrb_intern_lit(mrb, "_proc"));
|
||||
struct RProc *proc = mrb_proc_ptr(proc_value);
|
||||
|
||||
size = sizeof(struct RProc);
|
||||
if (!MRB_PROC_CFUNC_P(proc)) size += os_memsize_of_irep(mrb, proc->body.irep);
|
||||
return size;
|
||||
}
|
||||
|
||||
static mrb_bool
|
||||
obj_is_kind_of_checked(mrb_state *mrb, mrb_value obj, const char *classname)
|
||||
{
|
||||
mrb_value objclass = mrb_obj_value(mrb->object_class);
|
||||
|
||||
if (mrb_const_defined(mrb, objclass, mrb_intern_cstr(mrb, classname))) {
|
||||
struct RClass *klass = mrb_class_get(mrb, classname);
|
||||
return mrb_obj_is_kind_of(mrb, obj, klass);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static mrb_int
|
||||
os_memsize_of_object(mrb_state* mrb, mrb_value obj)
|
||||
{
|
||||
mrb_int size = 0;
|
||||
|
||||
switch(mrb_type(obj)) {
|
||||
case MRB_TT_STRING:
|
||||
size += mrb_objspace_page_slot_size();
|
||||
if (!RSTR_EMBED_P(RSTRING(obj)) && !RSTR_SHARED_P(RSTRING(obj))) {
|
||||
size += RSTRING_CAPA(obj);
|
||||
size++; /* NUL terminator */
|
||||
}
|
||||
break;
|
||||
case MRB_TT_CLASS:
|
||||
case MRB_TT_MODULE:
|
||||
case MRB_TT_SCLASS:
|
||||
case MRB_TT_ICLASS:
|
||||
size += mrb_gc_mark_mt_size(mrb, mrb_class_ptr(obj)) * sizeof(mrb_method_t);
|
||||
/* fall through */
|
||||
case MRB_TT_EXCEPTION:
|
||||
case MRB_TT_OBJECT: {
|
||||
size += mrb_objspace_page_slot_size();
|
||||
size += os_memsize_of_ivars(mrb, obj);
|
||||
if (obj_is_kind_of_checked(mrb, obj, "UnboundMethod") ||
|
||||
obj_is_kind_of_checked(mrb, obj, "Method")) {
|
||||
size += os_memsize_of_method(mrb, obj);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MRB_TT_HASH: {
|
||||
size += mrb_objspace_page_slot_size() +
|
||||
mrb_os_memsize_of_hash_table(obj);
|
||||
break;
|
||||
}
|
||||
case MRB_TT_ARRAY: {
|
||||
mrb_int len = RARRAY_LEN(obj);
|
||||
/* Arrays that do not fit within an RArray perform a heap allocation
|
||||
* storing an array of pointers to the original objects*/
|
||||
size += mrb_objspace_page_slot_size();
|
||||
if(len > MRB_ARY_EMBED_LEN_MAX) size += sizeof(mrb_value *) * len;
|
||||
break;
|
||||
}
|
||||
case MRB_TT_PROC: {
|
||||
struct RProc* proc = mrb_proc_ptr(obj);
|
||||
size += mrb_objspace_page_slot_size();
|
||||
size += MRB_ENV_LEN(proc->e.env) * sizeof(mrb_value);
|
||||
if(!MRB_PROC_CFUNC_P(proc)) size += os_memsize_of_irep(mrb, proc->body.irep);
|
||||
break;
|
||||
}
|
||||
case MRB_TT_DATA:
|
||||
size += mrb_objspace_page_slot_size();
|
||||
break;
|
||||
#ifndef MRB_WITHOUT_FLOAT
|
||||
case MRB_TT_FLOAT:
|
||||
#ifdef MRB_WORD_BOXING
|
||||
size += mrb_objspace_page_slot_size() +
|
||||
sizeof(struct RFloat);
|
||||
#endif
|
||||
break;
|
||||
#endif
|
||||
case MRB_TT_RANGE:
|
||||
#ifndef MRB_RANGE_EMBED
|
||||
size += mrb_objspace_page_slot_size() +
|
||||
sizeof(struct mrb_range_edges);
|
||||
#endif
|
||||
break;
|
||||
case MRB_TT_FIBER: {
|
||||
struct RFiber* f = (struct RFiber *)mrb_ptr(obj);
|
||||
ptrdiff_t stack_size = f->cxt->stend - f->cxt->stbase;
|
||||
ptrdiff_t ci_size = f->cxt->ciend - f->cxt->cibase;
|
||||
|
||||
size += mrb_objspace_page_slot_size() +
|
||||
sizeof(struct RFiber) +
|
||||
sizeof(struct mrb_context) +
|
||||
sizeof(struct RProc *) * f->cxt->esize +
|
||||
sizeof(uint16_t *) * f->cxt->rsize +
|
||||
sizeof(mrb_value) * stack_size +
|
||||
sizeof(mrb_callinfo) * ci_size;
|
||||
break;
|
||||
}
|
||||
case MRB_TT_ISTRUCT:
|
||||
size += mrb_objspace_page_slot_size();
|
||||
break;
|
||||
/* zero heap size types.
|
||||
* immediate VM stack values, contained within mrb_state, or on C stack */
|
||||
case MRB_TT_TRUE:
|
||||
case MRB_TT_FALSE:
|
||||
case MRB_TT_FIXNUM:
|
||||
case MRB_TT_BREAK:
|
||||
case MRB_TT_CPTR:
|
||||
case MRB_TT_SYMBOL:
|
||||
case MRB_TT_FREE:
|
||||
case MRB_TT_UNDEF:
|
||||
case MRB_TT_ENV:
|
||||
/* never used, silences compiler warning
|
||||
* not having a default: clause lets the compiler tell us when there is a new
|
||||
* TT not accounted for */
|
||||
case MRB_TT_MAXDEFINE:
|
||||
break;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* ObjectSpace.memsize_of(obj) -> Numeric
|
||||
*
|
||||
* Returns the amount of heap memory allocated for object in size_t units.
|
||||
*
|
||||
* The return value depends on the definition of size_t on that platform,
|
||||
* therefore the value is not comparable across platform types.
|
||||
*
|
||||
* Immediate values such as integers, booleans, symbols and unboxed float numbers
|
||||
* return 0. Additionally special objects which are small enough to fit inside an
|
||||
* object pointer, termed embedded objects, will return the size of the object pointer.
|
||||
* Strings and arrays below a compile-time defined size may be embedded.
|
||||
*/
|
||||
|
||||
static mrb_value
|
||||
os_memsize_of(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
mrb_int total;
|
||||
mrb_value obj;
|
||||
|
||||
mrb_get_args(mrb, "o", &obj);
|
||||
|
||||
total = os_memsize_of_object(mrb, obj);
|
||||
return mrb_fixnum_value(total);
|
||||
}
|
||||
|
||||
struct os_memsize_of_all_cb_data {
|
||||
mrb_int t;
|
||||
struct RClass *type;
|
||||
};
|
||||
|
||||
static int
|
||||
os_memsize_of_all_cb(mrb_state *mrb, struct RBasic *obj, void *d)
|
||||
{
|
||||
struct os_memsize_of_all_cb_data *data = (struct os_memsize_of_all_cb_data *)d;
|
||||
switch (obj->tt) {
|
||||
case MRB_TT_FREE: case MRB_TT_ENV:
|
||||
case MRB_TT_BREAK: case MRB_TT_ICLASS:
|
||||
/* internal objects that should not be counted */
|
||||
return MRB_EACH_OBJ_OK;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/* skip Proc objects for methods */
|
||||
if (obj->c == NULL) return 0;
|
||||
if (data->type == NULL || mrb_obj_is_kind_of(mrb, mrb_obj_value(obj), data->type))
|
||||
data->t += os_memsize_of_object(mrb, mrb_obj_value(obj));
|
||||
return MRB_EACH_OBJ_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* ObjectSpace.memsize_of_all([klass]) -> Numeric
|
||||
*
|
||||
* Return consuming memory size of all living objects of type klass.
|
||||
*
|
||||
*/
|
||||
|
||||
static mrb_value
|
||||
os_memsize_of_all(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
struct os_memsize_of_all_cb_data data = { 0 };
|
||||
mrb_get_args(mrb, "|c", &data.type);
|
||||
mrb_objspace_each_objects(mrb, os_memsize_of_all_cb, &data);
|
||||
return mrb_fixnum_value(data.t);
|
||||
}
|
||||
|
||||
void
|
||||
mrb_mruby_os_memsize_gem_init(mrb_state *mrb)
|
||||
{
|
||||
struct RClass *os = mrb_module_get(mrb, "ObjectSpace");
|
||||
mrb_define_class_method(mrb, os, "memsize_of", os_memsize_of, MRB_ARGS_REQ(1));
|
||||
mrb_define_class_method(mrb, os, "memsize_of_all", os_memsize_of_all, MRB_ARGS_OPT(1));
|
||||
}
|
||||
|
||||
void
|
||||
mrb_mruby_os_memsize_gem_final(mrb_state *mrb)
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
assert 'ObjectSpace.memsize_of' do
|
||||
# immediate literals
|
||||
int_size = ObjectSpace.memsize_of 1
|
||||
assert_equal int_size, 0, 'int zero'
|
||||
|
||||
sym_size = ObjectSpace.memsize_of :foo
|
||||
assert_equal sym_size, 0, 'sym zero'
|
||||
|
||||
assert_equal ObjectSpace.memsize_of(true), int_size
|
||||
assert_equal ObjectSpace.memsize_of(false), int_size
|
||||
|
||||
assert_not_equal ObjectSpace.memsize_of('a'), 0, 'memsize of str'
|
||||
|
||||
if __ENCODING__ == "UTF-8"
|
||||
assert_not_equal ObjectSpace.memsize_of("こんにちは世界"), 0, 'memsize of utf8 str'
|
||||
end
|
||||
|
||||
# class defs
|
||||
class_obj_size = ObjectSpace.memsize_of Class
|
||||
assert_not_equal class_obj_size, 0, 'Class obj not zero'
|
||||
|
||||
empty_class_def_size = ObjectSpace.memsize_of Class.new
|
||||
assert_not_equal empty_class_def_size, 0, 'Class def not zero'
|
||||
|
||||
proc_size = ObjectSpace.memsize_of Proc.new { x = 1; x }
|
||||
assert_not_equal proc_size, 0
|
||||
|
||||
class_with_methods = Class.new do
|
||||
def foo
|
||||
a = 0
|
||||
a + 1
|
||||
end
|
||||
end
|
||||
|
||||
m_size = ObjectSpace.memsize_of class_with_methods.instance_method(:foo)
|
||||
assert_not_equal m_size, 0, 'method size not zero'
|
||||
|
||||
# collections
|
||||
empty_array_size = ObjectSpace.memsize_of []
|
||||
assert_not_equal empty_array_size, 0, 'empty array size not zero'
|
||||
assert_operator empty_array_size, :<, ObjectSpace.memsize_of(Array.new(16)), 'large array size greater than embed'
|
||||
|
||||
# fiber
|
||||
empty_fiber_size = ObjectSpace.memsize_of(Fiber.new {})
|
||||
assert_not_equal empty_fiber_size, 0, 'empty fiber not zero'
|
||||
|
||||
#hash
|
||||
assert_not_equal ObjectSpace.memsize_of({}), 0, 'empty hash size not zero'
|
||||
end
|
||||
|
||||
assert 'ObjectSpace.memsize_of_all' do
|
||||
foo_class = Class.new do
|
||||
def initialize
|
||||
@a = 'a'
|
||||
@b = 'b'
|
||||
end
|
||||
end
|
||||
|
||||
foos = Array.new(10) { foo_class.new }
|
||||
foo_size = ObjectSpace.memsize_of(foos.first)
|
||||
|
||||
assert_equal ObjectSpace.memsize_of_all(foo_class), foo_size * foos.size, 'Memsize of all instance'
|
||||
end
|
||||
@@ -1298,7 +1298,8 @@ mrb_pack_pack(mrb_state *mrb, mrb_value ary)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (dir == PACK_DIR_STR || dir == PACK_DIR_BASE64) { /* always consumes 1 entry */
|
||||
if (dir == PACK_DIR_STR || dir == PACK_DIR_BASE64 || dir == PACK_DIR_HEX) {
|
||||
/* always consumes 1 entry */
|
||||
aidx++;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -3,39 +3,10 @@
|
||||
#
|
||||
# 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
|
||||
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
|
||||
s = args[i].to_s
|
||||
__printstr__ s
|
||||
__printstr__ "\n" if (s[-1] != "\n")
|
||||
i += 1
|
||||
end
|
||||
__printstr__ "\n" if len == 0
|
||||
nil
|
||||
end
|
||||
|
||||
##
|
||||
# Print human readable object description
|
||||
#
|
||||
# ISO 15.3.1.2.9
|
||||
# ISO 15.3.1.3.34
|
||||
def p(*args)
|
||||
i = 0
|
||||
|
||||
@@ -17,39 +17,73 @@
|
||||
#endif
|
||||
|
||||
static void
|
||||
printstr(mrb_state *mrb, mrb_value obj)
|
||||
printstr(mrb_state *mrb, const char *p, size_t len)
|
||||
{
|
||||
if (mrb_string_p(obj)) {
|
||||
#if defined(_WIN32)
|
||||
if (isatty(fileno(stdout))) {
|
||||
DWORD written;
|
||||
int mlen = (int)RSTRING_LEN(obj);
|
||||
char* utf8 = RSTRING_PTR(obj);
|
||||
int wlen = MultiByteToWideChar(CP_UTF8, 0, utf8, mlen, NULL, 0);
|
||||
wchar_t* utf16 = (wchar_t*)mrb_malloc(mrb, (wlen+1) * sizeof(wchar_t));
|
||||
if (MultiByteToWideChar(CP_UTF8, 0, utf8, mlen, utf16, wlen) > 0) {
|
||||
utf16[wlen] = 0;
|
||||
WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE),
|
||||
utf16, wlen, &written, NULL);
|
||||
}
|
||||
mrb_free(mrb, utf16);
|
||||
} else
|
||||
if (isatty(fileno(stdout))) {
|
||||
DWORD written;
|
||||
int wlen = MultiByteToWideChar(CP_UTF8, 0, p, len, NULL, 0);
|
||||
wchar_t* utf16 = (wchar_t*)mrb_malloc(mrb, (wlen+1) * sizeof(wchar_t));
|
||||
if (MultiByteToWideChar(CP_UTF8, 0, p, len, utf16, wlen) > 0) {
|
||||
utf16[wlen] = 0;
|
||||
WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE),
|
||||
utf16, wlen, &written, NULL);
|
||||
}
|
||||
mrb_free(mrb, utf16);
|
||||
} else
|
||||
#endif
|
||||
fwrite(RSTRING_PTR(obj), RSTRING_LEN(obj), 1, stdout);
|
||||
fflush(stdout);
|
||||
}
|
||||
fwrite(p, len, 1, stdout);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
/* 15.3.1.2.9 */
|
||||
/* 15.3.1.3.34 */
|
||||
mrb_value
|
||||
static mrb_value
|
||||
mrb_printstr(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
mrb_value argv = mrb_get_arg1(mrb);
|
||||
mrb_value s = mrb_get_arg1(mrb);
|
||||
|
||||
printstr(mrb, argv);
|
||||
if (mrb_string_p(s)) {
|
||||
printstr(mrb, RSTRING_PTR(s), RSTRING_LEN(s));
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
return argv;
|
||||
/* 15.3.1.2.10 */
|
||||
/* 15.3.1.3.35 */
|
||||
static mrb_value
|
||||
mrb_print(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
mrb_int argc, i;
|
||||
mrb_value *argv;
|
||||
|
||||
mrb_get_args(mrb, "*", &argv, &argc);
|
||||
for (i=0; i<argc; i++) {
|
||||
mrb_value s = mrb_str_to_str(mrb, argv[i]);
|
||||
printstr(mrb, RSTRING_PTR(s), RSTRING_LEN(s));
|
||||
}
|
||||
return mrb_nil_value();
|
||||
}
|
||||
|
||||
/* 15.3.1.2.11 */
|
||||
/* 15.3.1.3.39 */
|
||||
static mrb_value
|
||||
mrb_puts(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
mrb_int argc, i;
|
||||
mrb_value *argv;
|
||||
|
||||
mrb_get_args(mrb, "*", &argv, &argc);
|
||||
for (i=0; i<argc; i++) {
|
||||
mrb_value s = mrb_str_to_str(mrb, argv[i]);
|
||||
mrb_int len = RSTRING_LEN(s);
|
||||
printstr(mrb, RSTRING_PTR(s), len);
|
||||
if (len == 0 || RSTRING_PTR(s)[len-1] != '\n') {
|
||||
printstr(mrb, "\n", 1);
|
||||
}
|
||||
}
|
||||
if (argc == 0) {
|
||||
printstr(mrb, "\n", 1);
|
||||
}
|
||||
return mrb_nil_value();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -58,6 +92,8 @@ mrb_mruby_print_gem_init(mrb_state* mrb)
|
||||
struct RClass *krn;
|
||||
krn = mrb->kernel_module;
|
||||
mrb_define_method(mrb, krn, "__printstr__", mrb_printstr, MRB_ARGS_REQ(1));
|
||||
mrb_define_method(mrb, krn, "print", mrb_print, MRB_ARGS_ANY());
|
||||
mrb_define_method(mrb, krn, "puts", mrb_puts, MRB_ARGS_ANY());
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -218,6 +218,34 @@ mrb_ary_shuffle_bang(mrb_state *mrb, mrb_value ary)
|
||||
mrb_value r = mrb_nil_value();
|
||||
rand_state *random;
|
||||
|
||||
/*
|
||||
* MSC compiler bug generating invalid instructions with optimization
|
||||
* enabled. MSC errantly uses a hardcoded value with optimizations on
|
||||
* when using a fixed value from a union.
|
||||
* Creating a temp volatile variable and reassigning back to the original
|
||||
* value tricks the compiler to not perform this optimization;
|
||||
*/
|
||||
#if defined _MSC_VER && _MSC_VER >= 1923
|
||||
/* C++ will not cast away volatile easily, so we cannot do something like
|
||||
* volatile mrb_value rr = r; r = (mrb_value)rr; with C++.
|
||||
* That cast does work with C.
|
||||
* We also have to trick the compiler to not optimize away the const_cast entirely
|
||||
* by creating and manipulating an intermediate volatile pointer.
|
||||
*/
|
||||
volatile mrb_value *v_r;
|
||||
volatile mrb_int ii;
|
||||
mrb_value *p_r;
|
||||
v_r = &r;
|
||||
ii = 2;
|
||||
v_r = v_r + 2;
|
||||
#if defined __cplusplus
|
||||
p_r = const_cast<mrb_value*>(v_r - ii);
|
||||
#else
|
||||
p_r = (mrb_value*)v_r - ii;
|
||||
#endif
|
||||
r = *p_r;
|
||||
#endif
|
||||
|
||||
if (RARRAY_LEN(ary) > 1) {
|
||||
mrb_get_args(mrb, "|o", &r);
|
||||
|
||||
|
||||
@@ -146,20 +146,8 @@ MRuby::Gem::Specification.new('mruby-test') do |spec|
|
||||
end
|
||||
end
|
||||
|
||||
# store the last gem selection and make the re-build
|
||||
# of the test gem depending on a change to the gem
|
||||
# selection
|
||||
active_gems_path = "#{build_dir}/active_gems_path.lst"
|
||||
active_gem_list = File.read active_gems_path if File.exist? active_gems_path
|
||||
current_gem_list = build.gems.map(&:name).join("\n")
|
||||
task active_gems_path do |_t|
|
||||
mkdir_p File.dirname(active_gems_path)
|
||||
File.write active_gems_path, current_gem_list
|
||||
end
|
||||
file clib => active_gems_path if active_gem_list != current_gem_list
|
||||
|
||||
file mlib => clib
|
||||
file clib => [build.mrbcfile, __FILE__] do |_t|
|
||||
file clib => ["#{build.build_dir}/mrbgems/active_gems.txt", build.mrbcfile, __FILE__] do |_t|
|
||||
_pp "GEN", "*.rb", "#{clib.relative_path}"
|
||||
mkdir_p File.dirname(clib)
|
||||
open(clib, 'w') do |f|
|
||||
|
||||
+5
-1
@@ -12,7 +12,7 @@ class Array
|
||||
# ISO 15.2.12.5.10
|
||||
# def each(&block)
|
||||
# return to_enum :each unless block
|
||||
|
||||
#
|
||||
# idx = 0
|
||||
# while idx < length
|
||||
# block.call(self[idx])
|
||||
@@ -268,4 +268,8 @@ class Array
|
||||
def sort(&block)
|
||||
self.dup.sort!(&block)
|
||||
end
|
||||
|
||||
def to_a
|
||||
self
|
||||
end
|
||||
end
|
||||
|
||||
+5
-3
@@ -522,8 +522,10 @@ mrb_ary_push_m(mrb_state *mrb, mrb_value self)
|
||||
}
|
||||
array_copy(ARY_PTR(a)+len, argv, alen);
|
||||
ARY_SET_LEN(a, len2);
|
||||
mrb_write_barrier(mrb, (struct RBasic*)a);
|
||||
|
||||
while (alen--) {
|
||||
mrb_field_write_barrier_value(mrb, (struct RBasic*)a, *argv);
|
||||
argv++;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@@ -941,7 +943,7 @@ mrb_ary_aset(mrb_state *mrb, mrb_value self)
|
||||
mrb_value v1, v2, v3;
|
||||
mrb_int i, len;
|
||||
|
||||
mrb_ary_modify(mrb, mrb_ary_ptr(self));
|
||||
ary_modify(mrb, mrb_ary_ptr(self));
|
||||
if (mrb_get_argc(mrb) == 2) {
|
||||
mrb_value *vs = mrb_get_argv(mrb);
|
||||
v1 = vs[0]; v2 = vs[1];
|
||||
|
||||
+23
-6
@@ -587,6 +587,7 @@ void mrb_hash_check_kdict(mrb_state *mrb, mrb_value self);
|
||||
s: String [char*,mrb_int] Receive two arguments; s! gives (NULL,0) for nil
|
||||
z: String [char*] NUL terminated string; z! gives NULL for nil
|
||||
a: Array [mrb_value*,mrb_int] Receive two arguments; a! gives (NULL,0) for nil
|
||||
c: Class/Module [strcut RClass*]
|
||||
f: Fixnum/Float [mrb_float]
|
||||
i: Fixnum/Float [mrb_int]
|
||||
b: boolean [mrb_bool]
|
||||
@@ -713,6 +714,22 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'c':
|
||||
{
|
||||
struct RClass **p;
|
||||
|
||||
p = va_arg(ap, struct RClass**);
|
||||
if (i < argc) {
|
||||
mrb_value ss;
|
||||
|
||||
ss = argv[i++];
|
||||
if (!class_ptr_p(ss)) {
|
||||
mrb_raisef(mrb, E_TYPE_ERROR, "%v is not class/module", ss);
|
||||
}
|
||||
*p = mrb_class_ptr(ss);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'S':
|
||||
{
|
||||
mrb_value *p;
|
||||
@@ -1151,22 +1168,22 @@ mrb_prepend_module(mrb_state *mrb, struct RClass *c, struct RClass *m)
|
||||
static mrb_value
|
||||
mrb_mod_prepend_features(mrb_state *mrb, mrb_value mod)
|
||||
{
|
||||
mrb_value klass;
|
||||
struct RClass *c;
|
||||
|
||||
mrb_check_type(mrb, mod, MRB_TT_MODULE);
|
||||
mrb_get_args(mrb, "C", &klass);
|
||||
mrb_prepend_module(mrb, mrb_class_ptr(klass), mrb_class_ptr(mod));
|
||||
mrb_get_args(mrb, "c", &c);
|
||||
mrb_prepend_module(mrb, c, mrb_class_ptr(mod));
|
||||
return mod;
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
mrb_mod_append_features(mrb_state *mrb, mrb_value mod)
|
||||
{
|
||||
mrb_value klass;
|
||||
struct RClass *c;
|
||||
|
||||
mrb_check_type(mrb, mod, MRB_TT_MODULE);
|
||||
mrb_get_args(mrb, "C", &klass);
|
||||
mrb_include_module(mrb, mrb_class_ptr(klass), mrb_class_ptr(mod));
|
||||
mrb_get_args(mrb, "c", &c);
|
||||
mrb_include_module(mrb, c, mrb_class_ptr(mod));
|
||||
return mod;
|
||||
}
|
||||
|
||||
|
||||
@@ -107,10 +107,11 @@ mrb_obj_id(mrb_value obj)
|
||||
return MakeID(0); /* not define */
|
||||
case MRB_TT_FALSE:
|
||||
if (mrb_nil_p(obj))
|
||||
return MakeID(1);
|
||||
return MakeID(0);
|
||||
return MakeID(4);
|
||||
else
|
||||
return MakeID(0);
|
||||
case MRB_TT_TRUE:
|
||||
return MakeID(1);
|
||||
return MakeID(2);
|
||||
case MRB_TT_SYMBOL:
|
||||
return MakeID(mrb_symbol(obj));
|
||||
case MRB_TT_FIXNUM:
|
||||
|
||||
@@ -225,14 +225,8 @@ mrb_realloc(mrb_state *mrb, void *p, size_t len)
|
||||
p2 = mrb_realloc_simple(mrb, p, len);
|
||||
if (len == 0) return p2;
|
||||
if (p2 == NULL) {
|
||||
if (mrb->gc.out_of_memory) {
|
||||
mrb_raise_nomemory(mrb);
|
||||
/* mrb_panic(mrb); */
|
||||
}
|
||||
else {
|
||||
mrb->gc.out_of_memory = TRUE;
|
||||
mrb_raise_nomemory(mrb);
|
||||
}
|
||||
mrb->gc.out_of_memory = TRUE;
|
||||
mrb_raise_nomemory(mrb);
|
||||
}
|
||||
else {
|
||||
mrb->gc.out_of_memory = FALSE;
|
||||
@@ -673,7 +667,6 @@ gc_mark_children(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj)
|
||||
{
|
||||
mrb_assert(is_gray(obj));
|
||||
paint_black(obj);
|
||||
gc->gray_list = obj->gcnext;
|
||||
mrb_gc_mark(mrb, (struct RBasic*)obj->c);
|
||||
switch (obj->tt) {
|
||||
case MRB_TT_ICLASS:
|
||||
@@ -737,10 +730,11 @@ gc_mark_children(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj)
|
||||
case MRB_TT_ARRAY:
|
||||
{
|
||||
struct RArray *a = (struct RArray*)obj;
|
||||
size_t i, e;
|
||||
size_t i, e=ARY_LEN(a);
|
||||
mrb_value *p = ARY_PTR(a);
|
||||
|
||||
for (i=0,e=ARY_LEN(a); i<e; i++) {
|
||||
mrb_gc_mark_value(mrb, ARY_PTR(a)[i]);
|
||||
for (i=0; i<e; i++) {
|
||||
mrb_gc_mark_value(mrb, p[i]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -1049,10 +1043,9 @@ gc_gray_counts(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj)
|
||||
static void
|
||||
gc_mark_gray_list(mrb_state *mrb, mrb_gc *gc) {
|
||||
while (gc->gray_list) {
|
||||
if (is_gray(gc->gray_list))
|
||||
gc_mark_children(mrb, gc, gc->gray_list);
|
||||
else
|
||||
gc->gray_list = gc->gray_list->gcnext;
|
||||
struct RBasic *obj = gc->gray_list;
|
||||
gc->gray_list = obj->gcnext;
|
||||
gc_mark_children(mrb, gc, obj);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1064,6 +1057,7 @@ incremental_marking_phase(mrb_state *mrb, mrb_gc *gc, size_t limit)
|
||||
|
||||
while (gc->gray_list && tried_marks < limit) {
|
||||
struct RBasic *obj = gc->gray_list;
|
||||
gc->gray_list = obj->gcnext;
|
||||
gc_mark_children(mrb, gc, obj);
|
||||
tried_marks += gc_gray_counts(mrb, gc, obj);
|
||||
}
|
||||
@@ -1082,7 +1076,9 @@ final_marking_phase(mrb_state *mrb, mrb_gc *gc)
|
||||
}
|
||||
mrb_gc_mark_gv(mrb);
|
||||
mark_context(mrb, mrb->c);
|
||||
mark_context(mrb, mrb->root_c);
|
||||
if (mrb->c != mrb->root_c) {
|
||||
mark_context(mrb, mrb->root_c);
|
||||
}
|
||||
mrb_gc_mark(mrb, (struct RBasic*)mrb->exc);
|
||||
gc_mark_gray_list(mrb, gc);
|
||||
mrb_assert(gc->gray_list == NULL);
|
||||
@@ -1605,6 +1601,13 @@ mrb_objspace_each_objects(mrb_state *mrb, mrb_each_object_callback *callback, vo
|
||||
}
|
||||
}
|
||||
|
||||
mrb_int
|
||||
mrb_objspace_page_slot_size(void)
|
||||
{
|
||||
const mrb_int i = sizeof(RVALUE);
|
||||
return i;
|
||||
}
|
||||
|
||||
#ifdef GC_TEST
|
||||
#ifdef GC_DEBUG
|
||||
static mrb_value gc_test(mrb_state *, mrb_value);
|
||||
|
||||
+22
-2
@@ -174,6 +174,11 @@ ht_index(mrb_state *mrb, htable *t)
|
||||
segment *seg;
|
||||
size_t i;
|
||||
|
||||
if (size == 0) {
|
||||
t->index = NULL;
|
||||
mrb_free(mrb, index);
|
||||
return;
|
||||
}
|
||||
/* allocate index table */
|
||||
if (index && index->size >= UPPER_BOUND(index->capa)) {
|
||||
size = index->capa+1;
|
||||
@@ -194,7 +199,7 @@ ht_index(mrb_state *mrb, htable *t)
|
||||
index->table[i] = NULL;
|
||||
}
|
||||
|
||||
/* rebuld index */
|
||||
/* rebuild index */
|
||||
mask = HT_MASK(index);
|
||||
seg = t->rootseg;
|
||||
while (seg) {
|
||||
@@ -518,6 +523,20 @@ ht_foreach(mrb_state *mrb, htable *t, mrb_hash_foreach_func *func, void *p)
|
||||
}
|
||||
}
|
||||
|
||||
mrb_int
|
||||
mrb_os_memsize_of_hash_table(mrb_value obj)
|
||||
{
|
||||
struct htable *h = mrb_hash_ptr(obj)->ht;
|
||||
mrb_int segkv_size = 0;
|
||||
|
||||
if(h->index) segkv_size = (sizeof(struct segkv) * h->index->capa);
|
||||
|
||||
return sizeof(htable) +
|
||||
sizeof(segindex) +
|
||||
(sizeof(segment) * h->size) +
|
||||
segkv_size;
|
||||
}
|
||||
|
||||
/* Iterates over the hash table. */
|
||||
MRB_API void
|
||||
mrb_hash_foreach(mrb_state *mrb, struct RHash *hash, mrb_hash_foreach_func *func, void *p)
|
||||
@@ -1053,7 +1072,8 @@ mrb_hash_shift(mrb_state *mrb, mrb_value hash)
|
||||
|
||||
mrb_hash_modify(mrb, hash);
|
||||
if (t && t->size > 0) {
|
||||
mrb_value del_key, del_val;
|
||||
mrb_value del_key = mrb_nil_value();
|
||||
mrb_value del_val = mrb_nil_value();
|
||||
|
||||
ht_shift(mrb, t, &del_key, &del_val);
|
||||
mrb_gc_protect(mrb, del_key);
|
||||
|
||||
+38
-16
@@ -99,6 +99,18 @@ mrb_obj_id_m(mrb_state *mrb, mrb_value self)
|
||||
return mrb_fixnum_value(mrb_obj_id(self));
|
||||
}
|
||||
|
||||
static int
|
||||
env_bidx(struct REnv *e)
|
||||
{
|
||||
int bidx;
|
||||
|
||||
/* use saved block arg position */
|
||||
bidx = MRB_ENV_BIDX(e);
|
||||
/* bidx may be useless (e.g. define_method) */
|
||||
if (bidx >= MRB_ENV_LEN(e)) return -1;
|
||||
return bidx;
|
||||
}
|
||||
|
||||
/* 15.3.1.2.2 */
|
||||
/* 15.3.1.2.5 */
|
||||
/* 15.3.1.3.6 */
|
||||
@@ -129,6 +141,8 @@ mrb_f_block_given_p_m(mrb_state *mrb, mrb_value self)
|
||||
mrb_callinfo *ci = &mrb->c->ci[-1];
|
||||
mrb_callinfo *cibase = mrb->c->cibase;
|
||||
mrb_value *bp;
|
||||
int bidx;
|
||||
struct REnv *e = NULL;
|
||||
struct RProc *p;
|
||||
|
||||
if (ci <= cibase) {
|
||||
@@ -139,29 +153,36 @@ mrb_f_block_given_p_m(mrb_state *mrb, mrb_value self)
|
||||
/* search method/class/module proc */
|
||||
while (p) {
|
||||
if (MRB_PROC_SCOPE_P(p)) break;
|
||||
e = MRB_PROC_ENV(p);
|
||||
p = p->upper;
|
||||
}
|
||||
if (p == NULL) return mrb_false_value();
|
||||
if (e) {
|
||||
bidx = env_bidx(e);
|
||||
if (bidx < 0) return mrb_false_value();
|
||||
bp = &e->stack[bidx];
|
||||
goto block_given;
|
||||
}
|
||||
/* search ci corresponding to proc */
|
||||
while (cibase < ci) {
|
||||
if (ci->proc == p) break;
|
||||
ci--;
|
||||
}
|
||||
if (ci == cibase) {
|
||||
return mrb_false_value();
|
||||
/* proc is closure */
|
||||
if (!MRB_PROC_ENV_P(p)) return mrb_false_value();
|
||||
e = MRB_PROC_ENV(p);
|
||||
bidx = env_bidx(e);
|
||||
if (bidx < 0) return mrb_false_value();
|
||||
bp = &e->stack[bidx];
|
||||
}
|
||||
else if (ci->env) {
|
||||
struct REnv *e = ci->env;
|
||||
int bidx;
|
||||
|
||||
e = ci->env;
|
||||
/* top-level does not have block slot (always false) */
|
||||
if (e->stack == mrb->c->stbase)
|
||||
return mrb_false_value();
|
||||
/* use saved block arg position */
|
||||
bidx = MRB_ENV_BIDX(e);
|
||||
if (e->stack == mrb->c->stbase) return mrb_false_value();
|
||||
bidx = env_bidx(e);
|
||||
/* bidx may be useless (e.g. define_method) */
|
||||
if (bidx >= MRB_ENV_LEN(e))
|
||||
return mrb_false_value();
|
||||
if (bidx < 0) return mrb_false_value();
|
||||
bp = &e->stack[bidx];
|
||||
}
|
||||
else {
|
||||
@@ -173,6 +194,7 @@ mrb_f_block_given_p_m(mrb_state *mrb, mrb_value self)
|
||||
bp++;
|
||||
}
|
||||
}
|
||||
block_given:
|
||||
if (mrb_nil_p(*bp))
|
||||
return mrb_false_value();
|
||||
return mrb_true_value();
|
||||
@@ -498,11 +520,11 @@ mrb_obj_is_instance_of(mrb_state *mrb, mrb_value obj, struct RClass* c)
|
||||
static mrb_value
|
||||
obj_is_instance_of(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
mrb_value arg;
|
||||
struct RClass *c;
|
||||
|
||||
mrb_get_args(mrb, "C", &arg);
|
||||
mrb_get_args(mrb, "c", &c);
|
||||
|
||||
return mrb_bool_value(mrb_obj_is_instance_of(mrb, self, mrb_class_ptr(arg)));
|
||||
return mrb_bool_value(mrb_obj_is_instance_of(mrb, self, c));
|
||||
}
|
||||
|
||||
/* 15.3.1.3.24 */
|
||||
@@ -535,11 +557,11 @@ obj_is_instance_of(mrb_state *mrb, mrb_value self)
|
||||
static mrb_value
|
||||
mrb_obj_is_kind_of_m(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
mrb_value arg;
|
||||
struct RClass *c;
|
||||
|
||||
mrb_get_args(mrb, "C", &arg);
|
||||
mrb_get_args(mrb, "c", &c);
|
||||
|
||||
return mrb_bool_value(mrb_obj_is_kind_of(mrb, self, mrb_class_ptr(arg)));
|
||||
return mrb_bool_value(mrb_obj_is_kind_of(mrb, self, c));
|
||||
}
|
||||
|
||||
KHASH_DECLARE(st, mrb_sym, char, FALSE)
|
||||
|
||||
@@ -338,6 +338,7 @@ mrb_convert_type(mrb_state *mrb, mrb_value val, enum mrb_vtype type, const char
|
||||
if (mrb_type(val) == type) return val;
|
||||
v = convert_type(mrb, val, tname, method, TRUE);
|
||||
if (mrb_type(v) != type) {
|
||||
if (type == MRB_TT_STRING) return mrb_any_to_s(mrb, val);
|
||||
mrb_raisef(mrb, E_TYPE_ERROR, "%v cannot be converted to %s by #%s", val, tname, method);
|
||||
}
|
||||
return v;
|
||||
|
||||
@@ -164,8 +164,6 @@ mrb_irep_free(mrb_state *mrb, mrb_irep *irep)
|
||||
mrb_free(mrb, irep);
|
||||
}
|
||||
|
||||
void mrb_free_backtrace(mrb_state *mrb);
|
||||
|
||||
MRB_API void
|
||||
mrb_free_context(mrb_state *mrb, struct mrb_context *c)
|
||||
{
|
||||
|
||||
@@ -1121,6 +1121,7 @@ mrb_str_to_str(mrb_state *mrb, mrb_value str)
|
||||
return mrb_sym_str(mrb, mrb_symbol(str));
|
||||
case MRB_TT_FIXNUM:
|
||||
return mrb_fixnum_to_str(mrb, str, 10);
|
||||
case MRB_TT_SCLASS:
|
||||
case MRB_TT_CLASS:
|
||||
case MRB_TT_MODULE:
|
||||
return mrb_mod_to_s(mrb, str);
|
||||
|
||||
+18
-3
@@ -349,7 +349,7 @@ mrb_obj_iv_set_force(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value
|
||||
obj->iv = iv_new(mrb);
|
||||
}
|
||||
iv_put(mrb, obj->iv, sym, v);
|
||||
mrb_write_barrier(mrb, (struct RBasic*)obj);
|
||||
mrb_field_write_barrier_value(mrb, (struct RBasic*)obj, v);
|
||||
}
|
||||
|
||||
MRB_API void
|
||||
@@ -679,7 +679,7 @@ mrb_mod_cv_set(mrb_state *mrb, struct RClass *c, mrb_sym sym, mrb_value v)
|
||||
if (iv_get(mrb, t, sym, NULL)) {
|
||||
mrb_check_frozen(mrb, c);
|
||||
iv_put(mrb, t, sym, v);
|
||||
mrb_write_barrier(mrb, (struct RBasic*)c);
|
||||
mrb_field_write_barrier_value(mrb, (struct RBasic*)c, v);
|
||||
return;
|
||||
}
|
||||
c = c->super;
|
||||
@@ -711,7 +711,7 @@ mrb_mod_cv_set(mrb_state *mrb, struct RClass *c, mrb_sym sym, mrb_value v)
|
||||
}
|
||||
|
||||
iv_put(mrb, c->iv, sym, v);
|
||||
mrb_write_barrier(mrb, (struct RBasic*)c);
|
||||
mrb_field_write_barrier_value(mrb, (struct RBasic*)c, v);
|
||||
}
|
||||
|
||||
MRB_API void
|
||||
@@ -1128,6 +1128,21 @@ mrb_class_find_path(mrb_state *mrb, struct RClass *c)
|
||||
return path;
|
||||
}
|
||||
|
||||
mrb_int
|
||||
mrb_obj_iv_tbl_memsize(mrb_state* mrb, mrb_value obj)
|
||||
{
|
||||
size_t nseg = 0;
|
||||
segment *seg;
|
||||
|
||||
if (mrb_obj_ptr(obj)->iv == NULL) return 0;
|
||||
seg = mrb_obj_ptr(obj)->iv->rootseg;
|
||||
while (seg) {
|
||||
nseg++;
|
||||
seg = seg->next;
|
||||
}
|
||||
return sizeof(iv_tbl) + sizeof(segment)*nseg;
|
||||
}
|
||||
|
||||
#define identchar(c) (ISALNUM(c) || (c) == '_' || !ISASCII(c))
|
||||
|
||||
mrb_bool
|
||||
|
||||
@@ -269,14 +269,13 @@ top_proc(mrb_state *mrb, struct RProc *proc)
|
||||
#define CI_ACC_RESUMED -3
|
||||
|
||||
static inline mrb_callinfo*
|
||||
cipush(mrb_state *mrb)
|
||||
cipush(mrb_state *mrb, const mrb_code *pc, int push_stacks, int acc,
|
||||
struct RClass *target_class, struct RProc *proc, mrb_sym mid, int argc)
|
||||
{
|
||||
struct mrb_context *c = mrb->c;
|
||||
static const mrb_callinfo ci_zero = { 0 };
|
||||
mrb_callinfo *ci = c->ci;
|
||||
|
||||
int ridx = ci->ridx;
|
||||
|
||||
if (ci + 1 == c->ciend) {
|
||||
ptrdiff_t size = ci - c->cibase;
|
||||
|
||||
@@ -286,8 +285,16 @@ cipush(mrb_state *mrb)
|
||||
}
|
||||
ci = ++c->ci;
|
||||
*ci = ci_zero;
|
||||
ci->epos = mrb->c->eidx;
|
||||
ci->ridx = ridx;
|
||||
ci->mid = mid;
|
||||
ci->proc = proc;
|
||||
ci->stackent = c->stack;
|
||||
ci->epos = c->eidx;
|
||||
ci->ridx = ci[-1].ridx;
|
||||
ci->pc = pc;
|
||||
ci->argc = argc;
|
||||
ci->acc = acc;
|
||||
ci->target_class = target_class;
|
||||
c->stack += push_stacks;
|
||||
|
||||
return ci;
|
||||
}
|
||||
@@ -313,14 +320,16 @@ mrb_env_unshare(mrb_state *mrb, struct REnv *e)
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
static inline mrb_callinfo*
|
||||
cipop(mrb_state *mrb)
|
||||
{
|
||||
struct mrb_context *c = mrb->c;
|
||||
struct REnv *env = c->ci->env;
|
||||
|
||||
mrb->c->stack = c->ci->stackent;
|
||||
c->ci--;
|
||||
if (env) mrb_env_unshare(mrb, env);
|
||||
return c->ci;
|
||||
}
|
||||
|
||||
void mrb_exc_set(mrb_state *mrb, mrb_value exc);
|
||||
@@ -356,16 +365,9 @@ ecall(mrb_state *mrb)
|
||||
nregs = ci->proc->body.irep->nregs;
|
||||
}
|
||||
cioff = ci - c->cibase;
|
||||
ci = cipush(mrb);
|
||||
ci->stackent = mrb->c->stack;
|
||||
ci->mid = ci[-1].mid;
|
||||
ci->acc = CI_ACC_SKIP;
|
||||
ci->argc = 0;
|
||||
ci->proc = p;
|
||||
ci->target_class = MRB_PROC_TARGET_CLASS(p);
|
||||
ci = cipush(mrb, NULL, nregs, CI_ACC_SKIP, MRB_PROC_TARGET_CLASS(p), p, ci->mid, 0);
|
||||
env = MRB_PROC_ENV(p);
|
||||
mrb_assert(env);
|
||||
c->stack += nregs;
|
||||
exc = mrb->exc; mrb->exc = 0;
|
||||
if (exc) {
|
||||
mrb_gc_protect(mrb, mrb_obj_value(exc));
|
||||
@@ -447,7 +449,6 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc
|
||||
}
|
||||
MRB_CATCH(&c_jmp) { /* error */
|
||||
while (nth_ci < (mrb->c->ci - mrb->c->cibase)) {
|
||||
mrb->c->stack = mrb->c->ci->stackent;
|
||||
cipop(mrb);
|
||||
}
|
||||
mrb->jmp = 0;
|
||||
@@ -486,12 +487,7 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc
|
||||
if (mrb->c->ci - mrb->c->cibase > MRB_FUNCALL_DEPTH_MAX) {
|
||||
mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err));
|
||||
}
|
||||
ci = cipush(mrb);
|
||||
ci->mid = mid;
|
||||
ci->stackent = mrb->c->stack;
|
||||
ci->argc = (int)argc;
|
||||
ci->target_class = c;
|
||||
mrb->c->stack = mrb->c->stack + n;
|
||||
ci = cipush(mrb, NULL, n, 0, c, NULL, mid, argc);
|
||||
if (argc < 0) argc = 1;
|
||||
if (mrb->c->stbase <= argv && argv < mrb->c->stend) {
|
||||
voff = argv - mrb->c->stbase;
|
||||
@@ -524,7 +520,6 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc
|
||||
if (MRB_METHOD_CFUNC_P(m)) {
|
||||
ci->acc = CI_ACC_DIRECT;
|
||||
val = MRB_METHOD_CFUNC(m)(mrb, self);
|
||||
mrb->c->stack = mrb->c->ci->stackent;
|
||||
cipop(mrb);
|
||||
}
|
||||
else {
|
||||
@@ -565,11 +560,7 @@ mrb_exec_irep(mrb_state *mrb, mrb_value self, struct RProc *p)
|
||||
stack_clear(mrb->c->stack+keep, nregs-keep);
|
||||
}
|
||||
|
||||
ci = cipush(mrb);
|
||||
ci->target_class = 0;
|
||||
ci->pc = p->body.irep->iseq;
|
||||
ci->stackent = mrb->c->stack;
|
||||
ci->acc = 0;
|
||||
cipush(mrb, p->body.irep->iseq, 0, 0, NULL, NULL, 0, 0);
|
||||
|
||||
return self;
|
||||
}
|
||||
@@ -671,11 +662,7 @@ eval_under(mrb_state *mrb, mrb_value self, mrb_value blk, struct RClass *c)
|
||||
mrb->c->stack[0] = self;
|
||||
mrb->c->stack[1] = self;
|
||||
stack_clear(mrb->c->stack+2, nregs-2);
|
||||
ci = cipush(mrb);
|
||||
ci->target_class = 0;
|
||||
ci->pc = p->body.irep->iseq;
|
||||
ci->stackent = mrb->c->stack;
|
||||
ci->acc = 0;
|
||||
ci = cipush(mrb, p->body.irep->iseq, 0, 0, NULL, NULL, 0, 0);
|
||||
|
||||
return self;
|
||||
}
|
||||
@@ -751,13 +738,7 @@ mrb_yield_with_class(mrb_state *mrb, mrb_value b, mrb_int argc, const mrb_value
|
||||
mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err));
|
||||
}
|
||||
p = mrb_proc_ptr(b);
|
||||
ci = cipush(mrb);
|
||||
ci->mid = mid;
|
||||
ci->proc = p;
|
||||
ci->target_class = c;
|
||||
ci->acc = CI_ACC_SKIP;
|
||||
ci->stackent = mrb->c->stack;
|
||||
mrb->c->stack += n;
|
||||
ci = cipush(mrb, NULL, n, CI_ACC_SKIP, c, p, mid, 0 /* dummy */);
|
||||
if (argc >= CALL_MAXARGS) {
|
||||
ci->argc = -1;
|
||||
n = 3;
|
||||
@@ -779,7 +760,6 @@ mrb_yield_with_class(mrb_state *mrb, mrb_value b, mrb_int argc, const mrb_value
|
||||
|
||||
if (MRB_PROC_CFUNC_P(p)) {
|
||||
val = MRB_PROC_CFUNC(p)(mrb, self);
|
||||
mrb->c->stack = mrb->c->ci->stackent;
|
||||
cipop(mrb);
|
||||
}
|
||||
else {
|
||||
@@ -1328,15 +1308,7 @@ RETRY_TRY_BLOCK:
|
||||
mrb->c->ensure[epos+n] = NULL;
|
||||
if (proc == NULL) continue;
|
||||
irep = proc->body.irep;
|
||||
ci = cipush(mrb);
|
||||
ci->mid = ci[-1].mid;
|
||||
ci->argc = 0;
|
||||
ci->proc = proc;
|
||||
ci->stackent = mrb->c->stack;
|
||||
ci->target_class = target_class;
|
||||
ci->pc = pc;
|
||||
ci->acc = nregs;
|
||||
mrb->c->stack += ci->acc;
|
||||
ci = cipush(mrb, pc, nregs, nregs, target_class, proc, ci->mid, 0);
|
||||
mrb_stack_extend(mrb, irep->nregs);
|
||||
regs[0] = self;
|
||||
pc = irep->iseq;
|
||||
@@ -1418,17 +1390,7 @@ RETRY_TRY_BLOCK:
|
||||
}
|
||||
|
||||
/* push callinfo */
|
||||
ci = cipush(mrb);
|
||||
ci->mid = mid;
|
||||
ci->stackent = mrb->c->stack;
|
||||
ci->target_class = cls;
|
||||
ci->argc = argc;
|
||||
|
||||
ci->pc = pc;
|
||||
ci->acc = a;
|
||||
|
||||
/* prepare stack */
|
||||
mrb->c->stack += a;
|
||||
ci = cipush(mrb, pc, a, a, cls, NULL, mid, argc);
|
||||
|
||||
if (MRB_METHOD_CFUNC_P(m)) {
|
||||
if (MRB_METHOD_PROC_P(m)) {
|
||||
@@ -1470,7 +1432,6 @@ RETRY_TRY_BLOCK:
|
||||
}
|
||||
mrb->c->stack[0] = recv;
|
||||
/* pop stackpos */
|
||||
mrb->c->stack = ci->stackent;
|
||||
pc = ci->pc;
|
||||
cipop(mrb);
|
||||
JUMP;
|
||||
@@ -1508,10 +1469,9 @@ RETRY_TRY_BLOCK:
|
||||
if (mrb->exc) goto L_RAISE;
|
||||
/* pop stackpos */
|
||||
ci = mrb->c->ci;
|
||||
mrb->c->stack = ci->stackent;
|
||||
regs[ci->acc] = recv;
|
||||
pc = ci->pc;
|
||||
cipop(mrb);
|
||||
regs[ci->acc] = recv;
|
||||
irep = mrb->c->ci->proc->body.irep;
|
||||
pool = irep->pool;
|
||||
syms = irep->syms;
|
||||
@@ -1617,15 +1577,9 @@ RETRY_TRY_BLOCK:
|
||||
}
|
||||
|
||||
/* push callinfo */
|
||||
ci = cipush(mrb);
|
||||
ci->mid = mid;
|
||||
ci->stackent = mrb->c->stack;
|
||||
ci->target_class = cls;
|
||||
ci->pc = pc;
|
||||
ci->argc = argc;
|
||||
ci = cipush(mrb, pc, a, 0, cls, NULL, mid, argc);
|
||||
|
||||
/* prepare stack */
|
||||
mrb->c->stack += a;
|
||||
mrb->c->stack[0] = recv;
|
||||
|
||||
if (MRB_METHOD_CFUNC_P(m)) {
|
||||
@@ -1652,8 +1606,6 @@ RETRY_TRY_BLOCK:
|
||||
}
|
||||
}
|
||||
mrb->c->stack[0] = v;
|
||||
/* pop stackpos */
|
||||
mrb->c->stack = ci->stackent;
|
||||
pc = ci->pc;
|
||||
cipop(mrb);
|
||||
JUMP;
|
||||
@@ -1954,13 +1906,11 @@ RETRY_TRY_BLOCK:
|
||||
goto L_RESCUE;
|
||||
}
|
||||
while (ci[0].ridx == ci[-1].ridx) {
|
||||
cipop(mrb);
|
||||
mrb->c->stack = ci->stackent;
|
||||
if (ci->acc == CI_ACC_SKIP && prev_jmp) {
|
||||
ci = cipop(mrb);
|
||||
if (ci[1].acc == CI_ACC_SKIP && prev_jmp) {
|
||||
mrb->jmp = prev_jmp;
|
||||
MRB_THROW(prev_jmp);
|
||||
}
|
||||
ci = mrb->c->ci;
|
||||
if (ci == mrb->c->cibase) {
|
||||
if (ci->ridx == 0) {
|
||||
L_FTOP: /* fiber top */
|
||||
@@ -2142,15 +2092,13 @@ RETRY_TRY_BLOCK:
|
||||
return v;
|
||||
}
|
||||
acc = ci->acc;
|
||||
mrb->c->stack = ci->stackent;
|
||||
cipop(mrb);
|
||||
ci = cipop(mrb);
|
||||
if (acc == CI_ACC_SKIP || acc == CI_ACC_DIRECT) {
|
||||
mrb_gc_arena_restore(mrb, ai);
|
||||
mrb->jmp = prev_jmp;
|
||||
return v;
|
||||
}
|
||||
pc = ci->pc;
|
||||
ci = mrb->c->ci;
|
||||
pc = ci[1].pc;
|
||||
DEBUG(fprintf(stderr, "from :%s\n", mrb_sym_name(mrb, ci->mid)));
|
||||
proc = mrb->c->ci->proc;
|
||||
irep = proc->body.irep;
|
||||
@@ -2664,7 +2612,6 @@ RETRY_TRY_BLOCK:
|
||||
}
|
||||
|
||||
CASE(OP_EXEC, BB) {
|
||||
mrb_callinfo *ci;
|
||||
mrb_value recv = regs[a];
|
||||
struct RProc *p;
|
||||
mrb_irep *nirep = irep->reps[b];
|
||||
@@ -2677,19 +2624,7 @@ RETRY_TRY_BLOCK:
|
||||
p->flags |= MRB_PROC_SCOPE;
|
||||
|
||||
/* prepare call stack */
|
||||
ci = cipush(mrb);
|
||||
ci->pc = pc;
|
||||
ci->acc = a;
|
||||
ci->mid = 0;
|
||||
ci->stackent = mrb->c->stack;
|
||||
ci->argc = 0;
|
||||
ci->target_class = mrb_class_ptr(recv);
|
||||
|
||||
/* prepare stack */
|
||||
mrb->c->stack += a;
|
||||
|
||||
/* setup block to call */
|
||||
ci->proc = p;
|
||||
cipush(mrb, pc, a, a, mrb_class_ptr(recv), p, 0, 0);
|
||||
|
||||
irep = p->body.irep;
|
||||
pool = irep->pool;
|
||||
@@ -2834,7 +2769,6 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
|
||||
MRB_API mrb_value
|
||||
mrb_top_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int stack_keep)
|
||||
{
|
||||
mrb_callinfo *ci;
|
||||
mrb_value v;
|
||||
|
||||
if (!mrb->c->cibase) {
|
||||
@@ -2844,11 +2778,7 @@ mrb_top_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int sta
|
||||
mrb->c->ci->env = NULL;
|
||||
return mrb_vm_run(mrb, proc, self, stack_keep);
|
||||
}
|
||||
ci = cipush(mrb);
|
||||
ci->stackent = mrb->c->stack;
|
||||
ci->mid = 0;
|
||||
ci->acc = CI_ACC_SKIP;
|
||||
ci->target_class = mrb->object_class;
|
||||
cipush(mrb, NULL, 0, CI_ACC_SKIP, mrb->object_class, NULL, 0, 0);
|
||||
v = mrb_vm_run(mrb, proc, self, stack_keep);
|
||||
|
||||
return v;
|
||||
|
||||
@@ -5,7 +5,7 @@ end
|
||||
$dat_files = []
|
||||
|
||||
def bm_files
|
||||
Dir.glob("#{MRUBY_ROOT}/benchmark/bm_*.rb")
|
||||
Dir.glob("#{MRUBY_ROOT}/benchmark/bm_*.rb").sort
|
||||
end
|
||||
|
||||
def build_config_name
|
||||
@@ -67,8 +67,8 @@ MRuby.each_target do |target|
|
||||
puts "..."
|
||||
|
||||
data = (0...MRuby::BENCHMARK_REPEAT).map do |n|
|
||||
str = %x{(time -f "%e %S %U" #{mruby_bin} #{bm_file}) 2>&1 >/dev/null}
|
||||
str.split(' ').map(&:to_f)
|
||||
str = %x{(time -p #{mruby_bin} #{bm_file}) 2>&1 >/dev/null}
|
||||
str.scan(/\d+\.\d+$/).map(&:to_f) # [real, user, sys]
|
||||
end
|
||||
|
||||
File.open(task.name, "w") do |f|
|
||||
|
||||
+11
-1
@@ -5,9 +5,10 @@ MRuby.each_target do
|
||||
gems.check self
|
||||
|
||||
# loader all gems
|
||||
active_gems_txt = "#{build_dir}/mrbgems/active_gems.txt"
|
||||
self.libmruby_objs << objfile("#{build_dir}/mrbgems/gem_init")
|
||||
file objfile("#{build_dir}/mrbgems/gem_init") => ["#{build_dir}/mrbgems/gem_init.c", "#{build_dir}/LEGAL"]
|
||||
file "#{build_dir}/mrbgems/gem_init.c" => [MRUBY_CONFIG, __FILE__, *Dir.glob("#{build_dir}/mrbgems/mruby-*/*.c")] do |t|
|
||||
file "#{build_dir}/mrbgems/gem_init.c" => [active_gems_txt, MRUBY_CONFIG, __FILE__] do |t|
|
||||
mkdir_p "#{build_dir}/mrbgems"
|
||||
open(t.name, 'w') do |f|
|
||||
gem_func_gems = gems.select { |g| g.generate_functions }
|
||||
@@ -49,6 +50,15 @@ MRuby.each_target do
|
||||
f.puts %Q[}]
|
||||
end
|
||||
end
|
||||
file active_gems_txt => :generate_active_gems_txt
|
||||
task :generate_active_gems_txt do |t|
|
||||
def t.timestamp; Time.at(0) end
|
||||
active_gems = gems.sort_by(&:name).inject(""){|s, g| s << "#{g.name}\n"}
|
||||
if !File.exist?(active_gems_txt) || File.read(active_gems_txt) != active_gems
|
||||
mkdir_p File.dirname(active_gems_txt)
|
||||
File.write(active_gems_txt, active_gems)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# legal documents
|
||||
|
||||
Reference in New Issue
Block a user