natsu.fcall.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. #include "Chino.Kernel.h"
  2. #include "System.Console.h"
  3. #include <cmath>
  4. #include <random>
  5. #ifdef WIN32
  6. #include <Windows.h>
  7. #endif
  8. using namespace natsu;
  9. using namespace System_Private_CoreLib;
  10. using namespace System_Private_CoreLib::System;
  11. using namespace System_Private_CoreLib::System::Diagnostics;
  12. using namespace System_Private_CoreLib::System::Runtime;
  13. using namespace System_Private_CoreLib::System::Runtime::CompilerServices;
  14. using namespace System_Private_CoreLib::System::Runtime::InteropServices;
  15. using namespace System_Private_CoreLib::System::Threading;
  16. using namespace Chino_Threading;
  17. gc_obj_ref<Type> Object::GetType(::natsu::gc_obj_ref<Object> _this)
  18. {
  19. check_null_obj_ref(_this);
  20. pure_call();
  21. }
  22. gc_obj_ref<MulticastDelegate> MulticastDelegate::_s_CreateDelegateLike(gc_obj_ref<MulticastDelegate> delegate, gc_obj_ref<SZArray_1<Delegate>> invocationList)
  23. {
  24. auto d_len = invocationList->length();
  25. if (d_len == 0)
  26. {
  27. return nullptr;
  28. }
  29. else if (d_len == 1)
  30. {
  31. return invocationList->get(0).cast<MulticastDelegate>();
  32. }
  33. else
  34. {
  35. auto d = gc_alloc(*delegate.header().vtable_, sizeof(MulticastDelegate)).cast<MulticastDelegate>();
  36. d->_invocationList = invocationList;
  37. return d;
  38. }
  39. }
  40. void RuntimeImports::_s_GetRandomBytes(gc_ptr<uint8_t> buffer, int32_t length)
  41. {
  42. std::mt19937 rbe;
  43. std::generate_n(buffer.get(), length, std::ref(rbe));
  44. }
  45. void RuntimeImports::_s_RhZeroMemory(gc_ptr<void> b, uint64_t byteLength)
  46. {
  47. std::memset(b.ptr_, 0, byteLength);
  48. }
  49. int32_t RuntimeHelpers::_s_GetHashCode(::natsu::gc_obj_ref<::System_Private_CoreLib::System::Object> o)
  50. {
  51. return (int32_t)o.ptr_;
  52. }
  53. void Debugger::_s_BreakInternal()
  54. {
  55. #ifdef WIN32
  56. DebugBreak();
  57. #else
  58. assert(false);
  59. #endif
  60. }
  61. bool Debugger::_s_get_IsAttached()
  62. {
  63. #ifdef WIN32
  64. return IsDebuggerPresent();
  65. #else
  66. return false;
  67. #endif
  68. }
  69. bool Debugger::_s_LaunchInternal()
  70. {
  71. #ifdef WIN32
  72. while (IsDebuggerPresent())
  73. DebugBreak();
  74. return true;
  75. #else
  76. return false;
  77. #endif
  78. }
  79. void Debugger::_s_CustomNotification(gc_obj_ref<ICustomDebuggerNotification> data)
  80. {
  81. }
  82. void Environment::_s__Exit(int32_t exitCode)
  83. {
  84. exit(exitCode);
  85. }
  86. int32_t Environment::_s_get_TickCount()
  87. {
  88. return (int32_t)_s_get_TickCount64();
  89. }
  90. int64_t Environment::_s_get_TickCount64()
  91. {
  92. auto scheduler = Chino::Threading::Scheduler::_s_get_Current();
  93. return (int64_t)Chino::Threading::Scheduler::get_TickCount(scheduler);
  94. }
  95. void Marshal::_s_CopyToNative(gc_obj_ref<Object> source, int32_t startIndex, IntPtr destination, int32_t length)
  96. {
  97. check_null_obj_ref(source);
  98. check_null_obj_ref(destination._value);
  99. auto src = source.cast<RawSzArrayData>();
  100. auto element_size = source.header().vtable_->ElementSize;
  101. if ((startIndex + length) > (intptr_t)src->Count)
  102. throw_index_out_of_range_exception();
  103. std::memmove(destination._value, &src->Data + (size_t)startIndex * element_size, (size_t)length * element_size);
  104. }
  105. void Marshal::_s_CopyToManaged(IntPtr source, gc_obj_ref<Object> destination, int32_t startIndex, int32_t length)
  106. {
  107. check_null_obj_ref(source._value);
  108. check_null_obj_ref(destination);
  109. auto dest = destination.cast<RawSzArrayData>();
  110. auto element_size = destination.header().vtable_->ElementSize;
  111. if ((startIndex + length) > (intptr_t)dest->Count)
  112. throw_index_out_of_range_exception();
  113. std::memmove(&dest->Data + (size_t)startIndex * element_size, source._value, (size_t)length * element_size);
  114. }
  115. namespace
  116. {
  117. uint32_t get_current_thread_id()
  118. {
  119. return Chino::Threading::Scheduler::_s_get_CurrentThreadId();
  120. }
  121. }
  122. void Monitor::_s_Enter(gc_obj_ref<Object> obj)
  123. {
  124. bool lock_taken = false;
  125. _s_ReliableEnter(obj, lock_taken);
  126. }
  127. void Monitor::_s_ReliableEnter(gc_obj_ref<Object> obj, gc_ref<bool> lockTaken)
  128. {
  129. check_null_obj_ref(obj);
  130. auto thread_id = get_current_thread_id();
  131. auto &sync_header = obj.header().sync_header_;
  132. uint32_t expected = 0;
  133. while (true)
  134. {
  135. if (sync_header.lock_taken.compare_exchange_strong(expected, thread_id))
  136. {
  137. Volatile::_s_Write(*lockTaken, true);
  138. break;
  139. }
  140. Thread::_s_Sleep(1);
  141. }
  142. }
  143. void Monitor::_s_Exit(::natsu::gc_obj_ref<Object> obj)
  144. {
  145. check_null_obj_ref(obj);
  146. auto &sync_header = obj.header().sync_header_;
  147. sync_header.lock_taken.store(0);
  148. }
  149. void Monitor::_s_ReliableEnterTimeout(gc_obj_ref<Object> obj, int32_t timeout, gc_ref<bool> lockTaken)
  150. {
  151. pure_call();
  152. }
  153. bool Monitor::_s_IsEnteredNative(gc_obj_ref<Object> obj)
  154. {
  155. check_null_obj_ref(obj);
  156. auto thread_id = get_current_thread_id();
  157. auto &sync_header = obj.header().sync_header_;
  158. return sync_header.lock_taken.load() == thread_id;
  159. }
  160. bool Monitor::_s_ObjWait(bool exitContext, int32_t millisecondsTimeout, gc_obj_ref<Object> obj)
  161. {
  162. pure_call();
  163. }
  164. void Monitor::_s_ObjPulse(gc_obj_ref<Object> obj)
  165. {
  166. pure_call();
  167. }
  168. void Monitor::_s_ObjPulseAll(gc_obj_ref<Object> obj)
  169. {
  170. pure_call();
  171. }
  172. int64_t Monitor::_s_GetLockContentionCount()
  173. {
  174. return 0;
  175. }
  176. void Thread::_s_SleepInternal(int32_t millisecondsTimeout)
  177. {
  178. Chino::Threading::Scheduler::_s_Delay(TimeSpan::_s_FromMilliseconds(millisecondsTimeout));
  179. }
  180. bool Thread::_s_YieldInternal()
  181. {
  182. Chino::Threading::Scheduler::_s_Delay(TimeSpan::_s_FromTicks(0));
  183. return true;
  184. }
  185. int32_t Thread::_s_GetOptimalMaxSpinWaitsPerSpinIterationInternal()
  186. {
  187. return 1;
  188. }