зеркало из https://github.com/mozilla/gecko-dev.git
Bug 674283 - Add source map urls to JSScript. r=jorendorff.
This commit is contained in:
Родитель
4bd2484a4e
Коммит
9d7d97c0a9
|
@ -16,7 +16,18 @@ try { \n\
|
||||||
catch (e) \n\
|
catch (e) \n\
|
||||||
{ \n\
|
{ \n\
|
||||||
xx += 1; \n\
|
xx += 1; \n\
|
||||||
}";
|
}\n\
|
||||||
|
//@sourceMappingURL=http://example.com/path/to/source-map.json";
|
||||||
|
|
||||||
|
|
||||||
|
static bool
|
||||||
|
CharsMatch(const jschar *p, const char *q) {
|
||||||
|
while (*q) {
|
||||||
|
if (*p++ != *q++)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// Bug 670958 - fix JS_GetScriptLineExtent, among others
|
// Bug 670958 - fix JS_GetScriptLineExtent, among others
|
||||||
BEGIN_TEST(testScriptInfo)
|
BEGIN_TEST(testScriptInfo)
|
||||||
|
@ -34,7 +45,8 @@ BEGIN_TEST(testScriptInfo)
|
||||||
CHECK_EQUAL(JS_PCToLineNumber(cx, script, start), startLine);
|
CHECK_EQUAL(JS_PCToLineNumber(cx, script, start), startLine);
|
||||||
CHECK_EQUAL(JS_GetScriptLineExtent(cx, script), 10);
|
CHECK_EQUAL(JS_GetScriptLineExtent(cx, script), 10);
|
||||||
CHECK(strcmp(JS_GetScriptFilename(cx, script), __FILE__) == 0);
|
CHECK(strcmp(JS_GetScriptFilename(cx, script), __FILE__) == 0);
|
||||||
|
CHECK(CharsMatch(JS_GetScriptSourceMap(cx, script), "http://example.com/path/to/source-map.json"));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
END_TEST(testScriptInfo)
|
END_TEST(testScriptInfo)
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
* the Initial Developer. All Rights Reserved.
|
* the Initial Developer. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Contributor(s):
|
* Contributor(s):
|
||||||
|
* Nick Fitzgerald <nfitzgerald@mozilla.com>
|
||||||
*
|
*
|
||||||
* Alternatively, the contents of this file may be used under the terms of
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||||
|
@ -422,7 +423,7 @@ JS_ClearTrap(JSContext *cx, JSScript *script, jsbytecode *pc,
|
||||||
JSTrapHandler *handlerp, jsval *closurep)
|
JSTrapHandler *handlerp, jsval *closurep)
|
||||||
{
|
{
|
||||||
JSTrap *trap;
|
JSTrap *trap;
|
||||||
|
|
||||||
DBG_LOCK(cx->runtime);
|
DBG_LOCK(cx->runtime);
|
||||||
trap = FindTrap(cx->runtime, script, pc);
|
trap = FindTrap(cx->runtime, script, pc);
|
||||||
if (handlerp)
|
if (handlerp)
|
||||||
|
@ -1045,6 +1046,12 @@ JS_GetScriptFilename(JSContext *cx, JSScript *script)
|
||||||
return script->filename;
|
return script->filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JS_PUBLIC_API(const jschar *)
|
||||||
|
JS_GetScriptSourceMap(JSContext *cx, JSScript *script)
|
||||||
|
{
|
||||||
|
return script->sourceMap;
|
||||||
|
}
|
||||||
|
|
||||||
JS_PUBLIC_API(uintN)
|
JS_PUBLIC_API(uintN)
|
||||||
JS_GetScriptBaseLineNumber(JSContext *cx, JSScript *script)
|
JS_GetScriptBaseLineNumber(JSContext *cx, JSScript *script)
|
||||||
{
|
{
|
||||||
|
@ -1131,7 +1138,7 @@ JS_EvaluateInStackFrame(JSContext *cx, JSStackFrame *fp,
|
||||||
jschar *chars;
|
jschar *chars;
|
||||||
JSBool ok;
|
JSBool ok;
|
||||||
size_t len = length;
|
size_t len = length;
|
||||||
|
|
||||||
if (!CheckDebugMode(cx))
|
if (!CheckDebugMode(cx))
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
* the Initial Developer. All Rights Reserved.
|
* the Initial Developer. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Contributor(s):
|
* Contributor(s):
|
||||||
|
* Nick Fitzgerald <nfitzgerald@mozilla.com>
|
||||||
*
|
*
|
||||||
* Alternatively, the contents of this file may be used under the terms of
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||||
|
@ -349,6 +350,9 @@ JS_GetValidFrameCalleeObject(JSContext *cx, JSStackFrame *fp, jsval *vp);
|
||||||
extern JS_PUBLIC_API(const char *)
|
extern JS_PUBLIC_API(const char *)
|
||||||
JS_GetScriptFilename(JSContext *cx, JSScript *script);
|
JS_GetScriptFilename(JSContext *cx, JSScript *script);
|
||||||
|
|
||||||
|
extern JS_PUBLIC_API(const jschar *)
|
||||||
|
JS_GetScriptSourceMap(JSContext *cx, JSScript *script);
|
||||||
|
|
||||||
extern JS_PUBLIC_API(uintN)
|
extern JS_PUBLIC_API(uintN)
|
||||||
JS_GetScriptBaseLineNumber(JSContext *cx, JSScript *script);
|
JS_GetScriptBaseLineNumber(JSContext *cx, JSScript *script);
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
* the Initial Developer. All Rights Reserved.
|
* the Initial Developer. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Contributor(s):
|
* Contributor(s):
|
||||||
|
* Nick Fitzgerald <nfitzgerald@mozilla.com>
|
||||||
*
|
*
|
||||||
* Alternatively, the contents of this file may be used under the terms of
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||||
|
@ -179,6 +180,7 @@ TokenStream::init(const jschar *base, size_t length, const char *fn, uintN ln, J
|
||||||
userbuf.init(base, length);
|
userbuf.init(base, length);
|
||||||
linebase = base;
|
linebase = base;
|
||||||
prevLinebase = NULL;
|
prevLinebase = NULL;
|
||||||
|
sourceMap = NULL;
|
||||||
|
|
||||||
JSSourceHandler listener = cx->debugHooks->sourceHandler;
|
JSSourceHandler listener = cx->debugHooks->sourceHandler;
|
||||||
void *listenerData = cx->debugHooks->sourceHandlerData;
|
void *listenerData = cx->debugHooks->sourceHandlerData;
|
||||||
|
@ -247,6 +249,8 @@ TokenStream::~TokenStream()
|
||||||
{
|
{
|
||||||
if (flags & TSF_OWNFILENAME)
|
if (flags & TSF_OWNFILENAME)
|
||||||
cx->free_((void *) filename);
|
cx->free_((void *) filename);
|
||||||
|
if (sourceMap)
|
||||||
|
cx->free_(sourceMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Use the fastest available getc. */
|
/* Use the fastest available getc. */
|
||||||
|
@ -1132,6 +1136,19 @@ TokenStream::matchUnicodeEscapeIdent(int32 *cp)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Helper function which returns true if the first length(q) characters in p are
|
||||||
|
* the same as the characters in q.
|
||||||
|
*/
|
||||||
|
static bool
|
||||||
|
CharsMatch(const jschar *p, const char *q) {
|
||||||
|
while (*q) {
|
||||||
|
if (*p++ != *q++)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
TokenStream::getAtLine()
|
TokenStream::getAtLine()
|
||||||
{
|
{
|
||||||
|
@ -1145,12 +1162,7 @@ TokenStream::getAtLine()
|
||||||
* "//@line 123\n" sets the number of the *next* line after the
|
* "//@line 123\n" sets the number of the *next* line after the
|
||||||
* comment to 123. If we reach here, we've already seen "//".
|
* comment to 123. If we reach here, we've already seen "//".
|
||||||
*/
|
*/
|
||||||
if (peekChars(5, cp) &&
|
if (peekChars(5, cp) && CharsMatch(cp, "@line")) {
|
||||||
cp[0] == '@' &&
|
|
||||||
cp[1] == 'l' &&
|
|
||||||
cp[2] == 'i' &&
|
|
||||||
cp[3] == 'n' &&
|
|
||||||
cp[4] == 'e') {
|
|
||||||
skipChars(5);
|
skipChars(5);
|
||||||
while ((c = getChar()) != '\n' && c != EOF && IsSpaceOrBOM2(c))
|
while ((c = getChar()) != '\n' && c != EOF && IsSpaceOrBOM2(c))
|
||||||
continue;
|
continue;
|
||||||
|
@ -1200,6 +1212,42 @@ TokenStream::getAtLine()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
TokenStream::getAtSourceMappingURL()
|
||||||
|
{
|
||||||
|
jschar peeked[18];
|
||||||
|
|
||||||
|
/* Match comments of the form @sourceMappingURL=<url> */
|
||||||
|
if (peekChars(18, peeked) && CharsMatch(peeked, "@sourceMappingURL=")) {
|
||||||
|
skipChars(18);
|
||||||
|
tokenbuf.clear();
|
||||||
|
|
||||||
|
jschar c;
|
||||||
|
while (!IsSpaceOrBOM2((c = getChar())) &&
|
||||||
|
((char) c) != '\0' &&
|
||||||
|
((char) c) != EOF)
|
||||||
|
tokenbuf.append(c);
|
||||||
|
|
||||||
|
if (tokenbuf.empty())
|
||||||
|
/* The source map's URL was missing, but not quite an exception that
|
||||||
|
* we should stop and drop everything for, though. */
|
||||||
|
return true;
|
||||||
|
|
||||||
|
int len = tokenbuf.length();
|
||||||
|
|
||||||
|
if (sourceMap)
|
||||||
|
cx->free_(sourceMap);
|
||||||
|
sourceMap = (jschar *) cx->malloc_(sizeof(jschar) * (len + 1));
|
||||||
|
if (!sourceMap)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (int i = 0; i < len; i++)
|
||||||
|
sourceMap[i] = tokenbuf[i];
|
||||||
|
sourceMap[len] = '\0';
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
Token *
|
Token *
|
||||||
TokenStream::newToken(ptrdiff_t adjust)
|
TokenStream::newToken(ptrdiff_t adjust)
|
||||||
{
|
{
|
||||||
|
@ -1254,7 +1302,7 @@ bool
|
||||||
TokenStream::putIdentInTokenbuf(const jschar *identStart)
|
TokenStream::putIdentInTokenbuf(const jschar *identStart)
|
||||||
{
|
{
|
||||||
int32 c, qc;
|
int32 c, qc;
|
||||||
const jschar *tmp = userbuf.addressOfNextRawChar();
|
const jschar *tmp = userbuf.addressOfNextRawChar();
|
||||||
userbuf.setAddressOfNextRawChar(identStart);
|
userbuf.setAddressOfNextRawChar(identStart);
|
||||||
|
|
||||||
tokenbuf.clear();
|
tokenbuf.clear();
|
||||||
|
@ -1483,7 +1531,7 @@ TokenStream::getTokenInternal()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Identifiers containing no Unicode escapes can be atomized directly
|
* Identifiers containing no Unicode escapes can be atomized directly
|
||||||
* from userbuf. The rest must have the escapes converted via
|
* from userbuf. The rest must have the escapes converted via
|
||||||
* tokenbuf before atomizing.
|
* tokenbuf before atomizing.
|
||||||
|
@ -1681,7 +1729,7 @@ TokenStream::getTokenInternal()
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Unlike identifiers and strings, numbers cannot contain escaped
|
* Unlike identifiers and strings, numbers cannot contain escaped
|
||||||
* chars, so we don't need to use tokenbuf. Instead we can just
|
* chars, so we don't need to use tokenbuf. Instead we can just
|
||||||
* convert the jschars in userbuf directly to the numeric value.
|
* convert the jschars in userbuf directly to the numeric value.
|
||||||
|
@ -1899,6 +1947,9 @@ TokenStream::getTokenInternal()
|
||||||
if (cx->hasAtLineOption() && !getAtLine())
|
if (cx->hasAtLineOption() && !getAtLine())
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
if (!getAtSourceMappingURL())
|
||||||
|
goto error;
|
||||||
|
|
||||||
skipline:
|
skipline:
|
||||||
/* Optimize line skipping if we are not in an HTML comment. */
|
/* Optimize line skipping if we are not in an HTML comment. */
|
||||||
if (flags & TSF_IN_HTML_COMMENT) {
|
if (flags & TSF_IN_HTML_COMMENT) {
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
* the Initial Developer. All Rights Reserved.
|
* the Initial Developer. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Contributor(s):
|
* Contributor(s):
|
||||||
|
* Nick Fitzgerald <nfitzgerald@mozilla.com>
|
||||||
*
|
*
|
||||||
* Alternatively, the contents of this file may be used under the terms of
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||||
|
@ -485,6 +486,14 @@ class TokenStream
|
||||||
return matchToken(tt);
|
return matchToken(tt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Give up responsibility for managing the sourceMap filename's memory.
|
||||||
|
*/
|
||||||
|
const jschar *releaseSourceMap() {
|
||||||
|
const jschar* sm = sourceMap;
|
||||||
|
sourceMap = NULL;
|
||||||
|
return sm;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*
|
/*
|
||||||
|
@ -589,6 +598,7 @@ class TokenStream
|
||||||
bool matchUnicodeEscapeIdent(int32 *c);
|
bool matchUnicodeEscapeIdent(int32 *c);
|
||||||
bool peekChars(intN n, jschar *cp);
|
bool peekChars(intN n, jschar *cp);
|
||||||
bool getAtLine();
|
bool getAtLine();
|
||||||
|
bool getAtSourceMappingURL();
|
||||||
|
|
||||||
bool getXMLEntity();
|
bool getXMLEntity();
|
||||||
bool getXMLTextOrTag(TokenKind *ttp, Token **tpp);
|
bool getXMLTextOrTag(TokenKind *ttp, Token **tpp);
|
||||||
|
@ -626,6 +636,7 @@ class TokenStream
|
||||||
const jschar *prevLinebase; /* start of previous line; NULL if on the first line */
|
const jschar *prevLinebase; /* start of previous line; NULL if on the first line */
|
||||||
TokenBuf userbuf; /* user input buffer */
|
TokenBuf userbuf; /* user input buffer */
|
||||||
const char *filename; /* input filename or null */
|
const char *filename; /* input filename or null */
|
||||||
|
jschar *sourceMap; /* source map's filename or null */
|
||||||
void *listenerTSData;/* listener data for this TokenStream */
|
void *listenerTSData;/* listener data for this TokenStream */
|
||||||
CharBuffer tokenbuf; /* current token string buffer */
|
CharBuffer tokenbuf; /* current token string buffer */
|
||||||
int8 oneCharTokens[128]; /* table of one-char tokens */
|
int8 oneCharTokens[128]; /* table of one-char tokens */
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
* the Initial Developer. All Rights Reserved.
|
* the Initial Developer. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Contributor(s):
|
* Contributor(s):
|
||||||
|
* Nick Fitzgerald <nfitzgerald@mozilla.com>
|
||||||
*
|
*
|
||||||
* Alternatively, the contents of this file may be used under the terms of
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||||
|
@ -1190,6 +1191,8 @@ JSScript::NewScriptFromCG(JSContext *cx, JSCodeGenerator *cg)
|
||||||
if (script->principals)
|
if (script->principals)
|
||||||
JSPRINCIPALS_HOLD(cx, script->principals);
|
JSPRINCIPALS_HOLD(cx, script->principals);
|
||||||
|
|
||||||
|
script->sourceMap = (jschar *) cg->parser->tokenStream.releaseSourceMap();
|
||||||
|
|
||||||
if (!js_FinishTakingSrcNotes(cx, cg, script->notes()))
|
if (!js_FinishTakingSrcNotes(cx, cg, script->notes()))
|
||||||
goto bad;
|
goto bad;
|
||||||
if (cg->ntrynotes != 0)
|
if (cg->ntrynotes != 0)
|
||||||
|
@ -1402,6 +1405,9 @@ DestroyScript(JSContext *cx, JSScript *script, JSObject *owner)
|
||||||
|
|
||||||
script->pcCounters.destroy(cx);
|
script->pcCounters.destroy(cx);
|
||||||
|
|
||||||
|
if (script->sourceMap)
|
||||||
|
cx->free_(script->sourceMap);
|
||||||
|
|
||||||
memset(script, JS_FREE_PATTERN, script->totalSize());
|
memset(script, JS_FREE_PATTERN, script->totalSize());
|
||||||
cx->free_(script);
|
cx->free_(script);
|
||||||
}
|
}
|
||||||
|
|
|
@ -505,6 +505,7 @@ struct JSScript {
|
||||||
js::Bindings bindings; /* names of top-level variables in this script
|
js::Bindings bindings; /* names of top-level variables in this script
|
||||||
(and arguments if this is a function script) */
|
(and arguments if this is a function script) */
|
||||||
JSPrincipals *principals;/* principals for this script */
|
JSPrincipals *principals;/* principals for this script */
|
||||||
|
jschar *sourceMap; /* source map file or null */
|
||||||
|
|
||||||
JSObject *ownerObject;
|
JSObject *ownerObject;
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче