mirror of
https://github.com/luau-lang/luau.git
synced 2025-08-26 11:27:08 +01:00
# General * Expose an optional `get_alias` API as an alternative to `get_config` in Luau.Require and Luau.RequireNavigator. * Improve the Luau CLI's virtual filesystem implementation to fix bugs related to `init.luau`. Fixes https://github.com/luau-lang/luau/issues/1816 # New Type Solver * Avoid double reporting errors when erroneous arguments are provided to type functions. * Fix some instances of unresovable cyclic type functions in loops by only considering the first loop cycles. This results in some type inference inaccuracies when the type of a variable in loop through multiple iterations. Fixes https://github.com/luau-lang/luau/issues/1413. * Better generalize free types that have meaningful lower and upper bounds, especially for table indexers. * Report more specific errors when assigning or returning table literal types, instead of citing the *entire* table type. * Inference for functions with generic type packs is greatly improved. * Fix some internal compiler exceptions when using type-stating functions like `table.freeze` in `if _ then _ else _` expressions and short circuiting binary operations. * More consistently simplify unions of primitive types, especially in array-like and dictionary-like tables. * Fix a crash when type checking an erroneous type alias containing `typeof` with a type assertion expression, as in: ``` type MyTable = {} -- This will error at type checking time as it's a duplicate type MyTable = typeof(setmetatable(SomeTable :: {}, SomeMetaTable)); ``` * Fix a crash when inferring the type of an index expression where the indexee is invalid (e.g. `nil`). # Runtime * Avoid throwing an exception from `luau_load` if we run out of memory. * Type functions are no longer compiled and included in bytecode. Fixes #1817. * Fix some instances of Luau C API functions reading invalid debug information (generally when the first or last instruction of a block was being inspected). Fixes #1369. * Avoid potential signed integer overflow when doing bounds checks on tables. * Support 16 byte aligned userdata objects when system allocation alignment is also 16 bytes. * Fix memory leaks in `Luau.Require` when using VM build with no exceptions. Fixes #1827. --------- Co-authored-by: Andy Friesen <afriesen@roblox.com> Co-authored-by: Ariel Weiss <aaronweiss@roblox.com> Co-authored-by: Hunter Goldstein <hgoldstein@roblox.com> Co-authored-by: James McNellis <jmcnellis@roblox.com> Co-authored-by: Sora Kanosue <skanosue@roblox.com> Co-authored-by: Talha Pathan <tpathan@roblox.com> Co-authored-by: Varun Saini <vsaini@roblox.com> Co-authored-by: Vyacheslav Egorov <vegorov@roblox.com>
91 lines
3.5 KiB
C++
91 lines
3.5 KiB
C++
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
|
|
|
|
#include "Luau/Require.h"
|
|
|
|
#include "RequireImpl.h"
|
|
|
|
#include "lua.h"
|
|
#include "lualib.h"
|
|
|
|
static void validateConfig(lua_State* L, const luarequire_Configuration& config)
|
|
{
|
|
if (!config.is_require_allowed)
|
|
luaL_error(L, "require configuration is missing required function pointer: is_require_allowed");
|
|
if (!config.reset)
|
|
luaL_error(L, "require configuration is missing required function pointer: reset");
|
|
if (!config.jump_to_alias)
|
|
luaL_error(L, "require configuration is missing required function pointer: jump_to_alias");
|
|
if (!config.to_parent)
|
|
luaL_error(L, "require configuration is missing required function pointer: to_parent");
|
|
if (!config.to_child)
|
|
luaL_error(L, "require configuration is missing required function pointer: to_child");
|
|
if (!config.is_module_present)
|
|
luaL_error(L, "require configuration is missing required function pointer: is_module_present");
|
|
if (!config.get_chunkname)
|
|
luaL_error(L, "require configuration is missing required function pointer: get_chunkname");
|
|
if (!config.get_loadname)
|
|
luaL_error(L, "require configuration is missing required function pointer: get_loadname");
|
|
if (!config.get_cache_key)
|
|
luaL_error(L, "require configuration is missing required function pointer: get_cache_key");
|
|
if (!config.is_config_present)
|
|
luaL_error(L, "require configuration is missing required function pointer: is_config_present");
|
|
if (config.get_alias && config.get_config)
|
|
luaL_error(L, "require configuration cannot define both get_alias and get_config");
|
|
if (!config.get_alias && !config.get_config)
|
|
luaL_error(L, "require configuration is missing required function pointer: either get_alias or get_config (not both)");
|
|
if (!config.load)
|
|
luaL_error(L, "require configuration is missing required function pointer: load");
|
|
}
|
|
|
|
static int pushrequireclosureinternal(
|
|
lua_State* L,
|
|
luarequire_Configuration_init config_init,
|
|
void* ctx,
|
|
lua_CFunction requirelikefunc,
|
|
const char* debugname
|
|
)
|
|
{
|
|
luarequire_Configuration* config = static_cast<luarequire_Configuration*>(lua_newuserdata(L, sizeof(luarequire_Configuration)));
|
|
if (!config)
|
|
luaL_error(L, "failed to allocate memory for require configuration");
|
|
|
|
config_init(config);
|
|
validateConfig(L, *config);
|
|
|
|
lua_pushlightuserdata(L, ctx);
|
|
|
|
// require-like closure captures config and ctx as upvalues
|
|
lua_pushcclosurek(L, requirelikefunc, debugname, 2, Luau::Require::lua_requirecont);
|
|
return 1;
|
|
}
|
|
|
|
int luarequire_pushrequire(lua_State* L, luarequire_Configuration_init config_init, void* ctx)
|
|
{
|
|
return pushrequireclosureinternal(L, config_init, ctx, Luau::Require::lua_require, "require");
|
|
}
|
|
|
|
void luaopen_require(lua_State* L, luarequire_Configuration_init config_init, void* ctx)
|
|
{
|
|
luarequire_pushrequire(L, config_init, ctx);
|
|
lua_setglobal(L, "require");
|
|
}
|
|
|
|
int luarequire_pushproxyrequire(lua_State* L, luarequire_Configuration_init config_init, void* ctx)
|
|
{
|
|
return pushrequireclosureinternal(L, config_init, ctx, Luau::Require::lua_proxyrequire, "proxyrequire");
|
|
}
|
|
|
|
int luarequire_registermodule(lua_State* L)
|
|
{
|
|
return Luau::Require::registerModuleImpl(L);
|
|
}
|
|
|
|
int luarequire_clearcacheentry(lua_State* L)
|
|
{
|
|
return Luau::Require::clearCacheEntry(L);
|
|
}
|
|
|
|
int luarequire_clearcache(lua_State* L)
|
|
{
|
|
return Luau::Require::clearCache(L);
|
|
}
|