enclave 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (739) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +182 -0
  3. data/Rakefile +30 -0
  4. data/ext/enclave/enclave.c +390 -0
  5. data/ext/enclave/extconf.rb +33 -0
  6. data/ext/enclave/mruby/Makefile +63 -0
  7. data/ext/enclave/mruby/Rakefile +102 -0
  8. data/ext/enclave/mruby/benchmark/bm_ao_render.rb +309 -0
  9. data/ext/enclave/mruby/benchmark/bm_app_lc_fizzbuzz.rb +51 -0
  10. data/ext/enclave/mruby/benchmark/bm_fib.rb +6 -0
  11. data/ext/enclave/mruby/benchmark/bm_mandel_term.rb +34 -0
  12. data/ext/enclave/mruby/benchmark/bm_so_lists.rb +49 -0
  13. data/ext/enclave/mruby/benchmark/bm_so_mandelbrot.rb +65 -0
  14. data/ext/enclave/mruby/benchmark/vm_dispatch_bench.c +197 -0
  15. data/ext/enclave/mruby/benchmark/vm_optimization_bench.rb +513 -0
  16. data/ext/enclave/mruby/build/host/include/mrbconf.h +230 -0
  17. data/ext/enclave/mruby/build/host/include/mruby/array.h +303 -0
  18. data/ext/enclave/mruby/build/host/include/mruby/boxing_nan.h +169 -0
  19. data/ext/enclave/mruby/build/host/include/mruby/boxing_no.h +59 -0
  20. data/ext/enclave/mruby/build/host/include/mruby/boxing_word.h +248 -0
  21. data/ext/enclave/mruby/build/host/include/mruby/class.h +157 -0
  22. data/ext/enclave/mruby/build/host/include/mruby/common.h +127 -0
  23. data/ext/enclave/mruby/build/host/include/mruby/compile.h +187 -0
  24. data/ext/enclave/mruby/build/host/include/mruby/data.h +76 -0
  25. data/ext/enclave/mruby/build/host/include/mruby/debug.h +75 -0
  26. data/ext/enclave/mruby/build/host/include/mruby/dump.h +159 -0
  27. data/ext/enclave/mruby/build/host/include/mruby/endian.h +44 -0
  28. data/ext/enclave/mruby/build/host/include/mruby/error.h +168 -0
  29. data/ext/enclave/mruby/build/host/include/mruby/gc.h +77 -0
  30. data/ext/enclave/mruby/build/host/include/mruby/hash.h +234 -0
  31. data/ext/enclave/mruby/build/host/include/mruby/internal.h +278 -0
  32. data/ext/enclave/mruby/build/host/include/mruby/irep.h +142 -0
  33. data/ext/enclave/mruby/build/host/include/mruby/istruct.h +50 -0
  34. data/ext/enclave/mruby/build/host/include/mruby/khash.h +455 -0
  35. data/ext/enclave/mruby/build/host/include/mruby/mempool.h +19 -0
  36. data/ext/enclave/mruby/build/host/include/mruby/numeric.h +174 -0
  37. data/ext/enclave/mruby/build/host/include/mruby/object.h +44 -0
  38. data/ext/enclave/mruby/build/host/include/mruby/opcode.h +73 -0
  39. data/ext/enclave/mruby/build/host/include/mruby/ops.h +133 -0
  40. data/ext/enclave/mruby/build/host/include/mruby/presym/id.h +895 -0
  41. data/ext/enclave/mruby/build/host/include/mruby/presym/scanning.h +82 -0
  42. data/ext/enclave/mruby/build/host/include/mruby/presym/table.h +1787 -0
  43. data/ext/enclave/mruby/build/host/include/mruby/presym.h +65 -0
  44. data/ext/enclave/mruby/build/host/include/mruby/proc.h +184 -0
  45. data/ext/enclave/mruby/build/host/include/mruby/range.h +77 -0
  46. data/ext/enclave/mruby/build/host/include/mruby/re.h +16 -0
  47. data/ext/enclave/mruby/build/host/include/mruby/string.h +428 -0
  48. data/ext/enclave/mruby/build/host/include/mruby/throw.h +81 -0
  49. data/ext/enclave/mruby/build/host/include/mruby/value.h +471 -0
  50. data/ext/enclave/mruby/build/host/include/mruby/variable.h +108 -0
  51. data/ext/enclave/mruby/build/host/include/mruby/version.h +143 -0
  52. data/ext/enclave/mruby/build/host/include/mruby.h +1632 -0
  53. data/ext/enclave/mruby/build/host/mrbc/include/mruby/presym/id.h +281 -0
  54. data/ext/enclave/mruby/build/host/mrbc/include/mruby/presym/table.h +559 -0
  55. data/ext/enclave/mruby/build/host/mrbgems/gem_init.c +164 -0
  56. data/ext/enclave/mruby/build/host/mrbgems/mruby-array-ext/gem_init.c +650 -0
  57. data/ext/enclave/mruby/build/host/mrbgems/mruby-binding/gem_init.c +21 -0
  58. data/ext/enclave/mruby/build/host/mrbgems/mruby-catch/gem_init.c +86 -0
  59. data/ext/enclave/mruby/build/host/mrbgems/mruby-class-ext/gem_init.c +21 -0
  60. data/ext/enclave/mruby/build/host/mrbgems/mruby-compar-ext/gem_init.c +99 -0
  61. data/ext/enclave/mruby/build/host/mrbgems/mruby-complex/gem_init.c +362 -0
  62. data/ext/enclave/mruby/build/host/mrbgems/mruby-data/gem_init.c +21 -0
  63. data/ext/enclave/mruby/build/host/mrbgems/mruby-enum-chain/gem_init.c +229 -0
  64. data/ext/enclave/mruby/build/host/mrbgems/mruby-enum-ext/gem_init.c +1420 -0
  65. data/ext/enclave/mruby/build/host/mrbgems/mruby-enum-lazy/gem_init.c +602 -0
  66. data/ext/enclave/mruby/build/host/mrbgems/mruby-enumerator/gem_init.c +822 -0
  67. data/ext/enclave/mruby/build/host/mrbgems/mruby-eval/gem_init.c +21 -0
  68. data/ext/enclave/mruby/build/host/mrbgems/mruby-fiber/gem_init.c +21 -0
  69. data/ext/enclave/mruby/build/host/mrbgems/mruby-hash-ext/gem_init.c +591 -0
  70. data/ext/enclave/mruby/build/host/mrbgems/mruby-kernel-ext/gem_init.c +21 -0
  71. data/ext/enclave/mruby/build/host/mrbgems/mruby-math/gem_init.c +21 -0
  72. data/ext/enclave/mruby/build/host/mrbgems/mruby-metaprog/gem_init.c +21 -0
  73. data/ext/enclave/mruby/build/host/mrbgems/mruby-method/gem_init.c +153 -0
  74. data/ext/enclave/mruby/build/host/mrbgems/mruby-numeric-ext/gem_init.c +211 -0
  75. data/ext/enclave/mruby/build/host/mrbgems/mruby-object-ext/gem_init.c +94 -0
  76. data/ext/enclave/mruby/build/host/mrbgems/mruby-objectspace/gem_init.c +21 -0
  77. data/ext/enclave/mruby/build/host/mrbgems/mruby-pack/gem_init.c +21 -0
  78. data/ext/enclave/mruby/build/host/mrbgems/mruby-proc-binding/gem_init.c +21 -0
  79. data/ext/enclave/mruby/build/host/mrbgems/mruby-proc-ext/gem_init.c +237 -0
  80. data/ext/enclave/mruby/build/host/mrbgems/mruby-random/gem_init.c +21 -0
  81. data/ext/enclave/mruby/build/host/mrbgems/mruby-range-ext/gem_init.c +205 -0
  82. data/ext/enclave/mruby/build/host/mrbgems/mruby-rational/gem_init.c +147 -0
  83. data/ext/enclave/mruby/build/host/mrbgems/mruby-set/gem_init.c +487 -0
  84. data/ext/enclave/mruby/build/host/mrbgems/mruby-sprintf/gem_init.c +83 -0
  85. data/ext/enclave/mruby/build/host/mrbgems/mruby-string-ext/gem_init.c +220 -0
  86. data/ext/enclave/mruby/build/host/mrbgems/mruby-struct/gem_init.c +175 -0
  87. data/ext/enclave/mruby/build/host/mrbgems/mruby-symbol-ext/gem_init.c +153 -0
  88. data/ext/enclave/mruby/build/host/mrbgems/mruby-time/gem_init.c +21 -0
  89. data/ext/enclave/mruby/build/host/mrbgems/mruby-toplevel-ext/gem_init.c +78 -0
  90. data/ext/enclave/mruby/build/host/mrblib/mrblib.c +1758 -0
  91. data/ext/enclave/mruby/build_config/ArduinoDue.rb +72 -0
  92. data/ext/enclave/mruby/build_config/IntelEdison.rb +69 -0
  93. data/ext/enclave/mruby/build_config/IntelGalileo.rb +88 -0
  94. data/ext/enclave/mruby/build_config/RX630.rb +63 -0
  95. data/ext/enclave/mruby/build_config/android_arm64_v8a.rb +11 -0
  96. data/ext/enclave/mruby/build_config/android_armeabi_v7a_neon_hard.rb +13 -0
  97. data/ext/enclave/mruby/build_config/bench.rb +11 -0
  98. data/ext/enclave/mruby/build_config/boxing.rb +19 -0
  99. data/ext/enclave/mruby/build_config/chipKITMax32.rb +68 -0
  100. data/ext/enclave/mruby/build_config/ci/gcc-clang.rb +40 -0
  101. data/ext/enclave/mruby/build_config/ci/msvc.rb +20 -0
  102. data/ext/enclave/mruby/build_config/clang-asan.rb +11 -0
  103. data/ext/enclave/mruby/build_config/cosmopolitan.rb +86 -0
  104. data/ext/enclave/mruby/build_config/cross-32bit.rb +14 -0
  105. data/ext/enclave/mruby/build_config/cross-mingw-winetest.rb +90 -0
  106. data/ext/enclave/mruby/build_config/cross-mingw.rb +14 -0
  107. data/ext/enclave/mruby/build_config/default.rb +83 -0
  108. data/ext/enclave/mruby/build_config/dreamcast_shelf.rb +81 -0
  109. data/ext/enclave/mruby/build_config/emscripten-cxx.rb +12 -0
  110. data/ext/enclave/mruby/build_config/emscripten.rb +10 -0
  111. data/ext/enclave/mruby/build_config/gameboyadvance.rb +72 -0
  112. data/ext/enclave/mruby/build_config/helpers/wine_runner.rb +71 -0
  113. data/ext/enclave/mruby/build_config/host-cxx.rb +12 -0
  114. data/ext/enclave/mruby/build_config/host-debug.rb +20 -0
  115. data/ext/enclave/mruby/build_config/host-f32.rb +14 -0
  116. data/ext/enclave/mruby/build_config/host-gprof.rb +14 -0
  117. data/ext/enclave/mruby/build_config/host-m32.rb +15 -0
  118. data/ext/enclave/mruby/build_config/host-nofloat.rb +22 -0
  119. data/ext/enclave/mruby/build_config/host-shared.rb +36 -0
  120. data/ext/enclave/mruby/build_config/i586-pc-msdosdjgpp.rb +76 -0
  121. data/ext/enclave/mruby/build_config/luckfox_pico.rb +106 -0
  122. data/ext/enclave/mruby/build_config/milkv_duo.rb +106 -0
  123. data/ext/enclave/mruby/build_config/minimal.rb +4 -0
  124. data/ext/enclave/mruby/build_config/mrbc.rb +10 -0
  125. data/ext/enclave/mruby/build_config/nintendo_switch.rb +73 -0
  126. data/ext/enclave/mruby/build_config/nintendo_wii.rb +95 -0
  127. data/ext/enclave/mruby/build_config/no-float.rb +17 -0
  128. data/ext/enclave/mruby/build_config/playstationportable.rb +78 -0
  129. data/ext/enclave/mruby/build_config/serenity.rb +26 -0
  130. data/ext/enclave/mruby/build_config.rb +9 -0
  131. data/ext/enclave/mruby/examples/mrbgems/c_and_ruby_extension_example/mrblib/example.rb +5 -0
  132. data/ext/enclave/mruby/examples/mrbgems/c_and_ruby_extension_example/src/example.c +23 -0
  133. data/ext/enclave/mruby/examples/mrbgems/c_and_ruby_extension_example/test/example.rb +7 -0
  134. data/ext/enclave/mruby/examples/mrbgems/c_extension_example/src/example.c +23 -0
  135. data/ext/enclave/mruby/examples/mrbgems/c_extension_example/test/example.c +7 -0
  136. data/ext/enclave/mruby/examples/mrbgems/c_extension_example/test/example.rb +3 -0
  137. data/ext/enclave/mruby/examples/mrbgems/cdata_extension_example/src/example.c +77 -0
  138. data/ext/enclave/mruby/examples/mrbgems/cdata_extension_example/test/example.c +7 -0
  139. data/ext/enclave/mruby/examples/mrbgems/mruby-YOUR-bigint/core/bigint.c +70 -0
  140. data/ext/enclave/mruby/examples/mrbgems/ruby_extension_example/mrblib/example.rb +5 -0
  141. data/ext/enclave/mruby/examples/mrbgems/ruby_extension_example/test/example.rb +3 -0
  142. data/ext/enclave/mruby/include/mrbconf.h +230 -0
  143. data/ext/enclave/mruby/include/mruby/array.h +303 -0
  144. data/ext/enclave/mruby/include/mruby/boxing_nan.h +169 -0
  145. data/ext/enclave/mruby/include/mruby/boxing_no.h +59 -0
  146. data/ext/enclave/mruby/include/mruby/boxing_word.h +248 -0
  147. data/ext/enclave/mruby/include/mruby/class.h +157 -0
  148. data/ext/enclave/mruby/include/mruby/common.h +127 -0
  149. data/ext/enclave/mruby/include/mruby/compile.h +187 -0
  150. data/ext/enclave/mruby/include/mruby/data.h +76 -0
  151. data/ext/enclave/mruby/include/mruby/debug.h +75 -0
  152. data/ext/enclave/mruby/include/mruby/dump.h +159 -0
  153. data/ext/enclave/mruby/include/mruby/endian.h +44 -0
  154. data/ext/enclave/mruby/include/mruby/error.h +168 -0
  155. data/ext/enclave/mruby/include/mruby/gc.h +77 -0
  156. data/ext/enclave/mruby/include/mruby/hash.h +234 -0
  157. data/ext/enclave/mruby/include/mruby/internal.h +278 -0
  158. data/ext/enclave/mruby/include/mruby/irep.h +142 -0
  159. data/ext/enclave/mruby/include/mruby/istruct.h +50 -0
  160. data/ext/enclave/mruby/include/mruby/khash.h +455 -0
  161. data/ext/enclave/mruby/include/mruby/mempool.h +19 -0
  162. data/ext/enclave/mruby/include/mruby/numeric.h +174 -0
  163. data/ext/enclave/mruby/include/mruby/object.h +44 -0
  164. data/ext/enclave/mruby/include/mruby/opcode.h +73 -0
  165. data/ext/enclave/mruby/include/mruby/ops.h +133 -0
  166. data/ext/enclave/mruby/include/mruby/presym/scanning.h +82 -0
  167. data/ext/enclave/mruby/include/mruby/presym.h +65 -0
  168. data/ext/enclave/mruby/include/mruby/proc.h +184 -0
  169. data/ext/enclave/mruby/include/mruby/range.h +77 -0
  170. data/ext/enclave/mruby/include/mruby/re.h +16 -0
  171. data/ext/enclave/mruby/include/mruby/string.h +428 -0
  172. data/ext/enclave/mruby/include/mruby/throw.h +81 -0
  173. data/ext/enclave/mruby/include/mruby/value.h +471 -0
  174. data/ext/enclave/mruby/include/mruby/variable.h +108 -0
  175. data/ext/enclave/mruby/include/mruby/version.h +143 -0
  176. data/ext/enclave/mruby/include/mruby.h +1632 -0
  177. data/ext/enclave/mruby/lib/mruby/amalgam.rb +568 -0
  178. data/ext/enclave/mruby/lib/mruby/build/command.rb +383 -0
  179. data/ext/enclave/mruby/lib/mruby/build/load_gems.rb +383 -0
  180. data/ext/enclave/mruby/lib/mruby/build.rb +616 -0
  181. data/ext/enclave/mruby/lib/mruby/core_ext.rb +61 -0
  182. data/ext/enclave/mruby/lib/mruby/doc.rb +51 -0
  183. data/ext/enclave/mruby/lib/mruby/gem.rb +585 -0
  184. data/ext/enclave/mruby/lib/mruby/lockfile.rb +81 -0
  185. data/ext/enclave/mruby/lib/mruby/presym.rb +167 -0
  186. data/ext/enclave/mruby/lib/mruby/source.rb +32 -0
  187. data/ext/enclave/mruby/mrbgems/default-no-fpu.gembox +3 -0
  188. data/ext/enclave/mruby/mrbgems/default-no-stdio.gembox +4 -0
  189. data/ext/enclave/mruby/mrbgems/default.gembox +25 -0
  190. data/ext/enclave/mruby/mrbgems/full-core.gembox +6 -0
  191. data/ext/enclave/mruby/mrbgems/hal-posix-dir/mrbgem.rake +7 -0
  192. data/ext/enclave/mruby/mrbgems/hal-posix-dir/src/dir_hal.c +193 -0
  193. data/ext/enclave/mruby/mrbgems/hal-posix-io/mrbgem.rake +8 -0
  194. data/ext/enclave/mruby/mrbgems/hal-posix-io/src/io_hal.c +602 -0
  195. data/ext/enclave/mruby/mrbgems/hal-posix-socket/mrbgem.rake +8 -0
  196. data/ext/enclave/mruby/mrbgems/hal-posix-socket/src/socket_hal.c +158 -0
  197. data/ext/enclave/mruby/mrbgems/hal-posix-task/README.md +102 -0
  198. data/ext/enclave/mruby/mrbgems/hal-posix-task/mrbgem.rake +8 -0
  199. data/ext/enclave/mruby/mrbgems/hal-posix-task/src/task_hal.c +252 -0
  200. data/ext/enclave/mruby/mrbgems/hal-win-dir/mrbgem.rake +7 -0
  201. data/ext/enclave/mruby/mrbgems/hal-win-dir/src/dir_hal.c +249 -0
  202. data/ext/enclave/mruby/mrbgems/hal-win-io/mrbgem.rake +11 -0
  203. data/ext/enclave/mruby/mrbgems/hal-win-io/src/io_hal.c +646 -0
  204. data/ext/enclave/mruby/mrbgems/hal-win-socket/mrbgem.rake +12 -0
  205. data/ext/enclave/mruby/mrbgems/hal-win-socket/src/socket_hal.c +177 -0
  206. data/ext/enclave/mruby/mrbgems/hal-win-task/README.md +109 -0
  207. data/ext/enclave/mruby/mrbgems/hal-win-task/mrbgem.rake +11 -0
  208. data/ext/enclave/mruby/mrbgems/hal-win-task/src/task_hal.c +187 -0
  209. data/ext/enclave/mruby/mrbgems/math.gembox +12 -0
  210. data/ext/enclave/mruby/mrbgems/metaprog.gembox +21 -0
  211. data/ext/enclave/mruby/mrbgems/mruby-array-ext/README.md +87 -0
  212. data/ext/enclave/mruby/mrbgems/mruby-array-ext/mrbgem.rake +5 -0
  213. data/ext/enclave/mruby/mrbgems/mruby-array-ext/mrblib/array.rb +784 -0
  214. data/ext/enclave/mruby/mrbgems/mruby-array-ext/src/array.c +1583 -0
  215. data/ext/enclave/mruby/mrbgems/mruby-array-ext/test/array.rb +849 -0
  216. data/ext/enclave/mruby/mrbgems/mruby-benchmark/README.md +257 -0
  217. data/ext/enclave/mruby/mrbgems/mruby-benchmark/mrbgem.rake +10 -0
  218. data/ext/enclave/mruby/mrbgems/mruby-benchmark/mrblib/benchmark.rb +131 -0
  219. data/ext/enclave/mruby/mrbgems/mruby-benchmark/test/benchmark.rb +244 -0
  220. data/ext/enclave/mruby/mrbgems/mruby-bigint/README-fgmp.md +154 -0
  221. data/ext/enclave/mruby/mrbgems/mruby-bigint/README.md +44 -0
  222. data/ext/enclave/mruby/mrbgems/mruby-bigint/core/bigint.c +6335 -0
  223. data/ext/enclave/mruby/mrbgems/mruby-bigint/core/bigint.h +117 -0
  224. data/ext/enclave/mruby/mrbgems/mruby-bigint/mrbgem.rake +10 -0
  225. data/ext/enclave/mruby/mrbgems/mruby-bigint/test/bigint.rb +157 -0
  226. data/ext/enclave/mruby/mrbgems/mruby-bin-config/README.md +46 -0
  227. data/ext/enclave/mruby/mrbgems/mruby-bin-config/mrbgem.rake +49 -0
  228. data/ext/enclave/mruby/mrbgems/mruby-bin-config/mruby-config +46 -0
  229. data/ext/enclave/mruby/mrbgems/mruby-bin-config/mruby-config.bat +92 -0
  230. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/README.md +63 -0
  231. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/bintest/mrdb.rb +283 -0
  232. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/bintest/print.rb +703 -0
  233. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/mrbgem.rake +10 -0
  234. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.c +523 -0
  235. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.h +26 -0
  236. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apilist.c +238 -0
  237. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apilist.h +14 -0
  238. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apiprint.c +88 -0
  239. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apiprint.h +13 -0
  240. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apistring.c +34 -0
  241. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apistring.h +14 -0
  242. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/cmdbreak.c +436 -0
  243. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/cmdmisc.c +509 -0
  244. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/cmdprint.c +71 -0
  245. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/cmdrun.c +64 -0
  246. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.c +768 -0
  247. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.h +159 -0
  248. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/mrdbconf.h +24 -0
  249. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/mrdberror.h +19 -0
  250. data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/README.md +94 -0
  251. data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/bintest/mirb.rb +58 -0
  252. data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/mrbgem.rake +7 -0
  253. data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c +808 -0
  254. data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb_buffer.c +1035 -0
  255. data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb_buffer.h +185 -0
  256. data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb_completion.c +797 -0
  257. data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb_completion.h +132 -0
  258. data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb_editor.c +1118 -0
  259. data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb_editor.h +153 -0
  260. data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb_highlight.c +516 -0
  261. data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb_highlight.h +95 -0
  262. data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb_history.c +185 -0
  263. data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb_history.h +76 -0
  264. data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb_term.c +491 -0
  265. data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb_term.h +137 -0
  266. data/ext/enclave/mruby/mrbgems/mruby-bin-mrbc/README.md +58 -0
  267. data/ext/enclave/mruby/mrbgems/mruby-bin-mrbc/bintest/mrbc.rb +30 -0
  268. data/ext/enclave/mruby/mrbgems/mruby-bin-mrbc/mrbgem.rake +15 -0
  269. data/ext/enclave/mruby/mrbgems/mruby-bin-mrbc/tools/mrbc/mrbc.c +362 -0
  270. data/ext/enclave/mruby/mrbgems/mruby-bin-mrbc/tools/mrbc/stub.c +104 -0
  271. data/ext/enclave/mruby/mrbgems/mruby-bin-mruby/README.md +47 -0
  272. data/ext/enclave/mruby/mrbgems/mruby-bin-mruby/bintest/mruby.rb +178 -0
  273. data/ext/enclave/mruby/mrbgems/mruby-bin-mruby/mrbgem.rake +7 -0
  274. data/ext/enclave/mruby/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c +380 -0
  275. data/ext/enclave/mruby/mrbgems/mruby-bin-strip/README.md +38 -0
  276. data/ext/enclave/mruby/mrbgems/mruby-bin-strip/bintest/mruby_strip.rb +73 -0
  277. data/ext/enclave/mruby/mrbgems/mruby-bin-strip/mrbgem.rake +7 -0
  278. data/ext/enclave/mruby/mrbgems/mruby-bin-strip/tools/mruby-strip/mruby_strip.c +139 -0
  279. data/ext/enclave/mruby/mrbgems/mruby-binding/README.md +256 -0
  280. data/ext/enclave/mruby/mrbgems/mruby-binding/mrbgem.rake +7 -0
  281. data/ext/enclave/mruby/mrbgems/mruby-binding/src/binding.c +518 -0
  282. data/ext/enclave/mruby/mrbgems/mruby-binding/test/binding.c +14 -0
  283. data/ext/enclave/mruby/mrbgems/mruby-binding/test/binding.rb +64 -0
  284. data/ext/enclave/mruby/mrbgems/mruby-catch/README.md +94 -0
  285. data/ext/enclave/mruby/mrbgems/mruby-catch/mrbgem.rake +5 -0
  286. data/ext/enclave/mruby/mrbgems/mruby-catch/mrblib/catch.rb +29 -0
  287. data/ext/enclave/mruby/mrbgems/mruby-catch/src/catch.c +149 -0
  288. data/ext/enclave/mruby/mrbgems/mruby-catch/test/catch.rb +86 -0
  289. data/ext/enclave/mruby/mrbgems/mruby-class-ext/README.md +81 -0
  290. data/ext/enclave/mruby/mrbgems/mruby-class-ext/mrbgem.rake +5 -0
  291. data/ext/enclave/mruby/mrbgems/mruby-class-ext/src/class.c +377 -0
  292. data/ext/enclave/mruby/mrbgems/mruby-class-ext/test/class.rb +46 -0
  293. data/ext/enclave/mruby/mrbgems/mruby-class-ext/test/module.rb +109 -0
  294. data/ext/enclave/mruby/mrbgems/mruby-cmath/README.md +45 -0
  295. data/ext/enclave/mruby/mrbgems/mruby-cmath/mrbgem.rake +8 -0
  296. data/ext/enclave/mruby/mrbgems/mruby-cmath/src/cmath.c +426 -0
  297. data/ext/enclave/mruby/mrbgems/mruby-cmath/test/cmath.rb +41 -0
  298. data/ext/enclave/mruby/mrbgems/mruby-compar-ext/README.md +65 -0
  299. data/ext/enclave/mruby/mrbgems/mruby-compar-ext/mrbgem.rake +5 -0
  300. data/ext/enclave/mruby/mrbgems/mruby-compar-ext/mrblib/compar.rb +75 -0
  301. data/ext/enclave/mruby/mrbgems/mruby-compar-ext/test/compar.rb +21 -0
  302. data/ext/enclave/mruby/mrbgems/mruby-compiler/README.md +28 -0
  303. data/ext/enclave/mruby/mrbgems/mruby-compiler/core/codegen.c +7316 -0
  304. data/ext/enclave/mruby/mrbgems/mruby-compiler/core/keywords +52 -0
  305. data/ext/enclave/mruby/mrbgems/mruby-compiler/core/lex.def +207 -0
  306. data/ext/enclave/mruby/mrbgems/mruby-compiler/core/node.h +784 -0
  307. data/ext/enclave/mruby/mrbgems/mruby-compiler/core/parse.y +8977 -0
  308. data/ext/enclave/mruby/mrbgems/mruby-compiler/core/y.tab.c +16136 -0
  309. data/ext/enclave/mruby/mrbgems/mruby-compiler/mrbgem.rake +42 -0
  310. data/ext/enclave/mruby/mrbgems/mruby-complex/README.md +55 -0
  311. data/ext/enclave/mruby/mrbgems/mruby-complex/mrbgem.rake +7 -0
  312. data/ext/enclave/mruby/mrbgems/mruby-complex/mrblib/complex.rb +259 -0
  313. data/ext/enclave/mruby/mrbgems/mruby-complex/src/complex.c +597 -0
  314. data/ext/enclave/mruby/mrbgems/mruby-complex/test/complex.rb +174 -0
  315. data/ext/enclave/mruby/mrbgems/mruby-data/README.md +126 -0
  316. data/ext/enclave/mruby/mrbgems/mruby-data/mrbgem.rake +5 -0
  317. data/ext/enclave/mruby/mrbgems/mruby-data/src/data.c +550 -0
  318. data/ext/enclave/mruby/mrbgems/mruby-data/test/data.rb +76 -0
  319. data/ext/enclave/mruby/mrbgems/mruby-dir/README.md +53 -0
  320. data/ext/enclave/mruby/mrbgems/mruby-dir/include/dir_hal.h +79 -0
  321. data/ext/enclave/mruby/mrbgems/mruby-dir/mrbgem.rake +35 -0
  322. data/ext/enclave/mruby/mrbgems/mruby-dir/mrblib/dir.rb +124 -0
  323. data/ext/enclave/mruby/mrbgems/mruby-dir/src/dir.c +493 -0
  324. data/ext/enclave/mruby/mrbgems/mruby-dir/test/dir.rb +138 -0
  325. data/ext/enclave/mruby/mrbgems/mruby-dir/test/dirtest.c +125 -0
  326. data/ext/enclave/mruby/mrbgems/mruby-encoding/README.md +96 -0
  327. data/ext/enclave/mruby/mrbgems/mruby-encoding/mrbgem.rake +8 -0
  328. data/ext/enclave/mruby/mrbgems/mruby-encoding/src/encoding.c +128 -0
  329. data/ext/enclave/mruby/mrbgems/mruby-encoding/test/numeric.rb +27 -0
  330. data/ext/enclave/mruby/mrbgems/mruby-encoding/test/string.rb +30 -0
  331. data/ext/enclave/mruby/mrbgems/mruby-enum-chain/README.md +80 -0
  332. data/ext/enclave/mruby/mrbgems/mruby-enum-chain/mrbgem.rake +6 -0
  333. data/ext/enclave/mruby/mrbgems/mruby-enum-chain/mrblib/chain.rb +149 -0
  334. data/ext/enclave/mruby/mrbgems/mruby-enum-chain/test/enum_chain.rb +108 -0
  335. data/ext/enclave/mruby/mrbgems/mruby-enum-ext/README.md +487 -0
  336. data/ext/enclave/mruby/mrbgems/mruby-enum-ext/mrbgem.rake +5 -0
  337. data/ext/enclave/mruby/mrbgems/mruby-enum-ext/mrblib/enum.rb +938 -0
  338. data/ext/enclave/mruby/mrbgems/mruby-enum-ext/test/enum.rb +223 -0
  339. data/ext/enclave/mruby/mrbgems/mruby-enum-lazy/README.md +91 -0
  340. data/ext/enclave/mruby/mrbgems/mruby-enum-lazy/mrbgem.rake +7 -0
  341. data/ext/enclave/mruby/mrbgems/mruby-enum-lazy/mrblib/lazy.rb +363 -0
  342. data/ext/enclave/mruby/mrbgems/mruby-enum-lazy/test/lazy.rb +59 -0
  343. data/ext/enclave/mruby/mrbgems/mruby-enumerator/README.md +89 -0
  344. data/ext/enclave/mruby/mrbgems/mruby-enumerator/mrbgem.rake +6 -0
  345. data/ext/enclave/mruby/mrbgems/mruby-enumerator/mrblib/enumerator.rb +861 -0
  346. data/ext/enclave/mruby/mrbgems/mruby-enumerator/test/enumerator.rb +664 -0
  347. data/ext/enclave/mruby/mrbgems/mruby-errno/README.md +83 -0
  348. data/ext/enclave/mruby/mrbgems/mruby-errno/mrbgem.rake +5 -0
  349. data/ext/enclave/mruby/mrbgems/mruby-errno/mrblib/errno.rb +50 -0
  350. data/ext/enclave/mruby/mrbgems/mruby-errno/src/errno.c +335 -0
  351. data/ext/enclave/mruby/mrbgems/mruby-errno/src/gen.rb +18 -0
  352. data/ext/enclave/mruby/mrbgems/mruby-errno/src/known_errors.def +156 -0
  353. data/ext/enclave/mruby/mrbgems/mruby-errno/src/known_errors_def.cstub +780 -0
  354. data/ext/enclave/mruby/mrbgems/mruby-errno/test/errno.rb +57 -0
  355. data/ext/enclave/mruby/mrbgems/mruby-error/README.md +103 -0
  356. data/ext/enclave/mruby/mrbgems/mruby-error/mrbgem.rake +5 -0
  357. data/ext/enclave/mruby/mrbgems/mruby-error/src/exception.c +143 -0
  358. data/ext/enclave/mruby/mrbgems/mruby-error/test/exception.c +60 -0
  359. data/ext/enclave/mruby/mrbgems/mruby-error/test/exception.rb +55 -0
  360. data/ext/enclave/mruby/mrbgems/mruby-eval/README.md +26 -0
  361. data/ext/enclave/mruby/mrbgems/mruby-eval/mrbgem.rake +10 -0
  362. data/ext/enclave/mruby/mrbgems/mruby-eval/src/eval.c +437 -0
  363. data/ext/enclave/mruby/mrbgems/mruby-eval/test/binding.rb +81 -0
  364. data/ext/enclave/mruby/mrbgems/mruby-eval/test/eval.rb +185 -0
  365. data/ext/enclave/mruby/mrbgems/mruby-exit/mrbgem.rake +5 -0
  366. data/ext/enclave/mruby/mrbgems/mruby-exit/src/mruby_exit.c +83 -0
  367. data/ext/enclave/mruby/mrbgems/mruby-fiber/mrbgem.rake +5 -0
  368. data/ext/enclave/mruby/mrbgems/mruby-fiber/src/fiber.c +575 -0
  369. data/ext/enclave/mruby/mrbgems/mruby-fiber/test/fiber.rb +210 -0
  370. data/ext/enclave/mruby/mrbgems/mruby-fiber/test/fiber2.rb +155 -0
  371. data/ext/enclave/mruby/mrbgems/mruby-fiber/test/fibertest.c +87 -0
  372. data/ext/enclave/mruby/mrbgems/mruby-hash-ext/README.md +392 -0
  373. data/ext/enclave/mruby/mrbgems/mruby-hash-ext/mrbgem.rake +6 -0
  374. data/ext/enclave/mruby/mrbgems/mruby-hash-ext/mrblib/hash.rb +408 -0
  375. data/ext/enclave/mruby/mrbgems/mruby-hash-ext/src/hash_ext.c +392 -0
  376. data/ext/enclave/mruby/mrbgems/mruby-hash-ext/test/hash.rb +317 -0
  377. data/ext/enclave/mruby/mrbgems/mruby-io/README.md +198 -0
  378. data/ext/enclave/mruby/mrbgems/mruby-io/include/io_hal.h +451 -0
  379. data/ext/enclave/mruby/mrbgems/mruby-io/include/mruby/io.h +76 -0
  380. data/ext/enclave/mruby/mrbgems/mruby-io/mrbgem.rake +34 -0
  381. data/ext/enclave/mruby/mrbgems/mruby-io/mrblib/file.rb +109 -0
  382. data/ext/enclave/mruby/mrbgems/mruby-io/mrblib/file_constants.rb +24 -0
  383. data/ext/enclave/mruby/mrbgems/mruby-io/mrblib/io.rb +303 -0
  384. data/ext/enclave/mruby/mrbgems/mruby-io/mrblib/kernel.rb +175 -0
  385. data/ext/enclave/mruby/mrbgems/mruby-io/src/file.c +1192 -0
  386. data/ext/enclave/mruby/mrbgems/mruby-io/src/file_test.c +403 -0
  387. data/ext/enclave/mruby/mrbgems/mruby-io/src/io.c +2260 -0
  388. data/ext/enclave/mruby/mrbgems/mruby-io/src/mruby_io_gem.c +21 -0
  389. data/ext/enclave/mruby/mrbgems/mruby-io/test/file.rb +415 -0
  390. data/ext/enclave/mruby/mrbgems/mruby-io/test/file_test.rb +112 -0
  391. data/ext/enclave/mruby/mrbgems/mruby-io/test/io.rb +668 -0
  392. data/ext/enclave/mruby/mrbgems/mruby-io/test/mruby_io_test.c +293 -0
  393. data/ext/enclave/mruby/mrbgems/mruby-kernel-ext/README.md +165 -0
  394. data/ext/enclave/mruby/mrbgems/mruby-kernel-ext/mrbgem.rake +5 -0
  395. data/ext/enclave/mruby/mrbgems/mruby-kernel-ext/src/kernel.c +316 -0
  396. data/ext/enclave/mruby/mrbgems/mruby-kernel-ext/test/kernel.rb +134 -0
  397. data/ext/enclave/mruby/mrbgems/mruby-math/README.md +77 -0
  398. data/ext/enclave/mruby/mrbgems/mruby-math/mrbgem.rake +5 -0
  399. data/ext/enclave/mruby/mrbgems/mruby-math/src/math.c +753 -0
  400. data/ext/enclave/mruby/mrbgems/mruby-math/test/math.rb +201 -0
  401. data/ext/enclave/mruby/mrbgems/mruby-metaprog/README.md +123 -0
  402. data/ext/enclave/mruby/mrbgems/mruby-metaprog/mrbgem.rake +5 -0
  403. data/ext/enclave/mruby/mrbgems/mruby-metaprog/src/metaprog.c +739 -0
  404. data/ext/enclave/mruby/mrbgems/mruby-metaprog/test/metaprog.rb +465 -0
  405. data/ext/enclave/mruby/mrbgems/mruby-method/README.md +66 -0
  406. data/ext/enclave/mruby/mrbgems/mruby-method/mrbgem.rake +7 -0
  407. data/ext/enclave/mruby/mrbgems/mruby-method/mrblib/method.rb +73 -0
  408. data/ext/enclave/mruby/mrbgems/mruby-method/src/method.c +890 -0
  409. data/ext/enclave/mruby/mrbgems/mruby-method/test/method.rb +514 -0
  410. data/ext/enclave/mruby/mrbgems/mruby-numeric-ext/README.md +78 -0
  411. data/ext/enclave/mruby/mrbgems/mruby-numeric-ext/mrbgem.rake +5 -0
  412. data/ext/enclave/mruby/mrbgems/mruby-numeric-ext/mrblib/numeric_ext.rb +125 -0
  413. data/ext/enclave/mruby/mrbgems/mruby-numeric-ext/src/numeric_ext.c +527 -0
  414. data/ext/enclave/mruby/mrbgems/mruby-numeric-ext/test/numeric.rb +137 -0
  415. data/ext/enclave/mruby/mrbgems/mruby-object-ext/README.md +144 -0
  416. data/ext/enclave/mruby/mrbgems/mruby-object-ext/mrbgem.rake +5 -0
  417. data/ext/enclave/mruby/mrbgems/mruby-object-ext/mrblib/object.rb +33 -0
  418. data/ext/enclave/mruby/mrbgems/mruby-object-ext/src/object.c +128 -0
  419. data/ext/enclave/mruby/mrbgems/mruby-object-ext/test/nil.rb +16 -0
  420. data/ext/enclave/mruby/mrbgems/mruby-object-ext/test/object.rb +67 -0
  421. data/ext/enclave/mruby/mrbgems/mruby-object-ext/test/object_ext.c +17 -0
  422. data/ext/enclave/mruby/mrbgems/mruby-objectspace/README.md +59 -0
  423. data/ext/enclave/mruby/mrbgems/mruby-objectspace/mrbgem.rake +5 -0
  424. data/ext/enclave/mruby/mrbgems/mruby-objectspace/src/mruby_objectspace.c +188 -0
  425. data/ext/enclave/mruby/mrbgems/mruby-objectspace/test/objectspace.rb +60 -0
  426. data/ext/enclave/mruby/mrbgems/mruby-os-memsize/README.md +75 -0
  427. data/ext/enclave/mruby/mrbgems/mruby-os-memsize/mrbgem.rake +10 -0
  428. data/ext/enclave/mruby/mrbgems/mruby-os-memsize/src/memsize.c +271 -0
  429. data/ext/enclave/mruby/mrbgems/mruby-os-memsize/test/memsize.rb +63 -0
  430. data/ext/enclave/mruby/mrbgems/mruby-pack/README.md +140 -0
  431. data/ext/enclave/mruby/mrbgems/mruby-pack/mrbgem.rake +5 -0
  432. data/ext/enclave/mruby/mrbgems/mruby-pack/src/pack.c +2129 -0
  433. data/ext/enclave/mruby/mrbgems/mruby-pack/test/pack.rb +202 -0
  434. data/ext/enclave/mruby/mrbgems/mruby-proc-binding/README.md +140 -0
  435. data/ext/enclave/mruby/mrbgems/mruby-proc-binding/mrbgem.rake +10 -0
  436. data/ext/enclave/mruby/mrbgems/mruby-proc-binding/src/proc_binding.c +76 -0
  437. data/ext/enclave/mruby/mrbgems/mruby-proc-binding/test/proc_binding.c +14 -0
  438. data/ext/enclave/mruby/mrbgems/mruby-proc-binding/test/proc_binding.rb +22 -0
  439. data/ext/enclave/mruby/mrbgems/mruby-proc-ext/README.md +107 -0
  440. data/ext/enclave/mruby/mrbgems/mruby-proc-ext/mrbgem.rake +5 -0
  441. data/ext/enclave/mruby/mrbgems/mruby-proc-ext/mrblib/proc.rb +130 -0
  442. data/ext/enclave/mruby/mrbgems/mruby-proc-ext/src/proc.c +267 -0
  443. data/ext/enclave/mruby/mrbgems/mruby-proc-ext/test/proc.c +62 -0
  444. data/ext/enclave/mruby/mrbgems/mruby-proc-ext/test/proc.rb +130 -0
  445. data/ext/enclave/mruby/mrbgems/mruby-random/README.md +272 -0
  446. data/ext/enclave/mruby/mrbgems/mruby-random/mrbgem.rake +5 -0
  447. data/ext/enclave/mruby/mrbgems/mruby-random/src/random.c +608 -0
  448. data/ext/enclave/mruby/mrbgems/mruby-random/test/random.rb +151 -0
  449. data/ext/enclave/mruby/mrbgems/mruby-range-ext/README.md +93 -0
  450. data/ext/enclave/mruby/mrbgems/mruby-range-ext/mrbgem.rake +5 -0
  451. data/ext/enclave/mruby/mrbgems/mruby-range-ext/mrblib/range.rb +155 -0
  452. data/ext/enclave/mruby/mrbgems/mruby-range-ext/src/range.c +236 -0
  453. data/ext/enclave/mruby/mrbgems/mruby-range-ext/test/range.rb +211 -0
  454. data/ext/enclave/mruby/mrbgems/mruby-rational/README.md +61 -0
  455. data/ext/enclave/mruby/mrbgems/mruby-rational/mrbgem.rake +7 -0
  456. data/ext/enclave/mruby/mrbgems/mruby-rational/mrblib/rational.rb +66 -0
  457. data/ext/enclave/mruby/mrbgems/mruby-rational/src/rational.c +1269 -0
  458. data/ext/enclave/mruby/mrbgems/mruby-rational/test/rational.rb +316 -0
  459. data/ext/enclave/mruby/mrbgems/mruby-set/LICENSE +24 -0
  460. data/ext/enclave/mruby/mrbgems/mruby-set/README.md +260 -0
  461. data/ext/enclave/mruby/mrbgems/mruby-set/mrbgem.rake +9 -0
  462. data/ext/enclave/mruby/mrbgems/mruby-set/mrblib/set.rb +325 -0
  463. data/ext/enclave/mruby/mrbgems/mruby-set/mruby-set.gem +6 -0
  464. data/ext/enclave/mruby/mrbgems/mruby-set/src/set.c +1535 -0
  465. data/ext/enclave/mruby/mrbgems/mruby-set/test/set.rb +764 -0
  466. data/ext/enclave/mruby/mrbgems/mruby-sleep/README.md +29 -0
  467. data/ext/enclave/mruby/mrbgems/mruby-sleep/example/sleep.rb +2 -0
  468. data/ext/enclave/mruby/mrbgems/mruby-sleep/mrbgem.rake +5 -0
  469. data/ext/enclave/mruby/mrbgems/mruby-sleep/src/sleep.c +187 -0
  470. data/ext/enclave/mruby/mrbgems/mruby-sleep/test/sleep_test.rb +29 -0
  471. data/ext/enclave/mruby/mrbgems/mruby-socket/README.md +56 -0
  472. data/ext/enclave/mruby/mrbgems/mruby-socket/include/socket_hal.h +83 -0
  473. data/ext/enclave/mruby/mrbgems/mruby-socket/mrbgem.rake +37 -0
  474. data/ext/enclave/mruby/mrbgems/mruby-socket/mrblib/socket.rb +1131 -0
  475. data/ext/enclave/mruby/mrbgems/mruby-socket/src/const.cstub +480 -0
  476. data/ext/enclave/mruby/mrbgems/mruby-socket/src/const.def +172 -0
  477. data/ext/enclave/mruby/mrbgems/mruby-socket/src/gen.rb +17 -0
  478. data/ext/enclave/mruby/mrbgems/mruby-socket/src/socket.c +1374 -0
  479. data/ext/enclave/mruby/mrbgems/mruby-socket/test/addrinfo.rb +91 -0
  480. data/ext/enclave/mruby/mrbgems/mruby-socket/test/basicsocket.rb +17 -0
  481. data/ext/enclave/mruby/mrbgems/mruby-socket/test/ipsocket.rb +44 -0
  482. data/ext/enclave/mruby/mrbgems/mruby-socket/test/socket.rb +38 -0
  483. data/ext/enclave/mruby/mrbgems/mruby-socket/test/sockettest.c +84 -0
  484. data/ext/enclave/mruby/mrbgems/mruby-socket/test/tcpsocket.rb +4 -0
  485. data/ext/enclave/mruby/mrbgems/mruby-socket/test/udpsocket.rb +16 -0
  486. data/ext/enclave/mruby/mrbgems/mruby-socket/test/unix.rb +130 -0
  487. data/ext/enclave/mruby/mrbgems/mruby-sprintf/README.md +235 -0
  488. data/ext/enclave/mruby/mrbgems/mruby-sprintf/mrbgem.rake +5 -0
  489. data/ext/enclave/mruby/mrbgems/mruby-sprintf/mrblib/string.rb +24 -0
  490. data/ext/enclave/mruby/mrbgems/mruby-sprintf/src/sprintf.c +1195 -0
  491. data/ext/enclave/mruby/mrbgems/mruby-sprintf/test/sprintf.rb +92 -0
  492. data/ext/enclave/mruby/mrbgems/mruby-strftime/README.md +140 -0
  493. data/ext/enclave/mruby/mrbgems/mruby-strftime/mrbgem.rake +7 -0
  494. data/ext/enclave/mruby/mrbgems/mruby-strftime/src/strftime.c +119 -0
  495. data/ext/enclave/mruby/mrbgems/mruby-strftime/test/strftime.rb +152 -0
  496. data/ext/enclave/mruby/mrbgems/mruby-string-ext/README.md +886 -0
  497. data/ext/enclave/mruby/mrbgems/mruby-string-ext/mrbgem.rake +5 -0
  498. data/ext/enclave/mruby/mrbgems/mruby-string-ext/mrblib/string.rb +166 -0
  499. data/ext/enclave/mruby/mrbgems/mruby-string-ext/src/string.c +2290 -0
  500. data/ext/enclave/mruby/mrbgems/mruby-string-ext/test/numeric.rb +27 -0
  501. data/ext/enclave/mruby/mrbgems/mruby-string-ext/test/range.rb +26 -0
  502. data/ext/enclave/mruby/mrbgems/mruby-string-ext/test/string.rb +765 -0
  503. data/ext/enclave/mruby/mrbgems/mruby-struct/README.md +105 -0
  504. data/ext/enclave/mruby/mrbgems/mruby-struct/mrbgem.rake +5 -0
  505. data/ext/enclave/mruby/mrbgems/mruby-struct/mrblib/struct.rb +69 -0
  506. data/ext/enclave/mruby/mrbgems/mruby-struct/src/struct.c +812 -0
  507. data/ext/enclave/mruby/mrbgems/mruby-struct/test/struct.rb +303 -0
  508. data/ext/enclave/mruby/mrbgems/mruby-symbol-ext/README.md +50 -0
  509. data/ext/enclave/mruby/mrbgems/mruby-symbol-ext/mrbgem.rake +5 -0
  510. data/ext/enclave/mruby/mrbgems/mruby-symbol-ext/mrblib/symbol.rb +72 -0
  511. data/ext/enclave/mruby/mrbgems/mruby-symbol-ext/src/symbol.c +79 -0
  512. data/ext/enclave/mruby/mrbgems/mruby-symbol-ext/test/symbol.rb +55 -0
  513. data/ext/enclave/mruby/mrbgems/mruby-task/README.md +770 -0
  514. data/ext/enclave/mruby/mrbgems/mruby-task/examples/inspection.rb +65 -0
  515. data/ext/enclave/mruby/mrbgems/mruby-task/examples/priority.rb +41 -0
  516. data/ext/enclave/mruby/mrbgems/mruby-task/examples/producer_consumer.rb +58 -0
  517. data/ext/enclave/mruby/mrbgems/mruby-task/examples/simple.rb +27 -0
  518. data/ext/enclave/mruby/mrbgems/mruby-task/examples/statistics.rb +59 -0
  519. data/ext/enclave/mruby/mrbgems/mruby-task/examples/suspend_resume.rb +47 -0
  520. data/ext/enclave/mruby/mrbgems/mruby-task/examples/task_pass.rb +21 -0
  521. data/ext/enclave/mruby/mrbgems/mruby-task/include/task.h +143 -0
  522. data/ext/enclave/mruby/mrbgems/mruby-task/include/task_hal.h +162 -0
  523. data/ext/enclave/mruby/mrbgems/mruby-task/mrbgem.rake +36 -0
  524. data/ext/enclave/mruby/mrbgems/mruby-task/src/task.c +1573 -0
  525. data/ext/enclave/mruby/mrbgems/mruby-task/test/task.rb +185 -0
  526. data/ext/enclave/mruby/mrbgems/mruby-test/README.md +7 -0
  527. data/ext/enclave/mruby/mrbgems/mruby-test/driver.c +315 -0
  528. data/ext/enclave/mruby/mrbgems/mruby-test/mrbgem.rake +173 -0
  529. data/ext/enclave/mruby/mrbgems/mruby-test/vformat.c +151 -0
  530. data/ext/enclave/mruby/mrbgems/mruby-test-inline-struct/mrbgem.rake +5 -0
  531. data/ext/enclave/mruby/mrbgems/mruby-test-inline-struct/test/inline.c +92 -0
  532. data/ext/enclave/mruby/mrbgems/mruby-test-inline-struct/test/inline.rb +118 -0
  533. data/ext/enclave/mruby/mrbgems/mruby-time/README.md +102 -0
  534. data/ext/enclave/mruby/mrbgems/mruby-time/include/mruby/time.h +27 -0
  535. data/ext/enclave/mruby/mrbgems/mruby-time/mrbgem.rake +5 -0
  536. data/ext/enclave/mruby/mrbgems/mruby-time/src/time.c +1739 -0
  537. data/ext/enclave/mruby/mrbgems/mruby-time/test/time.rb +313 -0
  538. data/ext/enclave/mruby/mrbgems/mruby-toplevel-ext/README.md +32 -0
  539. data/ext/enclave/mruby/mrbgems/mruby-toplevel-ext/mrbgem.rake +5 -0
  540. data/ext/enclave/mruby/mrbgems/mruby-toplevel-ext/mrblib/toplevel.rb +24 -0
  541. data/ext/enclave/mruby/mrbgems/mruby-toplevel-ext/test/toplevel.rb +23 -0
  542. data/ext/enclave/mruby/mrbgems/stdlib-ext.gembox +21 -0
  543. data/ext/enclave/mruby/mrbgems/stdlib-io.gembox +15 -0
  544. data/ext/enclave/mruby/mrbgems/stdlib.gembox +63 -0
  545. data/ext/enclave/mruby/mrblib/10error.rb +23 -0
  546. data/ext/enclave/mruby/mrblib/array.rb +102 -0
  547. data/ext/enclave/mruby/mrblib/compar.rb +102 -0
  548. data/ext/enclave/mruby/mrblib/enum.rb +358 -0
  549. data/ext/enclave/mruby/mrblib/hash.rb +276 -0
  550. data/ext/enclave/mruby/mrblib/kernel.rb +45 -0
  551. data/ext/enclave/mruby/mrblib/numeric.rb +160 -0
  552. data/ext/enclave/mruby/mrblib/range.rb +98 -0
  553. data/ext/enclave/mruby/mrblib/string.rb +173 -0
  554. data/ext/enclave/mruby/mrblib/symbol.rb +8 -0
  555. data/ext/enclave/mruby/oss-fuzz/mruby_fuzzer.c +18 -0
  556. data/ext/enclave/mruby/oss-fuzz/proto_to_ruby.h +55 -0
  557. data/ext/enclave/mruby/src/allocf.c +37 -0
  558. data/ext/enclave/mruby/src/array.c +2302 -0
  559. data/ext/enclave/mruby/src/backtrace.c +294 -0
  560. data/ext/enclave/mruby/src/cdump.c +498 -0
  561. data/ext/enclave/mruby/src/class.c +4394 -0
  562. data/ext/enclave/mruby/src/codedump.c +693 -0
  563. data/ext/enclave/mruby/src/debug.c +290 -0
  564. data/ext/enclave/mruby/src/dump.c +998 -0
  565. data/ext/enclave/mruby/src/enum.c +30 -0
  566. data/ext/enclave/mruby/src/error.c +937 -0
  567. data/ext/enclave/mruby/src/etc.c +421 -0
  568. data/ext/enclave/mruby/src/fmt_fp.c +372 -0
  569. data/ext/enclave/mruby/src/gc.c +1610 -0
  570. data/ext/enclave/mruby/src/hash.c +2355 -0
  571. data/ext/enclave/mruby/src/init.c +50 -0
  572. data/ext/enclave/mruby/src/kernel.c +718 -0
  573. data/ext/enclave/mruby/src/load.c +760 -0
  574. data/ext/enclave/mruby/src/mempool.c +225 -0
  575. data/ext/enclave/mruby/src/numeric.c +2420 -0
  576. data/ext/enclave/mruby/src/numops.c +112 -0
  577. data/ext/enclave/mruby/src/object.c +883 -0
  578. data/ext/enclave/mruby/src/print.c +136 -0
  579. data/ext/enclave/mruby/src/proc.c +572 -0
  580. data/ext/enclave/mruby/src/range.c +597 -0
  581. data/ext/enclave/mruby/src/readfloat.c +228 -0
  582. data/ext/enclave/mruby/src/readint.c +27 -0
  583. data/ext/enclave/mruby/src/readnum.c +43 -0
  584. data/ext/enclave/mruby/src/state.c +247 -0
  585. data/ext/enclave/mruby/src/string.c +3577 -0
  586. data/ext/enclave/mruby/src/symbol.c +1023 -0
  587. data/ext/enclave/mruby/src/value_array.h +28 -0
  588. data/ext/enclave/mruby/src/variable.c +1475 -0
  589. data/ext/enclave/mruby/src/version.c +17 -0
  590. data/ext/enclave/mruby/src/vm.c +3696 -0
  591. data/ext/enclave/mruby/tasks/amalgam.rake +34 -0
  592. data/ext/enclave/mruby/tasks/benchmark.rake +93 -0
  593. data/ext/enclave/mruby/tasks/bin.rake +23 -0
  594. data/ext/enclave/mruby/tasks/core.rake +12 -0
  595. data/ext/enclave/mruby/tasks/doc.rake +118 -0
  596. data/ext/enclave/mruby/tasks/install.rake +40 -0
  597. data/ext/enclave/mruby/tasks/libmruby.rake +90 -0
  598. data/ext/enclave/mruby/tasks/mrbgems.rake +152 -0
  599. data/ext/enclave/mruby/tasks/mrblib.rake +29 -0
  600. data/ext/enclave/mruby/tasks/presym.rake +57 -0
  601. data/ext/enclave/mruby/tasks/test.rake +84 -0
  602. data/ext/enclave/mruby/tasks/toolchains/android.rake +228 -0
  603. data/ext/enclave/mruby/tasks/toolchains/clang.rake +8 -0
  604. data/ext/enclave/mruby/tasks/toolchains/emscripten.rake +57 -0
  605. data/ext/enclave/mruby/tasks/toolchains/gcc.rake +74 -0
  606. data/ext/enclave/mruby/tasks/toolchains/openwrt.rake +32 -0
  607. data/ext/enclave/mruby/tasks/toolchains/visualcpp.rake +48 -0
  608. data/ext/enclave/mruby/test/assert.rb +404 -0
  609. data/ext/enclave/mruby/test/bintest.rb +55 -0
  610. data/ext/enclave/mruby/test/t/argumenterror.rb +37 -0
  611. data/ext/enclave/mruby/test/t/array.rb +478 -0
  612. data/ext/enclave/mruby/test/t/basicobject.rb +10 -0
  613. data/ext/enclave/mruby/test/t/bs_block.rb +621 -0
  614. data/ext/enclave/mruby/test/t/bs_literal.rb +38 -0
  615. data/ext/enclave/mruby/test/t/class.rb +505 -0
  616. data/ext/enclave/mruby/test/t/codegen.rb +196 -0
  617. data/ext/enclave/mruby/test/t/comparable.rb +79 -0
  618. data/ext/enclave/mruby/test/t/ensure.rb +36 -0
  619. data/ext/enclave/mruby/test/t/enumerable.rb +134 -0
  620. data/ext/enclave/mruby/test/t/exception.rb +425 -0
  621. data/ext/enclave/mruby/test/t/false.rb +31 -0
  622. data/ext/enclave/mruby/test/t/float.rb +296 -0
  623. data/ext/enclave/mruby/test/t/gc.rb +45 -0
  624. data/ext/enclave/mruby/test/t/hash.rb +976 -0
  625. data/ext/enclave/mruby/test/t/indexerror.rb +6 -0
  626. data/ext/enclave/mruby/test/t/integer.rb +247 -0
  627. data/ext/enclave/mruby/test/t/iterations.rb +61 -0
  628. data/ext/enclave/mruby/test/t/kernel.rb +462 -0
  629. data/ext/enclave/mruby/test/t/lang.rb +74 -0
  630. data/ext/enclave/mruby/test/t/literals.rb +386 -0
  631. data/ext/enclave/mruby/test/t/localjumperror.rb +13 -0
  632. data/ext/enclave/mruby/test/t/methods.rb +138 -0
  633. data/ext/enclave/mruby/test/t/module.rb +931 -0
  634. data/ext/enclave/mruby/test/t/nameerror.rb +28 -0
  635. data/ext/enclave/mruby/test/t/nil.rb +39 -0
  636. data/ext/enclave/mruby/test/t/nomethoderror.rb +22 -0
  637. data/ext/enclave/mruby/test/t/numeric.rb +114 -0
  638. data/ext/enclave/mruby/test/t/object.rb +10 -0
  639. data/ext/enclave/mruby/test/t/proc.rb +198 -0
  640. data/ext/enclave/mruby/test/t/range.rb +194 -0
  641. data/ext/enclave/mruby/test/t/rangeerror.rb +6 -0
  642. data/ext/enclave/mruby/test/t/regexperror.rb +4 -0
  643. data/ext/enclave/mruby/test/t/runtimeerror.rb +6 -0
  644. data/ext/enclave/mruby/test/t/standarderror.rb +6 -0
  645. data/ext/enclave/mruby/test/t/string.rb +981 -0
  646. data/ext/enclave/mruby/test/t/superclass.rb +46 -0
  647. data/ext/enclave/mruby/test/t/symbol.rb +30 -0
  648. data/ext/enclave/mruby/test/t/syntax.rb +1296 -0
  649. data/ext/enclave/mruby/test/t/true.rb +31 -0
  650. data/ext/enclave/mruby/test/t/typeerror.rb +6 -0
  651. data/ext/enclave/mruby/test/t/unicode.rb +39 -0
  652. data/ext/enclave/mruby/test/t/vformat.rb +57 -0
  653. data/ext/enclave/mruby/tools/lrama/LEGAL.md +12 -0
  654. data/ext/enclave/mruby/tools/lrama/MIT +21 -0
  655. data/ext/enclave/mruby/tools/lrama/NEWS.md +696 -0
  656. data/ext/enclave/mruby/tools/lrama/exe/lrama +7 -0
  657. data/ext/enclave/mruby/tools/lrama/lib/lrama/bitmap.rb +34 -0
  658. data/ext/enclave/mruby/tools/lrama/lib/lrama/command.rb +68 -0
  659. data/ext/enclave/mruby/tools/lrama/lib/lrama/context.rb +499 -0
  660. data/ext/enclave/mruby/tools/lrama/lib/lrama/counterexamples/derivation.rb +66 -0
  661. data/ext/enclave/mruby/tools/lrama/lib/lrama/counterexamples/example.rb +129 -0
  662. data/ext/enclave/mruby/tools/lrama/lib/lrama/counterexamples/path.rb +29 -0
  663. data/ext/enclave/mruby/tools/lrama/lib/lrama/counterexamples/production_path.rb +19 -0
  664. data/ext/enclave/mruby/tools/lrama/lib/lrama/counterexamples/start_path.rb +23 -0
  665. data/ext/enclave/mruby/tools/lrama/lib/lrama/counterexamples/state_item.rb +8 -0
  666. data/ext/enclave/mruby/tools/lrama/lib/lrama/counterexamples/transition_path.rb +19 -0
  667. data/ext/enclave/mruby/tools/lrama/lib/lrama/counterexamples/triple.rb +23 -0
  668. data/ext/enclave/mruby/tools/lrama/lib/lrama/counterexamples.rb +298 -0
  669. data/ext/enclave/mruby/tools/lrama/lib/lrama/diagnostics.rb +36 -0
  670. data/ext/enclave/mruby/tools/lrama/lib/lrama/digraph.rb +83 -0
  671. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/auxiliary.rb +9 -0
  672. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/binding.rb +67 -0
  673. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/code/destructor_code.rb +42 -0
  674. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/code/initial_action_code.rb +36 -0
  675. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/code/no_reference_code.rb +30 -0
  676. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/code/printer_code.rb +42 -0
  677. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/code/rule_action.rb +92 -0
  678. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/code.rb +53 -0
  679. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/counter.rb +17 -0
  680. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/destructor.rb +11 -0
  681. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/error_token.rb +11 -0
  682. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/parameterizing_rule/resolver.rb +62 -0
  683. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/parameterizing_rule/rhs.rb +40 -0
  684. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/parameterizing_rule/rule.rb +24 -0
  685. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/parameterizing_rule.rb +5 -0
  686. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/percent_code.rb +14 -0
  687. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/precedence.rb +13 -0
  688. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/printer.rb +11 -0
  689. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/reference.rb +16 -0
  690. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/rule.rb +75 -0
  691. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/rule_builder.rb +255 -0
  692. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/stdlib.y +122 -0
  693. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/symbol.rb +105 -0
  694. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/symbols/resolver.rb +301 -0
  695. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/symbols.rb +3 -0
  696. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/type.rb +20 -0
  697. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/union.rb +12 -0
  698. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar.rb +407 -0
  699. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar_validator.rb +37 -0
  700. data/ext/enclave/mruby/tools/lrama/lib/lrama/lexer/grammar_file.rb +40 -0
  701. data/ext/enclave/mruby/tools/lrama/lib/lrama/lexer/location.rb +115 -0
  702. data/ext/enclave/mruby/tools/lrama/lib/lrama/lexer/token/char.rb +11 -0
  703. data/ext/enclave/mruby/tools/lrama/lib/lrama/lexer/token/ident.rb +11 -0
  704. data/ext/enclave/mruby/tools/lrama/lib/lrama/lexer/token/instantiate_rule.rb +30 -0
  705. data/ext/enclave/mruby/tools/lrama/lib/lrama/lexer/token/tag.rb +16 -0
  706. data/ext/enclave/mruby/tools/lrama/lib/lrama/lexer/token/user_code.rb +83 -0
  707. data/ext/enclave/mruby/tools/lrama/lib/lrama/lexer/token.rb +70 -0
  708. data/ext/enclave/mruby/tools/lrama/lib/lrama/lexer.rb +191 -0
  709. data/ext/enclave/mruby/tools/lrama/lib/lrama/logger.rb +21 -0
  710. data/ext/enclave/mruby/tools/lrama/lib/lrama/option_parser.rb +169 -0
  711. data/ext/enclave/mruby/tools/lrama/lib/lrama/options.rb +28 -0
  712. data/ext/enclave/mruby/tools/lrama/lib/lrama/output.rb +459 -0
  713. data/ext/enclave/mruby/tools/lrama/lib/lrama/parser.rb +2144 -0
  714. data/ext/enclave/mruby/tools/lrama/lib/lrama/report/duration.rb +27 -0
  715. data/ext/enclave/mruby/tools/lrama/lib/lrama/report/profile.rb +16 -0
  716. data/ext/enclave/mruby/tools/lrama/lib/lrama/report.rb +4 -0
  717. data/ext/enclave/mruby/tools/lrama/lib/lrama/state/reduce.rb +37 -0
  718. data/ext/enclave/mruby/tools/lrama/lib/lrama/state/reduce_reduce_conflict.rb +11 -0
  719. data/ext/enclave/mruby/tools/lrama/lib/lrama/state/resolved_conflict.rb +31 -0
  720. data/ext/enclave/mruby/tools/lrama/lib/lrama/state/shift.rb +15 -0
  721. data/ext/enclave/mruby/tools/lrama/lib/lrama/state/shift_reduce_conflict.rb +11 -0
  722. data/ext/enclave/mruby/tools/lrama/lib/lrama/state.rb +433 -0
  723. data/ext/enclave/mruby/tools/lrama/lib/lrama/states/item.rb +91 -0
  724. data/ext/enclave/mruby/tools/lrama/lib/lrama/states.rb +595 -0
  725. data/ext/enclave/mruby/tools/lrama/lib/lrama/states_reporter.rb +362 -0
  726. data/ext/enclave/mruby/tools/lrama/lib/lrama/trace_reporter.rb +45 -0
  727. data/ext/enclave/mruby/tools/lrama/lib/lrama/version.rb +5 -0
  728. data/ext/enclave/mruby/tools/lrama/lib/lrama.rb +22 -0
  729. data/ext/enclave/mruby/tools/lrama/template/bison/_yacc.h +71 -0
  730. data/ext/enclave/mruby/tools/lrama/template/bison/yacc.c +2068 -0
  731. data/ext/enclave/mruby/tools/lrama/template/bison/yacc.h +40 -0
  732. data/ext/enclave/sandbox_build_config.rb +15 -0
  733. data/ext/enclave/sandbox_core.c +722 -0
  734. data/ext/enclave/sandbox_core.h +87 -0
  735. data/lib/enclave/result.rb +29 -0
  736. data/lib/enclave/tool.rb +38 -0
  737. data/lib/enclave/version.rb +3 -0
  738. data/lib/enclave.rb +73 -0
  739. metadata +819 -0
