Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Spider Monkey: writable objects

  • Loading branch information...
commit 781f2587997f73b6d9643930ca77eb3733c4b773 1 parent 426bfdf
@erh erh authored
Showing with 74 additions and 16 deletions.
  1. +15 −0 jstests/eval6.js
  2. +59 −16 scripting/engine_spidermonkey.cpp
View
15 jstests/eval6.js
@@ -0,0 +1,15 @@
+
+t = db.eval6;
+t.drop();
+
+t.save( { a : 1 } );
+
+db.eval(
+ function(){
+ o = db.eval6.findOne();
+ o.b = 2;
+ db.eval6.save( o );
+ }
+);
+
+assert.eq( 2 , t.findOne().b );
View
75 scripting/engine_spidermonkey.cpp
@@ -9,6 +9,8 @@ namespace mongo {
boost::thread_specific_ptr<SMScope> currentScope( dontDeleteScope );
#define GETHOLDER(x,o) ((BSONHolder*)JS_GetPrivate( x , o ))
+
+ class BSONFieldIterator;
class BSONHolder {
public:
@@ -18,14 +20,51 @@ namespace mongo {
_inResolve = false;
}
- BSONObjIterator * it(){
- return new BSONObjIterator( _obj );
- }
+ BSONFieldIterator * it();
BSONObj _obj;
bool _inResolve;
+ list<string> _extra;
+ };
+
+ class BSONFieldIterator {
+ public:
+
+ BSONFieldIterator( BSONHolder * holder ){
+
+ BSONObjIterator it( holder->_obj );
+ while ( it.more() ){
+ BSONElement e = it.next();
+ if ( e.eoo() )
+ break;
+ _names.push_back( e.fieldName() );
+ }
+
+ _names.merge( holder->_extra );
+
+ _it = _names.begin();
+ }
+
+ bool more(){
+ return _it != _names.end();
+ }
+
+ string next(){
+ string s = *_it;
+ _it++;
+ return s;
+ }
+
+ private:
+ list<string> _names;
+ list<string>::iterator _it;
};
+ BSONFieldIterator * BSONHolder::it(){
+ return new BSONFieldIterator( this );
+ }
+
+
class Convertor : boost::noncopyable {
public:
Convertor( JSContext * cx ){
@@ -312,25 +351,20 @@ namespace mongo {
JSBool bson_enumerate( JSContext *cx, JSObject *obj, JSIterateOp enum_op, jsval *statep, jsid *idp ){
if ( enum_op == JSENUMERATE_INIT ){
- BSONObjIterator * it = GETHOLDER( cx , obj )->it();
+ BSONFieldIterator * it = GETHOLDER( cx , obj )->it();
*statep = PRIVATE_TO_JSVAL( it );
if ( idp )
*idp = JSVAL_ZERO;
return JS_TRUE;
}
- BSONObjIterator * it = (BSONObjIterator*)JSVAL_TO_PRIVATE( *statep );
+ BSONFieldIterator * it = (BSONFieldIterator*)JSVAL_TO_PRIVATE( *statep );
if ( enum_op == JSENUMERATE_NEXT ){
if ( it->more() ){
- BSONElement e = it->next();
- if ( e.eoo() ){
- *statep = 0;
- }
- else {
- Convertor c(cx);
- assert( JS_ValueToId( cx , c.toval( e.fieldName() ) , idp ) );
- }
+ string name = it->next();
+ Convertor c(cx);
+ assert( JS_ValueToId( cx , c.toval( name.c_str() ) , idp ) );
}
else {
*statep = 0;
@@ -346,7 +380,7 @@ namespace mongo {
uassert( "don't know what to do with this op" , 0 );
return JS_FALSE;
}
-
+
JSBool noaccess( JSContext *cx, JSObject *obj, jsval idval, jsval *vp){
BSONHolder * holder = GETHOLDER( cx , obj );
if ( holder->_inResolve )
@@ -362,13 +396,22 @@ namespace mongo {
JSCLASS_NO_OPTIONAL_MEMBERS
};
+ JSBool bson_add_prop( JSContext *cx, JSObject *obj, jsval idval, jsval *vp){
+ BSONHolder * holder = GETHOLDER( cx , obj );
+ if ( ! holder->_inResolve ){
+ Convertor c(cx);
+ holder->_extra.push_back( c.toString( idval ) );
+ }
+ return JS_TRUE;
+ }
+
JSClass bson_class = {
"bson_object" , JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE | JSCLASS_NEW_ENUMERATE ,
- JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
+ bson_add_prop, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
(JSEnumerateOp)bson_enumerate, (JSResolveOp)(&resolveBSONField) , JS_ConvertStub, bson_finalize ,
JSCLASS_NO_OPTIONAL_MEMBERS
};
-
+
static JSClass global_class = {
Please sign in to comment.
Something went wrong with that request. Please try again.