2018-12-27 01:12:09 -05:00
|
|
|
%# -*- C -*-
|
2018-09-11 05:48:58 -04:00
|
|
|
%# Copyright (c) 2018 Urabe, Shyouhei. All rights reserved.
|
|
|
|
%#
|
|
|
|
%# This file is a part of the programming language Ruby. Permission is hereby
|
|
|
|
%# granted, to either redistribute and/or modify this file, provided that the
|
|
|
|
%# conditions mentioned in the file COPYING are met. Consult the file for
|
|
|
|
%# details.
|
|
|
|
%;
|
2018-12-26 02:23:35 -05:00
|
|
|
#line <%= __LINE__ + 1 %> <%=cstr __FILE__ %>
|
2018-09-11 05:48:58 -04:00
|
|
|
|
|
|
|
static bool
|
|
|
|
leafness_of_getglobal(VALUE gentry)
|
|
|
|
{
|
|
|
|
const struct rb_global_entry *e = (void *)gentry;
|
|
|
|
|
|
|
|
if (UNLIKELY(rb_gvar_is_traced(e))) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* We cannot write this function using a switch() because a
|
|
|
|
* case label cannot be a function pointer. */
|
2018-11-10 20:25:33 -05:00
|
|
|
static rb_gvar_getter_t *const allowlist[] = {
|
2018-09-11 05:48:58 -04:00
|
|
|
rb_gvar_val_getter,
|
|
|
|
rb_gvar_var_getter,
|
2019-01-31 23:39:47 -05:00
|
|
|
/* rb_gvar_undef_getter issues rb_warning() */
|
2018-09-11 05:48:58 -04:00
|
|
|
};
|
|
|
|
rb_gvar_getter_t *f = rb_gvar_getter_function_of(e);
|
|
|
|
int i;
|
|
|
|
|
2018-11-10 20:25:33 -05:00
|
|
|
for (i = 0; i < numberof(allowlist); i++) {
|
|
|
|
if (f == allowlist[i]) {
|
2018-09-11 05:48:58 -04:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool
|
|
|
|
leafness_of_setglobal(VALUE gentry)
|
|
|
|
{
|
|
|
|
const struct rb_global_entry *e = (void *)gentry;
|
|
|
|
|
|
|
|
if (UNLIKELY(rb_gvar_is_traced(e))) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* We cannot write this function using a switch() because a
|
|
|
|
* case label cannot be a function pointer. */
|
2018-11-10 20:25:33 -05:00
|
|
|
static rb_gvar_setter_t *const allowlist[] = {
|
2018-09-11 05:48:58 -04:00
|
|
|
rb_gvar_val_setter,
|
2019-01-31 23:39:47 -05:00
|
|
|
/* rb_gvar_readonly_setter issues rb_name_error() */
|
2018-09-11 05:48:58 -04:00
|
|
|
rb_gvar_var_setter,
|
|
|
|
rb_gvar_undef_setter,
|
|
|
|
};
|
|
|
|
rb_gvar_setter_t *f = rb_gvar_setter_function_of(e);
|
|
|
|
int i;
|
|
|
|
|
2018-11-10 20:25:33 -05:00
|
|
|
for (i = 0; i < numberof(allowlist); i++) {
|
|
|
|
if (f == allowlist[i]) {
|
2018-09-11 05:48:58 -04:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#include "iseq.h"
|
|
|
|
|
|
|
|
static bool
|
|
|
|
leafness_of_defined(rb_num_t op_type)
|
|
|
|
{
|
|
|
|
/* see also: vm_insnhelper.c:vm_defined() */
|
|
|
|
switch (op_type) {
|
|
|
|
case DEFINED_IVAR:
|
|
|
|
case DEFINED_IVAR2:
|
|
|
|
case DEFINED_GVAR:
|
|
|
|
case DEFINED_CVAR:
|
|
|
|
case DEFINED_YIELD:
|
|
|
|
case DEFINED_REF:
|
|
|
|
case DEFINED_ZSUPER:
|
|
|
|
return false;
|
|
|
|
case DEFINED_CONST:
|
|
|
|
/* has rb_autoload_load(); */
|
|
|
|
return false;
|
|
|
|
case DEFINED_FUNC:
|
|
|
|
case DEFINED_METHOD:
|
|
|
|
/* calls #respond_to_missing? */
|
|
|
|
return false;
|
|
|
|
default:
|
|
|
|
rb_bug("unknown operand %ld: blame @shyouhei.", op_type);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool
|
|
|
|
leafness_of_checkmatch(rb_num_t flag)
|
|
|
|
{
|
|
|
|
/* see also: vm_insnhelper.c:check_match() */
|
|
|
|
if (flag == VM_CHECKMATCH_TYPE_WHEN) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* has rb_funcallv() */
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
2018-12-26 02:23:35 -05:00
|
|
|
#pragma RubyVM reset source
|