yarv-diff:108
From: ko1 atdot.net
Date: 27 Sep 2005 15:04:49 -0000
Subject: [yarv-diff:108] r264 - trunk
Author: ko1
Date: 2005-09-28 00:04:49 +0900 (Wed, 28 Sep 2005)
New Revision: 264
Added:
trunk/eval_load.c
Modified:
trunk/ChangeLog
trunk/common.mk
trunk/disasm.c
trunk/eval.c
trunk/eval_intern.h
trunk/eval_jump.h
trunk/eval_proc.c
trunk/test.rb
Log:
* common.mk, eval_load.c, eval.c, eval_intern.h : add eval_load.c
* disasm.c : fix around block local variables
* eval_proc.c : fix typo
Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog 2005-09-27 07:45:51 UTC (rev 263)
+++ trunk/ChangeLog 2005-09-27 15:04:49 UTC (rev 264)
@@ -4,6 +4,15 @@
# from Mon, 03 May 2004 01:24:19 +0900
#
+2005-09-28(Wed) 00:02:10 +0900 Koichi Sasada <ko1 atdot.net>
+
+ * common.mk, eval_load.c, eval.c, eval_intern.h : add eval_load.c
+
+ * disasm.c : fix around block local variables
+
+ * eval_proc.c : fix typo
+
+
2005-09-27(Tue) 16:45:20 +0900 Koichi Sasada <ko1 atdot.net>
* eval.c : remove debug print
Modified: trunk/common.mk
===================================================================
--- trunk/common.mk 2005-09-27 07:45:51 UTC (rev 263)
+++ trunk/common.mk 2005-09-27 15:04:49 UTC (rev 264)
@@ -24,6 +24,7 @@
error.$(OBJEXT) \
euc_jp.$(OBJEXT) \
eval.$(OBJEXT) \
+ eval_load.$(OBJEXT) \
eval_proc.$(OBJEXT) \
eval_thread.$(OBJEXT) \
file.$(OBJEXT) \
@@ -256,6 +257,11 @@
{$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h \
{$(VPATH)}node.h {$(VPATH)}env.h {$(VPATH)}util.h \
{$(VPATH)}rubysig.h {$(VPATH)}st.h {$(VPATH)}dln.h {$(VPATH)}yarv.h
+eval_load.$(OBJEXT): {$(VPATH)}eval_load.c {$(VPATH)}eval_intern.h \
+ {$(VPATH)}ruby.h config.h \
+ {$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h \
+ {$(VPATH)}node.h {$(VPATH)}env.h {$(VPATH)}util.h \
+ {$(VPATH)}rubysig.h {$(VPATH)}st.h {$(VPATH)}dln.h {$(VPATH)}yarv.h
eval_thread.$(OBJEXT): {$(VPATH)}eval_thread.c {$(VPATH)}eval_intern.h \
{$(VPATH)}ruby.h config.h \
{$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h \
Modified: trunk/disasm.c
===================================================================
--- trunk/disasm.c 2005-09-27 07:45:51 UTC (rev 263)
+++ trunk/disasm.c 2005-09-27 15:04:49 UTC (rev 264)
@@ -202,13 +202,20 @@
tbl = iseqdat->local_tbl;
if(tbl){
+ int opt = 0;
+ if(iseqdat->type == ISEQ_TYPE_METHOD ||
+ iseqdat->type == ISEQ_TYPE_TOP ||
+ iseqdat->type == ISEQ_TYPE_CLASS){
+ opt = 1;
+ }
+
snprintf(buff, sizeof(buff),
"local scope table (size: %d, argc: %d)\n",
iseqdat->local_size, iseqdat->argc);
rb_str_cat2(str, buff);
- for(i=0; i<iseqdat->local_size - 1; i++){
- char *name = rb_id2name(tbl[i+1]);
+ for(i=0; i<iseqdat->local_size - opt; i++){
+ char *name = rb_id2name(tbl[i+opt]);
char info[0x100];
char argi[0x100] = "";
char opti[0x100] = "";
Modified: trunk/eval.c
===================================================================
--- trunk/eval.c 2005-09-27 07:45:51 UTC (rev 263)
+++ trunk/eval.c 2005-09-27 15:04:49 UTC (rev 264)
@@ -33,16 +33,6 @@
ID rb_frame_callee();
static VALUE rb_frame_self();
-
-static int scope_vmode;
-#define SCOPE_PUBLIC 0
-#define SCOPE_PRIVATE 1
-#define SCOPE_PROTECTED 2
-#define SCOPE_MODFUNC 5
-#define SCOPE_MASK 7
-#define SCOPE_SET(f) (scope_vmode=(f))
-#define SCOPE_TEST(f) (scope_vmode&(f))
-
NODE* ruby_current_node;
static ID removed, singleton_removed, undefined, singleton_undefined;
@@ -60,12 +50,6 @@
static VALUE ruby_wrapper; /* security wrapper */
-#define PUSH_THREAD_TAG() \
- PUSH_TAG(PROT_THREAD)
-
-#define POP_THREAD_TAG() \
- POP_TAG()
-
static VALUE eval _((VALUE,VALUE,VALUE,char*,int));
static NODE *compile _((VALUE, char*, int));
@@ -2085,420 +2069,7 @@
return specific_eval(argc, argv, mod, mod);
}
-VALUE rb_load_path;
-
-NORETURN(static void load_failed _((VALUE)));
-
-void
-rb_load(VALUE fname, int wrap)
-{
- VALUE tmp;
- int state;
- volatile ID callee, this_func;
- volatile VALUE self = ruby_top_self;
- NODE * volatile last_node;
- NODE *saved_cref = ruby_cref();
-
- FilePathValue(fname);
- fname = rb_str_new4(fname);
- tmp = rb_find_file(fname);
- if (!tmp) {
- load_failed(fname);
- }
- fname = tmp;
-
- ruby_errinfo = Qnil; /* ensure */
- if (!wrap) {
- rb_secure(4); /* should alter global state */
- ruby_wrapper = 0;
- }
- else {
- /* load in anonymous module as toplevel */
- self = rb_obj_clone(ruby_top_self);
- rb_extend_object(self, ruby_wrapper);
- }
- /* default visibility is private at loading toplevel */
- SCOPE_SET(SCOPE_PRIVATE);
-
- PUSH_TAG(PROT_NONE);
- state = EXEC_TAG();
- if (state == 0) {
- yarv_load(RSTRING(fname)->ptr);
- }
- POP_TAG();
-
- if (ruby_nerrs > 0) {
- ruby_nerrs = 0;
- rb_exc_raise(ruby_errinfo);
- }
- if (state){
- jump_tag_but_local_jump(state, Qundef);
- }
-
- if (!NIL_P(ruby_errinfo)){
- /* exception during load */
- rb_exc_raise(ruby_errinfo);
- }
-}
-
-void
-rb_load_protect(fname, wrap, state)
- VALUE fname;
- int wrap;
- int *state;
-{
- int status;
-
- PUSH_THREAD_TAG();
- if ((status = EXEC_TAG()) == 0) {
- rb_load(fname, wrap);
- }
- else if (status == TAG_THREAD) {
- rb_thread_start_1();
- }
- POP_THREAD_TAG();
- if (state) *state = status;
-}
-
-/*
- * call-seq:
- * load(filename, wrap=false) => true
- *
- * Loads and executes the Ruby
- * program in the file _filename_. If the filename does not
- * resolve to an absolute path, the file is searched for in the library
- * directories listed in <code>$:</code>. If the optional _wrap_
- * parameter is +true+, the loaded script will be executed
- * under an anonymous module, protecting the calling program's global
- * namespace. In no circumstance will any local variables in the loaded
- * file be propagated to the loading environment.
- */
-
-
-static VALUE
-rb_f_load(argc, argv)
- int argc;
- VALUE *argv;
-{
- VALUE fname, wrap;
-
- rb_scan_args(argc, argv, "11", &fname, &wrap);
- rb_load(fname, RTEST(wrap));
- return Qtrue;
-}
-
-VALUE ruby_dln_librefs;
-static VALUE rb_features;
-static st_table *loading_tbl;
-
-#define IS_SOEXT(e) (strcmp(e, ".so") == 0 || strcmp(e, ".o") == 0)
-#ifdef DLEXT2
-#define IS_DLEXT(e) (strcmp(e, DLEXT) == 0 || strcmp(e, DLEXT2) == 0)
-#else
-#define IS_DLEXT(e) (strcmp(e, DLEXT) == 0)
-#endif
-
-static int
-rb_feature_p(feature, ext, rb)
- const char *feature, *ext;
- int rb;
-{
- VALUE v;
- char *f, *e;
- long i, len, elen;
-
- if (ext) {
- len = ext - feature;
- elen = strlen(ext);
- }
- else {
- len = strlen(feature);
- elen = 0;
- }
- for (i = 0; i < RARRAY(rb_features)->len; ++i) {
- v = RARRAY(rb_features)->ptr[i];
- f = StringValuePtr(v);
- if (strncmp(f, feature, len) != 0) continue;
- if (!*(e = f + len)) {
- if (ext) continue;
- return 'u';
- }
- if (*e != '.') continue;
- if ((!rb || !ext) && (IS_SOEXT(e) || IS_DLEXT(e))) {
- return 's';
- }
- if ((rb || !ext) && (strcmp(e, ".rb") == 0)) {
- return 'r';
- }
- }
- return 0;
-}
-
-static const char *const loadable_ext[] = {
- ".rb", DLEXT,
-#ifdef DLEXT2
- DLEXT2,
-#endif
- 0
-};
-
-static int search_required _((VALUE, VALUE *));
-
-int
-rb_provided(feature)
- const char *feature;
-{
- int i;
- char *buf;
- VALUE fname;
-
- if (rb_feature_p(feature, 0, Qfalse))
- return Qtrue;
- if (loading_tbl) {
- if (st_lookup(loading_tbl, (st_data_t)feature, 0)) return Qtrue;
- buf = ALLOCA_N(char, strlen(feature)+8);
- strcpy(buf, feature);
- for (i=0; loadable_ext[i]; i++) {
- strcpy(buf+strlen(feature), loadable_ext[i]);
- if (st_lookup(loading_tbl, (st_data_t)buf, 0)) return Qtrue;
- }
- }
- if (search_required(rb_str_new2(feature), &fname)) {
- feature = RSTRING(fname)->ptr;
- if (rb_feature_p(feature, 0, Qfalse))
- return Qtrue;
- if (loading_tbl && st_lookup(loading_tbl, (st_data_t)feature, 0))
- return Qtrue;
- }
- return Qfalse;
-}
-
static void
-rb_provide_feature(feature)
- VALUE feature;
-{
- rb_ary_push(rb_features, feature);
-}
-
-void
-rb_provide(feature)
- const char *feature;
-{
- rb_provide_feature(rb_str_new2(feature));
-}
-
-static int
-load_wait(ftptr)
- char *ftptr;
-{
- // TODO: fix me
- return Qtrue;
-}
-
-/*
- * 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 it's name already
- * appears in <code>$"</code>. However, the file name is not converted
- * to an absolute path, so that ``<code>require 'a';require
- * './a'</code>'' will load <code>a.rb</code> twice.
- *
- * require "my-library.rb"
- * require "db-driver"
- */
-
-VALUE
-rb_f_require(obj, fname)
- VALUE obj, fname;
-{
- return rb_require_safe(fname, ruby_safe_level);
-}
-
-static int
-search_required(fname, path)
- VALUE fname, *path;
-{
- VALUE tmp;
- char *ext, *ftptr;
- int type, ft = 0;
-
- *path = 0;
- ext = strrchr(ftptr = RSTRING(fname)->ptr, '.');
- if (ext && !strchr(ext, '/')) {
- if (strcmp(".rb", ext) == 0) {
- if (rb_feature_p(ftptr, ext, Qtrue)) return 'r';
- if (tmp = rb_find_file(fname)) {
- tmp = rb_file_expand_path(tmp, Qnil);
- ext = strrchr(ftptr = RSTRING(tmp)->ptr, '.');
- if (!rb_feature_p(ftptr, ext, Qtrue))
- *path = tmp;
- return 'r';
- }
- return 0;
- }
- else if (IS_SOEXT(ext)) {
- if (rb_feature_p(ftptr, ext, Qfalse)) return 's';
- tmp = rb_str_new(RSTRING(fname)->ptr, ext-RSTRING(fname)->ptr);
-#ifdef DLEXT2
- OBJ_FREEZE(tmp);
- if (rb_find_file_ext(&tmp, loadable_ext+1)) {
- tmp = rb_file_expand_path(tmp, Qnil);
- ext = strrchr(ftptr = RSTRING(tmp)->ptr, '.');
- if (!rb_feature_p(ftptr, ext, Qfalse))
- *path = tmp;
- return 's';
- }
-#else
- rb_str_cat2(tmp, DLEXT);
- OBJ_FREEZE(tmp);
- if (tmp = rb_find_file(tmp)) {
- tmp = rb_file_expand_path(tmp, Qnil);
- ext = strrchr(ftptr = RSTRING(tmp)->ptr, '.');
- if (!rb_feature_p(ftptr, ext, Qfalse))
- *path = tmp;
- return 's';
- }
-#endif
- }
- else if (IS_DLEXT(ext)) {
- if (rb_feature_p(ftptr, ext, Qfalse)) return 's';
- if (tmp = rb_find_file(fname)) {
- tmp = rb_file_expand_path(tmp, Qnil);
- ext = strrchr(ftptr = RSTRING(tmp)->ptr, '.');
- if (!rb_feature_p(ftptr, ext, Qfalse))
- *path = tmp;
- return 's';
- }
- }
- }
- else if ((ft = rb_feature_p(ftptr, 0, Qfalse)) == 'r') {
- return 'r';
- }
- tmp = fname;
- type = rb_find_file_ext(&tmp, loadable_ext);
- tmp = rb_file_expand_path(tmp, Qnil);
- switch (type) {
- case 0:
- ftptr = RSTRING(tmp)->ptr;
- if (ft) break;
- return rb_feature_p(ftptr, 0, Qfalse);
-
- default:
- if (ft) break;
- case 1:
- ext = strrchr(ftptr = RSTRING(tmp)->ptr, '.');
- if (rb_feature_p(ftptr, ext, !--type)) break;
- *path = tmp;
- }
- return type ? 's' : 'r';
-}
-
-static void
-load_failed(fname)
- VALUE fname;
-{
- rb_raise(rb_eLoadError, "no such file to load -- %s", RSTRING(fname)->ptr);
-}
-
-VALUE
-rb_require_safe(fname, safe)
- VALUE fname;
- int safe;
-{
- VALUE result = Qnil;
- volatile VALUE errinfo = ruby_errinfo;
- int state;
- struct {
- NODE *node;
- ID this_func, callee;
- int vmode, safe;
- } volatile saved;
- char *volatile ftptr = 0;
-
- saved.vmode = scope_vmode;
- saved.node = ruby_current_node;
- saved.safe = ruby_safe_level;
- PUSH_TAG(PROT_NONE);
- if ((state = EXEC_TAG()) == 0) {
- VALUE path;
- long handle;
- int found;
-
- ruby_safe_level = safe;
- FilePathValue(fname);
- *(volatile VALUE *)&fname = rb_str_new4(fname);
- found = search_required(fname, &path);
- if (found) {
- if (!path || load_wait(RSTRING(path)->ptr)) {
- result = Qfalse;
- }
- else {
- ruby_safe_level = 0;
- switch (found) {
- case 'r':
- /* loading ruby library should be serialized. */
- if (!loading_tbl) {
- loading_tbl = st_init_strtable();
- }
- /* partial state */
- ftptr = ruby_strdup(RSTRING(path)->ptr);
- st_insert(loading_tbl, (st_data_t)ftptr, (st_data_t)rb_vm_curr_thread());
- rb_load(path, 0);
- break;
-
- case 's':
- ruby_current_node = 0;
- ruby_sourcefile = rb_source_filename(RSTRING(path)->ptr);
- ruby_sourceline = 0;
- SCOPE_SET(SCOPE_PUBLIC);
- handle = (long)dln_load(RSTRING(path)->ptr);
- rb_ary_push(ruby_dln_librefs, LONG2NUM(handle));
- break;
- }
- rb_provide_feature(path);
- result = Qtrue;
- }
- }
- }
- POP_TAG();
- ruby_current_node = saved.node;
- ruby_set_current_source();
- SCOPE_SET(saved.vmode);
- ruby_safe_level = saved.safe;
- if (ftptr) {
- if (st_delete(loading_tbl, (st_data_t *)&ftptr, 0)) { /* loading done */
- free(ftptr);
- }
- }
- if (state) JUMP_TAG(state);
- if (NIL_P(result)) {
- load_failed(fname);
- }
- ruby_errinfo = errinfo;
-
- return result;
-}
-
-VALUE
-rb_require(fname)
- const char *fname;
-{
- VALUE fn = rb_str_new2(fname);
- OBJ_FREEZE(fn);
- return rb_require_safe(fn, ruby_safe_level);
-}
-
-static void
secure_visibility(self)
VALUE self;
{
@@ -3142,103 +2713,7 @@
rb_define_virtual_variable("$SAFE", safe_getter, safe_setter);
}
-/*
- * call-seq:
- * mod.autoload(name, filename) => nil
- *
- * Registers _filename_ to be loaded (using <code>Kernel::require</code>)
- * the first time that _module_ (which may be a <code>String</code> or
- * a symbol) is accessed in the namespace of _mod_.
- *
- * module A
- * end
- * A.autoload(:B, "b")
- * A::B.doit # autoloads "b"
- */
-static VALUE
-rb_mod_autoload(mod, sym, file)
- VALUE mod;
- VALUE sym;
- VALUE file;
-{
- ID id = rb_to_id(sym);
-
- Check_SafeStr(file);
- rb_autoload(mod, id, RSTRING(file)->ptr);
- return Qnil;
-}
-
-/*
- * MISSING: documentation
- */
-
-static VALUE
-rb_mod_autoload_p(mod, sym)
- VALUE mod, sym;
-{
- return rb_autoload_p(mod, rb_to_id(sym));
-}
-
-/*
- * call-seq:
- * autoload(module, filename) => nil
- *
- * Registers _filename_ to be loaded (using <code>Kernel::require</code>)
- * the first time that _module_ (which may be a <code>String</code> or
- * a symbol) is accessed.
- *
- * autoload(:MyModule, "/usr/local/lib/modules/my_module.rb")
- */
-
-static VALUE
-rb_f_autoload(obj, sym, file)
- VALUE obj;
- VALUE sym;
- VALUE file;
-{
- return rb_mod_autoload(ruby_cbase(), sym, file);
-}
-
-
-/*
- * MISSING: documentation
- */
-
-static VALUE
-rb_f_autoload_p(obj, sym)
- VALUE obj;
- VALUE sym;
-{
- /* use ruby_cbase() as same as rb_f_autoload. */
- return rb_mod_autoload_p(ruby_cbase(), sym);
-}
-
-void
-Init_load()
-{
- rb_load_path = rb_ary_new();
- rb_define_readonly_variable("$:", &rb_load_path);
- rb_define_readonly_variable("$-I", &rb_load_path);
- rb_define_readonly_variable("$LOAD_PATH", &rb_load_path);
-
- rb_features = rb_ary_new();
- rb_define_readonly_variable("$\"", &rb_features);
- rb_define_readonly_variable("$LOADED_FEATURES", &rb_features);
-
- rb_define_global_function("load", rb_f_load, -1);
- rb_define_global_function("require", rb_f_require, 1);
- rb_define_method(rb_cModule, "autoload", rb_mod_autoload, 2);
- rb_define_method(rb_cModule, "autoload?", rb_mod_autoload_p, 1);
- rb_define_global_function("autoload", rb_f_autoload, 2);
- rb_define_global_function("autoload?", rb_f_autoload_p, 1);
- rb_global_variable(&ruby_wrapper);
-
- ruby_dln_librefs = rb_ary_new();
- rb_global_variable(&ruby_dln_librefs);
-}
-
-
/* for parser */
VALUE
Modified: trunk/eval_intern.h
===================================================================
--- trunk/eval_intern.h 2005-09-27 07:45:51 UTC (rev 263)
+++ trunk/eval_intern.h 2005-09-27 15:04:49 UTC (rev 264)
@@ -215,6 +215,12 @@
_tag.tag = ptag; \
prot_tag = &_tag
+#define PUSH_THREAD_TAG() \
+ PUSH_TAG(PROT_THREAD)
+
+#define POP_THREAD_TAG() \
+ POP_TAG()
+
#define PROT_NONE Qfalse /* 0 */
#define PROT_THREAD Qtrue /* 2 */
#define PROT_FUNC INT2FIX(0) /* 1 */
@@ -245,11 +251,14 @@
#define TAG_THREAD 0xa
#define TAG_MASK 0xf
-#define YIELD_LAMBDA_CALL 1
-#define YIELD_PROC_CALL 2
-#define YIELD_PUBLIC_DEF 4
-#define YIELD_FUNC_AVALUE 1
-#define YIELD_FUNC_SVALUE 2
+static int scope_vmode;
+#define SCOPE_PUBLIC 0
+#define SCOPE_PRIVATE 1
+#define SCOPE_PROTECTED 2
+#define SCOPE_MODFUNC 5
+#define SCOPE_MASK 7
+#define SCOPE_SET(f) (scope_vmode=(f))
+#define SCOPE_TEST(f) (scope_vmode&(f))
struct ruby_env {
struct ruby_env *prev;
Modified: trunk/eval_jump.h
===================================================================
--- trunk/eval_jump.h 2005-09-27 07:45:51 UTC (rev 263)
+++ trunk/eval_jump.h 2005-09-27 15:04:49 UTC (rev 264)
@@ -325,147 +325,141 @@
void (*func) _((VALUE));
VALUE data;
{
- struct end_proc_data *link = ALLOC(struct end_proc_data);
- struct end_proc_data **list;
+ struct end_proc_data *link = ALLOC(struct end_proc_data);
+ struct end_proc_data **list;
- if (ruby_wrapper) list = &ephemeral_end_procs;
- else list = &end_procs;
- link->next = *list;
- link->func = func;
- link->data = data;
- link->safe = ruby_safe_level;
- *list = link;
+ if (ruby_wrapper) list = &ephemeral_end_procs;
+ else list = &end_procs;
+ link->next = *list;
+ link->func = func;
+ link->data = data;
+ link->safe = ruby_safe_level;
+ *list = link;
}
void
rb_mark_end_proc()
{
- struct end_proc_data *link;
+ struct end_proc_data *link;
- link = end_procs;
- while (link) {
- rb_gc_mark(link->data);
- link = link->next;
- }
- link = ephemeral_end_procs;
- while (link) {
- rb_gc_mark(link->data);
- link = link->next;
- }
- link = tmp_end_procs;
- while (link) {
- rb_gc_mark(link->data);
- link = link->next;
- }
+ link = end_procs;
+ while (link) {
+ rb_gc_mark(link->data);
+ link = link->next;
+ }
+ link = ephemeral_end_procs;
+ while (link) {
+ rb_gc_mark(link->data);
+ link = link->next;
+ }
+ link = tmp_end_procs;
+ while (link) {
+ rb_gc_mark(link->data);
+ link = link->next;
+ }
}
void
rb_exec_end_proc()
{
- struct end_proc_data *link, *tmp;
- int status;
- volatile int safe = ruby_safe_level;
+ struct end_proc_data *link, *tmp;
+ int status;
+ volatile int safe = ruby_safe_level;
- while (ephemeral_end_procs) {
- tmp_end_procs = link = ephemeral_end_procs;
- ephemeral_end_procs = 0;
- while (link) {
- PUSH_TAG(PROT_NONE);
- if ((status = EXEC_TAG()) == 0) {
- ruby_safe_level = link->safe;
- (*link->func)(link->data);
- }
- POP_TAG();
- if (status) {
- error_handle(status);
- }
- tmp = link;
- tmp_end_procs = link = link->next;
- free(tmp);
- }
+ while (ephemeral_end_procs) {
+ tmp_end_procs = link = ephemeral_end_procs;
+ ephemeral_end_procs = 0;
+ while (link) {
+ PUSH_TAG(PROT_NONE);
+ if ((status = EXEC_TAG()) == 0) {
+ ruby_safe_level = link->safe;
+ (*link->func)(link->data);
+ }
+ POP_TAG();
+ if (status) {
+ error_handle(status);
+ }
+ tmp = link;
+ tmp_end_procs = link = link->next;
+ free(tmp);
}
- while (end_procs) {
- tmp_end_procs = link = end_procs;
- end_procs = 0;
- while (link) {
- PUSH_TAG(PROT_NONE);
- if ((status = EXEC_TAG()) == 0) {
- ruby_safe_level = link->safe;
- (*link->func)(link->data);
- }
- POP_TAG();
- if (status) {
- error_handle(status);
- }
- tmp = link;
- tmp_end_procs = link = link->next;
- free(tmp);
- }
+ }
+ while (end_procs) {
+ tmp_end_procs = link = end_procs;
+ end_procs = 0;
+ while (link) {
+ PUSH_TAG(PROT_NONE);
+ if ((status = EXEC_TAG()) == 0) {
+ ruby_safe_level = link->safe;
+ (*link->func)(link->data);
+ }
+ POP_TAG();
+ if (status) {
+ error_handle(status);
+ }
+ tmp = link;
+ tmp_end_procs = link = link->next;
+ free(tmp);
}
- ruby_safe_level = safe;
+ }
+ ruby_safe_level = safe;
}
NORETURN(static void localjump_error(const char*, VALUE, int));
static void
-localjump_error(mesg, value, reason)
- const char *mesg;
- VALUE value;
- int reason;
+localjump_error(const char *mesg, VALUE value, int reason)
{
- VALUE exc = rb_exc_new2(rb_eLocalJumpError, mesg);
- ID id;
+ VALUE exc = rb_exc_new2(rb_eLocalJumpError, mesg);
+ ID id;
- rb_iv_set(exc, "@exit_value", value);
- switch (reason) {
- case TAG_BREAK:
- id = rb_intern("break"); break;
- case TAG_REDO:
- id = rb_intern("redo"); break;
- case TAG_RETRY:
- id = rb_intern("retry"); break;
- case TAG_NEXT:
- id = rb_intern("next"); break;
- case TAG_RETURN:
- id = rb_intern("return"); break;
- default:
- id = rb_intern("noreason"); break;
- }
- rb_iv_set(exc, "@reason", ID2SYM(id));
- rb_exc_raise(exc);
+ rb_iv_set(exc, "@exit_value", value);
+ switch (reason) {
+ case TAG_BREAK:
+ id = rb_intern("break"); break;
+ case TAG_REDO:
+ id = rb_intern("redo"); break;
+ case TAG_RETRY:
+ id = rb_intern("retry"); break;
+ case TAG_NEXT:
+ id = rb_intern("next"); break;
+ case TAG_RETURN:
+ id = rb_intern("return"); break;
+ default:
+ id = rb_intern("noreason"); break;
+ }
+ rb_iv_set(exc, "@reason", ID2SYM(id));
+ rb_exc_raise(exc);
}
-NORETURN(static void jump_tag_but_local_jump _((int,VALUE)));
-static void
-jump_tag_but_local_jump(state, val)
- int state;
- VALUE val;
+NORETURN(void jump_tag_but_local_jump(int,VALUE));
+void
+jump_tag_but_local_jump(int state, VALUE val)
{
-
- if (val == Qundef) val = prot_tag->retval;
- switch (state) {
- case 0:
- break;
- case TAG_RETURN:
- localjump_error("unexpected return", val, state);
- break;
- case TAG_BREAK:
- localjump_error("unexpected break", val, state);
- break;
- case TAG_NEXT:
- localjump_error("unexpected next", val, state);
- break;
- case TAG_REDO:
- localjump_error("unexpected redo", Qnil, state);
- break;
- case TAG_RETRY:
- localjump_error("retry outside of rescue clause", Qnil, state);
- break;
- default:
- break;
- }
- JUMP_TAG(state);
+ if (val == Qundef) val = prot_tag->retval;
+ switch (state) {
+ case 0:
+ break;
+ case TAG_RETURN:
+ localjump_error("unexpected return", val, state);
+ break;
+ case TAG_BREAK:
+ localjump_error("unexpected break", val, state);
+ break;
+ case TAG_NEXT:
+ localjump_error("unexpected next", val, state);
+ break;
+ case TAG_REDO:
+ localjump_error("unexpected redo", Qnil, state);
+ break;
+ case TAG_RETRY:
+ localjump_error("retry outside of rescue clause", Qnil, state);
+ break;
+ default:
+ break;
+ }
+ JUMP_TAG(state);
}
Added: trunk/eval_load.c
===================================================================
--- trunk/eval_load.c 2005-09-27 07:45:51 UTC (rev 263)
+++ trunk/eval_load.c 2005-09-27 15:04:49 UTC (rev 264)
@@ -0,0 +1,517 @@
+/*
+ * load methods from eval.c
+ */
+
+#include "eval_intern.h"
+
+extern VALUE ruby_top_self;
+
+VALUE ruby_dln_librefs;
+static VALUE rb_features;
+static st_table *loading_tbl;
+
+NORETURN(void jump_tag_but_local_jump(int,VALUE));
+
+#define IS_SOEXT(e) (strcmp(e, ".so") == 0 || strcmp(e, ".o") == 0)
+#ifdef DLEXT2
+#define IS_DLEXT(e) (strcmp(e, DLEXT) == 0 || strcmp(e, DLEXT2) == 0)
+#else
+#define IS_DLEXT(e) (strcmp(e, DLEXT) == 0)
+#endif
+
+static int
+rb_feature_p(feature, ext, rb)
+ const char *feature, *ext;
+ int rb;
+{
+ VALUE v;
+ char *f, *e;
+ long i, len, elen;
+
+ if (ext) {
+ len = ext - feature;
+ elen = strlen(ext);
+ }
+ else {
+ len = strlen(feature);
+ elen = 0;
+ }
+ for (i = 0; i < RARRAY(rb_features)->len; ++i) {
+ v = RARRAY(rb_features)->ptr[i];
+ f = StringValuePtr(v);
+ if (strncmp(f, feature, len) != 0) continue;
+ if (!*(e = f + len)) {
+ if (ext) continue;
+ return 'u';
+ }
+ if (*e != '.') continue;
+ if ((!rb || !ext) && (IS_SOEXT(e) || IS_DLEXT(e))) {
+ return 's';
+ }
+ if ((rb || !ext) && (strcmp(e, ".rb") == 0)) {
+ return 'r';
+ }
+ }
+ return 0;
+}
+
+static const char *const loadable_ext[] = {
+ ".rb", DLEXT,
+#ifdef DLEXT2
+ DLEXT2,
+#endif
+ 0
+};
+
+static int search_required _((VALUE, VALUE *));
+
+int
+rb_provided(feature)
+ const char *feature;
+{
+ int i;
+ char *buf;
+ VALUE fname;
+
+ if (rb_feature_p(feature, 0, Qfalse))
+ return Qtrue;
+ if (loading_tbl) {
+ if (st_lookup(loading_tbl, (st_data_t)feature, 0)) return Qtrue;
+ buf = ALLOCA_N(char, strlen(feature)+8);
+ strcpy(buf, feature);
+ for (i=0; loadable_ext[i]; i++) {
+ strcpy(buf+strlen(feature), loadable_ext[i]);
+ if (st_lookup(loading_tbl, (st_data_t)buf, 0)) return Qtrue;
+ }
+ }
+ if (search_required(rb_str_new2(feature), &fname)) {
+ feature = RSTRING(fname)->ptr;
+ if (rb_feature_p(feature, 0, Qfalse))
+ return Qtrue;
+ if (loading_tbl && st_lookup(loading_tbl, (st_data_t)feature, 0))
+ return Qtrue;
+ }
+ return Qfalse;
+}
+
+static void
+rb_provide_feature(feature)
+ VALUE feature;
+{
+ rb_ary_push(rb_features, feature);
+}
+
+void
+rb_provide(feature)
+ const char *feature;
+{
+ rb_provide_feature(rb_str_new2(feature));
+}
+
+VALUE rb_load_path;
+
+NORETURN(static void load_failed _((VALUE)));
+
+void
+rb_load(VALUE fname, int wrap)
+{
+ VALUE tmp;
+ int state;
+ volatile ID callee, this_func;
+ volatile VALUE self = ruby_top_self;
+ NODE * volatile last_node;
+
+ FilePathValue(fname);
+ fname = rb_str_new4(fname);
+ tmp = rb_find_file(fname);
+ if (!tmp) {
+ load_failed(fname);
+ }
+ fname = tmp;
+
+ ruby_errinfo = Qnil; /* ensure */
+ if (!wrap) {
+ rb_secure(4); /* should alter global state */
+ }
+ else {
+ /* load in anonymous module as toplevel */
+ self = rb_obj_clone(ruby_top_self);
+ }
+ /* default visibility is private at loading toplevel */
+ SCOPE_SET(SCOPE_PRIVATE);
+
+ PUSH_TAG(PROT_NONE);
+ state = EXEC_TAG();
+ if (state == 0) {
+ yarv_load(RSTRING(fname)->ptr);
+ }
+ POP_TAG();
+
+ if (ruby_nerrs > 0) {
+ ruby_nerrs = 0;
+ rb_exc_raise(ruby_errinfo);
+ }
+ if (state){
+ jump_tag_but_local_jump(state, Qundef);
+ }
+
+ if (!NIL_P(ruby_errinfo)){
+ /* exception during load */
+ rb_exc_raise(ruby_errinfo);
+ }
+}
+
+void
+rb_load_protect(fname, wrap, state)
+ VALUE fname;
+ int wrap;
+ int *state;
+{
+ int status;
+
+ PUSH_THREAD_TAG();
+ if ((status = EXEC_TAG()) == 0) {
+ rb_load(fname, wrap);
+ }
+ else if (status == TAG_THREAD) {
+ rb_thread_start_1();
+ }
+ POP_THREAD_TAG();
+ if (state) *state = status;
+}
+
+/*
+ * call-seq:
+ * load(filename, wrap=false) => true
+ *
+ * Loads and executes the Ruby
+ * program in the file _filename_. If the filename does not
+ * resolve to an absolute path, the file is searched for in the library
+ * directories listed in <code>$:</code>. If the optional _wrap_
+ * parameter is +true+, the loaded script will be executed
+ * under an anonymous module, protecting the calling program's global
+ * namespace. In no circumstance will any local variables in the loaded
+ * file be propagated to the loading environment.
+ */
+
+
+static VALUE
+rb_f_load(argc, argv)
+ int argc;
+ VALUE *argv;
+{
+ VALUE fname, wrap;
+
+ rb_scan_args(argc, argv, "11", &fname, &wrap);
+ rb_load(fname, RTEST(wrap));
+ return Qtrue;
+}
+
+static int
+load_wait(ftptr)
+ char *ftptr;
+{
+ // TODO: fix me
+ return Qtrue;
+}
+
+/*
+ * 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 it's name already
+ * appears in <code>$"</code>. However, the file name is not converted
+ * to an absolute path, so that ``<code>require 'a';require
+ * './a'</code>'' will load <code>a.rb</code> twice.
+ *
+ * require "my-library.rb"
+ * require "db-driver"
+ */
+
+VALUE
+rb_f_require(obj, fname)
+ VALUE obj, fname;
+{
+ return rb_require_safe(fname, ruby_safe_level);
+}
+
+static int
+search_required(fname, path)
+ VALUE fname, *path;
+{
+ VALUE tmp;
+ char *ext, *ftptr;
+ int type, ft = 0;
+
+ *path = 0;
+ ext = strrchr(ftptr = RSTRING(fname)->ptr, '.');
+ if (ext && !strchr(ext, '/')) {
+ if (strcmp(".rb", ext) == 0) {
+ if (rb_feature_p(ftptr, ext, Qtrue)) return 'r';
+ if (tmp = rb_find_file(fname)) {
+ tmp = rb_file_expand_path(tmp, Qnil);
+ ext = strrchr(ftptr = RSTRING(tmp)->ptr, '.');
+ if (!rb_feature_p(ftptr, ext, Qtrue))
+ *path = tmp;
+ return 'r';
+ }
+ return 0;
+ }
+ else if (IS_SOEXT(ext)) {
+ if (rb_feature_p(ftptr, ext, Qfalse)) return 's';
+ tmp = rb_str_new(RSTRING(fname)->ptr, ext-RSTRING(fname)->ptr);
+#ifdef DLEXT2
+ OBJ_FREEZE(tmp);
+ if (rb_find_file_ext(&tmp, loadable_ext+1)) {
+ tmp = rb_file_expand_path(tmp, Qnil);
+ ext = strrchr(ftptr = RSTRING(tmp)->ptr, '.');
+ if (!rb_feature_p(ftptr, ext, Qfalse))
+ *path = tmp;
+ return 's';
+ }
+#else
+ rb_str_cat2(tmp, DLEXT);
+ OBJ_FREEZE(tmp);
+ if (tmp = rb_find_file(tmp)) {
+ tmp = rb_file_expand_path(tmp, Qnil);
+ ext = strrchr(ftptr = RSTRING(tmp)->ptr, '.');
+ if (!rb_feature_p(ftptr, ext, Qfalse))
+ *path = tmp;
+ return 's';
+ }
+#endif
+ }
+ else if (IS_DLEXT(ext)) {
+ if (rb_feature_p(ftptr, ext, Qfalse)) return 's';
+ if (tmp = rb_find_file(fname)) {
+ tmp = rb_file_expand_path(tmp, Qnil);
+ ext = strrchr(ftptr = RSTRING(tmp)->ptr, '.');
+ if (!rb_feature_p(ftptr, ext, Qfalse))
+ *path = tmp;
+ return 's';
+ }
+ }
+ }
+ else if ((ft = rb_feature_p(ftptr, 0, Qfalse)) == 'r') {
+ return 'r';
+ }
+ tmp = fname;
+ type = rb_find_file_ext(&tmp, loadable_ext);
+ tmp = rb_file_expand_path(tmp, Qnil);
+ switch (type) {
+ case 0:
+ ftptr = RSTRING(tmp)->ptr;
+ if (ft) break;
+ return rb_feature_p(ftptr, 0, Qfalse);
+
+ default:
+ if (ft) break;
+ case 1:
+ ext = strrchr(ftptr = RSTRING(tmp)->ptr, '.');
+ if (rb_feature_p(ftptr, ext, !--type)) break;
+ *path = tmp;
+ }
+ return type ? 's' : 'r';
+}
+
+static void
+load_failed(fname)
+ VALUE fname;
+{
+ rb_raise(rb_eLoadError, "no such file to load -- %s", RSTRING(fname)->ptr);
+}
+
+VALUE
+rb_require_safe(fname, safe)
+ VALUE fname;
+ int safe;
+{
+ VALUE result = Qnil;
+ volatile VALUE errinfo = ruby_errinfo;
+ int state;
+ struct {
+ NODE *node;
+ ID this_func, callee;
+ int vmode, safe;
+ } volatile saved;
+ char *volatile ftptr = 0;
+
+ saved.vmode = scope_vmode;
+ saved.node = ruby_current_node;
+ saved.safe = ruby_safe_level;
+ PUSH_TAG(PROT_NONE);
+ if ((state = EXEC_TAG()) == 0) {
+ VALUE path;
+ long handle;
+ int found;
+
+ ruby_safe_level = safe;
+ FilePathValue(fname);
+ *(volatile VALUE *)&fname = rb_str_new4(fname);
+ found = search_required(fname, &path);
+ if (found) {
+ if (!path || load_wait(RSTRING(path)->ptr)) {
+ result = Qfalse;
+ }
+ else {
+ ruby_safe_level = 0;
+ switch (found) {
+ case 'r':
+ /* loading ruby library should be serialized. */
+ if (!loading_tbl) {
+ loading_tbl = st_init_strtable();
+ }
+ /* partial state */
+ ftptr = ruby_strdup(RSTRING(path)->ptr);
+ st_insert(loading_tbl, (st_data_t)ftptr, (st_data_t)rb_vm_curr_thread());
+ rb_load(path, 0);
+ break;
+
+ case 's':
+ ruby_current_node = 0;
+ ruby_sourcefile = rb_source_filename(RSTRING(path)->ptr);
+ ruby_sourceline = 0;
+ SCOPE_SET(SCOPE_PUBLIC);
+ handle = (long)dln_load(RSTRING(path)->ptr);
+ rb_ary_push(ruby_dln_librefs, LONG2NUM(handle));
+ break;
+ }
+ rb_provide_feature(path);
+ result = Qtrue;
+ }
+ }
+ }
+ POP_TAG();
+ ruby_current_node = saved.node;
+ ruby_set_current_source();
+ SCOPE_SET(saved.vmode);
+ ruby_safe_level = saved.safe;
+ if (ftptr) {
+ if (st_delete(loading_tbl, (st_data_t *)&ftptr, 0)) { /* loading done */
+ free(ftptr);
+ }
+ }
+ if (state) JUMP_TAG(state);
+ if (NIL_P(result)) {
+ load_failed(fname);
+ }
+ ruby_errinfo = errinfo;
+
+ return result;
+}
+
+VALUE
+rb_require(fname)
+ const char *fname;
+{
+ VALUE fn = rb_str_new2(fname);
+ OBJ_FREEZE(fn);
+ return rb_require_safe(fn, ruby_safe_level);
+}
+
+/*
+ * call-seq:
+ * mod.autoload(name, filename) => nil
+ *
+ * Registers _filename_ to be loaded (using <code>Kernel::require</code>)
+ * the first time that _module_ (which may be a <code>String</code> or
+ * a symbol) is accessed in the namespace of _mod_.
+ *
+ * module A
+ * end
+ * A.autoload(:B, "b")
+ * A::B.doit # autoloads "b"
+ */
+
+static VALUE
+rb_mod_autoload(mod, sym, file)
+ VALUE mod;
+ VALUE sym;
+ VALUE file;
+{
+ ID id = rb_to_id(sym);
+
+ Check_SafeStr(file);
+ rb_autoload(mod, id, RSTRING(file)->ptr);
+ return Qnil;
+}
+
+/*
+ * MISSING: documentation
+ */
+
+static VALUE
+rb_mod_autoload_p(mod, sym)
+ VALUE mod, sym;
+{
+ return rb_autoload_p(mod, rb_to_id(sym));
+}
+
+/*
+ * call-seq:
+ * autoload(module, filename) => nil
+ *
+ * Registers _filename_ to be loaded (using <code>Kernel::require</code>)
+ * the first time that _module_ (which may be a <code>String</code> or
+ * a symbol) is accessed.
+ *
+ * autoload(:MyModule, "/usr/local/lib/modules/my_module.rb")
+ */
+
+static VALUE
+rb_f_autoload(obj, sym, file)
+ VALUE obj;
+ VALUE sym;
+ VALUE file;
+{
+ // TODO: fix me
+ return rb_mod_autoload(rb_cObject, sym, file);
+}
+
+
+/*
+ * MISSING: documentation
+ */
+
+static VALUE
+rb_f_autoload_p(obj, sym)
+ VALUE obj;
+ VALUE sym;
+{
+ /* use ruby_cbase() as same as rb_f_autoload. */
+ // TODO: fix me
+ return rb_mod_autoload_p(rb_cObject, sym);
+}
+
+void
+Init_load()
+{
+ rb_load_path = rb_ary_new();
+ rb_define_readonly_variable("$:", &rb_load_path);
+ rb_define_readonly_variable("$-I", &rb_load_path);
+ rb_define_readonly_variable("$LOAD_PATH", &rb_load_path);
+
+ rb_features = rb_ary_new();
+ rb_define_readonly_variable("$\"", &rb_features);
+ rb_define_readonly_variable("$LOADED_FEATURES", &rb_features);
+
+ rb_define_global_function("load", rb_f_load, -1);
+ rb_define_global_function("require", rb_f_require, 1);
+ rb_define_method(rb_cModule, "autoload", rb_mod_autoload, 2);
+ rb_define_method(rb_cModule, "autoload?", rb_mod_autoload_p, 1);
+ rb_define_global_function("autoload", rb_f_autoload, 2);
+ rb_define_global_function("autoload?", rb_f_autoload_p, 1);
+
+ ruby_dln_librefs = rb_ary_new();
+ rb_global_variable(&ruby_dln_librefs);
+}
+
Property changes on: trunk/eval_load.c
___________________________________________________________________
Name: svn:executable
+ *
Modified: trunk/eval_proc.c
===================================================================
--- trunk/eval_proc.c 2005-09-27 07:45:51 UTC (rev 263)
+++ trunk/eval_proc.c 2005-09-27 15:04:49 UTC (rev 264)
@@ -62,7 +62,7 @@
VALUE self;
{
return th_make_env_object(GET_THREAD(),
- YARV_PERVIOUS_CONTROL_FRAME(GET_THREAD()->cfp));
+ YARV_PREVIOUS_CONTROL_FRAME(GET_THREAD()->cfp));
}
/*
@@ -139,7 +139,7 @@
block = GC_GUARDED_PTR_REF(cfp->lfp[0]);
}
else{
- cfp = YARV_PERVIOUS_CONTROL_FRAME(th->cfp);
+ cfp = YARV_PREVIOUS_CONTROL_FRAME(th->cfp);
if((block = GC_GUARDED_PTR_REF(cfp->lfp[0])) != 0){
if(is_lambda){
rb_warn("tried to create Proc object without a block");
@@ -149,7 +149,7 @@
rb_raise(rb_eArgError, "tried to create Proc object without a block");
}
}
- cfp = YARV_PERVIOUS_CONTROL_FRAME(cfp);
+ cfp = YARV_PREVIOUS_CONTROL_FRAME(cfp);
procval = th_make_proc(th, cfp, block);
if(is_lambda){
Modified: trunk/test.rb
===================================================================
--- trunk/test.rb 2005-09-27 07:45:51 UTC (rev 263)
+++ trunk/test.rb 2005-09-27 15:04:49 UTC (rev 264)
@@ -1,3 +1,21 @@
+
+@arg = 0
+lambda{|@a, @b|
+ p @a, @b
+}.call 1
+
+
+
+__END__
+
+require 'test_req'
+
+# test_req.rb
+p TOPLEVEL_BINDING.__id__
+eval('p a', TOPLEVEL_BINDING)
+
+
+__END__
i=0
1.times{|j|
1.times{|k|
@@ -5,8 +23,6 @@
}
}
-
-
__END__
require 'shellwords'
--
ML: yarv-diff quickml.atdot.net
Info: http://www.atdot.net/~ko1/quickml