From 1387f6d3e7e0b94456f48a6d5ae1b88c96dbd9f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petri=20H=C3=A4kkinen?= Date: Mon, 16 Dec 2024 11:47:45 +0200 Subject: [PATCH 1/9] Vector constants with two components --- Compiler/src/BuiltinFolding.cpp | 10 +++++++--- tests/Compiler.test.cpp | 21 +++++++++++++++------ 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/Compiler/src/BuiltinFolding.cpp b/Compiler/src/BuiltinFolding.cpp index 0886e94aa..9182d57e2 100644 --- a/Compiler/src/BuiltinFolding.cpp +++ b/Compiler/src/BuiltinFolding.cpp @@ -5,6 +5,8 @@ #include +LUAU_FASTFLAGVARIABLE(LuauVector2Constructor) + namespace Luau { namespace Compile @@ -471,11 +473,13 @@ Constant foldBuiltin(int bfid, const Constant* args, size_t count) break; case LBF_VECTOR: - if (count >= 3 && args[0].type == Constant::Type_Number && args[1].type == Constant::Type_Number && args[2].type == Constant::Type_Number) + if (count >= 2 && args[0].type == Constant::Type_Number && args[1].type == Constant::Type_Number) { - if (count == 3) + if (count == 2 && FFlag::LuauVector2Constructor) + return cvector(args[0].valueNumber, args[1].valueNumber, 0.0, 0.0); + else if (count == 3 && args[2].type == Constant::Type_Number) return cvector(args[0].valueNumber, args[1].valueNumber, args[2].valueNumber, 0.0); - else if (count == 4 && args[3].type == Constant::Type_Number) + else if (count == 4 && args[2].type == Constant::Type_Number && args[3].type == Constant::Type_Number) return cvector(args[0].valueNumber, args[1].valueNumber, args[2].valueNumber, args[3].valueNumber); } break; diff --git a/tests/Compiler.test.cpp b/tests/Compiler.test.cpp index 56201b324..22430f6d8 100644 --- a/tests/Compiler.test.cpp +++ b/tests/Compiler.test.cpp @@ -28,6 +28,7 @@ LUAU_FASTFLAG(LuauCompileOptimizeRevArith) LUAU_FASTFLAG(LuauCompileLibraryConstants) LUAU_FASTFLAG(LuauVectorBuiltins) LUAU_FASTFLAG(LuauVectorFolding) +LUAU_FASTFLAG(LuauVector2Constructor) LUAU_FASTFLAG(LuauCompileDisabledBuiltins) using namespace Luau; @@ -5102,34 +5103,42 @@ L0: RETURN R3 -1 )"); } -TEST_CASE("VectorLiterals") +TEST_CASE("VectorConstants") { - CHECK_EQ("\n" + compileFunction("return Vector3.new(1, 2, 3)", 0, 2, 0, /*enableVectors*/ true), R"( + ScopedFastFlag luauVectorBuiltins{FFlag::LuauVectorBuiltins, true}; + ScopedFastFlag luauVector2Constructor{FFlag::LuauVector2Constructor, true}; + + CHECK_EQ("\n" + compileFunction("return vector.create(1, 2)", 0, 2, 0, /*enableVectors*/ true), R"( +LOADK R0 K0 [1, 2, 0] +RETURN R0 1 +)"); + + CHECK_EQ("\n" + compileFunction("return vector.create(1, 2, 3)", 0, 2, 0, /*enableVectors*/ true), R"( LOADK R0 K0 [1, 2, 3] RETURN R0 1 )"); - CHECK_EQ("\n" + compileFunction("print(Vector3.new(1, 2, 3))", 0, 2, 0, /*enableVectors*/ true), R"( + CHECK_EQ("\n" + compileFunction("print(vector.create(1, 2, 3))", 0, 2, 0, /*enableVectors*/ true), R"( GETIMPORT R0 1 [print] LOADK R1 K2 [1, 2, 3] CALL R0 1 0 RETURN R0 0 )"); - CHECK_EQ("\n" + compileFunction("print(Vector3.new(1, 2, 3, 4))", 0, 2, 0, /*enableVectors*/ true), R"( + CHECK_EQ("\n" + compileFunction("print(vector.create(1, 2, 3, 4))", 0, 2, 0, /*enableVectors*/ true), R"( GETIMPORT R0 1 [print] LOADK R1 K2 [1, 2, 3, 4] CALL R0 1 0 RETURN R0 0 )"); - CHECK_EQ("\n" + compileFunction("return Vector3.new(0, 0, 0), Vector3.new(-0, 0, 0)", 0, 2, 0, /*enableVectors*/ true), R"( + CHECK_EQ("\n" + compileFunction("return vector.create(0, 0, 0), vector.create(-0, 0, 0)", 0, 2, 0, /*enableVectors*/ true), R"( LOADK R0 K0 [0, 0, 0] LOADK R1 K1 [-0, 0, 0] RETURN R0 2 )"); - CHECK_EQ("\n" + compileFunction("return type(Vector3.new(0, 0, 0))", 0, 2, 0, /*enableVectors*/ true), R"( + CHECK_EQ("\n" + compileFunction("return type(vector.create(0, 0, 0))", 0, 2, 0, /*enableVectors*/ true), R"( LOADK R0 K0 ['vector'] RETURN R0 1 )"); From 7246c2ae89a6ac9688ca97d3fe641abee7f51738 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petri=20H=C3=A4kkinen?= Date: Mon, 16 Dec 2024 12:09:00 +0200 Subject: [PATCH 2/9] Add 2-component overload for vector.create --- Compiler/src/BuiltinFolding.cpp | 4 ++-- VM/src/lveclib.cpp | 9 ++++++--- tests/Compiler.test.cpp | 4 ++-- tests/Conformance.test.cpp | 2 ++ tests/conformance/vector_library.lua | 6 ++++++ 5 files changed, 18 insertions(+), 7 deletions(-) diff --git a/Compiler/src/BuiltinFolding.cpp b/Compiler/src/BuiltinFolding.cpp index 9182d57e2..7aa8eb463 100644 --- a/Compiler/src/BuiltinFolding.cpp +++ b/Compiler/src/BuiltinFolding.cpp @@ -5,7 +5,7 @@ #include -LUAU_FASTFLAGVARIABLE(LuauVector2Constructor) +LUAU_FASTFLAGVARIABLE(LuauVector2Constants) namespace Luau { @@ -475,7 +475,7 @@ Constant foldBuiltin(int bfid, const Constant* args, size_t count) case LBF_VECTOR: if (count >= 2 && args[0].type == Constant::Type_Number && args[1].type == Constant::Type_Number) { - if (count == 2 && FFlag::LuauVector2Constructor) + if (count == 2 && FFlag::LuauVector2Constants) return cvector(args[0].valueNumber, args[1].valueNumber, 0.0, 0.0); else if (count == 3 && args[2].type == Constant::Type_Number) return cvector(args[0].valueNumber, args[1].valueNumber, args[2].valueNumber, 0.0); diff --git a/VM/src/lveclib.cpp b/VM/src/lveclib.cpp index 2a4e58c60..ff1fd2691 100644 --- a/VM/src/lveclib.cpp +++ b/VM/src/lveclib.cpp @@ -7,16 +7,19 @@ #include LUAU_FASTFLAGVARIABLE(LuauVectorMetatable) +LUAU_FASTFLAGVARIABLE(LuauVector2Constructor) static int vector_create(lua_State* L) { + // checking argument count to avoid accepting 'nil' as a valid value + int count = lua_gettop(L); + double x = luaL_checknumber(L, 1); double y = luaL_checknumber(L, 2); - double z = luaL_checknumber(L, 3); + double z = FFlag::LuauVector2Constructor ? (count >= 3 ? luaL_checknumber(L, 3) : 0.0) : luaL_checknumber(L, 3); #if LUA_VECTOR_SIZE == 4 - // checking argument count to avoid accepting 'nil' as a valid value - double w = lua_gettop(L) >= 4 ? luaL_checknumber(L, 4) : 0.0; + double w = count >= 4 ? luaL_checknumber(L, 4) : 0.0; lua_pushvector(L, float(x), float(y), float(z), float(w)); #else diff --git a/tests/Compiler.test.cpp b/tests/Compiler.test.cpp index 22430f6d8..39ed880be 100644 --- a/tests/Compiler.test.cpp +++ b/tests/Compiler.test.cpp @@ -28,7 +28,7 @@ LUAU_FASTFLAG(LuauCompileOptimizeRevArith) LUAU_FASTFLAG(LuauCompileLibraryConstants) LUAU_FASTFLAG(LuauVectorBuiltins) LUAU_FASTFLAG(LuauVectorFolding) -LUAU_FASTFLAG(LuauVector2Constructor) +LUAU_FASTFLAG(LuauVector2Constants) LUAU_FASTFLAG(LuauCompileDisabledBuiltins) using namespace Luau; @@ -5106,7 +5106,7 @@ L0: RETURN R3 -1 TEST_CASE("VectorConstants") { ScopedFastFlag luauVectorBuiltins{FFlag::LuauVectorBuiltins, true}; - ScopedFastFlag luauVector2Constructor{FFlag::LuauVector2Constructor, true}; + ScopedFastFlag luauVector2Constants{FFlag::LuauVector2Constants, true}; CHECK_EQ("\n" + compileFunction("return vector.create(1, 2)", 0, 2, 0, /*enableVectors*/ true), R"( LOADK R0 K0 [1, 2, 0] diff --git a/tests/Conformance.test.cpp b/tests/Conformance.test.cpp index c0e81371d..59201d268 100644 --- a/tests/Conformance.test.cpp +++ b/tests/Conformance.test.cpp @@ -41,6 +41,7 @@ LUAU_FASTFLAG(LuauVectorLibNativeCodegen) LUAU_FASTFLAG(LuauVectorLibNativeDot) LUAU_FASTFLAG(LuauVectorBuiltins) LUAU_FASTFLAG(LuauVectorMetatable) +LUAU_FASTFLAG(LuauVector2Constructor) static lua_CompileOptions defaultOptions() { @@ -895,6 +896,7 @@ TEST_CASE("VectorLibrary") ScopedFastFlag luauVectorLibNativeCodegen{FFlag::LuauVectorLibNativeCodegen, true}; ScopedFastFlag luauVectorLibNativeDot{FFlag::LuauVectorLibNativeDot, true}; ScopedFastFlag luauVectorMetatable{FFlag::LuauVectorMetatable, true}; + ScopedFastFlag luauVector2Constructor{FFlag::LuauVector2Constructor, true}; lua_CompileOptions copts = defaultOptions(); diff --git a/tests/conformance/vector_library.lua b/tests/conformance/vector_library.lua index 3f30d900d..7c6a0b8f7 100644 --- a/tests/conformance/vector_library.lua +++ b/tests/conformance/vector_library.lua @@ -13,6 +13,12 @@ end -- make sure we cover both builtin and C impl assert(vector.create(1, 2, 4) == vector.create("1", "2", "4")) +-- 'create' +local v12 = vector.create(1, 2) +local v123 = vector.create(1, 2, 3) +assert(v12.x == 1 and v12.y == 2 and v12.z == 0) +assert(v123.x == 1 and v123.y == 2 and v123.z == 3) + -- testing 'dot' with error handling and different call kinds to mostly check details in the codegen assert(vector.dot(vector.create(1, 2, 4), vector.create(5, 6, 7)) == 45) assert(ecall(function() vector.dot(vector.create(1, 2, 4)) end) == "missing argument #2 to 'dot' (vector expected)") From 044c97b38dd53d588861b52f7d9ab32dbd25b7b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petri=20H=C3=A4kkinen?= Date: Mon, 16 Dec 2024 14:02:00 +0200 Subject: [PATCH 3/9] Add support for two components to vector.create fastcall function --- VM/src/lbuiltins.cpp | 28 +++++++++++++++------------- tests/conformance/vector_library.lua | 1 + 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/VM/src/lbuiltins.cpp b/VM/src/lbuiltins.cpp index 0bca4495b..730a92659 100644 --- a/VM/src/lbuiltins.cpp +++ b/VM/src/lbuiltins.cpp @@ -25,6 +25,8 @@ #endif #endif +LUAU_FASTFLAG(LuauVector2Constructor) + // luauF functions implement FASTCALL instruction that performs a direct execution of some builtin functions from the VM // The rule of thumb is that FASTCALL functions can not call user code, yield, fail, or reallocate stack. // If types of the arguments mismatch, luauF_* needs to return -1 and the execution will fall back to the usual call path @@ -1055,25 +1057,25 @@ static int luauF_tunpack(lua_State* L, StkId res, TValue* arg0, int nresults, St static int luauF_vector(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) { - if (nparams >= 3 && nresults <= 1 && ttisnumber(arg0) && ttisnumber(args) && ttisnumber(args + 1)) + int minparams = FFlag::LuauVector2Constructor ? 2 : 3; + + if (nparams >= minparams && nparams <= LUA_VECTOR_SIZE && nresults <= 1 && ttisnumber(arg0) && ttisnumber(args)) { - double x = nvalue(arg0); - double y = nvalue(args); - double z = nvalue(args + 1); + float value[4]; + value[0] = (float)nvalue(arg0); + value[1] = (float)nvalue(args); + value[2] = 0.0; + value[3] = 0.0; -#if LUA_VECTOR_SIZE == 4 - double w = 0.0; - if (nparams >= 4) + for (int i = 2; i < nparams; i++) { - if (!ttisnumber(args + 2)) + StkId a = args + i - 1; + if (!ttisnumber(a)) return -1; - w = nvalue(args + 2); + value[i] = (float)nvalue(a); } - setvvalue(res, float(x), float(y), float(z), float(w)); -#else - setvvalue(res, float(x), float(y), float(z), 0.0f); -#endif + setvvalue(res, value[0], value[1], value[2], value[3]); return 1; } diff --git a/tests/conformance/vector_library.lua b/tests/conformance/vector_library.lua index 7c6a0b8f7..dd5f2d1b9 100644 --- a/tests/conformance/vector_library.lua +++ b/tests/conformance/vector_library.lua @@ -11,6 +11,7 @@ function ecall(fn, ...) end -- make sure we cover both builtin and C impl +assert(vector.create(1, 2) == vector.create("1", "2")) assert(vector.create(1, 2, 4) == vector.create("1", "2", "4")) -- 'create' From e8e84a72c5f66a43945bf90743e69142e36ec366 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petri=20H=C3=A4kkinen?= Date: Mon, 16 Dec 2024 15:06:53 +0200 Subject: [PATCH 4/9] Modify 3rd argument of vector.create to be optional in type definitions --- Analysis/src/EmbeddedBuiltinDefinitions.cpp | 17 +++++++++++++++-- tests/Conformance.test.cpp | 1 + tests/Fixture.cpp | 3 +++ tests/NonStrictTypeChecker.test.cpp | 4 +++- 4 files changed, 22 insertions(+), 3 deletions(-) diff --git a/Analysis/src/EmbeddedBuiltinDefinitions.cpp b/Analysis/src/EmbeddedBuiltinDefinitions.cpp index 828fc7ed3..e4b561d41 100644 --- a/Analysis/src/EmbeddedBuiltinDefinitions.cpp +++ b/Analysis/src/EmbeddedBuiltinDefinitions.cpp @@ -2,6 +2,7 @@ #include "Luau/BuiltinDefinitions.h" LUAU_FASTFLAG(LuauMathMap) +LUAU_FASTFLAG(LuauVector2Constructor) LUAU_FASTFLAGVARIABLE(LuauVectorDefinitions) LUAU_FASTFLAGVARIABLE(LuauVectorDefinitionsExtra) @@ -513,10 +514,22 @@ std::string getBuiltinDefinitionSource() { std::string result = FFlag::LuauMathMap ? kBuiltinDefinitionLuaSrcChecked : kBuiltinDefinitionLuaSrcChecked_DEPRECATED; + std::string vectorSrc; if (FFlag::LuauVectorDefinitionsExtra) - result += kBuiltinDefinitionVectorSrc; + vectorSrc = kBuiltinDefinitionVectorSrc; else if (FFlag::LuauVectorDefinitions) - result += kBuiltinDefinitionVectorSrc_DEPRECATED; + vectorSrc = kBuiltinDefinitionVectorSrc_DEPRECATED; + + if (FFlag::LuauVector2Constructor && !vectorSrc.empty()) + { + std::string what = "create: @checked (x: number, y: number, z: number) -> vector"; + std::string replacement = "create: @checked (x: number, y: number, z: number?) -> vector"; + std::string::size_type pos = vectorSrc.find(what); + LUAU_ASSERT(pos != std::string::npos); + vectorSrc.replace(pos, what.size(), replacement); + } + + result += vectorSrc; return result; } diff --git a/tests/Conformance.test.cpp b/tests/Conformance.test.cpp index 59201d268..56ddb9135 100644 --- a/tests/Conformance.test.cpp +++ b/tests/Conformance.test.cpp @@ -990,6 +990,7 @@ static void populateRTTI(lua_State* L, Luau::TypeId type) TEST_CASE("Types") { ScopedFastFlag luauVectorDefinitions{FFlag::LuauVectorDefinitions, true}; + ScopedFastFlag luauVector2Constructor{FFlag::LuauVector2Constructor, true}; runConformance( "types.lua", diff --git a/tests/Fixture.cpp b/tests/Fixture.cpp index 5a2f9319f..e22e52b00 100644 --- a/tests/Fixture.cpp +++ b/tests/Fixture.cpp @@ -25,6 +25,7 @@ static const char* mainModuleName = "MainModule"; LUAU_FASTFLAG(LuauSolverV2); +LUAU_FASTFLAG(LuauVector2Constructor) LUAU_FASTFLAG(DebugLuauLogSolverToJsonFile) LUAU_FASTFLAGVARIABLE(DebugLuauForceAllNewSolverTests); @@ -580,6 +581,8 @@ LoadDefinitionFileResult Fixture::loadDefinition(const std::string& source, bool BuiltinsFixture::BuiltinsFixture(bool prepareAutocomplete) : Fixture(prepareAutocomplete) { + ScopedFastFlag luauVector2Constructor{FFlag::LuauVector2Constructor, true}; + Luau::unfreeze(frontend.globals.globalTypes); Luau::unfreeze(frontend.globalsForAutocomplete.globalTypes); diff --git a/tests/NonStrictTypeChecker.test.cpp b/tests/NonStrictTypeChecker.test.cpp index 8d13ebde9..f613e7502 100644 --- a/tests/NonStrictTypeChecker.test.cpp +++ b/tests/NonStrictTypeChecker.test.cpp @@ -15,6 +15,7 @@ #include LUAU_FASTFLAG(LuauCountSelfCallsNonstrict) +LUAU_FASTFLAG(LuauVector2Constructor) using namespace Luau; @@ -581,7 +582,8 @@ buffer.readi8(b, 0) TEST_CASE_FIXTURE(NonStrictTypeCheckerFixture, "nonstrict_method_calls") { - ScopedFastFlag sff{FFlag::LuauCountSelfCallsNonstrict, true}; + ScopedFastFlag luauCountSelfCallsNonstrict{FFlag::LuauCountSelfCallsNonstrict, true}; + ScopedFastFlag luauVector2Constructor{FFlag::LuauVector2Constructor, true}; Luau::unfreeze(frontend.globals.globalTypes); Luau::unfreeze(frontend.globalsForAutocomplete.globalTypes); From 186b4e693b253f9519b7a3272af2a2db3c4a4d9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petri=20H=C3=A4kkinen?= Date: Tue, 17 Dec 2024 09:52:12 +0200 Subject: [PATCH 5/9] Switch vector library type definition based on flags without string manipulation --- Analysis/src/EmbeddedBuiltinDefinitions.cpp | 84 ++++++++++++++++----- 1 file changed, 66 insertions(+), 18 deletions(-) diff --git a/Analysis/src/EmbeddedBuiltinDefinitions.cpp b/Analysis/src/EmbeddedBuiltinDefinitions.cpp index e4b561d41..5b36450b6 100644 --- a/Analysis/src/EmbeddedBuiltinDefinitions.cpp +++ b/Analysis/src/EmbeddedBuiltinDefinitions.cpp @@ -454,7 +454,7 @@ declare buffer: { )BUILTIN_SRC"; -static const std::string kBuiltinDefinitionVectorSrc_DEPRECATED = R"BUILTIN_SRC( +static const std::string kBuiltinDefinitionVectorSrc_NoExtra_NoVector2Ctor_DEPRECATED = R"BUILTIN_SRC( -- TODO: this will be replaced with a built-in primitive type declare class vector end @@ -480,7 +480,33 @@ declare vector: { )BUILTIN_SRC"; -static const std::string kBuiltinDefinitionVectorSrc = R"BUILTIN_SRC( +static const std::string kBuiltinDefinitionVectorSrc_NoExtra_DEPRECATED = R"BUILTIN_SRC( + +-- TODO: this will be replaced with a built-in primitive type +declare class vector end + +declare vector: { + create: @checked (x: number, y: number, z: number?) -> vector, + magnitude: @checked (vec: vector) -> number, + normalize: @checked (vec: vector) -> vector, + cross: @checked (vec1: vector, vec2: vector) -> vector, + dot: @checked (vec1: vector, vec2: vector) -> number, + angle: @checked (vec1: vector, vec2: vector, axis: vector?) -> number, + floor: @checked (vec: vector) -> vector, + ceil: @checked (vec: vector) -> vector, + abs: @checked (vec: vector) -> vector, + sign: @checked (vec: vector) -> vector, + clamp: @checked (vec: vector, min: vector, max: vector) -> vector, + max: @checked (vector, ...vector) -> vector, + min: @checked (vector, ...vector) -> vector, + + zero: vector, + one: vector, +} + +)BUILTIN_SRC"; + +static const std::string kBuiltinDefinitionVectorSrc_NoVector2Ctor_DEPRECATED = R"BUILTIN_SRC( -- While vector would have been better represented as a built-in primitive type, type solver class handling covers most of the properties declare class vector @@ -510,26 +536,48 @@ declare vector: { )BUILTIN_SRC"; +static const std::string kBuiltinDefinitionVectorSrc = R"BUILTIN_SRC( + +-- While vector would have been better represented as a built-in primitive type, type solver class handling covers most of the properties +declare class vector + x: number + y: number + z: number +end + +declare vector: { + create: @checked (x: number, y: number, z: number?) -> vector, + magnitude: @checked (vec: vector) -> number, + normalize: @checked (vec: vector) -> vector, + cross: @checked (vec1: vector, vec2: vector) -> vector, + dot: @checked (vec1: vector, vec2: vector) -> number, + angle: @checked (vec1: vector, vec2: vector, axis: vector?) -> number, + floor: @checked (vec: vector) -> vector, + ceil: @checked (vec: vector) -> vector, + abs: @checked (vec: vector) -> vector, + sign: @checked (vec: vector) -> vector, + clamp: @checked (vec: vector, min: vector, max: vector) -> vector, + max: @checked (vector, ...vector) -> vector, + min: @checked (vector, ...vector) -> vector, + + zero: vector, + one: vector, +} + +)BUILTIN_SRC"; + std::string getBuiltinDefinitionSource() { std::string result = FFlag::LuauMathMap ? kBuiltinDefinitionLuaSrcChecked : kBuiltinDefinitionLuaSrcChecked_DEPRECATED; - std::string vectorSrc; - if (FFlag::LuauVectorDefinitionsExtra) - vectorSrc = kBuiltinDefinitionVectorSrc; - else if (FFlag::LuauVectorDefinitions) - vectorSrc = kBuiltinDefinitionVectorSrc_DEPRECATED; - - if (FFlag::LuauVector2Constructor && !vectorSrc.empty()) - { - std::string what = "create: @checked (x: number, y: number, z: number) -> vector"; - std::string replacement = "create: @checked (x: number, y: number, z: number?) -> vector"; - std::string::size_type pos = vectorSrc.find(what); - LUAU_ASSERT(pos != std::string::npos); - vectorSrc.replace(pos, what.size(), replacement); - } - - result += vectorSrc; + if (FFlag::LuauVectorDefinitionsExtra && FFlag::LuauVector2Constructor) + result += kBuiltinDefinitionVectorSrc; + else if (FFlag::LuauVectorDefinitionsExtra && !FFlag::LuauVector2Constructor) + result += kBuiltinDefinitionVectorSrc_NoVector2Ctor_DEPRECATED; + else if (FFlag::LuauVectorDefinitions && FFlag::LuauVector2Constructor) + result += kBuiltinDefinitionVectorSrc_NoExtra_DEPRECATED; + else if (FFlag::LuauVectorDefinitions && !FFlag::LuauVector2Constructor) + result += kBuiltinDefinitionVectorSrc_NoExtra_NoVector2Ctor_DEPRECATED; return result; } From 69b481cb06b1631c9a0033ce87ffd1e4b069db57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petri=20H=C3=A4kkinen?= Date: Tue, 17 Dec 2024 09:55:50 +0200 Subject: [PATCH 6/9] Clean up VectorConstants test. Add legacy constructor test case. --- tests/Compiler.test.cpp | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/tests/Compiler.test.cpp b/tests/Compiler.test.cpp index 39ed880be..5c950e87e 100644 --- a/tests/Compiler.test.cpp +++ b/tests/Compiler.test.cpp @@ -5108,39 +5108,45 @@ TEST_CASE("VectorConstants") ScopedFastFlag luauVectorBuiltins{FFlag::LuauVectorBuiltins, true}; ScopedFastFlag luauVector2Constants{FFlag::LuauVector2Constants, true}; - CHECK_EQ("\n" + compileFunction("return vector.create(1, 2)", 0, 2, 0, /*enableVectors*/ true), R"( + CHECK_EQ("\n" + compileFunction("return vector.create(1, 2)", 0, 2, 0), R"( LOADK R0 K0 [1, 2, 0] RETURN R0 1 )"); - CHECK_EQ("\n" + compileFunction("return vector.create(1, 2, 3)", 0, 2, 0, /*enableVectors*/ true), R"( + CHECK_EQ("\n" + compileFunction("return vector.create(1, 2, 3)", 0, 2, 0), R"( LOADK R0 K0 [1, 2, 3] RETURN R0 1 )"); - CHECK_EQ("\n" + compileFunction("print(vector.create(1, 2, 3))", 0, 2, 0, /*enableVectors*/ true), R"( + CHECK_EQ("\n" + compileFunction("print(vector.create(1, 2, 3))", 0, 2, 0), R"( GETIMPORT R0 1 [print] LOADK R1 K2 [1, 2, 3] CALL R0 1 0 RETURN R0 0 )"); - CHECK_EQ("\n" + compileFunction("print(vector.create(1, 2, 3, 4))", 0, 2, 0, /*enableVectors*/ true), R"( + CHECK_EQ("\n" + compileFunction("print(vector.create(1, 2, 3, 4))", 0, 2, 0), R"( GETIMPORT R0 1 [print] LOADK R1 K2 [1, 2, 3, 4] CALL R0 1 0 RETURN R0 0 )"); - CHECK_EQ("\n" + compileFunction("return vector.create(0, 0, 0), vector.create(-0, 0, 0)", 0, 2, 0, /*enableVectors*/ true), R"( + CHECK_EQ("\n" + compileFunction("return vector.create(0, 0, 0), vector.create(-0, 0, 0)", 0, 2, 0), R"( LOADK R0 K0 [0, 0, 0] LOADK R1 K1 [-0, 0, 0] RETURN R0 2 )"); - CHECK_EQ("\n" + compileFunction("return type(vector.create(0, 0, 0))", 0, 2, 0, /*enableVectors*/ true), R"( + CHECK_EQ("\n" + compileFunction("return type(vector.create(0, 0, 0))", 0, 2, 0), R"( LOADK R0 K0 ['vector'] RETURN R0 1 +)"); + + // test legacy constructor + CHECK_EQ("\n" + compileFunction("return Vector3.new(1, 2, 3)", 0, 2, 0, /*enableVectors*/ true), R"( +LOADK R0 K0 [1, 2, 3] +RETURN R0 1 )"); } From 21998aa34262112975c9a090a93f930120349585 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petri=20H=C3=A4kkinen?= Date: Tue, 17 Dec 2024 10:11:21 +0200 Subject: [PATCH 7/9] Reimplement changes to luauF_vector in less intrusive way --- VM/src/lbuiltins.cpp | 64 +++++++++++++++++++++++++++++++++----------- 1 file changed, 48 insertions(+), 16 deletions(-) diff --git a/VM/src/lbuiltins.cpp b/VM/src/lbuiltins.cpp index 730a92659..0e468890d 100644 --- a/VM/src/lbuiltins.cpp +++ b/VM/src/lbuiltins.cpp @@ -1057,26 +1057,58 @@ static int luauF_tunpack(lua_State* L, StkId res, TValue* arg0, int nresults, St static int luauF_vector(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) { - int minparams = FFlag::LuauVector2Constructor ? 2 : 3; - - if (nparams >= minparams && nparams <= LUA_VECTOR_SIZE && nresults <= 1 && ttisnumber(arg0) && ttisnumber(args)) + if (FFlag::LuauVector2Constructor) { - float value[4]; - value[0] = (float)nvalue(arg0); - value[1] = (float)nvalue(args); - value[2] = 0.0; - value[3] = 0.0; - - for (int i = 2; i < nparams; i++) + if (nparams >= 2 && nresults <= 1 && ttisnumber(arg0) && ttisnumber(args)) { - StkId a = args + i - 1; - if (!ttisnumber(a)) - return -1; - value[i] = (float)nvalue(a); + float x = (float)nvalue(arg0); + float y = (float)nvalue(args); + float z = 0.0f; + float w = 0.0f; + + if (nparams >= 3) + { + if (!ttisnumber(args + 1)) + return -1; + z = (float)nvalue(args + 1); + } + +#if LUA_VECTOR_SIZE == 4 + if (nparams >= 4) + { + if (!ttisnumber(args + 2)) + return -1; + w = (float)nvalue(args + 2); + } +#endif + + setvvalue(res, x, y, z, w); + return 1; } + } + else + { + if (nparams >= 3 && nresults <= 1 && ttisnumber(arg0) && ttisnumber(args) && ttisnumber(args + 1)) + { + double x = nvalue(arg0); + double y = nvalue(args); + double z = nvalue(args + 1); - setvvalue(res, value[0], value[1], value[2], value[3]); - return 1; +#if LUA_VECTOR_SIZE == 4 + double w = 0.0; + if (nparams >= 4) + { + if (!ttisnumber(args + 2)) + return -1; + w = nvalue(args + 2); + } + setvvalue(res, float(x), float(y), float(z), float(w)); +#else + setvvalue(res, float(x), float(y), float(z), 0.0f); +#endif + + return 1; + } } return -1; From 81488f1fe4ade85ea60d743da5081ae25bb6adaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petri=20H=C3=A4kkinen?= Date: Tue, 17 Dec 2024 10:51:30 +0200 Subject: [PATCH 8/9] Add vector lib micro benchmark (just vector.create at this point) --- bench/micro_tests/test_vector_lib.lua | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 bench/micro_tests/test_vector_lib.lua diff --git a/bench/micro_tests/test_vector_lib.lua b/bench/micro_tests/test_vector_lib.lua new file mode 100644 index 000000000..59bddc045 --- /dev/null +++ b/bench/micro_tests/test_vector_lib.lua @@ -0,0 +1,14 @@ +local function prequire(name) local success, result = pcall(require, name); return success and result end +local bench = script and require(script.Parent.bench_support) or prequire("bench_support") or require("../bench_support") + +bench.runCode(function() + for i=1,1000000 do + vector.create(i, 2, 3) + vector.create(i, 2, 3) + vector.create(i, 2, 3) + vector.create(i, 2, 3) + vector.create(i, 2, 3) + end +end, "vector: create") + +-- TODO: add more tests \ No newline at end of file From d1739ba151077b4c080233de6dcf7b6b55600282 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petri=20H=C3=A4kkinen?= Date: Tue, 17 Dec 2024 11:10:21 +0200 Subject: [PATCH 9/9] Fix unused variable warning --- VM/src/lbuiltins.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/VM/src/lbuiltins.cpp b/VM/src/lbuiltins.cpp index 0e468890d..5959de143 100644 --- a/VM/src/lbuiltins.cpp +++ b/VM/src/lbuiltins.cpp @@ -1064,7 +1064,6 @@ static int luauF_vector(lua_State* L, StkId res, TValue* arg0, int nresults, Stk float x = (float)nvalue(arg0); float y = (float)nvalue(args); float z = 0.0f; - float w = 0.0f; if (nparams >= 3) { @@ -1074,15 +1073,18 @@ static int luauF_vector(lua_State* L, StkId res, TValue* arg0, int nresults, Stk } #if LUA_VECTOR_SIZE == 4 + float w = 0.0f; if (nparams >= 4) { if (!ttisnumber(args + 2)) return -1; w = (float)nvalue(args + 2); } + setvvalue(res, x, y, z, w); +#else + setvvalue(res, x, y, z, 0.0f); #endif - setvvalue(res, x, y, z, w); return 1; } }