Skip to content

Commit b53dc39

Browse files
committed
Implement rb_ivar_foreach.
1 parent 3fe5fd1 commit b53dc39

File tree

4 files changed

+41
-1
lines changed

4 files changed

+41
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ Compatibility:
3232
* Match tag values used by `rb_protect` and `rb_jump_tag` for the `tk` gem (#2556, @aardvark179).
3333
* Implement `rb_eval_cmd_kw` to support the `tk` gem (#2556, @aardvark179).
3434
* Fix `rb_class2name` to call `inspect` on anonymous classes like in CRuby (#2701, @aardvark179).
35+
* Implement `rb_ivar_foreach` to iterate over instance and class variables like in CRuby (#2701, @aardvark179).
3536

3637
Performance:
3738

lib/truffle/truffle/cext.rb

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,34 @@ def rb_f_global_variables
484484
Kernel.global_variables
485485
end
486486

487+
def rb_ivar_foreach(object, func, arg)
488+
keys_and_vals = []
489+
if Module === object
490+
keys_and_vals << :__classpath__
491+
keys_and_vals << object.name
492+
493+
object.class_variables.each do |key|
494+
keys_and_vals << key
495+
keys_and_vals << object.class_variable_get(key)
496+
end
497+
end
498+
object.instance_variables.each do |key|
499+
keys_and_vals << key
500+
keys_and_vals << object.instance_variable_get(key)
501+
end
502+
503+
keys_and_vals.each_slice(2) do |key, val|
504+
st_result = Truffle::Interop.execute_without_conversion(
505+
func, Primitive.cext_sym2id(key), Primitive.cext_wrap(val), arg)
506+
507+
case st_result
508+
when ST_CONTINUE
509+
when ST_STOP then break
510+
else raise ArgumentError, "Unknown 'func' return value: #{st_result}"
511+
end
512+
end
513+
end
514+
487515
def rb_obj_instance_variables(object)
488516
object.instance_variables
489517
end

src/main/c/cext/ivar.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ VALUE rb_ivar_lookup(VALUE object, const char *name, VALUE default_value) {
5050

5151
// Needed to gem install oj
5252
void rb_ivar_foreach(VALUE obj, int (*func)(ANYARGS), st_data_t arg) {
53-
rb_tr_error("rb_ivar_foreach not implemented");
53+
polyglot_invoke(RUBY_CEXT, "rb_ivar_foreach", rb_tr_unwrap(obj), func, (void*)arg);
5454
}
5555

5656
VALUE rb_attr_get(VALUE object, ID name) {

src/main/java/org/truffleruby/cext/CExtNodes.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1530,6 +1530,17 @@ protected int rbEncMbcToCodepoint(Object string,
15301530
}
15311531
}
15321532

1533+
@Primitive(name = "cext_sym2id")
1534+
public abstract static class Sym2IDNode extends PrimitiveArrayArgumentsNode {
1535+
1536+
@Specialization
1537+
protected Object sym2id(RubySymbol symbol,
1538+
@Cached SymbolToIDNode symbolToIDNode) {
1539+
return symbolToIDNode.execute(symbol);
1540+
}
1541+
1542+
}
1543+
15331544
@Primitive(name = "cext_wrap")
15341545
public abstract static class WrapValueNode extends PrimitiveArrayArgumentsNode {
15351546

0 commit comments

Comments
 (0)