Memory

Functions for allocating, reading, writing, and freeing memory buffers.

m.alloc

Signature: m.alloc(size)

Description: Allocates a memory block of the specified size and returns a handle to it.

Parameters:

  • size (number): The size of the memory block to allocate in bytes.

Returns:

  • handle: A handle to the allocated memory block, or nil if allocation failed.

Example:

-- Allocate a memory buffer of 1024 bytes
local buffer = m.alloc(1024)

if buffer then
    engine.log("Memory allocation successful", 0, 255, 0, 255)
    
    -- Use the buffer...
    
    -- Free the buffer when done
    m.free(buffer)
else
    engine.log("Memory allocation failed", 255, 0, 0, 255)
end

m.free

Signature: m.free(handle)

Description: Frees a previously allocated memory block.

Parameters:

  • handle (handle): The handle to the memory block to free.

Returns: None

Example:

-- Allocate memory
local buffer = m.alloc(2048)

if buffer then
    -- Use the buffer...
    m.write_int32(buffer, 0, 12345)
    
    -- Free the memory when done
    m.free(buffer)
    engine.log("Memory freed successfully", 0, 255, 0, 255)
    
    -- IMPORTANT: Do not use the buffer handle after freeing it!
    -- This would cause undefined behavior or crashes
    -- m.read_int32(buffer, 0)  -- DON'T do this after freeing
end

m.read_double

Signature: m.read_double(handle, offset)

Description: Reads a 64-bit floating-point number (double) from the specified memory buffer at the given offset.

Parameters:

  • handle (handle): The handle to the memory buffer.

  • offset (number): The byte offset where the double value starts.

Returns:

  • number: The double value read from memory.

Example:

-- Allocate a buffer to store a double value
local buffer = m.alloc(8)  -- Double is 8 bytes

if buffer then
    -- Write a double value to the buffer
    m.write_double(buffer, 0, 3.14159265359)
    
    -- Read the double value back
    local value = m.read_double(buffer, 0)
    engine.log("Read double value: " .. value, 255, 255, 255, 255)
    
    -- Free the buffer when done
    m.free(buffer)
end

m.read_float

Signature: m.read_float(handle, offset)

Description: Reads a 32-bit floating-point number (float) from the specified memory buffer at the given offset.

Parameters:

  • handle (handle): The handle to the memory buffer.

  • offset (number): The byte offset where the float value starts.

Returns:

  • number: The float value read from memory.

Example:

-- Allocate a buffer to store a float value
local buffer = m.alloc(4)  -- Float is 4 bytes

if buffer then
    -- Write a float value to the buffer
    m.write_float(buffer, 0, 2.7182818)
    
    -- Read the float value back
    local value = m.read_float(buffer, 0)
    engine.log("Read float value: " .. value, 255, 255, 255, 255)
    
    -- Free the buffer when done
    m.free(buffer)
end

m.read_int64

Signature: m.read_int64(handle, offset)

Description: Reads a 64-bit integer from the specified memory buffer at the given offset.

Parameters:

  • handle (handle): The handle to the memory buffer.

  • offset (number): The byte offset where the 64-bit integer starts.

Returns:

  • number: The 64-bit integer value read from memory.

Example:

-- Allocate a buffer to store a 64-bit integer
local buffer = m.alloc(8)  -- Int64 is 8 bytes

if buffer then
    -- Write a 64-bit integer value to the buffer
    m.write_int64(buffer, 0, 1234567890123456)
    
    -- Read the 64-bit integer value back
    local value = m.read_int64(buffer, 0)
    engine.log("Read int64 value: " .. value, 255, 255, 255, 255)
    
    -- Free the buffer when done
    m.free(buffer)
end

m.read_int32

Signature: m.read_int32(handle, offset)

Description: Reads a 32-bit integer from the specified memory buffer at the given offset.

Parameters:

  • handle (handle): The handle to the memory buffer.

  • offset (number): The byte offset where the 32-bit integer starts.

Returns:

  • number: The 32-bit integer value read from memory.

Example:

-- Allocate a buffer to store a 32-bit integer
local buffer = m.alloc(4)  -- Int32 is 4 bytes

