diff --git a/shared/src/helpers/Convert.cpp b/shared/src/helpers/Convert.cpp index 4c056f81f..6e49ff78a 100644 --- a/shared/src/helpers/Convert.cpp +++ b/shared/src/helpers/Convert.cpp @@ -155,25 +155,25 @@ alt::MValue js::JSToMValue(v8::Local val, bool allowFunction) if(resource->IsVector3(v8Obj)) { alt::Vector3f vec; - vec[0] = obj.Get("x"); - vec[1] = obj.Get("y"); - vec[2] = obj.Get("z"); + vec[0] = obj.Get("x"); + vec[1] = obj.Get("y"); + vec[2] = obj.Get("z"); return core.CreateMValueVector3(vec); } else if(resource->IsVector2(v8Obj)) { alt::Vector2f vec; - vec[0] = obj.Get("x"); - vec[1] = obj.Get("y"); + vec[0] = obj.Get("x"); + vec[1] = obj.Get("y"); return core.CreateMValueVector2(vec); } else if(resource->IsRGBA(v8Obj)) { alt::RGBA rgba; - rgba.r = obj.Get("r"); - rgba.g = obj.Get("g"); - rgba.b = obj.Get("b"); - rgba.a = obj.Get("a"); + rgba.r = obj.Get("r"); + rgba.g = obj.Get("g"); + rgba.b = obj.Get("b"); + rgba.a = obj.Get("a"); return core.CreateMValueRGBA(rgba); } else if(resource->IsBaseObject(v8Obj)) diff --git a/shared/src/helpers/Convert.h b/shared/src/helpers/Convert.h index 7b7089f5a..3bd1be165 100644 --- a/shared/src/helpers/Convert.h +++ b/shared/src/helpers/Convert.h @@ -133,6 +133,23 @@ namespace js alt::MValueByteArray JSToRawBytes(v8::Local val, IResource* resource); v8::MaybeLocal RawBytesToJS(alt::MValueByteArrayConst val, IResource* resource); + // Creates a string that's cached by V8, only use this for constant strings which are commonly used, otherwise it explodes RAM usage! + template + inline v8::Local CachedString(const char (&val)[N]) + { + return v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), val, v8::NewStringType::kInternalized, N - 1).ToLocalChecked(); + } + inline v8::Local CachedString(const std::string& val) + { + return v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), val.data(), v8::NewStringType::kInternalized, (int)val.size()).ToLocalChecked(); + } + + template + inline v8::Local JSValue(const char (&val)[N]) + { + if constexpr(N == 1) return v8::String::Empty(v8::Isolate::GetCurrent()); + return v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), val, v8::NewStringType::kNormal, N - 1).ToLocalChecked(); + } inline v8::Local JSValue(const char* val) { if(val == nullptr) return v8::String::Empty(v8::Isolate::GetCurrent()); diff --git a/shared/src/helpers/JS.h b/shared/src/helpers/JS.h index cb5c8246f..8dd479938 100644 --- a/shared/src/helpers/JS.h +++ b/shared/src/helpers/JS.h @@ -197,10 +197,10 @@ namespace js void SetMethod(const std::string& key, internal::FunctionCallback func); // Falls back to default value if the value is not found or the type doesn't match - template + template T Get(const std::string& key, const T& defaultValue = T()) const { - v8::MaybeLocal maybeVal = object->Get(context, js::JSValue(key)); + v8::MaybeLocal maybeVal = object->Get(context, InternalizedString ? js::CachedString(key) : js::JSValue(key)); v8::Local val; if(!maybeVal.ToLocal(&val)) return defaultValue; std::optional result = js::CppValue(val); @@ -208,11 +208,11 @@ namespace js } // Throws an error and returns false if the value is not found or the type doesn't match - template + template bool Get(const std::string& key, T& out, bool throwOnError = true) { using Type = std::conditional_t, int, T>; - v8::MaybeLocal maybeVal = object->Get(context, js::JSValue(key)); + v8::MaybeLocal maybeVal = object->Get(context, InternalizedString ? js::CachedString(key) : js::JSValue(key)); v8::Local val; if(!maybeVal.ToLocal(&val)) { @@ -229,18 +229,19 @@ namespace js return true; } + template bool GetAsHash(const std::string& key, uint32_t& outValue) { Type argType = GetType(key); if(argType == Type::STRING) { - std::string val = Get(key); + std::string val = Get(key); outValue = alt::ICore::Instance().Hash(val); return true; } else if(argType == Type::NUMBER) { - uint32_t val = Get(key); + uint32_t val = Get(key); outValue = val; return true; } diff --git a/shared/src/helpers/ValueBuffer.cpp b/shared/src/helpers/ValueBuffer.cpp index 2b6888127..e4527948e 100644 --- a/shared/src/helpers/ValueBuffer.cpp +++ b/shared/src/helpers/ValueBuffer.cpp @@ -128,7 +128,7 @@ bool js::ValueSerializer::Entity(v8::Local& value) bool js::ValueSerializer::Vector3(v8::Local& value) { js::Object obj = value.As(); - alt::Vector3f vector{ obj.Get("x"), obj.Get("y"), obj.Get("z") }; + alt::Vector3f vector{ obj.Get("x"), obj.Get("y"), obj.Get("z") }; Float(vector[0]); Float(vector[1]); @@ -139,7 +139,7 @@ bool js::ValueSerializer::Vector3(v8::Local& value) bool js::ValueSerializer::Vector2(v8::Local& value) { js::Object obj = value.As(); - alt::Vector2f vector{ obj.Get("x"), obj.Get("y") }; + alt::Vector2f vector{ obj.Get("x"), obj.Get("y") }; Float(vector[0]); Float(vector[1]); @@ -149,7 +149,7 @@ bool js::ValueSerializer::Vector2(v8::Local& value) bool js::ValueSerializer::RGBA(v8::Local& value) { js::Object obj = value.As(); - alt::RGBA rgba{ obj.Get("r"), obj.Get("g"), obj.Get("b"), obj.Get("a") }; + alt::RGBA rgba{ obj.Get("r"), obj.Get("g"), obj.Get("b"), obj.Get("a") }; Byte(rgba.r); Byte(rgba.g); @@ -161,7 +161,7 @@ bool js::ValueSerializer::RGBA(v8::Local& value) bool js::ValueSerializer::Quaternion(v8::Local& value) { js::Object obj = value.As(); - alt::Quaternion quaternion{ obj.Get("x"), obj.Get("y"), obj.Get("z"), obj.Get("w") }; + alt::Quaternion quaternion{ obj.Get("x"), obj.Get("y"), obj.Get("z"), obj.Get("w") }; Float(quaternion.x); Float(quaternion.y);