Example #1
0
/* less bloat but this only works with 4 byte argv values
 */
bool ControllerListener::call(const char *funcname, int argc, jsval *argv) {
    jsval fval = JSVAL_VOID;
    jsval ret = JSVAL_VOID;
    JSBool res;
    
    func("calling js %s.%s()", name, funcname);
    JS_SetContextThread(jsContext);
    JS_BeginRequest(jsContext);
    res = JS_GetProperty(jsContext, jsObject, funcname, &fval);
    if(!res || JSVAL_IS_VOID(fval)) {
        // using func() instead of error() because this is not a real error condition.
        // controller could ask for unregistered functions ...
        // for instance in the case of a keyboardcontroller which propagates keystrokes 
        // for unregistered keys 
        func("method %s not found in %s controller", funcname, name);
        JS_EndRequest(jsContext);
        JS_ClearContextThread(jsContext);
        return(false);
    }
    
    res = JS_CallFunctionValue(jsContext, jsObject, fval, argc, argv, &ret);
    JS_EndRequest(jsContext);
    JS_ClearContextThread(jsContext);

    if(res == JS_FALSE) {
        error("%s : failed call", __PRETTY_FUNCTION__);
        return(false);
    }
    
    return(true);
}
Example #2
0
bool ControllerListener::frame()
{
    jsval ret = JSVAL_VOID;
    JSBool res;
    
    JS_SetContextThread(jsContext);
    JS_BeginRequest(jsContext);

    if (!frameFunc) {
        res = JS_GetProperty(jsContext, jsObject, "frame", &frameFunc);
        if(!res || JSVAL_IS_VOID(frameFunc)) {
            error("method frame not found in TriggerController");
            JS_ClearContextThread(jsContext);
            JS_EndRequest(jsContext);
            return false;
        }
    }
    res = JS_CallFunctionValue(jsContext, jsObject, frameFunc, 0, NULL, &ret);
    JS_EndRequest(jsContext);
    JS_ClearContextThread(jsContext);
    if (res == JS_FALSE) {
        error("trigger call frame() failed, deactivate ctrl");
        //active = false;
        return false;
    }
    return true;
}
Example #3
0
int JsParser::parse(const char *command) {
  func("%u:%s:%s",__LINE__,__FILE__,__FUNCTION__);
  int eval_res;
  jsval res;
  JSString *str;

  if(!command) { /* true paranoia */
    warning("NULL command passed to javascript parser");
    return 0;
  }

  func("JS parse: %s", command);

  JsExecutionContext *new_script = new JsExecutionContext(this);
  JS_SetContextThread(new_script->cx);
  JS_BeginRequest(new_script->cx);
  eval_res = evaluate(new_script->cx, new_script->obj,
		    (const char*)"parsed command", command, strlen(command));
  JS_EndRequest(new_script->cx);
  JS_ClearContextThread(new_script->cx);
  if (eval_res)
    runtimes.append(new_script);
  else
    delete new_script;

  func("JS parse result: %i", eval_res);
  return eval_res;
}
void *StartThreadSpidermonkey(void *pData)
{// begin StartThreadSpidermonkey
        pthread_mutex_lock(&g_pSpiderMonkeyMutex);
        /*
        The following mailling list post describes how to CORRECTLY use
        the threading API support with Spidermonkey
        "Thread from SpiderMonkey newsgroup"
        http://archive.gingerall.cz/archives/public/sablot2004/msg00117.html
        */
        // Notify the Spidermonkey that we'll be processing in a thread
#ifdef ADM_JS_THREADSAFE
        JS_SetContextThread(g_pCx);
        JS_BeginRequest(g_pCx);
#endif
        bool ret = false;
        const char *pScriptFile = static_cast<const char *>(pData);
        ret = parseECMAScript(pScriptFile);
        if(ret == false)
        {
                if( actual_workbench_file )
                        ADM_dealloc(actual_workbench_file);
                actual_workbench_file = ADM_strdup(pScriptFile);
        }
        // Notify Spidermonkey that our thread processing has finished
#ifdef ADM_JS_THREADSAFE
        JS_EndRequest(g_pCx);
        JS_ClearContextThread(g_pCx);
#endif
        pthread_mutex_unlock(&g_pSpiderMonkeyMutex);

        return NULL;
}// end StartThreadSpidermonkey
Example #5
0
JsExecutionContext::~JsExecutionContext()
{
  JS_SetContextThread(cx);
  JS_GC(cx);
  JS_BeginRequest(cx);
  JS_ClearScope(cx, obj);
  JS_EndRequest(cx);
  JS_ClearContextThread(cx);
  JS_DestroyContext(cx);
  JS_DestroyRuntime(rt);
}
Example #6
0
bool __fastcall GameEventCallback(Script* script, void* argv, uint argc)
{
	if(script->IsRunning() && script->IsListenerRegistered("gamemsg"))
	{
		AutoRoot** argv = new AutoRoot*[1];
		JS_SetContextThread(ScriptEngine::GetGlobalContext());
		argv[0] = new AutoRoot(STRING_TO_JSVAL(JS_NewStringCopyZ(ScriptEngine::GetGlobalContext(), (char*)argv)));
		JS_ClearContextThread(ScriptEngine::GetGlobalContext());
		script->ExecEventAsync("gamemsg", 1, argv);
	}
	return true;
}
Example #7
0
/* JSCall function by name, cvalues will be converted
 *
 * deactivates controller if any script errors!
 *
 * format values:
 * case 'b': BOOLEAN_TO_JSVAL((JSBool) va_arg(ap, int));
 * case 'c': INT_TO_JSVAL((uint16) va_arg(ap, unsigned int));
 * case 'i':
 * case 'j': js_NewNumberValue(cx, (jsdouble) va_arg(ap, int32), sp)
 * case 'u': js_NewNumberValue(cx, (jsdouble) va_arg(ap, uint32), sp)
 * case 'd':
 * case 'I': js_NewDoubleValue(cx, va_arg(ap, jsdouble), sp)
 * case 's': JS_NewStringCopyZ(cx, va_arg(ap, char *))
 * case 'W': JS_NewUCStringCopyZ(cx, va_arg(ap, jschar *))
 * case 'S': va_arg(ap, JSString *)
 * case 'o': OBJECT_TO_JSVAL(va_arg(ap, JSObject *)
 * case 'f':
 * fun = va_arg(ap, JSFunction *);
 *       fun ? OBJECT_TO_JSVAL(fun->object) : JSVAL_NULL;
 * case 'v': va_arg(ap, jsval);
 */
