diff --git a/dbtests/jstests.cpp b/dbtests/jstests.cpp index 8440b2e712c..9a1c9de2345 100644 --- a/dbtests/jstests.cpp +++ b/dbtests/jstests.cpp @@ -359,8 +359,37 @@ namespace JSTests { ASSERT_EQUALS( NumberDouble , out["b"].type() ); ASSERT_EQUALS( NumberInt , out["a"].type() ); + + // -- C -- + { + BSONObjBuilder b ; + + { + BSONObjBuilder c; + c.append( "0" , 5.5 ); + c.append( "1" , 6 ); + b.appendArray( "a" , c.obj() ); + } + + o = b.obj(); + } + + ASSERT_EQUALS( NumberDouble , o["a"].embeddedObjectUserCheck()["0"].type() ); + ASSERT_EQUALS( NumberInt , o["a"].embeddedObjectUserCheck()["1"].type() ); + + s->setObject( "z" , o , false ); + out = s->getObject( "z" ); + + ASSERT_EQUALS( NumberDouble , out["a"].embeddedObjectUserCheck()["0"].type() ); + ASSERT_EQUALS( NumberInt , out["a"].embeddedObjectUserCheck()["1"].type() ); + + s->invokeSafe( "z.z = 5;" , BSONObj() ); + out = s->getObject( "z" ); + ASSERT_EQUALS( 5 , out["z"].number() ); + ASSERT_EQUALS( NumberDouble , out["a"].embeddedObjectUserCheck()["0"].type() ); + ASSERT_EQUALS( NumberDouble , out["a"].embeddedObjectUserCheck()["1"].type() ); // TODO: this is technically bad, but here to make sure that i understand the behavior delete s; } diff --git a/scripting/engine_spidermonkey.cpp b/scripting/engine_spidermonkey.cpp index 0fc147f68a9..bb3396181b5 100644 --- a/scripting/engine_spidermonkey.cpp +++ b/scripting/engine_spidermonkey.cpp @@ -19,6 +19,7 @@ namespace mongo { BSONHolder( BSONObj obj ){ _obj = obj.getOwned(); _inResolve = false; + _modified = false; _magic = 17; } @@ -32,6 +33,7 @@ namespace mongo { bool _inResolve; char _magic; list _extra; + bool _modified; }; class BSONFieldIterator { @@ -122,7 +124,10 @@ namespace mongo { BSONObj orig; if ( JS_InstanceOf( _context , o , &bson_class , 0 ) ){ - orig = GETHOLDER(_context,o)->_obj; + BSONHolder * holder = GETHOLDER(_context,o); + if ( ! holder->_modified ) + return holder->_obj; + orig = holder->_obj; } BSONObjBuilder b; @@ -511,18 +516,26 @@ namespace mongo { if ( ! holder->_inResolve ){ Convertor c(cx); holder->_extra.push_back( c.toString( idval ) ); + holder->_modified = true; } return JS_TRUE; } + + JSBool mark_modified( JSContext *cx, JSObject *obj, jsval idval, jsval *vp){ + BSONHolder * holder = GETHOLDER( cx , obj ); + if ( holder->_inResolve ) + return JS_TRUE; + holder->_modified = true; + return JS_TRUE; + } + JSClass bson_class = { "bson_object" , JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE | JSCLASS_NEW_ENUMERATE , - bson_add_prop, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, + bson_add_prop, mark_modified, JS_PropertyStub, mark_modified, (JSEnumerateOp)bson_enumerate, (JSResolveOp)(&resolveBSONField) , JS_ConvertStub, bson_finalize , JSCLASS_NO_OPTIONAL_MEMBERS }; - - static JSClass global_class = { "global", JSCLASS_GLOBAL_FLAGS,