Bug 811784: Account for subscripts when figuring out what object to stick properties on. r=mrbkap

This commit is contained in:
Kyle Huey 2012-11-26 14:41:55 -08:00
Родитель a9a0fc4866
Коммит 38a35ea5a7
4 изменённых файлов: 66 добавлений и 18 удалений

Просмотреть файл

@ -625,6 +625,16 @@ mozJSComponentLoader::FindTargetObject(JSContext* aCx,
return NS_OK; return NS_OK;
} }
void
mozJSComponentLoader::NoteSubScript(JSScript* aScript, JSObject* aThisObject)
{
if (!mInitialized && NS_FAILED(ReallyInit())) {
MOZ_NOT_REACHED();
}
mThisObjects.Put(aScript, aThisObject);
}
// Some stack based classes for cleaning up on early return // Some stack based classes for cleaning up on early return
#ifdef HAVE_PR_MEMMAP #ifdef HAVE_PR_MEMMAP
class FileAutoCloser class FileAutoCloser

Просмотреть файл

@ -54,6 +54,8 @@ class mozJSComponentLoader : public mozilla::ModuleLoader,
static mozJSComponentLoader* Get() { return sSelf; } static mozJSComponentLoader* Get() { return sSelf; }
void NoteSubScript(JSScript* aScript, JSObject* aThisObject);
protected: protected:
static mozJSComponentLoader* sSelf; static mozJSComponentLoader* sSelf;

Просмотреть файл