bool ControllerListener::call(const char *funcname, int argc, const char *format, ...) {
    va_list ap;
    jsval fval = JSVAL_VOID;
    jsval ret = JSVAL_VOID;
    
    func("%s try calling method %s.%s(argc:%i)", __func__, name, funcname, argc);
    JS_SetContextThread(jsContext);
    JS_BeginRequest(jsContext);
    int res = JS_GetProperty(jsContext, jsObject, funcname, &fval);
    
    if(JSVAL_IS_VOID(fval)) {
        warning("method unresolved by JS_GetProperty");
    } else {
        jsval *argv;
        void *markp;
        
        va_start(ap, format);
        argv = JS_PushArgumentsVA(jsContext, &markp, format, ap);
        va_end(ap);
        
        res = JS_CallFunctionValue(jsContext, jsObject, fval, argc, argv, &ret);
        JS_PopArguments(jsContext, &markp);
        
        if (res) {
            if(!JSVAL_IS_VOID(ret)) {
                JSBool ok;
                JS_ValueToBoolean(jsContext, ret, &ok);
                if (ok) // JSfunc returned 'true', so event is done
                {
                    JS_EndRequest(jsContext);
                    JS_ClearContextThread(jsContext);
                    return true;
                }
            }
        }
    }
    JS_EndRequest(jsContext);
    JS_ClearContextThread(jsContext);
    return false; // no callback, redo on next controller
}
Example #8
0
bool __fastcall ChatEventCallback(Script* script, void* argv, uint argc)
{
	ChatEventHelper* helper = (ChatEventHelper*)argv;
	if(script->IsRunning() && script->IsListenerRegistered(helper->event))
	{
		AutoRoot** argv = new AutoRoot*[2];
		JS_SetContextThread(ScriptEngine::GetGlobalContext());
		argv[0] = new AutoRoot(STRING_TO_JSVAL(JS_NewStringCopyZ(ScriptEngine::GetGlobalContext(), helper->nick)));
		argv[1] = new AutoRoot(STRING_TO_JSVAL(JS_NewStringCopyZ(ScriptEngine::GetGlobalContext(), helper->msg)));
		JS_ClearContextThread(ScriptEngine::GetGlobalContext());
		script->ExecEventAsync(helper->event, 2, argv);
	}
	return true;
}
Example #9
0
bool __fastcall CopyDataCallback(Script* script, void* argv, uint argc)
{
	CopyDataHelper* helper = (CopyDataHelper*)argv;
	if(script->IsRunning() && script->IsListenerRegistered("copydata"))
	{
		AutoRoot** argv = new AutoRoot*[2];
		JS_SetContextThread(ScriptEngine::GetGlobalContext());
		argv[0] = new AutoRoot();
		JS_NewNumberValue(ScriptEngine::GetGlobalContext(), helper->mode, argv[0]->value());
		argv[1] = new AutoRoot(STRING_TO_JSVAL(JS_NewStringCopyZ(ScriptEngine::GetGlobalContext(), helper->msg)));
		JS_ClearContextThread(ScriptEngine::GetGlobalContext());
		script->ExecEventAsync("copydata", 2, argv);
	}
	return true;
}
Example #10
0
JsExecutionContext::JsExecutionContext(JsParser *jsParser)
{
  parser = jsParser;
  /* Create a new runtime environment. */
  rt = JS_NewRuntime(8L * 1024L * 1024L);
  if (!rt) {
    error("JsParser :: error creating runtime");
    return; /* XXX should return int or ptr! */
  }

  /* Create a new context. */
  cx = JS_NewContext(rt, STACK_CHUNK_SIZE);
  /* if global_context does not have a value, end the program here */
  if (cx == NULL) {
    error("JsParser :: error creating context");
    return;
  }

  JS_BeginRequest(cx);
  // Store a reference to ourselves in the context ...
  JS_SetContextPrivate(cx, parser);

  /* Set a more strict error checking */
  JS_SetOptions(cx, JSOPTION_VAROBJFIX); // | JSOPTION_STRICT);

  /* Set the branch callback */
#if defined JSOPTION_NATIVE_BRANCH_CALLBACK
  JS_SetBranchCallback(cx, js_static_branch_callback);
#else
  JS_SetOperationCallback(cx, js_static_branch_callback);
#endif

  /* Set the error reporter */
  JS_SetErrorReporter(cx, js_error_reporter);

  /* Create the global object here */
  //  JS_SetGlobalObject(global_context, global_object);
  //  this is done in init_class / JS_InitStandardClasses.
  obj = JS_NewObject(cx, &global_class, NULL, NULL);
  init_class();
  JS_EndRequest(cx);
  // deassociate this context from the creating thread
  // so that it can be used in other threads
  // https://developer.mozilla.org/en/SpiderMonkey/JSAPI_Reference/JS_NewContext
  JS_ClearContextThread(cx);
  /** register SIGINT signal */
  //   signal(SIGINT, js_sigint_handler);
}
Example #11
0
/* return lines read, or 0 on error */
int JsParser::open(const char* script_file) {

  JsExecutionContext *new_script = new JsExecutionContext(this);
  JS_SetContextThread(new_script->cx);
  JS_BeginRequest(new_script->cx);
  int ret = open(new_script->cx, new_script->obj, script_file);
  JS_EndRequest(new_script->cx);
  JS_ClearContextThread(new_script->cx);
  if (ret) {
    new_script->set_name(script_file);
    runtimes.append(new_script);
  } else {
    delete new_script;
  }
  return ret;
}
void SG_jscontext__release(SG_context * pCtx, SG_jscontext ** ppJs)
{
	if(ppJs==NULL || *ppJs==NULL)
		return;

	if(gpJSContextPoolGlobalState->ssjsMutable)
	{
		SG_httprequestprofiler__start(SG_HTTPREQUESTPROFILER_CATEGORY__JSREQUEST_TOGGLING);
		JS_EndRequest((*ppJs)->cx);
		JS_DestroyContext((*ppJs)->cx);
		SG_httprequestprofiler__stop();

		if(SG_context__has_err(pCtx)) // An error was produced during GC...
		{
			SG_log__report_error__current_error(pCtx);
			SG_context__err_reset(pCtx);
		}

		SG_NULLFREE(pCtx, (*ppJs));
	}
	else
	{
		SG_jscontext * pJs = *ppJs;

		JS_MaybeGC(pJs->cx);

		JS_SetContextPrivate(pJs->cx, NULL); // Clear out the old pCtx pointer.

		SG_httprequestprofiler__start(SG_HTTPREQUESTPROFILER_CATEGORY__JSREQUEST_TOGGLING);
		JS_EndRequest(pJs->cx);
		pJs->isInARequest = SG_FALSE;
		(void)JS_ClearContextThread(pJs->cx);
		SG_httprequestprofiler__stop();

		SG_ERR_CHECK_RETURN(  SG_mutex__lock(pCtx, &gpJSContextPoolGlobalState->lock)  );

		pJs->pNextAvailableContext = gpJSContextPoolGlobalState->pFirstAvailableContext;
		gpJSContextPoolGlobalState->pFirstAvailableContext = pJs;
		--gpJSContextPoolGlobalState->numContextsCheckedOut;

		SG_ERR_CHECK_RETURN(  SG_mutex__unlock(pCtx, &gpJSContextPoolGlobalState->lock)  );

		*ppJs = NULL;
	}
}
Example #13
0
bool __fastcall ItemEventCallback(Script* script, void* argv, uint argc)
{
	ItemEventHelper* helper = (ItemEventHelper*)argv;
	if(script->IsRunning() && script->IsListenerRegistered("itemaction"))
	{
		AutoRoot** argv = new AutoRoot*[4];
		JS_SetContextThread(ScriptEngine::GetGlobalContext());
		argv[0] = new AutoRoot();
		argv[1] = new AutoRoot();
		JS_NewNumberValue(ScriptEngine::GetGlobalContext(), helper->id, argv[0]->value());
		JS_NewNumberValue(ScriptEngine::GetGlobalContext(), helper->mode, argv[1]->value());
		argv[2] = new AutoRoot(STRING_TO_JSVAL(JS_NewStringCopyZ(ScriptEngine::GetGlobalContext(), helper->code)));
		argv[3] = new AutoRoot(BOOLEAN_TO_JSVAL(helper->global));
		JS_ClearContextThread(ScriptEngine::GetGlobalContext());
		script->ExecEventAsync("itemaction", 4, argv);
	}
	return true;
}
Example #14
0
void Engine::cleanup()
{
	while ( !m_contexts.empty() )
	{
		JSContext *cx = m_contexts.top();
		m_contexts.pop();

		JS_ClearContextThread(cx);
		JS_DestroyContext(cx);
	}

	if ( m_runtime!=NULL ) {
		JS_DestroyRuntime(m_runtime);
		m_runtime = NULL;
	}

	JS_ShutDown();
}
Example #15
0
bool __fastcall GameActionEventCallback(Script* script, void* argv, uint argc)
{
	GameActionEventHelper* helper = (GameActionEventHelper*)argv;
	if(script->IsRunning() && script->IsListenerRegistered("gameevent"))
	{
		AutoRoot** argv = new AutoRoot*[5];
		JS_SetContextThread(ScriptEngine::GetGlobalContext());
		argv[0] = new AutoRoot();
		argv[1] = new AutoRoot();
		argv[2] = new AutoRoot();
		JS_NewNumberValue(ScriptEngine::GetGlobalContext(), helper->mode, argv[0]->value());
		JS_NewNumberValue(ScriptEngine::GetGlobalContext(), helper->param1, argv[1]->value());
		JS_NewNumberValue(ScriptEngine::GetGlobalContext(), helper->param2, argv[2]->value());
		argv[3] = new AutoRoot(STRING_TO_JSVAL(JS_NewStringCopyZ(ScriptEngine::GetGlobalContext(), helper->name1)));
		argv[4] = new AutoRoot(STRING_TO_JSVAL(JS_NewStringCopyZ(ScriptEngine::GetGlobalContext(), helper->name2)));
		JS_ClearContextThread(ScriptEngine::GetGlobalContext());
		script->ExecEventAsync("gameevent", 5, argv);
	}
	return true;
}
Example #16
0
int Controller::JSCall(const char *funcname, int argc, const char *format, ...)
{
    int res;
    jsval *argv;
    va_list args;
    ControllerListener *listener = listeners.begin();
    va_start(args, format);
    va_end(args);
    while (listener) {
        void *markp = NULL;
        JS_SetContextThread(listener->context());
        JS_BeginRequest(listener->context());
        argv = JS_PushArgumentsVA(listener->context(), &markp, format, args);
        JS_EndRequest(listener->context());
        JS_ClearContextThread(listener->context());
        // TODO - unregister listener if returns false
        if (listener->call(funcname, argc, argv))
            res++;
        listener = (ControllerListener *)listener->next;
    }
    return res;
}
Example #17
0
File: js.c Project: Daisho/showtime
static int
js_init(void)
{
  JSContext *cx;
  jsval val;

  JS_SetCStringsAreUTF8();

  runtime = JS_NewRuntime(0x1000000);

  cx = js_newctx(err_reporter);

  JS_BeginRequest(cx);

  showtimeobj = JS_NewObject(cx, &showtime_class, NULL, NULL);
  JS_DefineFunctions(cx, showtimeobj, showtime_functions);

  val = INT_TO_JSVAL(showtime_get_version_int());
  JS_SetProperty(cx, showtimeobj, "currentVersionInt", &val);

  val = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, htsversion));
  JS_SetProperty(cx, showtimeobj, "currentVersionString", &val);


  JSFunction *fn = JS_DefineFunction(cx, showtimeobj, "RichText",
				     js_RichText, 1, 0);
  RichText = JS_GetFunctionObject(fn);
	     
  JS_AddNamedRoot(cx, &showtimeobj, "showtime");

  js_global_cx = cx;
  JS_EndRequest(cx);
  JS_ClearContextThread(cx);
  js_global_pc = prop_courier_create_lockmgr("js", js_lockmgr, cx,
					     js_global_pc_prologue,
					     js_global_pc_epilogue);
  return 0;
}
Example #18
0
inline void end_request(spidermonkey_vm *vm) {
  JS_EndRequest(vm->context);
  JS_ClearContextThread(vm->context);
}
Example #19
0
bool Engine::executeFile(FILE *file,HttpServerRequest &httpRequest,HttpServerResponse &httpResponse)
{
	JSContext *cx = NULL;
	JSObject *obj = NULL;

	m_mutex.acquire_write();

	// pop any available context
	if ( !m_contexts.empty() ) {
		cx = m_contexts.top();
		m_contexts.pop();
	}

	m_mutex.release();

	if ( cx==NULL )
	{
		// create new context
		cx = JS_NewContext(m_runtime,8192);
		if ( cx==NULL ) {
			LogManager::getInstance()->warning(LOGGER_CLASSNAME,"Could not create context. Engine is unavailable.");
			return false;
		}

		JS_SetErrorReporter(cx,reportError);

		if ( LogManager::getInstance()->isDebug() ) {
			LogManager::getInstance()->debug(LOGGER_CLASSNAME,"Created new context");
		}
	}

	bool result = false;

	// begin request (requires js_threadsafe compilation)
	JS_SetContextThread(cx);
	JS_BeginRequest(cx);

	// create global object
	obj = JS_NewObject(cx,&globalClass,0,0);
	if ( obj==NULL ) {
		LogManager::getInstance()->warning(LOGGER_CLASSNAME,"Could not create global object");
	}
	else
	{
		// initialize standard classes on global object
		if ( JS_InitStandardClasses(cx,obj)==JS_FALSE ) {
			LogManager::getInstance()->warning(LOGGER_CLASSNAME,"Could not init standard classes");
		}
		else
		{
			// initialize custom classes on global object
			if ( !initCustomClasses(cx,obj) ) {
				LogManager::getInstance()->warning(LOGGER_CLASSNAME,"Could not init custom classes");
			}
			else
			{
				// create predefined objects on global object
				createPredefinedObjects(cx,obj,httpRequest);

				// create context private
				ContextPrivate *cxPrivate = new ContextPrivate(this,httpRequest,httpResponse);
				JS_SetContextPrivate(cx,cxPrivate);

				// execute script in the context
				result = executeFile(file,cx,obj);

				// cleanup predefined objects on context object
				// note: this one might not be needed, remove later if ok
				cleanupPredefinedObjects(cx,obj);

				delete cxPrivate;
			}
		}
	}
	
	JS_GC(cx); // force garbage collection

	// end request (requires js_threadsafe)
	JS_EndRequest(cx);
	JS_ClearContextThread(cx);

	// return context to js engine
	m_mutex.acquire_write();
	m_contexts.push(cx);
	m_mutex.release();

	return result;
}
Example #20
0
void JsExecutionContext::gc()
{
  JS_SetContextThread(cx);
  JS_MaybeGC(cx);
  JS_ClearContextThread(cx);
}
Example #21
0
File: js.c Project: Daisho/showtime
static void
js_global_pc_epilogue(void)
{
  JS_ClearContextThread(js_global_cx);
}