Class: Rufus::Lua::Table

Inherits:
Object
  • Object
show all
Defined in:
lib/immunio/rufus_lua_ext/table.rb

Instance Method Summary collapse

Instance Method Details

#[](k) ⇒ Object



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/immunio/rufus_lua_ext/table.rb', line 19

def [](k)
  # Push table onto stack
  load_onto_stack

  # Push key onto stack
  stack_push(k)

  # Fetches the value from the table, replaces the key at the top of the
  # stack with the value. At the end, the stack still has the table at -2.
  Lib.lua_gettable(@pointer, -2)

  # Pop value off stack
  v = stack_pop

  # Pop table off stack
  stack_pop # <= Memory leak fixed here

  v
end

#[]=(k, v) ⇒ Object



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/immunio/rufus_lua_ext/table.rb', line 41

def []=(k, v)
  # Push table onto stack
  load_onto_stack

  stack_push(k)
  stack_push(v)

  # For the VM heavy thread test, we need to cause out-of-order execution in
  # methods modifying the Lua stack. Here we tell Ruby to swap out threads
  # if we are in the thread test.
  Thread.pass if $IMMUNIO_IN_THREAD_TEST

  # Sets the key-value pair onto the table, then pops the key and value but
  # leaves the table on the stack
  Lib.lua_settable(@pointer, -3)

  # Pop table off stack
  stack_pop # <= Memory leak fixed here

  v
end

#fetch(key, default = nil) ⇒ Object

Method to behave like Hash#fetch.



4
5
6
7
8
9
10
11
# File 'lib/immunio/rufus_lua_ext/table.rb', line 4

def fetch(key, default=nil)
  value = self[key]
  if value.nil?
    default
  else
    value
  end
end

#has_key?(key) ⇒ Boolean

Returns:

  • (Boolean)


13
14
15
# File 'lib/immunio/rufus_lua_ext/table.rb', line 13

def has_key?(key)
  self.fetch(key) != nil
end

#objlenObject



65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/immunio/rufus_lua_ext/table.rb', line 65

def objlen
  # Push table onto stack
  load_onto_stack

  # Gets the length of the table, but leaves the table on the stack
  len = Lib.lua_objlen(@pointer, -1)

  # Pop table off stack
  stack_pop # <= Memory leak fixed here

  len
end

#to_hObject



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/immunio/rufus_lua_ext/table.rb', line 83

def to_h
  # Load table onto stack
  load_onto_stack

  # Get position of table on stack
  table_pos = stack_top

  # This is the starter for the lua_next iterator. Push a nil value as a
  # sentinel onto the stack. This tells lua_next to fetch the first key-
  # value pair from the table.
  Lib.lua_pushnil(@pointer)

  h = {}

  # Fetch the next key-value pair. The last key must be on the top of the
  # stack. The key on the stack will be overwritten with the next key
  # fetched from the table. The value will be pushed onto the stack after
  # the key.
  #
  # In order to iterate, the caller must pop the value off the stack.
  # lua_next then uses the current key, which is once again at the top of
  # the stack, to locate the next key.
  #
  # But! When there are no more key-value pairs, this call will remove the
  # key from the stack, leaving the table at the top.
  #
  # WARNING: Lua keys can be anything (yes, that includes a table). We do
  # not support tables as keys. Keys must be nice numbers or strings.
  while Lib.lua_next(@pointer, table_pos) != 0 do
    # Grab key and value from top of stack
    value = stack_fetch(-1)
    key = stack_fetch(-2)

    # Pop the value off the stack leaving the key on top
    stack_unstack

    # Recurse into table if needed
    if Table === value
      if value[1]
        h[key] = value.to_a
      else
        h[key] = value.to_h
      end
    else
      h[key] = value
    end
  end

  # Remove the table pushed onto the stack at the very beginning
  Lib.lua_remove(@pointer, table_pos)

  h
end