mirror of
https://github.com/luau-lang/luau.git
synced 2024-12-14 06:00:39 +00:00
7d4033071a
### What's new * A bug in exception handling in GCC(11/12/13) on MacOS prevents our test suite from running. * Parser now supports leading `|` or `&` when declaring `Union` and `Intersection` types (#1286) * We now support parsing of attributes on functions as described in the [rfc](https://github.com/luau-lang/rfcs/pull/30) * With this change, expressions such as `local x = @native function(x) return x+1 end` and `f(@native function(x) return x+1 end)` are now valid. * Added support for `@native` attribute - we can now force native compilation of individual functions if the `@native` attribute is specified before the `function` keyword (works for lambdas too). ### New Solver * Many fixes in the new solver for crashes and instability * Refinements now use simplification and not normalization in a specific case of two tables * Assume that compound assignments do not change the type of the left-side operand * Fix error that prevented Class Methods from being overloaded ### VM * Updated description of Garbage Collector invariant --- ### Internal Contributors Co-authored-by: Aaron Weiss <aaronweiss@roblox.com> Co-authored-by: Alexander McCord <amccord@roblox.com> Co-authored-by: Andy Friesen <afriesen@roblox.com> Co-authored-by: Aviral Goel <agoel@roblox.com> Co-authored-by: Vighnesh Vijay <vvijay@roblox.com> Co-authored-by: Vyacheslav Egorov <vegorov@roblox.com> --------- Co-authored-by: Aaron Weiss <aaronweiss@roblox.com> Co-authored-by: Alexander McCord <amccord@roblox.com> Co-authored-by: Andy Friesen <afriesen@roblox.com> Co-authored-by: Aviral Goel <agoel@roblox.com> Co-authored-by: David Cope <dcope@roblox.com> Co-authored-by: Lily Brown <lbrown@roblox.com> Co-authored-by: Vyacheslav Egorov <vegorov@roblox.com>
135 lines
3.7 KiB
C++
135 lines
3.7 KiB
C++
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
|
|
#pragma once
|
|
|
|
#include "Luau/Bytecode.h"
|
|
#include "Luau/Common.h"
|
|
#include "Luau/DenseHash.h"
|
|
#include "Luau/IrData.h"
|
|
|
|
#include <vector>
|
|
|
|
struct Proto;
|
|
typedef uint32_t Instruction;
|
|
|
|
namespace Luau
|
|
{
|
|
namespace CodeGen
|
|
{
|
|
|
|
struct HostIrHooks;
|
|
|
|
struct IrBuilder
|
|
{
|
|
IrBuilder(const HostIrHooks& hostHooks);
|
|
|
|
void buildFunctionIr(Proto* proto);
|
|
|
|
void rebuildBytecodeBasicBlocks(Proto* proto);
|
|
void translateInst(LuauOpcode op, const Instruction* pc, int i);
|
|
void handleFastcallFallback(IrOp fallbackOrUndef, const Instruction* pc, int i);
|
|
|
|
bool isInternalBlock(IrOp block);
|
|
void beginBlock(IrOp block);
|
|
|
|
void loadAndCheckTag(IrOp loc, uint8_t tag, IrOp fallback);
|
|
|
|
// Clones all instructions into the current block
|
|
// Source block that is cloned cannot use values coming in from a predecessor
|
|
void clone(const IrBlock& source, bool removeCurrentTerminator);
|
|
|
|
IrOp undef();
|
|
|
|
IrOp constInt(int value);
|
|
IrOp constUint(unsigned value);
|
|
IrOp constDouble(double value);
|
|
IrOp constTag(uint8_t value);
|
|
IrOp constAny(IrConst constant, uint64_t asCommonKey);
|
|
|
|
IrOp cond(IrCondition cond);
|
|
|
|
IrOp inst(IrCmd cmd);
|
|
IrOp inst(IrCmd cmd, IrOp a);
|
|
IrOp inst(IrCmd cmd, IrOp a, IrOp b);
|
|
IrOp inst(IrCmd cmd, IrOp a, IrOp b, IrOp c);
|
|
IrOp inst(IrCmd cmd, IrOp a, IrOp b, IrOp c, IrOp d);
|
|
IrOp inst(IrCmd cmd, IrOp a, IrOp b, IrOp c, IrOp d, IrOp e);
|
|
IrOp inst(IrCmd cmd, IrOp a, IrOp b, IrOp c, IrOp d, IrOp e, IrOp f);
|
|
IrOp inst(IrCmd cmd, IrOp a, IrOp b, IrOp c, IrOp d, IrOp e, IrOp f, IrOp g);
|
|
|
|
IrOp block(IrBlockKind kind); // Requested kind can be ignored if we are in an outlined sequence
|
|
IrOp blockAtInst(uint32_t index);
|
|
|
|
IrOp vmReg(uint8_t index);
|
|
IrOp vmConst(uint32_t index);
|
|
IrOp vmUpvalue(uint8_t index);
|
|
|
|
IrOp vmExit(uint32_t pcpos);
|
|
|
|
const HostIrHooks& hostHooks;
|
|
|
|
bool inTerminatedBlock = false;
|
|
|
|
bool interruptRequested = false;
|
|
|
|
bool activeFastcallFallback = false;
|
|
IrOp fastcallFallbackReturn;
|
|
|
|
// Force builder to skip source commands
|
|
int cmdSkipTarget = -1;
|
|
|
|
IrFunction function;
|
|
|
|
uint32_t activeBlockIdx = ~0u;
|
|
|
|
std::vector<uint32_t> instIndexToBlock; // Block index at the bytecode instruction
|
|
|
|
struct LoopInfo
|
|
{
|
|
IrOp step;
|
|
int startpc = 0;
|
|
};
|
|
|
|
std::vector<LoopInfo> numericLoopStack;
|
|
|
|
// Similar to BytecodeBuilder, duplicate constants are removed used the same method
|
|
struct ConstantKey
|
|
{
|
|
IrConstKind kind;
|
|
// Note: this stores value* from IrConst; when kind is Double, this stores the same bits as double does but in uint64_t.
|
|
uint64_t value;
|
|
|
|
bool operator==(const ConstantKey& key) const
|
|
{
|
|
return kind == key.kind && value == key.value;
|
|
}
|
|
};
|
|
|
|
struct ConstantKeyHash
|
|
{
|
|
size_t operator()(const ConstantKey& key) const
|
|
{
|
|
// finalizer from MurmurHash64B
|
|
const uint32_t m = 0x5bd1e995;
|
|
|
|
uint32_t h1 = uint32_t(key.value);
|
|
uint32_t h2 = uint32_t(key.value >> 32) ^ (int(key.kind) * m);
|
|
|
|
h1 ^= h2 >> 18;
|
|
h1 *= m;
|
|
h2 ^= h1 >> 22;
|
|
h2 *= m;
|
|
h1 ^= h2 >> 17;
|
|
h1 *= m;
|
|
h2 ^= h1 >> 19;
|
|
h2 *= m;
|
|
|
|
// ... truncated to 32-bit output (normally hash is equal to (uint64_t(h1) << 32) | h2, but we only really need the lower 32-bit half)
|
|
return size_t(h2);
|
|
}
|
|
};
|
|
|
|
DenseHashMap<ConstantKey, uint32_t, ConstantKeyHash> constantMap;
|
|
};
|
|
|
|
} // namespace CodeGen
|
|
} // namespace Luau
|