tags 704042 patch
tags 704042 upstream
thanks

I have extracted the two patches which have been committed by upstream to address the issue, attaching them. Will create a package ready for NMU later to help speed things up if desired.

Cheers,

Adrian

--
 .''`.  John Paul Adrian Glaubitz
: :' :  Debian Developer - glaub...@debian.org
`. `'   Freie Universitaet Berlin - glaub...@physik.fu-berlin.de
  `-    GPG: 62FF 8A75 84E0 2956 9546  0006 7426 3B37 F5B5 F913
>From 3c5c12f7d57ba1e44250d3e1734885a5cafaf8e2 Mon Sep 17 00:00:00 2001
From: Dan Pasette <d...@10gen.com>
Date: Tue, 26 Mar 2013 16:52:39 -0400
Subject: [PATCH] SERVER-9124: Avoid raw pointers for SM's nativeHelper

---
 scripting/engine_spidermonkey.cpp |  116 +++++++++++++++++++++++++------------
 1 file changed, 78 insertions(+), 38 deletions(-)

diff --git a/scripting/engine_spidermonkey.cpp b/scripting/engine_spidermonkey.cpp
index 64fe21c..e857b90 100644
--- a/scripting/engine_spidermonkey.cpp
+++ b/scripting/engine_spidermonkey.cpp
@@ -47,6 +47,9 @@ namespace mongo {
         }
     };
 
