sweet-moon 0.0.4 → 0.0.5

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: 8e216a8bf96c191f08675bad6b2d4d9a1dceb9649a5e856ce4d6b4894e09b35e
4
+ data.tar.gz: b807eb9b92df1e53a0e0011f6132724c95b11a76dafab1073a46d2c5bf35c6ab
5
5
  SHA512:
6
- metadata.gz: 582a792771b05e59a577349070709e78bb2a569ef14cdb955fb2666e826eb401ba4aa4e7b19297c30fd64f98eda244d656caf2e904f9c1af95e971807aed8820
7
- data.tar.gz: 38307987e564f998b40b2792fd97a3e107095d6e46992689663d63d67bf248dfc16c3a8838f8461bf7a8765857e7b5c04da4e4ac3c636cd6a419abb85bab2e5b
6
+ metadata.gz: 538a7a773c11fe66a13c0be49efeb1f8d37da83f52a85d32fe8a7c52b3b590d155b0cdfb50efec3755181947db6a7b67a238b31c10bc382362b70301594949fb
7
+ data.tar.gz: 95d84ea3cf24919e4646c766f66302308f22392434ba5f76b0ae7743d4ef9ad3868d90b13b3d4bf26d58d7500d276b88be7ee26393818cf00950f08f4e6c4fc6
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
@@ -32,6 +32,7 @@ _Sweet Moon_ is a resilient solution that makes working with [Lua](https://www.l
32
32
  - [Integration with fnx](#integration-with-fnx)
33
33
  - [Global vs Isolated](#global-vs-isolated)
34
34
  - [Error Handling](#error-handling)
35
+ - [Ruby feat. Lua Errors](#ruby-feat-lua-errors)
35
36
  - [Where can I find .so files?](#where-can-i-find-so-files)
36
37
  - [Low-Level C API](#low-level-c-api)
37
38
  - [The API](#the-api)
@@ -71,7 +72,7 @@ gem install sweet-moon
71
72
  > **Disclaimer:** It's an early-stage project, and you should expect breaking changes.
72
73
 
73
74
  ```ruby
74
- gem 'sweet-moon', '~> 0.0.4'
75
+ gem 'sweet-moon', '~> 0.0.5'
75
76
  ```
76
77
 
77
78
  ```ruby
@@ -612,21 +613,21 @@ state.add_package_path('/home/me/my-lua-modules/?/init.lua')
612
613
 
613
614
  state.add_package_cpath('/home/me/my-lua-modules/?.so')
614
615
 
615
- state.add_package_path('/home/me/fennel.lua')
616
+ state.add_package_path('/home/me/fennel/?.lua')
616
617
 
617
- state.add_package_cpath('/home/me/lib.so')
618
+ state.add_package_cpath('/home/me/?.so')
618
619
 
619
620
  state.package_path
620
621
  # => ['./?.lua',
621
622
  # './?/init.lua',
622
623
  # '/home/me/my-lua-modules/?.lua',
623
624
  # '/home/me/my-lua-modules/?/init.lua',
624
- # '/home/me/fennel.lua']
625
+ # '/home/me/fennel/?.lua']
625
626
 
626
627
  state.package_cpath
627
628
  # => ['./?.so',
628
629
  # '/home/me/my-lua-modules/?.so',
629
- # '/home/me/lib.so']
630
+ # '/home/me/?.so']
630
631
  ```
631
632
 
632
633
  Requiring a module:
@@ -646,8 +647,8 @@ You can set packages in State constructors:
646
647
  require 'sweet-moon'
647
648
 
648
649
  SweetMoon::State.new(
649
- package_path: '/folder/lib.lua',
650
- package_cpath: '/lib/lib.so',
650
+ package_path: '/folder/lib/?.lua',
651
+ package_cpath: '/lib/lib/?.so',
651
652
  )
652
653
  ```
653
654
 
@@ -657,8 +658,8 @@ Also, you can add packages through the global config:
657
658
  require 'sweet-moon'
658
659
 
659
660
  SweetMoon.global.config(
660
- package_path: '/folder/lib.lua',
661
- package_cpath: '/lib/lib.so',
661
+ package_path: '/folder/lib/?.lua',
662
+ package_cpath: '/lib/lib/?.so',
662
663
  )
663
664
  ```
664
665
 
@@ -831,7 +832,7 @@ require 'sweet-moon'
831
832
 
832
833
  state = SweetMoon::State.new
833
834
 
834
- state.add_package_path('/folder/fennel.lua')
835
+ state.add_package_path('/folder/fennel/?.lua')
835
836
 
836
837
  state.fennel.eval('(+ 1 1)') # => 2
837
838
  ```
@@ -841,7 +842,7 @@ With the constructor:
841
842
  ```ruby
842
843
  require 'sweet-moon'
843
844
 
844
- fennel = SweetMoon::State.new(package_path: '/folder/fennel.lua').fennel
845
+ fennel = SweetMoon::State.new(package_path: '/folder/fennel/?.lua').fennel
845
846
 
846
847
  fennel.eval('(+ 1 1)') # => 2
847
848
  ```
@@ -851,7 +852,7 @@ With global:
851
852
  ```ruby
852
853
  require 'sweet-moon'
853
854
 
854
- SweetMoon.global.state.add_package_path('/folder/fennel.lua')
855
+ SweetMoon.global.state.add_package_path('/folder/fennel/?.lua')
855
856
 
856
857
  SweetMoon.global.state.fennel.eval('(+ 1 1)') # => 2
857
858
  ```
@@ -861,7 +862,7 @@ Alternatively:
861
862
  ```ruby
862
863
  require 'sweet-moon'
863
864
 
864
- SweetMoon.global.config(package_path: '/folder/fennel.lua')
865
+ SweetMoon.global.config(package_path: '/folder/fennel/?.lua')
865
866
 
866
867
  SweetMoon.global.state.fennel.eval('(+ 1 1)') # => 2
867
868
  ```
@@ -1007,6 +1008,108 @@ rescue LuaRuntimeError => error
1007
1008
  end
1008
1009
  ```
1009
1010
 
1011
+ ### Ruby feat. Lua Errors
1012
+
1013
+ Lua errors can be rescued inside Ruby:
1014
+
1015
+ ```lua
1016
+ -- source.lua
1017
+ error('error from lua')
1018
+ ```
1019
+
1020
+ ```ruby
1021
+ require 'sweet-moon'
1022
+ require 'sweet-moon/errors'
1023
+
1024
+ state = SweetMoon::State.new
1025
+
1026
+ begin
1027
+ state.load('source.lua')
1028
+ rescue LuaRuntimeError => e
1029
+ puts e.message
1030
+ # => source.lua:2: error from lua
1031
+ end
1032
+ ```
1033
+
1034
+ Ruby errors can be handled inside Lua:
1035
+
1036
+ ```ruby
1037
+ require 'sweet-moon'
1038
+
1039
+ state = SweetMoon::State.new
1040
+
1041
+ state.set(:rubyFn, -> { raise 'error from ruby' })
1042
+
1043
+ state.load('source.lua')
1044
+ ```
1045
+
1046
+ ```lua
1047
+ -- source.lua
1048
+ local status, err = pcall(rubyFn)
1049
+
1050
+ print(status) -- => false
1051
+
1052
+ print(err)
1053
+ -- [string " return function (...)..."]:5: RuntimeError: error from ruby stack traceback:
1054
+ -- [string " return function (...)..."]:5: in function 'rubyFn'
1055
+ -- [C]: in function 'pcall'
1056
+ -- source.lua:2: in main chunk
1057
+ ```
1058
+
1059
+ Ruby errors not handled inside Lua can be rescued inside Ruby again, with an additional Lua backtrace:
1060
+
1061
+ ```lua
1062
+ -- source.lua
1063
+ a = 1
1064
+
1065
+ rubyFn()
1066
+ ```
1067
+
1068
+ ```ruby
1069
+ require 'sweet-moon'
1070
+
1071
+ state = SweetMoon::State.new
1072
+
1073
+ state.set(:rubyFn, -> { raise 'error from ruby' })
1074
+
1075
+ begin
1076
+ state.load('source.lua')
1077
+ rescue RuntimeError => e
1078
+ puts e.message # => error from ruby
1079
+
1080
+ puts e.backtrace.last
1081
+ # => source.lua:4: in main chunk
1082
+ end
1083
+ ```
1084
+
1085
+ Lua errors inside Lua functions can be rescued inside Ruby:
1086
+
1087
+ ```lua
1088
+ -- source.lua
1089
+ function luaFn()
1090
+ error('lua function error')
1091
+ end
1092
+ ```
1093
+
1094
+ ```ruby
1095
+ require 'sweet-moon'
1096
+ require 'sweet-moon/errors'
1097
+
1098
+ state = SweetMoon::State.new
1099
+
1100
+ state.load('source.lua')
1101
+
1102
+ lua_fn = state.get(:luaFn)
1103
+
1104
+ begin
1105
+ lua_fn.()
1106
+ rescue LuaRuntimeError => e
1107
+ puts e.message # => "source.lua:3: lua function error"
1108
+ end
1109
+ ```
1110
+
1111
+ For Fennel, all the examples above are equally true, with additional stack traceback as well.
1112
+
1010
1113
  ## Where can I find .so files?
1011
1114
 
1012
1115
  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.
@@ -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
  },
@@ -1,67 +1,7 @@
1
- require 'ffi'
2
-
3
- require_relative 'interpreter'
4
- require_relative 'function'
5
- require_relative 'table'
1
+ require_relative '../54/reader'
6
2
 
7
3
  module Component
8
4
  module V50
9
- Reader = {
10
- read_all!: ->(api, state) {
11
- (1..api.lua_gettop(state[:lua])).map do
12
- Interpreter[:read_and_pop!].(api, state)[:output]
13
- end.reverse
14
- },
15
-
16
- read!: ->(api, state, stack_index = -1) {
17
- stack_index = api.lua_gettop(state[:lua]) if stack_index == -1
18
-
19
- type = api.lua_typename(state[:lua],
20
- api.lua_type(state[:lua], stack_index)).read_string
21
-
22
- case type
23
- when 'string'
24
- Reader[:read_string!].(api, state, stack_index)
25
- when 'number'
26
- Reader[:read_number!].(api, state, stack_index)
27
- when 'no value'
28
- { value: nil, pop: true, type: type }
29
- when 'nil'
30
- { value: nil, pop: true }
31
- when 'boolean'
32
- Reader[:read_boolean!].(api, state, stack_index)
33
- when 'table'
34
- Table[:read!].(api, state, stack_index)
35
- when 'function'
36
- Function[:read!].(api, state, stack_index)
37
- else
38
- # none nil boolean lightuserdata number
39
- # string table function userdata thread
40
- { value:
41
- "#{type}: 0x#{api.lua_topointer(state[:lua], stack_index).address}",
42
- type: type, pop: true }
43
- end
44
- },
45
-
46
- read_string!: ->(api, state, stack_index) {
47
- { value: api.lua_tostring(state[:lua], stack_index).read_string,
48
- pop: true }
49
- },
50
-
51
- read_number!: ->(api, state, stack_index) {
52
- if api.respond_to?(:lua_isinteger) &&
53
- api.respond_to?(:lua_tointeger) &&
54
- api.lua_isinteger(state[:lua], stack_index) == 1
55
-
56
- return { value: api.lua_tointeger(state[:lua], stack_index), pop: true }
57
- end
58
-
59
- { value: api.lua_tonumber(state[:lua], stack_index), pop: true }
60
- },
61
-
62
- read_boolean!: ->(api, state, stack_index) {
63
- { value: api.lua_toboolean(state[:lua], stack_index) == 1, pop: true }
64
- }
65
- }
5
+ Reader = Component::V54::Reader
66
6
  end
67
7
  end
@@ -6,56 +6,19 @@ require_relative 'reader'
6
6
  module Component
7
7
  module V50
8
8
  Table = {
9
- push!: ->(api, state, list, stack_index = -1) {
10
- stack_index = api.lua_gettop(state[:lua]) if stack_index == -1
11
-
9
+ create_table!: ->(api, state, _list) {
12
10
  api.lua_newtable(state[:lua])
13
-
14
- if list.is_a? Hash
15
- list.each_key do |key|
16
- Writer[:push!].(api, state, key)
17
- Writer[:push!].(api, state, list[key])
18
- api.lua_settable(state[:lua], stack_index + 1)
19
- end
20
- else
21
- list.each_with_index do |value, index|
22
- Writer[:push!].(api, state, index + 1)
23
- Writer[:push!].(api, state, value)
24
- api.lua_settable(state[:lua], stack_index + 1)
25
- end
26
- end
27
11
  },
28
12
 
29
- read!: ->(api, state, stack_index) {
30
- stack_index = api.lua_gettop(state[:lua]) if stack_index == -1
31
-
32
- type = api.lua_typename(state[:lua],
33
- api.lua_type(state[:lua], stack_index)).read_string
34
-
35
- api.lua_pushnil(state[:lua])
36
-
37
- return nil if type != 'table'
38
-
39
- tuples = []
40
-
41
- while api.lua_next(state[:lua], stack_index).positive?
42
- value = Reader[:read!].(api, state, stack_index + 2)
43
- key = Reader[:read!].(api, state, stack_index + 1)
44
- api.lua_settop(state[:lua], -2) if value[:pop]
45
-
46
- tuples << [key[:value], value[:value]]
47
-
48
- break if value[:type] == 'no value' || key[:value].instance_of?(Proc)
49
- end
50
-
51
- { value: Logic::Tables[:to_hash_or_array].(tuples), pop: true }
52
- },
13
+ push!: Component::V54::Table[:push!],
14
+ read!: Component::V54::Table[:read!],
53
15
 
54
- read_field_and_push!: ->(api, state, expected_key, stack_index) {
16
+ read_field_and_push!: ->(api, state, component, expected_key, stack_index) {
55
17
  stack_index = api.lua_gettop(state[:lua]) if stack_index == -1
56
18
 
57
- type = api.lua_typename(state[:lua],
58
- api.lua_type(state[:lua], stack_index)).read_string
19
+ type = api.lua_typename(
20
+ state[:lua], api.lua_type(state[:lua], stack_index)
21
+ ).read_string
59
22
 
60
23
  api.lua_pushnil(state[:lua])
61
24
 
@@ -64,8 +27,8 @@ module Component
64
27
  result = nil
65
28
 
66
29
  while api.lua_next(state[:lua], stack_index).positive?
67
- value = Reader[:read!].(api, state, stack_index + 2)
68
- key = Reader[:read!].(api, state, stack_index + 1)
30
+ value = component::Reader[:read!].(api, state, component, stack_index + 2)
31
+ key = component::Reader[:read!].(api, state, component, stack_index + 1)
69
32
 
70
33
  api.lua_settop(state[:lua], -2) if value[:pop]
71
34
 
@@ -73,7 +36,7 @@ module Component
73
36
  state[:lua], api.lua_type(state[:lua], stack_index + 1)
74
37
  ).read_string
75
38
 
76
- if Table[:is_same_key].(key_type, key[:value], expected_key)
39
+ if component::Table[:is_same_key].(key_type, key[:value], expected_key)
77
40
  result = value[:value]
78
41
  break
79
42
  end
@@ -83,7 +46,7 @@ module Component
83
46
 
84
47
  api.lua_settop(state[:lua], -2)
85
48
 
86
- Writer[:push!].(api, state, result)
49
+ component::Writer[:push!].(api, state, component, result)
87
50
  },
88
51
 
89
52
  is_same_key: ->(lua_key_type, lua_key, ruby_key) {
@@ -1,45 +1,7 @@
1
- require_relative 'function'
2
- require_relative 'table'
1
+ require_relative '../54/writer'
3
2
 
4
3
  module Component
5
4
  module V50
6
- Writer = {
7
- push!: ->(api, state, value) {
8
- case Writer[:_to_lua_type].(value)
9
- when 'string'
10
- api.lua_pushstring(state[:lua], value.to_s)
11
- when 'number'
12
- api.lua_pushnumber(state[:lua], value)
13
- when 'integer'
14
- if api.respond_to? :lua_pushinteger
15
- api.lua_pushinteger(state[:lua], value)
16
- else
17
- api.lua_pushnumber(state[:lua], value)
18
- end
19
- when 'nil'
20
- api.lua_pushnil(state[:lua])
21
- when 'boolean'
22
- api.lua_pushboolean(state[:lua], value ? 1 : 0)
23
- when 'table'
24
- Table[:push!].(api, state, value)
25
- when 'function'
26
- Function[:push!].(api, state, value)
27
- else
28
- api.lua_pushstring(
29
- state[:lua], "#<#{value.class}:0x#{format('%016x', value.object_id)}>"
30
- )
31
- end
32
- },
33
-
34
- _to_lua_type: ->(value) {
35
- return 'nil' if value.nil?
36
- return 'function' if value.is_a?(Proc)
37
- return 'integer' if value.is_a? Integer
38
- return 'number' if value.is_a? Float
39
- return 'table' if value.is_a?(Hash) || value.is_a?(Array)
40
- return 'string' if value.is_a?(String) || value.instance_of?(Symbol)
41
- return 'boolean' if [true, false].include? value
42
- }
43
- }
5
+ Writer = Component::V54::Writer
44
6
  end
45
7
  end
@@ -1,55 +1,9 @@
1
- require_relative '../../../logic/interpreters/interpreter_51'
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 V51
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::V51::Interpreter[:LUA_REGISTRYINDEX]
27
- )
28
-
29
- { value: ->(input = [], output = 1) {
30
- api.lua_rawgeti(
31
- state[:lua], Logic::V51::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
5
+ Function = Component::V54::Function
49
6
 
50
- result
51
- }, pop: false }
52
- }
53
- }
7
+ LUA_HANDLER = Component::V54::LUA_HANDLER
54
8
  end
55
9
  end