diff options
author | Andreas Kling <kling@serenityos.org> | 2021-03-21 18:03:00 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-03-21 21:39:39 +0100 |
commit | c8382c32e9b840d0a7bde0802b87f63188488982 (patch) | |
tree | 6fe1a43695a4c693c8dc5e996a7664cf6f3d61a8 /Userland/Libraries/LibJS/Runtime/Value.h | |
parent | 630d83be8f3e151f884f609d381603169bd20112 (diff) | |
download | serenity-c8382c32e9b840d0a7bde0802b87f63188488982.zip |
LibJS: Split Value::Type::Number into Int32 and Double
We now store 32-bit integers as 32-bit integers directly which avoids
having to convert them from doubles when they're only used as 32-bit
integers anyway. :^)
This patch feels a bit incomplete and there's a lot of opportunities
to take advantage of this information. We'll have to find and exploit
them eventually.
Diffstat (limited to 'Userland/Libraries/LibJS/Runtime/Value.h')
-rw-r--r-- | Userland/Libraries/LibJS/Runtime/Value.h | 43 |
1 files changed, 32 insertions, 11 deletions
diff --git a/Userland/Libraries/LibJS/Runtime/Value.h b/Userland/Libraries/LibJS/Runtime/Value.h index 1261bbfa65..4bf25007a8 100644 --- a/Userland/Libraries/LibJS/Runtime/Value.h +++ b/Userland/Libraries/LibJS/Runtime/Value.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Andreas Kling <kling@serenityos.org> + * Copyright (c) 2020-2021, Andreas Kling <kling@serenityos.org> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -47,7 +47,8 @@ public: Empty, Undefined, Null, - Number, + Int32, + Double, String, Object, Boolean, @@ -66,7 +67,7 @@ public: bool is_empty() const { return m_type == Type::Empty; } bool is_undefined() const { return m_type == Type::Undefined; } bool is_null() const { return m_type == Type::Null; } - bool is_number() const { return m_type == Type::Number; } + bool is_number() const { return m_type == Type::Int32 || m_type == Type::Double; } bool is_string() const { return m_type == Type::String; } bool is_object() const { return m_type == Type::Object; } bool is_boolean() const { return m_type == Type::Boolean; } @@ -107,21 +108,31 @@ public: } explicit Value(double value) - : m_type(Type::Number) { - m_value.as_double = value; + if (value >= NumericLimits<i32>::min() && value <= NumericLimits<i32>::max() && static_cast<i32>(value) == value) { + m_type = Type::Int32; + m_value.as_i32 = static_cast<i32>(value); + } else { + m_type = Type::Double; + m_value.as_double = value; + } } explicit Value(unsigned value) - : m_type(Type::Number) { - m_value.as_double = static_cast<double>(value); + if (value > NumericLimits<i32>::max()) { + m_value.as_double = static_cast<double>(value); + m_type = Type::Double; + } else { + m_value.as_i32 = static_cast<i32>(value); + m_type = Type::Int32; + } } explicit Value(i32 value) - : m_type(Type::Number) + : m_type(Type::Int32) { - m_value.as_double = value; + m_value.as_i32 = value; } Value(const Object* object) @@ -169,7 +180,9 @@ public: double as_double() const { - VERIFY(type() == Type::Number); + VERIFY(is_number()); + if (m_type == Type::Int32) + return m_value.as_i32; return m_value.as_double; } @@ -254,7 +267,12 @@ public: Value to_number(GlobalObject&) const; BigInt* to_bigint(GlobalObject&) const; double to_double(GlobalObject&) const; - i32 to_i32(GlobalObject&) const; + i32 to_i32(GlobalObject& global_object) const + { + if (m_type == Type::Int32) + return m_value.as_i32; + return to_i32_slow_case(global_object); + } u32 to_u32(GlobalObject&) const; size_t to_length(GlobalObject&) const; size_t to_index(GlobalObject&) const; @@ -273,8 +291,11 @@ public: private: Type m_type { Type::Empty }; + i32 to_i32_slow_case(GlobalObject&) const; + union { bool as_bool; + i32 as_i32; double as_double; PrimitiveString* as_string; Symbol* as_symbol; |