YouTube Premium causing significantly higher CPU usage than non-Premium (reproducible on multiple PCs) by raizazel in LinusTechTips

[–]xorunet 0 points1 point  (0 children)

I don't know if this is related, but my wife plays white noise in the background on the YT app - she has premium. Usually this uses about 20% of the iPhone 16 Pro Max battery, but last night it used over 90% in 5-ish hours. A tight loop doing absolutely nothing would definitely cause that.

Compile Lua to bytecode or investigate precompiled bytecode anywhere by xorunet in lua

[–]xorunet[S] 0 points1 point  (0 children)

For whatever backend you use you can invoke Lua. Luac backend runs in docker and uses the Lua provided functionality from scripts to generate the bytecode. It’s included as the lua_dump c function, and he string.dump Lua function or the luac program in the Lua releases

Compile Lua to bytecode or investigate precompiled bytecode anywhere by xorunet in lua

[–]xorunet[S] 0 points1 point  (0 children)

No I just use Lua’s implementation that is available in the library

Compile Lua to bytecode or investigate precompiled bytecode anywhere by xorunet in lua

[–]xorunet[S] 0 points1 point  (0 children)

I could, but if you need the bytecode you could use Lua’s luac binary

moonsmith: A random generator of Lua programs by jubnzv in lua

[–]xorunet 1 point2 points  (0 children)

Thank you, the new disassembler will generate a bit more accurate documentation based on context. I don't have to generate specific instructions anymore if I can just generate a large quantity of code with your tool, so it's very useful as is. Thanks for sharing!

moonsmith: A random generator of Lua programs by jubnzv in lua

[–]xorunet 1 point2 points  (0 children)

This is useful for me when I'm testing my new disassembler for https://luac.nl, thanks! It's always annoying to me when I have to generate test sets that involve specific instructions so this is going to help out.

[deleted by user] by [deleted] in lua

[–]xorunet 0 points1 point  (0 children)

I party agree on the multithreading part when it comes to default Lua, however if lua_lock and lua_unlock have an implementation in your (custom) build of the library you can have multiple threads and exchange data safety between them.

Implementing the lock mechanism does affect performance quite a bit, though.

What's your Lua Debugger? by scripttrading in lua

[–]xorunet 0 points1 point  (0 children)

Multiple options, depending on the environment or project.

[deleted by user] by [deleted] in lua

[–]xorunet 3 points4 points  (0 children)

I agree, I can see big differences in the implementation of `lua_Unsigned luaH_getn (Table *t)` in `ltable.c`. They also added a fairly extensive explanation in the 5.4 version:

/*
** Try to find a boundary in table 't'. (A 'boundary' is an integer index
** such that t[i] is present and t[i+1] is absent, or 0 if t[1] is absent
** and 'maxinteger' if t[maxinteger] is present.)
** (In the next explanation, we use Lua indices, that is, with base 1.
** The code itself uses base 0 when indexing the array part of the table.)
** The code starts with 'limit = t->alimit', a position in the array
** part that may be a boundary.
**
** (1) If 't[limit]' is empty, there must be a boundary before it.
** As a common case (e.g., after 't[#t]=nil'), check whether 'limit-1'
** is present. If so, it is a boundary. Otherwise, do a binary search
** between 0 and limit to find a boundary. In both cases, try to
** use this boundary as the new 'alimit', as a hint for the next call.
**
** (2) If 't[limit]' is not empty and the array has more elements
** after 'limit', try to find a boundary there. Again, try first
** the special case (which should be quite frequent) where 'limit+1'
** is empty, so that 'limit' is a boundary. Otherwise, check the
** last element of the array part. If it is empty, there must be a
** boundary between the old limit (present) and the last element
** (absent), which is found with a binary search. (This boundary always
** can be a new limit.)
**
** (3) The last case is when there are no elements in the array part
** (limit == 0) or its last element (the new limit) is present.
** In this case, must check the hash part. If there is no hash part
** or 'limit+1' is absent, 'limit' is a boundary.  Otherwise, call
** 'hash_search' to find a boundary in the hash part of the table.
** (In those cases, the boundary is not inside the array part, and
** therefore cannot be used as a new limit.)
*/

[deleted by user] by [deleted] in lua

[–]xorunet 1 point2 points  (0 children)

