summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--prism_compile.c296
1 files changed, 265 insertions, 31 deletions
@@ -207,21 +207,21 @@ parse_string_encoded(const pm_node_t *node, const pm_string_t *string, const pm_
}
static inline ID
-parse_symbol(const uint8_t *start, const uint8_t *end, pm_parser_t *parser)
{
rb_encoding *enc = rb_enc_from_index(rb_enc_find_index(parser->encoding->name));
return rb_intern3((const char *) start, end - start, enc);
}
static inline ID
-parse_string_symbol(const pm_string_t *string, pm_parser_t *parser)
{
const uint8_t *start = pm_string_source(string);
return parse_symbol(start, start + pm_string_length(string), parser);
}
static inline ID
-parse_location_symbol(pm_location_t *location, pm_parser_t *parser)
{
return parse_symbol(location->start, location->end, parser);
}
@@ -326,7 +326,7 @@ pm_new_regex(pm_regular_expression_node_t * cast, const pm_parser_t * parser) {
* literal values can be compiled into a literal array.
*/
static inline VALUE
-pm_static_literal_value(const pm_node_t *node, pm_scope_node_t *scope_node, pm_parser_t *parser)
{
// Every node that comes into this function should already be marked as
// static literal. If it's not, then we have a bug somewhere.
@@ -1147,6 +1147,118 @@ pm_setup_args(pm_arguments_node_t *arguments_node, int *flags, struct rb_callinf
return orig_argc;
}
static void
pm_compile_index_and_or_write_node(bool and_node, pm_node_t *receiver, pm_node_t *value, pm_arguments_node_t *arguments, pm_node_t *block, LINK_ANCHOR *const ret, rb_iseq_t *iseq, int lineno, const uint8_t * src, bool popped, pm_scope_node_t *scope_node, pm_parser_t *parser)
{
@@ -3234,6 +3346,20 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
return;
}
case PM_CASE_NODE: {
pm_case_node_t *case_node = (pm_case_node_t *)node;
bool has_predicate = case_node->predicate;
@@ -3731,13 +3857,23 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
}
ADD_INSN1(ret, &dummy_line_node, setconstant, child_name);
- return ;
}
case PM_CONSTANT_PATH_TARGET_NODE: {
- pm_constant_path_target_node_t *cast = (pm_constant_path_target_node_t *)node;
if (cast->parent) {
- PM_COMPILE(cast->parent);
}
return;
@@ -4379,6 +4515,33 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
return;
}
case PM_INSTANCE_VARIABLE_AND_WRITE_NODE: {
pm_instance_variable_and_write_node_t *instance_variable_and_write_node = (pm_instance_variable_and_write_node_t*) node;
@@ -5371,49 +5534,120 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
return;
}
case PM_RESCUE_NODE: {
- LABEL *excep_match = NEW_LABEL(lineno);
- LABEL *rescue_end = NEW_LABEL(lineno);
-
- ISEQ_COMPILE_DATA(iseq)->end_label = rescue_end;
-
- pm_rescue_node_t *rescue_node = (pm_rescue_node_t *)node;
iseq_set_exception_local_table(iseq);
- pm_node_list_t exception_list = rescue_node->exceptions;
- if (exception_list.size > 0) {
- for (size_t i = 0; i < exception_list.size; i++) {
ADD_GETLOCAL(ret, &dummy_line_node, LVAR_ERRINFO, 0);
- PM_COMPILE(exception_list.nodes[i]);
ADD_INSN1(ret, &dummy_line_node, checkmatch, INT2FIX(VM_CHECKMATCH_TYPE_RESCUE));
- ADD_INSN1(ret, &dummy_line_node, branchif, excep_match);
}
} else {
ADD_GETLOCAL(ret, &dummy_line_node, LVAR_ERRINFO, 0);
ADD_INSN1(ret, &dummy_line_node, putobject, rb_eStandardError);
ADD_INSN1(ret, &dummy_line_node, checkmatch, INT2FIX(VM_CHECKMATCH_TYPE_RESCUE));
- ADD_INSN1(ret, &dummy_line_node, branchif, excep_match);
}
- ADD_INSN1(ret, &dummy_line_node, jump, rescue_end);
- ADD_LABEL(ret, excep_match);
ADD_TRACE(ret, RUBY_EVENT_RESCUE);
- if (rescue_node->reference) {
- ADD_GETLOCAL(ret, &dummy_line_node, LVAR_ERRINFO, 0);
- PM_COMPILE((pm_node_t *)rescue_node->reference);
- }
- if (rescue_node->statements) {
- PM_COMPILE((pm_node_t *)rescue_node->statements);
}
- else {
PM_PUTNIL;
}
ADD_INSN(ret, &dummy_line_node, leave);
- ADD_LABEL(ret, rescue_end);
- if (rescue_node->consequent) {
- PM_COMPILE((pm_node_t *)rescue_node->consequent);
} else {
ADD_GETLOCAL(ret, &dummy_line_node, 1, 0);
}