if buffer then
    -- Write a 32-bit integer value to the buffer
    m.write_int32(buffer, 0, 42)
    
    -- Read the 32-bit integer value back
    local value = m.read_int32(buffer, 0)
    engine.log("Read int32 value: " .. value, 255, 255, 255, 255)
    
    -- Free the buffer when done
    m.free(buffer)
end

m.read_int16

Signature: m.read_int16(handle, offset)

Description: Reads a 16-bit integer from the specified memory buffer at the given offset.

Parameters:

  • handle (handle): The handle to the memory buffer.

  • offset (number): The byte offset where the 16-bit integer starts.

Returns:

  • number: The 16-bit integer value read from memory.

Example:

-- Allocate a buffer to store multiple values
local buffer = m.alloc(8)  -- Allocate space for multiple values

if buffer then
    -- Write a 16-bit integer value to the buffer at offset 2
    m.write_int16(buffer, 2, 12345)
    
    -- Read the 16-bit integer value back
    local value = m.read_int16(buffer, 2)
    engine.log("Read int16 value: " .. value, 255, 255, 255, 255)
    
    -- Free the buffer when done
    m.free(buffer)
end

m.read_int8

Signature: m.read_int8(handle, offset)

Description: Reads an 8-bit integer from the specified memory buffer at the given offset.

Parameters:

  • handle (handle): The handle to the memory buffer.

  • offset (number): The byte offset where the 8-bit integer starts.

Returns:

  • number: The 8-bit integer value read from memory.

Example:

-- Allocate a buffer to store a byte array
local buffer = m.alloc(4)  -- Allocate 4 bytes

if buffer then
    -- Write byte values to different offsets in the buffer
    m.write_int8(buffer, 0, 65)  -- ASCII 'A'
    m.write_int8(buffer, 1, 66)  -- ASCII 'B'
    m.write_int8(buffer, 2, 67)  -- ASCII 'C'
    m.write_int8(buffer, 3, 0)   -- Null terminator
    
    -- Read the byte values back
    local a = m.read_int8(buffer, 0)
    local b = m.read_int8(buffer, 1)
    local c = m.read_int8(buffer, 2)
    
    engine.log("Read bytes: " .. a .. ", " .. b .. ", " .. c, 255, 255, 255, 255)
    engine.log("As ASCII: " .. string.char(a, b, c), 255, 255, 255, 255)
    
    -- Or read as a string
    local str = m.read_string(buffer, 0)
    engine.log("Read string: " .. str, 255, 255, 255, 255)
    
    -- Free the buffer when done
    m.free(buffer)
end

m.read_string

Signature: m.read_string(handle, offset)

Description: Reads a null-terminated string from the specified memory buffer at the given offset.

Parameters:

  • handle (handle): The handle to the memory buffer.

  • offset (number): The byte offset where the string starts.

Returns:

  • string: The string read from memory.

Example:

-- Allocate a buffer for storing a string
local buffer = m.alloc(32)  -- Allocate 32 bytes for a string

if buffer then
    -- Write a string to the buffer (including null terminator)
    m.write_string(buffer, 0, "Hello, World!")
    
    -- Read the string back
    local str = m.read_string(buffer, 0)
    engine.log("Read string: " .. str, 255, 255, 255, 255)
    
    -- Free the buffer when done
    m.free(buffer)
end

m.read_wide_string

Signature: m.read_wide_string(handle, offset)

Description: Reads a null-terminated wide (UTF-16) string from the specified memory buffer at the given offset.

Parameters:

  • handle (handle): The handle to the memory buffer.

  • offset (number): The byte offset where the wide string starts.

Returns:

  • string: The wide string read from memory, converted to a Lua UTF-8 string.

Example:

-- Allocate a buffer for storing a wide string
local buffer = m.alloc(32)  -- Allocate 32 bytes for a string (16 UTF-16 characters)

if buffer then
    -- Write a wide string to the buffer
    m.write_wide_string(buffer, 0, "Hello, 世界!")
    
    -- Read the wide string back
    local str = m.read_wide_string(buffer, 0)
    engine.log("Read wide string: " .. str, 255, 255, 255, 255)
    
    -- Free the buffer when done
    m.free(buffer)
end

m.write_double

Signature: m.write_double(handle, offset, value)

Description: Writes a 64-bit floating-point number (double) to the specified memory buffer at the given offset.

Parameters:

  • handle (handle): The handle to the memory buffer.

  • offset (number): The byte offset where the double value should be written.

  • value (number): The double value to write.

