mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 628758 - Various compartment and request fixes for JSD (r=luke)
--HG-- extra : rebase_source : 98a06e6f9c7528ebbdbaa445d7cc8e28973d5d02
This commit is contained in:
parent
5d5948d114
commit
2af7d0908f
@ -527,6 +527,9 @@ jsd_GetScriptLineExtent(JSDContext* jsdc, JSDScript *jsdscript)
|
||||
jsuword
|
||||
jsd_GetClosestPC(JSDContext* jsdc, JSDScript* jsdscript, uintN line)
|
||||
{
|
||||
jsuword pc;
|
||||
JSCrossCompartmentCall *call;
|
||||
|
||||
#ifdef LIVEWIRE
|
||||
if( jsdscript && jsdscript->lwscript )
|
||||
{
|
||||
@ -537,20 +540,28 @@ jsd_GetClosestPC(JSDContext* jsdc, JSDScript* jsdscript, uintN line)
|
||||
}
|
||||
#endif
|
||||
|
||||
return (jsuword) JS_LineNumberToPC(jsdc->dumbContext,
|
||||
jsdscript->script, line );
|
||||
call = JS_EnterCrossCompartmentCallScript(jsdc->dumbContext, jsdscript->script);
|
||||
if(!call)
|
||||
return 0;
|
||||
pc = (jsuword) JS_LineNumberToPC(jsdc->dumbContext, jsdscript->script, line );
|
||||
JS_LeaveCrossCompartmentCall(call);
|
||||
return pc;
|
||||
}
|
||||
|
||||
uintN
|
||||
jsd_GetClosestLine(JSDContext* jsdc, JSDScript* jsdscript, jsuword pc)
|
||||
{
|
||||
JSCrossCompartmentCall *call;
|
||||
uintN first = jsdscript->lineBase;
|
||||
uintN last = first + jsd_GetScriptLineExtent(jsdc, jsdscript) - 1;
|
||||
uintN line = pc
|
||||
? JS_PCToLineNumber(jsdc->dumbContext,
|
||||
jsdscript->script,
|
||||
(jsbytecode*)pc)
|
||||
: 0;
|
||||
uintN line = 0;
|
||||
|
||||
call = JS_EnterCrossCompartmentCallScript(jsdc->dumbContext, jsdscript->script);
|
||||
if(!call)
|
||||
return 0;
|
||||
if (pc)
|
||||
line = JS_PCToLineNumber(jsdc->dumbContext, jsdscript->script, (jsbytecode*)pc);
|
||||
JS_LeaveCrossCompartmentCall(call);
|
||||
|
||||
if( line < first )
|
||||
return first;
|
||||
@ -594,10 +605,15 @@ jsd_GetScriptHook(JSDContext* jsdc, JSD_ScriptHookProc* hook, void** callerdata)
|
||||
JSBool
|
||||
jsd_EnableSingleStepInterrupts(JSDContext* jsdc, JSDScript* jsdscript, JSBool enable)
|
||||
{
|
||||
JSCrossCompartmentCall *call;
|
||||
JSBool rv;
|
||||
call = JS_EnterCrossCompartmentCallScript(jsdc->dumbContext, jsdscript->script);
|
||||
if(!call)
|
||||
return JS_FALSE;
|
||||
JSD_LOCK();
|
||||
rv = JS_SetSingleStepMode(jsdc->dumbContext, jsdscript->script, enable);
|
||||
JSD_UNLOCK();
|
||||
JS_LeaveCrossCompartmentCall(call);
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -802,6 +818,8 @@ jsd_SetExecutionHook(JSDContext* jsdc,
|
||||
void* callerdata)
|
||||
{
|
||||
JSDExecHook* jsdhook;
|
||||
JSBool rv;
|
||||
JSCrossCompartmentCall *call;
|
||||
|
||||
JSD_LOCK();
|
||||
if( ! hook )
|
||||
@ -831,10 +849,20 @@ jsd_SetExecutionHook(JSDContext* jsdc,
|
||||
jsdhook->hook = hook;
|
||||
jsdhook->callerdata = callerdata;
|
||||
|
||||
if( ! JS_SetTrap(jsdc->dumbContext, jsdscript->script,
|
||||
(jsbytecode*)pc, jsd_TrapHandler,
|
||||
PRIVATE_TO_JSVAL(jsdhook)) )
|
||||
{
|
||||
call = JS_EnterCrossCompartmentCallScript(jsdc->dumbContext, jsdscript->script);
|
||||
if(!call) {
|
||||
free(jsdhook);
|
||||
JSD_UNLOCK();
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
rv = JS_SetTrap(jsdc->dumbContext, jsdscript->script,
|
||||
(jsbytecode*)pc, jsd_TrapHandler,
|
||||
PRIVATE_TO_JSVAL(jsdhook));
|
||||
|
||||
JS_LeaveCrossCompartmentCall(call);
|
||||
|
||||
if ( ! rv ) {
|
||||
free(jsdhook);
|
||||
JSD_UNLOCK();
|
||||
return JS_FALSE;
|
||||
@ -851,6 +879,7 @@ jsd_ClearExecutionHook(JSDContext* jsdc,
|
||||
JSDScript* jsdscript,
|
||||
jsuword pc)
|
||||
{
|
||||
JSCrossCompartmentCall *call;
|
||||
JSDExecHook* jsdhook;
|
||||
|
||||
JSD_LOCK();
|
||||
@ -862,9 +891,17 @@ jsd_ClearExecutionHook(JSDContext* jsdc,
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
call = JS_EnterCrossCompartmentCallScript(jsdc->dumbContext, jsdscript->script);
|
||||
if(!call) {
|
||||
JSD_UNLOCK();
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
JS_ClearTrap(jsdc->dumbContext, jsdscript->script,
|
||||
(jsbytecode*)pc, NULL, NULL );
|
||||
|
||||
JS_LeaveCrossCompartmentCall(call);
|
||||
|
||||
JS_REMOVE_LINK(&jsdhook->links);
|
||||
free(jsdhook);
|
||||
|
||||
@ -886,6 +923,7 @@ jsd_ClearAllExecutionHooksForScript(JSDContext* jsdc, JSDScript* jsdscript)
|
||||
free(jsdhook);
|
||||
}
|
||||
|
||||
/* No cross-compartment call here because we may be in the middle of GC */
|
||||
JS_ClearScriptTraps(jsdc->dumbContext, jsdscript->script);
|
||||
JSD_UNLOCK();
|
||||
|
||||
|
@ -211,36 +211,50 @@ jsd_GetValueString(JSDContext* jsdc, JSDValue* jsdval)
|
||||
JSContext* cx = jsdc->dumbContext;
|
||||
JSExceptionState* exceptionState;
|
||||
JSCrossCompartmentCall *call = NULL;
|
||||
jsval stringval;
|
||||
JSString *string;
|
||||
JSBool needWrap;
|
||||
JSObject *scopeObj;
|
||||
|
||||
if(!jsdval->string)
|
||||
{
|
||||
/* if the jsval is a string, then we don't need to double root it */
|
||||
if(JSVAL_IS_STRING(jsdval->val))
|
||||
jsdval->string = JSVAL_TO_STRING(jsdval->val);
|
||||
else
|
||||
{
|
||||
JS_BeginRequest(cx);
|
||||
call = JSVAL_IS_PRIMITIVE(jsdval->val)
|
||||
? NULL
|
||||
: JS_EnterCrossCompartmentCall(jsdc->dumbContext, JSVAL_TO_OBJECT(jsdval->val));
|
||||
if(!call) {
|
||||
JS_EndRequest(cx);
|
||||
if(jsdval->string)
|
||||
return jsdval->string;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
exceptionState = JS_SaveExceptionState(cx);
|
||||
jsdval->string = JS_ValueToString(cx, jsdval->val);
|
||||
JS_RestoreExceptionState(cx, exceptionState);
|
||||
if(jsdval->string)
|
||||
{
|
||||
if(!JS_AddNamedStringRoot(cx, &jsdval->string, "ValueString"))
|
||||
jsdval->string = NULL;
|
||||
}
|
||||
JS_LeaveCrossCompartmentCall(call);
|
||||
JS_EndRequest(cx);
|
||||
}
|
||||
/* Reuse the string without copying or re-rooting it */
|
||||
if(JSVAL_IS_STRING(jsdval->val)) {
|
||||
jsdval->string = JSVAL_TO_STRING(jsdval->val);
|
||||
return jsdval->string;
|
||||
}
|
||||
|
||||
JS_BeginRequest(cx);
|
||||
|
||||
/* Objects call JS_ValueToString in their own compartment. */
|
||||
scopeObj = JSVAL_IS_OBJECT(jsdval->val) ? JSVAL_TO_OBJECT(jsdval->val) : jsdc->glob;
|
||||
call = JS_EnterCrossCompartmentCall(cx, scopeObj);
|
||||
if(!call) {
|
||||
JS_EndRequest(cx);
|
||||
return NULL;
|
||||
}
|
||||
exceptionState = JS_SaveExceptionState(cx);
|
||||
|
||||
string = JS_ValueToString(cx, jsdval->val);
|
||||
|
||||
JS_RestoreExceptionState(cx, exceptionState);
|
||||
JS_LeaveCrossCompartmentCall(call);
|
||||
|
||||
stringval = STRING_TO_JSVAL(string);
|
||||
call = JS_EnterCrossCompartmentCall(cx, jsdc->glob);
|
||||
if(!call || !JS_WrapValue(cx, &stringval)) {
|
||||
JS_EndRequest(cx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jsdval->string = JSVAL_TO_STRING(stringval);
|
||||
if(!JS_AddNamedStringRoot(cx, &jsdval->string, "ValueString"))
|
||||
jsdval->string = NULL;
|
||||
|
||||
JS_LeaveCrossCompartmentCall(call);
|
||||
JS_EndRequest(cx);
|
||||
|
||||
return jsdval->string;
|
||||
}
|
||||
|
||||
@ -281,6 +295,11 @@ jsd_GetValueFunctionId(JSDContext* jsdc, JSDValue* jsdval)
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
/*
|
||||
* Create a new JSD value referring to a jsval. Copy string values into the
|
||||
* JSD compartment. Leave all other GCTHINGs in their native compartments
|
||||
* and access them through cross-compartment calls.
|
||||
*/
|
||||
JSDValue*
|
||||
jsd_NewValue(JSDContext* jsdc, jsval val)
|
||||
{
|
||||
@ -292,7 +311,7 @@ jsd_NewValue(JSDContext* jsdc, jsval val)
|
||||
|
||||
if(JSVAL_IS_GCTHING(val))
|
||||
{
|
||||
JSBool ok = JS_FALSE;
|
||||
JSBool ok;
|
||||
JS_BeginRequest(jsdc->dumbContext);
|
||||
|
||||
call = JS_EnterCrossCompartmentCall(jsdc->dumbContext, jsdc->glob);
|
||||
@ -303,6 +322,12 @@ jsd_NewValue(JSDContext* jsdc, jsval val)
|
||||
}
|
||||
|
||||
ok = JS_AddNamedValueRoot(jsdc->dumbContext, &jsdval->val, "JSDValue");
|
||||
if(ok && JSVAL_IS_STRING(val)) {
|
||||
if(!JS_WrapValue(jsdc->dumbContext, &val)) {
|
||||
ok = JS_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
JS_LeaveCrossCompartmentCall(call);
|
||||
JS_EndRequest(jsdc->dumbContext);
|
||||
if(!ok)
|
||||
|
@ -1040,16 +1040,17 @@ jsdScript::CreatePPLineMap()
|
||||
JSAutoRequest ar(cx);
|
||||
JSObject *obj = JS_NewObject(cx, NULL, NULL, NULL);
|
||||
JSFunction *fun = JSD_GetJSFunction (mCx, mScript);
|
||||
JSScript *script;
|
||||
JSString *jsstr;
|
||||
JSScript *script; /* In JSD compartment */
|
||||
PRUint32 baseLine;
|
||||
PRBool scriptOwner = PR_FALSE;
|
||||
JSString *jsstr;
|
||||
size_t length;
|
||||
const jschar *chars;
|
||||
|
||||
if (fun) {
|
||||
uintN nargs;
|
||||
|
||||
/* Enter a new block so we can leave before the end of this block */
|
||||
do {
|
||||
{
|
||||
JSAutoEnterCompartment ac;
|
||||
if (!ac.enter(cx, JS_GetFunctionObject(fun)))
|
||||
return nsnull;
|
||||
@ -1060,13 +1061,12 @@ jsdScript::CreatePPLineMap()
|
||||
jsstr = JS_DecompileFunctionBody (cx, fun, 4);
|
||||
if (!jsstr)
|
||||
return nsnull;
|
||||
} while(false);
|
||||
|
||||
size_t length;
|
||||
const jschar *chars = JS_GetStringCharsAndLength(cx, jsstr, &length);
|
||||
if (!chars)
|
||||
return nsnull;
|
||||
|
||||
if (!(chars = JS_GetStringCharsAndLength(cx, jsstr, &length)))
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
JS::Anchor<JSString *> kungFuDeathGrip(jsstr);
|
||||
const char *argnames[] = {"arg1", "arg2", "arg3", "arg4",
|
||||
"arg5", "arg6", "arg7", "arg8",
|
||||
"arg9", "arg10", "arg11", "arg12" };
|
||||
@ -1076,27 +1076,24 @@ jsdScript::CreatePPLineMap()
|
||||
return nsnull;
|
||||
baseLine = 3;
|
||||
} else {
|
||||
/* Enter a new block so we can leave before the end of this block */
|
||||
do {
|
||||
script = JSD_GetJSScript(mCx, mScript);
|
||||
script = JSD_GetJSScript(mCx, mScript);
|
||||
JSString *jsstr;
|
||||
|
||||
{
|
||||
JSAutoEnterCompartment ac;
|
||||
if (!ac.enter(cx, script))
|
||||
return nsnull;
|
||||
|
||||
jsstr = JS_DecompileScript (cx, JSD_GetJSScript(mCx, mScript),
|
||||
"ppscript", 4);
|
||||
jsstr = JS_DecompileScript (cx, JSD_GetJSScript(mCx, mScript), "ppscript", 4);
|
||||
if (!jsstr)
|
||||
return nsnull;
|
||||
} while(false);
|
||||
|
||||
size_t length;
|
||||
const jschar *chars = JS_GetStringCharsAndLength(cx, jsstr, &length);
|
||||
if (!chars)
|
||||
return nsnull;
|
||||
if (!(chars = JS_GetStringCharsAndLength(cx, jsstr, &length)))
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
script = JS_CompileUCScript (cx, obj, chars, length,
|
||||
"x-jsd:ppbuffer?type=script", 1);
|
||||
JS::Anchor<JSString *> kungFuDeathGrip(jsstr);
|
||||
script = JS_CompileUCScript (cx, obj, chars, length, "x-jsd:ppbuffer?type=script", 1);
|
||||
if (!script)
|
||||
return nsnull;
|
||||
scriptOwner = PR_TRUE;
|
||||
@ -1190,6 +1187,9 @@ jsdScript::GetVersion (PRInt32 *_rval)
|
||||
ASSERT_VALID_EPHEMERAL;
|
||||
JSContext *cx = JSD_GetDefaultJSContext (mCx);
|
||||
JSScript *script = JSD_GetJSScript(mCx, mScript);
|
||||
JSAutoEnterCompartment ac;
|
||||
if (!ac.enter(cx, script))
|
||||
return NS_ERROR_FAILURE;
|
||||
*_rval = static_cast<PRInt32>(JS_GetScriptVersion(cx, script));
|
||||
return NS_OK;
|
||||
}
|
||||
@ -1288,6 +1288,9 @@ jsdScript::GetParameterNames(PRUint32* count, PRUnichar*** paramNames)
|
||||
JSFunction *fun = JSD_GetJSFunction (mCx, mScript);
|
||||
|
||||
JSAutoRequest ar(cx);
|
||||
JSAutoEnterCompartment ac;
|
||||
if (!ac.enter(cx, JS_GetFunctionObject(fun)))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
uintN nargs;
|
||||
if (!fun ||
|
||||
|
Loading…
Reference in New Issue
Block a user