@@ -0,0 +1,1573 @@
1
+ /*
2
+ ** task.c - Task scheduler
3
+ **
4
+ ** See Copyright Notice in mruby.h
5
+ */
6
+
7
+ #include <mruby.h>
8
+ #include <mruby/array.h>
9
+ #include <mruby/class.h>
10
+ #include <mruby/data.h>
11
+ #include <mruby/error.h>
12
+ #include <mruby/gc.h>
13
+ #include <mruby/hash.h>
14
+ #include <mruby/internal.h>
15
+ #include <mruby/presym.h>
16
+ #include <mruby/proc.h>
17
+ #include <mruby/string.h>
18
+ #include <mruby/variable.h>
19
+ #include <string.h>
20
+ #include <stdint.h>
21
+ #include <stdlib.h>
22
+ #include "task.h"
23
+ #include "task_hal.h"
24
+
25
+ /*
26
+ * Queue helper macros
27
+ */
28
+ #define q_dormant_ (mrb->task.queues[MRB_TASK_QUEUE_DORMANT])
29
+ #define q_ready_ (mrb->task.queues[MRB_TASK_QUEUE_READY])
30
+ #define q_waiting_ (mrb->task.queues[MRB_TASK_QUEUE_WAITING])
31
+ #define q_suspended_ (mrb->task.queues[MRB_TASK_QUEUE_SUSPENDED])
32
+ #define tick_ (mrb->task.tick)
33
+ #define wakeup_tick_ (mrb->task.wakeup_tick)
34
+ #define switching_ (mrb->task.switching)
35
+
36
+ /* Get task from current context using pointer arithmetic */
37
+ #define MRB2TASK(mrb) ((mrb_task *)((uint8_t *)mrb->c - offsetof(mrb_task, c)))
38
+
39
+ /* Get task pointer from self with validation */
40
+ #define TASK_GET_PTR_OR_RAISE(var, self) \
41
+ do { \
42
+ (var) = (mrb_task*)mrb_data_get_ptr(mrb, (self), &mrb_task_type); \
43
+ if (!(var)) { \
44
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid task"); \
45
+ } \
46
+ } while (0)
47
+
48
+ /* Convert microseconds to tick count */
49
+ #define USEC_TO_TICKS(usec) (((usec) / 1000) / MRB_TICK_UNIT)
50
+
51
+ /* Maximum value for scheduler_lock (uint8_t max) */
52
+ #define MRB_TASK_SCHEDULER_LOCK_MAX 255
53
+
54
+ /* Check scheduler lock and raise error if locked */
55
+ static inline void
56
+ task_check_scheduler_lock(mrb_state *mrb)
57
+ {
58
+ if (mrb->task.scheduler_lock > 0) {
59
+ mrb_raise(mrb, E_RUNTIME_ERROR, "Cannot use asynchronous Task API during synchronous execution");
60
+ }
61
+ }
62
+
63
+ /*
64
+ * Task data type for GC
65
+ */
66
+ static void
67
+ mrb_task_free(mrb_state *mrb, void *ptr)
68
+ {
69
+ mrb_task *t = (mrb_task*)ptr;
70
+ if (t) {
71
+ /* Unregister from GC protection (unless it's the main task during shutdown) */
72
+ if (t != mrb->task.main_task) {
73
+ mrb_gc_unregister(mrb, t->self);
74
+ }
75
+
76
+ /* Free context resources - always free if allocated */
77
+ /* Main task never has allocated context (stbase/cibase are NULL) */
78
+ if (t->c.stbase) {
79
+ mrb_free(mrb, t->c.stbase);
80
+ }
81
+ if (t->c.cibase) {
82
+ mrb_free(mrb, t->c.cibase);
83
+ }
84
+
85
+ /* Free the task structure itself */
86
+ mrb_free(mrb, t);
87
+ }
88
+ }
89
+
90
+ static const struct mrb_data_type mrb_task_type = {
91
+ "Task", mrb_task_free,
92
+ };
93
+
94
+ /*
95
+ * GC marking function for all tasks
96
+ * Called from gc.c during root_scan_phase
97
+ */
98
+ void
99
+ mrb_task_mark_all(mrb_state *mrb)
100
+ {
101
+ int qi;
102
+ for (qi = 0; qi < 4; qi++) {
103
+ mrb_task *t = mrb->task.queues[qi];
104
+ while (t) {
105
+ struct mrb_context *c = &t->c;
106
+ mrb_callinfo *ci;
107
+ size_t i, e;
108
+
109
+ /* Mark task's stack */
110
+ if (c->stbase) {
111
+ if (c->ci) {
112
+ e = (c->ci->stack ? c->ci->stack - c->stbase : 0);
113
+ e += mrb_ci_nregs(c->ci);
114
+ }
115
+ else {
116
+ e = 0;
117
+ }
118
+ if (c->stbase + e > c->stend) e = c->stend - c->stbase;
119
+ for (i = 0; i < e; i++) {
120
+ mrb_gc_mark_value(mrb, c->stbase[i]);
121
+ }
122
+ }
123
+
124
+ /* Mark call stack */
125
+ if (c->cibase && c->ci) {
126
+ for (ci = c->cibase; ci <= c->ci; ci++) {
127
+ if (ci->proc) {
128
+ mrb_gc_mark(mrb, (struct RBasic*)ci->proc);
129
+ }
130
+ if (ci->u.target_class) {
131
+ mrb_gc_mark(mrb, (struct RBasic*)ci->u.target_class);
132
+ }
133
+ }
134
+ }
135
+
136
+ /* Mark fiber */
137
+ mrb_gc_mark(mrb, (struct RBasic*)c->fib);
138
+
139
+ /* Mark task-specific values */
140
+ mrb_gc_mark_value(mrb, t->self);
141
+ if (t->status == MRB_TASK_STATUS_DORMANT) {
142
+ mrb_gc_mark_value(mrb, t->state.result);
143
+ }
144
+ mrb_gc_mark_value(mrb, t->name);
145
+
146
+ t = t->next;
147
+ }
148
+ }
149
+ }
150
+
151
+ /*
152
+ * Queue operations
153
+ */
154
+
155
+ /* Get queue head pointer based on task status */
156
+ static mrb_task**
157
+ q_get_queue(mrb_state *mrb, mrb_task *t)
158
+ {
159
+ switch (t->status) {
160
+ case MRB_TASK_STATUS_DORMANT:
161
+ return &q_dormant_;
162
+ case MRB_TASK_STATUS_READY:
163
+ case MRB_TASK_STATUS_RUNNING:
164
+ return &q_ready_;
165
+ case MRB_TASK_STATUS_WAITING:
166
+ return &q_waiting_;
167
+ case MRB_TASK_STATUS_SUSPENDED:
168
+ return &q_suspended_;
169
+ default:
170
+ return &q_dormant_;
171
+ }
172
+ }
173
+
174
+ /* Insert task into queue based on priority (higher priority = lower number = earlier in queue) */
175
+ static void
176
+ q_insert_task(mrb_state *mrb, mrb_task *t)
177
+ {
178
+ mrb_task **q = q_get_queue(mrb, t);
179
+ mrb_task *curr = *q;
180
+ mrb_task *prev = NULL;
181
+
182
+ /* Find insertion point - insert before first task with lower priority */
183
+ while (curr != NULL && curr->priority <= t->priority) {
184
+ prev = curr;
185
+ curr = curr->next;
186
+ }
187
+
188
+ /* Insert task */
189
+ t->next = curr;
190
+ if (prev == NULL) {
191
+ *q = t; /* Insert at head */
192
+ }
193
+ else {
194
+ prev->next = t; /* Insert after prev */
195
+ }
196
+ }
197
+
198
+ /* Delete task from its current queue */
199
+ static void
200
+ q_delete_task(mrb_state *mrb, mrb_task *t)
201
+ {
202
+ mrb_task **q = q_get_queue(mrb, t);
203
+ mrb_task *curr = *q;
204
+ mrb_task *prev = NULL;
205
+
206
+ /* Find and remove task */
207
+ while (curr != NULL) {
208
+ if (curr == t) {
209
+ if (prev == NULL) {
210
+ *q = curr->next; /* Remove from head */
211
+ }
212
+ else {
213
+ prev->next = curr->next; /* Remove from middle/end */
214
+ }
215
+ t->next = NULL;
216
+ return;
217
+ }
218
+ prev = curr;
219
+ curr = curr->next;
220
+ }
221
+ }
222
+
223
+ /* Cleanup terminated task and move to dormant queue if needed */
224
+ static inline mrb_bool
225
+ task_cleanup_if_stopped(mrb_state *mrb, mrb_task *t)
226
+ {
227
+ if (t->status == MRB_TASK_STATUS_DORMANT || t->c.status == MRB_TASK_STOPPED) {
228
+ /* Task is terminated but still in queue - remove it */
229
+ mrb_task_disable_irq();
230
+ q_delete_task(mrb, t);
231
+ if (t->status != MRB_TASK_STATUS_DORMANT) {
232
+ t->status = MRB_TASK_STATUS_DORMANT;
233
+ q_insert_task(mrb, t);
234
+ }
235
+ mrb_task_enable_irq();
236
+ return TRUE;
237
+ }
238
+ return FALSE;
239
+ }
240
+
241
+ /*
242
+ * Task lifecycle
243
+ */
244
+
245
+ /* Allocate new task */
246
+ static mrb_task*
247
+ task_alloc(mrb_state *mrb)
248
+ {
249
+ mrb_task *t = (mrb_task*)mrb_malloc(mrb, sizeof(mrb_task));
250
+ memset(t, 0, sizeof(mrb_task));
251
+ return t;
252
+ }
253
+
254
+ /* Initialize task context (stack and callinfo) - similar to Fiber */
255
+ static void
256
+ task_init_context(mrb_state *mrb, mrb_task *t, const struct RProc *proc)
257
+ {
258
+ static const struct mrb_context mrb_context_zero = { 0 };
259
+ struct mrb_context *c = &t->c;
260
+
261
+ *c = mrb_context_zero;
262
+
263
+ /* Initialize VM stack */
264
+ size_t slen = TASK_STACK_INIT_SIZE;
265
+ if (proc->body.irep->nregs > slen) {
266
+ slen += proc->body.irep->nregs;
267
+ }
268
+ c->stbase = (mrb_value*)mrb_malloc(mrb, slen * sizeof(mrb_value));
269
+ c->stend = c->stbase + slen;
270
+
271
+ /* Initialize stack values to nil */
272
+ {
273
+ mrb_value *s = c->stbase + 1;
274
+ mrb_value *send = c->stend;
275
+ while (s < send) {
276
+ SET_NIL_VALUE(*s);
277
+ s++;
278
+ }
279
+ }
280
+
281
+ /* Set receiver to top self */
282
+ c->stbase[0] = mrb_top_self(mrb);
283
+
284
+ /* Initialize callinfo stack */
285
+ static const mrb_callinfo ci_zero = { 0 };
286
+ c->cibase = (mrb_callinfo*)mrb_malloc(mrb, TASK_CI_INIT_SIZE * sizeof(mrb_callinfo));
287
+ c->ciend = c->cibase + TASK_CI_INIT_SIZE;
288
+ c->ci = c->cibase;
289
+ c->cibase[0] = ci_zero;
290
+
291
+ /* Setup callinfo */
292
+ mrb_callinfo *ci = c->ci;
293
+ mrb_vm_ci_target_class_set(ci, MRB_PROC_TARGET_CLASS(proc));
294
+ mrb_vm_ci_proc_set(ci, proc);
295
+ ci->stack = c->stbase;
296
+ ci->pc = proc->body.irep->iseq; /* Initialize PC to start of bytecode */
297
+
298
+ c->status = MRB_TASK_CREATED;
299
+ }
300
+
301
+ /*
302
+ * Scheduler core
303
+ */
304
+
305
+ /* Wake up tasks waiting on join for a completed task */
306
+ static void
307
+ wake_up_join_waiters(mrb_state *mrb, mrb_task *completed_task)
308
+ {
309
+ mrb_task *curr = q_waiting_;
310
+ while (curr != NULL) {
311
+ mrb_task *next = curr->next;
312
+ if (curr->reason == MRB_TASK_REASON_JOIN && curr->wait.join == completed_task) {
313
+ mrb_task_disable_irq();
314
+ q_delete_task(mrb, curr);
315
+ curr->status = MRB_TASK_STATUS_READY;
316
+ curr->reason = MRB_TASK_REASON_NONE;
317
+ curr->wait.join = NULL;
318
+ q_insert_task(mrb, curr);
319
+ mrb_task_enable_irq();
320
+ }
321
+ curr = next;
322
+ }
323
+ }
324
+
325
+ /* Change task state with IRQ protection and queue management */
326
+ static void
327
+ task_change_state(mrb_state *mrb, mrb_task *t, uint8_t new_status)
328
+ {
329
+ mrb_task_disable_irq();
330
+ q_delete_task(mrb, t);
331
+ t->status = new_status;
332
+ q_insert_task(mrb, t);
333
+ mrb_task_enable_irq();
334
+ }
335
+
336
+ /* Execute a single task - core task execution logic */
337
+ static void
338
+ execute_task(mrb_state *mrb, mrb_task *t)
339
+ {
340
+ struct mrb_context *prev_c;
341
+ mrb_callinfo *prev_ci;
342
+ uint8_t prev_cci;
343
+
344
+ /* Set task as running */
345
+ t->status = MRB_TASK_STATUS_RUNNING;
346
+ t->state.timeslice = MRB_TIMESLICE_TICK_COUNT;
347
+
348
+ /* Switch to task context */
349
+ prev_c = mrb->c;
350
+ prev_ci = prev_c->ci;
351
+ prev_cci = prev_c->ci->cci;
352
+ t->c.prev = mrb->c;
353
+ mrb->c = &t->c;
354
+
355
+ /* Clear switching flag */
356
+ switching_ = FALSE;
357
+
358
+ /* Save proc and PC to locals before calling mrb_vm_exec */
359
+ const struct RProc *proc = t->c.ci->proc;
360
+ const mrb_code *pc = t->c.ci->pc;
361
+
362
+ /* With C function boundary checks, proc should never be NULL on resume */
363
+ if (!proc) {
364
+ mrb_raise(mrb, E_RUNTIME_ERROR, "task context corrupted: no proc on resume");
365
+ }
366
+
367
+ /* Set vmexec flag to prevent fiber_terminate from being called */
368
+ t->c.vmexec = TRUE;
369
+
370
+ /* Execute task - PC is saved in ci->pc from previous run */
371
+ t->state.result = mrb_vm_exec(mrb, proc, pc);
372
+
373
+ /* Clear vmexec flag */
374
+ t->c.vmexec = FALSE;
375
+
376
+ /* Clear switching flag */
377
+ switching_ = FALSE;
378
+
379
+ /* Restore context */
380
+ mrb->c = prev_c;
381
+ t->c.prev = NULL;
382
+ prev_c->ci = prev_ci;
383
+ prev_ci->cci = prev_cci;
384
+
385
+ /* Handle task termination */
386
+ if (t->c.status == MRB_TASK_STOPPED) {
387
+ switching_ = FALSE;
388
+ mrb_task_disable_irq();
389
+ q_delete_task(mrb, t);
390
+ t->status = MRB_TASK_STATUS_DORMANT;
391
+ q_insert_task(mrb, t);
392
+ mrb_task_enable_irq();
393
+
394
+ /* Wake up tasks waiting on join */
395
+ wake_up_join_waiters(mrb, t);
396
+ }
397
+ else if (t->status == MRB_TASK_STATUS_RUNNING) {
398
+ /* Task yielded but still running - move to ready queue */
399
+ t->status = MRB_TASK_STATUS_READY;
400
+ }
401
+ }
402
+
403
+ /* Tick handler - called by timer interrupt */
404
+ MRB_API void
405
+ mrb_tick(mrb_state *mrb)
406
+ {
407
+ mrb_task *t;
408
+
409
+ /* Increment global tick counter */
410
+ tick_++;
411
+
412
+ /* Decrease timeslice for running task */
413
+ t = q_ready_;
414
+ if (t && t->status == MRB_TASK_STATUS_RUNNING && t->state.timeslice > 0) {
415
+ t->state.timeslice--;
416
+ if (t->state.timeslice == 0) {
417
+ switching_ = TRUE; /* Trigger context switch */
418
+ }
419
+ }
420
+
421
+ /* Wake up sleeping tasks whose wakeup time has passed */
422
+ if ((int32_t)(wakeup_tick_ - tick_) <= 0) {
423
+ mrb_task *curr = q_waiting_;
424
+ mrb_task *next;
425
+ uint32_t next_wakeup = UINT32_MAX;
426
+
427
+ while (curr != NULL) {
428
+ next = curr->next;
429
+
430
+ if (curr->reason == MRB_TASK_REASON_SLEEP) {
431
+ if ((int32_t)(curr->wait.wakeup_tick - tick_) <= 0) {
432
+ /* Time to wake up */
433
+ q_delete_task(mrb, curr);
434
+ curr->status = MRB_TASK_STATUS_READY;
435
+ curr->reason = MRB_TASK_REASON_NONE;
436
+ q_insert_task(mrb, curr);
437
+ switching_ = TRUE;
438
+ }
439
+ else if (curr->wait.wakeup_tick < next_wakeup) {
440
+ next_wakeup = curr->wait.wakeup_tick;
441
+ }
442
+ }
443
+
444
+ curr = next;
445
+ }
446
+
447
+ wakeup_tick_ = next_wakeup;
448
+ }
449
+ }
450
+
451
+ /* Main scheduler loop */
452
+ MRB_API mrb_value
453
+ mrb_task_run(mrb_state *mrb)
454
+ {
455
+ mrb_task *t;
456
+
457
+ while (1) {
458
+ t = q_ready_;
459
+
460
+ /* No task ready - check if all tasks are done */
461
+ if (!t) {
462
+ mrb_task_disable_irq();
463
+ mrb_bool exiting = !q_ready_ && !q_waiting_ && !q_suspended_;
464
+ mrb_task_enable_irq();
465
+ if (exiting) {
466
+ /* All tasks are dormant - scheduler done */
467
+ break;
468
+ }
469
+ /* If there are tasks waiting or suspended, idle */
470
+ mrb_hal_task_idle_cpu(mrb);
471
+ continue;
472
+ }
473
+
474
+ /* Safety check - don't execute terminated tasks */
475
+ if (task_cleanup_if_stopped(mrb, t)) {
476
+ continue;
477
+ }
478
+
479
+ /* Execute task using core logic */
480
+ execute_task(mrb, t);
481
+
482
+ /* Move to end of ready queue if still running (round-robin) */
483
+ if (t->status == MRB_TASK_STATUS_READY) {
484
+ task_change_state(mrb, t, MRB_TASK_STATUS_READY);
485
+ }
486
+
487
+ /* Run incremental GC if active */
488
+ if (mrb->gc.state != MRB_GC_STATE_ROOT) {
489
+ mrb_incremental_gc(mrb);
490
+ }
491
+ }
492
+
493
+ return mrb_nil_value();
494
+ }
495
+
496
+ /* Single-step task execution for WASM event loop integration */
497
+ MRB_API mrb_value
498
+ mrb_task_run_once(mrb_state *mrb)
499
+ {
500
+ mrb_task *t = q_ready_;
501
+
502
+ /* No task ready */
503
+ if (!t) {
504
+ return mrb_nil_value();
505
+ }
506
+
507
+ /* Safety check - don't execute terminated tasks */
508
+ if (task_cleanup_if_stopped(mrb, t)) {
509
+ return mrb_true_value();
510
+ }
511
+
512
+ /* Execute task using core logic */
513
+ execute_task(mrb, t);
514
+
515
+ /* Move to end of ready queue if still ready (round-robin) */
516
+ if (t->status == MRB_TASK_STATUS_READY) {
517
+ task_change_state(mrb, t, MRB_TASK_STATUS_READY);
518
+ }
519
+
520
+ /* Run incremental GC if active */
521
+ if (mrb->gc.state != MRB_GC_STATE_ROOT) {
522
+ mrb_incremental_gc(mrb);
523
+ }
524
+
525
+ return mrb_true_value();
526
+ }
527
+
528
+ /*
529
+ * Sleep operations
530
+ */
531
+
532
+ static void
533
+ sleep_us_impl(mrb_state *mrb, uint32_t usec)
534
+ {
535
+ mrb_task *t;
536
+
537
+ /* Check if we're in a task context */
538
+ if (mrb->c == mrb->root_c) {
539
+ /* Not in task context - sleep in real wall-clock time using HAL */
540
+ mrb_hal_task_sleep_us(mrb, usec);
541
+ /* Clear switching flag - we're in root context, not switching to a task */
542
+ switching_ = FALSE;
543
+ return;
544
+ }
545
+
546
+ /* Check for C function boundary - cannot do cooperative context switch */
547
+ mrb_callinfo *ci;
548
+ for (ci = mrb->c->ci; ci >= mrb->c->cibase; ci--) {
549
+ if (ci->cci > 0) {
550
+ /* Inside C function - fall back to blocking sleep without context switch */
551
+ mrb_hal_task_sleep_us(mrb, usec);
552
+ switching_ = FALSE;
553
+ return;
554
+ }
555
+ }
556
+
557
+ /* In task context - get current running task */
558
+ t = MRB2TASK(mrb);
559
+
560
+ mrb_task_disable_irq();
561
+
562
+ /* Remove from ready queue */
563
+ q_delete_task(mrb, t);
564
+
565
+ /* Move to waiting queue */
566
+ t->status = MRB_TASK_STATUS_WAITING;
567
+ t->reason = MRB_TASK_REASON_SLEEP;
568
+ /* Convert microseconds to ticks (tick unit is in milliseconds) */
569
+ t->wait.wakeup_tick = tick_ + USEC_TO_TICKS(usec);
570
+
571
+ /* Update next wakeup time if this task wakes earlier */
572
+ if ((int32_t)(t->wait.wakeup_tick - wakeup_tick_) < 0) {
573
+ wakeup_tick_ = t->wait.wakeup_tick;
574
+ }
575
+
576
+ q_insert_task(mrb, t);
577
+
578
+ mrb_task_enable_irq();
579
+
580
+ /* Trigger context switch */
581
+ switching_ = TRUE;
582
+ }
583
+
584
+ static void
585
+ sleep_ms_impl(mrb_state *mrb, uint32_t ms)
586
+ {
587
+ sleep_us_impl(mrb, ms * 1000);
588
+ }
589
+
590
+ static mrb_value
591
+ mrb_f_sleep(mrb_state *mrb, mrb_value self)
592
+ {
593
+ mrb_float sec = 0;
594
+ mrb_int n = mrb_get_args(mrb, "|f", &sec);
595
+
596
+ if (n == 0) {
597
+ /* No argument - suspend indefinitely */
598
+ mrb_task *t = q_ready_;
599
+ if (t) {
600
+ mrb_task_disable_irq();
601
+ q_delete_task(mrb, t);
602
+ t->status = MRB_TASK_STATUS_SUSPENDED;
603
+ q_insert_task(mrb, t);
604
+ mrb_task_enable_irq();
605
+ switching_ = TRUE;
606
+ }
607
+ return mrb_nil_value();
608
+ }
609
+
610
+ if (sec < 0) {
611
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "time interval must be positive");
612
+ }
613
+
614
+ mrb_int ms = (mrb_int)(sec * 1000);
615
+ sleep_ms_impl(mrb, (uint32_t)ms);
616
+
617
+ return mrb_fixnum_value((mrb_int)sec);
618
+ }
619
+
620
+ static mrb_value
621
+ mrb_f_sleep_ms(mrb_state *mrb, mrb_value self)
622
+ {
623
+ mrb_int ms;
624
+
625
+ mrb_get_args(mrb, "i", &ms);
626
+
627
+ if (ms < 0) {
628
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "time interval must be positive");
629
+ }
630
+
631
+ sleep_ms_impl(mrb, (uint32_t)ms);
632
+
633
+ return mrb_nil_value();
634
+ }
635
+
636
+ static mrb_value
637
+ mrb_f_usleep(mrb_state *mrb, mrb_value self)
638
+ {
639
+ mrb_int usec;
640
+
641
+ mrb_get_args(mrb, "i", &usec);
642
+
643
+ if (usec < 0) {
644
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "time interval must be positive");
645
+ }
646
+
647
+ sleep_us_impl(mrb, (uint32_t)usec);
648
+
649
+ return mrb_fixnum_value(usec);
650
+ }
651
+
652
+ /*
653
+ * Task class methods
654
+ */
655
+
656
+ static mrb_value
657
+ mrb_task_s_new(mrb_state *mrb, mrb_value self)
658
+ {
659
+ mrb_value blk;
660
+ mrb_value name_val = mrb_nil_value();
661
+ mrb_int priority = 128; /* Default middle priority */
662
+ mrb_value kw_values[2] = {mrb_undef_value(), mrb_undef_value()};
663
+ mrb_sym kw_names[2] = {MRB_SYM(name), MRB_SYM(priority)};
664
+ const mrb_kwargs kwargs = {
665
+ 2, 0, kw_names, kw_values, NULL
666
+ };
667
+
668
+ /* Get block and optional keyword arguments */
669
+ mrb_get_args(mrb, "&:", &blk, &kwargs);
670
+
671
+ if (mrb_nil_p(blk)) {
672
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "tried to create task without a block");
673
+ }
674
+
675
+ const struct RProc *proc = mrb_proc_ptr(blk);
676
+
677
+ /* Parse keyword arguments */
678
+ if (!mrb_undef_p(kw_values[0])) {
679
+ /* Validate name type - must be String */
680
+ if (!mrb_string_p(kw_values[0])) {
681
+ mrb_raise(mrb, E_TYPE_ERROR, "name must be a String");
682
+ }
683
+ name_val = kw_values[0];
684
+ }
685
+ if (!mrb_undef_p(kw_values[1])) {
686
+ /* Validate priority type - must be Integer */
687
+ if (!mrb_integer_p(kw_values[1])) {
688
+ mrb_raise(mrb, E_TYPE_ERROR, "priority must be an Integer");
689
+ }
690
+ priority = mrb_integer(kw_values[1]);
691
+ if (priority < 0 || priority > 255) {
692
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "priority must be 0-255");
693
+ }
694
+ }
695
+
696
+ /* Allocate and initialize task */
697
+ mrb_task *t = task_alloc(mrb);
698
+ t->priority = (uint8_t)priority;
699
+ t->status = MRB_TASK_STATUS_READY;
700
+ t->reason = MRB_TASK_REASON_NONE;
701
+ t->name = name_val;
702
+ /* Note: proc is stored in t->c.ci->proc and marked via callinfo GC */
703
+
704
+ /* Create Ruby object to hold task */
705
+ mrb_value task_obj = mrb_obj_value(mrb_data_object_alloc(mrb, mrb_class_get_id(mrb, MRB_SYM(Task)),
706
+ t, &mrb_task_type));
707
+ t->self = task_obj;
708
+
709
+ /* Register with GC to protect task object from collection */
710
+ mrb_gc_register(mrb, task_obj);
711
+
712
+ /* Initialize task context */
713
+ task_init_context(mrb, t, proc);
714
+
715
+ /* Insert into ready queue */
716
+ mrb_task_disable_irq();
717
+ q_insert_task(mrb, t);
718
+ mrb_task_enable_irq();
719
+
720
+ /* Trigger context switch if this task has higher priority than current */
721
+ if (q_ready_ && q_ready_->status == MRB_TASK_STATUS_RUNNING) {
722
+ if (t->priority < q_ready_->priority) {
723
+ switching_ = TRUE;
724
+ }
725
+ }
726
+
727
+ return task_obj;
728
+ }
729
+
730
+ static mrb_value
731
+ mrb_task_s_current(mrb_state *mrb, mrb_value self)
732
+ {
733
+ /* Check if we're in root context */
734
+ if (mrb->c == mrb->root_c) {
735
+ /* Return main task wrapper (lazy-allocate if needed) */
736
+ if (!mrb->task.main_task) {
737
+ struct RClass *task_class = mrb_class_ptr(self);
738
+ struct RData *data = mrb_data_object_alloc(mrb, task_class, NULL, &mrb_task_type);
739
+ mrb_task *t = (mrb_task*)mrb_calloc(mrb, 1, sizeof(mrb_task));
740
+
741
+ /* Initialize as main task - special status that's never scheduled */
742
+ t->priority = 0;
743
+ t->status = MRB_TASK_STATUS_RUNNING; /* Always running */
744
+ t->name = mrb_str_new_cstr(mrb, "main");
745
+ t->self = mrb_obj_value(data);
746
+ data->data = t;
747
+ data->type = &mrb_task_type;
748
+
749
+ /* Register for GC protection */
750
+ mrb_gc_register(mrb, t->self);
751
+
752
+ /* Note: t->c is not used - root context is in mrb->root_c */
753
+ mrb->task.main_task = t;
754
+ }
755
+ return mrb->task.main_task->self;
756
+ }
757
+
758
+ /* Use pointer arithmetic to get task from context - O(1) */
759
+ mrb_task *t = MRB2TASK(mrb);
760
+ return t->self;
761
+ }
762
+
763
+ static mrb_value
764
+ mrb_task_s_list(mrb_state *mrb, mrb_value self)
765
+ {
766
+ mrb_value ary = mrb_ary_new(mrb);
767
+
768
+ /* Iterate all queues and collect tasks */
769
+ for (int i = 0; i < MRB_NUM_TASK_QUEUE; i++) {
770
+ mrb_task *t = mrb->task.queues[i];
771
+ while (t != NULL) {
772
+ mrb_ary_push(mrb, ary, t->self);
773
+ t = t->next;
774
+ }
775
+ }
776
+
777
+ return ary;
778
+ }
779
+
780
+ /*
781
+ * Run one task iteration - helper for Task.pass from root context
782
+ * Waits for ready tasks if needed (cooperative yielding)
783
+ */
784
+ static void
785
+ task_run_one_iteration(mrb_state *mrb)
786
+ {
787
+ mrb_task *t = q_ready_;
788
+
789
+ /* No ready task - just return (sleep from root provides delays) */
790
+ if (!t) {
791
+ return;
792
+ }
793
+
794
+ /* Skip terminated tasks */
795
+ if (task_cleanup_if_stopped(mrb, t)) {
796
+ return;
797
+ }
798
+
799
+ /* Execute ready task */
800
+ execute_task(mrb, t);
801
+ }
802
+
803
+ static mrb_value
804
+ mrb_task_s_pass(mrb_state *mrb, mrb_value self)
805
+ {
806
+ if (mrb->c == mrb->root_c) {
807
+ /* Called from root context - run one task iteration */
808
+ task_run_one_iteration(mrb);
809
+ }
810
+ else {
811
+ /* Check for C function boundary - cannot yield from C function */
812
+ mrb_callinfo *ci;
813
+ for (ci = mrb->c->ci; ci >= mrb->c->cibase; ci--) {
814
+ if (ci->cci > 0) {
815
+ mrb_raise(mrb, E_RUNTIME_ERROR, "can't pass across C function boundary");
816
+ }
817
+ }
818
+
819
+ /* In task context - trigger context switch */
820
+ switching_ = TRUE;
821
+ }
822
+
823
+ return mrb_nil_value();
824
+ }
825
+
826
+ /* Helper to build statistics for a task queue */
827
+ static mrb_value
828
+ mrb_stat_sub(mrb_state *mrb, mrb_task *queue)
829
+ {
830
+ mrb_value stat = mrb_hash_new(mrb);
831
+ mrb_value tasks = mrb_ary_new(mrb);
832
+ mrb_task *curr = queue;
833
+ int count = 0;
834
+
835
+ /* Walk the queue and collect task objects */
836
+ while (curr) {
837
+ count++;
838
+ mrb_ary_push(mrb, tasks, curr->self);
839
+ curr = curr->next;
840
+ }
841
+
842
+ /* Build statistics hash */
843
+ mrb_hash_set(mrb, stat, mrb_symbol_value(MRB_SYM(count)), mrb_fixnum_value(count));
844
+ mrb_hash_set(mrb, stat, mrb_symbol_value(MRB_SYM(tasks)), tasks);
845
+
846
+ return stat;
847
+ }
848
+
849
+ static mrb_value
850
+ mrb_task_s_stat(mrb_state *mrb, mrb_value self)
851
+ {
852
+ mrb_value data = mrb_hash_new(mrb);
853
+
854
+ mrb_task_disable_irq();
855
+
856
+ /* Add global scheduler state */
857
+ mrb_hash_set(mrb, data, mrb_symbol_value(MRB_SYM(tick)), mrb_fixnum_value(tick_));
858
+ mrb_hash_set(mrb, data, mrb_symbol_value(MRB_SYM(wakeup_tick)), mrb_fixnum_value(wakeup_tick_));
859
+
860
+ /* Add statistics for each queue */
861
+ mrb_hash_set(mrb, data, mrb_symbol_value(MRB_SYM(dormant)), mrb_stat_sub(mrb, q_dormant_));
862
+ mrb_hash_set(mrb, data, mrb_symbol_value(MRB_SYM(ready)), mrb_stat_sub(mrb, q_ready_));
863
+ mrb_hash_set(mrb, data, mrb_symbol_value(MRB_SYM(waiting)), mrb_stat_sub(mrb, q_waiting_));
864
+ mrb_hash_set(mrb, data, mrb_symbol_value(MRB_SYM(suspended)), mrb_stat_sub(mrb, q_suspended_));
865
+
866
+ mrb_task_enable_irq();
867
+
868
+ return data;
869
+ }
870
+
871
+ static mrb_value
872
+ mrb_task_s_run(mrb_state *mrb, mrb_value self)
873
+ {
874
+ return mrb_task_run(mrb);
875
+ }
876
+
877
+ static mrb_value
878
+ mrb_task_s_get(mrb_state *mrb, mrb_value self)
879
+ {
880
+ mrb_value name;
881
+
882
+ mrb_get_args(mrb, "S", &name);
883
+
884
+ /* Search all queues for task with matching name */
885
+ for (int i = 0; i < MRB_NUM_TASK_QUEUE; i++) {
886
+ mrb_task *t = mrb->task.queues[i];
887
+ while (t != NULL) {
888
+ if (mrb_equal(mrb, t->name, name)) {
889
+ return t->self;
890
+ }
891
+ t = t->next;
892
+ }
893
+ }
894
+
895
+ return mrb_nil_value();
896
+ }
897
+
898
+ /*
899
+ * Task instance methods
900
+ */
901
+
902
+ MRB_API mrb_value
903
+ mrb_task_status(mrb_state *mrb, mrb_value self)
904
+ {
905
+ mrb_task *t;
906
+
907
+ TASK_GET_PTR_OR_RAISE(t, self);
908
+
909
+ /* Return status as symbol matching original implementation */
910
+ return mrb_symbol_value(
911
+ (t->status == MRB_TASK_STATUS_RUNNING) ? MRB_SYM(RUNNING) :
912
+ (t->status == MRB_TASK_STATUS_READY) ? MRB_SYM(READY) :
913
+ (t->status == MRB_TASK_STATUS_WAITING) ? MRB_SYM(WAITING) :
914
+ (t->status == MRB_TASK_STATUS_SUSPENDED) ? MRB_SYM(SUSPENDED) :
915
+ (t->status == MRB_TASK_STATUS_DORMANT) ? MRB_SYM(DORMANT) :
916
+ MRB_SYM(UNKNOWN));
917
+ }
918
+
919
+ static mrb_value
920
+ mrb_task_inspect(mrb_state *mrb, mrb_value self)
921
+ {
922
+ mrb_task *t;
923
+ char buf[256];
924
+ const char *name_str;
925
+ const char *status_str;
926
+
927
+ TASK_GET_PTR_OR_RAISE(t, self);
928
+
929
+ /* Get status string directly from task status field */
930
+ switch (t->status) {
931
+ case MRB_TASK_STATUS_RUNNING:
932
+ status_str = "RUNNING";
933
+ break;
934
+ case MRB_TASK_STATUS_READY:
935
+ status_str = "READY";
936
+ break;
937
+ case MRB_TASK_STATUS_WAITING:
938
+ status_str = "WAITING";
939
+ break;
940
+ case MRB_TASK_STATUS_SUSPENDED:
941
+ status_str = "SUSPENDED";
942
+ break;
943
+ case MRB_TASK_STATUS_DORMANT:
944
+ status_str = "DORMANT";
945
+ break;
946
+ default:
947
+ status_str = "UNKNOWN";
948
+ break;
949
+ }
950
+
951
+ /* Get name as C string - avoid mrb_funcall to prevent VM state issues */
952
+ if (mrb_string_p(t->name)) {
953
+ name_str = RSTRING_PTR(t->name);
954
+ }
955
+ else if (mrb_symbol_p(t->name)) {
956
+ name_str = mrb_sym_name(mrb, mrb_symbol(t->name));
957
+ }
958
+ else {
959
+ /* Treat nil, undef, or any other type as unnamed */
960
+ name_str = "(unnamed)";
961
+ }
962
+
963
+ /* Format: #<Task:0x12345678 name:STATUS> */
964
+ snprintf(buf, sizeof(buf), "#<Task:%p %s:%s>",
965
+ (void *)t,
966
+ name_str,
967
+ status_str);
968
+
969
+ return mrb_str_new_cstr(mrb, buf);
970
+ }
971
+
972
+ static mrb_value
973
+ mrb_task_name(mrb_state *mrb, mrb_value self)
974
+ {
975
+ mrb_task *t;
976
+
977
+ TASK_GET_PTR_OR_RAISE(t, self);
978
+
979
+ /* Return "(noname)" if name is not set */
980
+ if (mrb_nil_p(t->name)) {
981
+ return mrb_str_new_lit(mrb, "(noname)");
982
+ }
983
+
984
+ return t->name;
985
+ }
986
+
987
+ static mrb_value
988
+ mrb_task_set_name(mrb_state *mrb, mrb_value self)
989
+ {
990
+ mrb_task *t;
991
+ mrb_value name;
992
+
993
+ TASK_GET_PTR_OR_RAISE(t, self);
994
+
995
+ mrb_get_args(mrb, "o", &name);
996
+ t->name = name;
997
+
998
+ return name;
999
+ }
1000
+
1001
+ static mrb_value
1002
+ mrb_task_priority(mrb_state *mrb, mrb_value self)
1003
+ {
1004
+ mrb_task *t;
1005
+
1006
+ TASK_GET_PTR_OR_RAISE(t, self);
1007
+
1008
+ return mrb_fixnum_value(t->priority);
1009
+ }
1010
+
1011
+ static mrb_value
1012
+ mrb_task_set_priority(mrb_state *mrb, mrb_value self)
1013
+ {
1014
+ mrb_task *t;
1015
+ mrb_int priority;
1016
+
1017
+ TASK_GET_PTR_OR_RAISE(t, self);
1018
+
1019
+ mrb_get_args(mrb, "i", &priority);
1020
+
1021
+ if (priority < 0 || priority > 255) {
1022
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "priority must be 0-255");
1023
+ }
1024
+
1025
+ mrb_task_disable_irq();
1026
+ t->priority = (uint8_t)priority;
1027
+
1028
+ /* Re-sort in queue if task is ready */
1029
+ if (t->status == MRB_TASK_STATUS_READY || t->status == MRB_TASK_STATUS_RUNNING) {
1030
+ q_delete_task(mrb, t);
1031
+ q_insert_task(mrb, t);
1032
+ }
1033
+ mrb_task_enable_irq();
1034
+
1035
+ return mrb_fixnum_value(priority);
1036
+ }
1037
+
1038
+ /*
1039
+ * Forward declarations for internal functions
1040
+ */
1041
+ static void suspend_task_internal(mrb_state *mrb, mrb_task *t);
1042
+ static void resume_task_internal(mrb_state *mrb, mrb_task *t);
1043
+ static void terminate_task_internal(mrb_state *mrb, mrb_task *t);
1044
+
1045
+ static mrb_value
1046
+ mrb_task_suspend(mrb_state *mrb, mrb_value self)
1047
+ {
1048
+ mrb_task *t;
1049
+
1050
+ TASK_GET_PTR_OR_RAISE(t, self);
1051
+ task_check_scheduler_lock(mrb);
1052
+
1053
+ suspend_task_internal(mrb, t);
1054
+ return self;
1055
+ }
1056
+
1057
+ static mrb_value
1058
+ mrb_task_resume(mrb_state *mrb, mrb_value self)
1059
+ {
1060
+ mrb_task *t;
1061
+
1062
+ TASK_GET_PTR_OR_RAISE(t, self);
1063
+ task_check_scheduler_lock(mrb);
1064
+
1065
+ resume_task_internal(mrb, t);
1066
+ return self;
1067
+ }
1068
+
1069
+ static mrb_value
1070
+ mrb_task_terminate(mrb_state *mrb, mrb_value self)
1071
+ {
1072
+ mrb_task *t;
1073
+
1074
+ TASK_GET_PTR_OR_RAISE(t, self);
1075
+ task_check_scheduler_lock(mrb);
1076
+
1077
+ terminate_task_internal(mrb, t);
1078
+ return self;
1079
+ }
1080
+
1081
+ static mrb_value
1082
+ mrb_task_join(mrb_state *mrb, mrb_value self)
1083
+ {
1084
+ mrb_task *t, *current;
1085
+
1086
+ TASK_GET_PTR_OR_RAISE(t, self);
1087
+
1088
+ /* Get current task using pointer arithmetic */
1089
+ if (mrb->c == mrb->root_c) {
1090
+ mrb_raise(mrb, E_RUNTIME_ERROR, "join can only be called from running task");
1091
+ }
1092
+ current = MRB2TASK(mrb);
1093
+
1094
+ /* Can't join self */
1095
+ if (t == current) {
1096
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "can't join self");
1097
+ }
1098
+
1099
+ /* If task is already dormant, return immediately */
1100
+ if (t->status == MRB_TASK_STATUS_DORMANT) {
1101
+ return t->state.result;
1102
+ }
1103
+
1104
+ /* Wait for task to complete */
1105
+ mrb_task_disable_irq();
1106
+ q_delete_task(mrb, current);
1107
+ current->status = MRB_TASK_STATUS_WAITING;
1108
+ current->reason = MRB_TASK_REASON_JOIN;
1109
+ current->wait.join = t;
1110
+ q_insert_task(mrb, current);
1111
+ mrb_task_enable_irq();
1112
+
1113
+ /* Trigger context switch */
1114
+ switching_ = TRUE;
1115
+
1116
+ return t->state.result;
1117
+ }
1118
+
1119
+ /*
1120
+ * Synchronous execution
1121
+ */
1122
+
1123
+ /* Execute a proc synchronously without context switching
1124
+ *
1125
+ * This function creates a temporary task, executes it to completion,
1126
+ * and returns the result. The scheduler_lock prevents any asynchronous
1127
+ * task operations during execution.
1128
+ */
1129
+ MRB_API mrb_value
1130
+ mrb_execute_proc_synchronously(mrb_state *mrb, mrb_value proc_val, mrb_int argc, const mrb_value *argv)
1131
+ {
1132
+ struct RProc *proc = mrb_proc_ptr(proc_val);
1133
+ int ai = mrb_gc_arena_save(mrb);
1134
+
1135
+ /*
1136
+ * argc/argv are reserved for future use (e.g., passing arguments to
1137
+ * event handlers or callback functions). Currently all callers pass
1138
+ * 0 and NULL.
1139
+ */
1140
+ (void)argc;
1141
+ (void)argv;
1142
+
1143
+ /* 1. Lock scheduler and save context */
1144
+ if (mrb->task.scheduler_lock >= MRB_TASK_SCHEDULER_LOCK_MAX) {
1145
+ mrb_raise(mrb, E_RUNTIME_ERROR, "scheduler lock overflow");
1146
+ }
1147
+ mrb->task.scheduler_lock++;
1148
+ struct mrb_context *original_c = mrb->c;
1149
+
1150
+ /* 2. Create a temporary task */
1151
+ mrb_task *t = task_alloc(mrb);
1152
+ t->priority = 0; /* Highest priority */
1153
+ t->status = MRB_TASK_STATUS_DORMANT;
1154
+ t->reason = MRB_TASK_REASON_NONE;
1155
+ t->name = mrb_str_new_lit(mrb, "(sync)");
1156
+
1157
+ /* Initialize task context */
1158
+ task_init_context(mrb, t, proc);
1159
+
1160
+ /* Create wrapper object (not registered with GC as we'll free it manually) */
1161
+ struct RClass *task_class = mrb_class_get(mrb, "Task");
1162
+ mrb_value task_obj = mrb_obj_value(mrb_data_object_alloc(mrb, task_class, t, &mrb_task_type));
1163
+ t->self = task_obj;
1164
+
1165
+ /* 3. Move task from DORMANT to READY */
1166
+ mrb_task_disable_irq();
1167
+ t->status = MRB_TASK_STATUS_READY;
1168
+ q_insert_task(mrb, t);
1169
+ mrb_task_enable_irq();
1170
+
1171
+ /* 4. Execute the task in a dedicated loop (no context switching) */
1172
+ t->status = MRB_TASK_STATUS_RUNNING;
1173
+ mrb->c = &t->c;
1174
+
1175
+ while (t->c.status != MRB_TASK_STOPPED) {
1176
+ t->state.result = mrb_vm_exec(mrb, mrb->c->ci->proc, mrb->c->ci->pc);
1177
+ }
1178
+
1179
+ /* If there's an unhandled exception after VM stops, save it as result */
1180
+ if (mrb->exc) {
1181
+ t->state.result = mrb_obj_value(mrb->exc);
1182
+ }
1183
+
1184
+ /* 5. Get result and clean up */
1185
+ mrb_value result = t->state.result;
1186
+ if (mrb_obj_ptr(result) == mrb->exc) {
1187
+ mrb->exc = NULL; /* Clear exception */
1188
+ }
1189
+
1190
+ /* 6. Free the temporary task's resources */
1191
+ mrb_task_disable_irq();
1192
+ q_delete_task(mrb, t);
1193
+ mrb_task_enable_irq();
1194
+
1195
+ /* Prevent double-free: clear Data object's type before freeing task */
1196
+ DATA_TYPE(task_obj) = NULL;
1197
+
1198
+ /* Free context resources directly (bypass GC since we own this task) */
1199
+ if (t->c.stbase) {
1200
+ mrb_free(mrb, t->c.stbase);
1201
+ t->c.stbase = NULL;
1202
+ }
1203
+ if (t->c.cibase) {
1204
+ mrb_free(mrb, t->c.cibase);
1205
+ t->c.cibase = NULL;
1206
+ }
1207
+ mrb_free(mrb, t);
1208
+
1209
+ /* 7. Restore context and unlock */
1210
+ mrb->c = original_c;
1211
+ mrb->task.scheduler_lock--;
1212
+
1213
+ mrb_gc_arena_restore(mrb, ai);
1214
+ mrb_gc_protect(mrb, result);
1215
+
1216
+ return result;
1217
+ }
1218
+
1219
+ /*
1220
+ * Task.tick class method
1221
+ */
1222
+ static mrb_value
1223
+ mrb_task_s_tick(mrb_state *mrb, mrb_value self)
1224
+ {
1225
+ return mrb_int_value(mrb, tick_ * MRB_TICK_UNIT);
1226
+ }
1227
+
1228
+ /*
1229
+ * Create a task from a proc
1230
+ * This is called from mrc_create_task() in mrc_utils.c
1231
+ */
1232
+ MRB_API mrb_value
1233
+ mrb_create_task(mrb_state *mrb, struct RProc *proc, mrb_value name, mrb_value priority, mrb_value top_self)
1234
+ {
1235
+ task_check_scheduler_lock(mrb);
1236
+
1237
+ /* Validate/default priority */
1238
+ mrb_int prio = 128; /* Default priority */
1239
+ if (!mrb_nil_p(priority)) {
1240
+ if (!mrb_integer_p(priority)) {
1241
+ mrb_raise(mrb, E_TYPE_ERROR, "priority must be an Integer");
1242
+ }
1243
+ prio = mrb_integer(priority);
1244
+ if (prio < 0 || prio > 255) {
1245
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "priority must be 0-255");
1246
+ }
1247
+ }
1248
+
1249
+ /* Validate/default name */
1250
+ mrb_value name_val = mrb_nil_p(name) ? mrb_str_new_lit(mrb, "(noname)") : name;
1251
+
1252
+ /* Allocate and initialize task */
1253
+ mrb_task *t = task_alloc(mrb);
1254
+ t->priority = (uint8_t)prio;
1255
+ t->status = MRB_TASK_STATUS_READY;
1256
+ t->reason = MRB_TASK_REASON_NONE;
1257
+ t->name = name_val;
1258
+
1259
+ /* Create Ruby object to hold task */
1260
+ mrb_value task_obj = mrb_obj_value(mrb_data_object_alloc(mrb, mrb_class_get(mrb, "Task"),
1261
+ t, &mrb_task_type));
1262
+ t->self = task_obj;
1263
+
1264
+ /* Register with GC to protect task object from collection */
1265
+ mrb_gc_register(mrb, task_obj);
1266
+
1267
+ /* Initialize task context */
1268
+ task_init_context(mrb, t, proc);
1269
+
1270
+ /* Set top_self if provided */
1271
+ if (!mrb_nil_p(top_self)) {
1272
+ t->c.ci->stack[0] = top_self;
1273
+ }
1274
+
1275
+ /* Insert into ready queue */
1276
+ mrb_task_disable_irq();
1277
+ q_insert_task(mrb, t);
1278
+ mrb_task_enable_irq();
1279
+
1280
+ /* Trigger context switch if this task has higher priority than current */
1281
+ if (q_ready_ && q_ready_->status == MRB_TASK_STATUS_RUNNING) {
1282
+ if (t->priority < q_ready_->priority) {
1283
+ switching_ = TRUE;
1284
+ }
1285
+ }
1286
+
1287
+ return task_obj;
1288
+ }
1289
+
1290
+ /*
1291
+ * Internal: Suspend a task (no validation, no scheduler_lock check)
1292
+ */
1293
+ static void
1294
+ suspend_task_internal(mrb_state *mrb, mrb_task *t)
1295
+ {
1296
+ /*
1297
+ * WAITING task should also be suspended:
1298
+ * Suspend trigger may occur while the task is sleeping (WAITING).
1299
+ * DORMANT task should also be suspended:
1300
+ * e.g., IRB in PicoRuby suspends a DORMANT task to use it again.
1301
+ */
1302
+ if (t->status == MRB_TASK_STATUS_SUSPENDED) return;
1303
+
1304
+ /*
1305
+ * Determine if context switch is needed BEFORE changing state.
1306
+ * Context switch is needed when suspending a RUNNING task or
1307
+ * the current ready task.
1308
+ */
1309
+ mrb_bool need_switch = (t == q_ready_ || t->status == MRB_TASK_STATUS_RUNNING);
1310
+
1311
+ task_change_state(mrb, t, MRB_TASK_STATUS_SUSPENDED);
1312
+
1313
+ if (need_switch) {
1314
+ switching_ = TRUE;
1315
+ }
1316
+ }
1317
+
1318
+ /*
1319
+ * Suspend a task
1320
+ */
1321
+ MRB_API void
1322
+ mrb_suspend_task(mrb_state *mrb, mrb_value task)
1323
+ {
1324
+ task_check_scheduler_lock(mrb);
1325
+
1326
+ mrb_task *t = (mrb_task*)mrb_data_check_get_ptr(mrb, task, &mrb_task_type);
1327
+ if (!t) return;
1328
+
1329
+ suspend_task_internal(mrb, t);
1330
+ }
1331
+
1332
+ /*
1333
+ * Internal: Resume a task (no validation, no scheduler_lock check)
1334
+ */
1335
+ static void
1336
+ resume_task_internal(mrb_state *mrb, mrb_task *t)
1337
+ {
1338
+ if (t->status != MRB_TASK_STATUS_SUSPENDED) return;
1339
+
1340
+ /* Determine target state based on reason */
1341
+ uint8_t target_status = (t->reason == MRB_TASK_REASON_NONE) ?
1342
+ MRB_TASK_STATUS_READY : MRB_TASK_STATUS_WAITING;
1343
+
1344
+ task_change_state(mrb, t, target_status);
1345
+
1346
+ /* Trigger context switch if resumed task has higher priority */
1347
+ if (target_status == MRB_TASK_STATUS_READY && q_ready_ &&
1348
+ q_ready_->status == MRB_TASK_STATUS_RUNNING) {
1349
+ if (t->priority < q_ready_->priority) {
1350
+ switching_ = TRUE;
1351
+ }
1352
+ }
1353
+
1354
+ /* Update wakeup_tick if task has sleep reason */
1355
+ if (t->reason == MRB_TASK_REASON_SLEEP) {
1356
+ if ((int32_t)(t->wait.wakeup_tick - wakeup_tick_) < 0) {
1357
+ wakeup_tick_ = t->wait.wakeup_tick;
1358
+ }
1359
+ }
1360
+ }
1361
+
1362
+ /*
1363
+ * Resume a task
1364
+ */
1365
+ MRB_API void
1366
+ mrb_resume_task(mrb_state *mrb, mrb_value task)
1367
+ {
1368
+ task_check_scheduler_lock(mrb);
1369
+
1370
+ mrb_task *t = (mrb_task*)mrb_data_check_get_ptr(mrb, task, &mrb_task_type);
1371
+ if (!t) return;
1372
+
1373
+ resume_task_internal(mrb, t);
1374
+ }
1375
+
1376
+ /*
1377
+ * Internal: Terminate a task (no validation, no scheduler_lock check)
1378
+ */
1379
+ static void
1380
+ terminate_task_internal(mrb_state *mrb, mrb_task *t)
1381
+ {
1382
+ if (t->status == MRB_TASK_STATUS_DORMANT) return;
1383
+
1384
+ mrb_task_disable_irq();
1385
+ q_delete_task(mrb, t);
1386
+ t->status = MRB_TASK_STATUS_DORMANT;
1387
+ t->c.status = MRB_TASK_STOPPED;
1388
+ q_insert_task(mrb, t);
1389
+ mrb_task_enable_irq();
1390
+
1391
+ wake_up_join_waiters(mrb, t);
1392
+
1393
+ /* If terminating self, trigger context switch */
1394
+ if (t == q_ready_) {
1395
+ switching_ = TRUE;
1396
+ }
1397
+ }
1398
+
1399
+ /*
1400
+ * Terminate a task
1401
+ */
1402
+ MRB_API void
1403
+ mrb_terminate_task(mrb_state *mrb, mrb_value task)
1404
+ {
1405
+ task_check_scheduler_lock(mrb);
1406
+
1407
+ mrb_task *t = (mrb_task*)mrb_data_check_get_ptr(mrb, task, &mrb_task_type);
1408
+ if (!t) return;
1409
+
1410
+ terminate_task_internal(mrb, t);
1411
+ }
1412
+
1413
+ /*
1414
+ * Stop a task (mark as stopped but don't move to dormant)
1415
+ */
1416
+ MRB_API mrb_bool
1417
+ mrb_stop_task(mrb_state *mrb, mrb_value task)
1418
+ {
1419
+ task_check_scheduler_lock(mrb);
1420
+
1421
+ mrb_task *t = (mrb_task*)mrb_data_check_get_ptr(mrb, task, &mrb_task_type);
1422
+ if (!t) return FALSE;
1423
+
1424
+ if (t->c.status == MRB_TASK_STOPPED) {
1425
+ return FALSE; /* Already stopped */
1426
+ }
1427
+ t->c.status = MRB_TASK_STOPPED;
1428
+ return TRUE;
1429
+ }
1430
+
1431
+ /*
1432
+ * Get task result value
1433
+ */
1434
+ MRB_API mrb_value
1435
+ mrb_task_value(mrb_state *mrb, mrb_value task)
1436
+ {
1437
+ mrb_task *t = (mrb_task*)mrb_data_check_get_ptr(mrb, task, &mrb_task_type);
1438
+ if (!t) return mrb_nil_value();
1439
+
1440
+ return t->state.result;
1441
+ }
1442
+
1443
+ /*
1444
+ * Initialize task context with a new proc
1445
+ */
1446
+ MRB_API void
1447
+ mrb_task_init_context(mrb_state *mrb, mrb_value task, struct RProc *proc)
1448
+ {
1449
+ task_check_scheduler_lock(mrb);
1450
+
1451
+ mrb_task *t = (mrb_task*)mrb_data_check_get_ptr(mrb, task, &mrb_task_type);
1452
+ if (!t) return;
1453
+
1454
+ struct mrb_context *c = &t->c;
1455
+
1456
+ /* Cleanup existing context if any */
1457
+ if (c->stbase) {
1458
+ mrb_free(mrb, c->stbase);
1459
+ c->stbase = NULL;
1460
+ }
1461
+ if (c->cibase) {
1462
+ mrb_free(mrb, c->cibase);
1463
+ c->cibase = NULL;
1464
+ }
1465
+
1466
+ /* Re-initialize context */
1467
+ task_init_context(mrb, t, proc);
1468
+ }
1469
+
1470
+ /*
1471
+ * Reset task context to initial state
1472
+ */
1473
+ MRB_API void
1474
+ mrb_task_reset_context(mrb_state *mrb, mrb_value task)
1475
+ {
1476
+ task_check_scheduler_lock(mrb);
1477
+
1478
+ mrb_task *t = (mrb_task*)mrb_data_check_get_ptr(mrb, task, &mrb_task_type);
1479
+ if (!t) return;
1480
+
1481
+ struct mrb_context *c = &t->c;
1482
+ c->ci = c->cibase;
1483
+ c->status = MRB_TASK_CREATED;
1484
+ if (c->ci) {
1485
+ mrb_vm_ci_target_class_set(c->ci, mrb->object_class);
1486
+ }
1487
+ }
1488
+
1489
+ /*
1490
+ * Set proc for task
1491
+ */
1492
+ MRB_API void
1493
+ mrb_task_proc_set(mrb_state *mrb, mrb_value task, struct RProc *proc)
1494
+ {
1495
+ task_check_scheduler_lock(mrb);
1496
+
1497
+ mrb_task *t = (mrb_task*)mrb_data_check_get_ptr(mrb, task, &mrb_task_type);
1498
+ if (!t) return;
1499
+
1500
+ /* Handle environment resize if needed */
1501
+ if (t->c.cibase && t->c.cibase->u.env) {
1502
+ struct REnv *e = mrb_vm_ci_env(t->c.cibase);
1503
+ if (e && MRB_ENV_LEN(e) < proc->body.irep->nlocals) {
1504
+ MRB_ENV_SET_LEN(e, proc->body.irep->nlocals);
1505
+ }
1506
+ }
1507
+
1508
+ if (t->c.ci) {
1509
+ mrb_vm_ci_proc_set(t->c.ci, proc);
1510
+ }
1511
+ }
1512
+
1513
+ /*
1514
+ * Initialization
1515
+ */
1516
+
1517
+ void
1518
+ mrb_mruby_task_gem_init(mrb_state *mrb)
1519
+ {
1520
+ struct RClass *task_class;
1521
+
1522
+ /* Initialize HAL (timer and interrupts) */
1523
+ mrb_hal_task_init(mrb);
1524
+
1525
+ /* Initialize main task to NULL and scheduler_lock to 0 */
1526
+ mrb->task.main_task = NULL;
1527
+ mrb->task.scheduler_lock = 0;
1528
+
1529
+ task_class = mrb_define_class_id(mrb, MRB_SYM(Task), mrb->object_class);
1530
+ MRB_SET_INSTANCE_TT(task_class, MRB_TT_DATA);
1531
+
1532
+ /* Class methods */
1533
+ mrb_define_class_method_id(mrb, task_class, MRB_SYM(new), mrb_task_s_new, MRB_ARGS_KEY(2,0)|MRB_ARGS_BLOCK());
1534
+ mrb_define_class_method_id(mrb, task_class, MRB_SYM(current), mrb_task_s_current, MRB_ARGS_NONE());
1535
+ mrb_define_class_method_id(mrb, task_class, MRB_SYM(list), mrb_task_s_list, MRB_ARGS_NONE());
1536
+ mrb_define_class_method_id(mrb, task_class, MRB_SYM(pass), mrb_task_s_pass, MRB_ARGS_NONE());
1537
+ mrb_define_class_method_id(mrb, task_class, MRB_SYM(stat), mrb_task_s_stat, MRB_ARGS_NONE());
1538
+ mrb_define_class_method_id(mrb, task_class, MRB_SYM(get), mrb_task_s_get, MRB_ARGS_REQ(1));
1539
+ mrb_define_class_method_id(mrb, task_class, MRB_SYM(run), mrb_task_s_run, MRB_ARGS_NONE());
1540
+ mrb_define_class_method_id(mrb, task_class, MRB_SYM(tick), mrb_task_s_tick, MRB_ARGS_NONE());
1541
+
1542
+ /* Instance methods */
1543
+ mrb_define_method_id(mrb, task_class, MRB_SYM(status), mrb_task_status, MRB_ARGS_NONE());
1544
+ mrb_define_method_id(mrb, task_class, MRB_SYM(inspect), mrb_task_inspect, MRB_ARGS_NONE());
1545
+ mrb_define_method_id(mrb, task_class, MRB_SYM(name), mrb_task_name, MRB_ARGS_NONE());
1546
+ mrb_define_method_id(mrb, task_class, MRB_SYM_E(name), mrb_task_set_name, MRB_ARGS_REQ(1));
1547
+ mrb_define_method_id(mrb, task_class, MRB_SYM(priority), mrb_task_priority, MRB_ARGS_NONE());
1548
+ mrb_define_method_id(mrb, task_class, MRB_SYM_E(priority), mrb_task_set_priority, MRB_ARGS_REQ(1));
1549
+ mrb_define_method_id(mrb, task_class, MRB_SYM(suspend), mrb_task_suspend, MRB_ARGS_NONE());
1550
+ mrb_define_method_id(mrb, task_class, MRB_SYM(resume), mrb_task_resume, MRB_ARGS_NONE());
1551
+ mrb_define_method_id(mrb, task_class, MRB_SYM(terminate), mrb_task_terminate, MRB_ARGS_NONE());
1552
+ mrb_define_method_id(mrb, task_class, MRB_SYM(join), mrb_task_join, MRB_ARGS_NONE());
1553
+
1554
+ /* Kernel methods (module functions like CRuby)
1555
+ * Note: sleep and usleep override mruby-sleep's implementation to be task-aware
1556
+ * (cooperative sleep within tasks, blocking sleep otherwise)
1557
+ */
1558
+ mrb_define_module_function_id(mrb, mrb->kernel_module, MRB_SYM(sleep), mrb_f_sleep, MRB_ARGS_OPT(1));
1559
+ mrb_define_module_function_id(mrb, mrb->kernel_module, MRB_SYM(usleep), mrb_f_usleep, MRB_ARGS_REQ(1));
1560
+ mrb_define_module_function_id(mrb, mrb->kernel_module, MRB_SYM(sleep_ms), mrb_f_sleep_ms, MRB_ARGS_REQ(1));
1561
+ }
1562
+
1563
+ void
1564
+ mrb_mruby_task_gem_final(mrb_state *mrb)
1565
+ {
1566
+ /* Clear main task pointer - GC will handle freeing the object */
1567
+ if (mrb->task.main_task) {
1568
+ mrb_gc_unregister(mrb, mrb->task.main_task->self);
1569
+ mrb->task.main_task = NULL;
1570
+ }
1571
+
1572
+ mrb_hal_task_final(mrb);
1573
+ }