@ -31,6 +31,7 @@
#include "mozilla/scache/StartupCache.h" #include "mozilla/scache/StartupCache.h"
#include "mozilla/scache/StartupCacheUtils.h" #include "mozilla/scache/StartupCacheUtils.h"
#include "mozilla/Preferences.h"
using namespace mozilla::scache; using namespace mozilla::scache;
@ -77,12 +78,16 @@ nsresult
mozJSSubScriptLoader::ReadScript(nsIURI *uri, JSContext *cx, JSObject *target_obj, mozJSSubScriptLoader::ReadScript(nsIURI *uri, JSContext *cx, JSObject *target_obj,
const nsAString& charset, const char *uriStr, const nsAString& charset, const char *uriStr,
nsIIOService *serv, nsIPrincipal *principal, nsIIOService *serv, nsIPrincipal *principal,
JSScript **scriptp) bool reuseGlobal, JSScript **scriptp,
JSFunction **functionp)
{ {
nsCOMPtr<nsIChannel> chan; nsCOMPtr<nsIChannel> chan;
nsCOMPtr<nsIInputStream> instream; nsCOMPtr<nsIInputStream> instream;
JSErrorReporter er; JSErrorReporter er;
*scriptp = nullptr;
*functionp = nullptr;
nsresult rv; nsresult rv;
// Instead of calling NS_OpenURI, we create the channel ourselves and call // Instead of calling NS_OpenURI, we create the channel ourselves and call
// SetContentType, to avoid expensive MIME type lookups (bug 632490). // SetContentType, to avoid expensive MIME type lookups (bug 632490).
@ -130,13 +135,27 @@ mozJSSubScriptLoader::ReadScript(nsIURI *uri, JSContext *cx, JSObject *target_ob
return ReportError(cx, LOAD_ERROR_BADCHARSET); return ReportError(cx, LOAD_ERROR_BADCHARSET);
} }
*scriptp = JS::Compile(cx, target_obj_root, options, if (!reuseGlobal) {
reinterpret_cast<const jschar*>(script.get()), script.Length()); *scriptp = JS::Compile(cx, target_obj_root, options,
reinterpret_cast<const jschar*>(script.get()),
script.Length());
} else {
*functionp = JS::CompileFunction(cx, target_obj_root, options,
nullptr, 0, nullptr,
reinterpret_cast<const jschar*>(script.get()),
script.Length());
}
} else { } else {
// We only use LAZY_SOURCE when no special encoding is specified because // We only use LAZY_SOURCE when no special encoding is specified because
// the lazy source loader doesn't know the encoding. // the lazy source loader doesn't know the encoding.
options.setSourcePolicy(JS::CompileOptions::LAZY_SOURCE); if (!reuseGlobal) {
*scriptp = JS::Compile(cx, target_obj_root, options, buf.get(), len); options.setSourcePolicy(JS::CompileOptions::LAZY_SOURCE);
*scriptp = JS::Compile(cx, target_obj_root, options, buf.get(), len);
} else {
*functionp = JS::CompileFunction(cx, target_obj_root, options,
nullptr, 0, nullptr, buf.get(),
len);
}
} }
/* repent for our evil deeds */ /* repent for our evil deeds */
@ -180,16 +199,20 @@ mozJSSubScriptLoader::LoadSubScript(const nsAString& url,
JSAutoRequest ar(cx); JSAutoRequest ar(cx);
JSObject* targetObj; JSObject* targetObj;
if (!JS_ValueToObject(cx, target, &targetObj)) mozJSComponentLoader* loader = mozJSComponentLoader::Get();
rv = loader->FindTargetObject(cx, &targetObj);
NS_ENSURE_SUCCESS(rv, rv);
bool reusingGlobal = !JS_IsGlobalObject(targetObj);
// We base reusingGlobal off of what the loader told us, but we may not
// actually be using that object.
JSObject* passedObj;
if (!JS_ValueToObject(cx, target, &passedObj))
return NS_ERROR_ILLEGAL_VALUE; return NS_ERROR_ILLEGAL_VALUE;
if (passedObj)
if (!targetObj) { targetObj = passedObj;
// If the user didn't provide an object to eval onto, find one.
mozJSComponentLoader* loader = mozJSComponentLoader::Get();
rv = loader->FindTargetObject(cx, &targetObj);
NS_ENSURE_SUCCESS(rv, rv);
}
// Remember an object out of the calling compartment so that we // Remember an object out of the calling compartment so that we
// can properly wrap the result later. // can properly wrap the result later.
@ -274,20 +297,32 @@ mozJSSubScriptLoader::LoadSubScript(const nsAString& url,
cachePath.AppendPrintf("jssubloader/%d", version); cachePath.AppendPrintf("jssubloader/%d", version);
PathifyURI(uri, cachePath); PathifyURI(uri, cachePath);
JSFunction* function = nullptr;
script = nullptr; script = nullptr;
if (cache) if (cache)
rv = ReadCachedScript(cache, cachePath, cx, mSystemPrincipal, &script); rv = ReadCachedScript(cache, cachePath, cx, mSystemPrincipal, &script);
if (!script) { if (!script) {
rv = ReadScript(uri, cx, targetObj, charset, rv = ReadScript(uri, cx, targetObj, charset,
static_cast<const char*>(uriStr.get()), serv, static_cast<const char*>(uriStr.get()), serv,
principal, &script); principal, reusingGlobal, &script, &function);
writeScript = true; writeScript = !!script;
} }
if (NS_FAILED(rv) || !script) if (NS_FAILED(rv) || (!script && !function))
return rv; return rv;
bool ok = JS_ExecuteScriptVersion(cx, targetObj, script, retval, version); if (function) {
script = JS_GetFunctionScript(cx, function);
}
loader->NoteSubScript(script, targetObj);
bool ok = false;
if (function) {
ok = JS_CallFunction(cx, targetObj, function, 0, nullptr, retval);
} else {
ok = JS_ExecuteScriptVersion(cx, targetObj, script, retval, version);
}
if (ok) { if (ok) {
JSAutoCompartment rac(cx, result_obj); JSAutoCompartment rac(cx, result_obj);

Просмотреть файл

@ -33,7 +33,8 @@ private:
nsresult ReadScript(nsIURI *uri, JSContext *cx, JSObject *target_obj, nsresult ReadScript(nsIURI *uri, JSContext *cx, JSObject *target_obj,
const nsAString& charset, const char *uriStr, const nsAString& charset, const char *uriStr,
nsIIOService *serv, nsIPrincipal *principal, nsIIOService *serv, nsIPrincipal *principal,
JSScript **scriptp); bool reuseGlobal, JSScript **scriptp,
JSFunction **functionp);
nsCOMPtr<nsIPrincipal> mSystemPrincipal; nsCOMPtr<nsIPrincipal> mSystemPrincipal;
}; };