Returns: None

Example:

-- Allocate a buffer for multiple doubles
local buffer = m.alloc(16)  -- Allocate 16 bytes (2 doubles)

if buffer then
    -- Write two double values to the buffer
    m.write_double(buffer, 0, 3.14159265359)  -- Pi
    m.write_double(buffer, 8, 2.71828182846)  -- e
    
    -- Read the values back to verify
    local pi = m.read_double(buffer, 0)
    local e = m.read_double(buffer, 8)
    
    engine.log("Pi: " .. pi, 255, 255, 255, 255)
    engine.log("e: " .. e, 255, 255, 255, 255)
    
    -- Free the buffer when done
    m.free(buffer)
end

m.write_float

Signature: m.write_float(handle, offset, value)

Description: Writes a 32-bit floating-point number (float) to the specified memory buffer at the given offset.

Parameters:

  • handle (handle): The handle to the memory buffer.

  • offset (number): The byte offset where the float value should be written.

  • value (number): The float value to write.

Returns: None

Example:

-- Allocate a buffer for an array of floats
local float_count = 5
local buffer = m.alloc(float_count * 4)  -- Each float is 4 bytes

if buffer then
    -- Write a sequence of float values
    for i = 0, float_count-1 do
        m.write_float(buffer, i * 4, i * 1.5)
    end
    
    -- Read back all values
    for i = 0, float_count-1 do
        local value = m.read_float(buffer, i * 4)
        engine.log("Float at index " .. i .. ": " .. value, 255, 255, 255, 255)
    end
    
    -- Free the buffer when done
    m.free(buffer)
end

m.write_int64

Signature: m.write_int64(handle, offset, value)

Description: Writes a 64-bit integer to the specified memory buffer at the given offset.

Parameters:

  • handle (handle): The handle to the memory buffer.

  • offset (number): The byte offset where the 64-bit integer should be written.

  • value (number): The 64-bit integer value to write.

Returns: None

Example:

-- Allocate a buffer for a 64-bit integer
local buffer = m.alloc(8)  -- Int64 is 8 bytes

if buffer then
    -- Write a 64-bit integer value
    local big_number = 9223372036854775807  -- Max int64 value
    m.write_int64(buffer, 0, big_number)
    
    -- Read the value back
    local value = m.read_int64(buffer, 0)
    engine.log("Int64 value: " .. value, 255, 255, 255, 255)
    
    -- Free the buffer when done
    m.free(buffer)
end

m.write_int32

Signature: m.write_int32(handle, offset, value)

Description: Writes a 32-bit integer to the specified memory buffer at the given offset.

Parameters:

  • handle (handle): The handle to the memory buffer.

  • offset (number): The byte offset where the 32-bit integer should be written.

  • value (number): The 32-bit integer value to write.

Returns: None

Example:

-- Allocate a buffer for multiple integers
local buffer = m.alloc(12)  -- Space for 3 int32 values

if buffer then
    -- Write integer values at different offsets
    m.write_int32(buffer, 0, 123)
    m.write_int32(buffer, 4, 456)
    m.write_int32(buffer, 8, 789)
    
    -- Read all values back
    local val1 = m.read_int32(buffer, 0)
    local val2 = m.read_int32(buffer, 4)
    local val3 = m.read_int32(buffer, 8)
    
    engine.log("Values: " .. val1 .. ", " .. val2 .. ", " .. val3, 255, 255, 255, 255)
    
    -- Free the buffer when done
    m.free(buffer)
end

m.write_int16

Signature: m.write_int16(handle, offset, value)

Description: Writes a 16-bit integer to the specified memory buffer at the given offset.

Parameters:

  • handle (handle): The handle to the memory buffer.

  • offset (number): The byte offset where the 16-bit integer should be written.

  • value (number): The 16-bit integer value to write.

Returns: None

Example:

-- Allocate a buffer for a struct with mixed data types
local buffer = m.alloc(8)

