Merge branch 'master' into merge

This commit is contained in:
Arseny Kapoulkine 2022-08-18 14:06:14 -07:00
commit d614f43ebe
6 changed files with 31 additions and 11 deletions

View File

@ -13,9 +13,7 @@ on:
jobs:
callgrind:
name: callgrind
strategy:
fail-fast: false
matrix:
os: [ubuntu-22.04]
benchResultsRepo:
@ -44,9 +42,9 @@ jobs:
run: |
python bench/bench.py --callgrind --vm "./luau-gcc -O2" | tee -a bench-gcc-output.txt
- name: Run benchmark (bench-clang)
- name: Run benchmark (bench)
run: |
python bench/bench.py --callgrind --vm "./luau -O2" | tee -a bench-clang-output.txt
python bench/bench.py --callgrind --vm "./luau -O2" | tee -a bench-output.txt
- name: Run benchmark (analyze)
run: |
@ -78,13 +76,13 @@ jobs:
token: ${{ secrets.BENCH_GITHUB_TOKEN }}
path: "./gh-pages"
- name: Store results (bench-clang)
- name: Store results (bench)
uses: Roblox/rhysd-github-action-benchmark@v-luau
with:
name: callgrind clang
tool: "benchmarkluau"
output-file-path: ./bench-clang-output.txt
external-data-json-path: ./gh-pages/bench-clang.json
output-file-path: ./bench-output.txt
external-data-json-path: ./gh-pages/bench.json
- name: Store results (bench-gcc)
uses: Roblox/rhysd-github-action-benchmark@v-luau

View File

@ -1209,7 +1209,10 @@ void* lua_newuserdatadtor(lua_State* L, size_t sz, void (*dtor)(void*))
{
luaC_checkGC(L);
luaC_checkthreadsleep(L);
Udata* u = luaU_newudata(L, sz + sizeof(dtor), UTAG_IDTOR);
size_t as = sz + sizeof(dtor);
if (as < sizeof(dtor))
as = SIZE_MAX; // Will cause a memory error in luaU_newudata.
Udata* u = luaU_newudata(L, as, UTAG_IDTOR);
memcpy(&u->data + sz, &dtor, sizeof(dtor));
setuvalue(L, L->top, u);
api_incr_top(L);

View File

@ -70,6 +70,7 @@ Sandboxing challenges are [covered in the dedicated section](sandbox).
| `bit32` library | ✔️ | |
| `string.gsub` is stricter about using `%` on special characters only | ✔️ | |
| light C functions | 😞 | this changes semantics of fenv on C functions and has complex implications wrt runtime performance |
| NaN keys are supported for tables with `__newindex` | ✔️ | |
Two things that are important to call out here are various new metamethods for tables and yielding in metamethods. In both cases, there are performance implications to supporting this - our implementation is *very* highly tuned for performance, so any changes that affect the core fundamentals of how Lua works have a price. To support yielding in metamethods we'd need to make the core of the VM more involved, since almost every single "interesting" opcode would need to learn how to be resumable - which also complicates future JIT/AOT story. Metamethods in general are important for extensibility, but very challenging to deal with in implementation, so we err on the side of not supporting any new metamethods unless a strong need arises.

View File

@ -326,7 +326,6 @@ Luau uses comments that start from `!` to control certain aspects of analysis, f
--!nostrict
-- Unknown comment directive 'nostrict'; did you mean 'nonstrict'?"
```
```
## IntegerParsing (27)

View File

@ -51,8 +51,10 @@ end
To support self-iterating objects, we modify the iteration protocol as follows: instead of simply expanding the result of expression `iter` into three variables (`gen`, `state` and `index`), we check if the first result has an `__iter` metamethod (which can be the case if it's a table, userdata or another composite object (e.g. a record in the future). If it does, the metamethod is called with `gen` as the first argument, and the returned three values replace `gen`/`state`/`index`. This happens *before* the loop:
```lua
if getmetatable(gen) and getmetatable(gen).__iter then
gen, state, index = getmetatable(gen).__iter(gen)
local genmt = rawgetmetatable(gen) -- pseudo code for getmetatable that bypasses __metatable
local iterf = genmt and rawget(genmt, "__iter")
if iterf then
gen, state, index = iterf(gen)
end
```

View File

@ -716,6 +716,23 @@ TEST_CASE("Reference")
CHECK(dtorhits == 2);
}
TEST_CASE("NewUserdataOverflow")
{
StateRef globalState(luaL_newstate(), lua_close);
lua_State* L = globalState.get();
lua_pushcfunction(L, [](lua_State* L1) {
// The following userdata request might cause an overflow.
lua_newuserdatadtor(L1, SIZE_MAX, [](void* d){});
// The overflow might segfault in the following call.
lua_getmetatable(L1, -1);
return 0;
}, "PCall");
CHECK(lua_pcall(L, 0, 0, 0) == LUA_ERRRUN);
CHECK(strcmp(lua_tostring(L, -1), "memory allocation error: block too big") == 0);
}
TEST_CASE("ApiTables")
{
StateRef globalState(luaL_newstate(), lua_close);