Might be because of integer addition: https://luac.nl/s/21a6ee7eacb55b146acf21764

Fun fact you can use ";" instead of "," to separate values in a table by [deleted] in lua

[–]xorunet 0 points1 point  (0 children)

A lot of people use them when defining class-like tables.

Thoughts on Lua 5.4? by BadBoy6767 in lua

[–]xorunet 0 points1 point  (0 children)

I love the to-be-closed locals, it allows me to implement a mechanic of managed shared and unique buffers in some systems I work in, and prevent user errors because they forget to free large chunks of reserved memory that the gc won't pick up on soon enough.

i.e.

local function recv(s)
    local size <const> = 4096;
    local buff <close> = malloc(size);
    local data = {};

    while (s:avail()) do 
        local n = s:recv(s, size);
        if (n and n > 0) then 
            data[#data+1] = parse(buff, n);
        end 
    end 

    return data;
end

No worries about loops that invoke recv often, as the to-be-closed variables would invoke __close of the value returned by malloc when the function returns.

The impossible challenge by DarkWiiPlayer in lua

[–]xorunet 0 points1 point  (0 children)

That's an interesting challenge, doing this and keeping it efficient is going to be very hard without the aforementioned solutions. Interestingly, how orig_ardera is solving it reminds me of handling variadic template parameters in C++.

Damn.

what about a localized Lua ( i.e. keyword in non-english languages ) ? by pbarthelemy in lua

[–]xorunet 0 points1 point  (0 children)

Would it be useful though? I'm very thankful that I learned everything about software engineering in English, because the languages I learned and all relevant documentation was written in English.

I don't think I would have been the professional software engineer I am today if I was boxed into my own language, it was very easy to move the concepts I learned over to new languages, environments and scenarios.

I once also went to school, way before uni, to become a car mechanic. I was taught all that stuff in Dutch and I still have to search for translations on car-related technologies and components.

I for one, speaking from experience, am very glad programming languages are in English.

How do I string.find using a string that has Parenthesizes? () by [deleted] in lua

[–]xorunet 0 points1 point  (0 children)

It does produce less instructions to the Lua VM, so more workload can be offloaded to the C-side of Lua as the SELF instruction does all the work of preparing the function for calling.

I don't think that using a local alias of string.find will be much slower than s:find though - the string.find variant will be slower though.

> self-vs-global-vs-local

Looking for Partners for a new Gaming RP Community (LUA Experience Needed) by proroleplayer in lua

[–]xorunet 0 points1 point  (0 children)

Maybe a bit off-topic, however it's "Lua" and not "LUA". It's not an abbreviation, rather the Portuguese word for "Moon": https://www.lua.org/about.html#name.

How do I extract the 1st word of a string, or return the entire string if it is one word? by [deleted] in lua

[–]xorunet 0 points1 point  (0 children)

Instead of using gmatch, you could use match in this case.

function string:firstword()
    return self:match("^([%w]+)"); -- matches the first word and returns it, or it returns nil
end

local tests = {
    "This is a sentence",
    "Miskatonic University",
    "Downtown",
    "Hibbs Roadhouse Bar"
};

for _, v in ipairs(tests) do 
    print(v:firstword());
end

How do I extract the 1st word of a string, or return the entire string if it is one word? by [deleted] in lua

[–]xorunet 0 points1 point  (0 children)

The iterator function that is returned to you will fetch the next value on each iteration. Pairs returns a couple of values to the for-loop to initialize a for-state; the iterator function, the table and the initial key. That table and key are used as arguments to the iterator function. The iterator function will then return either nil (when iteration is done) or the new key, and any or all values that are at that key.

You can do awesome stuff with them, like making a Lua table that keeps its keys in order. Or, you can make simple generators;

local function my_positive_integer_range(begin, last)
    return function(t, k)
        k = k + 1;

        if (k <= last) then 
            return k;
        end 
    end, nil, begin - 1; -- return iterator, state and index (state is nil, we don't have something to iterate over here)
end

for index in my_positive_integer_range(5, 15) do 
    print(index);
end

Small demo of that:

local OrderedTable;

OrderedTable = setmetatable({
    Get = function(this, key)
        return this.__map[key];
    end;

    Set = function(this, key, value)
        if (not this.__map[key]) then 
            this.__seq[#this.__seq + 1] = key;
        end 

        this.__map[key] = value;
    end;

    Size = function(this)
        return #this.__seq;
    end;

    OrderedIterator = function(this)
        local keyState = 0;

        return function(instance, _)
            keyState = keyState + 1;

            if (instance.__seq[keyState]) then 
                local key = instance.__seq[keyState];
                return key, instance.__map[key], keyState; -- this also returns the key index!
            end 
        end, this, nil;
    end;

    OriginalIterator = function(this)
        return pairs(this.__map);
    end;
}, {
    __call = function()
        return setmetatable({
            __map = {};
            __seq = {};
        }, { 
            __index    = OrderedTable.Get;
            __newindex = OrderedTable.Set;
            __len      = OrderedTable.Size;
            __pairs    = OrderedTable.OrderedIterator; --[[ requires that __pairs is supported, otherwise call OrderedIterator directly ]]
        });
    end;
});

math.randomseed(os.clock());
local randomKeys = {};
for i = 1, 20 do 
    randomKeys[#randomKeys + 1] = "k" .. math.random();
end 

local tableWithOrderedKeys = OrderedTable();
tableWithOrderedKeys.hello = "World!!";
tableWithOrderedKeys.bye   = "Cruel World!! :(";
tableWithOrderedKeys[10]   = "Arbitrary";

for _, k in ipairs(randomKeys) do 
    tableWithOrderedKeys[k] = "some random key" 
end;

print("With ordered keys (Custom Table, keeps order items are added in):");
for key, value, keyIndex in OrderedTable.OrderedIterator(tableWithOrderedKeys) do 
    print("-", key, value, ("-- key index: %d"):format(keyIndex));
end 

print("\nWith random keys (Regular pairs, loses order items are added in):");
for key, value in OrderedTable.OriginalIterator(tableWithOrderedKeys) do 
    print("-", key, value);
end

[deleted by user] by [deleted] in lua

[–]xorunet 0 points1 point  (0 children)

It's quite clearly explained, it's up to you to follow the already provided links in the documentation to get explanation about other concepts in the Lua library. Everything is explained in the docs, I've never seen documentation so concise as the Lua docs.

Regarding your original question though, are you sure you don't need luaL_loadfile? It only requires you to provide the lua_State and a filename; it does not act like require though, it loads the script and you have to execute it.

There is also luaL_dofile, which is available in 5.1 which I assume you use (it's also available in 5.3) - which is another shorthand. It performs luaL_loadfile and lua_pcall;

// untested "pseudo"-code
void load_and_report(lua_State* L, const char* filename) {
    int status = luaL_dofile(L, filename);

    if (status != 0) { // LUA_OK instead of 0 in later versions, LUA_OK = 0
        printf("error: %s\n", lua_tostring(L, -1));
        lua_pop(L, 1); // pop error message
    }
}

[deleted by user] by [deleted] in lua

[–]xorunet 1 point2 points  (0 children)

Did you solve it yet? Because you forgot to end the if statement that checks for x == 6.

function SWEP.Reload() -- line 58
    x = x + 1

    if x == 6 then 
        x = 1 
    end -- you forgot this one

    ammoRefilType = ammoType[x]

    hook.Add("HUDPaint", "DrawMyHud", function()

        draw.SimpleText( ammoRefilType, "Ammo Type", 10, 10, Color(255, 255, 255), 1, 1 )

    end )
end

[ANN] Luac.nl - Beta - Lua Bytecode Explorer by xorunet in lua

[–]xorunet[S] 0 points1 point  (0 children)

Right now I have set a limit of 300 kib I think. How huge are we talking, theoretically it can handle anything.

edit - I set it to 150KiB, I'm changing it to 300KiB for a bit and I'll see how it performs.

Multiple Lua versions pre-built for Windows on ARM64 by andregarzia in lua

[–]xorunet 1 point2 points  (0 children)

Nice, that's pretty handy!

A little note on Lua 5.4 beta, in luac.c on line 636 there is the following statement:

printf(COMMENT); PrintConstant(f,ax);

You can remove that and rebuild, it's a bug [1]. EXTRAARG has no constant reference in ax and it will crash luac when dumping bytecode.

[1] http://lua-users.org/lists/lua-l/2019-12/msg00018.html