зеркало из https://github.com/github/ruby.git
[YARP] Fix variables in compilation (#8326)
* [YARP] Fixed several popped instructions * [YARP] Correctly compiling class path
This commit is contained in:
Родитель
6599ca44bb
Коммит
f1790fa4e7
|
@ -50,7 +50,7 @@ module YARP
|
|||
############################################################################
|
||||
|
||||
def test_ClassVariableReadNode
|
||||
# assert_equal 1, compile("class YARP::CompilerTest; @@yct = 1; end; @@yct")
|
||||
assert_equal 1, compile("class YARP::CompilerTest; @@yct = 1; @@yct; end")
|
||||
end
|
||||
|
||||
def test_ConstantPathNode
|
||||
|
@ -62,11 +62,11 @@ module YARP
|
|||
end
|
||||
|
||||
def test_GlobalVariableReadNode
|
||||
# assert_equal 1, compile("$yct = 1; $yct")
|
||||
assert_equal 1, compile("$yct = 1; $yct")
|
||||
end
|
||||
|
||||
def test_InstanceVariableReadNode
|
||||
# assert_equal 1, compile("class YARP::CompilerTest; @yct = 1; @yct; end")
|
||||
assert_equal 1, compile("class YARP::CompilerTest; @yct = 1; @yct; end")
|
||||
end
|
||||
|
||||
############################################################################
|
||||
|
@ -74,7 +74,7 @@ module YARP
|
|||
############################################################################
|
||||
|
||||
def test_ClassVariableWriteNode
|
||||
# assert_equal 1, compile("class YARP::CompilerTest; @@yct = 1; end")
|
||||
assert_equal 1, compile("class YARP::CompilerTest; @@yct = 1; end")
|
||||
end
|
||||
|
||||
def test_ConstantWriteNode
|
||||
|
@ -90,7 +90,7 @@ module YARP
|
|||
end
|
||||
|
||||
def test_InstanceVariableWriteNode
|
||||
# assert_equal 1, compile("class YARP::CompilerTest; @yct = 1; end")
|
||||
assert_equal 1, compile("class YARP::CompilerTest; @yct = 1; end")
|
||||
end
|
||||
|
||||
############################################################################
|
||||
|
@ -100,17 +100,17 @@ module YARP
|
|||
def test_EmbeddedVariableNode
|
||||
# assert_equal "1", compile('class YARP::CompilerTest; @yct = 1; "#@yct"; end')
|
||||
# assert_equal "1", compile('class YARP::CompilerTest; @@yct = 1; "#@@yct"; end')
|
||||
# assert_equal "1", compile('$yct = 1; "#$yct"')
|
||||
assert_equal "1", compile('$yct = 1; "#$yct"')
|
||||
end
|
||||
|
||||
def test_InterpolatedStringNode
|
||||
# assert_equal "1 1 1", compile('$yct = 1; "1 #$yct 1"')
|
||||
# assert_equal "1 3 1", compile('"1 #{1 + 2} 1"')
|
||||
assert_equal "1 1 1", compile('$yct = 1; "1 #$yct 1"')
|
||||
assert_equal "1 3 1", compile('"1 #{1 + 2} 1"')
|
||||
end
|
||||
|
||||
def test_InterpolatedSymbolNode
|
||||
# assert_equal :"1 1 1", compile('$yct = 1; :"1 #$yct 1"')
|
||||
# assert_equal :"1 3 1", compile(':"1 #{1 + 2} 1"')
|
||||
assert_equal :"1 1 1", compile('$yct = 1; :"1 #$yct 1"')
|
||||
assert_equal :"1 3 1", compile(':"1 #{1 + 2} 1"')
|
||||
end
|
||||
|
||||
def test_StringConcatNode
|
||||
|
|
|
@ -186,7 +186,7 @@ again:
|
|||
DECL_ANCHOR(cond_seq);
|
||||
INIT_ANCHOR(cond_seq);
|
||||
|
||||
yp_compile_node(iseq, cond, cond_seq, src, Qfalse, compile_context);
|
||||
yp_compile_node(iseq, cond, cond_seq, src, false, compile_context);
|
||||
ADD_SEQ(ret, cond_seq);
|
||||
}
|
||||
break;
|
||||
|
@ -301,7 +301,7 @@ yp_compile_while(rb_iseq_t *iseq, int lineno, yp_node_flags_t flags, enum yp_nod
|
|||
|
||||
ADD_LABEL(ret, redo_label);
|
||||
if (statements) {
|
||||
yp_compile_node(iseq, (yp_node_t *)statements, ret, src, Qtrue, compile_context);
|
||||
yp_compile_node(iseq, (yp_node_t *)statements, ret, src, true, compile_context);
|
||||
}
|
||||
|
||||
ADD_LABEL(ret, next_label);
|
||||
|
@ -355,12 +355,13 @@ yp_new_child_iseq(rb_iseq_t *iseq, yp_scope_node_t * node, yp_parser_t *parser,
|
|||
|
||||
|
||||
static int
|
||||
yp_compile_class_path(LINK_ANCHOR *const ret, rb_iseq_t *iseq, const yp_node_t *constant_path_node, const NODE *line_node)
|
||||
yp_compile_class_path(LINK_ANCHOR *const ret, rb_iseq_t *iseq, const yp_node_t *constant_path_node, const NODE *line_node, const uint8_t * src, bool popped, yp_compile_context_t *compile_context)
|
||||
{
|
||||
if (constant_path_node->type == YP_NODE_CONSTANT_PATH_NODE) {
|
||||
if (((yp_constant_path_node_t *)constant_path_node)->parent) {
|
||||
yp_node_t *parent = ((yp_constant_path_node_t *)constant_path_node)->parent;
|
||||
if (parent) {
|
||||
/* Bar::Foo */
|
||||
// TODO: yp_compile_node(ret, "nd_else->nd_head", cpath->nd_head));
|
||||
yp_compile_node(iseq, parent, ret, src, popped, compile_context);
|
||||
return VM_DEFINECLASS_FLAG_SCOPED;
|
||||
}
|
||||
else {
|
||||
|
@ -546,7 +547,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret,
|
|||
// TODO: Once we merge constant path nodes correctly, fix this flag
|
||||
const int flags = VM_DEFINECLASS_TYPE_CLASS |
|
||||
(class_node->superclass ? VM_DEFINECLASS_FLAG_HAS_SUPERCLASS : 0) |
|
||||
yp_compile_class_path(ret, iseq, class_node->constant_path, &dummy_line_node);
|
||||
yp_compile_class_path(ret, iseq, class_node->constant_path, &dummy_line_node, src, popped, compile_context);
|
||||
|
||||
if (class_node->superclass) {
|
||||
yp_compile_node(iseq, class_node->superclass, ret, src, popped, compile_context);
|
||||
|
@ -577,7 +578,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret,
|
|||
return;
|
||||
case YP_NODE_CLASS_VARIABLE_WRITE_NODE: {
|
||||
yp_class_variable_write_node_t *write_node = (yp_class_variable_write_node_t *) node;
|
||||
yp_compile_node(iseq, write_node->value, ret, src, popped, compile_context);
|
||||
yp_compile_node(iseq, write_node->value, ret, src, false, compile_context);
|
||||
if (!popped) {
|
||||
ADD_INSN(ret, &dummy_line_node, dup);
|
||||
}
|
||||
|
@ -729,7 +730,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret,
|
|||
return;
|
||||
case YP_NODE_GLOBAL_VARIABLE_WRITE_NODE: {
|
||||
yp_global_variable_write_node_t *write_node = (yp_global_variable_write_node_t *) node;
|
||||
yp_compile_node(iseq, write_node->value, ret, src, popped, compile_context);
|
||||
yp_compile_node(iseq, write_node->value, ret, src, false, compile_context);
|
||||
if (!popped) {
|
||||
ADD_INSN(ret, &dummy_line_node, dup);
|
||||
}
|
||||
|
@ -791,10 +792,12 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret,
|
|||
}
|
||||
case YP_NODE_INSTANCE_VARIABLE_WRITE_NODE: {
|
||||
yp_instance_variable_write_node_t *write_node = (yp_instance_variable_write_node_t *) node;
|
||||
yp_compile_node(iseq, write_node->value, ret, src, popped, compile_context);
|
||||
yp_compile_node(iseq, write_node->value, ret, src, false, compile_context);
|
||||
|
||||
if (!popped) {
|
||||
ADD_INSN(ret, &dummy_line_node, dup);
|
||||
}
|
||||
|
||||
ID ivar_name = parse_location_symbol(&write_node->name_loc);
|
||||
ADD_INSN2(ret, &dummy_line_node, setinstancevariable,
|
||||
ID2SYM(ivar_name),
|
||||
|
@ -954,7 +957,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret,
|
|||
const rb_iseq_t *module_iseq = NEW_CHILD_ISEQ(&scope_node, module_name, ISEQ_TYPE_CLASS, lineno);
|
||||
|
||||
const int flags = VM_DEFINECLASS_TYPE_MODULE |
|
||||
yp_compile_class_path(ret, iseq, module_node->constant_path, &dummy_line_node);
|
||||
yp_compile_class_path(ret, iseq, module_node->constant_path, &dummy_line_node, src, popped, compile_context);
|
||||
|
||||
ADD_INSN (ret, &dummy_line_node, putnil);
|
||||
ADD_INSN3(ret, &dummy_line_node, defineclass, ID2SYM(module_id), module_iseq, INT2FIX(flags));
|
||||
|
@ -1257,9 +1260,11 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret,
|
|||
for (size_t index = 0; index < node_list.size; index++) {
|
||||
// We only want to have popped == false for the last instruction
|
||||
if (!popped && (index != node_list.size - 1)) {
|
||||
popped = true;
|
||||
yp_compile_node(iseq, node_list.nodes[index], ret, src, true, compile_context);
|
||||
}
|
||||
else {
|
||||
yp_compile_node(iseq, node_list.nodes[index], ret, src, false, compile_context);
|
||||
}
|
||||
yp_compile_node(iseq, node_list.nodes[index], ret, src, popped, compile_context);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче