Skip to content

Instantly share code, notes, and snippets.

@aarvay
Created March 27, 2012 08:01
Show Gist options
  • Save aarvay/2213865 to your computer and use it in GitHub Desktop.
Save aarvay/2213865 to your computer and use it in GitHub Desktop.
Require Hack Patch
--- load-head.c 2012-03-27 11:29:29.000000000 +0530
+++ load.c 2012-03-27 11:26:22.000000000 +0530
@@ -4,21 +4,19 @@
#include "ruby/ruby.h"
#include "ruby/util.h"
-#include "internal.h"
#include "dln.h"
#include "eval_intern.h"
-
+#include "assert.h"
VALUE ruby_dln_librefs;
-#define IS_RBEXT(e) (strcmp((e), ".rb") == 0)
-#define IS_SOEXT(e) (strcmp((e), ".so") == 0 || strcmp((e), ".o") == 0)
+#define IS_RBEXT(e) (strcmp(e, ".rb") == 0)
+#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)
+#define IS_DLEXT(e) (strcmp(e, DLEXT) == 0 || strcmp(e, DLEXT2) == 0)
#else
-#define IS_DLEXT(e) (strcmp((e), DLEXT) == 0)
+#define IS_DLEXT(e) (strcmp(e, DLEXT) == 0)
#endif
-
static const char *const loadable_ext[] = {
".rb", DLEXT,
#ifdef DLEXT2
@@ -27,6 +25,26 @@
0
};
+static void
+print_str_ary(VALUE ary)
+{
+ long n = RARRAY_LEN(ary);
+ long i;
+ printf("\n{\n");
+
+ for(i =0; i < n; i++)
+ {
+ printf("%s,\n", RSTRING_PTR( RARRAY_PTR(ary)[i]));
+ }
+ printf("}\n");
+}
+
+static void
+print_str(VALUE ary)
+{
+ printf("%s\n" , RSTRING_PTR( ary));
+}
+
VALUE
rb_get_load_path(void)
{
@@ -64,47 +82,41 @@
}
static st_table *
+get_dollar_quote(void)
+{
+ return GET_VM()-> dollar_quote;
+}
+static st_table *
get_loading_table(void)
{
return GET_VM()->loading_table;
}
static VALUE
-loaded_feature_path(const char *name, long vlen, const char *feature, long len,
- int type, VALUE load_path)
+loaded_feature_path(const char *name, long vlen, const char *feature, long len, int type, VALUE load_path)
{
long i;
- long plen;
- const char *e;
-
- if(vlen < len) return 0;
- if (!strncmp(name+(vlen-len),feature,len)){
- plen = vlen - len - 1;
- } else {
- for (e = name + vlen; name != e && *e != '.' && *e != '/'; --e);
- if (*e!='.' ||
- e-name < len ||
- strncmp(e-len,feature,len) )
- return 0;
- plen = e - name - len - 1;
- }
+
for (i = 0; i < RARRAY_LEN(load_path); ++i) {
- VALUE p = RARRAY_PTR(load_path)[i];
- const char *s = StringValuePtr(p);
- long n = RSTRING_LEN(p);
-
- if (n != plen ) continue;
- if (n && (strncmp(name, s, n) || name[n] != '/')) continue;
- switch (type) {
- case 's':
- if (IS_DLEXT(&name[n+len+1])) return p;
- break;
- case 'r':
- if (IS_RBEXT(&name[n+len+1])) return p;
- break;
- default:
- return p;
- }
+ VALUE p = RARRAY_PTR(load_path)[i];
+ const char *s = StringValuePtr(p);
+ long n = RSTRING_LEN(p);
+ if (vlen < n + len + 1) continue;
+ if (n && (strncmp(name, s, n) || name[n] != '/')) continue;
+ if (strncmp(name + n + 1, feature, len)) continue;
+ if (name[n+len+1] && name[n+len+1] != '.') continue;
+ switch (type) {
+ case 's':
+ if (IS_DLEXT(&name[n+len+1])) return p;
+ break;
+ case 'r':
+ if (IS_RBEXT(&name[n+len+1])){
+ return p;
+ }
+ break;
+ default:
+ return p;
+ }
}
return 0;
}
@@ -134,87 +146,144 @@
{
VALUE v, features, p, load_path = 0;
const char *f, *e;
- long i, len, elen, n;
+ long i, j, len, elen, n;
st_table *loading_tbl;
st_data_t data;
int type;
+ int already_found = 0;
if (fn) *fn = 0;
if (ext) {
- elen = strlen(ext);
- len = strlen(feature) - elen;
- type = rb ? 'r' : 's';
+ elen= strlen(ext);
+ len = strlen(feature) - elen;
+ type = rb ? 'r' : 's';
}
else {
- len = strlen(feature);
- elen = 0;
- type = 0;
+ len = strlen(feature);
+ elen = 0;
+ type = 0;
}
+
features = get_loaded_features();
- for (i = 0; i < RARRAY_LEN(features); ++i) {
- v = RARRAY_PTR(features)[i];
- f = StringValuePtr(v);
- if ((n = RSTRING_LEN(v)) < len) continue;
- if (strncmp(f, feature, len) != 0) {
- if (expanded) continue;
- if (!load_path) load_path = rb_get_expanded_load_path();
- if (!(p = loaded_feature_path(f, n, feature, len, type, load_path)))
- continue;
- expanded = 1;
- f += RSTRING_LEN(p) + 1;
- }
- 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) && (IS_RBEXT(e))) {
- return 'r';
- }
+ char *which = feature ;
+ int found = 0 ;
+ found = st_lookup( get_dollar_quote() , feature , &found ) ;
+ if ( !ext && !found ){
+ for ( i = 0 ; loadable_ext[i] ; i ++ ) {
+
+ char *t = (char *) malloc( strlen(feature) + strlen(loadable_ext[i]) + 1 );
+ strcpy(t,feature);
+ strcat(t,loadable_ext[i]);
+ int temp;
+ temp = st_lookup( get_dollar_quote() , t , &temp );
+ if ( temp ) {
+ found = 1 ;
+ expanded = 1 ;
+ which = t ;
+ break;
+ }
+ }
+ }
+
+ if ( !expanded && !found ) {
+ load_path = rb_get_expanded_load_path();
+ for (i = 0; i < RARRAY_LEN(load_path) && !found; ++i) {
+ VALUE path = RARRAY_PTR(load_path)[i];
+ char *s = StringValuePtr(path);
+ strcat(s,"/");
+ strcat(s,feature);
+ if (ext) {
+ int temp = 0 ;
+ temp = st_lookup( get_dollar_quote() , s , &temp );
+ if (temp) {
+ found = 1 ;
+ which = s ;
+ expanded = 1 ;
+ break;
+ }
+ }
+ else {
+ for ( j = 0 ; loadable_ext[j] ; j++ ) {
+
+ char *t = (char *) malloc( strlen(s) + strlen(loadable_ext[j]) + 1 );
+ strcpy(t,s);
+ strcat(t,loadable_ext[j] );
+ int temp;
+ temp = st_lookup( get_dollar_quote() , t , &temp );
+ if (temp) {
+ found = 1 ;
+ expanded = 1 ;
+ which = t ;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ char ret = 0 ;
+ if ( found ){
+ e = strrchr( which , '.');
+ if ( !*e ){
+ if ( !ext ){
+ ret = 'u';
+ return 'u';
+ }
+ }
+ if ( *e == '.' ){
+ if ((!rb || !ext) && (IS_SOEXT(e) || IS_DLEXT(e))) {
+ ret = 's';
+ return 's';
+ }
+ if ((rb || !ext) && (IS_RBEXT(e))) {
+ ret ='r';
+ return 'r';
+ }
+ }
}
+
loading_tbl = get_loading_table();
if (loading_tbl) {
- f = 0;
- if (!expanded) {
- struct loaded_feature_searching fs;
- fs.name = feature;
- fs.len = len;
- fs.type = type;
- fs.load_path = load_path ? load_path : rb_get_expanded_load_path();
- fs.result = 0;
- st_foreach(loading_tbl, loaded_feature_path_i, (st_data_t)&fs);
- if ((f = fs.result) != 0) {
- if (fn) *fn = f;
- goto loading;
- }
- }
- if (st_get_key(loading_tbl, (st_data_t)feature, &data)) {
- if (fn) *fn = (const char*)data;
- loading:
- if (!ext) return 'u';
- return !IS_RBEXT(ext) ? 's' : 'r';
- }
- else {
- VALUE bufstr;
- char *buf;
-
- if (ext && *ext) return 0;
- bufstr = rb_str_tmp_new(len + DLEXT_MAXLEN);
- buf = RSTRING_PTR(bufstr);
- MEMCPY(buf, feature, char, len);
- for (i = 0; (e = loadable_ext[i]) != 0; i++) {
- strlcpy(buf + len, e, DLEXT_MAXLEN + 1);
- if (st_get_key(loading_tbl, (st_data_t)buf, &data)) {
- rb_str_resize(bufstr, 0);
- if (fn) *fn = (const char*)data;
- return i ? 's' : 'r';
- }
- }
- rb_str_resize(bufstr, 0);
- }
+ f = 0;
+ if (!expanded) {
+ struct loaded_feature_searching fs;
+ fs.name = feature;
+ fs.len = len;
+ fs.type = type;
+ fs.load_path = load_path ? load_path : rb_get_load_path();
+ fs.result = 0;
+ st_foreach(loading_tbl, loaded_feature_path_i, (st_data_t)&fs);
+ if ((f = fs.result) != 0) {
+ if (fn) *fn = f;
+ if (!ext) return 'u';
+ return !IS_RBEXT(ext) ? 's' : 'r';
+ }
+ }
+ if (st_get_key(loading_tbl, (st_data_t)feature, &data)) {
+ if (fn) *fn = (const char*)data;
+ if (!ext) return 'u';
+ return !IS_RBEXT(ext) ? 's' : 'r';
+ }
+ else {
+ VALUE bufstr;
+ char *buf;
+
+ if (ext && *ext){
+ return 0;
+ }
+ bufstr = rb_str_tmp_new(len + DLEXT_MAXLEN);
+ buf = RSTRING_PTR(bufstr);
+ MEMCPY(buf, feature, char, len);
+ for (i = 0; (e = loadable_ext[i]) != 0; i++) {
+ strlcpy(buf + len, e, DLEXT_MAXLEN + 1);
+ if (st_get_key(loading_tbl, (st_data_t)buf, &data)) {
+ rb_str_resize(bufstr, 0);
+ if (fn) *fn = (const char*)data;
+ return i ? 's' : 'r';
+ }
+ }
+ rb_str_resize(bufstr, 0);
+ }
}
return 0;
}
@@ -230,35 +299,30 @@
{
const char *ext = strrchr(feature, '.');
volatile VALUE fullpath = 0;
-
if (*feature == '.' &&
- (feature[1] == '/' || strncmp(feature+1, "./", 2) == 0)) {
- fullpath = rb_file_expand_path(rb_str_new2(feature), Qnil);
- feature = RSTRING_PTR(fullpath);
+ (feature[1] == '/' || strncmp(feature+1, "./", 2) == 0)) {
+ fullpath = rb_file_expand_path(rb_str_new2(feature), Qnil);
+ feature = RSTRING_PTR(fullpath);
}
if (ext && !strchr(ext, '/')) {
- if (IS_RBEXT(ext)) {
- if (rb_feature_p(feature, ext, TRUE, FALSE, loading)) return TRUE;
- return FALSE;
- }
- else if (IS_SOEXT(ext) || IS_DLEXT(ext)) {
- if (rb_feature_p(feature, ext, FALSE, FALSE, loading)) return TRUE;
- return FALSE;
- }
+ if (IS_RBEXT(ext)) {
+ if (rb_feature_p(feature, ext, TRUE, FALSE, loading)) return TRUE;
+ return FALSE;
+ }
+ else if (IS_SOEXT(ext) || IS_DLEXT(ext)) {
+ if (rb_feature_p(feature, ext, FALSE, FALSE, loading)) return TRUE;
+ return FALSE;
+ }
}
if (rb_feature_p(feature, 0, TRUE, FALSE, loading))
- return TRUE;
+ return TRUE;
return FALSE;
}
static void
rb_provide_feature(VALUE feature)
{
- if (OBJ_FROZEN(get_loaded_features())) {
- rb_raise(rb_eRuntimeError,
- "$LOADED_FEATURES is frozen; cannot append feature");
- }
- rb_ary_push(get_loaded_features(), feature);
+ st_add_direct( get_dollar_quote() , StringValuePtr(feature) , 42 );
}
void
@@ -305,7 +369,7 @@
th->mild_compile_error++;
node = (NODE *)rb_load_file(RSTRING_PTR(fname));
loaded = TRUE;
- iseq = rb_iseq_new_top(node, rb_str_new2("<top (required)>"), fname, rb_realpath_internal(Qnil, fname, 1), Qfalse);
+ iseq = rb_iseq_new_top(node, rb_str_new2("<top (required)>"), fname, fname, Qfalse);
th->mild_compile_error--;
rb_iseq_eval(iseq);
}
@@ -405,27 +469,7 @@
rb_warning("loading in progress, circular require considered harmful - %s", ftptr);
rb_backtrace();
}
- switch (rb_barrier_wait((VALUE)data)) {
- case Qfalse:
- data = (st_data_t)ftptr;
- st_delete(loading_tbl, &data, 0);
- return 0;
- case Qnil:
- return 0;
- }
- return (char *)ftptr;
-}
-
-static int
-release_barrier(st_data_t key, st_data_t *value, st_data_t done)
-{
- VALUE barrier = (VALUE)*value;
- if (done ? rb_barrier_destroy(barrier) : rb_barrier_release(barrier)) {
- /* still in-use */
- return ST_CONTINUE;
- }
- xfree((char *)key);
- return ST_DELETE;
+ return RTEST(rb_barrier_wait((VALUE)data)) ? (char *)ftptr : 0;
}
static void
@@ -433,47 +477,41 @@
{
if (ftptr) {
st_data_t key = (st_data_t)ftptr;
+ st_data_t data;
st_table *loading_tbl = get_loading_table();
- st_update(loading_tbl, key, release_barrier, done);
+ if (st_delete(loading_tbl, &key, &data)) {
+ VALUE barrier = (VALUE)data;
+ xfree((char *)key);
+ if (done)
+ rb_barrier_destroy(barrier);
+ else
+ rb_barrier_release(barrier);
+ }
}
}
/*
* call-seq:
- * require(name) -> true or false
+ * require(string) -> true or false
*
- * Loads the given +name+, returning +true+ if successful and +false+ if the
- * feature is already loaded.
- *
- * If the filename does not resolve to an absolute path, it will be searched
- * for in the directories listed in <code>$LOAD_PATH</code> (<code>$:</code>).
- *
- * If the filename has the extension ".rb", it is loaded as a source file; if
- * the extension is ".so", ".o", or ".dll", or the default shared library
- * extension 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 until found. If the file named cannot be found, a LoadError
- * will be raised.
- *
- * For Ruby extensions the filename given may use any shared library
- * extension. For example, on Linux the socket extension is "socket.so" and
- * <code>require 'socket.dll'</code> will load the socket extension.
- *
- * The absolute path of the loaded file is added to
- * <code>$LOADED_FEATURES</code> (<code>$"</code>). A file will not be
- * loaded again if its path already appears in <code>$"</code>. For example,
- * <code>require 'a'; require './a'</code> will not load <code>a.rb</code>
- * again.
- *
- * require "my-library.rb"
- * require "db-driver"
- *
- * Any constants or globals within the loaded source file will be available
- * in the calling program's global namespace. However, local variables will
- * not be propagated to the loading environment.
+ * Ruby tries to load the library named _string_, returning
+ * +true+ if successful. If the filename does not resolve to
+ * an absolute path, it will be searched for in the directories listed
+ * in <code>$:</code>. If the file has the extension ``.rb'', it is
+ * loaded as a source file; if the extension is ``.so'', ``.o'', or
+ * ``.dll'', or whatever the default shared library extension is on
+ * the current platform, Ruby loads the shared library as a Ruby
+ * extension. Otherwise, Ruby tries adding ``.rb'', ``.so'', and so on
+ * to the name. The name of the loaded feature is added to the array in
+ * <code>$"</code>. A feature will not be loaded if its name already
+ * appears in <code>$"</code>. The file name is converted to an absolute
+ * path, so ``<code>require 'a'; require './a'</code>'' will not load
+ * <code>a.rb</code> twice.
*
+ * require "my-library.rb"
+ * require "db-driver"
*/
VALUE
@@ -482,20 +520,13 @@
return rb_require_safe(fname, rb_safe_level());
}
-/*
- * call-seq:
- * require_relative(string) -> true or false
- *
- * Ruby tries to load the library named _string_ relative to the requiring
- * file's path. If the file's path cannot be determined a LoadError is raised.
- * If a file is loaded +true+ is returned and false otherwise.
- */
VALUE
rb_f_require_relative(VALUE obj, VALUE fname)
{
+ VALUE rb_current_realfilepath(void);
VALUE base = rb_current_realfilepath();
if (NIL_P(base)) {
- rb_loaderror("cannot infer basepath");
+ rb_raise(rb_eLoadError, "cannot infer basepath");
}
base = rb_file_dirname(base);
return rb_require_safe(rb_file_absolute_path(fname, base), rb_safe_level());
@@ -512,78 +543,80 @@
*path = 0;
ext = strrchr(ftptr = RSTRING_PTR(fname), '.');
if (ext && !strchr(ext, '/')) {
- if (IS_RBEXT(ext)) {
- if (rb_feature_p(ftptr, ext, TRUE, FALSE, &loading)) {
- if (loading) *path = rb_str_new2(loading);
- return 'r';
- }
- if ((tmp = rb_find_file_safe(fname, safe_level)) != 0) {
- ext = strrchr(ftptr = RSTRING_PTR(tmp), '.');
- if (!rb_feature_p(ftptr, ext, TRUE, TRUE, &loading) || loading)
- *path = tmp;
- return 'r';
- }
- return 0;
- }
- else if (IS_SOEXT(ext)) {
- if (rb_feature_p(ftptr, ext, FALSE, FALSE, &loading)) {
- if (loading) *path = rb_str_new2(loading);
- return 's';
- }
- tmp = rb_str_new(RSTRING_PTR(fname), ext - RSTRING_PTR(fname));
+ if (IS_RBEXT(ext)) {
+ if (rb_feature_p(ftptr, ext, TRUE, FALSE, &loading)) {
+ if (loading)
+ *path = rb_str_new2(loading);
+ return 'r';
+ }
+ if ((tmp = rb_find_file_safe(fname, safe_level)) != 0) {
+ ext = strrchr(ftptr = RSTRING_PTR(tmp), '.');
+ if (!rb_feature_p(ftptr, ext, TRUE, TRUE, &loading) || loading)
+ *path = tmp;
+ return 'r';
+ }
+ return 0;
+ }
+ else if (IS_SOEXT(ext)) {
+ if (rb_feature_p(ftptr, ext, FALSE, FALSE, &loading)) {
+ if (loading) *path = rb_str_new2(loading);
+ return 's';
+ }
+ tmp = rb_str_new(RSTRING_PTR(fname), ext - RSTRING_PTR(fname));
#ifdef DLEXT2
- OBJ_FREEZE(tmp);
- if (rb_find_file_ext_safe(&tmp, loadable_ext + 1, safe_level)) {
- ext = strrchr(ftptr = RSTRING_PTR(tmp), '.');
- if (!rb_feature_p(ftptr, ext, FALSE, TRUE, &loading) || loading)
- *path = tmp;
- return 's';
- }
+ OBJ_FREEZE(tmp);
+ if (rb_find_file_ext_safe(&tmp, loadable_ext + 1, safe_level)) {
+ ext = strrchr(ftptr = RSTRING_PTR(tmp), '.');
+ if (!rb_feature_p(ftptr, ext, FALSE, TRUE, &loading) || loading)
+ *path = tmp;
+ return 's';
+ }
#else
- rb_str_cat2(tmp, DLEXT);
- OBJ_FREEZE(tmp);
- if ((tmp = rb_find_file_safe(tmp, safe_level)) != 0) {
- ext = strrchr(ftptr = RSTRING_PTR(tmp), '.');
- if (!rb_feature_p(ftptr, ext, FALSE, TRUE, &loading) || loading)
- *path = tmp;
- return 's';
- }
+ rb_str_cat2(tmp, DLEXT);
+ OBJ_FREEZE(tmp);
+ if ((tmp = rb_find_file_safe(tmp, safe_level)) != 0) {
+ ext = strrchr(ftptr = RSTRING_PTR(tmp), '.');
+ if (!rb_feature_p(ftptr, ext, FALSE, TRUE, &loading) || loading)
+ *path = tmp;
+ return 's';
+ }
#endif
- }
- else if (IS_DLEXT(ext)) {
- if (rb_feature_p(ftptr, ext, FALSE, FALSE, &loading)) {
- if (loading) *path = rb_str_new2(loading);
- return 's';
- }
- if ((tmp = rb_find_file_safe(fname, safe_level)) != 0) {
- ext = strrchr(ftptr = RSTRING_PTR(tmp), '.');
- if (!rb_feature_p(ftptr, ext, FALSE, TRUE, &loading) || loading)
- *path = tmp;
- return 's';
- }
- }
+ }
+ else if (IS_DLEXT(ext)) {
+ if (rb_feature_p(ftptr, ext, FALSE, FALSE, &loading)) {
+ if (loading) *path = rb_str_new2(loading);
+ return 's';
+ }
+ if ((tmp = rb_find_file_safe(fname, safe_level)) != 0) {
+ ext = strrchr(ftptr = RSTRING_PTR(tmp), '.');
+ if (!rb_feature_p(ftptr, ext, FALSE, TRUE, &loading) || loading)
+ *path = tmp;
+ return 's';
+ }
+ }
}
else if ((ft = rb_feature_p(ftptr, 0, FALSE, FALSE, &loading)) == 'r') {
- if (loading) *path = rb_str_new2(loading);
- return 'r';
+ if (loading) *path = rb_str_new2(loading);
+ return 'r';
}
+
tmp = fname;
type = rb_find_file_ext_safe(&tmp, loadable_ext, safe_level);
switch (type) {
- case 0:
- if (ft)
- break;
- ftptr = RSTRING_PTR(tmp);
- return rb_feature_p(ftptr, 0, FALSE, TRUE, 0);
-
- default:
- if (ft)
- break;
- case 1:
- ext = strrchr(ftptr = RSTRING_PTR(tmp), '.');
- if (rb_feature_p(ftptr, ext, !--type, TRUE, &loading) && !loading)
- break;
- *path = tmp;
+ case 0:
+ if (ft)
+ break;
+ ftptr = RSTRING_PTR(tmp);
+ return rb_feature_p(ftptr, 0, FALSE, TRUE, 0);
+
+ default:
+ if (ft)
+ break;
+ case 1:
+ ext = strrchr(ftptr = RSTRING_PTR(tmp), '.');
+ if (rb_feature_p(ftptr, ext, !--type, TRUE, &loading) && !loading)
+ break;
+ *path = tmp;
}
return type ? 's' : 'r';
}
@@ -591,7 +624,9 @@
static void
load_failed(VALUE fname)
{
- rb_load_fail(fname, "cannot load such file");
+ VALUE mesg = rb_str_buf_new_cstr("no such file to load -- ");
+ rb_str_append(mesg, fname); /* should be ASCII compatible */
+ rb_exc_raise(rb_exc_new3(rb_eLoadError, mesg));
}
static VALUE
@@ -609,52 +644,52 @@
volatile VALUE errinfo = th->errinfo;
int state;
struct {
- int safe;
+ int safe;
} volatile saved;
char *volatile ftptr = 0;
PUSH_TAG();
saved.safe = rb_safe_level();
if ((state = EXEC_TAG()) == 0) {
- VALUE path;
- long handle;
- int found;
-
- rb_set_safe_level_force(safe);
- FilePathValue(fname);
- rb_set_safe_level_force(0);
- found = search_required(fname, &path, safe);
- if (found) {
- if (!path || !(ftptr = load_lock(RSTRING_PTR(path)))) {
- result = Qfalse;
- }
- else {
- switch (found) {
- case 'r':
- rb_load_internal(path, 0);
- break;
-
- case 's':
- handle = (long)rb_vm_call_cfunc(rb_vm_top_self(), load_ext,
- path, 0, path);
- rb_ary_push(ruby_dln_librefs, LONG2NUM(handle));
- break;
- }
- rb_provide_feature(path);
- result = Qtrue;
- }
- }
+ VALUE path;
+ long handle;
+ int found;
+
+ rb_set_safe_level_force(safe);
+ FilePathValue(fname);
+ rb_set_safe_level_force(0);
+ found = search_required(fname, &path, safe);
+ if (found) {
+ if (!path || !(ftptr = load_lock(RSTRING_PTR(path)))) {
+ result = Qfalse;
+ }
+ else {
+ switch (found) {
+ case 'r':
+ rb_load_internal(path, 0);
+ break;
+
+ case 's':
+ handle = (long)rb_vm_call_cfunc(rb_vm_top_self(), load_ext,
+ path, 0, path, path);
+ rb_ary_push(ruby_dln_librefs, LONG2NUM(handle));
+ break;
+ }
+ rb_provide_feature(path);
+ result = Qtrue;
+ }
+ }
}
POP_TAG();
load_unlock(ftptr, !state);
rb_set_safe_level_force(saved.safe);
if (state) {
- JUMP_TAG(state);
+ JUMP_TAG(state);
}
if (NIL_P(result)) {
- load_failed(fname);
+ load_failed(fname);
}
th->errinfo = errinfo;
@@ -678,15 +713,14 @@
return Qnil;
}
-RUBY_FUNC_EXPORTED void
+void
ruby_init_ext(const char *name, void (*init)(void))
{
- char* const lock_key = load_lock(name);
- if (lock_key) {
+ if (load_lock(name)) {
rb_vm_call_cfunc(rb_vm_top_self(), init_ext_call, (VALUE)init,
- 0, rb_str_new2(name));
+ 0, rb_str_new2(name), Qnil);
rb_provide(name);
- load_unlock(lock_key, 1);
+ load_unlock(name, 1);
}
}
@@ -730,11 +764,7 @@
static VALUE
rb_mod_autoload_p(VALUE mod, VALUE sym)
{
- ID id = rb_check_id(&sym);
- if (!id) {
- return Qnil;
- }
- return rb_autoload_p(mod, id);
+ return rb_autoload_p(mod, rb_to_id(sym));
}
/*
@@ -751,7 +781,7 @@
static VALUE
rb_f_autoload(VALUE obj, VALUE sym, VALUE file)
{
- VALUE klass = rb_class_real(rb_vm_cbase());
+ VALUE klass = rb_vm_cbase();
if (NIL_P(klass)) {
rb_raise(rb_eTypeError, "Can not set autoload on singleton class");
}
@@ -780,12 +810,19 @@
return rb_mod_autoload_p(klass, sym);
}
+VALUE
+append_load_path(VALUE ary, VALUE path)
+{
+ return rb_ary_push(ary, path);
+}
+
void
Init_load()
{
#undef rb_intern
-#define rb_intern(str) rb_intern2((str), strlen(str))
+#define rb_intern(str) rb_intern2(str, strlen(str))
rb_vm_t *vm = GET_VM();
+
static const char var_load_path[] = "$:";
ID id_load_path = rb_intern2(var_load_path, sizeof(var_load_path)-1);
@@ -796,7 +833,11 @@
rb_define_virtual_variable("$\"", get_loaded_features, 0);
rb_define_virtual_variable("$LOADED_FEATURES", get_loaded_features, 0);
- vm->loaded_features = rb_ary_new();
+ vm->loaded_features = rb_ary_new();
+ rb_define_singleton_method(vm->load_path, "<<", append_load_path, 1);
+ rb_define_singleton_method(vm->load_path, "unshift", append_load_path, 1);
+ vm -> dollar_quote = st_init_strtable();
+
rb_define_global_function("load", rb_f_load, -1);
rb_define_global_function("require", rb_f_require, 1);
@@ -808,4 +849,5 @@
ruby_dln_librefs = rb_ary_new();
rb_gc_register_mark_object(ruby_dln_librefs);
-}
\ No newline at end of file
+
+}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment