// TODO: This function identification code is broken. Fix it up to be more robust // // See: SERVER-16703 for more info void MozJSImplScope::_MozJSCreateFunction(const char* raw, ScriptingFunction functionNumber, JS::MutableHandleValue fun) { std::string code = jsSkipWhiteSpace(raw); if (!hasFunctionIdentifier(code)) { if (code.find('\n') == std::string::npos && !hasJSReturn(code) && (code.find(';') == std::string::npos || code.find(';') == code.size() - 1)) { code = "return " + code; } code = "function(){ " + code + "}"; } code = str::stream() << "_funcs" << functionNumber << " = " << code; JS::CompileOptions co(_context); setCompileOptions(&co); _checkErrorState(JS::Evaluate(_context, _global, co, code.c_str(), code.length(), fun)); uassert(10232, "not a function", fun.isObject() && JS_ObjectIsFunction(_context, fun.toObjectOrNull())); }
JSFunction * _compileFunction( const char * raw , JSObject * assoc , const char *& gcName ) { if ( ! assoc ) assoc = JS_GetGlobalObject( _context ); while (isspace(*raw)) { raw++; } stringstream fname; fname << "cf_"; static int fnum = 1; fname << "_" << fnum++ << "_"; if ( ! hasFunctionIdentifier( raw ) ) { string s = raw; if ( isSimpleStatement( s ) ) { s = "return " + s; } gcName = "cf anon"; fname << "anon"; return JS_CompileFunction( _context , assoc , fname.str().c_str() , 0 , 0 , s.c_str() , strlen( s.c_str() ) , "nofile_a" , 0 ); } string code = raw; size_t start = code.find( '(' ); assert( start != string::npos ); fname << "_f_" << trim( code.substr( 9 , start - 9 ) ); code = code.substr( start + 1 ); size_t end = code.find( ')' ); assert( end != string::npos ); string paramString = trim( code.substr( 0 , end ) ); code = code.substr( end + 1 ); vector<string> params; while ( paramString.size() ) { size_t c = paramString.find( ',' ); if ( c == string::npos ) { params.push_back( paramString ); break; } params.push_back( trim( paramString.substr( 0 , c ) ) ); paramString = trim( paramString.substr( c + 1 ) ); paramString = trim( paramString ); } boost::scoped_array<const char *> paramArray (new const char*[params.size()]); for ( size_t i=0; i<params.size(); i++ ) paramArray[i] = params[i].c_str(); JSFunction * func = JS_CompileFunction( _context , assoc , fname.str().c_str() , params.size() , paramArray.get() , code.c_str() , strlen( code.c_str() ) , "nofile_b" , 0 ); if ( ! func ) { cout << "compile failed for: " << raw << endl; return 0; } gcName = "cf normal"; return func; }