gecko-dev/js/jsj/jsjsa.c

221 строка
4.7 KiB
C

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/* ** */
/*
* stand-alone glue for js<->java
* this is used as a default if the host does not override
* the glue.
*/
#if defined (JAVA)
#include "jsapi.h"
#include "jri.h"
#include "jriext.h"
#include "jsjava.h"
#ifndef NSPR20
#include "prglobal.h"
#endif
#include "prthread.h"
#include "prmon.h"
#include "prlog.h"
#include "prcmon.h"
#ifndef NSPR20
#define WAIT_FOREVER LL_MAXINT
#else
#define WAIT_FOREVER PR_INTERVAL_NO_TIMEOUT
#endif
static JSTaskState *jsjiTask = 0;
static PRMonitor *jsmon = NULL;
/*
* callbacks to make js<->java glue work
*/
/**
* Liveconnect callback.
* Called to determine if Java is enabled
*
*/
PR_STATIC_CALLBACK(int)
sajsj_IsEnabled(void)
{
return (int)PR_TRUE;
}
static JSClass sajsj_global_class = {
"global", 0,
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
};
static JSObject *globalObject = NULL;
static JSContext *globalContext = NULL;
/*
* callback to find the JSContext for a particular JRIEnv
* here, this just returns the only JSContext we have.
* in the client, it looks up the java call stack for one?
*/
PR_STATIC_CALLBACK(JSContext *)
sajsj_CurrentContext(JRIEnv *env, char **errp)
{
*errp = 0;
return globalContext;
}
PR_STATIC_CALLBACK(JRIEnv *)
sajsj_CurrentEnv(JSContext *cx)
{
/* FIXME insurance? */
JRIEnv *env = JRI_GetCurrentEnv();
PR_ASSERT(env);
return env;
}
/*
* callbacks to maintain run-to-completion in the client
* and thread-safety in the standalone java.
*/
PR_STATIC_CALLBACK(void)
sajsj_EnterJS(void)
{
/* should ensure that only one thread can use the same
* context / object space at once */
PR_EnterMonitor(jsmon);
}
PR_STATIC_CALLBACK(void)
sajsj_ExitJS(void)
{
PR_ExitMonitor(jsmon);
}
PR_STATIC_CALLBACK(JSPrincipals *)
sajsj_getJSPrincipalsFromJavaCaller(JSContext *cx, int callerDepth)
{
return NULL;
}
PR_IMPLEMENT(JSObject *)
sajsj_GetDefaultObject(JRIEnv *env, jobject hint)
{
return globalObject;
}
static JSJCallbacks sajsjCallbacks = {
sajsj_IsEnabled,
sajsj_CurrentEnv,
sajsj_CurrentContext,
sajsj_EnterJS,
sajsj_ExitJS,
NULL,
sajsj_getJSPrincipalsFromJavaCaller,
sajsj_GetDefaultObject,
};
static void
sajsj_InitLocked()
{
JRIEnv *env;
/* if jsj has already been initialized, we don't do this
* standalone jsj setup, and none of the stuff in this
* file gets used */
if (!JSJ_Init(&sajsjCallbacks))
return;
jsjiTask = JS_Init(8L * 1024L * 1024L);
jsmon = PR_NewMonitor();
globalContext = JS_NewContext(jsjiTask, 8192);
PR_ASSERT(globalContext);
globalObject = NULL;
JS_AddRoot(globalContext, &globalObject);
globalObject = JS_NewObject(globalContext, &sajsj_global_class,
NULL, NULL);
if (!globalObject) {
PR_ASSERT(globalObject);
goto trash_cx;
}
if (!JS_InitStandardClasses(globalContext, globalObject))
goto trash_cx;
if (!JSJ_InitContext(globalContext, globalObject))
goto trash_cx;
env = JRI_GetCurrentEnv();
PR_ASSERT(env);
return;
trash_cx:
JS_DestroyContext(globalContext);
globalContext = NULL;
/* FIXME error codes? */
return;
}
PR_IMPLEMENT(void)
JSJ_InitStandalone()
{
static int initialized = -1;
if (initialized == 1)
return;
PR_CEnterMonitor(&initialized);
switch (initialized) {
case -1:
/* we're first */
initialized = 0; /* in progress */
PR_CExitMonitor(&initialized);
/* do it */
sajsj_InitLocked();
PR_CEnterMonitor(&initialized);
initialized = 1;
PR_CNotifyAll(&initialized);
break;
case 0:
/* in progress */
PR_CWait(&initialized, WAIT_FOREVER);
break;
case 1:
/* happened since the last check */
break;
}
PR_CExitMonitor(&initialized);
if (!jsjiTask)
return; /* FIXME fail loudly! */
return;
}
#endif /* defined (JAVA) */