mirror of
https://gitea.wildfiregames.com/0ad/0ad
synced 2026-06-16 05:13:58 -07:00
BinarySerializer: avoid creating unnecessary ScriptRequest
This commit is contained in:
parent
ab6a420f78
commit
bcd0e12cc3
3 changed files with 23 additions and 22 deletions
|
|
@ -72,10 +72,13 @@ CBinarySerializerScriptImpl::~CBinarySerializerScriptImpl()
|
|||
JS_RemoveExtraGCRootsTracer(rq.cx, Trace, this);
|
||||
}
|
||||
|
||||
void CBinarySerializerScriptImpl::HandleScriptVal(JS::HandleValue val)
|
||||
void CBinarySerializerScriptImpl::PutScriptVal(JS::HandleValue val)
|
||||
{
|
||||
ScriptRequest rq(m_ScriptInterface);
|
||||
HandleScriptVal(ScriptRequest(m_ScriptInterface), val);
|
||||
}
|
||||
|
||||
void CBinarySerializerScriptImpl::HandleScriptVal(const ScriptRequest& rq, JS::HandleValue val)
|
||||
{
|
||||
switch (JS_TypeOfValue(rq.cx, val))
|
||||
{
|
||||
case JSTYPE_UNDEFINED:
|
||||
|
|
@ -94,7 +97,7 @@ void CBinarySerializerScriptImpl::HandleScriptVal(JS::HandleValue val)
|
|||
JS::RootedObject obj(rq.cx, &val.toObject());
|
||||
|
||||
// If we've already serialized this object, just output a reference to it
|
||||
u32 tag = GetScriptBackrefTag(obj);
|
||||
u32 tag = GetScriptBackrefTag(rq, obj);
|
||||
if (tag != 0)
|
||||
{
|
||||
m_Serializer.NumberU8_Unbounded("type", SCRIPT_TYPE_BACKREF);
|
||||
|
|
@ -131,7 +134,7 @@ void CBinarySerializerScriptImpl::HandleScriptVal(JS::HandleValue val)
|
|||
// Now handle its array buffer
|
||||
// this may be a backref, since ArrayBuffers can be shared by multiple views
|
||||
JS::RootedValue bufferVal(rq.cx, JS::ObjectValue(*JS_GetArrayBufferViewBuffer(rq.cx, obj, &sharedMemory)));
|
||||
HandleScriptVal(bufferVal);
|
||||
HandleScriptVal(rq, bufferVal);
|
||||
break;
|
||||
}
|
||||
else if (JS::IsArrayBufferObject(obj))
|
||||
|
|
@ -179,8 +182,8 @@ void CBinarySerializerScriptImpl::HandleScriptVal(JS::HandleValue val)
|
|||
ENSURE(JS_GetElement(rq.cx, keyValuePairObj, 0, &key));
|
||||
ENSURE(JS_GetElement(rq.cx, keyValuePairObj, 1, &value));
|
||||
|
||||
HandleScriptVal(key);
|
||||
HandleScriptVal(value);
|
||||
HandleScriptVal(rq, key);
|
||||
HandleScriptVal(rq, value);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -208,7 +211,7 @@ void CBinarySerializerScriptImpl::HandleScriptVal(JS::HandleValue val)
|
|||
if (done)
|
||||
break;
|
||||
|
||||
HandleScriptVal(value);
|
||||
HandleScriptVal(rq, value);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -283,7 +286,7 @@ void CBinarySerializerScriptImpl::HandleScriptVal(JS::HandleValue val)
|
|||
JS::RootedString str(rq.cx, JS::ToString(rq.cx, val));
|
||||
if (!str)
|
||||
throw PSERROR_Serialize_ScriptError("JS_ValueToString failed");
|
||||
ScriptString("value", str);
|
||||
ScriptString(rq, "value", str);
|
||||
break;
|
||||
}
|
||||
else if (protokey == JSProto_Boolean)
|
||||
|
|
@ -332,12 +335,12 @@ void CBinarySerializerScriptImpl::HandleScriptVal(JS::HandleValue val)
|
|||
if (!idstr)
|
||||
throw PSERROR_Serialize_ScriptError("JS_ValueToString failed");
|
||||
|
||||
ScriptString("prop name", idstr);
|
||||
ScriptString(rq, "prop name", idstr);
|
||||
|
||||
if (!JS_GetPropertyById(rq.cx, obj, id, &propval))
|
||||
throw PSERROR_Serialize_ScriptError("JS_GetPropertyById failed");
|
||||
|
||||
HandleScriptVal(propval);
|
||||
HandleScriptVal(rq, propval);
|
||||
}
|
||||
|
||||
break;
|
||||
|
|
@ -378,7 +381,7 @@ void CBinarySerializerScriptImpl::HandleScriptVal(JS::HandleValue val)
|
|||
{
|
||||
m_Serializer.NumberU8_Unbounded("type", SCRIPT_TYPE_STRING);
|
||||
JS::RootedString stringVal(rq.cx, val.toString());
|
||||
ScriptString("string", stringVal);
|
||||
ScriptString(rq, "string", stringVal);
|
||||
break;
|
||||
}
|
||||
case JSTYPE_NUMBER:
|
||||
|
|
@ -427,10 +430,8 @@ void CBinarySerializerScriptImpl::HandleScriptVal(JS::HandleValue val)
|
|||
}
|
||||
}
|
||||
|
||||
void CBinarySerializerScriptImpl::ScriptString(const char* name, JS::HandleString string)
|
||||
void CBinarySerializerScriptImpl::ScriptString(const ScriptRequest& rq, const char* name, JS::HandleString string)
|
||||
{
|
||||
ScriptRequest rq(m_ScriptInterface);
|
||||
|
||||
#if BYTE_ORDER != LITTLE_ENDIAN
|
||||
#error TODO: probably need to convert JS strings to little-endian
|
||||
#endif
|
||||
|
|
@ -465,15 +466,13 @@ void CBinarySerializerScriptImpl::Trace(JSTracer *trc, void *data)
|
|||
serializer->m_ScriptBackrefTags.trace(trc);
|
||||
}
|
||||
|
||||
u32 CBinarySerializerScriptImpl::GetScriptBackrefTag(JS::HandleObject obj)
|
||||
u32 CBinarySerializerScriptImpl::GetScriptBackrefTag(const ScriptRequest& rq, JS::HandleObject obj)
|
||||
{
|
||||
// To support non-tree structures (e.g. "var x = []; var y = [x, x];"), we need a way
|
||||
// to indicate multiple references to one object(/array). So every time we serialize a
|
||||
// new object, we give it a new tag; when we serialize it a second time we just refer
|
||||
// to that tag.
|
||||
|
||||
ScriptRequest rq(m_ScriptInterface);
|
||||
|
||||
ObjectTagMap::Ptr ptr = m_ScriptBackrefTags.lookup(JS::Heap<JSObject*>(obj.get()));
|
||||
if (!ptr.found())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -86,9 +86,10 @@ public:
|
|||
CBinarySerializerScriptImpl(const ScriptInterface& scriptInterface, ISerializer& serializer);
|
||||
~CBinarySerializerScriptImpl();
|
||||
|
||||
void ScriptString(const char* name, JS::HandleString string);
|
||||
void HandleScriptVal(JS::HandleValue val);
|
||||
void PutScriptVal(JS::HandleValue val);
|
||||
private:
|
||||
void ScriptString(const ScriptRequest& rq, const char* name, JS::HandleString string);
|
||||
void HandleScriptVal(const ScriptRequest& rq, JS::HandleValue val);
|
||||
static void Trace(JSTracer* trc, void* data);
|
||||
|
||||
const ScriptInterface& m_ScriptInterface;
|
||||
|
|
@ -97,7 +98,7 @@ private:
|
|||
using ObjectTagMap = JS::GCHashMap<JS::Heap<JSObject*>, u32, js::StableCellHasher<JSObject*>, js::SystemAllocPolicy>;
|
||||
ObjectTagMap m_ScriptBackrefTags;
|
||||
u32 m_ScriptBackrefsNext;
|
||||
u32 GetScriptBackrefTag(JS::HandleObject obj);
|
||||
u32 GetScriptBackrefTag(const ScriptRequest& rq, JS::HandleObject obj);
|
||||
|
||||
JS::PropertyKey m_SerializePropId;
|
||||
JS::PropertyKey m_DeserializePropId;
|
||||
|
|
@ -205,7 +206,7 @@ protected:
|
|||
|
||||
virtual void PutScriptVal(const char* UNUSED(name), JS::MutableHandleValue value)
|
||||
{
|
||||
m_ScriptImpl->HandleScriptVal(value);
|
||||
m_ScriptImpl->PutScriptVal(value);
|
||||
}
|
||||
|
||||
virtual void PutRaw(const char* name, const u8* data, size_t len)
|
||||
|
|
|
|||
|
|
@ -35,7 +35,8 @@
|
|||
CStdDeserializer::CStdDeserializer(const ScriptInterface& scriptInterface, std::istream& stream) :
|
||||
m_ScriptInterface(scriptInterface), m_Stream(stream)
|
||||
{
|
||||
JS_AddExtraGCRootsTracer(ScriptRequest(scriptInterface).cx, CStdDeserializer::Trace, this);
|
||||
ScriptRequest rq(m_ScriptInterface);
|
||||
JS_AddExtraGCRootsTracer(rq.cx, CStdDeserializer::Trace, this);
|
||||
m_SerializePropId = JS::PropertyKey::fromPinnedString(JS_AtomizeAndPinString(rq.cx, "Serialize"));
|
||||
m_DeserializePropId = JS::PropertyKey::fromPinnedString(JS_AtomizeAndPinString(rq.cx, "Deserialize"));
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue