diff options
author | 卜部昌平 <shyouhei@ruby-lang.org> | 2020-04-08 13:28:13 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-04-08 13:28:13 +0900 |
commit | 9e6e39c3512f7a962c44dc3729c98a0f8be90341 (patch) | |
tree | 901a22676d54d78240e450b64a8cd06eb1703910 /include/ruby/3/fl_type.h | |
parent | 5ac4bf2cd87e1eb5779ca5ae7f96a1a22e8436d9 (diff) | |
download | ruby-9e6e39c3512f7a962c44dc3729c98a0f8be90341.tar.gz |
Merge pull request #2991 from shyouhei/ruby.h
Split ruby.h
Diffstat (limited to 'include/ruby/3/fl_type.h')
-rw-r--r-- | include/ruby/3/fl_type.h | 469 |
1 files changed, 469 insertions, 0 deletions
diff --git a/include/ruby/3/fl_type.h b/include/ruby/3/fl_type.h new file mode 100644 index 0000000000..62b6f1b9c6 --- /dev/null +++ b/include/ruby/3/fl_type.h @@ -0,0 +1,469 @@ +/** \noop-*-C++-*-vi:ft=cpp + * @file + * @author Ruby developers <ruby-core@ruby-lang.org> + * @copyright 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. + * @warning Symbols prefixed with either `RUBY3` or `ruby3` are + * implementation details. Don't take them as canon. They could + * rapidly appear then vanish. The name (path) of this header file + * is also an implementation detail. Do not expect it to persist + * at the place it is now. Developers are free to move it anywhere + * anytime at will. + * @note To ruby-core: remember that this header can be possibly + * recursively included from extension libraries written in C++. + * Do not expect for instance `__VA_ARGS__` is always available. + * We assume C99 for ruby itself but we don't assume languages of + * extension libraries. They could be written in C++98. + * @brief Defines enum ::ruby_fl_type. + */ +#ifndef RUBY3_FL_TYPE_H +#define RUBY3_FL_TYPE_H +#include "ruby/3/config.h" /* for ENUM_OVER_INT */ +#include "ruby/3/attr/artificial.h" +#include "ruby/3/attr/flag_enum.h" +#include "ruby/3/attr/forceinline.h" +#include "ruby/3/attr/noalias.h" +#include "ruby/3/attr/pure.h" +#include "ruby/3/cast.h" +#include "ruby/3/core/rbasic.h" +#include "ruby/3/dllexport.h" +#include "ruby/3/special_consts.h" +#include "ruby/3/stdbool.h" +#include "ruby/3/value.h" +#include "ruby/3/value_type.h" +#include "ruby/assert.h" +#include "ruby/defines.h" + +/** @cond INTERNAL_MACRO */ +#ifdef ENUM_OVER_INT +# define RUBY3_WIDER_ENUM 1 +#elif SIZEOF_INT * CHAR_BIT > 12+19+1 +# define RUBY3_WIDER_ENUM 1 +#else +# define RUBY3_WIDER_ENUM 0 +#endif +/** @endcond */ + +#define FL_SINGLETON RUBY3_CAST((VALUE)RUBY_FL_SINGLETON) +#define FL_WB_PROTECTED RUBY3_CAST((VALUE)RUBY_FL_WB_PROTECTED) +#define FL_PROMOTED0 RUBY3_CAST((VALUE)RUBY_FL_PROMOTED0) +#define FL_PROMOTED1 RUBY3_CAST((VALUE)RUBY_FL_PROMOTED1) +#define FL_FINALIZE RUBY3_CAST((VALUE)RUBY_FL_FINALIZE) +#define FL_TAINT RUBY3_CAST((VALUE)RUBY_FL_TAINT) +#define FL_UNTRUSTED RUBY3_CAST((VALUE)RUBY_FL_UNTRUSTED) +#define FL_SEEN_OBJ_ID RUBY3_CAST((VALUE)RUBY_FL_SEEN_OBJ_ID) +#define FL_EXIVAR RUBY3_CAST((VALUE)RUBY_FL_EXIVAR) +#define FL_FREEZE RUBY3_CAST((VALUE)RUBY_FL_FREEZE) + +#define FL_USHIFT RUBY3_CAST((VALUE)RUBY_FL_USHIFT) + +#define FL_USER0 RUBY3_CAST((VALUE)RUBY_FL_USER0) +#define FL_USER1 RUBY3_CAST((VALUE)RUBY_FL_USER1) +#define FL_USER2 RUBY3_CAST((VALUE)RUBY_FL_USER2) +#define FL_USER3 RUBY3_CAST((VALUE)RUBY_FL_USER3) +#define FL_USER4 RUBY3_CAST((VALUE)RUBY_FL_USER4) +#define FL_USER5 RUBY3_CAST((VALUE)RUBY_FL_USER5) +#define FL_USER6 RUBY3_CAST((VALUE)RUBY_FL_USER6) +#define FL_USER7 RUBY3_CAST((VALUE)RUBY_FL_USER7) +#define FL_USER8 RUBY3_CAST((VALUE)RUBY_FL_USER8) +#define FL_USER9 RUBY3_CAST((VALUE)RUBY_FL_USER9) +#define FL_USER10 RUBY3_CAST((VALUE)RUBY_FL_USER10) +#define FL_USER11 RUBY3_CAST((VALUE)RUBY_FL_USER11) +#define FL_USER12 RUBY3_CAST((VALUE)RUBY_FL_USER12) +#define FL_USER13 RUBY3_CAST((VALUE)RUBY_FL_USER13) +#define FL_USER14 RUBY3_CAST((VALUE)RUBY_FL_USER14) +#define FL_USER15 RUBY3_CAST((VALUE)RUBY_FL_USER15) +#define FL_USER16 RUBY3_CAST((VALUE)RUBY_FL_USER16) +#define FL_USER17 RUBY3_CAST((VALUE)RUBY_FL_USER17) +#define FL_USER18 RUBY3_CAST((VALUE)RUBY_FL_USER18) +#define FL_USER19 RUBY3_CAST((VALUE)(unsigned int)RUBY_FL_USER19) + +#define ELTS_SHARED RUBY_ELTS_SHARED +#define RUBY_ELTS_SHARED RUBY_ELTS_SHARED +#define RB_OBJ_FREEZE rb_obj_freeze_inline + +/** @cond INTERNAL_MACRO */ +#define RB_FL_ABLE RB_FL_ABLE +#define RB_FL_ALL RB_FL_ALL +#define RB_FL_ALL_RAW RB_FL_ALL_RAW +#define RB_FL_ANY RB_FL_ANY +#define RB_FL_ANY_RAW RB_FL_ANY_RAW +#define RB_FL_REVERSE RB_FL_REVERSE +#define RB_FL_REVERSE_RAW RB_FL_REVERSE_RAW +#define RB_FL_SET RB_FL_SET +#define RB_FL_SET_RAW RB_FL_SET_RAW +#define RB_FL_TEST RB_FL_TEST +#define RB_FL_TEST_RAW RB_FL_TEST_RAW +#define RB_FL_UNSET RB_FL_UNSET +#define RB_FL_UNSET_RAW RB_FL_UNSET_RAW +#define RB_OBJ_FREEZE_RAW RB_OBJ_FREEZE_RAW +#define RB_OBJ_FROZEN RB_OBJ_FROZEN +#define RB_OBJ_FROZEN_RAW RB_OBJ_FROZEN_RAW +#define RB_OBJ_INFECT RB_OBJ_INFECT +#define RB_OBJ_INFECT_RAW RB_OBJ_INFECT_RAW +#define RB_OBJ_TAINT RB_OBJ_TAINT +#define RB_OBJ_TAINTABLE RB_OBJ_TAINTABLE +#define RB_OBJ_TAINTED RB_OBJ_TAINTED +#define RB_OBJ_TAINTED_RAW RB_OBJ_TAINTED_RAW +#define RB_OBJ_TAINT_RAW RB_OBJ_TAINT_RAW +#define RB_OBJ_UNTRUST RB_OBJ_UNTRUST +#define RB_OBJ_UNTRUSTED RB_OBJ_UNTRUSTED +/** @endcond */ + +/** + * @defgroup deprecated_macros deprecated macro APIs + * @{ + * These macros are deprecated. Prefer their `RB_`-prefixed versions. + */ +#define FL_ABLE RB_FL_ABLE +#define FL_ALL RB_FL_ALL +#define FL_ALL_RAW RB_FL_ALL_RAW +#define FL_ANY RB_FL_ANY +#define FL_ANY_RAW RB_FL_ANY_RAW +#define FL_REVERSE RB_FL_REVERSE +#define FL_REVERSE_RAW RB_FL_REVERSE_RAW +#define FL_SET RB_FL_SET +#define FL_SET_RAW RB_FL_SET_RAW +#define FL_TEST RB_FL_TEST +#define FL_TEST_RAW RB_FL_TEST_RAW +#define FL_UNSET RB_FL_UNSET +#define FL_UNSET_RAW RB_FL_UNSET_RAW +#define OBJ_FREEZE RB_OBJ_FREEZE +#define OBJ_FREEZE_RAW RB_OBJ_FREEZE_RAW +#define OBJ_FROZEN RB_OBJ_FROZEN +#define OBJ_FROZEN_RAW RB_OBJ_FROZEN_RAW +#define OBJ_INFECT RB_OBJ_INFECT +#define OBJ_INFECT_RAW RB_OBJ_INFECT_RAW +#define OBJ_TAINT RB_OBJ_TAINT +#define OBJ_TAINTABLE RB_OBJ_TAINTABLE +#define OBJ_TAINTED RB_OBJ_TAINTED +#define OBJ_TAINTED_RAW RB_OBJ_TAINTED_RAW +#define OBJ_TAINT_RAW RB_OBJ_TAINT_RAW +#define OBJ_UNTRUST RB_OBJ_UNTRUST +#define OBJ_UNTRUSTED RB_OBJ_UNTRUSTED +/** @} */ + +/* This is an enum because GDB wants it (rather than a macro) */ +enum { RUBY_FL_USHIFT = 12 }; + +/* > The expression that defines the value of an enumeration constant shall be + * > an integer constant expression that has a value representable as an `int`. + * + * -- ISO/IEC 9899:2018 section 6.7.2.2 + * + * So ENUM_OVER_INT situation is an extension to the standard. Note however + * that we do not support 16 bit `int` environment. */ +RB_GNUC_EXTENSION +enum +RUBY3_ATTR_FLAG_ENUM() +ruby_fl_type { + RUBY_FL_WB_PROTECTED = (1<<5), + RUBY_FL_PROMOTED0 = (1<<5), + RUBY_FL_PROMOTED1 = (1<<6), + RUBY_FL_PROMOTED = RUBY_FL_PROMOTED0 | RUBY_FL_PROMOTED1, + RUBY_FL_FINALIZE = (1<<7), + RUBY_FL_TAINT = (1<<8), + RUBY_FL_UNTRUSTED = RUBY_FL_TAINT, + RUBY_FL_SEEN_OBJ_ID = (1<<9), + RUBY_FL_EXIVAR = (1<<10), + RUBY_FL_FREEZE = (1<<11), + +#define RUBY3_FL_USER_N(n) RUBY_FL_USER##n = (1<<(RUBY_FL_USHIFT+n)) + RUBY3_FL_USER_N(0), + RUBY3_FL_USER_N(1), + RUBY3_FL_USER_N(2), + RUBY3_FL_USER_N(3), + RUBY3_FL_USER_N(4), + RUBY3_FL_USER_N(5), + RUBY3_FL_USER_N(6), + RUBY3_FL_USER_N(7), + RUBY3_FL_USER_N(8), + RUBY3_FL_USER_N(9), + RUBY3_FL_USER_N(10), + RUBY3_FL_USER_N(11), + RUBY3_FL_USER_N(12), + RUBY3_FL_USER_N(13), + RUBY3_FL_USER_N(14), + RUBY3_FL_USER_N(15), + RUBY3_FL_USER_N(16), + RUBY3_FL_USER_N(17), + RUBY3_FL_USER_N(18), +#if ENUM_OVER_INT + RUBY3_FL_USER_N(19), +#else +# define RUBY_FL_USER19 (RUBY3_VALUE_ONE<<(RUBY_FL_USHIFT+19)) +#endif +#undef RUBY3_FL_USER_N +#undef RUBY3_WIDER_ENUM + + RUBY_ELTS_SHARED = RUBY_FL_USER2, + RUBY_FL_SINGLETON = RUBY_FL_USER0, +}; + +enum { RUBY_FL_DUPPED = RUBY_T_MASK | RUBY_FL_EXIVAR | RUBY_FL_TAINT }; + +RUBY3_SYMBOL_EXPORT_BEGIN() +void rb_obj_infect(VALUE victim, VALUE carrier); +void rb_freeze_singleton_class(VALUE klass); +RUBY3_SYMBOL_EXPORT_END() + +RUBY3_ATTR_PURE_ON_NDEBUG() +RUBY3_ATTR_ARTIFICIAL() +RUBY3_ATTR_FORCEINLINE() +static bool +RB_FL_ABLE(VALUE obj) +{ + if (RB_SPECIAL_CONST_P(obj)) { + return false; + } + else if (RB_TYPE_P(obj, RUBY_T_NODE)) { + return false; + } + else { + return true; + } +} + +RUBY3_ATTR_PURE_ON_NDEBUG() +RUBY3_ATTR_ARTIFICIAL() +static inline VALUE +RB_FL_TEST_RAW(VALUE obj, VALUE flags) +{ + RUBY3_ASSERT_OR_ASSUME(RB_FL_ABLE(obj)); + return RBASIC(obj)->flags & flags; +} + +RUBY3_ATTR_PURE_ON_NDEBUG() +RUBY3_ATTR_ARTIFICIAL() +static inline VALUE +RB_FL_TEST(VALUE obj, VALUE flags) +{ + if (RB_FL_ABLE(obj)) { + return RB_FL_TEST_RAW(obj, flags); + } + else { + return RUBY3_VALUE_NULL; + } +} + +RUBY3_ATTR_PURE_ON_NDEBUG() +RUBY3_ATTR_ARTIFICIAL() +static inline bool +RB_FL_ANY_RAW(VALUE obj, VALUE flags) +{ + return RB_FL_TEST_RAW(obj, flags); +} + +RUBY3_ATTR_PURE_ON_NDEBUG() +RUBY3_ATTR_ARTIFICIAL() +static inline bool +RB_FL_ANY(VALUE obj, VALUE flags) +{ + return RB_FL_TEST(obj, flags); +} + +RUBY3_ATTR_PURE_ON_NDEBUG() +RUBY3_ATTR_ARTIFICIAL() +static inline bool +RB_FL_ALL_RAW(VALUE obj, VALUE flags) +{ + return RB_FL_TEST_RAW(obj, flags) == flags; +} + +RUBY3_ATTR_PURE_ON_NDEBUG() +RUBY3_ATTR_ARTIFICIAL() +static inline bool +RB_FL_ALL(VALUE obj, VALUE flags) +{ + return RB_FL_TEST(obj, flags) == flags; +} + +RUBY3_ATTR_NOALIAS() +RUBY3_ATTR_ARTIFICIAL() +static inline void +ruby3_fl_set_raw_raw(struct RBasic *obj, VALUE flags) +{ + obj->flags |= flags; +} + +RUBY3_ATTR_ARTIFICIAL() +static inline void +RB_FL_SET_RAW(VALUE obj, VALUE flags) +{ + RUBY3_ASSERT_OR_ASSUME(RB_FL_ABLE(obj)); + ruby3_fl_set_raw_raw(RBASIC(obj), flags); +} + +RUBY3_ATTR_ARTIFICIAL() +static inline void +RB_FL_SET(VALUE obj, VALUE flags) +{ + if (RB_FL_ABLE(obj)) { + RB_FL_SET_RAW(obj, flags); + } +} + +RUBY3_ATTR_NOALIAS() +RUBY3_ATTR_ARTIFICIAL() +static inline void +ruby3_fl_unset_raw_raw(struct RBasic *obj, VALUE flags) +{ + obj->flags &= ~flags; +} + +RUBY3_ATTR_ARTIFICIAL() +static inline void +RB_FL_UNSET_RAW(VALUE obj, VALUE flags) +{ + RUBY3_ASSERT_OR_ASSUME(RB_FL_ABLE(obj)); + ruby3_fl_unset_raw_raw(RBASIC(obj), flags); +} + +RUBY3_ATTR_ARTIFICIAL() +static inline void +RB_FL_UNSET(VALUE obj, VALUE flags) +{ + if (RB_FL_ABLE(obj)) { + RB_FL_UNSET_RAW(obj, flags); + } +} + +RUBY3_ATTR_NOALIAS() +RUBY3_ATTR_ARTIFICIAL() +static inline void +ruby3_fl_reverse_raw_raw(struct RBasic *obj, VALUE flags) +{ + obj->flags ^= flags; +} + +RUBY3_ATTR_ARTIFICIAL() +static inline void +RB_FL_REVERSE_RAW(VALUE obj, VALUE flags) +{ + RUBY3_ASSERT_OR_ASSUME(RB_FL_ABLE(obj)); + ruby3_fl_reverse_raw_raw(RBASIC(obj), flags); +} + +RUBY3_ATTR_ARTIFICIAL() +static inline void +RB_FL_REVERSE(VALUE obj, VALUE flags) +{ + if (RB_FL_ABLE(obj)) { + RB_FL_REVERSE_RAW(obj, flags); + } +} + +RUBY3_ATTR_PURE_ON_NDEBUG() +RUBY3_ATTR_ARTIFICIAL() +static inline bool +RB_OBJ_TAINTABLE(VALUE obj) +{ + if (! RB_FL_ABLE(obj)) { + return false; + } + else if (RB_TYPE_P(obj, RUBY_T_BIGNUM)) { + return false; + } + else if (RB_TYPE_P(obj, RUBY_T_FLOAT)) { + return false; + } + else { + return true; + } +} + +RUBY3_ATTR_PURE_ON_NDEBUG() +RUBY3_ATTR_ARTIFICIAL() +static inline VALUE +RB_OBJ_TAINTED_RAW(VALUE obj) +{ + return RB_FL_TEST_RAW(obj, RUBY_FL_TAINT); +} + +RUBY3_ATTR_PURE_ON_NDEBUG() +RUBY3_ATTR_ARTIFICIAL() +static inline bool +RB_OBJ_TAINTED(VALUE obj) +{ + return RB_FL_ANY(obj, RUBY_FL_TAINT); +} + +RUBY3_ATTR_ARTIFICIAL() +static inline void +RB_OBJ_TAINT_RAW(VALUE obj) +{ + RB_FL_SET_RAW(obj, RUBY_FL_TAINT); +} + +RUBY3_ATTR_ARTIFICIAL() +static inline void +RB_OBJ_TAINT(VALUE obj) +{ + if (RB_OBJ_TAINTABLE(obj)) { + RB_OBJ_TAINT_RAW(obj); + } +} + +RUBY3_ATTR_ARTIFICIAL() +static inline void +RB_OBJ_INFECT_RAW(VALUE dst, VALUE src) +{ + RUBY3_ASSERT_OR_ASSUME(RB_OBJ_TAINTABLE(dst)); + RUBY3_ASSERT_OR_ASSUME(RB_FL_ABLE(src)); + RB_FL_SET_RAW(dst, RB_OBJ_TAINTED_RAW(src)); +} + +RUBY3_ATTR_ARTIFICIAL() +static inline void +RB_OBJ_INFECT(VALUE dst, VALUE src) +{ + if (RB_OBJ_TAINTABLE(dst) && RB_FL_ABLE(src)) { + RB_OBJ_INFECT_RAW(dst, src); + } +} + +RUBY3_ATTR_PURE_ON_NDEBUG() +RUBY3_ATTR_ARTIFICIAL() +/* It is intentional not to return bool here. There is a place in ruby core + * (namely class.c:singleton_class_of()) where return value of this function is + * verbatimly passed to RB_FL_SET_RAW. */ +static inline VALUE +RB_OBJ_FROZEN_RAW(VALUE obj) +{ + return RB_FL_TEST_RAW(obj, RUBY_FL_FREEZE); +} + +RUBY3_ATTR_PURE_ON_NDEBUG() +RUBY3_ATTR_ARTIFICIAL() +static inline bool +RB_OBJ_FROZEN(VALUE obj) +{ + if (! RB_FL_ABLE(obj)) { + return true; + } + else { + return RB_OBJ_FROZEN_RAW(obj); + } +} + +RUBY3_ATTR_ARTIFICIAL() +static inline void +RB_OBJ_FREEZE_RAW(VALUE obj) +{ + RB_FL_SET_RAW(obj, RUBY_FL_FREEZE); +} + +static inline void +rb_obj_freeze_inline(VALUE x) +{ + if (RB_FL_ABLE(x)) { + RB_OBJ_FREEZE_RAW(x); + if (RBASIC_CLASS(x) && !(RBASIC(x)->flags & RUBY_FL_SINGLETON)) { + rb_freeze_singleton_class(x); + } + } +} + +#endif /* RUBY3_FL_TYPE_H */ |