Files
Fig/src/Object/ObjectBase.hpp
T
PuqiAR 6dbecbbdc0 feat: 重构编译器以支持函数定义和调用,添加新的字节码以支持函数调用
另外,我很高兴地宣布,fib(40) 递归法 在我的平台, i5-13490f,只需要 6600ms, fib(30) 56ms
这是历史性的一刻!
2026-03-07 00:34:52 +08:00

231 lines
6.5 KiB
C++

/*!
@file src/Object/ObjectBase.hpp
@brief 值表示定义 (NaN Boxing) uint64
@author PuqiAR (im@puqiar.top)
@date 2026-02-19
*/
#pragma once
#include <bit>
#include <cstdint>
#include <Deps/Deps.hpp>
namespace Fig
{
struct Object; // 前置声明
/*
正常来说直接 Value = std::uint64_t会更快
但是这样会带来隐式转换的问题
因此我们封装成一个类,这样速度不会损失很多。
(release模式编译器会直接优化, 速度和uint64_t直接表示一样快)
*/
class Value
{
private:
std::uint64_t v_; // 唯一的物理成员 sizeof(Value) 永远是 8 字节。
// --- 私有掩码常量 ---
static constexpr std::uint64_t QNAN_MASK = 0x7ffc000000000000;
static constexpr std::uint64_t SIGN_BIT = 0x8000000000000000;
// 专门给 Int32 预留的高位 Tag
static constexpr std::uint32_t INT_TAG_HIGH = 0x7FFD0000;
// 基础原语 Tag
static constexpr std::uint64_t TAG_NULL = 1;
static constexpr std::uint64_t TAG_FALSE = 2;
static constexpr std::uint64_t TAG_TRUE = 3;
// 私有底层构造:仅供内部组装使用
constexpr explicit Value(uint64_t raw) : v_(raw) {}
public:
// 默认构造为 Null,保证未初始化变量也是安全的
constexpr Value()
{
*this = GetNullInstance();
}
[[nodiscard]] static constexpr Value FromDouble(double d)
{
uint64_t raw = std::bit_cast<uint64_t>(d);
// 清洗非法的 NaN
if ((raw & QNAN_MASK) == QNAN_MASK)
return Value(QNAN_MASK);
return Value(raw);
}
[[nodiscard]] static constexpr Value FromInt(std::int32_t i)
{
// 移位构造,彻底阻断符号扩展漏洞
return Value((static_cast<uint64_t>(INT_TAG_HIGH) << 32) | static_cast<uint32_t>(i));
}
[[nodiscard]] static constexpr Value &GetTrueInstance()
{
static Value trueInstance(QNAN_MASK | TAG_TRUE);
return trueInstance;
}
[[nodiscard]] static constexpr Value &GetFalseInstance()
{
static Value falseInstance(QNAN_MASK | TAG_FALSE);
return falseInstance;
}
[[nodiscard]] static constexpr Value &FromBool(bool b)
{
return (b ? GetTrueInstance() : GetFalseInstance());
}
[[nodiscard]] static constexpr Value &GetNullInstance()
{
static Value nullInstance(QNAN_MASK | TAG_NULL);
return nullInstance;
}
[[nodiscard]] static Value FromObject(Object *ptr)
{
return Value(reinterpret_cast<uint64_t>(ptr) | SIGN_BIT | QNAN_MASK);
}
// 类型检查 (Is)
[[nodiscard]] constexpr bool IsDouble() const
{
return (v_ & QNAN_MASK) != QNAN_MASK;
}
[[nodiscard]] constexpr bool IsInt() const
{
// 安全的高 32 位移位判定
return static_cast<uint32_t>(v_ >> 32) == INT_TAG_HIGH;
}
[[nodiscard]] constexpr bool IsNumber() const
{
return IsDouble() || IsInt();
}
[[nodiscard]] constexpr bool IsNull() const
{
return v_ == (QNAN_MASK | TAG_NULL);
}
[[nodiscard]] constexpr bool IsBool() const
{
return (v_ | 1) == (QNAN_MASK | TAG_TRUE);
}
[[nodiscard]] constexpr bool IsObject() const
{
return (v_ & (SIGN_BIT | QNAN_MASK)) == (SIGN_BIT | QNAN_MASK);
}
// 提取数据 (Unbox / As)
[[nodiscard]] constexpr double AsDouble() const
{
return std::bit_cast<double>(v_);
}
[[nodiscard]] constexpr int32_t AsInt() const
{
return static_cast<int32_t>(v_);
}
// 核心辅助:泛型数字提取。算术指令可以直接用这个,免去手写 if 分支
// 若不是 int/double 会导致非常恐怖的问题
[[nodiscard]] constexpr double CastToDouble() const
{
return IsInt() ? static_cast<double>(AsInt()) : AsDouble();
}
[[nodiscard]] constexpr bool AsBool() const
{
return v_ == (QNAN_MASK | TAG_TRUE);
}
[[nodiscard]] struct Object *AsObject() const
{
return reinterpret_cast<struct Object *>(v_ & ~(SIGN_BIT | QNAN_MASK));
}
// 重载
// 暴露原生值用于硬核位运算或 Hash 计算
[[nodiscard]] constexpr uint64_t Raw() const
{
return v_;
}
// 让 VM 的 OP_EQ 指令极简:`if (RA == RB)`
[[nodiscard]] constexpr bool operator==(const Value &other) const
{
// IEEE 754 规定浮点数有 +0.0 == -0.0 的特殊规则,所以不直接比对raw bits而是转换成 double进行C++比对
if (IsDouble() && other.IsDouble())
{
return AsDouble() == other.AsDouble();
}
// 直接比较 64 位整数内存,所以堆对象比较为地址(运算符重载由Compiler处理)
return v_ == other.v_;
}
[[nodiscard]] constexpr bool operator!=(const Value &other) const
{
return !(*this == other);
}
// 类函数
[[nodiscard]]
String ToString() const;
};
/*
C风格继承 + 手动分发
禁止任何 virtual 达到最高效率
*/
enum class ObjectType : uint8_t
{
String,
Function,
Struct,
Instance,
};
struct StructObject /* : public Object */; // 结构体基类的定义,前向声明
// Total 24 bytes size
struct Object
{
Object *next; // 8 bytes: gc链表
StructObject *klass; // 8 bytes: 一切皆对象,父类指针
ObjectType type; // 1 byte : 类型
bool isMarked = false; // 1 byte : gc标记
// + 6 bytes padding
constexpr bool isString() const
{
return type == ObjectType::String;
}
constexpr bool isFunction() const
{
return type == ObjectType::Function;
}
constexpr bool isStruct() const
{
return type == ObjectType::Struct;
}
constexpr bool isInstance() const
{
return type == ObjectType::Instance;
}
};
} // namespace Fig