43514.patch 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. Index: load.c
  2. ===================================================================
  3. --- a/load.c (revision 43513)
  4. +++ b/load.c (revision 43514)
  5. @@ -8,6 +8,7 @@
  6. #include "dln.h"
  7. #include "eval_intern.h"
  8. #include "probes.h"
  9. +#include "node.h"
  10. VALUE ruby_dln_librefs;
  11. @@ -482,6 +483,9 @@
  12. else {
  13. VALUE bufstr;
  14. char *buf;
  15. + static const char so_ext[][4] = {
  16. + ".so", ".o",
  17. + };
  18. if (ext && *ext) return 0;
  19. bufstr = rb_str_tmp_new(len + DLEXT_MAXLEN);
  20. @@ -495,6 +499,14 @@
  21. return i ? 's' : 'r';
  22. }
  23. }
  24. + for (i = 0; i < numberof(so_ext); i++) {
  25. + strlcpy(buf + len, so_ext[i], DLEXT_MAXLEN + 1);
  26. + if (st_get_key(loading_tbl, (st_data_t)buf, &data)) {
  27. + rb_str_resize(bufstr, 0);
  28. + if (fn) *fn = (const char*)data;
  29. + return 's';
  30. + }
  31. + }
  32. rb_str_resize(bufstr, 0);
  33. }
  34. }
  35. @@ -709,6 +721,14 @@
  36. st_insert(loading_tbl, (st_data_t)ftptr, data);
  37. return (char *)ftptr;
  38. }
  39. + else if (RB_TYPE_P((VALUE)data, T_NODE) && nd_type((VALUE)data) == NODE_MEMO) {
  40. + NODE *memo = RNODE(data);
  41. + void (*init)(void) = (void (*)(void))memo->nd_cfnc;
  42. + data = (st_data_t)rb_thread_shield_new();
  43. + st_insert(loading_tbl, (st_data_t)ftptr, data);
  44. + (*init)();
  45. + return (char *)"";
  46. + }
  47. if (RTEST(ruby_verbose)) {
  48. rb_warning("loading in progress, circular require considered harmful - %s", ftptr);
  49. rb_backtrace_print_to(rb_stderr);
  50. @@ -881,13 +901,16 @@
  51. switch (type) {
  52. case 0:
  53. if (ft)
  54. - break;
  55. + goto statically_linked;
  56. ftptr = RSTRING_PTR(tmp);
  57. return rb_feature_p(ftptr, 0, FALSE, TRUE, 0);
  58. default:
  59. - if (ft)
  60. - break;
  61. + if (ft) {
  62. + statically_linked:
  63. + if (loading) *path = rb_filesystem_str_new_cstr(loading);
  64. + return ft;
  65. + }
  66. case 1:
  67. ext = strrchr(ftptr = RSTRING_PTR(tmp), '.');
  68. if (rb_feature_p(ftptr, ext, !--type, TRUE, &loading) && !loading)
  69. @@ -957,6 +980,10 @@
  70. if (!path || !(ftptr = load_lock(RSTRING_PTR(path)))) {
  71. result = Qfalse;
  72. }
  73. + else if (!*ftptr) {
  74. + rb_provide_feature(path);
  75. + result = Qtrue;
  76. + }
  77. else {
  78. switch (found) {
  79. case 'r':
  80. @@ -1005,26 +1032,30 @@
  81. return rb_require_safe(fn, rb_safe_level());
  82. }
  83. -static VALUE
  84. -init_ext_call(VALUE arg)
  85. +static int
  86. +register_init_ext(st_data_t *key, st_data_t *value, st_data_t init, int existing)
  87. {
  88. - SCOPE_SET(NOEX_PUBLIC);
  89. - (*(void (*)(void))arg)();
  90. - return Qnil;
  91. + const char *name = (char *)*key;
  92. + if (existing) {
  93. + /* already registered */
  94. + rb_warn("%s is already registered", name);
  95. + }
  96. + else {
  97. + *value = (st_data_t)NEW_MEMO(init, 0, 0);
  98. + *key = (st_data_t)ruby_strdup(name);
  99. + }
  100. + return ST_CONTINUE;
  101. }
  102. RUBY_FUNC_EXPORTED void
  103. ruby_init_ext(const char *name, void (*init)(void))
  104. {
  105. - char* const lock_key = load_lock(name);
  106. - if (lock_key) {
  107. - VALUE feature = rb_usascii_str_new_cstr(name);
  108. - OBJ_FREEZE(feature);
  109. - rb_vm_call_cfunc(rb_vm_top_self(), init_ext_call, (VALUE)init,
  110. - 0, feature);
  111. - rb_provide_feature(feature);
  112. - load_unlock(lock_key, 1);
  113. + st_table *loading_tbl = get_loading_table();
  114. +
  115. + if (!loading_tbl) {
  116. + GET_VM()->loading_table = loading_tbl = st_init_strtable();
  117. }
  118. + st_update(loading_tbl, (st_data_t)name, register_init_ext, (st_data_t)init);
  119. }
  120. /*