Spider Monkey: writable objects

This commit is contained in:
Eliot Horowitz
2009-05-10 09:24:54 -04:00
parent 426bfdfe08
commit 781f258799
2 changed files with 74 additions and 16 deletions

View File

@@ -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 = {