Bug 761723 - Save script sources to implement Function.prototype.toString. r=jorendorff,njn,jimb,jst,Ms2ger

This commit is contained in:
Benjamin Peterson
2012-07-20 20:17:38 +02:00
parent 3aa7af89ad
commit 20adba28a8
257 changed files with 1254 additions and 8212 deletions

View File

@@ -21,6 +21,33 @@
using namespace js;
using namespace js::frontend;
class AutoAttachToRuntime {
JSRuntime *rt;
public:
ScriptSource *ss;
AutoAttachToRuntime(JSRuntime *rt)
: rt(rt), ss(NULL) {}
~AutoAttachToRuntime() {
// This makes the source visible to the GC. If compilation fails, and no
// script refers to it, it will be collected.
if (ss)
ss->attachToRuntime(rt);
}
};
static bool
CheckLength(JSContext *cx, size_t length)
{
// Note this limit is simply so we can store sourceStart and sourceEnd in
// JSScript as 32-bits. It could be lifted fairly easily, since the compiler
// is using size_t internally already.
if (length > UINT32_MAX) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_SOURCE_TOO_LONG);
return false;
}
return true;
}
JSScript *
frontend::CompileScript(JSContext *cx, HandleObject scopeChain, StackFrame *callerFrame,
JSPrincipals *principals, JSPrincipals *originPrincipals,
@@ -52,6 +79,15 @@ frontend::CompileScript(JSContext *cx, HandleObject scopeChain, StackFrame *call
JS_ASSERT_IF(callerFrame, compileAndGo);
JS_ASSERT_IF(staticLevel != 0, callerFrame);
if (!CheckLength(cx, length))
return NULL;
AutoAttachToRuntime attacher(cx->runtime);
SourceCompressionToken sct(cx->runtime);
ScriptSource *ss = ScriptSource::createFromSource(cx, chars, length, false, &sct);
if (!ss)
return NULL;
attacher.ss = ss;
Parser parser(cx, principals, originPrincipals, chars, length, filename, lineno, version,
/* foldConstants = */ true, compileAndGo);
if (!parser.init())
@@ -72,7 +108,10 @@ frontend::CompileScript(JSContext *cx, HandleObject scopeChain, StackFrame *call
compileAndGo,
noScriptRval,
version,
staticLevel));
staticLevel,
ss,
0,
length));
if (!script)
return NULL;
@@ -215,6 +254,15 @@ frontend::CompileFunctionBody(JSContext *cx, HandleFunction fun,
Bindings *bindings, const jschar *chars, size_t length,
const char *filename, unsigned lineno, JSVersion version)
{
if (!CheckLength(cx, length))
return false;
AutoAttachToRuntime attacher(cx->runtime);
SourceCompressionToken sct(cx->runtime);
ScriptSource *ss = ScriptSource::createFromSource(cx, chars, length, true, &sct);
if (!ss)
return NULL;
attacher.ss = ss;
Parser parser(cx, principals, originPrincipals, chars, length, filename, lineno, version,
/* foldConstants = */ true, /* compileAndGo = */ false);
if (!parser.init())
@@ -239,7 +287,10 @@ frontend::CompileFunctionBody(JSContext *cx, HandleFunction fun,
/* compileAndGo = */ false,
/* noScriptRval = */ false,
version,
staticLevel));
staticLevel,
ss,
0,
length));
if (!script)
return false;