sweet-moon 0.0.4 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
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
  },