mirror of
https://github.com/ruby/ruby.git
synced 2026-10-29 00:46:26 +08:00
Make ISeq binaries portable
* Make `__FILE__` a frozen core method that return the iseq path. * Make `load_from_binary` accept `file, path` like compile. [Feature #17593] [Feature #22395]
This commit is contained in:
1 parent
8197d2c567
commit
9ce0df6719
5 files changed
+42
-21
Notes:
git
2026-10-07 07:58:03 +00:00
No files matched your search
@@ -96,6 +96,7 @@ firstline, predefined = __LINE__+1, %[\
|
||||
core#undef_method
|
||||
core#define_method
|
||||
core#define_singleton_method
|
||||
core#iseq_path
|
||||
core#set_postexe
|
||||
core#hash_merge_ptr
|
||||
core#hash_merge_bang_ptr
|
||||
|
||||
@@ -95,6 +95,7 @@ bool rb_str_reembeddable_p(VALUE);
|
||||
bool rb_str_embedded_shared_root_p(VALUE);
|
||||
VALUE rb_str_upto_endless_each(VALUE, int (*each)(VALUE, VALUE), VALUE);
|
||||
VALUE rb_str_with_debug_created_info(VALUE, VALUE, int);
|
||||
VALUE rb_chilled_str_with_debug_created_info(VALUE, VALUE, int);
|
||||
VALUE rb_str_frozen_bare_string(VALUE);
|
||||
const char *rb_str_null_check(VALUE);
|
||||
VALUE rb_str_casecmp(VALUE str1, VALUE str2);
|
||||
|
||||
@@ -63,6 +63,7 @@ void rb_lastline_set_up(VALUE val, unsigned int up);
|
||||
|
||||
/* vm_eval.c */
|
||||
VALUE rb_current_realfilepath(void);
|
||||
VALUE rb_current_filepath(void);
|
||||
VALUE rb_check_block_call(VALUE, ID, int, const VALUE *, rb_block_call_func_t, VALUE);
|
||||
typedef void rb_check_funcall_hook(int, VALUE, ID, int, const VALUE *, VALUE);
|
||||
VALUE rb_check_funcall_with_hook_kw(VALUE recv, ID mid, int argc, const VALUE *argv,
|
||||
|
||||
+8
-21
@@ -803,21 +803,6 @@ pm_compile_regexp_dynamic(rb_iseq_t *iseq, const pm_node_t *node, const pm_node_
|
||||
PUSH_INSN2(ret, *node_location, toregexp, INT2FIX(parse_regexp_flags(node) & 0xFF), INT2FIX(length));
|
||||
}
|
||||
|
||||
static VALUE
|
||||
pm_source_file_value(const pm_source_file_node_t *node, const pm_scope_node_t *scope_node)
|
||||
{
|
||||
const pm_string_t *filepath = &node->filepath;
|
||||
size_t length = pm_string_length(filepath);
|
||||
|
||||
if (length > 0) {
|
||||
rb_encoding *filepath_encoding = scope_node->filepath_encoding != NULL ? scope_node->filepath_encoding : rb_utf8_encoding();
|
||||
return rb_enc_interned_str((const char *) pm_string_source(filepath), length, filepath_encoding);
|
||||
}
|
||||
else {
|
||||
return rb_fstring_lit("<compiled>");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a static literal string, optionally with attached debugging
|
||||
* information.
|
||||
@@ -5764,8 +5749,6 @@ pm_compile_shareable_constant_literal(rb_iseq_t *iseq, const pm_node_t *node, pm
|
||||
return pm_static_literal_value(iseq, node, scope_node);
|
||||
case PM_STRING_NODE:
|
||||
return parse_static_literal_string(iseq, scope_node, node, &((const pm_string_node_t *) node)->unescaped);
|
||||
case PM_SOURCE_FILE_NODE:
|
||||
return pm_source_file_value((const pm_source_file_node_t *) node, scope_node);
|
||||
case PM_ARRAY_NODE: {
|
||||
const pm_array_node_t *cast = (const pm_array_node_t *) node;
|
||||
VALUE result = rb_ary_new_capa(cast->elements.size);
|
||||
@@ -10497,17 +10480,21 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
|
||||
// ^^^^^^^^
|
||||
if (!popped) {
|
||||
const pm_source_file_node_t *cast = (const pm_source_file_node_t *) node;
|
||||
VALUE string = pm_source_file_value(cast, scope_node);
|
||||
|
||||
int string_type;
|
||||
if (PM_NODE_FLAG_P(cast, PM_STRING_FLAGS_FROZEN)) {
|
||||
PUSH_INSN1(ret, location, putobject, string);
|
||||
string_type = ISEQ_FROZEN_STRING_LITERAL_ENABLED;
|
||||
}
|
||||
else if (PM_NODE_FLAG_P(cast, PM_STRING_FLAGS_MUTABLE)) {
|
||||
PUSH_INSN1(ret, location, dupstring, string);
|
||||
string_type = ISEQ_FROZEN_STRING_LITERAL_DISABLED;
|
||||
}
|
||||
else {
|
||||
PUSH_INSN1(ret, location, dupchilledstring, string);
|
||||
string_type = ISEQ_FROZEN_STRING_LITERAL_UNSET;
|
||||
}
|
||||
|
||||
PUSH_INSN1(ret, location, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
|
||||
PUSH_INSN1(ret, location, putobject, INT2FIX(string_type));
|
||||
PUSH_SEND(ret, location, id_core_iseq_path, INT2FIX(1));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -4322,6 +4322,36 @@ m_core_set_postexe(VALUE self)
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
m_core_iseq_path(VALUE self, VALUE frozen_string_literal_option_value)
|
||||
{
|
||||
rb_execution_context_t *ec = GET_EC();
|
||||
rb_control_frame_t *cfp = ec->cfp;
|
||||
cfp = vm_get_ruby_level_caller_cfp(ec, RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp));
|
||||
if (cfp == NULL) {
|
||||
return Qnil;
|
||||
}
|
||||
const rb_iseq_t *iseq = CFP_ISEQ(cfp);
|
||||
VALUE path = rb_iseq_path(iseq);
|
||||
if (RTEST(path)) {
|
||||
int frozen_string_literal_option = NUM2INT(frozen_string_literal_option_value);
|
||||
switch (frozen_string_literal_option) {
|
||||
case ISEQ_FROZEN_STRING_LITERAL_ENABLED:
|
||||
RUBY_ASSERT(OBJ_FROZEN(path));
|
||||
break;
|
||||
case ISEQ_FROZEN_STRING_LITERAL_DISABLED:
|
||||
path = rb_str_resurrect(path);
|
||||
break;
|
||||
case ISEQ_FROZEN_STRING_LITERAL_UNSET:
|
||||
path = rb_ec_str_resurrect(ec, path, true);
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE_RETURN(Qundef);
|
||||
}
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
core_hash_merge(VALUE hash, long argc, const VALUE *argv, bool dup)
|
||||
{
|
||||
@@ -4617,6 +4647,7 @@ Init_VM(void)
|
||||
rb_define_method_id(klass, id_core_set_variable_alias, m_core_set_variable_alias, 2);
|
||||
rb_define_method_id(klass, id_core_undef_method, m_core_undef_method, 2);
|
||||
rb_define_method_id(klass, id_core_set_postexe, m_core_set_postexe, 0);
|
||||
rb_define_method_id(klass, id_core_iseq_path, m_core_iseq_path, 1);
|
||||
rb_define_method_id(klass, id_core_hash_merge_ptr, m_core_hash_merge_ptr, -1);
|
||||
rb_define_method_id(klass, id_core_hash_merge_bang_ptr, m_core_hash_merge_bang_ptr, -1);
|
||||
rb_define_method_id(klass, id_core_hash_merge_kwd, m_core_hash_merge_kwd, 2);
|
||||
|
||||
Reference in new issue
Block a user