common.h 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. #pragma once
  2. #include <cmath>
  3. #include <cstring>
  4. #include <sstream>
  5. #include <regex>
  6. #include <stdexcept>
  7. #include <vector>
  8. #include <string>
  9. #include <chrono>
  10. #include <string_view>
  11. #include <iomanip>
  12. #include <memory>
  13. #include <iostream>
  14. #include <map>
  15. #include <set>
  16. #include <algorithm>
  17. #include <initializer_list>
  18. #include <variant>
  19. #include <type_traits>
  20. #include <random>
  21. #include <bitset>
  22. #include <deque>
  23. #define PK_VERSION "1.3.6"
  24. #include "config.h"
  25. #include "export.h"
  26. #ifdef min
  27. #undef min
  28. #endif
  29. #ifdef max
  30. #undef max
  31. #endif
  32. /*******************************************************************************/
  33. #if PK_ENABLE_STD_FUNCTION
  34. #include <functional>
  35. #endif
  36. /*******************************************************************************/
  37. #if PK_ENABLE_THREAD
  38. #define PK_THREAD_LOCAL thread_local
  39. #include <mutex>
  40. struct GIL {
  41. inline static std::mutex _mutex;
  42. explicit GIL() { _mutex.lock(); }
  43. ~GIL() { _mutex.unlock(); }
  44. };
  45. #define PK_GLOBAL_SCOPE_LOCK() GIL _lock;
  46. #else
  47. #define PK_THREAD_LOCAL
  48. #define PK_GLOBAL_SCOPE_LOCK()
  49. #endif
  50. /*******************************************************************************/
  51. #define PK_UNUSED(x) (void)(x)
  52. #define PK_LOCAL_STATIC static
  53. namespace pkpy{
  54. namespace std = ::std;
  55. template <size_t T>
  56. struct NumberTraits;
  57. template <>
  58. struct NumberTraits<4> {
  59. using int_t = int32_t;
  60. using float_t = float;
  61. static constexpr int_t kMaxSmallInt = (1 << 28) - 1;
  62. static constexpr int_t kMinSmallInt = - (1 << 28);
  63. static constexpr float_t kEpsilon = 1e-4;
  64. };
  65. template <>
  66. struct NumberTraits<8> {
  67. using int_t = int64_t;
  68. using float_t = double;
  69. static constexpr int_t kMaxSmallInt = (1ll << 60) - 1;
  70. static constexpr int_t kMinSmallInt = - (1ll << 60);
  71. static constexpr float_t kEpsilon = 1e-8;
  72. };
  73. using Number = NumberTraits<sizeof(void*)>;
  74. using i64 = int64_t; // always 64-bit
  75. using f64 = Number::float_t;
  76. template<size_t T>
  77. union BitsCvtImpl;
  78. template<>
  79. union BitsCvtImpl<4>{
  80. NumberTraits<4>::int_t _int;
  81. NumberTraits<4>::float_t _float;
  82. // 1 + 8 + 23
  83. int sign() const { return _int >> 31; }
  84. unsigned int exp() const { return (_int >> 23) & 0b1111'1111; }
  85. uint64_t mantissa() const { return _int & 0x7fffff; }
  86. void set_exp(int exp) { _int = (_int & 0x807f'ffff) | (exp << 23); }
  87. void set_sign(int sign) { _int = (_int & 0x7fff'ffff) | (sign << 31); }
  88. void zero_mantissa() { _int &= 0xff80'0000; }
  89. static constexpr int C0 = 127; // 2^7 - 1
  90. static constexpr int C1 = -62; // 2 - 2^6
  91. static constexpr int C2 = 63; // 2^6 - 1
  92. static constexpr NumberTraits<4>::int_t C3 = 0b1011'1111'1111'1111'1111'1111'1111'1111;
  93. static constexpr int C4 = 0b11111111;
  94. BitsCvtImpl(NumberTraits<4>::float_t val): _float(val) {}
  95. BitsCvtImpl(NumberTraits<4>::int_t val): _int(val) {}
  96. // void print(){
  97. // std::string s = std::bitset<32>(_int).to_string();
  98. // std::cout << s.substr(0, 1) << '|';
  99. // std::cout << s.substr(1, 8) << '|';
  100. // std::cout << s.substr(9) << std::endl;
  101. // }
  102. };
  103. template<>
  104. union BitsCvtImpl<8>{
  105. NumberTraits<8>::int_t _int;
  106. NumberTraits<8>::float_t _float;
  107. // 1 + 11 + 52
  108. int sign() const { return _int >> 63; }
  109. unsigned int exp() const { return (_int >> 52) & 0b0111'1111'1111; }
  110. uint64_t mantissa() const { return _int & 0xfffffffffffff; }
  111. void set_exp(uint64_t exp) { _int = (_int & 0x800f'ffff'ffff'ffff) | (exp << 52); }
  112. void set_sign(uint64_t sign) { _int = (_int & 0x7fff'ffff'ffff'ffff) | (sign << 63); }
  113. void zero_mantissa() { _int &= 0xfff0'0000'0000'0000; }
  114. static constexpr int C0 = 1023; // 2^10 - 1
  115. static constexpr int C1 = -510; // 2 - 2^9
  116. static constexpr int C2 = 511; // 2^9 - 1
  117. static constexpr NumberTraits<8>::int_t C3 = 0b1011'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111;
  118. static constexpr int C4 = 0b11111111111;
  119. BitsCvtImpl(NumberTraits<8>::float_t val): _float(val) {}
  120. BitsCvtImpl(NumberTraits<8>::int_t val): _int(val) {}
  121. void print(){
  122. std::string s = std::bitset<64>(_int).to_string();
  123. std::cout << s.substr(0, 1) << '|';
  124. std::cout << s.substr(1, 11) << '|';
  125. std::cout << s.substr(12) << std::endl;
  126. }
  127. };
  128. using BitsCvt = BitsCvtImpl<sizeof(void*)>;
  129. static_assert(sizeof(i64) == 8);
  130. static_assert(sizeof(Number::float_t) == sizeof(void*));
  131. static_assert(sizeof(Number::int_t) == sizeof(void*));
  132. static_assert(sizeof(BitsCvt) == sizeof(void*));
  133. static_assert(std::numeric_limits<f64>::is_iec559);
  134. struct Dummy { }; // for special objects: True, False, None, Ellipsis, etc.
  135. struct DummyInstance { };
  136. struct DummyModule { };
  137. struct NoReturn { };
  138. struct Discarded { };
  139. struct Type {
  140. int index;
  141. constexpr Type(int index): index(index) {}
  142. bool operator==(Type other) const { return this->index == other.index; }
  143. bool operator!=(Type other) const { return this->index != other.index; }
  144. operator int() const { return this->index; }
  145. };
  146. #define PK_LAMBDA(x) ([](VM* vm, ArgsView args) { return x; })
  147. #define PK_VAR_LAMBDA(x) ([](VM* vm, ArgsView args) { return VAR(x); })
  148. #define PK_ACTION(x) ([](VM* vm, ArgsView args) { x; return vm->None; })
  149. #ifdef POCKETPY_H
  150. #define PK_FATAL_ERROR() throw std::runtime_error( "L" + std::to_string(__LINE__) + " FATAL_ERROR()!");
  151. #else
  152. #define PK_FATAL_ERROR() throw std::runtime_error( __FILE__ + std::string(":") + std::to_string(__LINE__) + " FATAL_ERROR()!");
  153. #endif
  154. #define PK_ASSERT(x) if(!(x)) PK_FATAL_ERROR();
  155. struct PyObject;
  156. #define PK_BITS(p) (reinterpret_cast<Number::int_t>(p))
  157. inline PyObject* tag_float(f64 val){
  158. BitsCvt decomposed(val);
  159. // std::cout << "tagging: " << val << std::endl;
  160. int sign = decomposed.sign();
  161. int exp_7b = decomposed.exp() - BitsCvt::C0;
  162. if(exp_7b < BitsCvt::C1){
  163. exp_7b = BitsCvt::C1 - 1; // -63 + 63 = 0
  164. decomposed.zero_mantissa();
  165. }else if(exp_7b > BitsCvt::C2){
  166. exp_7b = BitsCvt::C2 + 1; // 64 + 63 = 127
  167. if(!std::isnan(val)) decomposed.zero_mantissa();
  168. }
  169. decomposed.set_exp(exp_7b + BitsCvt::C2);
  170. decomposed._int = (decomposed._int << 1) | 0b01;
  171. decomposed.set_sign(sign);
  172. return reinterpret_cast<PyObject*>(decomposed._int);
  173. }
  174. inline f64 untag_float(PyObject* val){
  175. BitsCvt decomposed(reinterpret_cast<Number::int_t>(val));
  176. // std::cout << "untagging: " << val << std::endl;
  177. decomposed._int = (decomposed._int >> 1) & BitsCvt::C3;
  178. unsigned int exp_7b = decomposed.exp();
  179. if(exp_7b == 0) return 0.0f;
  180. if(exp_7b == BitsCvt::C0){
  181. decomposed.set_exp(BitsCvt::C4);
  182. return decomposed._float;
  183. }
  184. decomposed.set_exp(exp_7b - BitsCvt::C2 + BitsCvt::C0);
  185. return decomposed._float;
  186. }
  187. // is_pod<> for c++17 and c++20
  188. template<typename T>
  189. struct is_pod {
  190. static constexpr bool value = std::is_trivially_copyable_v<T> && std::is_standard_layout_v<T>;
  191. };
  192. #define PK_ALWAYS_PASS_BY_POINTER(T) \
  193. T(const T&) = delete; \
  194. T& operator=(const T&) = delete; \
  195. T(T&&) = delete; \
  196. T& operator=(T&&) = delete;
  197. inline const char* kPlatformStrings[] = {
  198. "win32", // 0
  199. "emscripten", // 1
  200. "ios", // 2
  201. "darwin", // 3
  202. "android", // 4
  203. "linux", // 5
  204. "unknown" // 6
  205. };
  206. } // namespace pkpy