mirror of
https://github.com/luau-lang/luau.git
synced 2024-11-15 22:35:43 +08:00
Merge remote-tracking branch 'origin/master' into merge
This commit is contained in:
commit
188ffdfdfb
@ -69,6 +69,7 @@ Sandboxing challenges are [covered in the dedicated section](sandbox).
|
|||||||
| `\0` in patterns | ✔️ | |
|
| `\0` in patterns | ✔️ | |
|
||||||
| `bit32` library | ✔️ | |
|
| `bit32` library | ✔️ | |
|
||||||
| `string.gsub` is stricter about using `%` on special characters only | ✔️ | |
|
| `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 |
|
||||||
|
|
||||||
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.
|
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.
|
||||||
|
|
||||||
|
97
docs/_posts/2022-06-01-luau-recap-may-2022.md
Normal file
97
docs/_posts/2022-06-01-luau-recap-may-2022.md
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
---
|
||||||
|
layout: single
|
||||||
|
title: "Luau Recap: May 2022"
|
||||||
|
---
|
||||||
|
|
||||||
|
This month Luau team has worked to bring you a new language feature together with more typechecking improvements and bugfixes!
|
||||||
|
|
||||||
|
[Cross-posted to the [Roblox Developer Forum](https://devforum.roblox.com/t/luau-recap-may-2022/).]
|
||||||
|
|
||||||
|
## Generalized iteration
|
||||||
|
|
||||||
|
We have extended the semantics of standard Lua syntax for iterating through containers, `for vars in values` with support for generalized iteration.
|
||||||
|
In Lua, to iterate over a table you need to use an iterator like `next` or a function that returns one like `pairs` or `ipairs`. In Luau, you can now simply iterate over a table:
|
||||||
|
|
||||||
|
```lua
|
||||||
|
for k, v in {1, 4, 9} do
|
||||||
|
assert(k * k == v)
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
This works for tables but can also be customized for tables or userdata by implementing `__iter` metamethod. It is called before the iteration begins, and should return an iterator function like `next` (or a custom one):
|
||||||
|
|
||||||
|
```lua
|
||||||
|
local obj = { items = {1, 4, 9} }
|
||||||
|
setmetatable(obj, { __iter = function(o) return next, o.items end })
|
||||||
|
|
||||||
|
for k, v in obj do
|
||||||
|
assert(k * k == v)
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
The default iteration order for tables is specified to be consecutive for elements `1..#t` and unordered after that, visiting every element.
|
||||||
|
Similar to iteration using `pairs`, modifying the table entries for keys other than the current one results in unspecified behavior.
|
||||||
|
|
||||||
|
## Typechecking improvements
|
||||||
|
|
||||||
|
We have added a missing check to compare implicit table keys against the key type of the table indexer:
|
||||||
|
|
||||||
|
```lua
|
||||||
|
-- error is correctly reported, implicit keys (1,2,3) are not compatible with [string]
|
||||||
|
local t: { [string]: boolean } = { true, true, false }
|
||||||
|
```
|
||||||
|
|
||||||
|
Rules for `==` and `~=` have been relaxed for union types, if any of the union parts can be compared, operation succeeds:
|
||||||
|
|
||||||
|
```lua
|
||||||
|
--!strict
|
||||||
|
local function compare(v1: Vector3, v2: Vector3?)
|
||||||
|
return v1 == v2 -- no longer an error
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
Table value type propagation now correctly works with `[any]` key type:
|
||||||
|
|
||||||
|
```lua
|
||||||
|
--!strict
|
||||||
|
type X = {[any]: string | boolean}
|
||||||
|
local x: X = { key = "str" } -- no longer gives an incorrect error
|
||||||
|
```
|
||||||
|
|
||||||
|
If a generic function doesn't provide type annotations for all arguments and the return value, additional generic type parameters might be added automatically:
|
||||||
|
|
||||||
|
```lua
|
||||||
|
-- previously it was foo<T>, now it's foo<T, b>, because second argument is also generic
|
||||||
|
function foo<T>(x: T, y) end
|
||||||
|
```
|
||||||
|
|
||||||
|
We have also fixed various issues that have caused crashes, with many of them coming from your bug reports.
|
||||||
|
|
||||||
|
## Linter improvements
|
||||||
|
|
||||||
|
`GlobalUsedAsLocal` lint warning has been extended to notice when global variable writes always happen before their use in a local scope, suggesting that they can be replaced with a local variable:
|
||||||
|
|
||||||
|
```lua
|
||||||
|
function bar()
|
||||||
|
foo = 6 -- Global 'foo' is never read before being written. Consider changing it to local
|
||||||
|
return foo
|
||||||
|
end
|
||||||
|
function baz()
|
||||||
|
foo = 10
|
||||||
|
return foo
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
## Performance improvements
|
||||||
|
|
||||||
|
Garbage collection CPU utilization has been tuned to further reduce frame time spikes of individual collection steps and to bring different GC stages to the same level of CPU utilization.
|
||||||
|
|
||||||
|
Returning a type-cast local (`return a :: type`) as well as returning multiple local variables (`return a, b, c`) is now a little bit more efficient.
|
||||||
|
|
||||||
|
### Function inlining and loop unrolling
|
||||||
|
|
||||||
|
In the open-source release of Luau, when optimization level 2 is enabled, the compiler will now perform function inlining and loop unrolling.
|
||||||
|
|
||||||
|
Only loops with loop bounds known at compile time, such as `for i=1,4 do`, can be unrolled. The loop body must be simple enough for the optimization to be profitable; compiler uses heuristics to estimate the performance benefit and automatically decide if unrolling should be performed.
|
||||||
|
|
||||||
|
Only local functions (defined either as `local function foo` or `local foo = function`) can be inlined. The function body must be simple enough for the optimization to be profitable; compiler uses heuristics to estimate the performance benefit and automatically decide if each call to the function should be inlined instead. Additionally recursive invocations of a function can't be inlined at this time, and inlining is completely disabled for modules that use `getfenv`/`setfenv` functions.
|
Loading…
Reference in New Issue
Block a user