Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

SERVER-9124: avoid raw pointers for SM's nativeHelper

  • Loading branch information...
commit 4c93c589bca1099b78e8b0fe48b64e434eb462f1 1 parent cb9f8b3
Ben Becker vrtx authored

Showing 1 changed file with 76 additions and 51 deletions. Show diff stats Hide diff stats

  1. +76 51 src/mongo/scripting/engine_spidermonkey.cpp
127 src/mongo/scripting/engine_spidermonkey.cpp
@@ -45,6 +45,9 @@
45 45
46 46 namespace mongo {
47 47
  48 + typedef std::map<double, NativeFunction> FunctionMap;
  49 + typedef std::map<double, void*> ArgumentMap;
  50 +
48 51 string trim( string s ) {
49 52 while ( s.size() && isspace( s[0] ) )
50 53 s = s.substr( 1 );
@@ -1174,56 +1177,8 @@ namespace mongo {
1174 1177 return JS_TRUE;
1175 1178 }
1176 1179
1177   - JSBool native_helper( JSContext *cx , JSObject *obj , uintN argc, jsval *argv , jsval *rval ) {
1178   - try {
1179   - Convertor c(cx);
1180   - NativeFunction func = reinterpret_cast<NativeFunction>(
1181   - static_cast<long long>( c.getNumber( obj , "x" ) ) );
1182   - void* data = reinterpret_cast<void*>(
1183   - static_cast<long long>( c.getNumber( obj , "y" ) ) );
1184   - verify( func );
1185   -
1186   - BSONObj a;
1187   - if ( argc > 0 ) {
1188   - BSONObjBuilder args;
1189   - for ( uintN i = 0; i < argc; ++i ) {
1190   - c.append( args , args.numStr( i ) , argv[i] );
1191   - }
1192   - a = args.obj();
1193   - }
1194   -
1195   - BSONObj out;
1196   - try {
1197   - out = func( a, data );
1198   - }
1199   - catch ( std::exception& e ) {
1200   - if ( ! JS_IsExceptionPending( cx ) ) {
1201   - JS_ReportError( cx, e.what() );
1202   - }
1203   - return JS_FALSE;
1204   - }
1205   -
1206   - if ( out.isEmpty() ) {
1207   - *rval = JSVAL_VOID;
1208   - }
1209   - else {
1210   - *rval = c.toval( out.firstElement() );
1211   - }
1212   - }
1213   - catch ( const AssertionException& e ) {
1214   - if ( ! JS_IsExceptionPending( cx ) ) {
1215   - JS_ReportError( cx, e.what() );
1216   - }
1217   - return JS_FALSE;
1218   - }
1219   - catch ( const std::exception& e ) {
1220   - log() << "unhandled exception: " << e.what() << ", throwing Fatal Assertion" << endl;
1221   - fassertFailed( 16281 );
1222   - }
1223   - return JS_TRUE;
1224   - }
1225   -
1226 1180 JSBool native_load( JSContext *cx , JSObject *obj , uintN argc, jsval *argv , jsval *rval );
  1181 + JSBool native_helper(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
1227 1182
1228 1183 JSBool native_gc( JSContext *cx , JSObject *obj , uintN argc, jsval *argv , jsval *rval ) {
1229 1184 JS_GC( cx );
@@ -1869,12 +1824,16 @@ namespace mongo {
1869 1824 smlock;
1870 1825 string name = field;
1871 1826 jsval v;
1872   - v = _convertor->toval( static_cast<double>( reinterpret_cast<long long>(func) ) );
  1827 + double funcId = static_cast<double>(_functionMap.size());
  1828 + _functionMap.insert(make_pair(funcId, func));
  1829 + v = _convertor->toval(funcId);
1873 1830 _convertor->setProperty( _global, (name + "_").c_str(), v );
1874 1831
1875 1832 stringstream code;
1876 1833 if (data) {
1877   - v = _convertor->toval( static_cast<double>( reinterpret_cast<long long>(data) ) );
  1834 + double argsId = static_cast<double>(_argumentMap.size());
  1835 + _argumentMap.insert(make_pair(argsId, data));
  1836 + v = _convertor->toval(argsId);
1878 1837 _convertor->setProperty( _global, (name + "_data_").c_str(), v );
1879 1838 code << field << "_" << " = { x : " << field << "_ , y: " << field << "_data_ }; ";
1880 1839 } else {
@@ -1892,6 +1851,10 @@ namespace mongo {
1892 1851
1893 1852 JSContext *SavedContext() const { return _context; }
1894 1853
  1854 + // map from internal function id to function pointer
  1855 + FunctionMap _functionMap;
  1856 + // map from internal function argument id to function pointer
  1857 + ArgumentMap _argumentMap;
1895 1858 private:
1896 1859
1897 1860 void _postCreateHacks() {
@@ -1970,7 +1933,69 @@ namespace mongo {
1970 1933 return JS_TRUE;
1971 1934 }
1972 1935
  1936 + JSBool native_helper( JSContext *cx , JSObject *obj , uintN argc, jsval *argv , jsval *rval ) {
  1937 + try {
  1938 + Convertor c(cx);
  1939 +
  1940 + // get function pointer from JS caller's argument property 'x'
  1941 + massert(16735, "nativeHelper argument requires object with 'x' property",
  1942 + c.hasProperty(obj, "x"));
  1943 + double functionAddress = c.getNumber(obj, "x");
  1944 + FunctionMap::iterator funcIter = currentScope->_functionMap.find(functionAddress);
  1945 + massert(16734, "JavaScript function not in map",
  1946 + funcIter != currentScope->_functionMap.end());
  1947 + NativeFunction func = funcIter->second;
  1948 + verify(func);
  1949 +
  1950 + // get data pointer from JS caller's argument property 'y'
  1951 + void* data = NULL;
  1952 + if (c.hasProperty(obj, "y")) {
  1953 + double argumentAddress = c.getNumber(obj, "y");
  1954 + ArgumentMap::iterator argIter = currentScope->_argumentMap.find(argumentAddress);
  1955 + massert(16736, "nativeHelper 'y' parameter must be in the argumentMap",
  1956 + argIter != currentScope->_argumentMap.end());
  1957 + data = argIter->second;
  1958 + }
  1959 +
  1960 + BSONObj a;
  1961 + if ( argc > 0 ) {
  1962 + BSONObjBuilder args;
  1963 + for ( uintN i = 0; i < argc; ++i ) {
  1964 + c.append( args , args.numStr( i ) , argv[i] );
  1965 + }
  1966 + a = args.obj();
  1967 + }
  1968 +
  1969 + BSONObj out;
  1970 + try {
  1971 + out = func( a, data );
  1972 + }
  1973 + catch ( std::exception& e ) {
  1974 + if ( ! JS_IsExceptionPending( cx ) ) {
  1975 + JS_ReportError( cx, e.what() );
  1976 + }
  1977 + return JS_FALSE;
  1978 + }
1973 1979
  1980 + if ( out.isEmpty() ) {
  1981 + *rval = JSVAL_VOID;
  1982 + }
  1983 + else {
  1984 + *rval = c.toval( out.firstElement() );
  1985 + }
  1986 + }
  1987 + catch ( const AssertionException& e ) {
  1988 + if ( ! JS_IsExceptionPending( cx ) ) {
  1989 + JS_ReportError( cx, e.what() );
  1990 + }
  1991 + return JS_FALSE;
  1992 + }
  1993 + catch ( const std::exception& e ) {
  1994 + log() << "unhandled exception: " << e.what() << ", throwing Fatal Assertion" << endl;
  1995 + fassertFailed( 16281 );
  1996 + }
  1997 + return JS_TRUE;
  1998 + }
1974 1999
1975 2000 void SMEngine::runTest() {
1976 2001 SMScope s;

0 comments on commit 4c93c58

Please sign in to comment.
Something went wrong with that request. Please try again.