+    typedef std::map<long long, NativeFunction> FunctionMap;
+    typedef std::map<long long, void*> ArgumentMap;
+
     string trim( string s ) {
         while ( s.size() && isspace( s[0] ) )
             s = s.substr( 1 );
@@ -997,43 +1000,8 @@ namespace mongo {
         return JS_TRUE;
     }
 
-    JSBool native_helper( JSContext *cx , JSObject *obj , uintN argc, jsval *argv , jsval *rval ) {
-        Convertor c(cx);
-
-        NativeFunction func = (NativeFunction)((long long)c.getNumber( obj , "x" ) );
-        void* data = (void*)((long long)c.getNumber( obj , "y" ) );
-        assert( func );
-
-        BSONObj a;
-        if ( argc > 0 ) {
-            BSONObjBuilder args;
-            for ( uintN i=0; i<argc; i++ ) {
-                c.append( args , args.numStr( i ) , argv[i] );
-            }
-
-            a = args.obj();
-        }
-
-        BSONObj out;
-        try {
-            out = func( a, data );
-        }
-        catch ( std::exception& e ) {
-            JS_ReportError( cx , e.what() );
-            return JS_FALSE;
-        }
-
-        if ( out.isEmpty() ) {
-            *rval = JSVAL_VOID;
-        }
-        else {
-            *rval = c.toval( out.firstElement() );
-        }
-
-        return JS_TRUE;
-    }
-
     JSBool native_load( JSContext *cx , JSObject *obj , uintN argc, jsval *argv , jsval *rval );
+    JSBool native_helper( JSContext *cx , JSObject *obj , uintN argc, jsval *argv , jsval *rval );
 
     JSBool native_gc( JSContext *cx , JSObject *obj , uintN argc, jsval *argv , jsval *rval ) {
         JS_GC( cx );
@@ -1611,11 +1579,17 @@ namespace mongo {
         void injectNative( const char *field, NativeFunction func, void* data ) {
             smlock;
             string name = field;
-            _convertor->setProperty( _global , (name + "_").c_str() , _convertor->toval( (double)(long long)func ) );
+            long long funcId = static_cast<long long>(_functionMap.size());
+            _functionMap.insert(make_pair(funcId, func));
+            jsval v = _convertor->toval(funcId);
+            _convertor->setProperty(_global, (name + "_").c_str(), v);
 
             stringstream code;
             if (data) {
-                _convertor->setProperty( _global , (name + "_data_").c_str() , _convertor->toval( (double)(long long)data ) );
+                long long argsId = static_cast<long long>(_argumentMap.size());
+                _argumentMap.insert(make_pair(argsId, data));
+                v = _convertor->toval(argsId);
+                _convertor->setProperty(_global, (name + "_data_").c_str(), v);
                 code << field << "_" << " = { x : " << field << "_ , y: " << field << "_data_ }; ";
             } else {
                 code << field << "_" << " = { x : " << field << "_ }; ";
@@ -1631,6 +1605,10 @@ namespace mongo {
 
         JSContext *SavedContext() const { return _context; }
 
+        // map from internal function id to function pointer
+        FunctionMap _functionMap;
+        // map from internal function argument id to function pointer
+        ArgumentMap _argumentMap;
     private:
 
         void _postCreateHacks() {
@@ -1696,7 +1674,69 @@ namespace mongo {
         return JS_TRUE;
     }
 
+    JSBool native_helper( JSContext *cx , JSObject *obj , uintN argc, jsval *argv , jsval *rval ) {
+        try {
+            Convertor c(cx);
+
+            // get function pointer from JS caller's argument property 'x'
+            massert(16735, "nativeHelper argument requires object with 'x' property",
+                    c.hasProperty(obj, "x"));
+            FunctionMap::iterator funcIter =
+                    currentScope->_functionMap.find(static_cast<long long>(c.getNumber(obj, "x")));
+            massert(16734, "JavaScript function not in map",
+                    funcIter != currentScope->_functionMap.end());
+            NativeFunction func = funcIter->second;
+            assert(func);
+
+            // get data pointer from JS caller's argument property 'y'
+            void* data = NULL;
+            if (c.hasProperty(obj, "y")) {
+                ArgumentMap::iterator argIter = currentScope->_argumentMap.find(
+                                static_cast<long long>(c.getNumber(obj, "y")));
+                massert(16736, "nativeHelper 'y' parameter must be in the argumentMap",
+                        argIter != currentScope->_argumentMap.end());
+                data = argIter->second;
+            }
+
+            BSONObj a;
+            if ( argc > 0 ) {
+                BSONObjBuilder args;
+                for ( uintN i = 0; i < argc; ++i ) {
+                    c.append( args , args.numStr( i ) , argv[i] );
+                }
+                a = args.obj();
+            }
+
+            BSONObj out;
+            try {
+                out = func( a, data );
+            }
+            catch ( std::exception& e ) {
+                if ( ! JS_IsExceptionPending( cx ) ) {
+                    JS_ReportError( cx, e.what() );
+                }
+                return JS_FALSE;
+            }
 
+            if ( out.isEmpty() ) {
+                *rval = JSVAL_VOID;
+            }
+            else {
+                *rval = c.toval( out.firstElement() );
+            }
+        }
+        catch ( const AssertionException& e ) {
+            if ( ! JS_IsExceptionPending( cx ) ) {
+                JS_ReportError( cx, e.what() );
+            }
+            return JS_FALSE;
+        }
+        catch ( const std::exception& e ) {
+            log() << "unhandled exception: " << e.what() << ", throwing Fatal Assertion" << endl;
+            verifyFailed( 16281 );
+        }
+        return JS_TRUE;
+    }
 
     void SMEngine::runTest() {
         SMScope s;
-- 
1.7.10.4

>From bb999bb5032346e4391d80225b1532bc43df9446 Mon Sep 17 00:00:00 2001
From: Ben Becker <ben.bec...@10gen.com>
Date: Tue, 26 Mar 2013 18:33:20 -0700
Subject: [PATCH] SERVER-9124: cast id to double before converting to JS

---
 scripting/engine_spidermonkey.cpp |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/scripting/engine_spidermonkey.cpp b/scripting/engine_spidermonkey.cpp
index e857b90..e409e6f 100644
--- a/scripting/engine_spidermonkey.cpp
+++ b/scripting/engine_spidermonkey.cpp
@@ -1581,14 +1581,14 @@ namespace mongo {
             string name = field;
             long long funcId = static_cast<long long>(_functionMap.size());
             _functionMap.insert(make_pair(funcId, func));
-            jsval v = _convertor->toval(funcId);
+            jsval v = _convertor->toval((static_cast<double>(funcId)));
             _convertor->setProperty(_global, (name + "_").c_str(), v);
-
             stringstream code;
+
             if (data) {
                 long long argsId = static_cast<long long>(_argumentMap.size());
                 _argumentMap.insert(make_pair(argsId, data));
-                v = _convertor->toval(argsId);
+                v = _convertor->toval(static_cast<double>(argsId));
                 _convertor->setProperty(_global, (name + "_data_").c_str(), v);
                 code << field << "_" << " = { x : " << field << "_ , y: " << field << "_data_ }; ";
             } else {
-- 
1.7.10.4

Reply via email to