if buffer then
    -- Write 16-bit integers at different offsets
    m.write_int16(buffer, 0, 12345)  -- First int16
    m.write_int16(buffer, 2, -1)     -- Second int16 (negative value)
    m.write_int16(buffer, 4, 0)      -- Third int16
    m.write_int16(buffer, 6, 32767)  -- Fourth int16 (max positive value)
    
    -- Read the values back
    local val1 = m.read_int16(buffer, 0)
    local val2 = m.read_int16(buffer, 2)
    local val3 = m.read_int16(buffer, 4)
    local val4 = m.read_int16(buffer, 6)
    
    engine.log("Int16 values: " .. val1 .. ", " .. val2 .. ", " .. 
               val3 .. ", " .. val4, 255, 255, 255, 255)
    
    -- Free the buffer when done
    m.free(buffer)
end

m.write_int8

Signature: m.write_int8(handle, offset, value)

Description: Writes an 8-bit integer to the specified memory buffer at the given offset.

Parameters:

  • handle (handle): The handle to the memory buffer.

  • offset (number): The byte offset where the 8-bit integer should be written.

  • value (number): The 8-bit integer value to write.

Returns: None

Example:

-- Allocate a buffer for a byte array
local buffer = m.alloc(4)

if buffer then
    -- Write a sequence of bytes (RGBA color)
    m.write_int8(buffer, 0, 255)  -- Red
    m.write_int8(buffer, 1, 128)  -- Green
    m.write_int8(buffer, 2, 64)   -- Blue
    m.write_int8(buffer, 3, 255)  -- Alpha
    
    -- Read the color components back
    local r = m.read_int8(buffer, 0)
    local g = m.read_int8(buffer, 1)
    local b = m.read_int8(buffer, 2)
    local a = m.read_int8(buffer, 3)
    
    engine.log("RGBA Color: " .. r .. ", " .. g .. ", " .. b .. ", " .. a,
               r, g, b, a)
    
    -- Free the buffer when done
    m.free(buffer)
end

m.write_string

Signature: m.write_string(handle, offset, str)

Description: Writes a null-terminated string to the specified memory buffer at the given offset.

Parameters:

  • handle (handle): The handle to the memory buffer.

  • offset (number): The byte offset where the string should be written.

  • str (string): The string to write.

Returns: None

Example:

-- Allocate a buffer for a string
local buffer = m.alloc(64)  -- Allocate more than enough space

if buffer then
    -- Write a string to the buffer
    local message = "Hello from Lua!"
    m.write_string(buffer, 0, message)
    
    -- Read the string back
    local read_message = m.read_string(buffer, 0)
    engine.log("Written string: " .. read_message, 255, 255, 255, 255)
    
    -- Write another string at an offset
    m.write_string(buffer, 20, "Second string")
    
    -- Read the second string back
    local second_message = m.read_string(buffer, 20)
    engine.log("Second string: " .. second_message, 255, 255, 255, 255)
    
    -- Free the buffer when done
    m.free(buffer)
end

m.write_wide_string

Signature: m.write_wide_string(handle, offset, str)

Description: Writes a null-terminated wide (UTF-16) string to the specified memory buffer at the given offset.

Parameters:

  • handle (handle): The handle to the memory buffer.

  • offset (number): The byte offset where the wide string should be written.

  • str (string): The string to write (will be converted to UTF-16).

Returns: None

Example:

-- Allocate a buffer for a wide string
local buffer = m.alloc(64)  -- Allocate space for wide string

if buffer then
    -- Write a Unicode string to the buffer as a wide string
    local message = "Unicode Text: 你好, こんにちは, Привет"
    m.write_wide_string(buffer, 0, message)
    
    -- Read the wide string back
    local read_message = m.read_wide_string(buffer, 0)
    engine.log("Unicode string: " .. read_message, 255, 255, 255, 255)
    
    -- Free the buffer when done
    m.free(buffer)
end

m.get_size

Signature: m.get_size(handle)

Description: Returns the total size in bytes of the allocated memory buffer.

Parameters:

  • handle (handle): The handle to the memory buffer.

Returns:

  • number: The size of the buffer in bytes.

Example:

-- Allocate a buffer
local buffer_size = 1024
local buffer = m.alloc(buffer_size)

if buffer then
    -- Get the actual allocated size
    local size = m.get_size(buffer)
    
    engine.log("Requested " .. buffer_size .. " bytes, allocated " .. size .. " bytes", 
               255, 255, 255, 255)
    
    -- Use the buffer...
    
    -- Free the buffer when done
    m.free(buffer)
end

Last updated

Was this helpful?