Ticket #4244: deserializer-cleanup.patch

File deserializer-cleanup.patch, 7.8 KB (added by Itms, 8 years ago)
  • source/simulation2/serialization/StdDeserializer.cpp

     
    2828#include "lib/byte_order.h"
    2929
    3030CStdDeserializer::CStdDeserializer(ScriptInterface& scriptInterface, std::istream& stream) :
    31     m_ScriptInterface(scriptInterface), m_Stream(stream), 
     31    m_ScriptInterface(scriptInterface), m_Stream(stream),
    3232    m_dummyObject(scriptInterface.GetJSRuntime())
    3333{
    3434    JSContext* cx = m_ScriptInterface.GetContext();
     
    104104    // but that doesn't work (at least on MSVC) since in_avail isn't
    105105    // guaranteed to return the actual number of bytes available; see e.g.
    106106    // http://social.msdn.microsoft.com/Forums/en/vclanguage/thread/13009a88-933f-4be7-bf3d-150e425e66a6#70ea562d-8605-4742-8851-1bae431ce6ce
    107    
     107
    108108    // Instead we'll just verify that it's not an extremely large number:
    109109    if (numBytes > 64*MiB)
    110110        throw PSERROR_Deserialize_OutOfBounds("RequireBytesInStream");
     
    121121    ret.set(m_ScriptBackrefs[tag]);
    122122}
    123123
    124 u32 CStdDeserializer::ReserveScriptBackref()
    125 {
    126     m_ScriptBackrefs.push_back(JS::Heap<JSObject*>(m_dummyObject));
    127     return m_ScriptBackrefs.size()-1;
    128 }
    129 
    130 void CStdDeserializer::SetReservedScriptBackref(u32 tag, JS::HandleObject obj)
    131 {
    132     ENSURE(m_ScriptBackrefs[tag] == m_dummyObject);
    133     m_ScriptBackrefs[tag] = JS::Heap<JSObject*>(obj);
    134 }
    135 
    136124void CStdDeserializer::FreeScriptBackrefs()
    137125{
    138126    m_ScriptBackrefs.clear();
     
    202190
    203191            if (hasCustomDeserialize)
    204192            {
     193                AddScriptBackref(obj);
     194
    205195                JS::RootedValue serialize(cx);
    206196                if (!JS_GetProperty(cx, obj, "Serialize", &serialize))
    207197                    throw PSERROR_Serialize_ScriptError("JS_GetProperty failed");
     
    214204
    215205                JS::RootedValue objVal(cx, JS::ObjectValue(*obj));
    216206                m_ScriptInterface.CallFunctionVoid(objVal, "Deserialize", data);
    217                
    218                 AddScriptBackref(obj);
    219                
     207
    220208                return JS::ObjectValue(*obj);
    221209            }
    222210        }
     
    352340        NumberU32_Unbounded("length", length);
    353341
    354342        // To match the serializer order, we reserve the typed array's backref tag here
    355         u32 arrayTag = ReserveScriptBackref();
     343        JS::RootedObject arrayObj(cx);
     344        AddScriptBackref(arrayObj);
    356345
    357346        // Get buffer object
    358347        JS::RootedValue bufferVal(cx, ReadScriptVal("buffer", JS::NullPtr()));
     
    364353        if (!JS_IsArrayBufferObject(bufferObj))
    365354            throw PSERROR_Deserialize_ScriptError("js_IsArrayBuffer failed");
    366355
    367         JS::RootedObject arrayObj(cx);
    368356        switch(arrayType)
    369357        {
    370358        case SCRIPT_TYPED_ARRAY_INT8:
     
    400388        if (!arrayObj)
    401389            throw PSERROR_Deserialize_ScriptError("js_CreateTypedArrayWithBuffer failed");
    402390
    403         SetReservedScriptBackref(arrayTag, arrayObj);
    404 
    405391        return JS::ObjectValue(*arrayObj);
    406392    }
    407393    case SCRIPT_TYPE_ARRAY_BUFFER:
     
    423409    case SCRIPT_TYPE_OBJECT_MAP:
    424410    {
    425411        JS::RootedObject obj(cx, JS::NewMapObject(cx));
     412        AddScriptBackref(obj);
     413
    426414        u32 mapSize;
    427415        NumberU32_Unbounded("map size", mapSize);
    428416
    429         // To match the serializer order, we reserve the map's backref tag here
    430         u32 mapTag = ReserveScriptBackref();
    431        
    432417        for (u32 i=0; i<mapSize; ++i)
    433418        {
    434419            JS::RootedValue key(cx, ReadScriptVal("map key", JS::NullPtr()));
     
    435420            JS::RootedValue value(cx, ReadScriptVal("map value", JS::NullPtr()));
    436421            JS::MapSet(cx, obj, key, value);
    437422        }
    438         SetReservedScriptBackref(mapTag, obj);
     423
    439424        return JS::ObjectValue(*obj);
    440425    }
    441426    case SCRIPT_TYPE_OBJECT_SET:
    442427    {
    443         u32 setSize;
    444         NumberU32_Unbounded("set size", setSize);
    445428        JS::RootedValue setVal(cx);
    446429        m_ScriptInterface.Eval("(new Set())", &setVal);
    447430
    448         // To match the serializer order, we reserve the set's backref tag here
    449         u32 setTag = ReserveScriptBackref();
     431        JS::RootedObject setObj(cx, &setVal.toObject());
     432        AddScriptBackref(setObj);
    450433
     434        u32 setSize;
     435        NumberU32_Unbounded("set size", setSize);
     436
    451437        for (u32 i=0; i<setSize; ++i)
    452438        {
    453439            JS::RootedValue value(cx, ReadScriptVal("set value", JS::NullPtr()));
    454440            m_ScriptInterface.CallFunctionVoid(setVal, "add", value);
    455441        }
    456         JS::RootedObject setObj(cx, &setVal.toObject());
    457         SetReservedScriptBackref(setTag, setObj);
     442
    458443        return setVal;
    459444    }
    460445    default:
     
    520505{
    521506    JSContext* cx = m_ScriptInterface.GetContext();
    522507    JSAutoRequest rq(cx);
    523    
     508
    524509    if (!objVal.isObject())
    525510        throw PSERROR_Deserialize_ScriptError();
    526511
  • source/simulation2/serialization/StdDeserializer.h

     
    1 /* Copyright (C) 2013 Wildfire Games.
     1/* Copyright (C) 2016 Wildfire Games.
    22 * This file is part of 0 A.D.
    33 *
    44 * 0 A.D. is free software: you can redistribute it and/or modify
     
    5454
    5555    virtual void AddScriptBackref(JS::HandleObject obj);
    5656    virtual void GetScriptBackref(u32 tag, JS::MutableHandleObject ret);
    57     virtual u32 ReserveScriptBackref();
    58     virtual void SetReservedScriptBackref(u32 tag, JS::HandleObject obj);
    5957    void FreeScriptBackrefs();
    6058    std::vector<JS::Heap<JSObject*> > m_ScriptBackrefs;
    6159    JS::PersistentRooted<JSObject*> m_dummyObject;
  • source/simulation2/tests/test_Serializer.h

     
    1 /* Copyright (C) 2015 Wildfire Games.
     1/* Copyright (C) 2016 Wildfire Games.
    22 * This file is part of 0 A.D.
    33 *
    44 * 0 A.D. is free software: you can redistribute it and/or modify
     
    294294        ScriptInterface script("Test", "Test", g_ScriptRuntime);
    295295        JSContext* cx = script.GetContext();
    296296        JSAutoRequest rq(cx);
    297        
     297
    298298        JS::RootedValue obj(cx);
    299299        TSM_ASSERT(msg, script.Eval(input, &obj));
    300300
     
    467467            "var arr=new Uint32Array(8);"
    468468            "for(var i=0; i<arr.length; ++i)"
    469469            "  arr[i]=(i+1)*536870912;"
    470             "arr", 
     470            "arr",
    471471        /* expected: */
    472472            "({0:536870912, 1:1073741824, 2:1610612736, 3:2147483648, 4:2684354560, 5:3221225472, 6:3758096384, 7:0})"
    473473        );
     
    476476            "var arr=new Float32Array(2);"
    477477            "arr[0]=3.4028234e38;"
    478478            "arr[1]=Infinity;"
    479             "arr", 
     479            "arr",
    480480        /* expected: */
    481481            "({0:3.4028234663852886e+38, 1:Infinity})"
    482482        );
     
    485485            "var arr=new Float64Array(2);"
    486486            "arr[0]=1.7976931348623157e308;"
    487487            "arr[1]=-Infinity;"
    488             "arr", 
     488            "arr",
    489489        /* expected: */
    490490            "({0:1.7976931348623157e+308, 1:-Infinity})"
    491491        );
     
    594594            "\x00\x00\x00\x00" // size
    595595        );
    596596
    597         helper_script_roundtrip("Set with elements and property", 
     597        helper_script_roundtrip("Set with elements and property",
    598598            "var a = new Set(); a.add(12); a.add(\"bar\"); a.foo = 27; a",
    599599        /* expected: */
    600600            "({})",
     
    673673        );
    674674
    675675        helper_script_roundtrip("Nested maps using backrefs",
    676             "var a = new Map(); var b = new Map(); b.set(1, a); b.set(2, a); b",
     676            "var a = new Map(); var b = new Map(); a.set(1, b); a.set(2, b); a",
    677677        /* expected: */
    678678            "({})",
    679679        /* expected stream: */
     
    689689            "\x05" // SCRIPT_TYPE_INT
    690690            "\x02\0\0\0" // 2
    691691            "\x08" // SCRIPT_TYPE_BACKREF
    692             "\x02\0\0\0" // ref. to object #2, i.e. "a", with #1 being "b"
     692            "\x02\0\0\0" // ref. to object #2, i.e. "b", with #1 being "a"
    693693        );
    694694    }
    695695
     
    757757        ScriptInterface script("Test", "Test", g_ScriptRuntime);
    758758        JSContext* cx = script.GetContext();
    759759        JSAutoRequest rq(cx);
    760        
     760
    761761        JS::RootedValue obj(cx);
    762762
    763763        std::stringstream stream;
     
    792792        ScriptInterface script("Test", "Test", g_ScriptRuntime);
    793793        JSContext* cx = script.GetContext();
    794794        JSAutoRequest rq(cx);
    795        
     795
    796796        JS::RootedValue obj(cx);
    797797        TS_ASSERT(script.Eval(input, &obj));
    798798