sweet-moon 0.0.4 → 0.0.7

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bdfabe100158948ea2c29fadca09e82cd9567d71230627f6bd0e8ba3a04f523d
4
- data.tar.gz: 3bb2925b0ef437c3942a837a67bb94261d89c9aaf5a011973dcf4b98db07e6b9
3
+ metadata.gz: 880cceae5913b9a748b5b318bfc27c56ccf58d7ae54b7f31f8aeea943c524aac
4
+ data.tar.gz: ab2abc87ef9ead4ea7be474963a92ad647326ec6d4ad1bfec62ed20d103d4e4c
5
5
  SHA512:
6
- metadata.gz: 582a792771b05e59a577349070709e78bb2a569ef14cdb955fb2666e826eb401ba4aa4e7b19297c30fd64f98eda244d656caf2e904f9c1af95e971807aed8820
7
- data.tar.gz: 38307987e564f998b40b2792fd97a3e107095d6e46992689663d63d67bf248dfc16c3a8838f8461bf7a8765857e7b5c04da4e4ac3c636cd6a419abb85bab2e5b
6
+ metadata.gz: 1b613dba97c24527e3e71a8bd7c6d14cd98edcd9a0083a85463a3300f05886a81da33ea5c515108fe523ed43ab012760954edd40dacec4aa38a250e6846b3906
7
+ data.tar.gz: c8c09f0f1bc7cde58c789975b84491399af843b8d95cb69bd3600dbb4c22a056f232e99eea50d3af969ebea6fa298bd86214a596d7ab67afe5c4a209d8a43fa3
data/.rubocop.yml CHANGED
@@ -5,6 +5,9 @@ AllCops:
5
5
  Style/Documentation:
6
6
  Enabled: false
7
7
 
8
+ Lint/RescueException:
9
+ Exclude: ['components/interpreters/**/function.rb']
10
+
8
11
  Layout/LineLength:
9
12
  Max: 86
10
13
  Exclude: ['spec/**/*', 'logic/signatures/*']
data/README.md CHANGED
@@ -28,10 +28,14 @@ _Sweet Moon_ is a resilient solution that makes working with [Lua](https://www.l
28
28
  - [Fennel](#fennel)
29
29
  - [Fennel Usage](#fennel-usage)
30
30
  - [Fennel Global vs Local Variables](#fennel-global-vs-local-variables)
31
+ - [allowedGlobals and options](#allowedglobals-and-options)
31
32
  - [Fennel Setup](#fennel-setup)
32
33
  - [Integration with fnx](#integration-with-fnx)
34
+ - [Fennel REPL](#fennel-repl)
33
35
  - [Global vs Isolated](#global-vs-isolated)
36
+ - [Global FFI](#global-ffi)
34
37
  - [Error Handling](#error-handling)
38
+ - [Ruby feat. Lua Errors](#ruby-feat-lua-errors)
35
39
  - [Where can I find .so files?](#where-can-i-find-so-files)
36
40
  - [Low-Level C API](#low-level-c-api)
37
41
  - [The API](#the-api)
@@ -71,7 +75,7 @@ gem install sweet-moon
71
75
  > **Disclaimer:** It's an early-stage project, and you should expect breaking changes.
72
76
 
73
77
  ```ruby
74
- gem 'sweet-moon', '~> 0.0.4'
78
+ gem 'sweet-moon', '~> 0.0.7'
75
79
  ```
76
80
 
77
81
  ```ruby
@@ -442,6 +446,16 @@ second = state.get(:second)
442
446
  second.([%w[a b c]]) # => 'b'
443
447
  ```
444
448
 
449
+ Alternatively, you can send the `outputs` parameter:
450
+
451
+ ```ruby
452
+ require 'sweet-moon'
453
+
454
+ state = SweetMoon::State.new
455
+
456
+ state.eval('return "a", "b"', { outputs: 2 }) # => ['a', 'b']
457
+ ```
458
+
445
459
  You can call Ruby _Lambdas_ from _Lua_ as well:
446
460
 
447
461
  ```ruby
@@ -612,21 +626,21 @@ state.add_package_path('/home/me/my-lua-modules/?/init.lua')
612
626
 
613
627
  state.add_package_cpath('/home/me/my-lua-modules/?.so')
614
628
 
615
- state.add_package_path('/home/me/fennel.lua')
629
+ state.add_package_path('/home/me/fennel/?.lua')
616
630
 
617
- state.add_package_cpath('/home/me/lib.so')
631
+ state.add_package_cpath('/home/me/?.so')
618
632
 
619
633
  state.package_path
620
634
  # => ['./?.lua',
621
635
  # './?/init.lua',
622
636
  # '/home/me/my-lua-modules/?.lua',
623
637
  # '/home/me/my-lua-modules/?/init.lua',
624
- # '/home/me/fennel.lua']
638
+ # '/home/me/fennel/?.lua']
625
639
 
626
640
  state.package_cpath
627
641
  # => ['./?.so',
628
642
  # '/home/me/my-lua-modules/?.so',
629
- # '/home/me/lib.so']
643
+ # '/home/me/?.so']
630
644
  ```
631
645
 
632
646
  Requiring a module:
@@ -646,8 +660,8 @@ You can set packages in State constructors:
646
660
  require 'sweet-moon'
647
661
 
648
662
  SweetMoon::State.new(
649
- package_path: '/folder/lib.lua',
650
- package_cpath: '/lib/lib.so',
663
+ package_path: '/folder/lib/?.lua',
664
+ package_cpath: '/lib/lib/?.so',
651
665
  )
652
666
  ```
653
667
 
@@ -657,8 +671,8 @@ Also, you can add packages through the global config:
657
671
  require 'sweet-moon'
658
672
 
659
673
  SweetMoon.global.config(
660
- package_path: '/folder/lib.lua',
661
- package_cpath: '/lib/lib.so',
674
+ package_path: '/folder/lib/?.lua',
675
+ package_cpath: '/lib/lib/?.so',
662
676
  )
663
677
  ```
664
678
 
@@ -818,6 +832,71 @@ fennel.eval('var-b') # => nil
818
832
  fennel.eval('_G.var-b') # => 35
819
833
  ```
820
834
 
835
+ ### allowedGlobals and options
836
+
837
+ As Lua, Fennel functions may return [multiple results](https://www.lua.org/pil/5.1.html), so `eval` and `load` accept a second parameter to indicate the expected number of outputs:
838
+
839
+ ```fnl
840
+ ; source.fnl
841
+
842
+ (fn multi [] (values "c" "d"))
843
+
844
+ (multi)
845
+ ```
846
+
847
+ ```ruby
848
+ require 'sweet-moon'
849
+
850
+ fennel = SweetMoon::State.new.fennel
851
+
852
+ fennel.eval('(values "a" "b")', 2) # => ['a', 'b']
853
+ fennel.load('source.fnl', 2) # => ['c', 'd']
854
+ ```
855
+
856
+ The Fennel API offers [some options](https://fennel-lang.org/api) that `eval` and `load` accept as a third parameter:
857
+
858
+ ```ruby
859
+ require 'sweet-moon'
860
+
861
+ fennel = SweetMoon::State.new.fennel
862
+
863
+ fennel.eval('(print (+ 2 3))', 1, { allowedGlobals: ['print'] }) # => 5
864
+
865
+ fennel.eval('(print (+ 2 3))', 1, { allowedGlobals: [] })
866
+ # Compile error in unknown:1 (SweetMoon::Errors::LuaRuntimeError)
867
+ # unknown identifier in strict mode: print
868
+
869
+ # (print (+ 2 3))
870
+ # ^^^^^
871
+ # * Try looking to see if there's a typo.
872
+ # * Try using the _G table instead, eg. _G.print if you really want a global.
873
+ # * Try moving this code to somewhere that print is in scope.
874
+ # * Try binding print as a local in the scope of this code.
875
+ ```
876
+
877
+ Alternatively, you can use the second parameter for options as well:
878
+
879
+ ```ruby
880
+ require 'sweet-moon'
881
+
882
+ fennel = SweetMoon::State.new.fennel
883
+
884
+ fennel.eval('(print (+ 2 3))', { allowedGlobals: ['print'] }) # => 5
885
+ ```
886
+
887
+ You can also specify the expected outputs in the options parameter (it will be removed and not forwarded to Fennel):
888
+
889
+ ```ruby
890
+ require 'sweet-moon'
891
+
892
+ fennel = SweetMoon::State.new.fennel
893
+
894
+ fennel.eval(
895
+ '(values "a" "b")',
896
+ { allowedGlobals: ['values'], outputs: 2 }
897
+ ) # => ['a', 'b']
898
+ ```
899
+
821
900
  ### Fennel Setup
822
901
 
823
902
  To ensure that the Fennel module is available, you can set up the [_LuaRocks_](#integration-withluarocks) integration or manually add the `package_path` for the module.
@@ -831,7 +910,7 @@ require 'sweet-moon'
831
910
 
832
911
  state = SweetMoon::State.new
833
912
 
834
- state.add_package_path('/folder/fennel.lua')
913
+ state.add_package_path('/folder/fennel/?.lua')
835
914
 
836
915
  state.fennel.eval('(+ 1 1)') # => 2
837
916
  ```
@@ -841,7 +920,7 @@ With the constructor:
841
920
  ```ruby
842
921
  require 'sweet-moon'
843
922
 
844
- fennel = SweetMoon::State.new(package_path: '/folder/fennel.lua').fennel
923
+ fennel = SweetMoon::State.new(package_path: '/folder/fennel/?.lua').fennel
845
924
 
846
925
  fennel.eval('(+ 1 1)') # => 2
847
926
  ```
@@ -851,7 +930,7 @@ With global:
851
930
  ```ruby
852
931
  require 'sweet-moon'
853
932
 
854
- SweetMoon.global.state.add_package_path('/folder/fennel.lua')
933
+ SweetMoon.global.state.add_package_path('/folder/fennel/?.lua')
855
934
 
856
935
  SweetMoon.global.state.fennel.eval('(+ 1 1)') # => 2
857
936
  ```
@@ -861,7 +940,7 @@ Alternatively:
861
940
  ```ruby
862
941
  require 'sweet-moon'
863
942
 
864
- SweetMoon.global.config(package_path: '/folder/fennel.lua')
943
+ SweetMoon.global.config(package_path: '/folder/fennel/?.lua')
865
944
 
866
945
  SweetMoon.global.state.fennel.eval('(+ 1 1)') # => 2
867
946
  ```
@@ -888,6 +967,44 @@ To enforce the path for the `.fnx.fnl` file:
888
967
  fennel.eval('(let [fnx (require :fnx)] (fnx.bootstrap! "/project/.fnx.fnl"))')
889
968
  ```
890
969
 
970
+ ### Fennel REPL
971
+
972
+ In Ruby, you can start a [REPL](https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop) at any time somewhere in your code with [_pry_](https://github.com/pry/pry):
973
+
974
+ ```ruby
975
+ require 'pry'
976
+
977
+ binding.pry
978
+ ```
979
+
980
+ The same is true for Fennel, you just need to:
981
+ ```fnl
982
+ (let [fennel (require :fennel)]
983
+ (fennel.repl {}))
984
+ ```
985
+
986
+ Fennel's REPL won't have your _local_ values. But, you can tweak it to receive values to be checked inside the REPL:
987
+
988
+ ```fnl
989
+ (fn my-repl [to-expose]
990
+ (let [fennel (require :fennel) env _G]
991
+ (each [key value (pairs to-expose)] (tset env key value))
992
+ (fennel.repl {:env env})))
993
+
994
+ (local value "some value")
995
+
996
+ (my-repl {:value value})
997
+
998
+ ; Inside the REPL:
999
+
1000
+ ; >> value
1001
+ ; "some value"
1002
+ ```
1003
+
1004
+ You can install [_readline_](https://luarocks.org/modules/peterbillam/readline) for a better experience, e.g., autocompleting.
1005
+
1006
+ > _Check [Fennel's documentation](https://fennel-lang.org/api#start-a-configurable-repl) to learn more about the REPL._
1007
+
891
1008
  ## Global vs Isolated
892
1009
 
893
1010
  You can use the **global** helper that provides an _API_ and a _State_ for quick-and-dirty coding. It uses internally a Ruby [_Singleton_](https://docs.ruby-lang.org/en/3.1/Singleton.html):
@@ -934,6 +1051,8 @@ api_5.luaL_newstate
934
1051
  api_3.luaH_new
935
1052
  ```
936
1053
 
1054
+ > _Check the caveats related to [_Global FFI_](#global-ffi) when working with multiple versions._
1055
+
937
1056
  On the other hand, using the **global** _State_ may lead to a lot of issues. You need to consider from simple things – _"If I load two different files, the first file may impact the state of the second one?"_ – to more complex ones like multithreading, concurrency, etc.
938
1057
 
939
1058
  So, you can at any time create a new isolated _State_ and destroy it when you don't need it anymore:
@@ -963,6 +1082,48 @@ state_5.eval('return _VERSION') # => Lua 5.4
963
1082
  state_3.eval('return _VERSION') # => Lua 3.2
964
1083
  ```
965
1084
 
1085
+ > _Check the caveats related to [_Global FFI_](#global-ffi) when working with multiple versions._
1086
+
1087
+ ## Global FFI
1088
+
1089
+ Some Lua libraries (e.g., [_readline_](https://pjb.com.au/comp/lua/readline.html) and [_luafilesystem_](https://keplerproject.github.io/luafilesystem/)) require the Lua C API functions available in the global C environment.
1090
+
1091
+ By default, _Sweet Moon_ enables [_Global FFI_](https://github.com/ffi/ffi/wiki/Loading-Libraries#function-visibility) to reduce friction when using popular libraries.
1092
+
1093
+ Using distinct Lua versions simultaneously with multiple _Shared Objects_ may be dangerous in this setup: Two APIs with the same name functions could be an issue because something will be overwritten.
1094
+
1095
+ Also, libraries that need Lua C API functions are compiled for a specific Lua version. If you are, e.g., using _LuaJIT_ and your library expects the _Standard Lua_, you may face issues.
1096
+
1097
+ You can disable _Global FFI_ at any time with:
1098
+
1099
+ ```ruby
1100
+ require 'sweet-moon'
1101
+
1102
+ SweetMoon.global.config(global_ffi: false)
1103
+
1104
+ SweetMoon::State.new(global_ffi: false)
1105
+
1106
+ SweetMoon::API.new(global_ffi: false)
1107
+ ```
1108
+
1109
+ To check if it's enabled or not:
1110
+
1111
+ ```ruby
1112
+ require 'sweet-moon'
1113
+
1114
+ SweetMoon.global.api.meta.global_ffi # => true
1115
+ SweetMoon.global.state.meta.global_ffi # => true
1116
+
1117
+ SweetMoon::API.new.meta.global_ffi # => true
1118
+
1119
+ SweetMoon::State.new.meta.global_ffi # => true
1120
+ ```
1121
+
1122
+ **Caveats:**
1123
+
1124
+ Binding globally a C API is irreversible, so if you start something with `global_ffi: true` and then change to `global_ffi: false`, it won't make the global one disappear. If you need _local_, ensure that you do it from the first line and never put anything as global throughout the entire program life cycle.
1125
+
1126
+ Also, the simple action of accessing `meta.global_ff` will bind the API, so you need to set your desired configuration before checking.
966
1127
 
967
1128
  ## Error Handling
968
1129
 
@@ -1007,6 +1168,108 @@ rescue LuaRuntimeError => error
1007
1168
  end
1008
1169
  ```
1009
1170
 
1171
+ ### Ruby feat. Lua Errors
1172
+
1173
+ Lua errors can be rescued inside Ruby:
1174
+
1175
+ ```lua
1176
+ -- source.lua
1177
+ error('error from lua')
1178
+ ```
1179
+
1180
+ ```ruby
1181
+ require 'sweet-moon'
1182
+ require 'sweet-moon/errors'
1183
+
1184
+ state = SweetMoon::State.new
1185
+
1186
+ begin
1187
+ state.load('source.lua')
1188
+ rescue LuaRuntimeError => e
1189
+ puts e.message
1190
+ # => source.lua:2: error from lua
1191
+ end
1192
+ ```
1193
+
1194
+ Ruby errors can be handled inside Lua:
1195
+
1196
+ ```ruby
1197
+ require 'sweet-moon'
1198
+
1199
+ state = SweetMoon::State.new
1200
+
1201
+ state.set(:rubyFn, -> { raise 'error from ruby' })
1202
+
1203
+ state.load('source.lua')
1204
+ ```
1205
+
1206
+ ```lua
1207
+ -- source.lua
1208
+ local status, err = pcall(rubyFn)
1209
+
1210
+ print(status) -- => false
1211
+
1212
+ print(err)
1213
+ -- [string " return function (...)..."]:5: RuntimeError: error from ruby stack traceback:
1214
+ -- [string " return function (...)..."]:5: in function 'rubyFn'
1215
+ -- [C]: in function 'pcall'
1216
+ -- source.lua:2: in main chunk
1217
+ ```
1218
+
1219
+ Ruby errors not handled inside Lua can be rescued inside Ruby again, with an additional Lua backtrace:
1220
+
1221
+ ```lua
1222
+ -- source.lua
1223
+ a = 1
1224
+
1225
+ rubyFn()
1226
+ ```
1227
+
1228
+ ```ruby
1229
+ require 'sweet-moon'
1230
+
1231
+ state = SweetMoon::State.new
1232
+
1233
+ state.set(:rubyFn, -> { raise 'error from ruby' })
1234
+
1235
+ begin
1236
+ state.load('source.lua')
1237
+ rescue RuntimeError => e
1238
+ puts e.message # => error from ruby
1239
+
1240
+ puts e.backtrace.last
1241
+ # => source.lua:4: in main chunk
1242
+ end
1243
+ ```
1244
+
1245
+ Lua errors inside Lua functions can be rescued inside Ruby:
1246
+
1247
+ ```lua
1248
+ -- source.lua
1249
+ function luaFn()
1250
+ error('lua function error')
1251
+ end
1252
+ ```
1253
+
1254
+ ```ruby
1255
+ require 'sweet-moon'
1256
+ require 'sweet-moon/errors'
1257
+
1258
+ state = SweetMoon::State.new
1259
+
1260
+ state.load('source.lua')
1261
+
1262
+ lua_fn = state.get(:luaFn)
1263
+
1264
+ begin
1265
+ lua_fn.()
1266
+ rescue LuaRuntimeError => e
1267
+ puts e.message # => "source.lua:3: lua function error"
1268
+ end
1269
+ ```
1270
+
1271
+ For Fennel, all the examples above are equally true, with additional stack traceback as well.
1272
+
1010
1273
  ## Where can I find .so files?
1011
1274
 
1012
1275
  Due to the Lua's popularity, you likely have it already on your system, and _Sweet Moon_ will be able to find the files by itself.
@@ -1261,6 +1524,8 @@ Update the [`config/tests.yml`](https://github.com/gbaptista/sweet-moon/blob/mai
1261
1524
 
1262
1525
  Alternatively: Find or build the _Shared Objects_ for your Operating System on your own.
1263
1526
 
1527
+ Install the expected Lua _rocks_ described in `config/tests.yml`.
1528
+
1264
1529
  ### Running
1265
1530
 
1266
1531
  ```sh
data/components/api.rb CHANGED
@@ -2,7 +2,7 @@ require 'ffi'
2
2
 
3
3
  module Component
4
4
  API = {
5
- open!: ->(shared_objects) {
5
+ open!: ->(shared_objects, options = {}, default = {}) {
6
6
  api = Module.new
7
7
 
8
8
  api.extend FFI::Library
@@ -10,8 +10,11 @@ module Component
10
10
  # TODO: Lua Constants
11
11
  # attach_variable
12
12
 
13
- if shared_objects.size > 1
14
- # TODO: Dangerous
13
+ global_ffi = default[:global_ffi]
14
+
15
+ global_ffi = options[:global_ffi] unless options[:global_ffi].nil?
16
+
17
+ if global_ffi
15
18
  api.ffi_lib_flags(:global, :now)
16
19
  else
17
20
  api.ffi_lib_flags(:local, :now)
@@ -0,0 +1,17 @@
1
+ require 'singleton'
2
+
3
+ module Component
4
+ class Default
5
+ include Singleton
6
+
7
+ attr_reader :options
8
+
9
+ def initialize
10
+ @options = { global_ffi: true }
11
+ end
12
+
13
+ def set(key, value)
14
+ @options[key.to_sym] = value
15
+ end
16
+ end
17
+ end
@@ -6,7 +6,8 @@ module Component
6
6
  ffi: [:cfunction, [:pointer], :int],
7
7
  overwrite: {
8
8
  lua_pushcclosure: [%i[pointer cfunction int], :void],
9
- lua_tocfunction: [%i[pointer int], :cfunction]
9
+ lua_tocfunction: [%i[pointer int], :cfunction],
10
+ lua_atpanic: [%i[pointer cfunction], :cfunction]
10
11
  }
11
12
  }
12
13
  ],
@@ -6,7 +6,8 @@ module Component
6
6
  ffi: [:cfunction, [:pointer], :int],
7
7
  overwrite: {
8
8
  lua_pushcclosure: [%i[pointer cfunction int], :void],
9
- lua_tocfunction: [%i[pointer int], :cfunction]
9
+ lua_tocfunction: [%i[pointer int], :cfunction],
10
+ lua_atpanic: [%i[pointer cfunction], :cfunction]
10
11
  }
11
12
  }
12
13
  ],
@@ -6,7 +6,8 @@ module Component
6
6
  ffi: [:cfunction, [:pointer], :int],
7
7
  overwrite: {
8
8
  lua_pushcclosure: [%i[pointer cfunction int], :void],
9
- lua_tocfunction: [%i[pointer int], :cfunction]
9
+ lua_tocfunction: [%i[pointer int], :cfunction],
10
+ lua_atpanic: [%i[pointer cfunction], :cfunction]
10
11
  }
11
12
  }
12
13
  ],
@@ -1,55 +1,19 @@
1
- require_relative '../../../logic/interpreters/interpreter_50'
2
- require_relative '../../../dsl/errors'
3
-
4
- require_relative 'writer'
5
- require_relative 'reader'
1
+ require_relative '../54/function'
6
2
 
7
3
  module Component
8
4
  module V50
9
- Function = {
10
- push!: ->(api, state, closure) {
11
- handler = ->(current_state) {
12
- updated_state = state.merge(lua: current_state)
13
- input = Reader[:read_all!].(api, updated_state)
14
- result = closure.(*input)
15
- Writer[:push!].(api, updated_state, result)
16
- return 1
17
- }
18
-
19
- state[:avoid_gc] << handler
20
-
21
- api.lua_pushcclosure(state[:lua], handler, 0)
22
- },
23
-
24
- read!: ->(api, state, _stack_index) {
25
- reference = api.luaL_ref(
26
- state[:lua], Logic::V50::Interpreter[:LUA_REGISTRYINDEX]
27
- )
28
-
29
- { value: ->(input = [], output = 1) {
30
- api.lua_rawgeti(
31
- state[:lua], Logic::V50::Interpreter[:LUA_REGISTRYINDEX], reference
32
- )
33
-
34
- input.each do |value|
35
- Writer[:push!].(api, state, value)
36
- end
37
-
38
- result = Interpreter[:call!].(api, state, input.size, output)
39
-
40
- if result[:error]
41
- raise SweetMoon::Errors::SweetMoonErrorHelper.for(
42
- result[:error][:status]
43
- ), result[:error][:value]
44
- end
45
-
46
- result = Reader[:read_all!].(api, state)
47
-
48
- return result.first if output == 1
49
-
50
- result
51
- }, pop: false }
52
- }
53
- }
5
+ Function = Component::V54::Function
6
+
7
+ LUA_HANDLER = <<~LUA
8
+ return function (...)
9
+ result = _ruby(unpack(arg))
10
+
11
+ if result['error'] then
12
+ error(result['output'])
13
+ else
14
+ return result['output']
15
+ end
16
+ end
17
+ LUA
54
18
  end
55
19
  end
@@ -1,17 +1,19 @@
1
1
  require_relative '../../../logic/interpreters/interpreter_50'
2
2
 
3
+ require_relative 'function'
3
4
  require_relative 'reader'
4
- require_relative 'writer'
5
5
  require_relative 'table'
6
+ require_relative 'writer'
6
7
 
7
8
  module Component
8
9
  module V50
9
10
  Interpreter = {
10
11
  version: Logic::V50::Interpreter[:version],
12
+ logic: Logic::V50,
11
13
 
12
14
  create_state!: ->(api) {
13
15
  state = api.lua_open
14
- { state: { lua: state, avoid_gc: [] },
16
+ { state: { lua: state, avoid_gc: [], ruby_error_info: nil },
15
17
  error: state ? nil : :MemoryAllocation }
16
18
  },
17
19
 
@@ -48,7 +50,7 @@ module Component
48
50
  },
49
51
 
50
52
  push_value!: ->(api, state, value) {
51
- Writer[:push!].(api, state, value)
53
+ Writer[:push!].(api, state, Component::V50, value)
52
54
  { state: state }
53
55
  },
54
56
 
@@ -70,7 +72,10 @@ module Component
70
72
  api.lua_pushstring(state[:lua], variable.to_s)
71
73
  api.lua_gettable(state[:lua], Logic::V50::Interpreter[:LUA_GLOBALSINDEX])
72
74
 
73
- Table[:read_field_and_push!].(api, state, key, -1) unless key.nil?
75
+ unless key.nil?
76
+ Table[:read_field_and_push!].(api, state, Component::V50, key,
77
+ -1)
78
+ end
74
79
 
75
80
  { state: state, extra_pop: extra_pop }
76
81
  },
@@ -81,7 +86,8 @@ module Component
81
86
  },
82
87
 
83
88
  read_and_pop!: ->(api, state, stack_index = -1, extra_pop: false) {
84
- result = Component::V50::Reader[:read!].(api, state, stack_index)
89
+ result = Component::V50::Reader[:read!].(api, state, Component::V50,
90
+ stack_index)
85
91
 
86
92
  api.lua_settop(state[:lua], -2) if result[:pop]
87
93
  api.lua_settop(state[:lua], -2) if extra_pop
@@ -90,7 +96,7 @@ module Component
90
96
  },
91
97
 
92
98
  read_all!: ->(api, state) {
93
- result = Reader[:read_all!].(api, state)
99
+ result = Reader[:read_all!].(api, state, Component::V50)
94
100
 
95
101
  { state: state, output: result }
96
102
  },