mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-06 14:44:26 +00:00
Bug 885758 - Add ExclusiveContext for use by threads with exclusive access to their compartment, r=billm.
This commit is contained in:
parent
63ed0e9589
commit
aafb978437
@ -512,7 +512,7 @@ struct GCMethods<T *>
|
||||
#endif
|
||||
};
|
||||
|
||||
#if defined(DEBUG) && defined(JS_THREADSAFE)
|
||||
#if defined(DEBUG)
|
||||
/* This helper allows us to assert that Rooted<T> is scoped within a request. */
|
||||
extern JS_PUBLIC_API(bool)
|
||||
IsInRequest(JSContext *cx);
|
||||
@ -533,21 +533,16 @@ namespace JS {
|
||||
template <typename T>
|
||||
class MOZ_STACK_CLASS Rooted : public js::RootedBase<T>
|
||||
{
|
||||
void init(JSContext *cxArg) {
|
||||
MOZ_ASSERT(cxArg);
|
||||
#ifdef JS_THREADSAFE
|
||||
MOZ_ASSERT(js::IsInRequest(cxArg));
|
||||
#endif
|
||||
/* Note: CX is a subclass of either ContextFriendFields or PerThreadDataFriendFields. */
|
||||
template <typename CX>
|
||||
void init(CX *cx) {
|
||||
#ifdef JSGC_TRACK_EXACT_ROOTS
|
||||
js::ContextFriendFields *cx = js::ContextFriendFields::get(cxArg);
|
||||
commonInit(cx->thingGCRooters);
|
||||
#endif
|
||||
}
|
||||
js::ThingRootKind kind = js::GCMethods<T>::kind();
|
||||
this->stack = &cx->thingGCRooters[kind];
|
||||
this->prev = *stack;
|
||||
*stack = reinterpret_cast<Rooted<void*>*>(this);
|
||||
|
||||
void init(js::PerThreadDataFriendFields *pt) {
|
||||
MOZ_ASSERT(pt);
|
||||
#ifdef JSGC_TRACK_EXACT_ROOTS
|
||||
commonInit(pt->thingGCRooters);
|
||||
JS_ASSERT(!js::GCMethods<T>::poisoned(ptr));
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -557,7 +552,8 @@ class MOZ_STACK_CLASS Rooted : public js::RootedBase<T>
|
||||
: ptr(js::GCMethods<T>::initial())
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
init(cx);
|
||||
MOZ_ASSERT(js::IsInRequest(cx));
|
||||
init(js::ContextFriendFields::get(cx));
|
||||
}
|
||||
|
||||
Rooted(JSContext *cx, T initial
|
||||
@ -565,23 +561,40 @@ class MOZ_STACK_CLASS Rooted : public js::RootedBase<T>
|
||||
: ptr(initial)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
init(cx);
|
||||
MOZ_ASSERT(js::IsInRequest(cx));
|
||||
init(js::ContextFriendFields::get(cx));
|
||||
}
|
||||
|
||||
Rooted(js::PerThreadData *pt
|
||||
Rooted(js::ContextFriendFields *cx
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: ptr(js::GCMethods<T>::initial())
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
init(js::PerThreadDataFriendFields::get(pt));
|
||||
init(cx);
|
||||
}
|
||||
|
||||
Rooted(js::PerThreadData *pt, T initial
|
||||
Rooted(js::ContextFriendFields *cx, T initial
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: ptr(initial)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
init(js::PerThreadDataFriendFields::get(pt));
|
||||
init(cx);
|
||||
}
|
||||
|
||||
Rooted(js::PerThreadDataFriendFields *pt
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: ptr(js::GCMethods<T>::initial())
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
init(pt);
|
||||
}
|
||||
|
||||
Rooted(js::PerThreadDataFriendFields *pt, T initial
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: ptr(initial)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
init(pt);
|
||||
}
|
||||
|
||||
Rooted(JSRuntime *rt
|
||||
@ -642,20 +655,6 @@ class MOZ_STACK_CLASS Rooted : public js::RootedBase<T>
|
||||
bool operator==(const T &other) const { return ptr == other; }
|
||||
|
||||
private:
|
||||
void commonInit(Rooted<void*> **thingGCRooters) {
|
||||
#if defined(DEBUG) && defined(JS_GC_ZEAL) && defined(JSGC_ROOT_ANALYSIS) && !defined(JS_THREADSAFE)
|
||||
scanned = false;
|
||||
#endif
|
||||
#ifdef JSGC_TRACK_EXACT_ROOTS
|
||||
js::ThingRootKind kind = js::GCMethods<T>::kind();
|
||||
this->stack = &thingGCRooters[kind];
|
||||
this->prev = *stack;
|
||||
*stack = reinterpret_cast<Rooted<void*>*>(this);
|
||||
|
||||
JS_ASSERT(!js::GCMethods<T>::poisoned(ptr));
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef JSGC_TRACK_EXACT_ROOTS
|
||||
Rooted<void*> **stack, *prev;
|
||||
#endif
|
||||
@ -713,8 +712,9 @@ class SkipRoot
|
||||
const uint8_t *start;
|
||||
const uint8_t *end;
|
||||
|
||||
template <typename T>
|
||||
void init(SkipRoot **head, const T *ptr, size_t count) {
|
||||
template <typename CX, typename T>
|
||||
void init(CX *cx, const T *ptr, size_t count) {
|
||||
SkipRoot **head = &cx->skipGCRooters;
|
||||
this->stack = head;
|
||||
this->prev = *stack;
|
||||
*stack = this;
|
||||
@ -723,23 +723,6 @@ class SkipRoot
|
||||
}
|
||||
|
||||
public:
|
||||
template <typename T>
|
||||
SkipRoot(JSContext *cx, const T *ptr, size_t count = 1
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
{
|
||||
init(&ContextFriendFields::get(cx)->skipGCRooters, ptr, count);
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
SkipRoot(js::PerThreadData *ptd, const T *ptr, size_t count = 1
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
{
|
||||
PerThreadDataFriendFields *ptff = PerThreadDataFriendFields::get(ptd);
|
||||
init(&ptff->skipGCRooters, ptr, count);
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
}
|
||||
|
||||
~SkipRoot() {
|
||||
JS_ASSERT(*stack == this);
|
||||
*stack = prev;
|
||||
@ -753,22 +736,36 @@ class SkipRoot
|
||||
|
||||
#else /* DEBUG && JSGC_ROOT_ANALYSIS */
|
||||
|
||||
template <typename T>
|
||||
void init(js::ContextFriendFields *cx, const T *ptr, size_t count) {}
|
||||
|
||||
public:
|
||||
|
||||
#endif /* DEBUG && JSGC_ROOT_ANALYSIS */
|
||||
|
||||
template <typename T>
|
||||
SkipRoot(JSContext *cx, const T *ptr, size_t count = 1
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
{
|
||||
init(ContextFriendFields::get(cx), ptr, count);
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
SkipRoot(PerThreadData *ptd, const T *ptr, size_t count = 1
|
||||
SkipRoot(ContextFriendFields *cx, const T *ptr, size_t count = 1
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
{
|
||||
init(cx, ptr, count);
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
}
|
||||
|
||||
#endif /* DEBUG && JSGC_ROOT_ANALYSIS */
|
||||
template <typename T>
|
||||
SkipRoot(PerThreadData *pt, const T *ptr, size_t count = 1
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
{
|
||||
init(PerThreadDataFriendFields::get(pt), ptr, count);
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
}
|
||||
|
||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
};
|
||||
@ -778,15 +775,17 @@ template <typename T>
|
||||
class FakeRooted : public RootedBase<T>
|
||||
{
|
||||
public:
|
||||
FakeRooted(JSContext *cx
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
template <typename CX>
|
||||
FakeRooted(CX *cx
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: ptr(GCMethods<T>::initial())
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
}
|
||||
|
||||
FakeRooted(JSContext *cx, T initial
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
template <typename CX>
|
||||
FakeRooted(CX *cx, T initial
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: ptr(initial)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
|
@ -35,7 +35,7 @@ Module::setScript(JSScript *script)
|
||||
}
|
||||
|
||||
Module *
|
||||
Module::create(JSContext *cx, HandleAtom atom)
|
||||
Module::create(ExclusiveContext *cx, HandleAtom atom)
|
||||
{
|
||||
RootedObject object(cx, NewBuiltinClassInstance(cx, &class_));
|
||||
if (!object)
|
||||
|
@ -13,7 +13,7 @@ namespace js {
|
||||
|
||||
class Module : public JSObject {
|
||||
public:
|
||||
static Module *create(JSContext *cx, js::HandleAtom atom);
|
||||
static Module *create(ExclusiveContext *cx, js::HandleAtom atom);
|
||||
|
||||
JSAtom *atom() {
|
||||
return &getReservedSlot(ATOM_SLOT).toString()->asAtom();
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "vm/StringBuffer.h"
|
||||
|
||||
#include "jsobjinlines.h"
|
||||
#include "jsstrinlines.h"
|
||||
|
||||
using namespace js;
|
||||
using namespace js::types;
|
||||
|
@ -179,16 +179,19 @@ frontend::CompileScript(JSContext *cx, HandleObject scopeChain,
|
||||
|
||||
Maybe<Parser<SyntaxParseHandler> > syntaxParser;
|
||||
if (canLazilyParse) {
|
||||
syntaxParser.construct(cx, options, chars, length, /* foldConstants = */ false,
|
||||
syntaxParser.construct(cx, &cx->tempLifoAlloc(),
|
||||
options, chars, length, /* foldConstants = */ false,
|
||||
(Parser<SyntaxParseHandler> *) NULL,
|
||||
(LazyScript *) NULL);
|
||||
}
|
||||
|
||||
Parser<FullParseHandler> parser(cx, options, chars, length, /* foldConstants = */ true,
|
||||
Parser<FullParseHandler> parser(cx, &cx->tempLifoAlloc(),
|
||||
options, chars, length, /* foldConstants = */ true,
|
||||
canLazilyParse ? &syntaxParser.ref() : NULL, NULL);
|
||||
parser.sct = sct;
|
||||
|
||||
GlobalSharedContext globalsc(cx, scopeChain, StrictModeFromContext(cx));
|
||||
GlobalSharedContext globalsc(cx, scopeChain,
|
||||
options.strictOption, options.extraWarningsOption);
|
||||
|
||||
bool savedCallerFun =
|
||||
options.compileAndGo &&
|
||||
@ -354,7 +357,7 @@ frontend::CompileLazyFunction(JSContext *cx, HandleFunction fun, LazyScript *laz
|
||||
.setNoScriptRval(false)
|
||||
.setSelfHostingMode(false);
|
||||
|
||||
Parser<FullParseHandler> parser(cx, options, chars, length,
|
||||
Parser<FullParseHandler> parser(cx, &cx->tempLifoAlloc(), options, chars, length,
|
||||
/* foldConstants = */ true, NULL, lazy);
|
||||
|
||||
uint32_t staticLevel = lazy->staticLevel(cx);
|
||||
@ -422,14 +425,16 @@ frontend::CompileFunctionBody(JSContext *cx, MutableHandleFunction fun, CompileO
|
||||
|
||||
Maybe<Parser<SyntaxParseHandler> > syntaxParser;
|
||||
if (canLazilyParse) {
|
||||
syntaxParser.construct(cx, options, chars, length, /* foldConstants = */ false,
|
||||
syntaxParser.construct(cx, &cx->tempLifoAlloc(),
|
||||
options, chars, length, /* foldConstants = */ false,
|
||||
(Parser<SyntaxParseHandler> *) NULL,
|
||||
(LazyScript *) NULL);
|
||||
}
|
||||
|
||||
JS_ASSERT(!options.forEval);
|
||||
|
||||
Parser<FullParseHandler> parser(cx, options, chars, length, /* foldConstants = */ true,
|
||||
Parser<FullParseHandler> parser(cx, &cx->tempLifoAlloc(),
|
||||
options, chars, length, /* foldConstants = */ true,
|
||||
canLazilyParse ? &syntaxParser.ref() : NULL, NULL);
|
||||
parser.sct = &sct;
|
||||
|
||||
@ -465,7 +470,7 @@ frontend::CompileFunctionBody(JSContext *cx, MutableHandleFunction fun, CompileO
|
||||
// directive, we backup and reparse it as strict.
|
||||
TokenStream::Position start(parser.keepAtoms);
|
||||
parser.tokenStream.tell(&start);
|
||||
bool strict = StrictModeFromContext(cx);
|
||||
bool strict = options.strictOption;
|
||||
bool becameStrict;
|
||||
FunctionBox *funbox;
|
||||
ParseNode *pn;
|
||||
|
@ -49,7 +49,7 @@ using mozilla::DoubleIsInt32;
|
||||
using mozilla::PodCopy;
|
||||
|
||||
static bool
|
||||
SetSrcNoteOffset(JSContext *cx, BytecodeEmitter *bce, unsigned index, unsigned which, ptrdiff_t offset);
|
||||
SetSrcNoteOffset(ExclusiveContext *cx, BytecodeEmitter *bce, unsigned index, unsigned which, ptrdiff_t offset);
|
||||
|
||||
struct frontend::StmtInfoBCE : public StmtInfoBase
|
||||
{
|
||||
@ -60,7 +60,7 @@ struct frontend::StmtInfoBCE : public StmtInfoBase
|
||||
ptrdiff_t breaks; /* offset of last break in loop */
|
||||
ptrdiff_t continues; /* offset of last continue in loop */
|
||||
|
||||
StmtInfoBCE(JSContext *cx) : StmtInfoBase(cx) {}
|
||||
StmtInfoBCE(ExclusiveContext *cx) : StmtInfoBase(cx) {}
|
||||
|
||||
/*
|
||||
* To reuse space, alias two of the ptrdiff_t fields for use during
|
||||
@ -122,7 +122,7 @@ BytecodeEmitter::init()
|
||||
}
|
||||
|
||||
static ptrdiff_t
|
||||
EmitCheck(JSContext *cx, BytecodeEmitter *bce, ptrdiff_t delta)
|
||||
EmitCheck(ExclusiveContext *cx, BytecodeEmitter *bce, ptrdiff_t delta)
|
||||
{
|
||||
ptrdiff_t offset = bce->code().length();
|
||||
|
||||
@ -147,7 +147,7 @@ CurrentBlock(StmtInfoBCE *topStmt)
|
||||
}
|
||||
|
||||
static void
|
||||
UpdateDepth(JSContext *cx, BytecodeEmitter *bce, ptrdiff_t target)
|
||||
UpdateDepth(ExclusiveContext *cx, BytecodeEmitter *bce, ptrdiff_t target)
|
||||
{
|
||||
jsbytecode *pc = bce->code(target);
|
||||
JSOp op = (JSOp) *pc;
|
||||
@ -190,7 +190,7 @@ UpdateDepth(JSContext *cx, BytecodeEmitter *bce, ptrdiff_t target)
|
||||
}
|
||||
|
||||
ptrdiff_t
|
||||
frontend::Emit1(JSContext *cx, BytecodeEmitter *bce, JSOp op)
|
||||
frontend::Emit1(ExclusiveContext *cx, BytecodeEmitter *bce, JSOp op)
|
||||
{
|
||||
ptrdiff_t offset = EmitCheck(cx, bce, 1);
|
||||
if (offset < 0)
|
||||
@ -203,7 +203,7 @@ frontend::Emit1(JSContext *cx, BytecodeEmitter *bce, JSOp op)
|
||||
}
|
||||
|
||||
ptrdiff_t
|
||||
frontend::Emit2(JSContext *cx, BytecodeEmitter *bce, JSOp op, jsbytecode op1)
|
||||
frontend::Emit2(ExclusiveContext *cx, BytecodeEmitter *bce, JSOp op, jsbytecode op1)
|
||||
{
|
||||
ptrdiff_t offset = EmitCheck(cx, bce, 2);
|
||||
if (offset < 0)
|
||||
@ -217,7 +217,7 @@ frontend::Emit2(JSContext *cx, BytecodeEmitter *bce, JSOp op, jsbytecode op1)
|
||||
}
|
||||
|
||||
ptrdiff_t
|
||||
frontend::Emit3(JSContext *cx, BytecodeEmitter *bce, JSOp op, jsbytecode op1,
|
||||
frontend::Emit3(ExclusiveContext *cx, BytecodeEmitter *bce, JSOp op, jsbytecode op1,
|
||||
jsbytecode op2)
|
||||
{
|
||||
/* These should filter through EmitVarOp. */
|
||||
@ -237,7 +237,7 @@ frontend::Emit3(JSContext *cx, BytecodeEmitter *bce, JSOp op, jsbytecode op1,
|
||||
}
|
||||
|
||||
ptrdiff_t
|
||||
frontend::EmitN(JSContext *cx, BytecodeEmitter *bce, JSOp op, size_t extra)
|
||||
frontend::EmitN(ExclusiveContext *cx, BytecodeEmitter *bce, JSOp op, size_t extra)
|
||||
{
|
||||
ptrdiff_t length = 1 + (ptrdiff_t)extra;
|
||||
ptrdiff_t offset = EmitCheck(cx, bce, length);
|
||||
@ -259,7 +259,7 @@ frontend::EmitN(JSContext *cx, BytecodeEmitter *bce, JSOp op, size_t extra)
|
||||
}
|
||||
|
||||
static ptrdiff_t
|
||||
EmitJump(JSContext *cx, BytecodeEmitter *bce, JSOp op, ptrdiff_t off)
|
||||
EmitJump(ExclusiveContext *cx, BytecodeEmitter *bce, JSOp op, ptrdiff_t off)
|
||||
{
|
||||
ptrdiff_t offset = EmitCheck(cx, bce, 5);
|
||||
if (offset < 0)
|
||||
@ -306,10 +306,9 @@ StatementName(StmtInfoBCE *topStmt)
|
||||
}
|
||||
|
||||
static void
|
||||
ReportStatementTooLarge(JSContext *cx, StmtInfoBCE *topStmt)
|
||||
ReportStatementTooLarge(TokenStream &ts, StmtInfoBCE *topStmt)
|
||||
{
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NEED_DIET,
|
||||
StatementName(topStmt));
|
||||
ts.reportError(JSMSG_NEED_DIET, StatementName(topStmt));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -317,7 +316,7 @@ ReportStatementTooLarge(JSContext *cx, StmtInfoBCE *topStmt)
|
||||
* so that we can walk back up the chain fixing up the op and jump offset.
|
||||
*/
|
||||
static ptrdiff_t
|
||||
EmitBackPatchOp(JSContext *cx, BytecodeEmitter *bce, ptrdiff_t *lastp)
|
||||
EmitBackPatchOp(ExclusiveContext *cx, BytecodeEmitter *bce, ptrdiff_t *lastp)
|
||||
{
|
||||
ptrdiff_t offset, delta;
|
||||
|
||||
@ -330,7 +329,7 @@ EmitBackPatchOp(JSContext *cx, BytecodeEmitter *bce, ptrdiff_t *lastp)
|
||||
|
||||
/* Updates line number notes, not column notes. */
|
||||
static inline bool
|
||||
UpdateLineNumberNotes(JSContext *cx, BytecodeEmitter *bce, uint32_t offset)
|
||||
UpdateLineNumberNotes(ExclusiveContext *cx, BytecodeEmitter *bce, uint32_t offset)
|
||||
{
|
||||
TokenStream *ts = &bce->parser->tokenStream;
|
||||
if (!ts->srcCoords.isOnThisLine(offset, bce->currentLine())) {
|
||||
@ -365,7 +364,7 @@ UpdateLineNumberNotes(JSContext *cx, BytecodeEmitter *bce, uint32_t offset)
|
||||
|
||||
/* A function, so that we avoid macro-bloating all the other callsites. */
|
||||
static bool
|
||||
UpdateSourceCoordNotes(JSContext *cx, BytecodeEmitter *bce, uint32_t offset)
|
||||
UpdateSourceCoordNotes(ExclusiveContext *cx, BytecodeEmitter *bce, uint32_t offset)
|
||||
{
|
||||
if (!UpdateLineNumberNotes(cx, bce, offset))
|
||||
return false;
|
||||
@ -391,7 +390,7 @@ UpdateSourceCoordNotes(JSContext *cx, BytecodeEmitter *bce, uint32_t offset)
|
||||
}
|
||||
|
||||
static ptrdiff_t
|
||||
EmitLoopHead(JSContext *cx, BytecodeEmitter *bce, ParseNode *nextpn)
|
||||
EmitLoopHead(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *nextpn)
|
||||
{
|
||||
if (nextpn) {
|
||||
/*
|
||||
@ -410,7 +409,7 @@ EmitLoopHead(JSContext *cx, BytecodeEmitter *bce, ParseNode *nextpn)
|
||||
}
|
||||
|
||||
static bool
|
||||
EmitLoopEntry(JSContext *cx, BytecodeEmitter *bce, ParseNode *nextpn)
|
||||
EmitLoopEntry(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *nextpn)
|
||||
{
|
||||
if (nextpn) {
|
||||
/* Update the line number, as for LOOPHEAD. */
|
||||
@ -445,7 +444,7 @@ EmitLoopEntry(JSContext *cx, BytecodeEmitter *bce, ParseNode *nextpn)
|
||||
* a type set to store its result.
|
||||
*/
|
||||
static inline void
|
||||
CheckTypeSet(JSContext *cx, BytecodeEmitter *bce, JSOp op)
|
||||
CheckTypeSet(ExclusiveContext *cx, BytecodeEmitter *bce, JSOp op)
|
||||
{
|
||||
if (js_CodeSpec[op].format & JOF_TYPESET) {
|
||||
if (bce->typesetCount < UINT16_MAX)
|
||||
@ -494,7 +493,7 @@ CheckTypeSet(JSContext *cx, BytecodeEmitter *bce, JSOp op)
|
||||
JS_END_MACRO
|
||||
|
||||
static bool
|
||||
FlushPops(JSContext *cx, BytecodeEmitter *bce, int *npops)
|
||||
FlushPops(ExclusiveContext *cx, BytecodeEmitter *bce, int *npops)
|
||||
{
|
||||
JS_ASSERT(*npops != 0);
|
||||
if (NewSrcNote(cx, bce, SRC_HIDDEN) < 0)
|
||||
@ -505,7 +504,7 @@ FlushPops(JSContext *cx, BytecodeEmitter *bce, int *npops)
|
||||
}
|
||||
|
||||
static bool
|
||||
PopIterator(JSContext *cx, BytecodeEmitter *bce)
|
||||
PopIterator(ExclusiveContext *cx, BytecodeEmitter *bce)
|
||||
{
|
||||
if (NewSrcNote(cx, bce, SRC_HIDDEN) < 0)
|
||||
return false;
|
||||
@ -518,7 +517,7 @@ PopIterator(JSContext *cx, BytecodeEmitter *bce)
|
||||
* Emit additional bytecode(s) for non-local jumps.
|
||||
*/
|
||||
static bool
|
||||
EmitNonLocalJumpFixup(JSContext *cx, BytecodeEmitter *bce, StmtInfoBCE *toStmt)
|
||||
EmitNonLocalJumpFixup(ExclusiveContext *cx, BytecodeEmitter *bce, StmtInfoBCE *toStmt)
|
||||
{
|
||||
/*
|
||||
* The non-local jump fixup we emit will unbalance bce->stackDepth, because
|
||||
@ -608,7 +607,7 @@ EmitNonLocalJumpFixup(JSContext *cx, BytecodeEmitter *bce, StmtInfoBCE *toStmt)
|
||||
static const jsatomid INVALID_ATOMID = -1;
|
||||
|
||||
static ptrdiff_t
|
||||
EmitGoto(JSContext *cx, BytecodeEmitter *bce, StmtInfoBCE *toStmt, ptrdiff_t *lastp,
|
||||
EmitGoto(ExclusiveContext *cx, BytecodeEmitter *bce, StmtInfoBCE *toStmt, ptrdiff_t *lastp,
|
||||
SrcNoteType noteType = SRC_NULL)
|
||||
{
|
||||
if (!EmitNonLocalJumpFixup(cx, bce, toStmt))
|
||||
@ -623,7 +622,7 @@ EmitGoto(JSContext *cx, BytecodeEmitter *bce, StmtInfoBCE *toStmt, ptrdiff_t *la
|
||||
}
|
||||
|
||||
static bool
|
||||
BackPatch(JSContext *cx, BytecodeEmitter *bce, ptrdiff_t last, jsbytecode *target, jsbytecode op)
|
||||
BackPatch(ExclusiveContext *cx, BytecodeEmitter *bce, ptrdiff_t last, jsbytecode *target, jsbytecode op)
|
||||
{
|
||||
jsbytecode *pc, *stop;
|
||||
ptrdiff_t delta, span;
|
||||
@ -681,7 +680,7 @@ PushBlockScopeBCE(BytecodeEmitter *bce, StmtInfoBCE *stmt, StaticBlockObject &bl
|
||||
// Patches |breaks| and |continues| unless the top statement info record
|
||||
// represents a try-catch-finally suite. May fail if a jump offset overflows.
|
||||
static bool
|
||||
PopStatementBCE(JSContext *cx, BytecodeEmitter *bce)
|
||||
PopStatementBCE(ExclusiveContext *cx, BytecodeEmitter *bce)
|
||||
{
|
||||
StmtInfoBCE *stmt = bce->topStmt;
|
||||
if (!stmt->isTrying() &&
|
||||
@ -695,7 +694,7 @@ PopStatementBCE(JSContext *cx, BytecodeEmitter *bce)
|
||||
}
|
||||
|
||||
static bool
|
||||
EmitIndex32(JSContext *cx, JSOp op, uint32_t index, BytecodeEmitter *bce)
|
||||
EmitIndex32(ExclusiveContext *cx, JSOp op, uint32_t index, BytecodeEmitter *bce)
|
||||
{
|
||||
const size_t len = 1 + UINT32_INDEX_LEN;
|
||||
JS_ASSERT(len == size_t(js_CodeSpec[op].length));
|
||||
@ -712,7 +711,7 @@ EmitIndex32(JSContext *cx, JSOp op, uint32_t index, BytecodeEmitter *bce)
|
||||
}
|
||||
|
||||
static bool
|
||||
EmitIndexOp(JSContext *cx, JSOp op, uint32_t index, BytecodeEmitter *bce)
|
||||
EmitIndexOp(ExclusiveContext *cx, JSOp op, uint32_t index, BytecodeEmitter *bce)
|
||||
{
|
||||
const size_t len = js_CodeSpec[op].length;
|
||||
JS_ASSERT(len >= 1 + UINT32_INDEX_LEN);
|
||||
@ -729,7 +728,7 @@ EmitIndexOp(JSContext *cx, JSOp op, uint32_t index, BytecodeEmitter *bce)
|
||||
}
|
||||
|
||||
static bool
|
||||
EmitAtomOp(JSContext *cx, JSAtom *atom, JSOp op, BytecodeEmitter *bce)
|
||||
EmitAtomOp(ExclusiveContext *cx, JSAtom *atom, JSOp op, BytecodeEmitter *bce)
|
||||
{
|
||||
JS_ASSERT(JOF_OPTYPE(op) == JOF_ATOM);
|
||||
|
||||
@ -746,21 +745,21 @@ EmitAtomOp(JSContext *cx, JSAtom *atom, JSOp op, BytecodeEmitter *bce)
|
||||
}
|
||||
|
||||
static bool
|
||||
EmitAtomOp(JSContext *cx, ParseNode *pn, JSOp op, BytecodeEmitter *bce)
|
||||
EmitAtomOp(ExclusiveContext *cx, ParseNode *pn, JSOp op, BytecodeEmitter *bce)
|
||||
{
|
||||
JS_ASSERT(pn->pn_atom != NULL);
|
||||
return EmitAtomOp(cx, pn->pn_atom, op, bce);
|
||||
}
|
||||
|
||||
static bool
|
||||
EmitObjectOp(JSContext *cx, ObjectBox *objbox, JSOp op, BytecodeEmitter *bce)
|
||||
EmitObjectOp(ExclusiveContext *cx, ObjectBox *objbox, JSOp op, BytecodeEmitter *bce)
|
||||
{
|
||||
JS_ASSERT(JOF_OPTYPE(op) == JOF_OBJECT);
|
||||
return EmitIndex32(cx, op, bce->objectList.add(objbox), bce);
|
||||
}
|
||||
|
||||
static bool
|
||||
EmitRegExp(JSContext *cx, uint32_t index, BytecodeEmitter *bce)
|
||||
EmitRegExp(ExclusiveContext *cx, uint32_t index, BytecodeEmitter *bce)
|
||||
{
|
||||
return EmitIndex32(cx, JSOP_REGEXP, index, bce);
|
||||
}
|
||||
@ -773,7 +772,7 @@ EmitRegExp(JSContext *cx, uint32_t index, BytecodeEmitter *bce)
|
||||
* used as a non-asserting version of EMIT_UINT16_IMM_OP.
|
||||
*/
|
||||
static bool
|
||||
EmitUnaliasedVarOp(JSContext *cx, JSOp op, uint16_t slot, BytecodeEmitter *bce)
|
||||
EmitUnaliasedVarOp(ExclusiveContext *cx, JSOp op, uint16_t slot, BytecodeEmitter *bce)
|
||||
{
|
||||
JS_ASSERT(JOF_OPTYPE(op) != JOF_SCOPECOORD);
|
||||
ptrdiff_t off = EmitN(cx, bce, op, sizeof(uint16_t));
|
||||
@ -784,7 +783,7 @@ EmitUnaliasedVarOp(JSContext *cx, JSOp op, uint16_t slot, BytecodeEmitter *bce)
|
||||
}
|
||||
|
||||
static bool
|
||||
EmitAliasedVarOp(JSContext *cx, JSOp op, ScopeCoordinate sc, BytecodeEmitter *bce)
|
||||
EmitAliasedVarOp(ExclusiveContext *cx, JSOp op, ScopeCoordinate sc, BytecodeEmitter *bce)
|
||||
{
|
||||
JS_ASSERT(JOF_OPTYPE(op) == JOF_SCOPECOORD);
|
||||
|
||||
@ -842,7 +841,7 @@ LookupAliasedName(HandleScript script, PropertyName *name, uint16_t *pslot)
|
||||
}
|
||||
|
||||
static bool
|
||||
EmitAliasedVarOp(JSContext *cx, JSOp op, ParseNode *pn, BytecodeEmitter *bce)
|
||||
EmitAliasedVarOp(ExclusiveContext *cx, JSOp op, ParseNode *pn, BytecodeEmitter *bce)
|
||||
{
|
||||
unsigned skippedScopes = 0;
|
||||
BytecodeEmitter *bceOfDef = bce;
|
||||
@ -894,7 +893,7 @@ EmitAliasedVarOp(JSContext *cx, JSOp op, ParseNode *pn, BytecodeEmitter *bce)
|
||||
}
|
||||
|
||||
static bool
|
||||
EmitVarOp(JSContext *cx, ParseNode *pn, JSOp op, BytecodeEmitter *bce)
|
||||
EmitVarOp(ExclusiveContext *cx, ParseNode *pn, JSOp op, BytecodeEmitter *bce)
|
||||
{
|
||||
JS_ASSERT(pn->isKind(PNK_FUNCTION) || pn->isKind(PNK_NAME));
|
||||
JS_ASSERT(!pn->pn_cookie.isFree());
|
||||
@ -935,7 +934,7 @@ GetIncDecInfo(ParseNodeKind kind, bool *post)
|
||||
}
|
||||
|
||||
static bool
|
||||
EmitVarIncDec(JSContext *cx, ParseNode *pn, BytecodeEmitter *bce)
|
||||
EmitVarIncDec(ExclusiveContext *cx, ParseNode *pn, BytecodeEmitter *bce)
|
||||
{
|
||||
JSOp op = pn->pn_kid->getOp();
|
||||
JS_ASSERT(IsArgOp(op) || IsLocalOp(op) || IsAliasedVarOp(op));
|
||||
@ -1027,7 +1026,7 @@ BytecodeEmitter::isAliasedName(ParseNode *pn)
|
||||
* The function returns -1 on failures.
|
||||
*/
|
||||
static int
|
||||
AdjustBlockSlot(JSContext *cx, BytecodeEmitter *bce, int slot)
|
||||
AdjustBlockSlot(ExclusiveContext *cx, BytecodeEmitter *bce, int slot)
|
||||
{
|
||||
JS_ASSERT((unsigned) slot < bce->maxStackDepth);
|
||||
if (bce->sc->isFunctionBox()) {
|
||||
@ -1041,7 +1040,7 @@ AdjustBlockSlot(JSContext *cx, BytecodeEmitter *bce, int slot)
|
||||
}
|
||||
|
||||
static bool
|
||||
EmitEnterBlock(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn, JSOp op)
|
||||
EmitEnterBlock(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn, JSOp op)
|
||||
{
|
||||
JS_ASSERT(pn->isKind(PNK_LEXICALSCOPE));
|
||||
if (!EmitObjectOp(cx, pn->pn_objbox, op, bce))
|
||||
@ -1070,7 +1069,7 @@ EmitEnterBlock(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn, JSOp op)
|
||||
|
||||
JS_ASSERT(dn->isDefn());
|
||||
JS_ASSERT(unsigned(dn->frameSlot() + depthPlusFixed) < JS_BIT(16));
|
||||
if (!dn->pn_cookie.set(cx, dn->pn_cookie.level(),
|
||||
if (!dn->pn_cookie.set(bce->parser->tokenStream, dn->pn_cookie.level(),
|
||||
uint16_t(dn->frameSlot() + depthPlusFixed)))
|
||||
return false;
|
||||
|
||||
@ -1168,7 +1167,7 @@ TryConvertFreeName(BytecodeEmitter *bce, ParseNode *pn)
|
||||
default: return false;
|
||||
}
|
||||
pn->setOp(op);
|
||||
JS_ALWAYS_TRUE(pn->pn_cookie.set(bce->sc->context, hops, slot));
|
||||
JS_ALWAYS_TRUE(pn->pn_cookie.set(bce->parser->tokenStream, hops, slot));
|
||||
return true;
|
||||
}
|
||||
hops++;
|
||||
@ -1241,7 +1240,7 @@ TryConvertFreeName(BytecodeEmitter *bce, ParseNode *pn)
|
||||
* op=, e.g. +=).
|
||||
*/
|
||||
static bool
|
||||
BindNameToSlotHelper(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
BindNameToSlotHelper(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
{
|
||||
JS_ASSERT(pn->isKind(PNK_NAME));
|
||||
|
||||
@ -1289,7 +1288,7 @@ BindNameToSlotHelper(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
if (pn->isConst()) {
|
||||
if (bce->sc->needStrictChecks()) {
|
||||
JSAutoByteString name;
|
||||
if (!js_AtomToPrintableString(cx, pn->pn_atom, &name) ||
|
||||
if (!AtomToPrintableString(cx, pn->pn_atom, &name) ||
|
||||
!bce->reportStrictModeError(pn, JSMSG_READ_ONLY, name.ptr()))
|
||||
{
|
||||
return false;
|
||||
@ -1462,7 +1461,7 @@ BindNameToSlotHelper(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
|
||||
JS_ASSERT(!pn->isOp(op));
|
||||
pn->setOp(op);
|
||||
if (!pn->pn_cookie.set(bce->sc->context, skip, dn->pn_cookie.slot()))
|
||||
if (!pn->pn_cookie.set(bce->parser->tokenStream, skip, dn->pn_cookie.slot()))
|
||||
return false;
|
||||
|
||||
pn->pn_dflags |= PND_BOUND;
|
||||
@ -1475,7 +1474,7 @@ BindNameToSlotHelper(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
* and we do not want to allow self-hosted code to use the dynamic scope.
|
||||
*/
|
||||
static bool
|
||||
BindNameToSlot(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
BindNameToSlot(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
{
|
||||
if (!BindNameToSlotHelper(cx, bce, pn))
|
||||
return false;
|
||||
@ -1501,7 +1500,7 @@ BindNameToSlot(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
* pop bytecode.
|
||||
*/
|
||||
static bool
|
||||
CheckSideEffects(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn, bool *answer)
|
||||
CheckSideEffects(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn, bool *answer)
|
||||
{
|
||||
if (!pn || *answer)
|
||||
return true;
|
||||
@ -1729,15 +1728,20 @@ BytecodeEmitter::needsImplicitThis()
|
||||
}
|
||||
|
||||
void
|
||||
BytecodeEmitter::tellDebuggerAboutCompiledScript(JSContext *cx)
|
||||
BytecodeEmitter::tellDebuggerAboutCompiledScript(ExclusiveContext *cx)
|
||||
{
|
||||
// Note: when parsing off thread the resulting scripts need to be handed to
|
||||
// the debugger after rejoining to the main thread.
|
||||
if (!cx->isJSContext())
|
||||
return;
|
||||
|
||||
RootedFunction function(cx, script->function());
|
||||
CallNewScriptHook(cx, script, function);
|
||||
CallNewScriptHook(cx->asJSContext(), script, function);
|
||||
if (!parent) {
|
||||
GlobalObject *compileAndGoGlobal = NULL;
|
||||
if (script->compileAndGo)
|
||||
compileAndGoGlobal = &script->global();
|
||||
Debugger::onNewScript(cx, script, compileAndGoGlobal);
|
||||
Debugger::onNewScript(cx->asJSContext(), script, compileAndGoGlobal);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1786,7 +1790,7 @@ BytecodeEmitter::reportStrictModeError(ParseNode *pn, unsigned errorNumber, ...)
|
||||
}
|
||||
|
||||
static bool
|
||||
EmitNameOp(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn, bool callContext)
|
||||
EmitNameOp(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn, bool callContext)
|
||||
{
|
||||
JSOp op;
|
||||
|
||||
@ -1851,7 +1855,7 @@ EmitNameOp(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn, bool callContext)
|
||||
}
|
||||
|
||||
static inline bool
|
||||
EmitElemOpBase(JSContext *cx, BytecodeEmitter *bce, JSOp op)
|
||||
EmitElemOpBase(ExclusiveContext *cx, BytecodeEmitter *bce, JSOp op)
|
||||
{
|
||||
if (Emit1(cx, bce, op) < 0)
|
||||
return false;
|
||||
@ -1867,7 +1871,7 @@ EmitElemOpBase(JSContext *cx, BytecodeEmitter *bce, JSOp op)
|
||||
}
|
||||
|
||||
static bool
|
||||
EmitPropLHS(JSContext *cx, ParseNode *pn, JSOp op, BytecodeEmitter *bce)
|
||||
EmitPropLHS(ExclusiveContext *cx, ParseNode *pn, JSOp op, BytecodeEmitter *bce)
|
||||
{
|
||||
JS_ASSERT(pn->isKind(PNK_DOT));
|
||||
ParseNode *pn2 = pn->maybeExpr();
|
||||
@ -1915,7 +1919,7 @@ EmitPropLHS(JSContext *cx, ParseNode *pn, JSOp op, BytecodeEmitter *bce)
|
||||
}
|
||||
|
||||
static bool
|
||||
EmitPropOp(JSContext *cx, ParseNode *pn, JSOp op, BytecodeEmitter *bce)
|
||||
EmitPropOp(ExclusiveContext *cx, ParseNode *pn, JSOp op, BytecodeEmitter *bce)
|
||||
{
|
||||
JS_ASSERT(pn->isArity(PN_NAME));
|
||||
|
||||
@ -1938,7 +1942,7 @@ EmitPropOp(JSContext *cx, ParseNode *pn, JSOp op, BytecodeEmitter *bce)
|
||||
}
|
||||
|
||||
static bool
|
||||
EmitPropIncDec(JSContext *cx, ParseNode *pn, BytecodeEmitter *bce)
|
||||
EmitPropIncDec(ExclusiveContext *cx, ParseNode *pn, BytecodeEmitter *bce)
|
||||
{
|
||||
JS_ASSERT(pn->pn_kid->getKind() == PNK_DOT);
|
||||
|
||||
@ -1977,7 +1981,7 @@ EmitPropIncDec(JSContext *cx, ParseNode *pn, BytecodeEmitter *bce)
|
||||
}
|
||||
|
||||
static bool
|
||||
EmitNameIncDec(JSContext *cx, ParseNode *pn, BytecodeEmitter *bce)
|
||||
EmitNameIncDec(ExclusiveContext *cx, ParseNode *pn, BytecodeEmitter *bce)
|
||||
{
|
||||
const JSCodeSpec *cs = &js_CodeSpec[pn->pn_kid->getOp()];
|
||||
|
||||
@ -2014,7 +2018,7 @@ EmitNameIncDec(JSContext *cx, ParseNode *pn, BytecodeEmitter *bce)
|
||||
}
|
||||
|
||||
static bool
|
||||
EmitElemOperands(JSContext *cx, ParseNode *pn, JSOp op, BytecodeEmitter *bce)
|
||||
EmitElemOperands(ExclusiveContext *cx, ParseNode *pn, JSOp op, BytecodeEmitter *bce)
|
||||
{
|
||||
ParseNode *left, *right;
|
||||
|
||||
@ -2061,13 +2065,13 @@ EmitElemOperands(JSContext *cx, ParseNode *pn, JSOp op, BytecodeEmitter *bce)
|
||||
}
|
||||
|
||||
static bool
|
||||
EmitElemOp(JSContext *cx, ParseNode *pn, JSOp op, BytecodeEmitter *bce)
|
||||
EmitElemOp(ExclusiveContext *cx, ParseNode *pn, JSOp op, BytecodeEmitter *bce)
|
||||
{
|
||||
return EmitElemOperands(cx, pn, op, bce) && EmitElemOpBase(cx, bce, op);
|
||||
}
|
||||
|
||||
static bool
|
||||
EmitElemIncDec(JSContext *cx, ParseNode *pn, BytecodeEmitter *bce)
|
||||
EmitElemIncDec(ExclusiveContext *cx, ParseNode *pn, BytecodeEmitter *bce)
|
||||
{
|
||||
JS_ASSERT(pn->pn_kid->getKind() == PNK_ELEM);
|
||||
|
||||
@ -2115,7 +2119,7 @@ EmitElemIncDec(JSContext *cx, ParseNode *pn, BytecodeEmitter *bce)
|
||||
}
|
||||
|
||||
static bool
|
||||
EmitNumberOp(JSContext *cx, double dval, BytecodeEmitter *bce)
|
||||
EmitNumberOp(ExclusiveContext *cx, double dval, BytecodeEmitter *bce)
|
||||
{
|
||||
int32_t ival;
|
||||
uint32_t u;
|
||||
@ -2167,7 +2171,7 @@ SetJumpOffsetAt(BytecodeEmitter *bce, ptrdiff_t off)
|
||||
* into EmitTree which is recursive and uses relatively little stack space.
|
||||
*/
|
||||
MOZ_NEVER_INLINE static bool
|
||||
EmitSwitch(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
EmitSwitch(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
{
|
||||
JSOp switchOp;
|
||||
bool hasDefault;
|
||||
@ -2237,8 +2241,7 @@ EmitSwitch(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
ScopedJSFreePtr<ParseNode*> table(NULL);
|
||||
|
||||
if (caseCount > JS_BIT(16)) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_TOO_MANY_CASES);
|
||||
bce->parser->tokenStream.reportError(JSMSG_TOO_MANY_CASES);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -2310,7 +2313,7 @@ EmitSwitch(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
intmap_bitlen = JS_BIT(16);
|
||||
intmap = cx->pod_malloc<jsbitmap>(JS_BIT(16) >> JS_BITS_PER_WORD_LOG2);
|
||||
if (!intmap) {
|
||||
JS_ReportOutOfMemory(cx);
|
||||
js_ReportOutOfMemory(cx);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -2516,7 +2519,7 @@ EmitSwitch(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
}
|
||||
|
||||
bool
|
||||
frontend::EmitFunctionScript(JSContext *cx, BytecodeEmitter *bce, ParseNode *body)
|
||||
frontend::EmitFunctionScript(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *body)
|
||||
{
|
||||
/*
|
||||
* The decompiler has assumptions about what may occur immediately after
|
||||
@ -2604,7 +2607,7 @@ frontend::EmitFunctionScript(JSContext *cx, BytecodeEmitter *bce, ParseNode *bod
|
||||
}
|
||||
|
||||
static bool
|
||||
MaybeEmitVarDecl(JSContext *cx, BytecodeEmitter *bce, JSOp prologOp, ParseNode *pn,
|
||||
MaybeEmitVarDecl(ExclusiveContext *cx, BytecodeEmitter *bce, JSOp prologOp, ParseNode *pn,
|
||||
jsatomid *result)
|
||||
{
|
||||
jsatomid atomIndex;
|
||||
@ -2650,10 +2653,10 @@ enum VarEmitOption
|
||||
#if JS_HAS_DESTRUCTURING
|
||||
|
||||
typedef bool
|
||||
(*DestructuringDeclEmitter)(JSContext *cx, BytecodeEmitter *bce, JSOp prologOp, ParseNode *pn);
|
||||
(*DestructuringDeclEmitter)(ExclusiveContext *cx, BytecodeEmitter *bce, JSOp prologOp, ParseNode *pn);
|
||||
|
||||
static bool
|
||||
EmitDestructuringDecl(JSContext *cx, BytecodeEmitter *bce, JSOp prologOp, ParseNode *pn)
|
||||
EmitDestructuringDecl(ExclusiveContext *cx, BytecodeEmitter *bce, JSOp prologOp, ParseNode *pn)
|
||||
{
|
||||
JS_ASSERT(pn->isKind(PNK_NAME));
|
||||
if (!BindNameToSlot(cx, bce, pn))
|
||||
@ -2664,7 +2667,7 @@ EmitDestructuringDecl(JSContext *cx, BytecodeEmitter *bce, JSOp prologOp, ParseN
|
||||
}
|
||||
|
||||
static bool
|
||||
EmitDestructuringDecls(JSContext *cx, BytecodeEmitter *bce, JSOp prologOp, ParseNode *pn)
|
||||
EmitDestructuringDecls(ExclusiveContext *cx, BytecodeEmitter *bce, JSOp prologOp, ParseNode *pn)
|
||||
{
|
||||
ParseNode *pn2, *pn3;
|
||||
DestructuringDeclEmitter emitter;
|
||||
@ -2692,7 +2695,7 @@ EmitDestructuringDecls(JSContext *cx, BytecodeEmitter *bce, JSOp prologOp, Parse
|
||||
}
|
||||
|
||||
static bool
|
||||
EmitDestructuringOpsHelper(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn,
|
||||
EmitDestructuringOpsHelper(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn,
|
||||
VarEmitOption emitOption);
|
||||
|
||||
/*
|
||||
@ -2708,7 +2711,7 @@ EmitDestructuringOpsHelper(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn,
|
||||
* lhs expression. (Same post-condition as EmitDestructuringOpsHelper)
|
||||
*/
|
||||
static bool
|
||||
EmitDestructuringLHS(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn, VarEmitOption emitOption)
|
||||
EmitDestructuringLHS(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn, VarEmitOption emitOption)
|
||||
{
|
||||
JS_ASSERT(emitOption != DefineVars);
|
||||
|
||||
@ -2825,7 +2828,7 @@ EmitDestructuringLHS(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn, VarEmit
|
||||
* lhs expression. (Same post-condition as EmitDestructuringLHS)
|
||||
*/
|
||||
static bool
|
||||
EmitDestructuringOpsHelper(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn,
|
||||
EmitDestructuringOpsHelper(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn,
|
||||
VarEmitOption emitOption)
|
||||
{
|
||||
JS_ASSERT(emitOption != DefineVars);
|
||||
@ -2942,7 +2945,7 @@ EmitDestructuringOpsHelper(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn,
|
||||
}
|
||||
|
||||
static bool
|
||||
EmitDestructuringOps(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn, bool isLet = false)
|
||||
EmitDestructuringOps(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn, bool isLet = false)
|
||||
{
|
||||
/*
|
||||
* Call our recursive helper to emit the destructuring assignments and
|
||||
@ -2953,7 +2956,7 @@ EmitDestructuringOps(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn, bool is
|
||||
}
|
||||
|
||||
static bool
|
||||
EmitGroupAssignment(JSContext *cx, BytecodeEmitter *bce, JSOp prologOp,
|
||||
EmitGroupAssignment(ExclusiveContext *cx, BytecodeEmitter *bce, JSOp prologOp,
|
||||
ParseNode *lhs, ParseNode *rhs)
|
||||
{
|
||||
unsigned depth, limit, i, nslots;
|
||||
@ -3007,7 +3010,7 @@ enum GroupOption { GroupIsDecl, GroupIsNotDecl };
|
||||
* we set *pop to JSOP_NOP so callers can veto emitting pn followed by a pop.
|
||||
*/
|
||||
static bool
|
||||
MaybeEmitGroupAssignment(JSContext *cx, BytecodeEmitter *bce, JSOp prologOp, ParseNode *pn,
|
||||
MaybeEmitGroupAssignment(ExclusiveContext *cx, BytecodeEmitter *bce, JSOp prologOp, ParseNode *pn,
|
||||
GroupOption groupOption, JSOp *pop)
|
||||
{
|
||||
JS_ASSERT(pn->isKind(PNK_ASSIGN));
|
||||
@ -3040,7 +3043,7 @@ MaybeEmitGroupAssignment(JSContext *cx, BytecodeEmitter *bce, JSOp prologOp, Par
|
||||
* 1:1 correspondence and lhs elements are simple names.
|
||||
*/
|
||||
static bool
|
||||
MaybeEmitLetGroupDecl(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn, JSOp *pop)
|
||||
MaybeEmitLetGroupDecl(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn, JSOp *pop)
|
||||
{
|
||||
JS_ASSERT(pn->isKind(PNK_ASSIGN));
|
||||
JS_ASSERT(pn->isOp(JSOP_NOP));
|
||||
@ -3071,7 +3074,7 @@ MaybeEmitLetGroupDecl(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn, JSOp *
|
||||
#endif /* JS_HAS_DESTRUCTURING */
|
||||
|
||||
static bool
|
||||
EmitVariables(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn, VarEmitOption emitOption,
|
||||
EmitVariables(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn, VarEmitOption emitOption,
|
||||
bool isLet = false)
|
||||
{
|
||||
JS_ASSERT(pn->isArity(PN_LIST));
|
||||
@ -3260,7 +3263,7 @@ EmitVariables(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn, VarEmitOption
|
||||
}
|
||||
|
||||
static bool
|
||||
EmitAssignment(JSContext *cx, BytecodeEmitter *bce, ParseNode *lhs, JSOp op, ParseNode *rhs)
|
||||
EmitAssignment(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *lhs, JSOp op, ParseNode *rhs)
|
||||
{
|
||||
/*
|
||||
* Check left operand type and generate specialized code for it.
|
||||
@ -3465,7 +3468,7 @@ EmitAssignment(JSContext *cx, BytecodeEmitter *bce, ParseNode *lhs, JSOp op, Par
|
||||
}
|
||||
|
||||
static bool
|
||||
EmitNewInit(JSContext *cx, BytecodeEmitter *bce, JSProtoKey key, ParseNode *pn)
|
||||
EmitNewInit(ExclusiveContext *cx, BytecodeEmitter *bce, JSProtoKey key, ParseNode *pn)
|
||||
{
|
||||
const size_t len = 1 + UINT32_INDEX_LEN;
|
||||
ptrdiff_t offset = EmitCheck(cx, bce, len);
|
||||
@ -3484,7 +3487,7 @@ EmitNewInit(JSContext *cx, BytecodeEmitter *bce, JSProtoKey key, ParseNode *pn)
|
||||
}
|
||||
|
||||
bool
|
||||
ParseNode::getConstantValue(JSContext *cx, bool strictChecks, MutableHandleValue vp)
|
||||
ParseNode::getConstantValue(ExclusiveContext *cx, bool strictChecks, MutableHandleValue vp)
|
||||
{
|
||||
switch (getKind()) {
|
||||
case PNK_NUMBER:
|
||||
@ -3587,7 +3590,7 @@ ParseNode::getConstantValue(JSContext *cx, bool strictChecks, MutableHandleValue
|
||||
}
|
||||
|
||||
static bool
|
||||
EmitSingletonInitialiser(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
EmitSingletonInitialiser(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
{
|
||||
RootedValue value(cx);
|
||||
if (!pn->getConstantValue(cx, bce->sc->needStrictChecks(), &value))
|
||||
@ -3614,7 +3617,7 @@ class EmitLevelManager
|
||||
};
|
||||
|
||||
static bool
|
||||
EmitCatch(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
EmitCatch(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
{
|
||||
ptrdiff_t guardJump;
|
||||
|
||||
@ -3698,7 +3701,7 @@ EmitCatch(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
* the comment on EmitSwitch.
|
||||
*/
|
||||
MOZ_NEVER_INLINE static bool
|
||||
EmitTry(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
EmitTry(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
{
|
||||
StmtInfoBCE stmtInfo(cx);
|
||||
ptrdiff_t catchJump = -1;
|
||||
@ -3919,7 +3922,7 @@ EmitTry(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
}
|
||||
|
||||
static bool
|
||||
EmitIf(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
EmitIf(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
{
|
||||
StmtInfoBCE stmtInfo(cx);
|
||||
|
||||
@ -4033,7 +4036,7 @@ EmitIf(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
* the comment on EmitSwitch.
|
||||
*/
|
||||
MOZ_NEVER_INLINE static bool
|
||||
EmitLet(JSContext *cx, BytecodeEmitter *bce, ParseNode *pnLet)
|
||||
EmitLet(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pnLet)
|
||||
{
|
||||
JS_ASSERT(pnLet->isArity(PN_BINARY));
|
||||
ParseNode *varList = pnLet->pn_left;
|
||||
@ -4081,7 +4084,7 @@ EmitLet(JSContext *cx, BytecodeEmitter *bce, ParseNode *pnLet)
|
||||
* the comment on EmitSwitch.
|
||||
*/
|
||||
MOZ_NEVER_INLINE static bool
|
||||
EmitLexicalScope(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
EmitLexicalScope(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
{
|
||||
JS_ASSERT(pn->isKind(PNK_LEXICALSCOPE));
|
||||
JS_ASSERT(pn->getOp() == JSOP_LEAVEBLOCK);
|
||||
@ -4104,7 +4107,7 @@ EmitLexicalScope(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
}
|
||||
|
||||
static bool
|
||||
EmitWith(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
EmitWith(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
{
|
||||
StmtInfoBCE stmtInfo(cx);
|
||||
if (!EmitTree(cx, bce, pn->pn_left))
|
||||
@ -4121,7 +4124,7 @@ EmitWith(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
}
|
||||
|
||||
static bool
|
||||
EmitForIn(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn, ptrdiff_t top)
|
||||
EmitForIn(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn, ptrdiff_t top)
|
||||
{
|
||||
StmtInfoBCE stmtInfo(cx);
|
||||
PushStatementBCE(bce, &stmtInfo, STMT_FOR_IN_LOOP, top);
|
||||
@ -4286,7 +4289,7 @@ EmitForIn(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn, ptrdiff_t top)
|
||||
}
|
||||
|
||||
static bool
|
||||
EmitNormalFor(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn, ptrdiff_t top)
|
||||
EmitNormalFor(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn, ptrdiff_t top)
|
||||
{
|
||||
StmtInfoBCE stmtInfo(cx);
|
||||
PushStatementBCE(bce, &stmtInfo, STMT_FOR_LOOP, top);
|
||||
@ -4437,7 +4440,7 @@ EmitNormalFor(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn, ptrdiff_t top)
|
||||
}
|
||||
|
||||
static inline bool
|
||||
EmitFor(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn, ptrdiff_t top)
|
||||
EmitFor(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn, ptrdiff_t top)
|
||||
{
|
||||
JS_ASSERT(pn->pn_left->isKind(PNK_FORIN) || pn->pn_left->isKind(PNK_FORHEAD));
|
||||
return pn->pn_left->isKind(PNK_FORIN)
|
||||
@ -4446,7 +4449,7 @@ EmitFor(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn, ptrdiff_t top)
|
||||
}
|
||||
|
||||
static JS_NEVER_INLINE bool
|
||||
EmitFunc(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
EmitFunc(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
{
|
||||
FunctionBox *funbox = pn->pn_funbox;
|
||||
RootedFunction fun(cx, funbox->function());
|
||||
@ -4477,7 +4480,8 @@ EmitFunc(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
* make a deep clone of its contents.
|
||||
*/
|
||||
bool singleton =
|
||||
cx->typeInferenceEnabled() &&
|
||||
cx->isJSContext() &&
|
||||
cx->asJSContext()->typeInferenceEnabled() &&
|
||||
bce->script->compileAndGo &&
|
||||
(bce->checkSingletonContext() ||
|
||||
(!bce->isInLoop() &&
|
||||
@ -4502,17 +4506,23 @@ EmitFunc(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
|
||||
// Inherit most things (principals, version, etc) from the parent.
|
||||
Rooted<JSScript*> parent(cx, bce->script);
|
||||
CompileOptions options(cx);
|
||||
CompileOptions options(bce->parser->options());
|
||||
options.setPrincipals(parent->principals())
|
||||
.setOriginPrincipals(parent->originPrincipals)
|
||||
.setCompileAndGo(parent->compileAndGo)
|
||||
.setSelfHostingMode(parent->selfHosted)
|
||||
.setNoScriptRval(false)
|
||||
.setForEval(false)
|
||||
.setVersion(parent->getVersion());
|
||||
|
||||
bool generateBytecode = true;
|
||||
#ifdef JS_ION
|
||||
if (funbox->useAsm) {
|
||||
if (!cx->isJSContext()) {
|
||||
bce->parser->tokenStream.reportError(JSMSG_SYNTAX_ERROR);
|
||||
return false;
|
||||
}
|
||||
|
||||
RootedFunction moduleFun(cx);
|
||||
|
||||
// In a function like this:
|
||||
@ -4523,7 +4533,7 @@ EmitFunc(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
// one past the final '}'. We need to exclude that final '}',
|
||||
// so we use |funbox->bufEnd - 1| below.
|
||||
//
|
||||
if (!CompileAsmJS(cx, *bce->tokenStream(), pn, options,
|
||||
if (!CompileAsmJS(cx->asJSContext(), *bce->tokenStream(), pn, options,
|
||||
bce->script->scriptSource(), funbox->asmStart, funbox->bufEnd - 1,
|
||||
&moduleFun))
|
||||
return false;
|
||||
@ -4612,7 +4622,7 @@ EmitFunc(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
}
|
||||
|
||||
static bool
|
||||
EmitDo(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
EmitDo(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
{
|
||||
/* Emit an annotated nop so we know to decompile a 'do' keyword. */
|
||||
ptrdiff_t noteIndex = NewSrcNote(cx, bce, SRC_WHILE);
|
||||
@ -4673,7 +4683,7 @@ EmitDo(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
}
|
||||
|
||||
static bool
|
||||
EmitWhile(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn, ptrdiff_t top)
|
||||
EmitWhile(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn, ptrdiff_t top)
|
||||
{
|
||||
/*
|
||||
* Minimize bytecodes issued for one or more iterations by jumping to
|
||||
@ -4726,7 +4736,7 @@ EmitWhile(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn, ptrdiff_t top)
|
||||
}
|
||||
|
||||
static bool
|
||||
EmitBreak(JSContext *cx, BytecodeEmitter *bce, PropertyName *label)
|
||||
EmitBreak(ExclusiveContext *cx, BytecodeEmitter *bce, PropertyName *label)
|
||||
{
|
||||
StmtInfoBCE *stmt = bce->topStmt;
|
||||
SrcNoteType noteType;
|
||||
@ -4744,7 +4754,7 @@ EmitBreak(JSContext *cx, BytecodeEmitter *bce, PropertyName *label)
|
||||
}
|
||||
|
||||
static bool
|
||||
EmitContinue(JSContext *cx, BytecodeEmitter *bce, PropertyName *label)
|
||||
EmitContinue(ExclusiveContext *cx, BytecodeEmitter *bce, PropertyName *label)
|
||||
{
|
||||
StmtInfoBCE *stmt = bce->topStmt;
|
||||
if (label) {
|
||||
@ -4765,7 +4775,7 @@ EmitContinue(JSContext *cx, BytecodeEmitter *bce, PropertyName *label)
|
||||
}
|
||||
|
||||
static bool
|
||||
EmitReturn(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
EmitReturn(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
{
|
||||
if (!UpdateSourceCoordNotes(cx, bce, pn->pn_pos.begin))
|
||||
return false;
|
||||
@ -4807,7 +4817,7 @@ EmitReturn(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
}
|
||||
|
||||
static bool
|
||||
EmitStatementList(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn, ptrdiff_t top)
|
||||
EmitStatementList(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn, ptrdiff_t top)
|
||||
{
|
||||
JS_ASSERT(pn->isArity(PN_LIST));
|
||||
|
||||
@ -4828,7 +4838,7 @@ EmitStatementList(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn, ptrdiff_t
|
||||
}
|
||||
|
||||
static bool
|
||||
EmitStatement(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
EmitStatement(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
{
|
||||
JS_ASSERT(pn->isKind(PNK_SEMI));
|
||||
|
||||
@ -4904,7 +4914,7 @@ EmitStatement(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
}
|
||||
|
||||
static bool
|
||||
EmitDelete(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
EmitDelete(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
{
|
||||
/*
|
||||
* Under ECMA 3, deleting a non-reference returns true -- but alas we
|
||||
@ -4961,7 +4971,7 @@ EmitDelete(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
}
|
||||
|
||||
static bool
|
||||
EmitCallOrNew(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
EmitCallOrNew(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
{
|
||||
bool callop = pn->isKind(PNK_CALL);
|
||||
|
||||
@ -4983,8 +4993,9 @@ EmitCallOrNew(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
uint32_t argc = pn->pn_count - 1;
|
||||
|
||||
if (argc >= ARGC_LIMIT) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
callop ? JSMSG_TOO_MANY_FUN_ARGS : JSMSG_TOO_MANY_CON_ARGS);
|
||||
bce->parser->tokenStream.reportError(callop
|
||||
? JSMSG_TOO_MANY_FUN_ARGS
|
||||
: JSMSG_TOO_MANY_CON_ARGS);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -5111,7 +5122,7 @@ EmitCallOrNew(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
}
|
||||
|
||||
static bool
|
||||
EmitLogical(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
EmitLogical(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
{
|
||||
/*
|
||||
* JSOP_OR converts the operand on the stack to boolean, leaves the original
|
||||
@ -5187,7 +5198,7 @@ EmitLogical(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
* the comment on EmitSwitch.
|
||||
*/
|
||||
MOZ_NEVER_INLINE static bool
|
||||
EmitIncOrDec(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
EmitIncOrDec(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
{
|
||||
/* Emit lvalue-specialized code for ++/-- operators. */
|
||||
ParseNode *pn2 = pn->pn_kid;
|
||||
@ -5266,7 +5277,7 @@ EmitIncOrDec(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
* the comment on EmitSwitch.
|
||||
*/
|
||||
MOZ_NEVER_INLINE static bool
|
||||
EmitLabeledStatement(JSContext *cx, BytecodeEmitter *bce, const LabeledStatement *pn)
|
||||
EmitLabeledStatement(ExclusiveContext *cx, BytecodeEmitter *bce, const LabeledStatement *pn)
|
||||
{
|
||||
/*
|
||||
* Emit a JSOP_LABEL instruction. The argument is the offset to the statement
|
||||
@ -5295,7 +5306,7 @@ EmitLabeledStatement(JSContext *cx, BytecodeEmitter *bce, const LabeledStatement
|
||||
}
|
||||
|
||||
static bool
|
||||
EmitSyntheticStatements(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn, ptrdiff_t top)
|
||||
EmitSyntheticStatements(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn, ptrdiff_t top)
|
||||
{
|
||||
JS_ASSERT(pn->isArity(PN_LIST));
|
||||
StmtInfoBCE stmtInfo(cx);
|
||||
@ -5311,7 +5322,7 @@ EmitSyntheticStatements(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn, ptrd
|
||||
}
|
||||
|
||||
static bool
|
||||
EmitConditionalExpression(JSContext *cx, BytecodeEmitter *bce, ConditionalExpression &conditional)
|
||||
EmitConditionalExpression(ExclusiveContext *cx, BytecodeEmitter *bce, ConditionalExpression &conditional)
|
||||
{
|
||||
/* Emit the condition, then branch if false to the else part. */
|
||||
if (!EmitTree(cx, bce, &conditional.condition()))
|
||||
@ -5352,7 +5363,7 @@ EmitConditionalExpression(JSContext *cx, BytecodeEmitter *bce, ConditionalExpres
|
||||
* the comment on EmitSwitch.
|
||||
*/
|
||||
MOZ_NEVER_INLINE static bool
|
||||
EmitObject(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
EmitObject(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
{
|
||||
#if JS_HAS_DESTRUCTURING_SHORTHAND
|
||||
if (pn->pn_xflags & PNX_DESTRUCT) {
|
||||
@ -5470,7 +5481,7 @@ EmitObject(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
}
|
||||
|
||||
static bool
|
||||
EmitArray(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
EmitArray(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
{
|
||||
/*
|
||||
* Emit code for [a, b, c] that is equivalent to constructing a new
|
||||
@ -5557,7 +5568,7 @@ EmitArray(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
}
|
||||
|
||||
static bool
|
||||
EmitUnary(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
EmitUnary(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
{
|
||||
if (!UpdateSourceCoordNotes(cx, bce, pn->pn_pos.begin))
|
||||
return false;
|
||||
@ -5578,7 +5589,7 @@ EmitUnary(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
}
|
||||
|
||||
static bool
|
||||
EmitDefaults(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
EmitDefaults(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
{
|
||||
JS_ASSERT(pn->isKind(PNK_ARGSBODY));
|
||||
|
||||
@ -5613,7 +5624,7 @@ EmitDefaults(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
}
|
||||
|
||||
bool
|
||||
frontend::EmitTree(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
frontend::EmitTree(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
{
|
||||
JS_CHECK_RECURSION(cx, return false);
|
||||
|
||||
@ -6027,7 +6038,7 @@ frontend::EmitTree(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
}
|
||||
|
||||
static int
|
||||
AllocSrcNote(JSContext *cx, SrcNotesVector ¬es)
|
||||
AllocSrcNote(ExclusiveContext *cx, SrcNotesVector ¬es)
|
||||
{
|
||||
// Start it off moderately large to avoid repeated resizings early on.
|
||||
if (notes.capacity() == 0 && !notes.reserve(1024))
|
||||
@ -6042,7 +6053,7 @@ AllocSrcNote(JSContext *cx, SrcNotesVector ¬es)
|
||||
}
|
||||
|
||||
int
|
||||
frontend::NewSrcNote(JSContext *cx, BytecodeEmitter *bce, SrcNoteType type)
|
||||
frontend::NewSrcNote(ExclusiveContext *cx, BytecodeEmitter *bce, SrcNoteType type)
|
||||
{
|
||||
SrcNotesVector ¬es = bce->notes();
|
||||
int index;
|
||||
@ -6083,7 +6094,7 @@ frontend::NewSrcNote(JSContext *cx, BytecodeEmitter *bce, SrcNoteType type)
|
||||
}
|
||||
|
||||
int
|
||||
frontend::NewSrcNote2(JSContext *cx, BytecodeEmitter *bce, SrcNoteType type, ptrdiff_t offset)
|
||||
frontend::NewSrcNote2(ExclusiveContext *cx, BytecodeEmitter *bce, SrcNoteType type, ptrdiff_t offset)
|
||||
{
|
||||
int index;
|
||||
|
||||
@ -6096,7 +6107,7 @@ frontend::NewSrcNote2(JSContext *cx, BytecodeEmitter *bce, SrcNoteType type, ptr
|
||||
}
|
||||
|
||||
int
|
||||
frontend::NewSrcNote3(JSContext *cx, BytecodeEmitter *bce, SrcNoteType type, ptrdiff_t offset1,
|
||||
frontend::NewSrcNote3(ExclusiveContext *cx, BytecodeEmitter *bce, SrcNoteType type, ptrdiff_t offset1,
|
||||
ptrdiff_t offset2)
|
||||
{
|
||||
int index;
|
||||
@ -6112,7 +6123,7 @@ frontend::NewSrcNote3(JSContext *cx, BytecodeEmitter *bce, SrcNoteType type, ptr
|
||||
}
|
||||
|
||||
bool
|
||||
frontend::AddToSrcNoteDelta(JSContext *cx, BytecodeEmitter *bce, jssrcnote *sn, ptrdiff_t delta)
|
||||
frontend::AddToSrcNoteDelta(ExclusiveContext *cx, BytecodeEmitter *bce, jssrcnote *sn, ptrdiff_t delta)
|
||||
{
|
||||
/*
|
||||
* Called only from FinishTakingSrcNotes to add to main script note
|
||||
@ -6136,11 +6147,11 @@ frontend::AddToSrcNoteDelta(JSContext *cx, BytecodeEmitter *bce, jssrcnote *sn,
|
||||
}
|
||||
|
||||
static bool
|
||||
SetSrcNoteOffset(JSContext *cx, BytecodeEmitter *bce, unsigned index, unsigned which,
|
||||
SetSrcNoteOffset(ExclusiveContext *cx, BytecodeEmitter *bce, unsigned index, unsigned which,
|
||||
ptrdiff_t offset)
|
||||
{
|
||||
if (size_t(offset) > SN_MAX_OFFSET) {
|
||||
ReportStatementTooLarge(cx, bce->topStmt);
|
||||
ReportStatementTooLarge(bce->parser->tokenStream, bce->topStmt);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -6218,7 +6229,7 @@ DumpSrcNoteSizeHist()
|
||||
* CORRESPONDING CHANGES!
|
||||
*/
|
||||
bool
|
||||
frontend::FinishTakingSrcNotes(JSContext *cx, BytecodeEmitter *bce, jssrcnote *notes)
|
||||
frontend::FinishTakingSrcNotes(ExclusiveContext *cx, BytecodeEmitter *bce, jssrcnote *notes)
|
||||
{
|
||||
JS_ASSERT(bce->current == &bce->main);
|
||||
|
||||
|
@ -26,7 +26,7 @@ namespace frontend {
|
||||
|
||||
struct CGTryNoteList {
|
||||
Vector<JSTryNote> list;
|
||||
CGTryNoteList(JSContext *cx) : list(cx) {}
|
||||
CGTryNoteList(ExclusiveContext *cx) : list(cx) {}
|
||||
|
||||
bool append(JSTryNoteKind kind, unsigned stackDepth, size_t start, size_t end);
|
||||
size_t length() const { return list.length(); }
|
||||
@ -47,7 +47,7 @@ struct CGObjectList {
|
||||
class CGConstList {
|
||||
Vector<Value> list;
|
||||
public:
|
||||
CGConstList(JSContext *cx) : list(cx) {}
|
||||
CGConstList(ExclusiveContext *cx) : list(cx) {}
|
||||
bool append(Value v) { JS_ASSERT_IF(v.isString(), v.toString()->isAtom()); return list.append(v); }
|
||||
size_t length() const { return list.length(); }
|
||||
void finish(ConstArray *array);
|
||||
@ -78,7 +78,7 @@ struct BytecodeEmitter
|
||||
uint32_t lastColumn; /* zero-based column index on currentLine of
|
||||
last SRC_COLSPAN-annotated opcode */
|
||||
|
||||
EmitSection(JSContext *cx, uint32_t lineNum)
|
||||
EmitSection(ExclusiveContext *cx, uint32_t lineNum)
|
||||
: code(cx), notes(cx), lastNoteOffset(0), currentLine(lineNum), lastColumn(0)
|
||||
{}
|
||||
};
|
||||
@ -180,7 +180,7 @@ struct BytecodeEmitter
|
||||
|
||||
bool needsImplicitThis();
|
||||
|
||||
void tellDebuggerAboutCompiledScript(JSContext *cx);
|
||||
void tellDebuggerAboutCompiledScript(ExclusiveContext *cx);
|
||||
|
||||
inline TokenStream *tokenStream();
|
||||
|
||||
@ -207,37 +207,37 @@ struct BytecodeEmitter
|
||||
* Emit one bytecode.
|
||||
*/
|
||||
ptrdiff_t
|
||||
Emit1(JSContext *cx, BytecodeEmitter *bce, JSOp op);
|
||||
Emit1(ExclusiveContext *cx, BytecodeEmitter *bce, JSOp op);
|
||||
|
||||
/*
|
||||
* Emit two bytecodes, an opcode (op) with a byte of immediate operand (op1).
|
||||
*/
|
||||
ptrdiff_t
|
||||
Emit2(JSContext *cx, BytecodeEmitter *bce, JSOp op, jsbytecode op1);
|
||||
Emit2(ExclusiveContext *cx, BytecodeEmitter *bce, JSOp op, jsbytecode op1);
|
||||
|
||||
/*
|
||||
* Emit three bytecodes, an opcode with two bytes of immediate operands.
|
||||
*/
|
||||
ptrdiff_t
|
||||
Emit3(JSContext *cx, BytecodeEmitter *bce, JSOp op, jsbytecode op1, jsbytecode op2);
|
||||
Emit3(ExclusiveContext *cx, BytecodeEmitter *bce, JSOp op, jsbytecode op1, jsbytecode op2);
|
||||
|
||||
/*
|
||||
* Emit (1 + extra) bytecodes, for N bytes of op and its immediate operand.
|
||||
*/
|
||||
ptrdiff_t
|
||||
EmitN(JSContext *cx, BytecodeEmitter *bce, JSOp op, size_t extra);
|
||||
EmitN(ExclusiveContext *cx, BytecodeEmitter *bce, JSOp op, size_t extra);
|
||||
|
||||
/*
|
||||
* Emit code into bce for the tree rooted at pn.
|
||||
*/
|
||||
bool
|
||||
EmitTree(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn);
|
||||
EmitTree(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn);
|
||||
|
||||
/*
|
||||
* Emit function code using bce for the tree rooted at body.
|
||||
*/
|
||||
bool
|
||||
EmitFunctionScript(JSContext *cx, BytecodeEmitter *bce, ParseNode *body);
|
||||
EmitFunctionScript(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *body);
|
||||
|
||||
/*
|
||||
* Append a new source note of the given type (and therefore size) to bce's
|
||||
@ -246,21 +246,21 @@ EmitFunctionScript(JSContext *cx, BytecodeEmitter *bce, ParseNode *body);
|
||||
* memory.
|
||||
*/
|
||||
int
|
||||
NewSrcNote(JSContext *cx, BytecodeEmitter *bce, SrcNoteType type);
|
||||
NewSrcNote(ExclusiveContext *cx, BytecodeEmitter *bce, SrcNoteType type);
|
||||
|
||||
int
|
||||
NewSrcNote2(JSContext *cx, BytecodeEmitter *bce, SrcNoteType type, ptrdiff_t offset);
|
||||
NewSrcNote2(ExclusiveContext *cx, BytecodeEmitter *bce, SrcNoteType type, ptrdiff_t offset);
|
||||
|
||||
int
|
||||
NewSrcNote3(JSContext *cx, BytecodeEmitter *bce, SrcNoteType type, ptrdiff_t offset1,
|
||||
NewSrcNote3(ExclusiveContext *cx, BytecodeEmitter *bce, SrcNoteType type, ptrdiff_t offset1,
|
||||
ptrdiff_t offset2);
|
||||
|
||||
/* NB: this function can add at most one extra extended delta note. */
|
||||
bool
|
||||
AddToSrcNoteDelta(JSContext *cx, BytecodeEmitter *bce, jssrcnote *sn, ptrdiff_t delta);
|
||||
AddToSrcNoteDelta(ExclusiveContext *cx, BytecodeEmitter *bce, jssrcnote *sn, ptrdiff_t delta);
|
||||
|
||||
bool
|
||||
FinishTakingSrcNotes(JSContext *cx, BytecodeEmitter *bce, jssrcnote *notes);
|
||||
FinishTakingSrcNotes(ExclusiveContext *cx, BytecodeEmitter *bce, jssrcnote *notes);
|
||||
|
||||
/*
|
||||
* Finish taking source notes in cx's notePool, copying final notes to the new
|
||||
|
@ -15,6 +15,8 @@
|
||||
#include "frontend/Parser.h"
|
||||
#include "vm/NumericConversions.h"
|
||||
|
||||
#include "jscntxtinlines.h"
|
||||
|
||||
using namespace js;
|
||||
using namespace js::frontend;
|
||||
|
||||
@ -67,7 +69,7 @@ ContainsVarOrConst(ParseNode *pn)
|
||||
* XXX handles only strings and numbers for now
|
||||
*/
|
||||
static bool
|
||||
FoldType(JSContext *cx, ParseNode *pn, ParseNodeKind kind)
|
||||
FoldType(ExclusiveContext *cx, ParseNode *pn, ParseNodeKind kind)
|
||||
{
|
||||
if (!pn->isKind(kind)) {
|
||||
switch (kind) {
|
||||
@ -107,7 +109,7 @@ FoldType(JSContext *cx, ParseNode *pn, ParseNodeKind kind)
|
||||
* a successful call to this function.
|
||||
*/
|
||||
static bool
|
||||
FoldBinaryNumeric(JSContext *cx, JSOp op, ParseNode *pn1, ParseNode *pn2,
|
||||
FoldBinaryNumeric(ExclusiveContext *cx, JSOp op, ParseNode *pn1, ParseNode *pn2,
|
||||
ParseNode *pn)
|
||||
{
|
||||
double d, d2;
|
||||
@ -244,8 +246,9 @@ condIf(const ParseNode *pn, ParseNodeKind kind)
|
||||
}
|
||||
|
||||
static bool
|
||||
Fold(JSContext *cx, ParseNode **pnp, FullParseHandler &handler, bool inGenexpLambda,
|
||||
SyntacticContext sc)
|
||||
Fold(ExclusiveContext *cx, ParseNode **pnp,
|
||||
FullParseHandler &handler, const CompileOptions &options,
|
||||
bool inGenexpLambda, SyntacticContext sc)
|
||||
{
|
||||
ParseNode *pn = *pnp;
|
||||
ParseNode *pn1 = NULL, *pn2 = NULL, *pn3 = NULL;
|
||||
@ -256,18 +259,18 @@ Fold(JSContext *cx, ParseNode **pnp, FullParseHandler &handler, bool inGenexpLam
|
||||
switch (pn->getArity()) {
|
||||
case PN_CODE:
|
||||
if (pn->isKind(PNK_FUNCTION) &&
|
||||
pn->pn_funbox->useAsmOrInsideUseAsm() && cx->hasOption(JSOPTION_ASMJS))
|
||||
pn->pn_funbox->useAsmOrInsideUseAsm() && options.asmJSOption)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (pn->getKind() == PNK_MODULE) {
|
||||
if (!Fold(cx, &pn->pn_body, handler, false, SyntacticContext::Other))
|
||||
if (!Fold(cx, &pn->pn_body, handler, options, false, SyntacticContext::Other))
|
||||
return false;
|
||||
} else {
|
||||
// Note: pn_body is NULL for functions which are being lazily parsed.
|
||||
JS_ASSERT(pn->getKind() == PNK_FUNCTION);
|
||||
if (pn->pn_body) {
|
||||
if (!Fold(cx, &pn->pn_body, handler, pn->pn_funbox->inGenexpLambda,
|
||||
if (!Fold(cx, &pn->pn_body, handler, options, pn->pn_funbox->inGenexpLambda,
|
||||
SyntacticContext::Other))
|
||||
return false;
|
||||
}
|
||||
@ -287,7 +290,7 @@ Fold(JSContext *cx, ParseNode **pnp, FullParseHandler &handler, bool inGenexpLam
|
||||
listp = &(*listp)->pn_next;
|
||||
|
||||
for (; *listp; listp = &(*listp)->pn_next) {
|
||||
if (!Fold(cx, listp, handler, inGenexpLambda, kidsc))
|
||||
if (!Fold(cx, listp, handler, options, inGenexpLambda, kidsc))
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -303,13 +306,13 @@ Fold(JSContext *cx, ParseNode **pnp, FullParseHandler &handler, bool inGenexpLam
|
||||
case PN_TERNARY:
|
||||
/* Any kid may be null (e.g. for (;;)). */
|
||||
if (pn->pn_kid1) {
|
||||
if (!Fold(cx, &pn->pn_kid1, handler, inGenexpLambda, condIf(pn, PNK_IF)))
|
||||
if (!Fold(cx, &pn->pn_kid1, handler, options, inGenexpLambda, condIf(pn, PNK_IF)))
|
||||
return false;
|
||||
}
|
||||
pn1 = pn->pn_kid1;
|
||||
|
||||
if (pn->pn_kid2) {
|
||||
if (!Fold(cx, &pn->pn_kid2, handler, inGenexpLambda, condIf(pn, PNK_FORHEAD)))
|
||||
if (!Fold(cx, &pn->pn_kid2, handler, options, inGenexpLambda, condIf(pn, PNK_FORHEAD)))
|
||||
return false;
|
||||
if (pn->isKind(PNK_FORHEAD) && pn->pn_kid2->isKind(PNK_TRUE)) {
|
||||
handler.freeTree(pn->pn_kid2);
|
||||
@ -319,7 +322,7 @@ Fold(JSContext *cx, ParseNode **pnp, FullParseHandler &handler, bool inGenexpLam
|
||||
pn2 = pn->pn_kid2;
|
||||
|
||||
if (pn->pn_kid3) {
|
||||
if (!Fold(cx, &pn->pn_kid3, handler, inGenexpLambda, SyntacticContext::Other))
|
||||
if (!Fold(cx, &pn->pn_kid3, handler, options, inGenexpLambda, SyntacticContext::Other))
|
||||
return false;
|
||||
}
|
||||
pn3 = pn->pn_kid3;
|
||||
@ -331,17 +334,17 @@ Fold(JSContext *cx, ParseNode **pnp, FullParseHandler &handler, bool inGenexpLam
|
||||
SyntacticContext kidsc = SyntacticContext::Other;
|
||||
if (sc == SyntacticContext::Condition)
|
||||
kidsc = sc;
|
||||
if (!Fold(cx, &pn->pn_left, handler, inGenexpLambda, kidsc))
|
||||
if (!Fold(cx, &pn->pn_left, handler, options, inGenexpLambda, kidsc))
|
||||
return false;
|
||||
if (!Fold(cx, &pn->pn_right, handler, inGenexpLambda, kidsc))
|
||||
if (!Fold(cx, &pn->pn_right, handler, options, inGenexpLambda, kidsc))
|
||||
return false;
|
||||
} else {
|
||||
/* First kid may be null (for default case in switch). */
|
||||
if (pn->pn_left) {
|
||||
if (!Fold(cx, &pn->pn_left, handler, inGenexpLambda, condIf(pn, PNK_WHILE)))
|
||||
if (!Fold(cx, &pn->pn_left, handler, options, inGenexpLambda, condIf(pn, PNK_WHILE)))
|
||||
return false;
|
||||
}
|
||||
if (!Fold(cx, &pn->pn_right, handler, inGenexpLambda, condIf(pn, PNK_DOWHILE)))
|
||||
if (!Fold(cx, &pn->pn_right, handler, options, inGenexpLambda, condIf(pn, PNK_DOWHILE)))
|
||||
return false;
|
||||
}
|
||||
pn1 = pn->pn_left;
|
||||
@ -368,7 +371,7 @@ Fold(JSContext *cx, ParseNode **pnp, FullParseHandler &handler, bool inGenexpLam
|
||||
: pn->isKind(PNK_DELETE)
|
||||
? SyntacticContext::Delete
|
||||
: SyntacticContext::Other;
|
||||
if (!Fold(cx, &pn->pn_kid, handler, inGenexpLambda, kidsc))
|
||||
if (!Fold(cx, &pn->pn_kid, handler, options, inGenexpLambda, kidsc))
|
||||
return false;
|
||||
}
|
||||
pn1 = pn->pn_kid;
|
||||
@ -385,7 +388,7 @@ Fold(JSContext *cx, ParseNode **pnp, FullParseHandler &handler, bool inGenexpLam
|
||||
ParseNode **lhsp = &pn->pn_expr;
|
||||
while (*lhsp && (*lhsp)->isArity(PN_NAME) && !(*lhsp)->isUsed())
|
||||
lhsp = &(*lhsp)->pn_expr;
|
||||
if (*lhsp && !Fold(cx, lhsp, handler, inGenexpLambda, SyntacticContext::Other))
|
||||
if (*lhsp && !Fold(cx, lhsp, handler, options, inGenexpLambda, SyntacticContext::Other))
|
||||
return false;
|
||||
pn1 = *lhsp;
|
||||
}
|
||||
@ -804,15 +807,14 @@ Fold(JSContext *cx, ParseNode **pnp, FullParseHandler &handler, bool inGenexpLam
|
||||
}
|
||||
|
||||
bool
|
||||
frontend::FoldConstants(JSContext *cx, ParseNode **pnp, Parser<FullParseHandler> *parser)
|
||||
frontend::FoldConstants(ExclusiveContext *cx, ParseNode **pnp, Parser<FullParseHandler> *parser)
|
||||
{
|
||||
|
||||
// Don't fold constants if the code has requested "use asm" as
|
||||
// constant-folding will misrepresent the source text for the purpose
|
||||
// of type checking. (Also guard against entering a function containing
|
||||
// "use asm", see PN_FUNC case below.)
|
||||
if (parser->pc->useAsmOrInsideUseAsm() && cx->hasOption(JSOPTION_ASMJS))
|
||||
if (parser->pc->useAsmOrInsideUseAsm() && parser->options().asmJSOption)
|
||||
return true;
|
||||
|
||||
return Fold(cx, pnp, parser->handler, false, SyntacticContext::Other);
|
||||
return Fold(cx, pnp, parser->handler, parser->options(), false, SyntacticContext::Other);
|
||||
}
|
||||
|
@ -28,10 +28,11 @@ namespace frontend {
|
||||
// if (!FoldConstants(cx, &pn, parser))
|
||||
// return false;
|
||||
bool
|
||||
FoldConstants(JSContext *cx, ParseNode **pnp, Parser<FullParseHandler> *parser);
|
||||
FoldConstants(ExclusiveContext *cx, ParseNode **pnp, Parser<FullParseHandler> *parser);
|
||||
|
||||
inline bool
|
||||
FoldConstants(JSContext *cx, SyntaxParseHandler::Node *pnp, Parser<SyntaxParseHandler> *parser)
|
||||
FoldConstants(ExclusiveContext *cx, SyntaxParseHandler::Node *pnp,
|
||||
Parser<SyntaxParseHandler> *parser)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -69,9 +69,10 @@ class FullParseHandler
|
||||
typedef ParseNode *Node;
|
||||
typedef Definition *DefinitionNode;
|
||||
|
||||
FullParseHandler(JSContext *cx, TokenStream &tokenStream, bool foldConstants,
|
||||
FullParseHandler(ExclusiveContext *cx, LifoAlloc &alloc,
|
||||
TokenStream &tokenStream, bool foldConstants,
|
||||
Parser<SyntaxParseHandler> *syntaxParser, LazyScript *lazyOuterFunction)
|
||||
: allocator(cx),
|
||||
: allocator(cx, alloc),
|
||||
tokenStream(tokenStream),
|
||||
foldConstants(foldConstants),
|
||||
lazyOuterFunction_(lazyOuterFunction),
|
||||
|
@ -16,21 +16,21 @@ namespace frontend {
|
||||
|
||||
template <class Map>
|
||||
inline bool
|
||||
AtomThingMapPtr<Map>::ensureMap(JSContext *cx)
|
||||
AtomThingMapPtr<Map>::ensureMap(ExclusiveContext *cx)
|
||||
{
|
||||
if (map_)
|
||||
return true;
|
||||
map_ = cx->runtime()->parseMapPool.acquire<Map>();
|
||||
map_ = cx->parseMapPool().acquire<Map>();
|
||||
return !!map_;
|
||||
}
|
||||
|
||||
template <class Map>
|
||||
inline void
|
||||
AtomThingMapPtr<Map>::releaseMap(JSContext *cx)
|
||||
AtomThingMapPtr<Map>::releaseMap(ExclusiveContext *cx)
|
||||
{
|
||||
if (!map_)
|
||||
return;
|
||||
cx->runtime()->parseMapPool.release(map_);
|
||||
cx->parseMapPool().release(map_);
|
||||
map_ = NULL;
|
||||
}
|
||||
|
||||
@ -38,7 +38,7 @@ template <typename ParseHandler>
|
||||
inline bool
|
||||
AtomDecls<ParseHandler>::init()
|
||||
{
|
||||
map = cx->runtime()->parseMapPool.acquire<AtomDefnListMap>();
|
||||
map = cx->parseMapPool().acquire<AtomDefnListMap>();
|
||||
return map;
|
||||
}
|
||||
|
||||
@ -47,7 +47,7 @@ inline
|
||||
AtomDecls<ParseHandler>::~AtomDecls()
|
||||
{
|
||||
if (map)
|
||||
cx->runtime()->parseMapPool.release(map);
|
||||
cx->parseMapPool().release(map);
|
||||
}
|
||||
|
||||
} /* namespace frontend */
|
||||
|
@ -58,9 +58,9 @@ ParseMapPool::allocateFresh()
|
||||
}
|
||||
|
||||
DefinitionList::Node *
|
||||
DefinitionList::allocNode(JSContext *cx, uintptr_t head, Node *tail)
|
||||
DefinitionList::allocNode(ExclusiveContext *cx, LifoAlloc &alloc, uintptr_t head, Node *tail)
|
||||
{
|
||||
Node *result = cx->tempLifoAlloc().new_<Node>(head, tail);
|
||||
Node *result = alloc.new_<Node>(head, tail);
|
||||
if (!result)
|
||||
js_ReportOutOfMemory(cx);
|
||||
return result;
|
||||
@ -105,11 +105,11 @@ AtomDecls<ParseHandler>::addShadow(JSAtom *atom, typename ParseHandler::Definiti
|
||||
if (!p)
|
||||
return map->add(p, atom, DefinitionList(ParseHandler::definitionToBits(defn)));
|
||||
|
||||
return p.value().pushFront<ParseHandler>(cx, defn);
|
||||
return p.value().pushFront<ParseHandler>(cx, alloc, defn);
|
||||
}
|
||||
|
||||
void
|
||||
frontend::InitAtomMap(JSContext *cx, frontend::AtomIndexMap *indices, HeapPtrAtom *atoms)
|
||||
frontend::InitAtomMap(frontend::AtomIndexMap *indices, HeapPtrAtom *atoms)
|
||||
{
|
||||
if (indices->isMap()) {
|
||||
typedef AtomIndexMap::WordMap WordMap;
|
||||
|
@ -30,7 +30,7 @@ typedef InlineMap<JSAtom *, DefinitionList, 24> AtomDefnListMap;
|
||||
* the list and map->vector must point to pre-allocated memory.
|
||||
*/
|
||||
void
|
||||
InitAtomMap(JSContext *cx, AtomIndexMap *indices, HeapPtr<JSAtom> *atoms);
|
||||
InitAtomMap(AtomIndexMap *indices, HeapPtr<JSAtom> *atoms);
|
||||
|
||||
/*
|
||||
* A pool that permits the reuse of the backing storage for the defn, index, or
|
||||
@ -127,8 +127,8 @@ struct AtomThingMapPtr
|
||||
|
||||
void init() { clearMap(); }
|
||||
|
||||
bool ensureMap(JSContext *cx);
|
||||
void releaseMap(JSContext *cx);
|
||||
bool ensureMap(ExclusiveContext *cx);
|
||||
void releaseMap(ExclusiveContext *cx);
|
||||
|
||||
bool hasMap() const { return map_; }
|
||||
Map *getMap() { return map_; }
|
||||
@ -149,10 +149,10 @@ typedef AtomThingMapPtr<AtomIndexMap> AtomIndexMapPtr;
|
||||
template <typename AtomThingMapPtrT>
|
||||
class OwnedAtomThingMapPtr : public AtomThingMapPtrT
|
||||
{
|
||||
JSContext *cx;
|
||||
ExclusiveContext *cx;
|
||||
|
||||
public:
|
||||
explicit OwnedAtomThingMapPtr(JSContext *cx) : cx(cx) {
|
||||
explicit OwnedAtomThingMapPtr(ExclusiveContext *cx) : cx(cx) {
|
||||
AtomThingMapPtrT::init();
|
||||
}
|
||||
|
||||
@ -244,8 +244,8 @@ class DefinitionList
|
||||
}
|
||||
|
||||
static Node *
|
||||
allocNode(JSContext *cx, uintptr_t bits, Node *tail);
|
||||
|
||||
allocNode(ExclusiveContext *cx, LifoAlloc &alloc, uintptr_t bits, Node *tail);
|
||||
|
||||
public:
|
||||
class Range
|
||||
{
|
||||
@ -336,17 +336,18 @@ class DefinitionList
|
||||
* Return true on success. On OOM, report on cx and return false.
|
||||
*/
|
||||
template <typename ParseHandler>
|
||||
bool pushFront(JSContext *cx, typename ParseHandler::DefinitionNode defn) {
|
||||
bool pushFront(ExclusiveContext *cx, LifoAlloc &alloc,
|
||||
typename ParseHandler::DefinitionNode defn) {
|
||||
Node *tail;
|
||||
if (isMultiple()) {
|
||||
tail = firstNode();
|
||||
} else {
|
||||
tail = allocNode(cx, u.bits, NULL);
|
||||
tail = allocNode(cx, alloc, u.bits, NULL);
|
||||
if (!tail)
|
||||
return false;
|
||||
}
|
||||
|
||||
Node *node = allocNode(cx, ParseHandler::definitionToBits(defn), tail);
|
||||
Node *node = allocNode(cx, alloc, ParseHandler::definitionToBits(defn), tail);
|
||||
if (!node)
|
||||
return false;
|
||||
*this = DefinitionList(node);
|
||||
@ -404,14 +405,15 @@ class AtomDecls
|
||||
/* AtomDeclsIter needs to get at the DefnListMap directly. */
|
||||
friend class AtomDeclsIter;
|
||||
|
||||
JSContext *cx;
|
||||
ExclusiveContext *cx;
|
||||
LifoAlloc &alloc;
|
||||
AtomDefnListMap *map;
|
||||
|
||||
AtomDecls(const AtomDecls &other) MOZ_DELETE;
|
||||
void operator=(const AtomDecls &other) MOZ_DELETE;
|
||||
|
||||
public:
|
||||
explicit AtomDecls(JSContext *cx) : cx(cx), map(NULL) {}
|
||||
explicit AtomDecls(ExclusiveContext *cx, LifoAlloc &alloc) : cx(cx), alloc(alloc), map(NULL) {}
|
||||
|
||||
~AtomDecls();
|
||||
|
||||
|
@ -8,6 +8,8 @@
|
||||
#include "frontend/ParseNode.h"
|
||||
#include "frontend/Parser.h"
|
||||
|
||||
#include "jscntxtinlines.h"
|
||||
|
||||
using namespace js;
|
||||
using namespace js::frontend;
|
||||
|
||||
@ -240,7 +242,7 @@ ParseNodeAllocator::allocNode()
|
||||
return pn;
|
||||
}
|
||||
|
||||
void *p = cx->tempLifoAlloc().alloc(sizeof (ParseNode));
|
||||
void *p = alloc.alloc(sizeof (ParseNode));
|
||||
if (!p)
|
||||
js_ReportOutOfMemory(cx);
|
||||
return p;
|
||||
|
@ -51,15 +51,13 @@ class UpvarCookie
|
||||
uint16_t slot() const { JS_ASSERT(!isFree()); return slot_; }
|
||||
|
||||
// This fails and issues an error message if newLevel is too large.
|
||||
bool set(JSContext *cx, unsigned newLevel, uint16_t newSlot) {
|
||||
bool set(TokenStream &ts, unsigned newLevel, uint16_t newSlot) {
|
||||
// This is an unsigned-to-uint16_t conversion, test for too-high
|
||||
// values. In practice, recursion in Parser and/or BytecodeEmitter
|
||||
// will blow the stack if we nest functions more than a few hundred
|
||||
// deep, so this will never trigger. Oh well.
|
||||
if (newLevel >= FREE_LEVEL) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_TOO_DEEP, js_function_str);
|
||||
return false;
|
||||
}
|
||||
if (newLevel >= FREE_LEVEL)
|
||||
return ts.reportError(JSMSG_TOO_DEEP);
|
||||
level_ = newLevel;
|
||||
slot_ = newSlot;
|
||||
return true;
|
||||
@ -803,7 +801,7 @@ class ParseNode
|
||||
#endif
|
||||
;
|
||||
|
||||
bool getConstantValue(JSContext *cx, bool strictChecks, MutableHandleValue vp);
|
||||
bool getConstantValue(ExclusiveContext *cx, bool strictChecks, MutableHandleValue vp);
|
||||
inline bool isConstant();
|
||||
|
||||
template <class NodeType>
|
||||
@ -1357,7 +1355,9 @@ struct Definition : public ParseNode
|
||||
class ParseNodeAllocator
|
||||
{
|
||||
public:
|
||||
explicit ParseNodeAllocator(JSContext *cx) : cx(cx), freelist(NULL) {}
|
||||
explicit ParseNodeAllocator(ExclusiveContext *cx, LifoAlloc &alloc)
|
||||
: cx(cx), alloc(alloc), freelist(NULL)
|
||||
{}
|
||||
|
||||
void *allocNode();
|
||||
void freeNode(ParseNode *pn);
|
||||
@ -1365,7 +1365,8 @@ class ParseNodeAllocator
|
||||
void prepareNodeForMutation(ParseNode *pn);
|
||||
|
||||
private:
|
||||
JSContext *cx;
|
||||
ExclusiveContext *cx;
|
||||
LifoAlloc &alloc;
|
||||
ParseNode *freelist;
|
||||
};
|
||||
|
||||
|
@ -77,7 +77,10 @@ bool
|
||||
GenerateBlockId(ParseContext<ParseHandler> *pc, uint32_t &blockid)
|
||||
{
|
||||
if (pc->blockidGen == JS_BIT(20)) {
|
||||
JS_ReportErrorNumber(pc->sc->context, js_GetErrorMessage, NULL, JSMSG_NEED_DIET, "program");
|
||||
if (!pc->sc->context->isJSContext())
|
||||
return false;
|
||||
JS_ReportErrorNumber(pc->sc->context->asJSContext(),
|
||||
js_GetErrorMessage, NULL, JSMSG_NEED_DIET, "program");
|
||||
return false;
|
||||
}
|
||||
JS_ASSERT(pc->blockidGen < JS_BIT(20));
|
||||
@ -102,8 +105,8 @@ PushStatementPC(ParseContext<ParseHandler> *pc, StmtInfoPC *stmt, StmtType type)
|
||||
// See comment on member function declaration.
|
||||
template <>
|
||||
bool
|
||||
ParseContext<FullParseHandler>::define(JSContext *cx, HandlePropertyName name,
|
||||
ParseNode *pn, Definition::Kind kind)
|
||||
ParseContext<FullParseHandler>::define(TokenStream &ts,
|
||||
PropertyName *name, ParseNode *pn, Definition::Kind kind)
|
||||
{
|
||||
JS_ASSERT(!pn->isUsed());
|
||||
JS_ASSERT_IF(pn->isDefn(), pn->isPlaceholder());
|
||||
@ -154,11 +157,11 @@ ParseContext<FullParseHandler>::define(JSContext *cx, HandlePropertyName name,
|
||||
JS_ASSERT(sc->isFunctionBox());
|
||||
dn->setOp(JSOP_GETARG);
|
||||
dn->pn_dflags |= PND_BOUND;
|
||||
if (!dn->pn_cookie.set(cx, staticLevel, args_.length()))
|
||||
if (!dn->pn_cookie.set(ts, staticLevel, args_.length()))
|
||||
return false;
|
||||
if (!args_.append(dn))
|
||||
return false;
|
||||
if (name == cx->names().empty)
|
||||
if (name == ts.names().empty)
|
||||
break;
|
||||
if (!decls_.addUnique(name, dn))
|
||||
return false;
|
||||
@ -169,7 +172,7 @@ ParseContext<FullParseHandler>::define(JSContext *cx, HandlePropertyName name,
|
||||
if (sc->isFunctionBox()) {
|
||||
dn->setOp(JSOP_GETLOCAL);
|
||||
dn->pn_dflags |= PND_BOUND;
|
||||
if (!dn->pn_cookie.set(cx, staticLevel, vars_.length()))
|
||||
if (!dn->pn_cookie.set(ts, staticLevel, vars_.length()))
|
||||
return false;
|
||||
if (!vars_.append(dn))
|
||||
return false;
|
||||
@ -195,7 +198,7 @@ ParseContext<FullParseHandler>::define(JSContext *cx, HandlePropertyName name,
|
||||
|
||||
template <>
|
||||
bool
|
||||
ParseContext<SyntaxParseHandler>::define(JSContext *cx, HandlePropertyName name, Node pn,
|
||||
ParseContext<SyntaxParseHandler>::define(TokenStream &ts, PropertyName *name, Node pn,
|
||||
Definition::Kind kind)
|
||||
{
|
||||
JS_ASSERT(!decls_.lookupFirst(name));
|
||||
@ -296,12 +299,13 @@ AppendPackedBindings(const ParseContext<ParseHandler> *pc, const DeclVector &vec
|
||||
|
||||
template <typename ParseHandler>
|
||||
bool
|
||||
ParseContext<ParseHandler>::generateFunctionBindings(JSContext *cx, InternalHandle<Bindings*> bindings) const
|
||||
ParseContext<ParseHandler>::generateFunctionBindings(ExclusiveContext *cx, LifoAlloc &alloc,
|
||||
InternalHandle<Bindings*> bindings) const
|
||||
{
|
||||
JS_ASSERT(sc->isFunctionBox());
|
||||
|
||||
unsigned count = args_.length() + vars_.length();
|
||||
Binding *packedBindings = cx->tempLifoAlloc().newArrayUninitialized<Binding>(count);
|
||||
Binding *packedBindings = alloc.newArrayUninitialized<Binding>(count);
|
||||
if (!packedBindings) {
|
||||
js_ReportOutOfMemory(cx);
|
||||
return false;
|
||||
@ -380,47 +384,47 @@ Parser<SyntaxParseHandler>::abortIfSyntaxParser()
|
||||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
Parser<ParseHandler>::Parser(JSContext *cx, const CompileOptions &options,
|
||||
Parser<ParseHandler>::Parser(ExclusiveContext *cx, LifoAlloc *alloc,
|
||||
const CompileOptions &options,
|
||||
const jschar *chars, size_t length, bool foldConstants,
|
||||
Parser<SyntaxParseHandler> *syntaxParser,
|
||||
LazyScript *lazyOuterFunction)
|
||||
: AutoGCRooter(cx, PARSER),
|
||||
context(cx),
|
||||
alloc(*alloc),
|
||||
tokenStream(cx, options, chars, length, thisForCtor(), keepAtoms),
|
||||
traceListHead(NULL),
|
||||
pc(NULL),
|
||||
sct(NULL),
|
||||
keepAtoms(cx->runtime()),
|
||||
keepAtoms(cx->asJSContext()->runtime()),
|
||||
foldConstants(foldConstants),
|
||||
compileAndGo(options.compileAndGo),
|
||||
selfHostingMode(options.selfHostingMode),
|
||||
abortedSyntaxParse(false),
|
||||
handler(cx, tokenStream, foldConstants, syntaxParser, lazyOuterFunction)
|
||||
handler(cx, *alloc, tokenStream, foldConstants, syntaxParser, lazyOuterFunction)
|
||||
{
|
||||
cx->runtime()->activeCompilations++;
|
||||
cx->asJSContext()->runtime()->activeCompilations++;
|
||||
|
||||
// The Mozilla specific JSOPTION_EXTRA_WARNINGS option adds extra warnings
|
||||
// which are not generated if functions are parsed lazily. Note that the
|
||||
// standard "use strict" does not inhibit lazy parsing.
|
||||
if (context->hasExtraWarningsOption())
|
||||
if (options.extraWarningsOption)
|
||||
handler.disableSyntaxParser();
|
||||
|
||||
tempPoolMark = cx->tempLifoAlloc().mark();
|
||||
tempPoolMark = alloc->mark();
|
||||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
Parser<ParseHandler>::~Parser()
|
||||
{
|
||||
JSContext *cx = context;
|
||||
cx->tempLifoAlloc().release(tempPoolMark);
|
||||
cx->runtime()->activeCompilations--;
|
||||
context->asJSContext()->runtime()->activeCompilations--;
|
||||
|
||||
alloc.release(tempPoolMark);
|
||||
|
||||
/*
|
||||
* The parser can allocate enormous amounts of memory for large functions.
|
||||
* Eagerly free the memory now (which otherwise won't be freed until the
|
||||
* next GC) to avoid unnecessary OOMs.
|
||||
*/
|
||||
cx->tempLifoAlloc().freeAllIfHugeAndUnused();
|
||||
alloc.freeAllIfHugeAndUnused();
|
||||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
@ -437,7 +441,7 @@ Parser<ParseHandler>::newObjectBox(JSObject *obj)
|
||||
* function.
|
||||
*/
|
||||
|
||||
ObjectBox *objbox = context->tempLifoAlloc().new_<ObjectBox>(obj, traceListHead);
|
||||
ObjectBox *objbox = alloc.new_<ObjectBox>(obj, traceListHead);
|
||||
if (!objbox) {
|
||||
js_ReportOutOfMemory(context);
|
||||
return NULL;
|
||||
@ -449,10 +453,10 @@ Parser<ParseHandler>::newObjectBox(JSObject *obj)
|
||||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
FunctionBox::FunctionBox(JSContext *cx, ObjectBox* traceListHead, JSFunction *fun,
|
||||
ParseContext<ParseHandler> *outerpc, bool strict)
|
||||
FunctionBox::FunctionBox(ExclusiveContext *cx, ObjectBox* traceListHead, JSFunction *fun,
|
||||
ParseContext<ParseHandler> *outerpc, bool strict, bool extraWarnings)
|
||||
: ObjectBox(fun, traceListHead),
|
||||
SharedContext(cx, strict),
|
||||
SharedContext(cx, strict, extraWarnings),
|
||||
bindings(),
|
||||
bufStart(0),
|
||||
bufEnd(0),
|
||||
@ -526,7 +530,8 @@ Parser<ParseHandler>::newFunctionBox(JSFunction *fun,
|
||||
* function.
|
||||
*/
|
||||
FunctionBox *funbox =
|
||||
context->tempLifoAlloc().new_<FunctionBox>(context, traceListHead, fun, outerpc, strict);
|
||||
alloc.new_<FunctionBox>(context, traceListHead, fun, outerpc,
|
||||
strict, options().extraWarningsOption);
|
||||
if (!funbox) {
|
||||
js_ReportOutOfMemory(context);
|
||||
return NULL;
|
||||
@ -537,10 +542,10 @@ Parser<ParseHandler>::newFunctionBox(JSFunction *fun,
|
||||
return funbox;
|
||||
}
|
||||
|
||||
ModuleBox::ModuleBox(JSContext *cx, ObjectBox *traceListHead, Module *module,
|
||||
ParseContext<FullParseHandler> *pc)
|
||||
: ObjectBox(module, traceListHead),
|
||||
SharedContext(cx, true)
|
||||
ModuleBox::ModuleBox(ExclusiveContext *cx, ObjectBox *traceListHead, Module *module,
|
||||
ParseContext<FullParseHandler> *pc, bool extraWarnings)
|
||||
: ObjectBox(module, traceListHead),
|
||||
SharedContext(cx, true, extraWarnings)
|
||||
{
|
||||
}
|
||||
|
||||
@ -558,7 +563,8 @@ Parser<FullParseHandler>::newModuleBox(Module *module, ParseContext<FullParseHan
|
||||
* function.
|
||||
*/
|
||||
ModuleBox *modulebox =
|
||||
context->tempLifoAlloc().new_<ModuleBox>(context, traceListHead, module, outerpc);
|
||||
alloc.new_<ModuleBox>(context, traceListHead, module, outerpc,
|
||||
options().extraWarningsOption);
|
||||
if (!modulebox) {
|
||||
js_ReportOutOfMemory(context);
|
||||
return NULL;
|
||||
@ -597,7 +603,8 @@ Parser<ParseHandler>::parse(JSObject *chain)
|
||||
* an object lock before it finishes generating bytecode into a script
|
||||
* protected from the GC by a root or a stack frame reference.
|
||||
*/
|
||||
GlobalSharedContext globalsc(context, chain, StrictModeFromContext(context));
|
||||
GlobalSharedContext globalsc(context, chain,
|
||||
options().strictOption, options().extraWarningsOption);
|
||||
ParseContext<ParseHandler> globalpc(this, NULL, &globalsc, /* staticLevel = */ 0, /* bodyid = */ 0);
|
||||
if (!globalpc.init())
|
||||
return null();
|
||||
@ -757,7 +764,7 @@ Parser<ParseHandler>::reportBadReturn(Node pn, ParseReportKind kind,
|
||||
JSAutoByteString name;
|
||||
JSAtom *atom = pc->sc->asFunctionBox()->function()->atom();
|
||||
if (atom) {
|
||||
if (!js_AtomToPrintableString(context, atom, &name))
|
||||
if (!AtomToPrintableString(context, atom, &name))
|
||||
return false;
|
||||
} else {
|
||||
errnum = anonerrnum;
|
||||
@ -792,7 +799,7 @@ Parser<ParseHandler>::checkStrictAssignment(Node lhs)
|
||||
|
||||
if (atom == context->names().eval || atom == context->names().arguments) {
|
||||
JSAutoByteString name;
|
||||
if (!js_AtomToPrintableString(context, atom, &name) ||
|
||||
if (!AtomToPrintableString(context, atom, &name) ||
|
||||
!report(ParseStrictError, pc->sc->strict, lhs,
|
||||
JSMSG_DEPRECATED_ASSIGN, name.ptr()))
|
||||
{
|
||||
@ -817,7 +824,7 @@ Parser<ParseHandler>::checkStrictBinding(HandlePropertyName name, Node pn)
|
||||
|
||||
if (name == context->names().eval || name == context->names().arguments || IsKeyword(name)) {
|
||||
JSAutoByteString bytes;
|
||||
if (!js_AtomToPrintableString(context, name, &bytes))
|
||||
if (!AtomToPrintableString(context, name, &bytes))
|
||||
return false;
|
||||
return report(ParseStrictError, pc->sc->strict, pn,
|
||||
JSMSG_BAD_BINDING, bytes.ptr());
|
||||
@ -865,14 +872,14 @@ Parser<FullParseHandler>::standaloneFunctionBody(HandleFunction fun, const AutoN
|
||||
return null();
|
||||
|
||||
InternalHandle<Bindings*> scriptBindings(script, &script->bindings);
|
||||
if (!funpc.generateFunctionBindings(context, scriptBindings))
|
||||
if (!funpc.generateFunctionBindings(context, alloc, scriptBindings))
|
||||
return null();
|
||||
|
||||
// Also populate the internal bindings of the function box, so that
|
||||
// heavyweight tests while emitting bytecode work.
|
||||
InternalHandle<Bindings*> funboxBindings =
|
||||
InternalHandle<Bindings*>::fromMarkedLocation(&(*funbox)->bindings);
|
||||
if (!funpc.generateFunctionBindings(context, funboxBindings))
|
||||
if (!funpc.generateFunctionBindings(context, alloc, funboxBindings))
|
||||
return null();
|
||||
|
||||
return pn;
|
||||
@ -907,7 +914,7 @@ Parser<FullParseHandler>::checkFunctionArguments()
|
||||
Definition *dn = r.front().value().get<FullParseHandler>();
|
||||
pc->lexdeps->remove(arguments);
|
||||
dn->pn_dflags |= PND_IMPLICITARGUMENTS;
|
||||
if (!pc->define(context, arguments, dn, Definition::VAR))
|
||||
if (!pc->define(tokenStream, arguments, dn, Definition::VAR))
|
||||
return false;
|
||||
pc->sc->asFunctionBox()->usesArguments = true;
|
||||
break;
|
||||
@ -936,7 +943,7 @@ Parser<FullParseHandler>::checkFunctionArguments()
|
||||
ParseNode *pn = newName(arguments);
|
||||
if (!pn)
|
||||
return false;
|
||||
if (!pc->define(context, arguments, pn, Definition::VAR))
|
||||
if (!pc->define(tokenStream, arguments, pn, Definition::VAR))
|
||||
return false;
|
||||
argumentsHasBinding = true;
|
||||
argumentsHasLocalBinding = true;
|
||||
@ -1051,7 +1058,7 @@ Parser<ParseHandler>::functionBody(FunctionSyntaxKind kind, FunctionBodyType typ
|
||||
}
|
||||
|
||||
/* Check for falling off the end of a function that returns a value. */
|
||||
if (context->hasExtraWarningsOption() && pc->funHasReturnExpr && !checkFinalReturn(pn))
|
||||
if (options().extraWarningsOption && pc->funHasReturnExpr && !checkFinalReturn(pn))
|
||||
return null();
|
||||
|
||||
/* Define the 'arguments' binding if necessary. */
|
||||
@ -1143,10 +1150,10 @@ Parser<FullParseHandler>::makeDefIntoUse(Definition *dn, ParseNode *pn, JSAtom *
|
||||
template <typename ParseHandler>
|
||||
struct BindData
|
||||
{
|
||||
BindData(JSContext *cx) : let(cx) {}
|
||||
BindData(ExclusiveContext *cx) : let(cx) {}
|
||||
|
||||
typedef bool
|
||||
(*Binder)(JSContext *cx, BindData *data, HandlePropertyName name, Parser<ParseHandler> *parser);
|
||||
(*Binder)(BindData *data, HandlePropertyName name, Parser<ParseHandler> *parser);
|
||||
|
||||
/* name node for definition processing and error source coordinates */
|
||||
typename ParseHandler::Node pn;
|
||||
@ -1155,7 +1162,7 @@ struct BindData
|
||||
Binder binder; /* binder, discriminates u */
|
||||
|
||||
struct LetData {
|
||||
LetData(JSContext *cx) : blockObj(cx) {}
|
||||
LetData(ExclusiveContext *cx) : blockObj(cx) {}
|
||||
VarContext varContext;
|
||||
RootedStaticBlockObject blockObj;
|
||||
unsigned overflow;
|
||||
@ -1203,12 +1210,12 @@ Parser<ParseHandler>::newFunction(GenericParseContext *pc, HandleAtom atom,
|
||||
: JSFunction::INTERPRETED;
|
||||
fun = NewFunction(context, NullPtr(), NULL, 0, flags, parent, atom,
|
||||
JSFunction::FinalizeKind, MaybeSingletonObject);
|
||||
if (selfHostingMode)
|
||||
if (options().selfHostingMode)
|
||||
fun->setIsSelfHostedBuiltin();
|
||||
if (fun && !compileAndGo) {
|
||||
if (!JSObject::clearParent(context, fun))
|
||||
if (fun && !options().compileAndGo) {
|
||||
if (!JSObject::clearParent(context->asJSContext(), fun))
|
||||
return NULL;
|
||||
if (!JSObject::clearType(context, fun))
|
||||
if (!JSObject::clearType(context->asJSContext(), fun))
|
||||
return NULL;
|
||||
fun->setEnvironment(NULL);
|
||||
}
|
||||
@ -1216,18 +1223,18 @@ Parser<ParseHandler>::newFunction(GenericParseContext *pc, HandleAtom atom,
|
||||
}
|
||||
|
||||
static bool
|
||||
MatchOrInsertSemicolon(JSContext *cx, TokenStream *ts)
|
||||
MatchOrInsertSemicolon(TokenStream &ts)
|
||||
{
|
||||
TokenKind tt = ts->peekTokenSameLine(TSF_OPERAND);
|
||||
TokenKind tt = ts.peekTokenSameLine(TSF_OPERAND);
|
||||
if (tt == TOK_ERROR)
|
||||
return false;
|
||||
if (tt != TOK_EOF && tt != TOK_EOL && tt != TOK_SEMI && tt != TOK_RC) {
|
||||
/* Advance the scanner for proper error location reporting. */
|
||||
ts->getToken(TSF_OPERAND);
|
||||
ts->reportError(JSMSG_SEMI_BEFORE_STMNT);
|
||||
ts.getToken(TSF_OPERAND);
|
||||
ts.reportError(JSMSG_SEMI_BEFORE_STMNT);
|
||||
return false;
|
||||
}
|
||||
(void) ts->matchToken(TOK_SEMI);
|
||||
(void) ts.matchToken(TOK_SEMI);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1249,11 +1256,11 @@ Parser<ParseHandler>::getOrCreateLexicalDependency(ParseContext<ParseHandler> *p
|
||||
}
|
||||
|
||||
static bool
|
||||
ConvertDefinitionToNamedLambdaUse(JSContext *cx, ParseContext<FullParseHandler> *pc,
|
||||
ConvertDefinitionToNamedLambdaUse(TokenStream &ts, ParseContext<FullParseHandler> *pc,
|
||||
FunctionBox *funbox, Definition *dn)
|
||||
{
|
||||
dn->setOp(JSOP_CALLEE);
|
||||
if (!dn->pn_cookie.set(cx, pc->staticLevel, UpvarCookie::CALLEE_SLOT))
|
||||
if (!dn->pn_cookie.set(ts, pc->staticLevel, UpvarCookie::CALLEE_SLOT))
|
||||
return false;
|
||||
dn->pn_dflags |= PND_BOUND;
|
||||
JS_ASSERT(dn->kind() == Definition::NAMED_LAMBDA);
|
||||
@ -1302,7 +1309,7 @@ Parser<FullParseHandler>::leaveFunction(ParseNode *fn, HandlePropertyName funNam
|
||||
JS_ASSERT(dn->isPlaceholder());
|
||||
|
||||
if (atom == funName && kind == Expression) {
|
||||
if (!ConvertDefinitionToNamedLambdaUse(context, pc, funbox, dn))
|
||||
if (!ConvertDefinitionToNamedLambdaUse(tokenStream, pc, funbox, dn))
|
||||
return false;
|
||||
continue;
|
||||
}
|
||||
@ -1380,7 +1387,7 @@ Parser<FullParseHandler>::leaveFunction(ParseNode *fn, HandlePropertyName funNam
|
||||
|
||||
InternalHandle<Bindings*> bindings =
|
||||
InternalHandle<Bindings*>::fromMarkedLocation(&funbox->bindings);
|
||||
return pc->generateFunctionBindings(context, bindings);
|
||||
return pc->generateFunctionBindings(context, alloc, bindings);
|
||||
}
|
||||
|
||||
template <>
|
||||
@ -1428,7 +1435,7 @@ Parser<ParseHandler>::defineArg(Node funcpn, HandlePropertyName name,
|
||||
*/
|
||||
if (sc->needStrictChecks()) {
|
||||
JSAutoByteString bytes;
|
||||
if (!js_AtomToPrintableString(context, name, &bytes))
|
||||
if (!AtomToPrintableString(context, name, &bytes))
|
||||
return false;
|
||||
if (!report(ParseStrictError, pc->sc->strict, pn,
|
||||
JSMSG_DUPLICATE_FORMAL, bytes.ptr()))
|
||||
@ -1458,13 +1465,13 @@ Parser<ParseHandler>::defineArg(Node funcpn, HandlePropertyName name,
|
||||
return false;
|
||||
|
||||
handler.addFunctionArgument(funcpn, argpn);
|
||||
return pc->define(context, name, argpn, Definition::ARG);
|
||||
return pc->define(tokenStream, name, argpn, Definition::ARG);
|
||||
}
|
||||
|
||||
#if JS_HAS_DESTRUCTURING
|
||||
template <typename ParseHandler>
|
||||
/* static */ bool
|
||||
Parser<ParseHandler>::bindDestructuringArg(JSContext *cx, BindData<ParseHandler> *data,
|
||||
Parser<ParseHandler>::bindDestructuringArg(BindData<ParseHandler> *data,
|
||||
HandlePropertyName name, Parser<ParseHandler> *parser)
|
||||
{
|
||||
ParseContext<ParseHandler> *pc = parser->pc;
|
||||
@ -1478,7 +1485,7 @@ Parser<ParseHandler>::bindDestructuringArg(JSContext *cx, BindData<ParseHandler>
|
||||
if (!parser->checkStrictBinding(name, data->pn))
|
||||
return false;
|
||||
|
||||
return pc->define(cx, name, data->pn, Definition::VAR);
|
||||
return pc->define(parser->tokenStream, name, data->pn, Definition::VAR);
|
||||
}
|
||||
#endif /* JS_HAS_DESTRUCTURING */
|
||||
|
||||
@ -1569,7 +1576,7 @@ Parser<ParseHandler>::functionArguments(FunctionSyntaxKind kind, Node *listp, No
|
||||
if (!rhs)
|
||||
return false;
|
||||
|
||||
if (!pc->define(context, name, rhs, Definition::ARG))
|
||||
if (!pc->define(tokenStream, name, rhs, Definition::ARG))
|
||||
return false;
|
||||
|
||||
Node item = handler.newBinary(PNK_ASSIGN, lhs, rhs);
|
||||
@ -1676,12 +1683,12 @@ Parser<FullParseHandler>::checkFunctionDefinition(HandlePropertyName funName,
|
||||
JS_ASSERT(!dn->isUsed());
|
||||
JS_ASSERT(dn->isDefn());
|
||||
|
||||
if (context->hasExtraWarningsOption() || dn->kind() == Definition::CONST) {
|
||||
if (options().extraWarningsOption || dn->kind() == Definition::CONST) {
|
||||
JSAutoByteString name;
|
||||
ParseReportKind reporter = (dn->kind() != Definition::CONST)
|
||||
? ParseExtraWarning
|
||||
: ParseError;
|
||||
if (!js_AtomToPrintableString(context, funName, &name) ||
|
||||
if (!AtomToPrintableString(context, funName, &name) ||
|
||||
!report(reporter, false, NULL, JSMSG_REDECLARED_VAR,
|
||||
Definition::kindString(dn->kind()), name.ptr()))
|
||||
{
|
||||
@ -1720,7 +1727,7 @@ Parser<FullParseHandler>::checkFunctionDefinition(HandlePropertyName funName,
|
||||
pn = fn;
|
||||
}
|
||||
|
||||
if (!pc->define(context, funName, pn, Definition::VAR))
|
||||
if (!pc->define(tokenStream, funName, pn, Definition::VAR))
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1865,7 +1872,7 @@ Parser<SyntaxParseHandler>::checkFunctionDefinition(HandlePropertyName funName,
|
||||
if (DefinitionNode dn = pc->decls().lookupFirst(funName)) {
|
||||
if (dn == Definition::CONST) {
|
||||
JSAutoByteString name;
|
||||
if (!js_AtomToPrintableString(context, funName, &name) ||
|
||||
if (!AtomToPrintableString(context, funName, &name) ||
|
||||
!report(ParseError, false, null(), JSMSG_REDECLARED_VAR,
|
||||
Definition::kindString(dn), name.ptr()))
|
||||
{
|
||||
@ -1876,7 +1883,7 @@ Parser<SyntaxParseHandler>::checkFunctionDefinition(HandlePropertyName funName,
|
||||
if (pc->lexdeps.lookupDefn<SyntaxParseHandler>(funName))
|
||||
pc->lexdeps->remove(funName);
|
||||
|
||||
if (!pc->define(context, funName, *pn, Definition::VAR))
|
||||
if (!pc->define(tokenStream, funName, *pn, Definition::VAR))
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -2177,14 +2184,14 @@ Parser<FullParseHandler>::standaloneLazyFunction(HandleFunction fun, unsigned st
|
||||
if (fun->isNamedLambda()) {
|
||||
if (AtomDefnPtr p = pc->lexdeps->lookup(funName)) {
|
||||
Definition *dn = p.value().get<FullParseHandler>();
|
||||
if (!ConvertDefinitionToNamedLambdaUse(context, pc, funbox, dn))
|
||||
if (!ConvertDefinitionToNamedLambdaUse(tokenStream, pc, funbox, dn))
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
InternalHandle<Bindings*> bindings =
|
||||
InternalHandle<Bindings*>::fromMarkedLocation(&funbox->bindings);
|
||||
if (!pc->generateFunctionBindings(context, bindings))
|
||||
if (!pc->generateFunctionBindings(context, alloc, bindings))
|
||||
return null();
|
||||
|
||||
return pn;
|
||||
@ -2267,7 +2274,7 @@ Parser<ParseHandler>::functionArgsAndBodyGeneric(Node pn, HandleFunction fun,
|
||||
if (tokenStream.hadError())
|
||||
return false;
|
||||
funbox->bufEnd = pos().end;
|
||||
if (kind == Statement && !MatchOrInsertSemicolon(context, &tokenStream))
|
||||
if (kind == Statement && !MatchOrInsertSemicolon(tokenStream))
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
@ -2279,7 +2286,7 @@ template <>
|
||||
ParseNode *
|
||||
Parser<FullParseHandler>::moduleDecl()
|
||||
{
|
||||
JS_ASSERT(tokenStream.currentToken().name() == context->runtime()->atomState.module);
|
||||
JS_ASSERT(tokenStream.currentToken().name() == context->names().module);
|
||||
if (!((pc->sc->isGlobalSharedContext() || pc->sc->isModuleBox()) && pc->atBodyLevel()))
|
||||
{
|
||||
report(ParseError, false, NULL, JSMSG_MODULE_STATEMENT);
|
||||
@ -2421,7 +2428,7 @@ Parser<ParseHandler>::maybeParseDirective(Node pn, bool *cont)
|
||||
// in other browsers first.
|
||||
handler.setPrologue(pn);
|
||||
|
||||
if (directive == context->runtime()->atomState.useStrict) {
|
||||
if (directive == context->names().useStrict) {
|
||||
// We're going to be in strict mode. Note that this scope explicitly
|
||||
// had "use strict";
|
||||
pc->sc->setExplicitUseStrict();
|
||||
@ -2531,14 +2538,14 @@ Parser<ParseHandler>::condition()
|
||||
}
|
||||
|
||||
static bool
|
||||
MatchLabel(JSContext *cx, TokenStream *ts, MutableHandlePropertyName label)
|
||||
MatchLabel(TokenStream &ts, MutableHandlePropertyName label)
|
||||
{
|
||||
TokenKind tt = ts->peekTokenSameLine(TSF_OPERAND);
|
||||
TokenKind tt = ts.peekTokenSameLine(TSF_OPERAND);
|
||||
if (tt == TOK_ERROR)
|
||||
return false;
|
||||
if (tt == TOK_NAME) {
|
||||
(void) ts->getToken();
|
||||
label.set(ts->currentToken().name());
|
||||
(void) ts.getToken();
|
||||
label.set(ts.currentToken().name());
|
||||
} else {
|
||||
label.set(NULL);
|
||||
}
|
||||
@ -2550,7 +2557,7 @@ bool
|
||||
Parser<ParseHandler>::reportRedeclaration(Node pn, bool isConst, JSAtom *atom)
|
||||
{
|
||||
JSAutoByteString name;
|
||||
if (js_AtomToPrintableString(context, atom, &name))
|
||||
if (AtomToPrintableString(context, atom, &name))
|
||||
report(ParseError, false, pn, JSMSG_REDECLARED_VAR, isConst ? "const" : "variable", name.ptr());
|
||||
return false;
|
||||
}
|
||||
@ -2566,7 +2573,7 @@ Parser<ParseHandler>::reportRedeclaration(Node pn, bool isConst, JSAtom *atom)
|
||||
*/
|
||||
template <>
|
||||
/* static */ bool
|
||||
Parser<FullParseHandler>::bindLet(JSContext *cx, BindData<FullParseHandler> *data,
|
||||
Parser<FullParseHandler>::bindLet(BindData<FullParseHandler> *data,
|
||||
HandlePropertyName name, Parser<FullParseHandler> *parser)
|
||||
{
|
||||
ParseContext<FullParseHandler> *pc = parser->pc;
|
||||
@ -2574,6 +2581,8 @@ Parser<FullParseHandler>::bindLet(JSContext *cx, BindData<FullParseHandler> *dat
|
||||
if (!parser->checkStrictBinding(name, pn))
|
||||
return false;
|
||||
|
||||
ExclusiveContext *cx = parser->context;
|
||||
|
||||
Rooted<StaticBlockObject *> blockObj(cx, data->let.blockObj);
|
||||
unsigned blockCount = blockObj->slotCount();
|
||||
if (blockCount == JS_BIT(16)) {
|
||||
@ -2588,7 +2597,7 @@ Parser<FullParseHandler>::bindLet(JSContext *cx, BindData<FullParseHandler> *dat
|
||||
* and eval code, js::frontend::CompileScript will adjust the slot
|
||||
* again to include script->nfixed.
|
||||
*/
|
||||
if (!pn->pn_cookie.set(parser->context, pc->staticLevel, uint16_t(blockCount)))
|
||||
if (!pn->pn_cookie.set(parser->tokenStream, pc->staticLevel, uint16_t(blockCount)))
|
||||
return false;
|
||||
|
||||
/*
|
||||
@ -2600,7 +2609,7 @@ Parser<FullParseHandler>::bindLet(JSContext *cx, BindData<FullParseHandler> *dat
|
||||
Definition *dn = pc->decls().lookupFirst(name);
|
||||
if (dn && dn->pn_blockid == pc->blockid())
|
||||
return parser->reportRedeclaration(pn, dn->isConst(), name);
|
||||
if (!pc->define(cx, name, pn, Definition::LET))
|
||||
if (!pc->define(parser->tokenStream, name, pn, Definition::LET))
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -2624,7 +2633,7 @@ Parser<FullParseHandler>::bindLet(JSContext *cx, BindData<FullParseHandler> *dat
|
||||
|
||||
template <>
|
||||
/* static */ bool
|
||||
Parser<SyntaxParseHandler>::bindLet(JSContext *cx, BindData<SyntaxParseHandler> *data,
|
||||
Parser<SyntaxParseHandler>::bindLet(BindData<SyntaxParseHandler> *data,
|
||||
HandlePropertyName name, Parser<SyntaxParseHandler> *parser)
|
||||
{
|
||||
return true;
|
||||
@ -2632,17 +2641,17 @@ Parser<SyntaxParseHandler>::bindLet(JSContext *cx, BindData<SyntaxParseHandler>
|
||||
|
||||
template <typename ParseHandler, class Op>
|
||||
static inline bool
|
||||
ForEachLetDef(JSContext *cx, ParseContext<ParseHandler> *pc,
|
||||
ForEachLetDef(TokenStream &ts, ParseContext<ParseHandler> *pc,
|
||||
HandleStaticBlockObject blockObj, Op op)
|
||||
{
|
||||
for (Shape::Range<CanGC> r(cx, blockObj->lastProperty()); !r.empty(); r.popFront()) {
|
||||
for (Shape::Range<CanGC> r(ts.context(), blockObj->lastProperty()); !r.empty(); r.popFront()) {
|
||||
Shape &shape = r.front();
|
||||
|
||||
/* Beware the destructuring dummy slots. */
|
||||
if (JSID_IS_INT(shape.propid()))
|
||||
continue;
|
||||
|
||||
if (!op(cx, pc, blockObj, shape, JSID_TO_ATOM(shape.propid())))
|
||||
if (!op(ts, pc, blockObj, shape, JSID_TO_ATOM(shape.propid())))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@ -2650,7 +2659,7 @@ ForEachLetDef(JSContext *cx, ParseContext<ParseHandler> *pc,
|
||||
|
||||
template <typename ParseHandler>
|
||||
struct PopLetDecl {
|
||||
bool operator()(JSContext *, ParseContext<ParseHandler> *pc, HandleStaticBlockObject,
|
||||
bool operator()(TokenStream &, ParseContext<ParseHandler> *pc, HandleStaticBlockObject,
|
||||
const Shape &, JSAtom *atom)
|
||||
{
|
||||
pc->popLetDecl(atom);
|
||||
@ -2660,16 +2669,16 @@ struct PopLetDecl {
|
||||
|
||||
template <typename ParseHandler>
|
||||
static void
|
||||
PopStatementPC(JSContext *cx, ParseContext<ParseHandler> *pc)
|
||||
PopStatementPC(TokenStream &ts, ParseContext<ParseHandler> *pc)
|
||||
{
|
||||
RootedStaticBlockObject blockObj(cx, pc->topStmt->blockObj);
|
||||
RootedStaticBlockObject blockObj(ts.context(), pc->topStmt->blockObj);
|
||||
JS_ASSERT(!!blockObj == (pc->topStmt->isBlockScope));
|
||||
|
||||
FinishPopStatement(pc);
|
||||
|
||||
if (blockObj) {
|
||||
JS_ASSERT(!blockObj->inDictionaryMode());
|
||||
ForEachLetDef(cx, pc, blockObj, PopLetDecl<ParseHandler>());
|
||||
ForEachLetDef(ts, pc, blockObj, PopLetDecl<ParseHandler>());
|
||||
blockObj->resetPrevBlockChainFromParser();
|
||||
}
|
||||
}
|
||||
@ -2735,9 +2744,10 @@ OuterLet(ParseContext<ParseHandler> *pc, StmtInfoPC *stmt, HandleAtom atom)
|
||||
|
||||
template <typename ParseHandler>
|
||||
/* static */ bool
|
||||
Parser<ParseHandler>::bindVarOrConst(JSContext *cx, BindData<ParseHandler> *data,
|
||||
Parser<ParseHandler>::bindVarOrConst(BindData<ParseHandler> *data,
|
||||
HandlePropertyName name, Parser<ParseHandler> *parser)
|
||||
{
|
||||
ExclusiveContext *cx = parser->context;
|
||||
ParseContext<ParseHandler> *pc = parser->pc;
|
||||
Node pn = data->pn;
|
||||
bool isConstDecl = data->op == JSOP_DEFCONST;
|
||||
@ -2772,8 +2782,10 @@ Parser<ParseHandler>::bindVarOrConst(JSContext *cx, BindData<ParseHandler> *data
|
||||
DefinitionList::Range defs = pc->decls().lookupMulti(name);
|
||||
JS_ASSERT_IF(stmt, !defs.empty());
|
||||
|
||||
if (defs.empty())
|
||||
return pc->define(cx, name, pn, isConstDecl ? Definition::CONST : Definition::VAR);
|
||||
if (defs.empty()) {
|
||||
return pc->define(parser->tokenStream, name, pn,
|
||||
isConstDecl ? Definition::CONST : Definition::VAR);
|
||||
}
|
||||
|
||||
/*
|
||||
* There was a previous declaration with the same name. The standard
|
||||
@ -2786,7 +2798,7 @@ Parser<ParseHandler>::bindVarOrConst(JSContext *cx, BindData<ParseHandler> *data
|
||||
Definition::Kind dn_kind = parser->handler.getDefinitionKind(dn);
|
||||
if (dn_kind == Definition::ARG) {
|
||||
JSAutoByteString bytes;
|
||||
if (!js_AtomToPrintableString(cx, name, &bytes))
|
||||
if (!AtomToPrintableString(cx, name, &bytes))
|
||||
return false;
|
||||
|
||||
if (isConstDecl) {
|
||||
@ -2801,13 +2813,13 @@ Parser<ParseHandler>::bindVarOrConst(JSContext *cx, BindData<ParseHandler> *data
|
||||
(dn_kind == Definition::LET &&
|
||||
(stmt->type != STMT_CATCH || OuterLet(pc, stmt, name))));
|
||||
|
||||
if (cx->hasExtraWarningsOption()
|
||||
if (parser->options().extraWarningsOption
|
||||
? data->op != JSOP_DEFVAR || dn_kind != Definition::VAR
|
||||
: error)
|
||||
{
|
||||
JSAutoByteString bytes;
|
||||
ParseReportKind reporter = error ? ParseError : ParseExtraWarning;
|
||||
if (!js_AtomToPrintableString(cx, name, &bytes) ||
|
||||
if (!AtomToPrintableString(cx, name, &bytes) ||
|
||||
!parser->report(reporter, false, pn, JSMSG_REDECLARED_VAR,
|
||||
Definition::kindString(dn_kind), bytes.ptr()))
|
||||
{
|
||||
@ -2879,7 +2891,7 @@ Parser<FullParseHandler>::bindDestructuringVar(BindData<FullParseHandler> *data,
|
||||
RootedPropertyName name(context, pn->pn_atom->asPropertyName());
|
||||
|
||||
data->pn = pn;
|
||||
if (!data->binder(context, data, name, this))
|
||||
if (!data->binder(data, name, this))
|
||||
return false;
|
||||
|
||||
/*
|
||||
@ -3164,13 +3176,13 @@ struct AddLetDecl
|
||||
|
||||
AddLetDecl(uint32_t blockid) : blockid(blockid) {}
|
||||
|
||||
bool operator()(JSContext *cx, ParseContext<FullParseHandler> *pc,
|
||||
bool operator()(TokenStream &ts, ParseContext<FullParseHandler> *pc,
|
||||
HandleStaticBlockObject blockObj, const Shape &shape, JSAtom *)
|
||||
{
|
||||
ParseNode *def = (ParseNode *) blockObj->getSlot(shape.slot()).toPrivate();
|
||||
def->pn_blockid = blockid;
|
||||
RootedPropertyName name(cx, def->name());
|
||||
return pc->define(cx, name, def, Definition::LET);
|
||||
RootedPropertyName name(ts.context(), def->name());
|
||||
return pc->define(ts, name, def, Definition::LET);
|
||||
}
|
||||
};
|
||||
|
||||
@ -3187,7 +3199,7 @@ Parser<FullParseHandler>::pushLetScope(HandleStaticBlockObject blockObj, StmtInf
|
||||
pn->pn_dflags |= PND_LET;
|
||||
|
||||
/* Populate the new scope with decls found in the head with updated blockid. */
|
||||
if (!ForEachLetDef(context, pc, blockObj, AddLetDecl(stmt->blockid)))
|
||||
if (!ForEachLetDef(tokenStream, pc, blockObj, AddLetDecl(stmt->blockid)))
|
||||
return null();
|
||||
|
||||
return pn;
|
||||
@ -3274,12 +3286,12 @@ Parser<ParseHandler>::letBlock(LetContext letContext)
|
||||
return null();
|
||||
}
|
||||
handler.setLeaveBlockResult(block, expr, letContext != LetStatement);
|
||||
PopStatementPC(context, pc);
|
||||
PopStatementPC(tokenStream, pc);
|
||||
|
||||
handler.setEndPosition(pnlet, pos().end);
|
||||
|
||||
if (needExprStmt) {
|
||||
if (!MatchOrInsertSemicolon(context, &tokenStream))
|
||||
if (!MatchOrInsertSemicolon(tokenStream))
|
||||
return null();
|
||||
return handler.newExprStatement(pnlet, pos().end);
|
||||
}
|
||||
@ -3311,7 +3323,7 @@ Parser<ParseHandler>::blockStatement()
|
||||
return null();
|
||||
|
||||
MUST_MATCH_TOKEN(TOK_RC, JSMSG_CURLY_IN_COMPOUND);
|
||||
PopStatementPC(context, pc);
|
||||
PopStatementPC(tokenStream, pc);
|
||||
return list;
|
||||
}
|
||||
|
||||
@ -3443,7 +3455,7 @@ Parser<ParseHandler>::variables(ParseNodeKind kind, bool *psimple,
|
||||
if (data.op == JSOP_DEFCONST)
|
||||
handler.setFlag(pn2, PND_CONST);
|
||||
data.pn = pn2;
|
||||
if (!data.binder(context, &data, name, this))
|
||||
if (!data.binder(&data, name, this))
|
||||
return null();
|
||||
handler.addList(pn, pn2);
|
||||
|
||||
@ -3574,7 +3586,7 @@ Parser<FullParseHandler>::letStatement()
|
||||
} while (0);
|
||||
|
||||
/* Check termination of this primitive statement. */
|
||||
return MatchOrInsertSemicolon(context, &tokenStream) ? pn : NULL;
|
||||
return MatchOrInsertSemicolon(tokenStream) ? pn : NULL;
|
||||
}
|
||||
|
||||
template <>
|
||||
@ -3595,7 +3607,7 @@ Parser<ParseHandler>::expressionStatement()
|
||||
Node pnexpr = expr();
|
||||
if (!pnexpr)
|
||||
return null();
|
||||
if (!MatchOrInsertSemicolon(context, &tokenStream))
|
||||
if (!MatchOrInsertSemicolon(tokenStream))
|
||||
return null();
|
||||
return handler.newExprStatement(pnexpr, pos().end);
|
||||
}
|
||||
@ -3633,7 +3645,7 @@ Parser<ParseHandler>::ifStatement()
|
||||
elseBranch = null();
|
||||
}
|
||||
|
||||
PopStatementPC(context, pc);
|
||||
PopStatementPC(tokenStream, pc);
|
||||
return handler.newIfStatement(begin, cond, thenBranch, elseBranch);
|
||||
}
|
||||
|
||||
@ -3651,12 +3663,12 @@ Parser<ParseHandler>::doWhileStatement()
|
||||
Node cond = condition();
|
||||
if (!cond)
|
||||
return null();
|
||||
PopStatementPC(context, pc);
|
||||
PopStatementPC(tokenStream, pc);
|
||||
|
||||
if (versionNumber() == JSVERSION_ECMA_3) {
|
||||
// Pedantically require a semicolon or line break, following ES3.
|
||||
// Bug 880329 proposes removing this case.
|
||||
if (!MatchOrInsertSemicolon(context, &tokenStream))
|
||||
if (!MatchOrInsertSemicolon(tokenStream))
|
||||
return null();
|
||||
} else {
|
||||
// The semicolon after do-while is even more optional than most
|
||||
@ -3683,7 +3695,7 @@ Parser<ParseHandler>::whileStatement()
|
||||
Node body = statement();
|
||||
if (!body)
|
||||
return null();
|
||||
PopStatementPC(context, pc);
|
||||
PopStatementPC(tokenStream, pc);
|
||||
return handler.newWhileStatement(begin, cond, body);
|
||||
}
|
||||
|
||||
@ -4049,9 +4061,9 @@ Parser<FullParseHandler>::forStatement()
|
||||
|
||||
#if JS_HAS_BLOCK_SCOPE
|
||||
if (blockObj)
|
||||
PopStatementPC(context, pc);
|
||||
PopStatementPC(tokenStream, pc);
|
||||
#endif
|
||||
PopStatementPC(context, pc);
|
||||
PopStatementPC(tokenStream, pc);
|
||||
|
||||
ParseNode *forLoop = handler.newForStatement(begin, forHead, body, iflags);
|
||||
if (!forLoop)
|
||||
@ -4187,7 +4199,7 @@ Parser<SyntaxParseHandler>::forStatement()
|
||||
if (!statement())
|
||||
return null();
|
||||
|
||||
PopStatementPC(context, pc);
|
||||
PopStatementPC(tokenStream, pc);
|
||||
return SyntaxParseHandler::NodeGeneric;
|
||||
}
|
||||
|
||||
@ -4282,7 +4294,7 @@ Parser<ParseHandler>::switchStatement()
|
||||
caseList = pc->blockNode;
|
||||
pc->blockNode = saveBlock;
|
||||
|
||||
PopStatementPC(context, pc);
|
||||
PopStatementPC(tokenStream, pc);
|
||||
|
||||
handler.setEndPosition(caseList, pos().end);
|
||||
|
||||
@ -4297,7 +4309,7 @@ Parser<ParseHandler>::continueStatement()
|
||||
uint32_t begin = pos().begin;
|
||||
|
||||
RootedPropertyName label(context);
|
||||
if (!MatchLabel(context, &tokenStream, &label))
|
||||
if (!MatchLabel(tokenStream, &label))
|
||||
return null();
|
||||
|
||||
StmtInfoPC *stmt = pc->topStmt;
|
||||
@ -4330,7 +4342,7 @@ Parser<ParseHandler>::continueStatement()
|
||||
}
|
||||
}
|
||||
|
||||
if (!MatchOrInsertSemicolon(context, &tokenStream))
|
||||
if (!MatchOrInsertSemicolon(tokenStream))
|
||||
return null();
|
||||
|
||||
return handler.newContinueStatement(label, TokenPos(begin, pos().end));
|
||||
@ -4344,7 +4356,7 @@ Parser<ParseHandler>::breakStatement()
|
||||
uint32_t begin = pos().begin;
|
||||
|
||||
RootedPropertyName label(context);
|
||||
if (!MatchLabel(context, &tokenStream, &label))
|
||||
if (!MatchLabel(tokenStream, &label))
|
||||
return null();
|
||||
StmtInfoPC *stmt = pc->topStmt;
|
||||
if (label) {
|
||||
@ -4367,7 +4379,7 @@ Parser<ParseHandler>::breakStatement()
|
||||
}
|
||||
}
|
||||
|
||||
if (!MatchOrInsertSemicolon(context, &tokenStream))
|
||||
if (!MatchOrInsertSemicolon(tokenStream))
|
||||
return null();
|
||||
|
||||
return handler.newBreakStatement(label, TokenPos(begin, pos().end));
|
||||
@ -4435,7 +4447,7 @@ Parser<ParseHandler>::returnStatementOrYieldExpression()
|
||||
}
|
||||
|
||||
if (!isYield) {
|
||||
if (!MatchOrInsertSemicolon(context, &tokenStream))
|
||||
if (!MatchOrInsertSemicolon(tokenStream))
|
||||
return null();
|
||||
}
|
||||
|
||||
@ -4452,7 +4464,7 @@ Parser<ParseHandler>::returnStatementOrYieldExpression()
|
||||
return null();
|
||||
}
|
||||
|
||||
if (context->hasExtraWarningsOption() && pc->funHasReturnExpr && pc->funHasReturnVoid &&
|
||||
if (options().extraWarningsOption && pc->funHasReturnExpr && pc->funHasReturnVoid &&
|
||||
!reportBadReturn(pn, ParseExtraWarning,
|
||||
JSMSG_NO_RETURN_VALUE, JSMSG_ANON_NO_RETURN_VALUE))
|
||||
{
|
||||
@ -4498,7 +4510,7 @@ Parser<FullParseHandler>::withStatement()
|
||||
Node innerBlock = statement();
|
||||
if (!innerBlock)
|
||||
return null();
|
||||
PopStatementPC(context, pc);
|
||||
PopStatementPC(tokenStream, pc);
|
||||
|
||||
pc->sc->setBindingsAccessedDynamically();
|
||||
pc->parsingWith = oldParsingWith;
|
||||
@ -4548,7 +4560,7 @@ Parser<ParseHandler>::labeledStatement()
|
||||
return null();
|
||||
|
||||
/* Pop the label, set pn_expr, and return early. */
|
||||
PopStatementPC(context, pc);
|
||||
PopStatementPC(tokenStream, pc);
|
||||
|
||||
return handler.newLabeledStatement(label, pn, begin);
|
||||
}
|
||||
@ -4573,7 +4585,7 @@ Parser<ParseHandler>::throwStatement()
|
||||
if (!throwExpr)
|
||||
return null();
|
||||
|
||||
if (!MatchOrInsertSemicolon(context, &tokenStream))
|
||||
if (!MatchOrInsertSemicolon(tokenStream))
|
||||
return null();
|
||||
|
||||
return handler.newThrowStatement(throwExpr, TokenPos(begin, pos().end));
|
||||
@ -4612,7 +4624,7 @@ Parser<ParseHandler>::tryStatement()
|
||||
if (!innerBlock)
|
||||
return null();
|
||||
MUST_MATCH_TOKEN(TOK_RC, JSMSG_CURLY_AFTER_TRY);
|
||||
PopStatementPC(context, pc);
|
||||
PopStatementPC(tokenStream, pc);
|
||||
|
||||
bool hasUnconditionalCatch = false;
|
||||
Node catchList = null();
|
||||
@ -4677,7 +4689,7 @@ Parser<ParseHandler>::tryStatement()
|
||||
if (!catchName)
|
||||
return null();
|
||||
data.pn = catchName;
|
||||
if (!data.binder(context, &data, label, this))
|
||||
if (!data.binder(&data, label, this))
|
||||
return null();
|
||||
break;
|
||||
}
|
||||
@ -4707,7 +4719,7 @@ Parser<ParseHandler>::tryStatement()
|
||||
if (!catchBody)
|
||||
return null();
|
||||
MUST_MATCH_TOKEN(TOK_RC, JSMSG_CURLY_AFTER_CATCH);
|
||||
PopStatementPC(context, pc);
|
||||
PopStatementPC(tokenStream, pc);
|
||||
|
||||
if (!catchGuard)
|
||||
hasUnconditionalCatch = true;
|
||||
@ -4731,7 +4743,7 @@ Parser<ParseHandler>::tryStatement()
|
||||
if (!finallyBlock)
|
||||
return null();
|
||||
MUST_MATCH_TOKEN(TOK_RC, JSMSG_CURLY_AFTER_FINALLY);
|
||||
PopStatementPC(context, pc);
|
||||
PopStatementPC(tokenStream, pc);
|
||||
} else {
|
||||
tokenStream.ungetToken();
|
||||
}
|
||||
@ -4749,7 +4761,7 @@ Parser<ParseHandler>::debuggerStatement()
|
||||
{
|
||||
TokenPos p;
|
||||
p.begin = pos().begin;
|
||||
if (!MatchOrInsertSemicolon(context, &tokenStream))
|
||||
if (!MatchOrInsertSemicolon(tokenStream))
|
||||
return null();
|
||||
p.end = pos().end;
|
||||
|
||||
@ -4860,7 +4872,7 @@ Parser<ParseHandler>::statement(bool canHaveDirectives)
|
||||
}
|
||||
|
||||
/* Check termination of this primitive statement. */
|
||||
return MatchOrInsertSemicolon(context, &tokenStream) ? pn : null();
|
||||
return MatchOrInsertSemicolon(tokenStream) ? pn : null();
|
||||
}
|
||||
|
||||
template <>
|
||||
@ -5514,23 +5526,23 @@ GenexpGuard<ParseHandler>::maybeNoteGenerator(Node pn)
|
||||
*/
|
||||
template <typename ParseHandler>
|
||||
static bool
|
||||
BumpStaticLevel(ParseNode *pn, ParseContext<ParseHandler> *pc)
|
||||
BumpStaticLevel(TokenStream &ts, ParseNode *pn, ParseContext<ParseHandler> *pc)
|
||||
{
|
||||
if (pn->pn_cookie.isFree())
|
||||
return true;
|
||||
|
||||
unsigned level = unsigned(pn->pn_cookie.level()) + 1;
|
||||
JS_ASSERT(level >= pc->staticLevel);
|
||||
return pn->pn_cookie.set(pc->sc->context, level, pn->pn_cookie.slot());
|
||||
return pn->pn_cookie.set(ts, level, pn->pn_cookie.slot());
|
||||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
static bool
|
||||
AdjustBlockId(ParseNode *pn, unsigned adjust, ParseContext<ParseHandler> *pc)
|
||||
AdjustBlockId(TokenStream &ts, ParseNode *pn, unsigned adjust, ParseContext<ParseHandler> *pc)
|
||||
{
|
||||
JS_ASSERT(pn->isArity(PN_LIST) || pn->isArity(PN_CODE) || pn->isArity(PN_NAME));
|
||||
if (JS_BIT(20) - pn->pn_blockid <= adjust + 1) {
|
||||
JS_ReportErrorNumber(pc->sc->context, js_GetErrorMessage, NULL, JSMSG_NEED_DIET, "program");
|
||||
ts.reportError(JSMSG_NEED_DIET, "program");
|
||||
return false;
|
||||
}
|
||||
pn->pn_blockid += adjust;
|
||||
@ -5554,7 +5566,7 @@ CompExprTransplanter::transplant(ParseNode *pn)
|
||||
return false;
|
||||
}
|
||||
if (pn->pn_pos >= root->pn_pos) {
|
||||
if (!AdjustBlockId(pn, adjust, pc))
|
||||
if (!AdjustBlockId(parser->tokenStream, pn, adjust, pc))
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
@ -5588,7 +5600,7 @@ CompExprTransplanter::transplant(ParseNode *pn)
|
||||
return false;
|
||||
|
||||
if (pn->isDefn()) {
|
||||
if (genexp && !BumpStaticLevel(pn, pc))
|
||||
if (genexp && !BumpStaticLevel(parser->tokenStream, pn, pc))
|
||||
return false;
|
||||
} else if (pn->isUsed()) {
|
||||
JS_ASSERT(pn->pn_cookie.isFree());
|
||||
@ -5606,9 +5618,9 @@ CompExprTransplanter::transplant(ParseNode *pn)
|
||||
* will be visited further below.
|
||||
*/
|
||||
if (dn->isPlaceholder() && dn->pn_pos >= root->pn_pos && dn->dn_uses == pn) {
|
||||
if (genexp && !BumpStaticLevel(dn, pc))
|
||||
if (genexp && !BumpStaticLevel(parser->tokenStream, dn, pc))
|
||||
return false;
|
||||
if (!AdjustBlockId(dn, adjust, pc))
|
||||
if (!AdjustBlockId(parser->tokenStream, dn, adjust, pc))
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -5673,9 +5685,9 @@ CompExprTransplanter::transplant(ParseNode *pn)
|
||||
* to only bump the definition once.
|
||||
*/
|
||||
if (genexp && !visitedImplicitArguments.has(dn)) {
|
||||
if (!BumpStaticLevel(dn, pc))
|
||||
if (!BumpStaticLevel(parser->tokenStream, dn, pc))
|
||||
return false;
|
||||
if (!AdjustBlockId(dn, adjust, pc))
|
||||
if (!AdjustBlockId(parser->tokenStream, dn, adjust, pc))
|
||||
return false;
|
||||
if (!visitedImplicitArguments.put(dn))
|
||||
return false;
|
||||
@ -5685,7 +5697,7 @@ CompExprTransplanter::transplant(ParseNode *pn)
|
||||
}
|
||||
|
||||
if (pn->pn_pos >= root->pn_pos) {
|
||||
if (!AdjustBlockId(pn, adjust, pc))
|
||||
if (!AdjustBlockId(parser->tokenStream, pn, adjust, pc))
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
@ -5891,7 +5903,7 @@ Parser<FullParseHandler>::comprehensionTail(ParseNode *kid, unsigned blockid, bo
|
||||
|
||||
case TOK_NAME:
|
||||
data.pn = pn3;
|
||||
if (!data.binder(context, &data, name, this))
|
||||
if (!data.binder(&data, name, this))
|
||||
return null();
|
||||
break;
|
||||
|
||||
@ -5940,7 +5952,7 @@ Parser<FullParseHandler>::comprehensionTail(ParseNode *kid, unsigned blockid, bo
|
||||
pn2->pn_kid = kid;
|
||||
*pnp = pn2;
|
||||
|
||||
PopStatementPC(context, pc);
|
||||
PopStatementPC(tokenStream, pc);
|
||||
return pn;
|
||||
}
|
||||
|
||||
@ -6660,7 +6672,7 @@ Parser<ParseHandler>::primaryExpr(TokenKind tt)
|
||||
(oldAssignType != VALUE || assignType != VALUE || pc->sc->needStrictChecks()))
|
||||
{
|
||||
JSAutoByteString name;
|
||||
if (!js_AtomToPrintableString(context, atom, &name))
|
||||
if (!AtomToPrintableString(context, atom, &name))
|
||||
return null();
|
||||
|
||||
ParseReportKind reportKind =
|
||||
|
@ -29,7 +29,7 @@ struct StmtInfoPC : public StmtInfoBase {
|
||||
|
||||
uint32_t blockid; /* for simplified dominance computation */
|
||||
|
||||
StmtInfoPC(JSContext *cx) : StmtInfoBase(cx) {}
|
||||
StmtInfoPC(ExclusiveContext *cx) : StmtInfoBase(cx) {}
|
||||
};
|
||||
|
||||
typedef HashSet<JSAtom *> FuncStmtSet;
|
||||
@ -155,7 +155,7 @@ struct ParseContext : public GenericParseContext
|
||||
* 'pn' if they are in the scope of 'pn'.
|
||||
* + Pre-existing placeholders in the scope of 'pn' have been removed.
|
||||
*/
|
||||
bool define(JSContext *cx, HandlePropertyName name, Node pn, Definition::Kind);
|
||||
bool define(TokenStream &ts, PropertyName *name, Node pn, Definition::Kind);
|
||||
|
||||
/*
|
||||
* Let definitions may shadow same-named definitions in enclosing scopes.
|
||||
@ -187,7 +187,8 @@ struct ParseContext : public GenericParseContext
|
||||
* - Sometimes a script's bindings are accessed at runtime to retrieve the
|
||||
* contents of the lexical scope (e.g., from the debugger).
|
||||
*/
|
||||
bool generateFunctionBindings(JSContext *cx, InternalHandle<Bindings*> bindings) const;
|
||||
bool generateFunctionBindings(ExclusiveContext *cx, LifoAlloc &alloc,
|
||||
InternalHandle<Bindings*> bindings) const;
|
||||
|
||||
public:
|
||||
uint32_t yieldOffset; /* offset of a yield expression that might
|
||||
@ -240,7 +241,7 @@ struct ParseContext : public GenericParseContext
|
||||
parenDepth(0),
|
||||
yieldCount(0),
|
||||
blockNode(ParseHandler::null()),
|
||||
decls_(prs->context),
|
||||
decls_(prs->context, prs->alloc),
|
||||
args_(prs->context),
|
||||
vars_(prs->context),
|
||||
yieldOffset(0),
|
||||
@ -304,7 +305,9 @@ template <typename ParseHandler>
|
||||
class Parser : private AutoGCRooter, public StrictModeGetter
|
||||
{
|
||||
public:
|
||||
JSContext *const context; /* FIXME Bug 551291: use AutoGCRooter::context? */
|
||||
ExclusiveContext *const context;
|
||||
LifoAlloc &alloc;
|
||||
|
||||
TokenStream tokenStream;
|
||||
LifoAlloc::Mark tempPoolMark;
|
||||
|
||||
@ -323,25 +326,6 @@ class Parser : private AutoGCRooter, public StrictModeGetter
|
||||
const bool foldConstants:1;
|
||||
|
||||
private:
|
||||
/* Script can optimize name references based on scope chain. */
|
||||
const bool compileAndGo:1;
|
||||
|
||||
/*
|
||||
* In self-hosting mode, scripts emit JSOP_CALLINTRINSIC instead of
|
||||
* JSOP_NAME or JSOP_GNAME to access unbound variables. JSOP_CALLINTRINSIC
|
||||
* does a name lookup in a special object that contains properties
|
||||
* installed during global initialization and that properties from
|
||||
* self-hosted scripts get copied into lazily upon first access in a
|
||||
* global.
|
||||
* As that object is inaccessible to client code, the lookups are
|
||||
* guaranteed to return the original objects, ensuring safe implementation
|
||||
* of self-hosted builtins.
|
||||
* Additionally, the special syntax _CallFunction(receiver, ...args, fun)
|
||||
* is supported, for which bytecode is emitted that invokes |fun| with
|
||||
* |receiver| as the this-object and ...args as the arguments..
|
||||
*/
|
||||
const bool selfHostingMode:1;
|
||||
|
||||
/*
|
||||
* Not all language constructs can be handled during syntax parsing. If it
|
||||
* is not known whether the parse succeeds or fails, this bit is set and
|
||||
@ -364,7 +348,7 @@ class Parser : private AutoGCRooter, public StrictModeGetter
|
||||
bool reportWithOffset(ParseReportKind kind, bool strict, uint32_t offset, unsigned errorNumber,
|
||||
...);
|
||||
|
||||
Parser(JSContext *cx, const CompileOptions &options,
|
||||
Parser(ExclusiveContext *cx, LifoAlloc *alloc, const CompileOptions &options,
|
||||
const jschar *chars, size_t length, bool foldConstants,
|
||||
Parser<SyntaxParseHandler> *syntaxParser,
|
||||
LazyScript *lazyOuterFunction);
|
||||
@ -439,6 +423,10 @@ class Parser : private AutoGCRooter, public StrictModeGetter
|
||||
|
||||
virtual bool strictMode() { return pc->sc->strict; }
|
||||
|
||||
const CompileOptions &options() const {
|
||||
return tokenStream.options();
|
||||
}
|
||||
|
||||
private:
|
||||
/*
|
||||
* JS parsers, from lowest to highest precedence.
|
||||
@ -563,15 +551,15 @@ class Parser : private AutoGCRooter, public StrictModeGetter
|
||||
}
|
||||
|
||||
static bool
|
||||
bindDestructuringArg(JSContext *cx, BindData<ParseHandler> *data,
|
||||
bindDestructuringArg(BindData<ParseHandler> *data,
|
||||
HandlePropertyName name, Parser<ParseHandler> *parser);
|
||||
|
||||
static bool
|
||||
bindLet(JSContext *cx, BindData<ParseHandler> *data,
|
||||
bindLet(BindData<ParseHandler> *data,
|
||||
HandlePropertyName name, Parser<ParseHandler> *parser);
|
||||
|
||||
static bool
|
||||
bindVarOrConst(JSContext *cx, BindData<ParseHandler> *data,
|
||||
bindVarOrConst(BindData<ParseHandler> *data,
|
||||
HandlePropertyName name, Parser<ParseHandler> *parser);
|
||||
|
||||
static Node null() { return ParseHandler::null(); }
|
||||
|
@ -16,7 +16,7 @@ namespace frontend {
|
||||
inline bool
|
||||
SharedContext::needStrictChecks()
|
||||
{
|
||||
return context->hasExtraWarningsOption() || strict;
|
||||
return strict || extraWarnings;
|
||||
}
|
||||
|
||||
} /* namespace frontend */
|
||||
|
@ -149,16 +149,18 @@ class GlobalSharedContext;
|
||||
class SharedContext
|
||||
{
|
||||
public:
|
||||
JSContext *const context;
|
||||
ExclusiveContext *const context;
|
||||
AnyContextFlags anyCxFlags;
|
||||
bool strict;
|
||||
bool extraWarnings;
|
||||
|
||||
// If it's function code, funbox must be non-NULL and scopeChain must be NULL.
|
||||
// If it's global code, funbox must be NULL.
|
||||
SharedContext(JSContext *cx, bool strict)
|
||||
SharedContext(ExclusiveContext *cx, bool strict, bool extraWarnings)
|
||||
: context(cx),
|
||||
anyCxFlags(),
|
||||
strict(strict)
|
||||
strict(strict),
|
||||
extraWarnings(extraWarnings)
|
||||
{}
|
||||
|
||||
virtual ObjectBox *toObjectBox() = 0;
|
||||
@ -187,8 +189,9 @@ class GlobalSharedContext : public SharedContext
|
||||
const RootedObject scopeChain_; /* scope chain object for the script */
|
||||
|
||||
public:
|
||||
GlobalSharedContext(JSContext *cx, JSObject *scopeChain, bool strict)
|
||||
: SharedContext(cx, strict),
|
||||
GlobalSharedContext(ExclusiveContext *cx, JSObject *scopeChain,
|
||||
bool strict, bool extraWarnings)
|
||||
: SharedContext(cx, strict, extraWarnings),
|
||||
scopeChain_(cx, scopeChain)
|
||||
{}
|
||||
|
||||
@ -208,8 +211,8 @@ class ModuleBox : public ObjectBox, public SharedContext
|
||||
public:
|
||||
Bindings bindings;
|
||||
|
||||
ModuleBox(JSContext *cx, ObjectBox *traceListHead, Module *module,
|
||||
ParseContext<FullParseHandler> *pc);
|
||||
ModuleBox(ExclusiveContext *cx, ObjectBox *traceListHead, Module *module,
|
||||
ParseContext<FullParseHandler> *pc, bool extraWarnings);
|
||||
ObjectBox *toObjectBox() { return this; }
|
||||
Module *module() const { return &object->as<Module>(); }
|
||||
};
|
||||
@ -243,8 +246,9 @@ class FunctionBox : public ObjectBox, public SharedContext
|
||||
FunctionContextFlags funCxFlags;
|
||||
|
||||
template <typename ParseHandler>
|
||||
FunctionBox(JSContext *cx, ObjectBox* traceListHead, JSFunction *fun, ParseContext<ParseHandler> *pc,
|
||||
bool strict);
|
||||
FunctionBox(ExclusiveContext *cx, ObjectBox* traceListHead, JSFunction *fun,
|
||||
ParseContext<ParseHandler> *pc,
|
||||
bool strict, bool extraWarnings);
|
||||
|
||||
ObjectBox *toObjectBox() { return this; }
|
||||
JSFunction *function() const { return &object->as<JSFunction>(); }
|
||||
@ -361,7 +365,7 @@ struct StmtInfoBase {
|
||||
RootedAtom label; /* name of LABEL */
|
||||
Rooted<StaticBlockObject *> blockObj; /* block scope object */
|
||||
|
||||
StmtInfoBase(JSContext *cx)
|
||||
StmtInfoBase(ExclusiveContext *cx)
|
||||
: isBlockScope(false), isForLetBlock(false), label(cx), blockObj(cx)
|
||||
{}
|
||||
|
||||
|
@ -42,7 +42,8 @@ class SyntaxParseHandler
|
||||
};
|
||||
typedef Definition::Kind DefinitionNode;
|
||||
|
||||
SyntaxParseHandler(JSContext *cx, TokenStream &tokenStream, bool foldConstants,
|
||||
SyntaxParseHandler(ExclusiveContext *cx, LifoAlloc &alloc,
|
||||
TokenStream &tokenStream, bool foldConstants,
|
||||
Parser<SyntaxParseHandler> *syntaxParser, LazyScript *lazyOuterFunction)
|
||||
: lastAtom(NULL),
|
||||
tokenStream(tokenStream)
|
||||
|
@ -117,7 +117,7 @@ frontend::IsKeyword(JSLinearString *str)
|
||||
return FindKeyword(str->chars(), str->length()) != NULL;
|
||||
}
|
||||
|
||||
TokenStream::SourceCoords::SourceCoords(JSContext *cx, uint32_t ln)
|
||||
TokenStream::SourceCoords::SourceCoords(ExclusiveContext *cx, uint32_t ln)
|
||||
: lineStartOffsets_(cx), initialLineNum_(ln), lastLineIndex_(0)
|
||||
{
|
||||
// This is actually necessary! Removing it causes compile errors on
|
||||
@ -262,10 +262,11 @@ TokenStream::SourceCoords::lineNumAndColumnIndex(uint32_t offset, uint32_t *line
|
||||
#endif
|
||||
|
||||
/* Initialize members that aren't initialized in |init|. */
|
||||
TokenStream::TokenStream(JSContext *cx, const CompileOptions &options,
|
||||
TokenStream::TokenStream(ExclusiveContext *cx, const CompileOptions &options,
|
||||
const jschar *base, size_t length, StrictModeGetter *smg,
|
||||
AutoKeepAtoms& keepAtoms)
|
||||
: srcCoords(cx, options.lineno),
|
||||
options_(options),
|
||||
tokens(),
|
||||
cursor(),
|
||||
lookahead(),
|
||||
@ -276,9 +277,7 @@ TokenStream::TokenStream(JSContext *cx, const CompileOptions &options,
|
||||
userbuf(cx, base - options.column, length + options.column), // See comment below
|
||||
filename(options.filename),
|
||||
sourceMap(NULL),
|
||||
listenerTSData(),
|
||||
tokenbuf(cx),
|
||||
version(options.version),
|
||||
cx(cx),
|
||||
originPrincipals(JSScript::normalizeOriginPrincipals(options.principals,
|
||||
options.originPrincipals)),
|
||||
@ -293,14 +292,19 @@ TokenStream::TokenStream(JSContext *cx, const CompileOptions &options,
|
||||
// this line then adjust the next character.
|
||||
userbuf.setAddressOfNextRawChar(base);
|
||||
|
||||
if (originPrincipals)
|
||||
JS_HoldPrincipals(originPrincipals);
|
||||
JSContext *ncx = cx->asJSContext();
|
||||
{
|
||||
if (originPrincipals)
|
||||
JS_HoldPrincipals(originPrincipals);
|
||||
|
||||
JSSourceHandler listener = cx->runtime()->debugHooks.sourceHandler;
|
||||
void *listenerData = cx->runtime()->debugHooks.sourceHandlerData;
|
||||
JSSourceHandler listener = ncx->runtime()->debugHooks.sourceHandler;
|
||||
void *listenerData = ncx->runtime()->debugHooks.sourceHandlerData;
|
||||
|
||||
if (listener)
|
||||
listener(options.filename, options.lineno, base, length, &listenerTSData, listenerData);
|
||||
if (listener) {
|
||||
void *listenerTSData;
|
||||
listener(options.filename, options.lineno, base, length, &listenerTSData, listenerData);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This table holds all the token kinds that satisfy these properties:
|
||||
@ -355,7 +359,7 @@ TokenStream::~TokenStream()
|
||||
if (sourceMap)
|
||||
js_free(sourceMap);
|
||||
if (originPrincipals)
|
||||
JS_DropPrincipals(cx->runtime(), originPrincipals);
|
||||
JS_DropPrincipals(cx->asJSContext()->runtime(), originPrincipals);
|
||||
}
|
||||
|
||||
/* Use the fastest available getc. */
|
||||
@ -583,7 +587,7 @@ TokenStream::reportStrictModeErrorNumberVA(uint32_t offset, bool strictMode, uns
|
||||
unsigned flags = JSREPORT_STRICT;
|
||||
if (strictMode)
|
||||
flags |= JSREPORT_ERROR;
|
||||
else if (cx->hasExtraWarningsOption())
|
||||
else if (options().extraWarningsOption)
|
||||
flags |= JSREPORT_WARNING;
|
||||
else
|
||||
return true;
|
||||
@ -649,11 +653,16 @@ TokenStream::reportCompileErrorNumberVA(uint32_t offset, unsigned flags, unsigne
|
||||
{
|
||||
bool warning = JSREPORT_IS_WARNING(flags);
|
||||
|
||||
if (warning && cx->hasWErrorOption()) {
|
||||
if (warning && options().werrorOption) {
|
||||
flags &= ~JSREPORT_WARNING;
|
||||
warning = false;
|
||||
}
|
||||
|
||||
if (!this->cx->isJSContext())
|
||||
return warning;
|
||||
|
||||
JSContext *cx = this->cx->asJSContext();
|
||||
|
||||
CompileError err(cx);
|
||||
|
||||
err.report.flags = flags;
|
||||
@ -762,7 +771,7 @@ TokenStream::reportWarning(unsigned errorNumber, ...)
|
||||
bool
|
||||
TokenStream::reportStrictWarningErrorNumberVA(uint32_t offset, unsigned errorNumber, va_list args)
|
||||
{
|
||||
if (!cx->hasExtraWarningsOption())
|
||||
if (!options().extraWarningsOption)
|
||||
return true;
|
||||
|
||||
return reportCompileErrorNumberVA(offset, JSREPORT_STRICT|JSREPORT_WARNING, errorNumber, args);
|
||||
@ -903,7 +912,7 @@ TokenStream::newToken(ptrdiff_t adjust)
|
||||
}
|
||||
|
||||
JS_ALWAYS_INLINE JSAtom *
|
||||
TokenStream::atomize(JSContext *cx, CharBuffer &cb)
|
||||
TokenStream::atomize(ExclusiveContext *cx, CharBuffer &cb)
|
||||
{
|
||||
return AtomizeChars<CanGC>(cx, cb.begin(), cb.length());
|
||||
}
|
||||
|
@ -359,12 +359,6 @@ struct CompileError {
|
||||
void throwError();
|
||||
};
|
||||
|
||||
inline bool
|
||||
StrictModeFromContext(JSContext *cx)
|
||||
{
|
||||
return cx->hasOption(JSOPTION_STRICT_MODE);
|
||||
}
|
||||
|
||||
// Ideally, tokenizing would be entirely independent of context. But the
|
||||
// strict mode flag, which is in SharedContext, affects tokenizing, and
|
||||
// TokenStream needs to see it.
|
||||
@ -433,14 +427,13 @@ class MOZ_STACK_CLASS TokenStream
|
||||
public:
|
||||
typedef Vector<jschar, 32> CharBuffer;
|
||||
|
||||
TokenStream(JSContext *cx, const CompileOptions &options,
|
||||
TokenStream(ExclusiveContext *cx, const CompileOptions &options,
|
||||
const jschar *base, size_t length, StrictModeGetter *smg,
|
||||
AutoKeepAtoms& keepAtoms);
|
||||
|
||||
~TokenStream();
|
||||
|
||||
/* Accessors. */
|
||||
JSContext *getContext() const { return cx; }
|
||||
bool onCurrentLine(const TokenPos &pos) const { return srcCoords.isOnThisLine(pos.end, lineno); }
|
||||
const Token ¤tToken() const { return tokens[cursor]; }
|
||||
bool isCurrentTokenType(TokenKind type) const {
|
||||
@ -454,8 +447,8 @@ class MOZ_STACK_CLASS TokenStream
|
||||
const char *getFilename() const { return filename; }
|
||||
unsigned getLineno() const { return lineno; }
|
||||
unsigned getColumn() const { return userbuf.addressOfNextRawChar() - linebase - 1; }
|
||||
JSVersion versionNumber() const { return VersionNumber(version); }
|
||||
JSVersion versionWithFlags() const { return version; }
|
||||
JSVersion versionNumber() const { return VersionNumber(options().version); }
|
||||
JSVersion versionWithFlags() const { return options().version; }
|
||||
bool hadError() const { return !!(flags & TSF_HAD_ERROR); }
|
||||
|
||||
bool isCurrentTokenEquality() const {
|
||||
@ -505,7 +498,7 @@ class MOZ_STACK_CLASS TokenStream
|
||||
bool strictMode() const { return strictModeGetter && strictModeGetter->strictMode(); }
|
||||
|
||||
void onError();
|
||||
static JSAtom *atomize(JSContext *cx, CharBuffer &cb);
|
||||
static JSAtom *atomize(ExclusiveContext *cx, CharBuffer &cb);
|
||||
bool putIdentInTokenbuf(const jschar *identStart);
|
||||
|
||||
/*
|
||||
@ -737,7 +730,7 @@ class MOZ_STACK_CLASS TokenStream
|
||||
uint32_t lineNumToIndex(uint32_t lineNum) const { return lineNum - initialLineNum_; }
|
||||
|
||||
public:
|
||||
SourceCoords(JSContext *cx, uint32_t ln);
|
||||
SourceCoords(ExclusiveContext *cx, uint32_t ln);
|
||||
|
||||
void add(uint32_t lineNum, uint32_t lineStartOffset);
|
||||
void fill(const SourceCoords &other);
|
||||
@ -756,6 +749,18 @@ class MOZ_STACK_CLASS TokenStream
|
||||
|
||||
SourceCoords srcCoords;
|
||||
|
||||
JSAtomState &names() const {
|
||||
return cx->names();
|
||||
}
|
||||
|
||||
ExclusiveContext *context() const {
|
||||
return cx;
|
||||
}
|
||||
|
||||
const CompileOptions &options() const {
|
||||
return options_;
|
||||
}
|
||||
|
||||
private:
|
||||
/*
|
||||
* This is the low-level interface to the JS source code buffer. It just
|
||||
@ -766,7 +771,7 @@ class MOZ_STACK_CLASS TokenStream
|
||||
*/
|
||||
class TokenBuf {
|
||||
public:
|
||||
TokenBuf(JSContext *cx, const jschar *buf, size_t length)
|
||||
TokenBuf(ExclusiveContext *cx, const jschar *buf, size_t length)
|
||||
: base_(buf), limit_(buf + length), ptr(buf),
|
||||
skipBase(cx, &base_), skipLimit(cx, &limit_), skipPtr(cx, &ptr)
|
||||
{ }
|
||||
@ -891,6 +896,9 @@ class MOZ_STACK_CLASS TokenStream
|
||||
void updateLineInfoForEOL();
|
||||
void updateFlagsForEOL();
|
||||
|
||||
// Options used for parsing/tokenizing.
|
||||
const CompileOptions &options_;
|
||||
|
||||
Token tokens[ntokens];/* circular token buffer */
|
||||
unsigned cursor; /* index of last parsed token */
|
||||
unsigned lookahead; /* count of lookahead tokens */
|
||||
@ -901,13 +909,11 @@ class MOZ_STACK_CLASS TokenStream
|
||||
TokenBuf userbuf; /* user input buffer */
|
||||
const char *filename; /* input filename or null */
|
||||
jschar *sourceMap; /* source map's filename or null */
|
||||
void *listenerTSData;/* listener data for this TokenStream */
|
||||
CharBuffer tokenbuf; /* current token string buffer */
|
||||
int8_t oneCharTokens[128]; /* table of one-char tokens */
|
||||
bool maybeEOL[256]; /* probabilistic EOL lookup table */
|
||||
bool maybeStrSpecial[256];/* speeds up string scanning */
|
||||
JSVersion version; /* (i.e. to identify keywords) */
|
||||
JSContext *const cx;
|
||||
ExclusiveContext *const cx;
|
||||
JSPrincipals *const originPrincipals;
|
||||
StrictModeGetter *strictModeGetter; /* used to test for strict mode */
|
||||
|
||||
|
@ -572,16 +572,20 @@ AutoGCRooter::trace(JSTracer *trc)
|
||||
/* static */ void
|
||||
AutoGCRooter::traceAll(JSTracer *trc)
|
||||
{
|
||||
for (js::AutoGCRooter *gcr = trc->runtime->autoGCRooters; gcr; gcr = gcr->down)
|
||||
gcr->trace(trc);
|
||||
for (ContextIter cx(trc->runtime); !cx.done(); cx.next()) {
|
||||
for (js::AutoGCRooter *gcr = cx->autoGCRooters; gcr; gcr = gcr->down)
|
||||
gcr->trace(trc);
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
AutoGCRooter::traceAllWrappers(JSTracer *trc)
|
||||
{
|
||||
for (js::AutoGCRooter *gcr = trc->runtime->autoGCRooters; gcr; gcr = gcr->down) {
|
||||
if (gcr->tag_ == WRAPVECTOR || gcr->tag_ == WRAPPER)
|
||||
gcr->trace(trc);
|
||||
for (ContextIter cx(trc->runtime); !cx.done(); cx.next()) {
|
||||
for (js::AutoGCRooter *gcr = cx->autoGCRooters; gcr; gcr = gcr->down) {
|
||||
if (gcr->tag_ == WRAPVECTOR || gcr->tag_ == WRAPPER)
|
||||
gcr->trace(trc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "gdb-tests.h"
|
||||
#include "jsatom.h"
|
||||
#include "jscntxt.h"
|
||||
|
||||
// When JSGC_ANALYSIS is #defined, Rooted<JSFlatString*> needs the definition
|
||||
// of JSFlatString in order to figure out its ThingRootKind
|
||||
|
@ -1452,7 +1452,7 @@ class MOZ_STACK_CLASS ModuleCompiler
|
||||
for (unsigned i = 0; i < slowFunctions_.length(); i++) {
|
||||
SlowFunction &func = slowFunctions_[i];
|
||||
JSAutoByteString name;
|
||||
if (!js_AtomToPrintableString(cx_, func.name, &name))
|
||||
if (!AtomToPrintableString(cx_, func.name, &name))
|
||||
return;
|
||||
slowFuns.reset(JS_smprintf("%s%s:%u:%u (%ums)%s", slowFuns.get(),
|
||||
name.ptr(), func.line, func.column, func.ms,
|
||||
|
@ -446,7 +446,7 @@ SendFunctionsToVTune(JSContext *cx, AsmJSModule &module)
|
||||
return false;
|
||||
|
||||
JSAutoByteString bytes;
|
||||
const char *method_name = js_AtomToPrintableString(cx, func.name, &bytes);
|
||||
const char *method_name = AtomToPrintableString(cx, func.name, &bytes);
|
||||
if (!method_name)
|
||||
return false;
|
||||
|
||||
|
@ -4447,7 +4447,7 @@ IonBuilder::createThisScriptedSingleton(HandleFunction target, MDefinition *call
|
||||
|
||||
// Generate an inline path to create a new |this| object with
|
||||
// the given singleton prototype.
|
||||
types::TypeObject *type = proto->getNewType(cx, &ObjectClass, target);
|
||||
types::TypeObject *type = cx->getNewType(&ObjectClass, proto.get(), target);
|
||||
if (!type)
|
||||
return NULL;
|
||||
if (!types::TypeScript::ThisTypes(target->nonLazyScript())->hasType(types::Type::ObjectType(type)))
|
||||
|
@ -802,6 +802,12 @@ MacroAssembler::performOsr()
|
||||
ret();
|
||||
}
|
||||
|
||||
static void
|
||||
ReportOverRecursed(JSContext *cx)
|
||||
{
|
||||
js_ReportOverRecursed(cx);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::generateBailoutTail(Register scratch, Register bailoutInfo)
|
||||
{
|
||||
@ -823,7 +829,7 @@ MacroAssembler::generateBailoutTail(Register scratch, Register bailoutInfo)
|
||||
loadJSContext(ReturnReg);
|
||||
setupUnalignedABICall(1, scratch);
|
||||
passABIArg(ReturnReg);
|
||||
callWithABI(JS_FUNC_TO_DATA_PTR(void *, js_ReportOverRecursed));
|
||||
callWithABI(JS_FUNC_TO_DATA_PTR(void *, ReportOverRecursed));
|
||||
jump(&exception);
|
||||
}
|
||||
|
||||
|
@ -256,8 +256,8 @@ do {
|
||||
} while(0)
|
||||
|
||||
static ParallelResult
|
||||
ParCompareStrings(ForkJoinSlice *slice, HandleString str1,
|
||||
HandleString str2, int32_t *res)
|
||||
ParCompareStrings(ForkJoinSlice *slice, JSString *str1,
|
||||
JSString *str2, int32_t *res)
|
||||
{
|
||||
if (!str1->isLinear())
|
||||
return TP_RETRY_SEQUENTIALLY;
|
||||
@ -283,9 +283,7 @@ ParCompareMaybeStrings(ForkJoinSlice *slice,
|
||||
return TP_RETRY_SEQUENTIALLY;
|
||||
if (!v2.isString())
|
||||
return TP_RETRY_SEQUENTIALLY;
|
||||
RootedString str1(slice->perThreadData, v1.toString());
|
||||
RootedString str2(slice->perThreadData, v2.toString());
|
||||
return ParCompareStrings(slice, str1, str2, res);
|
||||
return ParCompareStrings(slice, v1.toString(), v2.toString(), res);
|
||||
}
|
||||
|
||||
template<bool Equal>
|
||||
|
@ -13,11 +13,11 @@ using namespace js;
|
||||
void *
|
||||
TempAllocPolicy::onOutOfMemory(void *p, size_t nbytes)
|
||||
{
|
||||
return cx_->runtime()->onOutOfMemory(p, nbytes, cx_);
|
||||
return static_cast<ThreadSafeContext *>(cx_)->onOutOfMemory(p, nbytes);
|
||||
}
|
||||
|
||||
void
|
||||
TempAllocPolicy::reportAllocOverflow() const
|
||||
{
|
||||
js_ReportAllocationOverflow(cx_);
|
||||
js_ReportAllocationOverflow(static_cast<ThreadSafeContext *>(cx_));
|
||||
}
|
||||
|
@ -13,6 +13,8 @@ struct JSContext;
|
||||
|
||||
namespace js {
|
||||
|
||||
class ContextFriendFields;
|
||||
|
||||
/*
|
||||
* Allocation policies. These model the concept:
|
||||
* - public copy constructor, assignment, destructor
|
||||
@ -52,7 +54,7 @@ class SystemAllocPolicy
|
||||
*/
|
||||
class TempAllocPolicy
|
||||
{
|
||||
JSContext *const cx_;
|
||||
ContextFriendFields *const cx_;
|
||||
|
||||
/*
|
||||
* Non-inline helper to call JSRuntime::onOutOfMemory with minimal
|
||||
@ -61,11 +63,8 @@ class TempAllocPolicy
|
||||
JS_FRIEND_API(void *) onOutOfMemory(void *p, size_t nbytes);
|
||||
|
||||
public:
|
||||
TempAllocPolicy(JSContext *cx) : cx_(cx) {}
|
||||
|
||||
JSContext *context() const {
|
||||
return cx_;
|
||||
}
|
||||
TempAllocPolicy(JSContext *cx) : cx_((ContextFriendFields *) cx) {} // :(
|
||||
TempAllocPolicy(ContextFriendFields *cx) : cx_(cx) {}
|
||||
|
||||
void *malloc_(size_t bytes) {
|
||||
void *p = js_malloc(bytes);
|
||||
|
@ -816,7 +816,6 @@ JSRuntime::JSRuntime(JSUseHelperThreads useHelperThreads)
|
||||
analysisPurgeCallback(NULL),
|
||||
analysisPurgeTriggerBytes(0),
|
||||
gcMallocBytes(0),
|
||||
autoGCRooters(NULL),
|
||||
scriptAndCountsVector(NULL),
|
||||
NaNValue(UndefinedValue()),
|
||||
negativeInfinityValue(UndefinedValue()),
|
||||
@ -5181,6 +5180,10 @@ JS::CompileOptions::CompileOptions(JSContext *cx, JSVersion version)
|
||||
noScriptRval(cx->hasOption(JSOPTION_NO_SCRIPT_RVAL)),
|
||||
selfHostingMode(false),
|
||||
canLazilyParse(true),
|
||||
strictOption(cx->hasOption(JSOPTION_STRICT_MODE)),
|
||||
extraWarningsOption(cx->hasExtraWarningsOption()),
|
||||
werrorOption(cx->hasWErrorOption()),
|
||||
asmJSOption(cx->hasOption(JSOPTION_ASMJS)),
|
||||
sourcePolicy(SAVE_SOURCE)
|
||||
{
|
||||
}
|
||||
@ -5311,7 +5314,8 @@ JS_BufferIsCompilableUnit(JSContext *cx, JSObject *objArg, const char *utf8, siz
|
||||
{
|
||||
CompileOptions options(cx);
|
||||
options.setCompileAndGo(false);
|
||||
Parser<frontend::FullParseHandler> parser(cx, options, chars, length,
|
||||
Parser<frontend::FullParseHandler> parser(cx, &cx->tempLifoAlloc(),
|
||||
options, chars, length,
|
||||
/* foldConstants = */ true, NULL, NULL);
|
||||
older = JS_SetErrorReporter(cx, NULL);
|
||||
if (!parser.parse(obj) && parser.tokenStream.isUnexpectedEOF()) {
|
||||
@ -7122,7 +7126,18 @@ JS_CallOnce(JSCallOnceType *once, JSInitCallback func)
|
||||
}
|
||||
|
||||
AutoGCRooter::AutoGCRooter(JSContext *cx, ptrdiff_t tag)
|
||||
: down(cx->runtime()->autoGCRooters), tag_(tag), stackTop(&cx->runtime()->autoGCRooters)
|
||||
: down(ContextFriendFields::get(cx)->autoGCRooters),
|
||||
tag_(tag),
|
||||
stackTop(&ContextFriendFields::get(cx)->autoGCRooters)
|
||||
{
|
||||
JS_ASSERT(this != *stackTop);
|
||||
*stackTop = this;
|
||||
}
|
||||
|
||||
AutoGCRooter::AutoGCRooter(ContextFriendFields *cx, ptrdiff_t tag)
|
||||
: down(cx->autoGCRooters),
|
||||
tag_(tag),
|
||||
stackTop(&cx->autoGCRooters)
|
||||
{
|
||||
JS_ASSERT(this != *stackTop);
|
||||
*stackTop = this;
|
||||
|
@ -54,6 +54,7 @@ class JS_PUBLIC_API(AutoCheckRequestDepth)
|
||||
JSContext *cx;
|
||||
public:
|
||||
AutoCheckRequestDepth(JSContext *cx);
|
||||
AutoCheckRequestDepth(js::ContextFriendFields *cx);
|
||||
~AutoCheckRequestDepth();
|
||||
};
|
||||
|
||||
@ -84,6 +85,7 @@ inline void AssertArgumentsAreSane(JSContext *cx, const Value &v) {
|
||||
class JS_PUBLIC_API(AutoGCRooter) {
|
||||
public:
|
||||
AutoGCRooter(JSContext *cx, ptrdiff_t tag);
|
||||
AutoGCRooter(js::ContextFriendFields *cx, ptrdiff_t tag);
|
||||
|
||||
~AutoGCRooter() {
|
||||
JS_ASSERT(this == *stackTop);
|
||||
@ -227,6 +229,13 @@ class AutoVectorRooter : protected AutoGCRooter
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
}
|
||||
|
||||
explicit AutoVectorRooter(js::ContextFriendFields *cx, ptrdiff_t tag
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: AutoGCRooter(cx, tag), vector(cx), vectorRoot(cx, &vector)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
}
|
||||
|
||||
typedef T ElementType;
|
||||
|
||||
size_t length() const { return vector.length(); }
|
||||
@ -578,7 +587,14 @@ class AutoFunctionVector : public AutoVectorRooter<JSFunction *>
|
||||
{
|
||||
public:
|
||||
explicit AutoFunctionVector(JSContext *cx
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: AutoVectorRooter<JSFunction *>(cx, FUNVECTOR)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
}
|
||||
|
||||
explicit AutoFunctionVector(js::ContextFriendFields *cx
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: AutoVectorRooter<JSFunction *>(cx, FUNVECTOR)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
@ -606,7 +622,8 @@ class AutoScriptVector : public AutoVectorRooter<JSScript *>
|
||||
class JS_PUBLIC_API(CustomAutoRooter) : private AutoGCRooter
|
||||
{
|
||||
public:
|
||||
explicit CustomAutoRooter(JSContext *cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
template <typename CX>
|
||||
explicit CustomAutoRooter(CX *cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: AutoGCRooter(cx, CUSTOM)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
@ -3938,6 +3955,10 @@ struct JS_PUBLIC_API(CompileOptions) {
|
||||
bool noScriptRval;
|
||||
bool selfHostingMode;
|
||||
bool canLazilyParse;
|
||||
bool strictOption;
|
||||
bool extraWarningsOption;
|
||||
bool werrorOption;
|
||||
bool asmJSOption;
|
||||
enum SourcePolicy {
|
||||
NO_SOURCE,
|
||||
LAZY_SOURCE,
|
||||
@ -4469,6 +4490,8 @@ class JSAutoByteString
|
||||
return mBytes;
|
||||
}
|
||||
|
||||
char *encodeLatin1(js::ContextFriendFields *cx, JSString *str);
|
||||
|
||||
char *encodeUtf8(JSContext *cx, JSString *str) {
|
||||
JS_ASSERT(!mBytes);
|
||||
JS_ASSERT(cx);
|
||||
|
@ -423,7 +423,10 @@ js::CanonicalizeArrayLengthValue(JSContext *cx, HandleValue v, uint32_t *newLen)
|
||||
if (d == *newLen)
|
||||
return true;
|
||||
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_ARRAY_LENGTH);
|
||||
if (!cx->isJSContext())
|
||||
return false;
|
||||
|
||||
JS_ReportErrorNumber(cx->asJSContext(), js_GetErrorMessage, NULL, JSMSG_BAD_ARRAY_LENGTH);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -461,14 +464,14 @@ js::ArraySetLength(JSContext *cx, Handle<ArrayObject*> arr, HandleId id, unsigne
|
||||
return true;
|
||||
|
||||
if (setterIsStrict) {
|
||||
return JS_ReportErrorFlagsAndNumber(cx, JSREPORT_ERROR, js_GetErrorMessage, NULL,
|
||||
return JS_ReportErrorFlagsAndNumber(cx->asJSContext(),
|
||||
JSREPORT_ERROR, js_GetErrorMessage, NULL,
|
||||
JSMSG_CANT_REDEFINE_ARRAY_LENGTH);
|
||||
}
|
||||
|
||||
return JSObject::reportReadOnly(cx, id, JSREPORT_STRICT | JSREPORT_WARNING);
|
||||
return JSObject::reportReadOnly(cx->asJSContext(), id, JSREPORT_STRICT | JSREPORT_WARNING);
|
||||
}
|
||||
|
||||
|
||||
/* Step 8. */
|
||||
bool succeeded = true;
|
||||
do {
|
||||
@ -657,7 +660,8 @@ js::ArraySetLength(JSContext *cx, Handle<ArrayObject*> arr, HandleId id, unsigne
|
||||
}
|
||||
|
||||
bool
|
||||
js::WouldDefinePastNonwritableLength(JSContext *cx, HandleObject obj, uint32_t index, bool strict,
|
||||
js::WouldDefinePastNonwritableLength(ExclusiveContext *cx,
|
||||
HandleObject obj, uint32_t index, bool strict,
|
||||
bool *definesPast)
|
||||
{
|
||||
if (!obj->is<ArrayObject>()) {
|
||||
@ -678,13 +682,19 @@ js::WouldDefinePastNonwritableLength(JSContext *cx, HandleObject obj, uint32_t i
|
||||
}
|
||||
|
||||
*definesPast = true;
|
||||
if (!strict && !cx->hasExtraWarningsOption())
|
||||
|
||||
if (!cx->isJSContext())
|
||||
return true;
|
||||
|
||||
JSContext *ncx = cx->asJSContext();
|
||||
|
||||
if (!strict && !ncx->hasExtraWarningsOption())
|
||||
return true;
|
||||
|
||||
// Error in strict mode code or warn with strict option.
|
||||
// XXX include the index and maybe array length in the error message
|
||||
unsigned flags = strict ? JSREPORT_ERROR : (JSREPORT_STRICT | JSREPORT_WARNING);
|
||||
return JS_ReportErrorFlagsAndNumber(cx, flags, js_GetErrorMessage, NULL,
|
||||
return JS_ReportErrorFlagsAndNumber(ncx, flags, js_GetErrorMessage, NULL,
|
||||
JSMSG_CANT_DEFINE_PAST_ARRAY_LENGTH);
|
||||
}
|
||||
|
||||
@ -768,7 +778,7 @@ Class ArrayObject::class_ = {
|
||||
};
|
||||
|
||||
static bool
|
||||
AddLengthProperty(JSContext *cx, HandleObject obj)
|
||||
AddLengthProperty(ExclusiveContext *cx, HandleObject obj)
|
||||
{
|
||||
/*
|
||||
* Add the 'length' property for a newly created array,
|
||||
@ -2883,7 +2893,7 @@ js_InitArrayClass(JSContext *cx, HandleObject obj)
|
||||
if (!proto)
|
||||
return NULL;
|
||||
|
||||
RootedTypeObject type(cx, proto->getNewType(cx, &ArrayObject::class_));
|
||||
RootedTypeObject type(cx, cx->getNewType(&ArrayObject::class_, proto.get()));
|
||||
if (!type)
|
||||
return NULL;
|
||||
|
||||
@ -2941,7 +2951,7 @@ js_InitArrayClass(JSContext *cx, HandleObject obj)
|
||||
*/
|
||||
|
||||
static inline bool
|
||||
EnsureNewArrayElements(JSContext *cx, JSObject *obj, uint32_t length)
|
||||
EnsureNewArrayElements(ExclusiveContext *cx, JSObject *obj, uint32_t length)
|
||||
{
|
||||
/*
|
||||
* If ensureElements creates dynamically allocated slots, then having
|
||||
@ -2959,81 +2969,84 @@ EnsureNewArrayElements(JSContext *cx, JSObject *obj, uint32_t length)
|
||||
|
||||
template<bool allocateCapacity>
|
||||
static JS_ALWAYS_INLINE ArrayObject *
|
||||
NewArray(JSContext *cx, uint32_t length, JSObject *protoArg, NewObjectKind newKind = GenericObject)
|
||||
NewArray(ExclusiveContext *cxArg, uint32_t length,
|
||||
JSObject *protoArg, NewObjectKind newKind = GenericObject)
|
||||
{
|
||||
gc::AllocKind allocKind = GuessArrayGCKind(length);
|
||||
JS_ASSERT(CanBeFinalizedInBackground(allocKind, &ArrayObject::class_));
|
||||
allocKind = GetBackgroundAllocKind(allocKind);
|
||||
|
||||
NewObjectCache &cache = cx->runtime()->newObjectCache;
|
||||
|
||||
NewObjectCache::EntryIndex entry = -1;
|
||||
if (newKind == GenericObject &&
|
||||
!cx->compartment()->objectMetadataCallback &&
|
||||
cache.lookupGlobal(&ArrayObject::class_, cx->global(), allocKind, &entry))
|
||||
{
|
||||
RootedObject obj(cx, cache.newObjectFromHit(cx, entry,
|
||||
GetInitialHeap(newKind, &ArrayObject::class_)));
|
||||
if (obj) {
|
||||
/* Fixup the elements pointer and length, which may be incorrect. */
|
||||
Rooted<ArrayObject*> arr(cx, &obj->as<ArrayObject>());
|
||||
arr->setFixedElements();
|
||||
ArrayObject::setLength(cx, arr, length);
|
||||
if (allocateCapacity && !EnsureNewArrayElements(cx, arr, length))
|
||||
return NULL;
|
||||
return arr;
|
||||
if (JSContext *cx = cxArg->maybeJSContext()) {
|
||||
NewObjectCache &cache = cx->runtime()->newObjectCache;
|
||||
if (newKind == GenericObject &&
|
||||
!cx->compartment()->objectMetadataCallback &&
|
||||
cache.lookupGlobal(&ArrayObject::class_, cx->global(), allocKind, &entry))
|
||||
{
|
||||
RootedObject obj(cx, cache.newObjectFromHit(cx, entry,
|
||||
GetInitialHeap(newKind, &ArrayObject::class_)));
|
||||
if (obj) {
|
||||
/* Fixup the elements pointer and length, which may be incorrect. */
|
||||
Rooted<ArrayObject*> arr(cx, &obj->as<ArrayObject>());
|
||||
arr->setFixedElements();
|
||||
ArrayObject::setLength(cx, arr, length);
|
||||
if (allocateCapacity && !EnsureNewArrayElements(cx, arr, length))
|
||||
return NULL;
|
||||
return arr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RootedObject proto(cx, protoArg);
|
||||
RootedObject proto(cxArg, protoArg);
|
||||
if (protoArg)
|
||||
JS::PoisonPtr(&protoArg);
|
||||
|
||||
if (!proto && !FindProto(cx, &ArrayObject::class_, &proto))
|
||||
if (!proto && !FindProto(cxArg, &ArrayObject::class_, &proto))
|
||||
return NULL;
|
||||
|
||||
RootedTypeObject type(cx, proto->getNewType(cx, &ArrayObject::class_));
|
||||
RootedTypeObject type(cxArg, cxArg->getNewType(&ArrayObject::class_, proto.get()));
|
||||
if (!type)
|
||||
return NULL;
|
||||
|
||||
JSObject *metadata = NULL;
|
||||
if (!NewObjectMetadata(cx, &metadata))
|
||||
if (!NewObjectMetadata(cxArg, &metadata))
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* Get a shape with zero fixed slots, regardless of the size class.
|
||||
* See JSObject::createArray.
|
||||
*/
|
||||
RootedShape shape(cx, EmptyShape::getInitialShape(cx, &ArrayObject::class_, TaggedProto(proto),
|
||||
cx->global(), metadata, gc::FINALIZE_OBJECT0));
|
||||
RootedShape shape(cxArg, EmptyShape::getInitialShape(cxArg, &ArrayObject::class_,
|
||||
TaggedProto(proto), cxArg->global(),
|
||||
metadata, gc::FINALIZE_OBJECT0));
|
||||
if (!shape)
|
||||
return NULL;
|
||||
|
||||
RootedObject obj(cx, JSObject::createArray(cx, allocKind,
|
||||
GetInitialHeap(newKind, &ArrayObject::class_),
|
||||
shape, type, length));
|
||||
if (!obj)
|
||||
Rooted<ArrayObject*> arr(cxArg, JSObject::createArray(cxArg, allocKind,
|
||||
GetInitialHeap(newKind, &ArrayObject::class_),
|
||||
shape, type, length));
|
||||
if (!arr)
|
||||
return NULL;
|
||||
|
||||
Rooted<ArrayObject*> arr(cx, &obj->as<ArrayObject>());
|
||||
|
||||
if (shape->isEmptyShape()) {
|
||||
if (!AddLengthProperty(cx, arr))
|
||||
if (!AddLengthProperty(cxArg, arr))
|
||||
return NULL;
|
||||
shape = arr->lastProperty();
|
||||
EmptyShape::insertInitialShape(cx, shape, proto);
|
||||
EmptyShape::insertInitialShape(cxArg, shape, proto);
|
||||
}
|
||||
|
||||
if (newKind == SingletonObject && !JSObject::setSingletonType(cx, arr))
|
||||
if (newKind == SingletonObject && !JSObject::setSingletonType(cxArg, arr))
|
||||
return NULL;
|
||||
|
||||
if (entry != -1)
|
||||
cache.fillGlobal(entry, &ArrayObject::class_, cx->global(), allocKind, arr);
|
||||
if (entry != -1) {
|
||||
cxArg->asJSContext()->runtime()->newObjectCache.fillGlobal(entry, &ArrayObject::class_,
|
||||
cxArg->global(), allocKind, arr);
|
||||
}
|
||||
|
||||
if (allocateCapacity && !EnsureNewArrayElements(cx, arr, length))
|
||||
if (allocateCapacity && !EnsureNewArrayElements(cxArg, arr, length))
|
||||
return NULL;
|
||||
|
||||
Probes::createObject(cx, arr);
|
||||
Probes::createObject(cxArg, arr);
|
||||
return arr;
|
||||
}
|
||||
|
||||
@ -3045,14 +3058,14 @@ js::NewDenseEmptyArray(JSContext *cx, JSObject *proto /* = NULL */,
|
||||
}
|
||||
|
||||
ArrayObject * JS_FASTCALL
|
||||
js::NewDenseAllocatedArray(JSContext *cx, uint32_t length, JSObject *proto /* = NULL */,
|
||||
js::NewDenseAllocatedArray(ExclusiveContext *cx, uint32_t length, JSObject *proto /* = NULL */,
|
||||
NewObjectKind newKind /* = GenericObject */)
|
||||
{
|
||||
return NewArray<true>(cx, length, proto, newKind);
|
||||
}
|
||||
|
||||
ArrayObject * JS_FASTCALL
|
||||
js::NewDenseUnallocatedArray(JSContext *cx, uint32_t length, JSObject *proto /* = NULL */,
|
||||
js::NewDenseUnallocatedArray(ExclusiveContext *cx, uint32_t length, JSObject *proto /* = NULL */,
|
||||
NewObjectKind newKind /* = GenericObject */)
|
||||
{
|
||||
return NewArray<false>(cx, length, proto, newKind);
|
||||
|
@ -50,7 +50,7 @@ NewDenseEmptyArray(JSContext *cx, JSObject *proto = NULL,
|
||||
|
||||
/* Create a dense array with length and capacity == 'length', initialized length set to 0. */
|
||||
extern ArrayObject * JS_FASTCALL
|
||||
NewDenseAllocatedArray(JSContext *cx, uint32_t length, JSObject *proto = NULL,
|
||||
NewDenseAllocatedArray(ExclusiveContext *cx, uint32_t length, JSObject *proto = NULL,
|
||||
NewObjectKind newKind = GenericObject);
|
||||
|
||||
/*
|
||||
@ -58,7 +58,7 @@ NewDenseAllocatedArray(JSContext *cx, uint32_t length, JSObject *proto = NULL,
|
||||
* contents. This is useful, e.g., when accepting length from the user.
|
||||
*/
|
||||
extern ArrayObject * JS_FASTCALL
|
||||
NewDenseUnallocatedArray(JSContext *cx, uint32_t length, JSObject *proto = NULL,
|
||||
NewDenseUnallocatedArray(ExclusiveContext *cx, uint32_t length, JSObject *proto = NULL,
|
||||
NewObjectKind newKind = GenericObject);
|
||||
|
||||
/* Create a dense array with a copy of the dense array elements in src. */
|
||||
@ -76,7 +76,8 @@ NewDenseCopiedArray(JSContext *cx, uint32_t length, const Value *values, JSObjec
|
||||
* increase the length of the array.
|
||||
*/
|
||||
extern bool
|
||||
WouldDefinePastNonwritableLength(JSContext *cx, HandleObject obj, uint32_t index, bool strict,
|
||||
WouldDefinePastNonwritableLength(ExclusiveContext *cx,
|
||||
HandleObject obj, uint32_t index, bool strict,
|
||||
bool *definesPast);
|
||||
|
||||
/*
|
||||
|
@ -37,9 +37,9 @@ using mozilla::ArrayLength;
|
||||
using mozilla::RangedPtr;
|
||||
|
||||
const char *
|
||||
js_AtomToPrintableString(JSContext *cx, JSAtom *atom, JSAutoByteString *bytes)
|
||||
js::AtomToPrintableString(ExclusiveContext *cx, JSAtom *atom, JSAutoByteString *bytes)
|
||||
{
|
||||
return js_ValueToPrintable(cx, StringValue(atom), bytes);
|
||||
return js_ValueToPrintable(cx->asJSContext(), StringValue(atom), bytes);
|
||||
}
|
||||
|
||||
const char * const js::TypeStrings[] = {
|
||||
@ -232,11 +232,11 @@ enum OwnCharsBehavior
|
||||
*/
|
||||
JS_ALWAYS_INLINE
|
||||
static JSAtom *
|
||||
AtomizeAndTakeOwnership(JSContext *cx, jschar *tbchars, size_t length, InternBehavior ib)
|
||||
AtomizeAndTakeOwnership(ExclusiveContext *cx, jschar *tbchars, size_t length, InternBehavior ib)
|
||||
{
|
||||
JS_ASSERT(tbchars[length] == 0);
|
||||
|
||||
if (JSAtom *s = cx->runtime()->staticStrings.lookup(tbchars, length)) {
|
||||
if (JSAtom *s = cx->staticStrings().lookup(tbchars, length)) {
|
||||
js_free(tbchars);
|
||||
return s;
|
||||
}
|
||||
@ -247,7 +247,7 @@ AtomizeAndTakeOwnership(JSContext *cx, jschar *tbchars, size_t length, InternBeh
|
||||
* unchanged, we need to re-lookup the table position because a last-ditch
|
||||
* GC will potentially free some table entries.
|
||||
*/
|
||||
AtomSet& atoms = cx->runtime()->atoms;
|
||||
AtomSet& atoms = cx->atoms();
|
||||
AtomSet::AddPtr p = atoms.lookupForAdd(AtomHasher::Lookup(tbchars, length));
|
||||
SkipRoot skipHash(cx, &p); /* Prevent the hash from being poisoned. */
|
||||
if (p) {
|
||||
@ -269,7 +269,7 @@ AtomizeAndTakeOwnership(JSContext *cx, jschar *tbchars, size_t length, InternBeh
|
||||
|
||||
if (!atoms.relookupOrAdd(p, AtomHasher::Lookup(tbchars, length),
|
||||
AtomStateEntry(atom, bool(ib)))) {
|
||||
JS_ReportOutOfMemory(cx); /* SystemAllocPolicy does not report OOM. */
|
||||
js_ReportOutOfMemory(cx); /* SystemAllocPolicy does not report OOM. */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -280,9 +280,9 @@ AtomizeAndTakeOwnership(JSContext *cx, jschar *tbchars, size_t length, InternBeh
|
||||
template <AllowGC allowGC>
|
||||
JS_ALWAYS_INLINE
|
||||
static JSAtom *
|
||||
AtomizeAndCopyChars(JSContext *cx, const jschar *tbchars, size_t length, InternBehavior ib)
|
||||
AtomizeAndCopyChars(ExclusiveContext *cx, const jschar *tbchars, size_t length, InternBehavior ib)
|
||||
{
|
||||
if (JSAtom *s = cx->runtime()->staticStrings.lookup(tbchars, length))
|
||||
if (JSAtom *s = cx->staticStrings().lookup(tbchars, length))
|
||||
return s;
|
||||
|
||||
/*
|
||||
@ -292,7 +292,7 @@ AtomizeAndCopyChars(JSContext *cx, const jschar *tbchars, size_t length, InternB
|
||||
* GC will potentially free some table entries.
|
||||
*/
|
||||
|
||||
AtomSet& atoms = cx->runtime()->atoms;
|
||||
AtomSet& atoms = cx->atoms();
|
||||
AtomSet::AddPtr p = atoms.lookupForAdd(AtomHasher::Lookup(tbchars, length));
|
||||
SkipRoot skipHash(cx, &p); /* Prevent the hash from being poisoned. */
|
||||
if (p) {
|
||||
@ -311,7 +311,7 @@ AtomizeAndCopyChars(JSContext *cx, const jschar *tbchars, size_t length, InternB
|
||||
|
||||
if (!atoms.relookupOrAdd(p, AtomHasher::Lookup(tbchars, length),
|
||||
AtomStateEntry(atom, bool(ib)))) {
|
||||
JS_ReportOutOfMemory(cx); /* SystemAllocPolicy does not report OOM. */
|
||||
js_ReportOutOfMemory(cx); /* SystemAllocPolicy does not report OOM. */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -320,7 +320,8 @@ AtomizeAndCopyChars(JSContext *cx, const jschar *tbchars, size_t length, InternB
|
||||
|
||||
template <AllowGC allowGC>
|
||||
JSAtom *
|
||||
js::AtomizeString(JSContext *cx, JSString *str, js::InternBehavior ib /* = js::DoNotInternAtom */)
|
||||
js::AtomizeString(ExclusiveContext *cx, JSString *str,
|
||||
js::InternBehavior ib /* = js::DoNotInternAtom */)
|
||||
{
|
||||
if (str->isAtom()) {
|
||||
JSAtom &atom = str->asAtom();
|
||||
@ -328,7 +329,7 @@ js::AtomizeString(JSContext *cx, JSString *str, js::InternBehavior ib /* = js::D
|
||||
if (ib != InternAtom || js::StaticStrings::isStatic(&atom))
|
||||
return &atom;
|
||||
|
||||
AtomSet::Ptr p = cx->runtime()->atoms.lookup(AtomHasher::Lookup(&atom));
|
||||
AtomSet::Ptr p = cx->atoms().lookup(AtomHasher::Lookup(&atom));
|
||||
JS_ASSERT(p); /* Non-static atom must exist in atom state set. */
|
||||
JS_ASSERT(p->asPtr() == &atom);
|
||||
JS_ASSERT(ib == InternAtom);
|
||||
@ -336,7 +337,7 @@ js::AtomizeString(JSContext *cx, JSString *str, js::InternBehavior ib /* = js::D
|
||||
return &atom;
|
||||
}
|
||||
|
||||
const jschar *chars = str->getChars(cx);
|
||||
const jschar *chars = str->getChars(cx->asJSContext());
|
||||
if (!chars)
|
||||
return NULL;
|
||||
|
||||
@ -346,7 +347,7 @@ js::AtomizeString(JSContext *cx, JSString *str, js::InternBehavior ib /* = js::D
|
||||
if (!allowGC)
|
||||
return NULL;
|
||||
|
||||
JSLinearString *linear = str->ensureLinear(cx);
|
||||
JSLinearString *linear = str->ensureLinear(cx->asJSContext());
|
||||
if (!linear)
|
||||
return NULL;
|
||||
|
||||
@ -355,13 +356,13 @@ js::AtomizeString(JSContext *cx, JSString *str, js::InternBehavior ib /* = js::D
|
||||
}
|
||||
|
||||
template JSAtom *
|
||||
js::AtomizeString<CanGC>(JSContext *cx, JSString *str, js::InternBehavior ib);
|
||||
js::AtomizeString<CanGC>(ExclusiveContext *cx, JSString *str, InternBehavior ib);
|
||||
|
||||
template JSAtom *
|
||||
js::AtomizeString<NoGC>(JSContext *cx, JSString *str, js::InternBehavior ib);
|
||||
js::AtomizeString<NoGC>(ExclusiveContext *cx, JSString *str, InternBehavior ib);
|
||||
|
||||
JSAtom *
|
||||
js::Atomize(JSContext *cx, const char *bytes, size_t length, InternBehavior ib)
|
||||
js::Atomize(ExclusiveContext *cx, const char *bytes, size_t length, InternBehavior ib)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
|
||||
@ -379,7 +380,11 @@ js::Atomize(JSContext *cx, const char *bytes, size_t length, InternBehavior ib)
|
||||
*/
|
||||
jschar inflated[ATOMIZE_BUF_MAX];
|
||||
size_t inflatedLength = ATOMIZE_BUF_MAX - 1;
|
||||
InflateStringToBuffer(cx, bytes, length, inflated, &inflatedLength);
|
||||
if (!InflateStringToBuffer(cx->maybeJSContext(),
|
||||
bytes, length, inflated, &inflatedLength))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
return AtomizeAndCopyChars<CanGC>(cx, inflated, inflatedLength, ib);
|
||||
}
|
||||
|
||||
@ -391,7 +396,7 @@ js::Atomize(JSContext *cx, const char *bytes, size_t length, InternBehavior ib)
|
||||
|
||||
template <AllowGC allowGC>
|
||||
JSAtom *
|
||||
js::AtomizeChars(JSContext *cx, const jschar *chars, size_t length, InternBehavior ib)
|
||||
js::AtomizeChars(ExclusiveContext *cx, const jschar *chars, size_t length, InternBehavior ib)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
|
||||
@ -402,14 +407,16 @@ js::AtomizeChars(JSContext *cx, const jschar *chars, size_t length, InternBehavi
|
||||
}
|
||||
|
||||
template JSAtom *
|
||||
js::AtomizeChars<CanGC>(JSContext *cx, const jschar *chars, size_t length, InternBehavior ib);
|
||||
js::AtomizeChars<CanGC>(ExclusiveContext *cx,
|
||||
const jschar *chars, size_t length, InternBehavior ib);
|
||||
|
||||
template JSAtom *
|
||||
js::AtomizeChars<NoGC>(JSContext *cx, const jschar *chars, size_t length, InternBehavior ib);
|
||||
js::AtomizeChars<NoGC>(ExclusiveContext *cx,
|
||||
const jschar *chars, size_t length, InternBehavior ib);
|
||||
|
||||
template <AllowGC allowGC>
|
||||
bool
|
||||
js::IndexToIdSlow(JSContext *cx, uint32_t index,
|
||||
js::IndexToIdSlow(ExclusiveContext *cx, uint32_t index,
|
||||
typename MaybeRooted<jsid, allowGC>::MutableHandleType idp)
|
||||
{
|
||||
JS_ASSERT(index > JSID_INT_MAX);
|
||||
@ -427,14 +434,14 @@ js::IndexToIdSlow(JSContext *cx, uint32_t index,
|
||||
}
|
||||
|
||||
template bool
|
||||
js::IndexToIdSlow<CanGC>(JSContext *cx, uint32_t index, MutableHandleId idp);
|
||||
js::IndexToIdSlow<CanGC>(ExclusiveContext *cx, uint32_t index, MutableHandleId idp);
|
||||
|
||||
template bool
|
||||
js::IndexToIdSlow<NoGC>(JSContext *cx, uint32_t index, FakeMutableHandle<jsid> idp);
|
||||
js::IndexToIdSlow<NoGC>(ExclusiveContext *cx, uint32_t index, FakeMutableHandle<jsid> idp);
|
||||
|
||||
template <AllowGC allowGC>
|
||||
JSAtom *
|
||||
js::ToAtom(JSContext *cx, typename MaybeRooted<Value, allowGC>::HandleType v)
|
||||
js::ToAtom(ExclusiveContext *cx, typename MaybeRooted<Value, allowGC>::HandleType v)
|
||||
{
|
||||
if (!v.isString()) {
|
||||
JSString *str = js::ToStringSlow<allowGC>(cx, v);
|
||||
@ -453,10 +460,10 @@ js::ToAtom(JSContext *cx, typename MaybeRooted<Value, allowGC>::HandleType v)
|
||||
}
|
||||
|
||||
template JSAtom *
|
||||
js::ToAtom<CanGC>(JSContext *cx, HandleValue v);
|
||||
js::ToAtom<CanGC>(ExclusiveContext *cx, HandleValue v);
|
||||
|
||||
template JSAtom *
|
||||
js::ToAtom<NoGC>(JSContext *cx, Value v);
|
||||
js::ToAtom<NoGC>(ExclusiveContext *cx, Value v);
|
||||
|
||||
template<XDRMode mode>
|
||||
bool
|
||||
|
@ -45,16 +45,12 @@ struct JsidHasher
|
||||
}
|
||||
};
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
/*
|
||||
* Return a printable, lossless char[] representation of a string-type atom.
|
||||
* The lifetime of the result matches the lifetime of bytes.
|
||||
*/
|
||||
extern const char *
|
||||
js_AtomToPrintableString(JSContext *cx, JSAtom *atom, JSAutoByteString *bytes);
|
||||
|
||||
namespace js {
|
||||
AtomToPrintableString(ExclusiveContext *cx, JSAtom *atom, JSAutoByteString *bytes);
|
||||
|
||||
/* Compute a hash function from chars/length. */
|
||||
inline uint32_t
|
||||
@ -215,21 +211,21 @@ enum InternBehavior
|
||||
};
|
||||
|
||||
extern JSAtom *
|
||||
Atomize(JSContext *cx, const char *bytes, size_t length,
|
||||
Atomize(ExclusiveContext *cx, const char *bytes, size_t length,
|
||||
js::InternBehavior ib = js::DoNotInternAtom);
|
||||
|
||||
template <AllowGC allowGC>
|
||||
extern JSAtom *
|
||||
AtomizeChars(JSContext *cx, const jschar *chars, size_t length,
|
||||
AtomizeChars(ExclusiveContext *cx, const jschar *chars, size_t length,
|
||||
js::InternBehavior ib = js::DoNotInternAtom);
|
||||
|
||||
template <AllowGC allowGC>
|
||||
extern JSAtom *
|
||||
AtomizeString(JSContext *cx, JSString *str, js::InternBehavior ib = js::DoNotInternAtom);
|
||||
AtomizeString(ExclusiveContext *cx, JSString *str, js::InternBehavior ib = js::DoNotInternAtom);
|
||||
|
||||
template <AllowGC allowGC>
|
||||
extern JSAtom *
|
||||
ToAtom(JSContext *cx, typename MaybeRooted<Value, allowGC>::HandleType v);
|
||||
ToAtom(ExclusiveContext *cx, typename MaybeRooted<Value, allowGC>::HandleType v);
|
||||
|
||||
template<XDRMode mode>
|
||||
bool
|
||||
|
@ -107,11 +107,11 @@ BackfillIndexInCharBuffer(uint32_t index, mozilla::RangedPtr<T> end)
|
||||
|
||||
template <AllowGC allowGC>
|
||||
bool
|
||||
IndexToIdSlow(JSContext *cx, uint32_t index,
|
||||
IndexToIdSlow(ExclusiveContext *cx, uint32_t index,
|
||||
typename MaybeRooted<jsid, allowGC>::MutableHandleType idp);
|
||||
|
||||
inline bool
|
||||
IndexToId(JSContext *cx, uint32_t index, MutableHandleId idp)
|
||||
IndexToId(ExclusiveContext *cx, uint32_t index, MutableHandleId idp)
|
||||
{
|
||||
MaybeCheckStackRoots(cx);
|
||||
|
||||
@ -194,14 +194,14 @@ TypeName(JSType type, JSContext *cx)
|
||||
}
|
||||
|
||||
inline Handle<PropertyName*>
|
||||
ClassName(JSProtoKey key, JSContext *cx)
|
||||
ClassName(JSProtoKey key, ExclusiveContext *cx)
|
||||
{
|
||||
JS_ASSERT(key < JSProto_LIMIT);
|
||||
JS_STATIC_ASSERT(offsetof(JSAtomState, Null) +
|
||||
JSProto_LIMIT * sizeof(FixedHeapPtr<PropertyName>) <=
|
||||
sizeof(JSAtomState));
|
||||
JS_STATIC_ASSERT(JSProto_Null == 0);
|
||||
return (&cx->runtime()->atomState.Null)[key];
|
||||
return (&cx->names().Null)[key];
|
||||
}
|
||||
|
||||
} // namespace js
|
||||
|
@ -178,9 +178,9 @@ js_InitBooleanClass(JSContext *cx, HandleObject obj)
|
||||
}
|
||||
|
||||
JSString *
|
||||
js_BooleanToString(JSContext *cx, JSBool b)
|
||||
js_BooleanToString(ExclusiveContext *cx, JSBool b)
|
||||
{
|
||||
return b ? cx->runtime()->atomState.true_ : cx->runtime()->atomState.false_;
|
||||
return b ? cx->names().true_ : cx->names().false_;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
|
@ -16,7 +16,7 @@ extern JSObject *
|
||||
js_InitBooleanClass(JSContext *cx, js::HandleObject obj);
|
||||
|
||||
extern JSString *
|
||||
js_BooleanToString(JSContext *cx, JSBool b);
|
||||
js_BooleanToString(js::ExclusiveContext *cx, JSBool b);
|
||||
|
||||
namespace js {
|
||||
|
||||
|
@ -375,8 +375,12 @@ PopulateReportBlame(JSContext *cx, JSErrorReport *report)
|
||||
* not occur, so GC must be avoided or suppressed.
|
||||
*/
|
||||
void
|
||||
js_ReportOutOfMemory(JSContext *cx)
|
||||
js_ReportOutOfMemory(ThreadSafeContext *cxArg)
|
||||
{
|
||||
if (!cxArg->isJSContext())
|
||||
return;
|
||||
JSContext *cx = cxArg->asJSContext();
|
||||
|
||||
cx->runtime()->hadOutOfMemory = true;
|
||||
|
||||
if (JS_IsRunning(cx)) {
|
||||
@ -422,12 +426,20 @@ js_ReportOverRecursed(JSContext *maybecx)
|
||||
}
|
||||
|
||||
void
|
||||
js_ReportAllocationOverflow(JSContext *maybecx)
|
||||
js_ReportOverRecursed(ThreadSafeContext *cx)
|
||||
{
|
||||
if (maybecx) {
|
||||
AutoSuppressGC suppressGC(maybecx);
|
||||
JS_ReportErrorNumber(maybecx, js_GetErrorMessage, NULL, JSMSG_ALLOC_OVERFLOW);
|
||||
}
|
||||
js_ReportOverRecursed(cx->maybeJSContext());
|
||||
}
|
||||
|
||||
void
|
||||
js_ReportAllocationOverflow(ThreadSafeContext *cxArg)
|
||||
{
|
||||
if (!cxArg || !cxArg->isJSContext())
|
||||
return;
|
||||
JSContext *cx = cxArg->asJSContext();
|
||||
|
||||
AutoSuppressGC suppressGC(cx);
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_ALLOC_OVERFLOW);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1025,19 +1037,6 @@ js::ThreadSafeContext::ThreadSafeContext(JSRuntime *rt, PerThreadData *pt, Conte
|
||||
perThreadData(pt)
|
||||
{ }
|
||||
|
||||
bool
|
||||
ThreadSafeContext::isJSContext() const
|
||||
{
|
||||
return contextKind_ == Context_JS;
|
||||
}
|
||||
|
||||
JSContext *
|
||||
ThreadSafeContext::asJSContext()
|
||||
{
|
||||
JS_ASSERT(isJSContext());
|
||||
return reinterpret_cast<JSContext *>(this);
|
||||
}
|
||||
|
||||
bool
|
||||
ThreadSafeContext::isForkJoinSlice() const
|
||||
{
|
||||
@ -1052,7 +1051,7 @@ ThreadSafeContext::asForkJoinSlice()
|
||||
}
|
||||
|
||||
JSContext::JSContext(JSRuntime *rt)
|
||||
: ThreadSafeContext(rt, &rt->mainThread, Context_JS),
|
||||
: ExclusiveContext(rt, &rt->mainThread, Context_JS),
|
||||
throwing(false),
|
||||
exception(UndefinedValue()),
|
||||
options_(0),
|
||||
@ -1084,13 +1083,6 @@ JSContext::JSContext(JSRuntime *rt)
|
||||
|
||||
JS_ASSERT(static_cast<ContextFriendFields*>(this) ==
|
||||
ContextFriendFields::get(this));
|
||||
|
||||
#ifdef JSGC_TRACK_EXACT_ROOTS
|
||||
PodArrayZero(thingGCRooters);
|
||||
#endif
|
||||
#if defined(DEBUG) && defined(JS_GC_ZEAL) && defined(JSGC_ROOT_ANALYSIS) && !defined(JS_THREADSAFE)
|
||||
skipGCRooters = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
JSContext::~JSContext()
|
||||
@ -1311,10 +1303,22 @@ JS::AutoCheckRequestDepth::AutoCheckRequestDepth(JSContext *cx)
|
||||
cx->runtime()->checkRequestDepth++;
|
||||
}
|
||||
|
||||
JS::AutoCheckRequestDepth::AutoCheckRequestDepth(ContextFriendFields *cxArg)
|
||||
: cx(static_cast<ThreadSafeContext *>(cxArg)->maybeJSContext())
|
||||
{
|
||||
if (cx) {
|
||||
JS_ASSERT(cx->runtime()->requestDepth || cx->runtime()->isHeapBusy());
|
||||
cx->runtime()->assertValidThread();
|
||||
cx->runtime()->checkRequestDepth++;
|
||||
}
|
||||
}
|
||||
|
||||
JS::AutoCheckRequestDepth::~AutoCheckRequestDepth()
|
||||
{
|
||||
JS_ASSERT(cx->runtime()->checkRequestDepth != 0);
|
||||
cx->runtime()->checkRequestDepth--;
|
||||
if (cx) {
|
||||
JS_ASSERT(cx->runtime()->checkRequestDepth != 0);
|
||||
cx->runtime()->checkRequestDepth--;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
221
js/src/jscntxt.h
221
js/src/jscntxt.h
@ -30,6 +30,17 @@
|
||||
#pragma warning(disable:4355) /* Silence warning about "this" used in base member initializer list */
|
||||
#endif
|
||||
|
||||
struct DtoaState;
|
||||
|
||||
extern void
|
||||
js_ReportOutOfMemory(js::ThreadSafeContext *cx);
|
||||
|
||||
extern void
|
||||
js_ReportAllocationOverflow(js::ThreadSafeContext *cx);
|
||||
|
||||
extern void
|
||||
js_ReportOverRecursed(js::ThreadSafeContext *cx);
|
||||
|
||||
namespace js {
|
||||
|
||||
struct CallsiteCloneKey {
|
||||
@ -98,29 +109,44 @@ TraceCycleDetectionSet(JSTracer *trc, ObjectSet &set);
|
||||
struct AutoResolving;
|
||||
|
||||
class ForkJoinSlice;
|
||||
class RegExpCompartment;
|
||||
class DtoaCache;
|
||||
|
||||
/*
|
||||
* ThreadSafeContext is the base class for both JSContext, the "normal"
|
||||
* sequential context, and ForkJoinSlice, the per-thread parallel context used
|
||||
* in PJS.
|
||||
* Execution Context Overview:
|
||||
*
|
||||
* When cast to a ThreadSafeContext, the only usable operations are casting
|
||||
* back to the context from which it came, and generic allocation
|
||||
* operations. These generic versions branch internally based on whether the
|
||||
* underneath context is really a JSContext or a ForkJoinSlice, and are in
|
||||
* general more expensive than using the context directly.
|
||||
* Several different structures may be used to provide a context for operations
|
||||
* on the VM. Each context is thread local, but varies in what data it can
|
||||
* access and what other threads may be running.
|
||||
*
|
||||
* Thus, ThreadSafeContext should only be used for VM functions that may be
|
||||
* called in both sequential and parallel execution. The most likely class of
|
||||
* VM functions that do these are those that allocate commonly used data
|
||||
* structures, such as concatenating strings and extending elements.
|
||||
* - ThreadSafeContext is used by threads operating in one compartment which
|
||||
* may run in parallel with other threads operating on the same or other
|
||||
* compartments.
|
||||
*
|
||||
* - ExclusiveContext is used by threads operating in one compartment, where
|
||||
* other threads may operate in other compartments, but *not* the one which
|
||||
* the ExclusiveContext is in. A thread with an ExclusiveContext may enter the
|
||||
* atoms compartment and atomize strings, in which case a lock is used.
|
||||
*
|
||||
* - JSContext is used only by the runtime's main thread. The context may
|
||||
* operate in any compartment which is not locked by an ExclusiveContext or
|
||||
* ThreadSafeContext, and will only run in parallel with threads using such
|
||||
* contexts.
|
||||
*
|
||||
* An ExclusiveContext coerces to a ThreadSafeContext, and a JSContext coerces
|
||||
* to an ExclusiveContext or ThreadSafeContext.
|
||||
*
|
||||
* Contexts which are a ThreadSafeContext but not an ExclusiveContext are used
|
||||
* to represent a ForkJoinSlice, the per-thread parallel context used in PJS.
|
||||
*/
|
||||
struct ThreadSafeContext : js::ContextFriendFields,
|
||||
|
||||
struct ThreadSafeContext : ContextFriendFields,
|
||||
public MallocProvider<ThreadSafeContext>
|
||||
{
|
||||
public:
|
||||
enum ContextKind {
|
||||
Context_JS,
|
||||
Context_Exclusive,
|
||||
Context_ForkJoin
|
||||
};
|
||||
|
||||
@ -130,14 +156,46 @@ struct ThreadSafeContext : js::ContextFriendFields,
|
||||
public:
|
||||
PerThreadData *perThreadData;
|
||||
|
||||
explicit ThreadSafeContext(JSRuntime *rt, PerThreadData *pt, ContextKind kind);
|
||||
ThreadSafeContext(JSRuntime *rt, PerThreadData *pt, ContextKind kind);
|
||||
|
||||
bool isJSContext() const;
|
||||
JSContext *asJSContext();
|
||||
bool isJSContext() const {
|
||||
return contextKind_ == Context_JS;
|
||||
}
|
||||
|
||||
JSContext *maybeJSContext() const {
|
||||
if (isJSContext())
|
||||
return (JSContext *) this;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
JSContext *asJSContext() const {
|
||||
// Note: there is no way to perform an unchecked coercion from a
|
||||
// ThreadSafeContext to a JSContext. This ensures that trying to use
|
||||
// the context as a JSContext off the main thread will NULL crash
|
||||
// rather than race.
|
||||
JS_ASSERT(isJSContext());
|
||||
return maybeJSContext();
|
||||
}
|
||||
|
||||
bool isExclusiveContext() const {
|
||||
return contextKind_ == Context_JS || contextKind_ == Context_Exclusive;
|
||||
}
|
||||
|
||||
ExclusiveContext *maybeExclusiveContext() const {
|
||||
if (isExclusiveContext())
|
||||
return (ExclusiveContext *) this;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ExclusiveContext *asExclusiveContext() const {
|
||||
JS_ASSERT(isExclusiveContext());
|
||||
return maybeExclusiveContext();
|
||||
}
|
||||
|
||||
bool isForkJoinSlice() const;
|
||||
ForkJoinSlice *asForkJoinSlice();
|
||||
|
||||
// The generational GC nursery may only be used on the main thread.
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
inline bool hasNursery() const {
|
||||
return isJSContext();
|
||||
@ -149,20 +207,16 @@ struct ThreadSafeContext : js::ContextFriendFields,
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Cut outs for string operations. */
|
||||
StaticStrings &staticStrings() { return runtime_->staticStrings; }
|
||||
JSAtomState &names() { return runtime_->atomState; }
|
||||
|
||||
/*
|
||||
* Allocator used when allocating GCThings on this context. If we are a
|
||||
* JSContext, this is the Zone allocator of the JSContext's zone. If we
|
||||
* are the per-thread data of a ForkJoinSlice, this is a per-thread
|
||||
* allocator.
|
||||
* JSContext, this is the Zone allocator of the JSContext's zone.
|
||||
* Otherwise, this is a per-thread allocator.
|
||||
*
|
||||
* This does not live in PerThreadData because the notion of an allocator
|
||||
* is only per-thread in PJS. The runtime (and the main thread) can have
|
||||
* more than one zone, each with its own allocator, and it's up to the
|
||||
* context to specify what compartment and zone we are operating in.
|
||||
* is only per-thread when off the main thread. The runtime (and the main
|
||||
* thread) can have more than one zone, each with its own allocator, and
|
||||
* it's up to the context to specify what compartment and zone we are
|
||||
* operating in.
|
||||
*/
|
||||
protected:
|
||||
Allocator *allocator_;
|
||||
@ -172,39 +226,106 @@ struct ThreadSafeContext : js::ContextFriendFields,
|
||||
|
||||
inline Allocator *const allocator();
|
||||
|
||||
/* GC support. */
|
||||
AllowGC allowGC() const {
|
||||
switch (contextKind_) {
|
||||
case Context_JS:
|
||||
return CanGC;
|
||||
case Context_ForkJoin:
|
||||
return NoGC;
|
||||
default:
|
||||
/* Silence warnings. */
|
||||
MOZ_ASSUME_UNREACHABLE("Bad context kind");
|
||||
}
|
||||
}
|
||||
// Allocations can only trigger GC when running on the main thread.
|
||||
inline AllowGC allowGC() const { return isJSContext() ? CanGC : NoGC; }
|
||||
|
||||
template <typename T>
|
||||
bool isInsideCurrentZone(T thing) const {
|
||||
return thing->isInsideZone(zone_);
|
||||
}
|
||||
|
||||
void *onOutOfMemory(void *p, size_t nbytes) {
|
||||
return runtime_->onOutOfMemory(p, nbytes, isJSContext() ? asJSContext() : NULL);
|
||||
template <typename T>
|
||||
inline bool isInsideCurrentCompartment(T thing) const {
|
||||
return thing->compartment() == compartment_;
|
||||
}
|
||||
|
||||
void *onOutOfMemory(void *p, size_t nbytes) {
|
||||
return runtime_->onOutOfMemory(p, nbytes, maybeJSContext());
|
||||
}
|
||||
|
||||
inline void updateMallocCounter(size_t nbytes) {
|
||||
/* Note: this is racy. */
|
||||
// Note: this is racy.
|
||||
runtime_->updateMallocCounter(zone_, nbytes);
|
||||
}
|
||||
|
||||
void reportAllocationOverflow() {
|
||||
js_ReportAllocationOverflow(isJSContext() ? asJSContext() : NULL);
|
||||
js_ReportAllocationOverflow(this);
|
||||
}
|
||||
|
||||
// Builtin atoms are immutable and may be accessed freely from any thread.
|
||||
JSAtomState &names() { return runtime_->atomState; }
|
||||
StaticStrings &staticStrings() { return runtime_->staticStrings; }
|
||||
PropertyName *emptyString() { return runtime_->emptyString; }
|
||||
|
||||
// GCs cannot happen while non-main threads are running.
|
||||
uint64_t gcNumber() { return runtime_->gcNumber; }
|
||||
bool isHeapBusy() { return runtime_->isHeapBusy(); }
|
||||
|
||||
// Thread local data that may be accessed freely.
|
||||
DtoaState *dtoaState() {
|
||||
return perThreadData->dtoaState;
|
||||
}
|
||||
};
|
||||
|
||||
class ExclusiveContext : public ThreadSafeContext
|
||||
{
|
||||
friend class gc::ArenaLists;
|
||||
friend class CompartmentChecker;
|
||||
friend class AutoEnterAtomsCompartment;
|
||||
friend struct StackBaseShape;
|
||||
friend void JSScript::initCompartmentAndPrincipals(ExclusiveContext *cx,
|
||||
const JS::CompileOptions &options);
|
||||
|
||||
inline void privateSetCompartment(JSCompartment *comp);
|
||||
|
||||
public:
|
||||
|
||||
ExclusiveContext(JSRuntime *rt, PerThreadData *pt, ContextKind kind)
|
||||
: ThreadSafeContext(rt, pt, kind)
|
||||
{}
|
||||
|
||||
inline bool typeInferenceEnabled() const;
|
||||
|
||||
// Per compartment data that can be accessed freely from an ExclusiveContext.
|
||||
inline RegExpCompartment ®Exps();
|
||||
inline RegExpStatics *regExpStatics();
|
||||
inline PropertyTree &propertyTree();
|
||||
inline BaseShapeSet &baseShapes();
|
||||
inline InitialShapeSet &initialShapes();
|
||||
inline DtoaCache &dtoaCache();
|
||||
types::TypeObject *getNewType(Class *clasp, TaggedProto proto, JSFunction *fun = NULL);
|
||||
|
||||
// Current global. This is only safe to use within the scope of the
|
||||
// AutoCompartment from which it's called.
|
||||
inline js::Handle<js::GlobalObject*> global() const;
|
||||
|
||||
// Methods to access runtime wide data that must be protected by locks.
|
||||
|
||||
frontend::ParseMapPool &parseMapPool() {
|
||||
runtime_->assertValidThread();
|
||||
return runtime_->parseMapPool;
|
||||
}
|
||||
|
||||
AtomSet &atoms() {
|
||||
runtime_->assertValidThread();
|
||||
return runtime_->atoms;
|
||||
}
|
||||
|
||||
ScriptDataTable &scriptDataTable() {
|
||||
runtime_->assertValidThread();
|
||||
return runtime_->scriptDataTable;
|
||||
}
|
||||
};
|
||||
|
||||
inline void
|
||||
MaybeCheckStackRoots(ExclusiveContext *cx)
|
||||
{
|
||||
MaybeCheckStackRoots(cx->maybeJSContext());
|
||||
}
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
struct JSContext : js::ThreadSafeContext,
|
||||
struct JSContext : public js::ExclusiveContext,
|
||||
public mozilla::LinkedListElement<JSContext>
|
||||
{
|
||||
explicit JSContext(JSRuntime *rt);
|
||||
@ -294,12 +415,6 @@ struct JSContext : js::ThreadSafeContext,
|
||||
inline void setDefaultCompartmentObjectIfUnset(JSObject *obj);
|
||||
JSObject *maybeDefaultCompartmentObject() const { return defaultCompartmentObject_; }
|
||||
|
||||
/*
|
||||
* Current global. This is only safe to use within the scope of the
|
||||
* AutoCompartment from which it's called.
|
||||
*/
|
||||
inline js::Handle<js::GlobalObject*> global() const;
|
||||
|
||||
/* Wrap cx->exception for the current compartment. */
|
||||
void wrapPendingException();
|
||||
|
||||
@ -316,8 +431,6 @@ struct JSContext : js::ThreadSafeContext,
|
||||
void *data;
|
||||
void *data2;
|
||||
|
||||
inline js::RegExpStatics *regExpStatics();
|
||||
|
||||
public:
|
||||
|
||||
/*
|
||||
@ -349,8 +462,6 @@ struct JSContext : js::ThreadSafeContext,
|
||||
inline js::LifoAlloc &analysisLifoAlloc();
|
||||
inline js::LifoAlloc &typeLifoAlloc();
|
||||
|
||||
inline js::PropertyTree &propertyTree();
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
unsigned outstandingRequests;/* number of JS_BeginRequest calls
|
||||
without the corresponding
|
||||
@ -365,8 +476,6 @@ struct JSContext : js::ThreadSafeContext,
|
||||
|
||||
bool jitIsBroken;
|
||||
|
||||
inline bool typeInferenceEnabled() const;
|
||||
|
||||
void updateJITEnabled();
|
||||
|
||||
/* Whether this context has JS frames on the stack. */
|
||||
@ -604,13 +713,13 @@ extern bool
|
||||
js_ReportErrorNumberUCArray(JSContext *cx, unsigned flags, JSErrorCallback callback,
|
||||
void *userRef, const unsigned errorNumber,
|
||||
const jschar **args);
|
||||
#endif
|
||||
|
||||
extern JSBool
|
||||
js_ExpandErrorArguments(JSContext *cx, JSErrorCallback callback,
|
||||
void *userRef, const unsigned errorNumber,
|
||||
char **message, JSErrorReport *reportp,
|
||||
js::ErrorArgumentsType argumentsType, va_list ap);
|
||||
#endif
|
||||
|
||||
namespace js {
|
||||
|
||||
|
@ -30,12 +30,12 @@ namespace js {
|
||||
#ifdef JS_CRASH_DIAGNOSTICS
|
||||
class CompartmentChecker
|
||||
{
|
||||
JSContext *context;
|
||||
ExclusiveContext *context;
|
||||
JSCompartment *compartment;
|
||||
|
||||
public:
|
||||
explicit CompartmentChecker(JSContext *cx)
|
||||
: context(cx), compartment(cx->compartment())
|
||||
explicit CompartmentChecker(ExclusiveContext *cx)
|
||||
: context(cx), compartment(cx->compartment_)
|
||||
{}
|
||||
|
||||
/*
|
||||
@ -61,7 +61,7 @@ class CompartmentChecker
|
||||
}
|
||||
|
||||
void check(JSCompartment *c) {
|
||||
if (c && c != context->runtime()->atomsCompartment) {
|
||||
if (c && c != compartment->rt->atomsCompartment) {
|
||||
if (!compartment)
|
||||
compartment = c;
|
||||
else if (c != compartment)
|
||||
@ -140,13 +140,12 @@ class CompartmentChecker
|
||||
* depends on other objects not having been swept yet.
|
||||
*/
|
||||
#define START_ASSERT_SAME_COMPARTMENT() \
|
||||
JS_ASSERT(cx->compartment()->zone() == cx->zone()); \
|
||||
if (cx->runtime()->isHeapBusy()) \
|
||||
if (cx->isHeapBusy()) \
|
||||
return; \
|
||||
CompartmentChecker c(cx)
|
||||
|
||||
template <class T1> inline void
|
||||
assertSameCompartment(JSContext *cx, const T1 &t1)
|
||||
assertSameCompartment(ExclusiveContext *cx, const T1 &t1)
|
||||
{
|
||||
#ifdef JS_CRASH_DIAGNOSTICS
|
||||
START_ASSERT_SAME_COMPARTMENT();
|
||||
@ -155,7 +154,7 @@ assertSameCompartment(JSContext *cx, const T1 &t1)
|
||||
}
|
||||
|
||||
template <class T1> inline void
|
||||
assertSameCompartmentDebugOnly(JSContext *cx, const T1 &t1)
|
||||
assertSameCompartmentDebugOnly(ExclusiveContext *cx, const T1 &t1)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
START_ASSERT_SAME_COMPARTMENT();
|
||||
@ -164,7 +163,7 @@ assertSameCompartmentDebugOnly(JSContext *cx, const T1 &t1)
|
||||
}
|
||||
|
||||
template <class T1, class T2> inline void
|
||||
assertSameCompartment(JSContext *cx, const T1 &t1, const T2 &t2)
|
||||
assertSameCompartment(ExclusiveContext *cx, const T1 &t1, const T2 &t2)
|
||||
{
|
||||
#ifdef JS_CRASH_DIAGNOSTICS
|
||||
START_ASSERT_SAME_COMPARTMENT();
|
||||
@ -174,7 +173,7 @@ assertSameCompartment(JSContext *cx, const T1 &t1, const T2 &t2)
|
||||
}
|
||||
|
||||
template <class T1, class T2, class T3> inline void
|
||||
assertSameCompartment(JSContext *cx, const T1 &t1, const T2 &t2, const T3 &t3)
|
||||
assertSameCompartment(ExclusiveContext *cx, const T1 &t1, const T2 &t2, const T3 &t3)
|
||||
{
|
||||
#ifdef JS_CRASH_DIAGNOSTICS
|
||||
START_ASSERT_SAME_COMPARTMENT();
|
||||
@ -185,7 +184,8 @@ assertSameCompartment(JSContext *cx, const T1 &t1, const T2 &t2, const T3 &t3)
|
||||
}
|
||||
|
||||
template <class T1, class T2, class T3, class T4> inline void
|
||||
assertSameCompartment(JSContext *cx, const T1 &t1, const T2 &t2, const T3 &t3, const T4 &t4)
|
||||
assertSameCompartment(ExclusiveContext *cx,
|
||||
const T1 &t1, const T2 &t2, const T3 &t3, const T4 &t4)
|
||||
{
|
||||
#ifdef JS_CRASH_DIAGNOSTICS
|
||||
START_ASSERT_SAME_COMPARTMENT();
|
||||
@ -197,7 +197,8 @@ assertSameCompartment(JSContext *cx, const T1 &t1, const T2 &t2, const T3 &t3, c
|
||||
}
|
||||
|
||||
template <class T1, class T2, class T3, class T4, class T5> inline void
|
||||
assertSameCompartment(JSContext *cx, const T1 &t1, const T2 &t2, const T3 &t3, const T4 &t4, const T5 &t5)
|
||||
assertSameCompartment(ExclusiveContext *cx,
|
||||
const T1 &t1, const T2 &t2, const T3 &t3, const T4 &t4, const T5 &t5)
|
||||
{
|
||||
#ifdef JS_CRASH_DIAGNOSTICS
|
||||
START_ASSERT_SAME_COMPARTMENT();
|
||||
@ -338,6 +339,42 @@ CallSetter(JSContext *cx, HandleObject obj, HandleId id, StrictPropertyOp op, un
|
||||
return CallJSPropertyOpSetter(cx, op, obj, nid, strict, vp);
|
||||
}
|
||||
|
||||
inline uintptr_t
|
||||
GetNativeStackLimit(ExclusiveContext *cx)
|
||||
{
|
||||
return GetNativeStackLimit(cx->asJSContext()->runtime());
|
||||
}
|
||||
|
||||
inline RegExpCompartment &
|
||||
ExclusiveContext::regExps()
|
||||
{
|
||||
return compartment_->regExps;
|
||||
}
|
||||
|
||||
inline PropertyTree&
|
||||
ExclusiveContext::propertyTree()
|
||||
{
|
||||
return compartment_->propertyTree;
|
||||
}
|
||||
|
||||
inline BaseShapeSet &
|
||||
ExclusiveContext::baseShapes()
|
||||
{
|
||||
return compartment_->baseShapes;
|
||||
}
|
||||
|
||||
inline InitialShapeSet &
|
||||
ExclusiveContext::initialShapes()
|
||||
{
|
||||
return compartment_->initialShapes;
|
||||
}
|
||||
|
||||
inline DtoaCache &
|
||||
ExclusiveContext::dtoaCache()
|
||||
{
|
||||
return compartment_->dtoaCache;
|
||||
}
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
inline js::LifoAlloc &
|
||||
@ -360,12 +397,6 @@ JSContext::setPendingException(js::Value v) {
|
||||
js::assertSameCompartment(this, v);
|
||||
}
|
||||
|
||||
inline js::PropertyTree&
|
||||
JSContext::propertyTree()
|
||||
{
|
||||
return compartment()->propertyTree;
|
||||
}
|
||||
|
||||
inline void
|
||||
JSContext::setDefaultCompartmentObject(JSObject *obj)
|
||||
{
|
||||
@ -435,6 +466,18 @@ JSContext::setCompartment(JSCompartment *comp)
|
||||
allocator_ = zone_ ? &zone_->allocator : NULL;
|
||||
}
|
||||
|
||||
inline void
|
||||
js::ExclusiveContext::privateSetCompartment(JSCompartment *comp)
|
||||
{
|
||||
if (isJSContext()) {
|
||||
asJSContext()->setCompartment(comp);
|
||||
} else {
|
||||
compartment_ = comp;
|
||||
if (zone_ != comp->zone())
|
||||
MOZ_CRASH();
|
||||
}
|
||||
}
|
||||
|
||||
inline JSScript *
|
||||
JSContext::currentScript(jsbytecode **ppc,
|
||||
MaybeAllowCrossCompartment allowCrossCompartment) const
|
||||
|
@ -135,6 +135,7 @@ struct JSCompartment
|
||||
private:
|
||||
friend struct JSRuntime;
|
||||
friend struct JSContext;
|
||||
friend class js::ExclusiveContext;
|
||||
js::ReadBarriered<js::GlobalObject> global_;
|
||||
|
||||
unsigned enterCompartmentDepth;
|
||||
@ -225,9 +226,6 @@ struct JSCompartment
|
||||
js::types::TypeObjectSet lazyTypeObjects;
|
||||
void sweepNewTypeObjectTable(js::types::TypeObjectSet &table);
|
||||
|
||||
js::types::TypeObject *getNewType(JSContext *cx, js::Class *clasp, js::TaggedProto proto,
|
||||
JSFunction *fun = NULL);
|
||||
|
||||
js::types::TypeObject *getLazyType(JSContext *cx, js::Class *clasp, js::TaggedProto proto);
|
||||
|
||||
/*
|
||||
@ -411,14 +409,20 @@ class js::AutoDebugModeGC
|
||||
}
|
||||
};
|
||||
|
||||
namespace js {
|
||||
|
||||
inline bool
|
||||
JSContext::typeInferenceEnabled() const
|
||||
ExclusiveContext::typeInferenceEnabled() const
|
||||
{
|
||||
return compartment()->zone()->types.inferenceEnabled;
|
||||
// Type inference cannot be enabled in compartments which are accessed off
|
||||
// the main thread by an ExclusiveContext. TI data is stored in per-zone
|
||||
// allocators which could otherwise race with main thread operations.
|
||||
JS_ASSERT_IF(!isJSContext(), !compartment_->zone()->types.inferenceEnabled);
|
||||
return compartment_->zone()->types.inferenceEnabled;
|
||||
}
|
||||
|
||||
inline js::Handle<js::GlobalObject*>
|
||||
JSContext::global() const
|
||||
ExclusiveContext::global() const
|
||||
{
|
||||
/*
|
||||
* It's safe to use |unsafeGet()| here because any compartment that is
|
||||
@ -426,11 +430,9 @@ JSContext::global() const
|
||||
* barrier on it. Once the compartment is popped, the handle is no longer
|
||||
* safe to use.
|
||||
*/
|
||||
return js::Handle<js::GlobalObject*>::fromMarkedLocation(compartment()->global_.unsafeGet());
|
||||
return Handle<GlobalObject*>::fromMarkedLocation(compartment_->global_.unsafeGet());
|
||||
}
|
||||
|
||||
namespace js {
|
||||
|
||||
class AssertCompartmentUnchanged
|
||||
{
|
||||
public:
|
||||
|
@ -41,7 +41,7 @@ js::AutoCompartment::~AutoCompartment()
|
||||
namespace js {
|
||||
|
||||
/*
|
||||
* Entering the atoms comaprtment is not possible with the AutoCompartment
|
||||
* Entering the atoms compartment is not possible with AutoCompartment
|
||||
* since the atoms compartment does not have a global.
|
||||
*
|
||||
* Note: since most of the VM assumes that cx->global is non-null, only a
|
||||
@ -50,19 +50,19 @@ namespace js {
|
||||
*/
|
||||
class AutoEnterAtomsCompartment
|
||||
{
|
||||
JSContext *cx;
|
||||
ExclusiveContext *cx;
|
||||
JSCompartment *oldCompartment;
|
||||
public:
|
||||
AutoEnterAtomsCompartment(JSContext *cx)
|
||||
AutoEnterAtomsCompartment(ExclusiveContext *cx)
|
||||
: cx(cx),
|
||||
oldCompartment(cx->compartment())
|
||||
oldCompartment(cx->compartment_)
|
||||
{
|
||||
cx->setCompartment(cx->runtime()->atomsCompartment);
|
||||
cx->privateSetCompartment(cx->runtime_->atomsCompartment);
|
||||
}
|
||||
|
||||
~AutoEnterAtomsCompartment()
|
||||
{
|
||||
cx->setCompartment(oldCompartment);
|
||||
cx->privateSetCompartment(oldCompartment);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include "vm/StringBuffer.h"
|
||||
|
||||
#include "jsobjinlines.h"
|
||||
#include "jsstrinlines.h"
|
||||
|
||||
using namespace js;
|
||||
using namespace js::types;
|
||||
|
@ -30,6 +30,7 @@
|
||||
|
||||
#include "jsfuninlines.h"
|
||||
#include "jsobjinlines.h"
|
||||
#include "jsstrinlines.h"
|
||||
|
||||
using namespace js;
|
||||
using namespace js::gc;
|
||||
|
@ -1128,11 +1128,15 @@ js_ReportIsNotFunction(JSContext *cx, const JS::Value& v)
|
||||
return ReportIsNotFunction(cx, v);
|
||||
}
|
||||
|
||||
#if defined(DEBUG) && defined(JS_THREADSAFE)
|
||||
#ifdef DEBUG
|
||||
JS_PUBLIC_API(bool)
|
||||
js::IsInRequest(JSContext *cx)
|
||||
{
|
||||
#ifdef JS_THREADSAFE
|
||||
return !!cx->runtime()->requestDepth;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -619,6 +619,12 @@ GetNativeStackLimit(const JSRuntime *rt)
|
||||
return PerThreadDataFriendFields::getMainThread(rt)->nativeStackLimit;
|
||||
}
|
||||
|
||||
inline uintptr_t
|
||||
GetNativeStackLimit(JSContext *cx)
|
||||
{
|
||||
return GetNativeStackLimit(GetRuntime(cx));
|
||||
}
|
||||
|
||||
/*
|
||||
* These macros report a stack overflow and run |onerror| if we are close to
|
||||
* using up the C stack. The JS_CHECK_CHROME_RECURSION variant gives us a little
|
||||
@ -628,7 +634,7 @@ GetNativeStackLimit(const JSRuntime *rt)
|
||||
#define JS_CHECK_RECURSION(cx, onerror) \
|
||||
JS_BEGIN_MACRO \
|
||||
int stackDummy_; \
|
||||
if (!JS_CHECK_STACK_SIZE(js::GetNativeStackLimit(js::GetRuntime(cx)), &stackDummy_)) { \
|
||||
if (!JS_CHECK_STACK_SIZE(js::GetNativeStackLimit(cx), &stackDummy_)) { \
|
||||
js_ReportOverRecursed(cx); \
|
||||
onerror; \
|
||||
} \
|
||||
@ -637,7 +643,7 @@ GetNativeStackLimit(const JSRuntime *rt)
|
||||
#define JS_CHECK_RECURSION_WITH_EXTRA_DONT_REPORT(cx, extra, onerror) \
|
||||
JS_BEGIN_MACRO \
|
||||
uint8_t stackDummy_; \
|
||||
if (!JS_CHECK_STACK_SIZE(js::GetNativeStackLimit(js::GetRuntime(cx)), \
|
||||
if (!JS_CHECK_STACK_SIZE(js::GetNativeStackLimit(cx), \
|
||||
&stackDummy_ - (extra))) \
|
||||
{ \
|
||||
onerror; \
|
||||
@ -647,7 +653,7 @@ GetNativeStackLimit(const JSRuntime *rt)
|
||||
#define JS_CHECK_CHROME_RECURSION(cx, onerror) \
|
||||
JS_BEGIN_MACRO \
|
||||
int stackDummy_; \
|
||||
if (!JS_CHECK_STACK_SIZE_WITH_TOLERANCE(js::GetNativeStackLimit(js::GetRuntime(cx)), \
|
||||
if (!JS_CHECK_STACK_SIZE_WITH_TOLERANCE(js::GetNativeStackLimit(cx), \
|
||||
&stackDummy_, \
|
||||
1024 * sizeof(size_t))) \
|
||||
{ \
|
||||
|
@ -1534,7 +1534,7 @@ JSFunction::isBuiltinFunctionConstructor()
|
||||
}
|
||||
|
||||
JSFunction *
|
||||
js::NewFunction(JSContext *cx, HandleObject funobjArg, Native native, unsigned nargs,
|
||||
js::NewFunction(ExclusiveContext *cx, HandleObject funobjArg, Native native, unsigned nargs,
|
||||
JSFunction::Flags flags, HandleObject parent, HandleAtom atom,
|
||||
gc::AllocKind allocKind /* = JSFunction::FinalizeKind */,
|
||||
NewObjectKind newKind /* = GenericObject */)
|
||||
|
@ -356,7 +356,7 @@ class JSFunction : public JSObject
|
||||
inline const js::Value &getExtendedSlot(size_t which) const;
|
||||
|
||||
/* Constructs a new type for the function if necessary. */
|
||||
static bool setTypeForScriptedFunction(JSContext *cx, js::HandleFunction fun,
|
||||
static bool setTypeForScriptedFunction(js::ExclusiveContext *cx, js::HandleFunction fun,
|
||||
bool singleton = false);
|
||||
|
||||
/* GC support. */
|
||||
@ -386,7 +386,7 @@ extern JSBool
|
||||
Function(JSContext *cx, unsigned argc, Value *vp);
|
||||
|
||||
extern JSFunction *
|
||||
NewFunction(JSContext *cx, HandleObject funobj, JSNative native, unsigned nargs,
|
||||
NewFunction(ExclusiveContext *cx, HandleObject funobj, JSNative native, unsigned nargs,
|
||||
JSFunction::Flags flags, HandleObject parent, HandleAtom atom,
|
||||
gc::AllocKind allocKind = JSFunction::FinalizeKind,
|
||||
NewObjectKind newKind = GenericObject);
|
||||
|
@ -393,7 +393,7 @@ TryNewNurseryGCThing(ThreadSafeContext *tcx, size_t thingSize)
|
||||
*/
|
||||
template <typename T, AllowGC allowGC>
|
||||
inline T *
|
||||
NewGCThing(js::ThreadSafeContext *tcx, AllocKind kind, size_t thingSize, InitialHeap heap)
|
||||
NewGCThing(ThreadSafeContext *tcx, AllocKind kind, size_t thingSize, InitialHeap heap)
|
||||
{
|
||||
JS_ASSERT(thingSize == js::gc::Arena::thingSize(kind));
|
||||
|
||||
@ -418,7 +418,7 @@ NewGCThing(js::ThreadSafeContext *tcx, AllocKind kind, size_t thingSize, Initial
|
||||
MaybeCheckStackRoots(cx);
|
||||
}
|
||||
|
||||
#if defined(JSGC_GENERATIONAL)
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
if (tcx->hasNursery() && ShouldNurseryAllocate(tcx->nursery(), kind, heap)) {
|
||||
T *t = TryNewNurseryGCThing<T, allowGC>(tcx, thingSize);
|
||||
if (t)
|
||||
|
@ -2338,9 +2338,9 @@ TypeZone::init(JSContext *cx)
|
||||
}
|
||||
|
||||
TypeObject *
|
||||
TypeCompartment::newTypeObject(JSContext *cx, Class *clasp, Handle<TaggedProto> proto, bool unknown)
|
||||
TypeCompartment::newTypeObject(ExclusiveContext *cx, Class *clasp, Handle<TaggedProto> proto, bool unknown)
|
||||
{
|
||||
JS_ASSERT_IF(proto.isObject(), cx->compartment() == proto.toObject()->compartment());
|
||||
JS_ASSERT_IF(proto.isObject(), cx->isInsideCurrentCompartment(proto.toObject()));
|
||||
|
||||
TypeObject *object = gc::NewGCThing<TypeObject, CanGC>(cx, gc::FINALIZE_TYPE_OBJECT,
|
||||
sizeof(TypeObject), gc::TenuredHeap);
|
||||
@ -5879,11 +5879,14 @@ JSScript::makeAnalysis(JSContext *cx)
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
JSFunction::setTypeForScriptedFunction(JSContext *cx, HandleFunction fun, bool singleton /* = false */)
|
||||
JSFunction::setTypeForScriptedFunction(ExclusiveContext *cxArg, HandleFunction fun,
|
||||
bool singleton /* = false */)
|
||||
{
|
||||
if (!cx->typeInferenceEnabled())
|
||||
if (!cxArg->typeInferenceEnabled())
|
||||
return true;
|
||||
|
||||
JSContext *cx = cxArg->asJSContext();
|
||||
|
||||
if (singleton) {
|
||||
if (!setSingletonType(cx, fun))
|
||||
return false;
|
||||
@ -5954,7 +5957,7 @@ JSObject::splicePrototype(JSContext *cx, Class *clasp, Handle<TaggedProto> proto
|
||||
}
|
||||
|
||||
if (!cx->typeInferenceEnabled()) {
|
||||
TypeObject *type = cx->compartment()->getNewType(cx, clasp, proto);
|
||||
TypeObject *type = cx->getNewType(clasp, proto);
|
||||
if (!type)
|
||||
return false;
|
||||
self->type_ = type;
|
||||
@ -6092,10 +6095,12 @@ JSObject::setNewTypeUnknown(JSContext *cx, Class *clasp, HandleObject obj)
|
||||
}
|
||||
|
||||
TypeObject *
|
||||
JSCompartment::getNewType(JSContext *cx, Class *clasp, TaggedProto proto_, JSFunction *fun_)
|
||||
ExclusiveContext::getNewType(Class *clasp, TaggedProto proto_, JSFunction *fun_)
|
||||
{
|
||||
JS_ASSERT_IF(fun_, proto_.isObject());
|
||||
JS_ASSERT_IF(proto_.isObject(), cx->compartment() == proto_.toObject()->compartment());
|
||||
JS_ASSERT_IF(proto_.isObject(), isInsideCurrentCompartment(proto_.toObject()));
|
||||
|
||||
TypeObjectSet &newTypeObjects = compartment_->newTypeObjects;
|
||||
|
||||
if (!newTypeObjects.initialized() && !newTypeObjects.init())
|
||||
return NULL;
|
||||
@ -6116,15 +6121,15 @@ JSCompartment::getNewType(JSContext *cx, Class *clasp, TaggedProto proto_, JSFun
|
||||
* 'prototype' property of some scripted function.
|
||||
*/
|
||||
if (type->newScript && type->newScript->fun != fun_)
|
||||
type->clearNewScript(cx);
|
||||
type->clearNewScript(asJSContext());
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
Rooted<TaggedProto> proto(cx, proto_);
|
||||
RootedFunction fun(cx, fun_);
|
||||
Rooted<TaggedProto> proto(this, proto_);
|
||||
RootedFunction fun(this, fun_);
|
||||
|
||||
if (proto.isObject() && !proto.toObject()->setDelegate(cx))
|
||||
if (proto.isObject() && !proto.toObject()->setDelegate(this))
|
||||
return NULL;
|
||||
|
||||
bool markUnknown =
|
||||
@ -6132,16 +6137,17 @@ JSCompartment::getNewType(JSContext *cx, Class *clasp, TaggedProto proto_, JSFun
|
||||
? proto.toObject()->lastProperty()->hasObjectFlag(BaseShape::NEW_TYPE_UNKNOWN)
|
||||
: true;
|
||||
|
||||
RootedTypeObject type(cx, types.newTypeObject(cx, clasp, proto, markUnknown));
|
||||
RootedTypeObject type(this, compartment_->types.newTypeObject(this, clasp, proto, markUnknown));
|
||||
if (!type)
|
||||
return NULL;
|
||||
|
||||
if (!newTypeObjects.relookupOrAdd(p, TypeObjectSet::Lookup(clasp, proto), type.get()))
|
||||
return NULL;
|
||||
|
||||
if (!cx->typeInferenceEnabled())
|
||||
if (!typeInferenceEnabled())
|
||||
return type;
|
||||
|
||||
JSContext *cx = asJSContext();
|
||||
AutoEnterAnalysis enter(cx);
|
||||
|
||||
/*
|
||||
@ -6182,12 +6188,6 @@ JSCompartment::getNewType(JSContext *cx, Class *clasp, TaggedProto proto_, JSFun
|
||||
return type;
|
||||
}
|
||||
|
||||
TypeObject *
|
||||
JSObject::getNewType(JSContext *cx, Class *clasp, JSFunction *fun)
|
||||
{
|
||||
return cx->compartment()->getNewType(cx, clasp, this, fun);
|
||||
}
|
||||
|
||||
TypeObject *
|
||||
JSCompartment::getLazyType(JSContext *cx, Class *clasp, TaggedProto proto)
|
||||
{
|
||||
|
@ -1412,7 +1412,7 @@ struct TypeCompartment
|
||||
* or JSProto_Object to indicate a type whose class is unknown (not just
|
||||
* js_ObjectClass).
|
||||
*/
|
||||
TypeObject *newTypeObject(JSContext *cx, Class *clasp, Handle<TaggedProto> proto,
|
||||
TypeObject *newTypeObject(ExclusiveContext *cx, Class *clasp, Handle<TaggedProto> proto,
|
||||
bool unknown = false);
|
||||
|
||||
/* Get or make an object for an allocation site, and add to the allocation site table. */
|
||||
|
@ -509,7 +509,7 @@ GetTypeNewObject(JSContext *cx, JSProtoKey key)
|
||||
RootedObject proto(cx);
|
||||
if (!js_GetClassPrototype(cx, key, &proto))
|
||||
return NULL;
|
||||
return proto->getNewType(cx, GetClassForProtoKey(key));
|
||||
return cx->getNewType(GetClassForProtoKey(key), proto.get());
|
||||
}
|
||||
|
||||
/* Get a type object for the immediate allocation site within a native. */
|
||||
@ -556,12 +556,12 @@ TypeMonitorCall(JSContext *cx, const js::CallArgs &args, bool constructing)
|
||||
}
|
||||
|
||||
inline bool
|
||||
TrackPropertyTypes(JSContext *cx, JSObject *obj, jsid id)
|
||||
TrackPropertyTypes(ExclusiveContext *cx, JSObject *obj, jsid id)
|
||||
{
|
||||
if (!cx->typeInferenceEnabled() || obj->hasLazyType() || obj->type()->unknownProperties())
|
||||
return false;
|
||||
|
||||
if (obj->hasSingletonType() && !obj->type()->maybeGetProperty(id, cx))
|
||||
if (obj->hasSingletonType() && !obj->type()->maybeGetProperty(id, cx->asJSContext()))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
@ -587,21 +587,23 @@ EnsureTrackPropertyTypes(JSContext *cx, JSObject *obj, jsid id)
|
||||
|
||||
/* Add a possible type for a property of obj. */
|
||||
inline void
|
||||
AddTypePropertyId(JSContext *cx, JSObject *obj, jsid id, Type type)
|
||||
AddTypePropertyId(ExclusiveContext *cx, JSObject *obj, jsid id, Type type)
|
||||
{
|
||||
if (cx->typeInferenceEnabled())
|
||||
if (cx->typeInferenceEnabled()) {
|
||||
id = IdToTypeId(id);
|
||||
if (TrackPropertyTypes(cx, obj, id))
|
||||
obj->type()->addPropertyType(cx, id, type);
|
||||
if (TrackPropertyTypes(cx, obj, id))
|
||||
obj->type()->addPropertyType(cx->asJSContext(), id, type);
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
AddTypePropertyId(JSContext *cx, JSObject *obj, jsid id, const Value &value)
|
||||
AddTypePropertyId(ExclusiveContext *cx, JSObject *obj, jsid id, const Value &value)
|
||||
{
|
||||
if (cx->typeInferenceEnabled())
|
||||
if (cx->typeInferenceEnabled()) {
|
||||
id = IdToTypeId(id);
|
||||
if (TrackPropertyTypes(cx, obj, id))
|
||||
obj->type()->addPropertyType(cx, id, value);
|
||||
if (TrackPropertyTypes(cx, obj, id))
|
||||
obj->type()->addPropertyType(cx->asJSContext(), id, value);
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
@ -620,10 +622,10 @@ AddTypeProperty(JSContext *cx, TypeObject *obj, const char *name, const Value &v
|
||||
|
||||
/* Set one or more dynamic flags on a type object. */
|
||||
inline void
|
||||
MarkTypeObjectFlags(JSContext *cx, JSObject *obj, TypeObjectFlags flags)
|
||||
MarkTypeObjectFlags(ExclusiveContext *cx, JSObject *obj, TypeObjectFlags flags)
|
||||
{
|
||||
if (cx->typeInferenceEnabled() && !obj->hasLazyType() && !obj->type()->hasAllFlags(flags))
|
||||
obj->type()->setFlags(cx, flags);
|
||||
obj->type()->setFlags(cx->asJSContext(), flags);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -649,20 +651,21 @@ MarkTypeObjectUnknownProperties(JSContext *cx, TypeObject *obj,
|
||||
* have a getter/setter.
|
||||
*/
|
||||
inline void
|
||||
MarkTypePropertyConfigured(JSContext *cx, HandleObject obj, jsid id)
|
||||
MarkTypePropertyConfigured(ExclusiveContext *cx, HandleObject obj, jsid id)
|
||||
{
|
||||
if (cx->typeInferenceEnabled())
|
||||
if (cx->typeInferenceEnabled()) {
|
||||
id = IdToTypeId(id);
|
||||
if (TrackPropertyTypes(cx, obj, id))
|
||||
obj->type()->markPropertyConfigured(cx, id);
|
||||
if (TrackPropertyTypes(cx, obj, id))
|
||||
obj->type()->markPropertyConfigured(cx->asJSContext(), id);
|
||||
}
|
||||
}
|
||||
|
||||
/* Mark a state change on a particular object. */
|
||||
inline void
|
||||
MarkObjectStateChange(JSContext *cx, JSObject *obj)
|
||||
MarkObjectStateChange(ExclusiveContext *cx, JSObject *obj)
|
||||
{
|
||||
if (cx->typeInferenceEnabled() && !obj->hasLazyType() && !obj->type()->unknownProperties())
|
||||
obj->type()->markStateChange(cx);
|
||||
obj->type()->markStateChange(cx->asJSContext());
|
||||
}
|
||||
|
||||
/*
|
||||
@ -671,17 +674,23 @@ MarkObjectStateChange(JSContext *cx, JSObject *obj)
|
||||
*/
|
||||
|
||||
inline void
|
||||
FixArrayType(JSContext *cx, HandleObject obj)
|
||||
FixArrayType(ExclusiveContext *cxArg, HandleObject obj)
|
||||
{
|
||||
if (cx->typeInferenceEnabled())
|
||||
cx->compartment()->types.fixArrayType(cx, obj);
|
||||
if (cxArg->isJSContext()) {
|
||||
JSContext *cx = cxArg->asJSContext();
|
||||
if (cx->typeInferenceEnabled())
|
||||
cx->compartment()->types.fixArrayType(cx, obj);
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
FixObjectType(JSContext *cx, HandleObject obj)
|
||||
FixObjectType(ExclusiveContext *cxArg, HandleObject obj)
|
||||
{
|
||||
if (cx->typeInferenceEnabled())
|
||||
cx->compartment()->types.fixObjectType(cx, obj);
|
||||
if (cxArg->isJSContext()) {
|
||||
JSContext *cx = cxArg->asJSContext();
|
||||
if (cx->typeInferenceEnabled())
|
||||
cx->compartment()->types.fixObjectType(cx, obj);
|
||||
}
|
||||
}
|
||||
|
||||
/* Interface helpers for JSScript*. */
|
||||
@ -785,7 +794,7 @@ TypeScript::StandardType(JSContext *cx, JSProtoKey key)
|
||||
RootedObject proto(cx);
|
||||
if (!js_GetClassPrototype(cx, key, &proto, NULL))
|
||||
return NULL;
|
||||
return proto->getNewType(cx, GetClassForProtoKey(key));
|
||||
return cx->getNewType(GetClassForProtoKey(key), proto.get());
|
||||
}
|
||||
|
||||
struct AllocationSiteKey {
|
||||
|
@ -342,7 +342,7 @@ GetCustomIterator(JSContext *cx, HandleObject obj, unsigned flags, MutableHandle
|
||||
* trace, so the object we are iterating over is on top of the stack (-1).
|
||||
*/
|
||||
JSAutoByteString bytes;
|
||||
if (!js_AtomToPrintableString(cx, name, &bytes))
|
||||
if (!AtomToPrintableString(cx, name, &bytes))
|
||||
return false;
|
||||
RootedValue val(cx, ObjectValue(*obj));
|
||||
js_ReportValueError2(cx, JSMSG_BAD_TRAP_RETURN_VALUE,
|
||||
@ -375,7 +375,7 @@ static inline PropertyIteratorObject *
|
||||
NewPropertyIteratorObject(JSContext *cx, unsigned flags)
|
||||
{
|
||||
if (flags & JSITER_ENUMERATE) {
|
||||
RootedTypeObject type(cx, cx->compartment()->getNewType(cx, &PropertyIteratorObject::class_, NULL));
|
||||
RootedTypeObject type(cx, cx->getNewType(&PropertyIteratorObject::class_, NULL));
|
||||
if (!type)
|
||||
return NULL;
|
||||
|
||||
|
104
js/src/jsnum.cpp
104
js/src/jsnum.cpp
@ -53,7 +53,8 @@ using mozilla::RangedPtr;
|
||||
* js_strtod_harder to get the correct answer.
|
||||
*/
|
||||
static bool
|
||||
ComputeAccurateDecimalInteger(JSContext *cx, const jschar *start, const jschar *end, double *dp)
|
||||
ComputeAccurateDecimalInteger(ExclusiveContext *cx,
|
||||
const jschar *start, const jschar *end, double *dp)
|
||||
{
|
||||
size_t length = end - start;
|
||||
char *cstr = cx->pod_malloc<char>(length + 1);
|
||||
@ -69,9 +70,9 @@ ComputeAccurateDecimalInteger(JSContext *cx, const jschar *start, const jschar *
|
||||
|
||||
char *estr;
|
||||
int err = 0;
|
||||
*dp = js_strtod_harder(cx->mainThread().dtoaState, cstr, &estr, &err);
|
||||
*dp = js_strtod_harder(cx->dtoaState(), cstr, &estr, &err);
|
||||
if (err == JS_DTOA_ENOMEM) {
|
||||
JS_ReportOutOfMemory(cx);
|
||||
js_ReportOutOfMemory(cx);
|
||||
js_free(cstr);
|
||||
return false;
|
||||
}
|
||||
@ -186,7 +187,7 @@ js::ParseDecimalNumber(const JS::TwoByteChars chars)
|
||||
}
|
||||
|
||||
bool
|
||||
js::GetPrefixInteger(JSContext *cx, const jschar *start, const jschar *end, int base,
|
||||
js::GetPrefixInteger(ExclusiveContext *cx, const jschar *start, const jschar *end, int base,
|
||||
const jschar **endp, double *dp)
|
||||
{
|
||||
JS_ASSERT(start <= end);
|
||||
@ -510,26 +511,24 @@ ToCStringBuf::~ToCStringBuf()
|
||||
|
||||
template <AllowGC allowGC>
|
||||
JSFlatString *
|
||||
js::Int32ToString(ThreadSafeContext *tcx, int32_t si)
|
||||
js::Int32ToString(ThreadSafeContext *cx, int32_t si)
|
||||
{
|
||||
uint32_t ui;
|
||||
if (si >= 0) {
|
||||
if (StaticStrings::hasInt(si))
|
||||
return tcx->staticStrings().getInt(si);
|
||||
return cx->staticStrings().getInt(si);
|
||||
ui = si;
|
||||
} else {
|
||||
ui = uint32_t(-si);
|
||||
JS_ASSERT_IF(si == INT32_MIN, ui == uint32_t(INT32_MAX) + 1);
|
||||
}
|
||||
|
||||
JSCompartment *c = NULL;
|
||||
if (tcx->isJSContext()) {
|
||||
c = tcx->asJSContext()->compartment();
|
||||
if (JSFlatString *str = c->dtoaCache.lookup(10, si))
|
||||
if (cx->isExclusiveContext()) {
|
||||
if (JSFlatString *str = cx->asExclusiveContext()->dtoaCache().lookup(10, si))
|
||||
return str;
|
||||
}
|
||||
|
||||
JSShortString *str = js_NewGCShortString<allowGC>(tcx);
|
||||
JSShortString *str = js_NewGCShortString<allowGC>(cx);
|
||||
if (!str)
|
||||
return NULL;
|
||||
|
||||
@ -544,12 +543,8 @@ js::Int32ToString(ThreadSafeContext *tcx, int32_t si)
|
||||
jschar *dst = str->init(end - start);
|
||||
PodCopy(dst, start.get(), end - start + 1);
|
||||
|
||||
/*
|
||||
* Only attempt to cache the result if we have a JSContext, as it is
|
||||
* racy.
|
||||
*/
|
||||
if (c)
|
||||
c->dtoaCache.cache(10, si, str);
|
||||
if (cx->isExclusiveContext())
|
||||
cx->asExclusiveContext()->dtoaCache().cache(10, si, str);
|
||||
return str;
|
||||
}
|
||||
|
||||
@ -1194,7 +1189,7 @@ js_InitNumberClass(JSContext *cx, HandleObject obj)
|
||||
}
|
||||
|
||||
static char *
|
||||
FracNumberToCString(ThreadSafeContext *tcx, ToCStringBuf *cbuf, double d, int base = 10)
|
||||
FracNumberToCString(ThreadSafeContext *cx, ToCStringBuf *cbuf, double d, int base = 10)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
{
|
||||
@ -1218,7 +1213,7 @@ FracNumberToCString(ThreadSafeContext *tcx, ToCStringBuf *cbuf, double d, int ba
|
||||
converter.ToShortest(d, &builder);
|
||||
numStr = builder.Finalize();
|
||||
} else {
|
||||
numStr = cbuf->dbuf = js_dtobasestr(tcx->perThreadData->dtoaState, base, d);
|
||||
numStr = cbuf->dbuf = js_dtobasestr(cx->dtoaState(), base, d);
|
||||
}
|
||||
return numStr;
|
||||
}
|
||||
@ -1234,7 +1229,7 @@ js::NumberToCString(JSContext *cx, ToCStringBuf *cbuf, double d, int base/* = 10
|
||||
|
||||
template <AllowGC allowGC>
|
||||
static JSString * JS_FASTCALL
|
||||
js_NumberToStringWithBase(ThreadSafeContext *tcx, double d, int base)
|
||||
js_NumberToStringWithBase(ThreadSafeContext *cx, double d, int base)
|
||||
{
|
||||
ToCStringBuf cbuf;
|
||||
char *numStr;
|
||||
@ -1247,38 +1242,34 @@ js_NumberToStringWithBase(ThreadSafeContext *tcx, double d, int base)
|
||||
if (base < 2 || base > 36)
|
||||
return NULL;
|
||||
|
||||
JSCompartment *c = NULL;
|
||||
JSContext *cx = NULL;
|
||||
if (tcx->isJSContext()) {
|
||||
cx = tcx->asJSContext();
|
||||
c = cx->compartment();
|
||||
}
|
||||
|
||||
int32_t i;
|
||||
if (mozilla::DoubleIsInt32(d, &i)) {
|
||||
if (base == 10 && StaticStrings::hasInt(i))
|
||||
return tcx->staticStrings().getInt(i);
|
||||
return cx->staticStrings().getInt(i);
|
||||
if (unsigned(i) < unsigned(base)) {
|
||||
if (i < 10)
|
||||
return tcx->staticStrings().getInt(i);
|
||||
return cx->staticStrings().getInt(i);
|
||||
jschar c = 'a' + i - 10;
|
||||
JS_ASSERT(StaticStrings::hasUnit(c));
|
||||
return tcx->staticStrings().getUnit(c);
|
||||
return cx->staticStrings().getUnit(c);
|
||||
}
|
||||
|
||||
if (JSFlatString *str = c ? c->dtoaCache.lookup(base, d) : NULL)
|
||||
return str;
|
||||
if (cx->isExclusiveContext()) {
|
||||
if (JSFlatString *str = cx->asExclusiveContext()->dtoaCache().lookup(base, d))
|
||||
return str;
|
||||
}
|
||||
|
||||
numStr = IntToCString(&cbuf, i, base);
|
||||
JS_ASSERT(!cbuf.dbuf && numStr >= cbuf.sbuf && numStr < cbuf.sbuf + cbuf.sbufSize);
|
||||
} else {
|
||||
if (JSFlatString *str = c ? c->dtoaCache.lookup(base, d) : NULL)
|
||||
return str;
|
||||
if (cx->isExclusiveContext()) {
|
||||
if (JSFlatString *str = cx->asExclusiveContext()->dtoaCache().lookup(base, d))
|
||||
return str;
|
||||
}
|
||||
|
||||
numStr = FracNumberToCString(tcx, &cbuf, d, base);
|
||||
numStr = FracNumberToCString(cx, &cbuf, d, base);
|
||||
if (!numStr) {
|
||||
if (cx)
|
||||
JS_ReportOutOfMemory(cx);
|
||||
js_ReportOutOfMemory(cx);
|
||||
return NULL;
|
||||
}
|
||||
JS_ASSERT_IF(base == 10,
|
||||
@ -1287,29 +1278,26 @@ js_NumberToStringWithBase(ThreadSafeContext *tcx, double d, int base)
|
||||
cbuf.dbuf && cbuf.dbuf == numStr);
|
||||
}
|
||||
|
||||
JSFlatString *s = js_NewStringCopyZ<allowGC>(tcx, numStr);
|
||||
JSFlatString *s = js_NewStringCopyZ<allowGC>(cx, numStr);
|
||||
|
||||
if (cx->isExclusiveContext())
|
||||
cx->asExclusiveContext()->dtoaCache().cache(base, d, s);
|
||||
|
||||
/*
|
||||
* We will only cache dtoa results if we have a JSContext, as it is
|
||||
* racy.
|
||||
*/
|
||||
if (c)
|
||||
c->dtoaCache.cache(base, d, s);
|
||||
return s;
|
||||
}
|
||||
|
||||
template <AllowGC allowGC>
|
||||
JSString *
|
||||
js_NumberToString(ThreadSafeContext *tcx, double d)
|
||||
js_NumberToString(ThreadSafeContext *cx, double d)
|
||||
{
|
||||
return js_NumberToStringWithBase<allowGC>(tcx, d, 10);
|
||||
return js_NumberToStringWithBase<allowGC>(cx, d, 10);
|
||||
}
|
||||
|
||||
template JSString *
|
||||
js_NumberToString<CanGC>(ThreadSafeContext *tcx, double d);
|
||||
js_NumberToString<CanGC>(ThreadSafeContext *cx, double d);
|
||||
|
||||
template JSString *
|
||||
js_NumberToString<NoGC>(ThreadSafeContext *tcx, double d);
|
||||
js_NumberToString<NoGC>(ThreadSafeContext *cx, double d);
|
||||
|
||||
JSFlatString *
|
||||
js::NumberToString(JSContext *cx, double d)
|
||||
@ -1372,7 +1360,7 @@ js::NumberValueToStringBuffer(JSContext *cx, const Value &v, StringBuffer &sb)
|
||||
}
|
||||
|
||||
bool
|
||||
js::StringToNumber(JSContext *cx, JSString *str, double *result)
|
||||
js::StringToNumber(ExclusiveContext *cx, JSString *str, double *result)
|
||||
{
|
||||
size_t length = str->length();
|
||||
const jschar *chars = str->getChars(NULL);
|
||||
@ -1436,8 +1424,9 @@ js::StringToNumber(JSContext *cx, JSString *str, double *result)
|
||||
#if defined(_MSC_VER)
|
||||
# pragma optimize("g", off)
|
||||
#endif
|
||||
JS_PUBLIC_API(bool)
|
||||
js::ToNumberSlow(JSContext *cx, Value v, double *out)
|
||||
|
||||
bool
|
||||
js::ToNumberSlow(ExclusiveContext *cx, Value v, double *out)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
/*
|
||||
@ -1485,7 +1474,7 @@ js::ToNumberSlow(JSContext *cx, Value v, double *out)
|
||||
|
||||
JS_ASSERT(v.isObject());
|
||||
RootedValue v2(cx, v);
|
||||
if (!ToPrimitive(cx, JSTYPE_NUMBER, &v2))
|
||||
if (!ToPrimitive(cx->asJSContext(), JSTYPE_NUMBER, &v2))
|
||||
return false;
|
||||
v = v2;
|
||||
if (v.isObject())
|
||||
@ -1495,6 +1484,13 @@ js::ToNumberSlow(JSContext *cx, Value v, double *out)
|
||||
*out = js_NaN;
|
||||
return true;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
js::ToNumberSlow(JSContext *cx, Value v, double *out)
|
||||
{
|
||||
return ToNumberSlow(static_cast<ExclusiveContext *>(cx), v, out);
|
||||
}
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma optimize("", on)
|
||||
#endif
|
||||
@ -1601,7 +1597,7 @@ js::ToUint16Slow(JSContext *cx, const Value &v, uint16_t *out)
|
||||
}
|
||||
|
||||
JSBool
|
||||
js_strtod(JSContext *cx, const jschar *s, const jschar *send,
|
||||
js_strtod(ExclusiveContext *cx, const jschar *s, const jschar *send,
|
||||
const jschar **ep, double *dp)
|
||||
{
|
||||
size_t i;
|
||||
@ -1637,7 +1633,7 @@ js_strtod(JSContext *cx, const jschar *s, const jschar *send,
|
||||
estr = istr + 8;
|
||||
} else {
|
||||
int err;
|
||||
d = js_strtod_harder(cx->mainThread().dtoaState, cstr, &estr, &err);
|
||||
d = js_strtod_harder(cx->dtoaState(), cstr, &estr, &err);
|
||||
if (d == HUGE_VAL)
|
||||
d = js_PositiveInfinity;
|
||||
else if (d == -HUGE_VAL)
|
||||
|
@ -55,7 +55,7 @@ namespace js {
|
||||
|
||||
template <AllowGC allowGC>
|
||||
extern JSFlatString *
|
||||
Int32ToString(ThreadSafeContext *tcx, int32_t i);
|
||||
Int32ToString(ThreadSafeContext *cx, int32_t i);
|
||||
|
||||
/*
|
||||
* Convert an integer or double (contained in the given value) to a string and
|
||||
@ -128,11 +128,11 @@ ParseDecimalNumber(const JS::TwoByteChars chars);
|
||||
* *dp == 0 and *endp == start upon return.
|
||||
*/
|
||||
extern bool
|
||||
GetPrefixInteger(JSContext *cx, const jschar *start, const jschar *end, int base,
|
||||
GetPrefixInteger(ExclusiveContext *cx, const jschar *start, const jschar *end, int base,
|
||||
const jschar **endp, double *dp);
|
||||
|
||||
extern bool
|
||||
StringToNumber(JSContext *cx, JSString *str, double *result);
|
||||
StringToNumber(ExclusiveContext *cx, JSString *str, double *result);
|
||||
|
||||
/* ES5 9.3 ToNumber, overwriting *vp with the appropriate number value. */
|
||||
JS_ALWAYS_INLINE bool
|
||||
@ -169,7 +169,7 @@ num_parseInt(JSContext *cx, unsigned argc, Value *vp);
|
||||
* Return false if out of memory.
|
||||
*/
|
||||
extern JSBool
|
||||
js_strtod(JSContext *cx, const jschar *s, const jschar *send,
|
||||
js_strtod(js::ExclusiveContext *cx, const jschar *s, const jschar *send,
|
||||
const jschar **ep, double *dp);
|
||||
|
||||
extern JSBool
|
||||
@ -263,6 +263,21 @@ SafeMul(int32_t one, int32_t two, int32_t *res)
|
||||
return ores == (int64_t)*res;
|
||||
}
|
||||
|
||||
extern bool
|
||||
ToNumberSlow(ExclusiveContext *cx, Value v, double *dp);
|
||||
|
||||
// Variant of ToNumber which takes an ExclusiveContext instead of a JSContext.
|
||||
// ToNumber is part of the API and can't use ExclusiveContext directly.
|
||||
JS_ALWAYS_INLINE bool
|
||||
ToNumber(ExclusiveContext *cx, const Value &v, double *out)
|
||||
{
|
||||
if (v.isNumber()) {
|
||||
*out = v.toNumber();
|
||||
return true;
|
||||
}
|
||||
return ToNumberSlow(cx, v, out);
|
||||
}
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
#endif /* jsnum_h */
|
||||
|
303
js/src/jsobj.cpp
303
js/src/jsobj.cpp
@ -1291,13 +1291,13 @@ NewObjectGCKind(js::Class *clasp)
|
||||
}
|
||||
|
||||
static inline JSObject *
|
||||
NewObject(JSContext *cx, Class *clasp, types::TypeObject *type_, JSObject *parent,
|
||||
NewObject(ExclusiveContext *cx, Class *clasp, types::TypeObject *type_, JSObject *parent,
|
||||
gc::AllocKind kind, NewObjectKind newKind)
|
||||
{
|
||||
JS_ASSERT(clasp != &ArrayObject::class_);
|
||||
JS_ASSERT_IF(clasp == &JSFunction::class_,
|
||||
kind == JSFunction::FinalizeKind || kind == JSFunction::ExtendedFinalizeKind);
|
||||
JS_ASSERT_IF(parent, &parent->global() == cx->compartment()->maybeGlobal());
|
||||
JS_ASSERT_IF(parent, &parent->global() == cx->global());
|
||||
|
||||
RootedTypeObject type(cx, type_);
|
||||
|
||||
@ -1327,7 +1327,7 @@ NewObject(JSContext *cx, Class *clasp, types::TypeObject *type_, JSObject *paren
|
||||
* slices, and it will prevent any future incremental GCs.
|
||||
*/
|
||||
if (clasp->trace && !(clasp->flags & JSCLASS_IMPLEMENTS_BARRIERS))
|
||||
cx->runtime()->gcIncrementalEnabled = false;
|
||||
cx->asJSContext()->runtime()->gcIncrementalEnabled = false;
|
||||
|
||||
Probes::createObject(cx, obj);
|
||||
return obj;
|
||||
@ -1343,33 +1343,34 @@ NewObjectCache::fillProto(EntryIndex entry, Class *clasp, js::TaggedProto proto,
|
||||
}
|
||||
|
||||
JSObject *
|
||||
js::NewObjectWithGivenProto(JSContext *cx, js::Class *clasp,
|
||||
js::NewObjectWithGivenProto(ExclusiveContext *cxArg, js::Class *clasp,
|
||||
js::TaggedProto proto_, JSObject *parent_,
|
||||
gc::AllocKind allocKind, NewObjectKind newKind)
|
||||
{
|
||||
Rooted<TaggedProto> proto(cx, proto_);
|
||||
RootedObject parent(cx, parent_);
|
||||
Rooted<TaggedProto> proto(cxArg, proto_);
|
||||
RootedObject parent(cxArg, parent_);
|
||||
|
||||
if (CanBeFinalizedInBackground(allocKind, clasp))
|
||||
allocKind = GetBackgroundAllocKind(allocKind);
|
||||
|
||||
NewObjectCache &cache = cx->runtime()->newObjectCache;
|
||||
|
||||
NewObjectCache::EntryIndex entry = -1;
|
||||
if (proto.isObject() &&
|
||||
newKind == GenericObject &&
|
||||
!cx->compartment()->objectMetadataCallback &&
|
||||
(!parent || parent == proto.toObject()->getParent()) &&
|
||||
!proto.toObject()->is<GlobalObject>())
|
||||
{
|
||||
if (cache.lookupProto(clasp, proto.toObject(), allocKind, &entry)) {
|
||||
JSObject *obj = cache.newObjectFromHit(cx, entry, GetInitialHeap(newKind, clasp));
|
||||
if (obj)
|
||||
return obj;
|
||||
if (JSContext *cx = cxArg->maybeJSContext()) {
|
||||
NewObjectCache &cache = cx->runtime()->newObjectCache;
|
||||
if (proto.isObject() &&
|
||||
newKind == GenericObject &&
|
||||
!cx->compartment()->objectMetadataCallback &&
|
||||
(!parent || parent == proto.toObject()->getParent()) &&
|
||||
!proto.toObject()->is<GlobalObject>())
|
||||
{
|
||||
if (cache.lookupProto(clasp, proto.toObject(), allocKind, &entry)) {
|
||||
JSObject *obj = cache.newObjectFromHit(cx, entry, GetInitialHeap(newKind, clasp));
|
||||
if (obj)
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
types::TypeObject *type = cx->compartment()->getNewType(cx, clasp, proto, NULL);
|
||||
types::TypeObject *type = cxArg->getNewType(clasp, proto, NULL);
|
||||
if (!type)
|
||||
return NULL;
|
||||
|
||||
@ -1380,28 +1381,31 @@ js::NewObjectWithGivenProto(JSContext *cx, js::Class *clasp,
|
||||
if (!parent && proto.isObject())
|
||||
parent = proto.toObject()->getParent();
|
||||
|
||||
RootedObject obj(cx, NewObject(cx, clasp, type, parent, allocKind, newKind));
|
||||
RootedObject obj(cxArg, NewObject(cxArg, clasp, type, parent, allocKind, newKind));
|
||||
if (!obj)
|
||||
return NULL;
|
||||
|
||||
if (entry != -1 && !obj->hasDynamicSlots())
|
||||
cache.fillProto(entry, clasp, proto, allocKind, obj);
|
||||
if (entry != -1 && !obj->hasDynamicSlots()) {
|
||||
cxArg->asJSContext()->runtime()->newObjectCache.fillProto(entry, clasp,
|
||||
proto, allocKind, obj);
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
JSObject *
|
||||
js::NewObjectWithClassProtoCommon(JSContext *cx, js::Class *clasp, JSObject *protoArg, JSObject *parentArg,
|
||||
js::NewObjectWithClassProtoCommon(ExclusiveContext *cxArg,
|
||||
js::Class *clasp, JSObject *protoArg, JSObject *parentArg,
|
||||
gc::AllocKind allocKind, NewObjectKind newKind)
|
||||
{
|
||||
if (protoArg)
|
||||
return NewObjectWithGivenProto(cx, clasp, protoArg, parentArg, allocKind, newKind);
|
||||
return NewObjectWithGivenProto(cxArg, clasp, protoArg, parentArg, allocKind, newKind);
|
||||
|
||||
if (CanBeFinalizedInBackground(allocKind, clasp))
|
||||
allocKind = GetBackgroundAllocKind(allocKind);
|
||||
|
||||
if (!parentArg)
|
||||
parentArg = cx->global();
|
||||
parentArg = cxArg->global();
|
||||
|
||||
/*
|
||||
* Use the object cache, except for classes without a cached proto key.
|
||||
@ -1414,37 +1418,41 @@ js::NewObjectWithClassProtoCommon(JSContext *cx, js::Class *clasp, JSObject *pro
|
||||
*/
|
||||
JSProtoKey protoKey = GetClassProtoKey(clasp);
|
||||
|
||||
NewObjectCache &cache = cx->runtime()->newObjectCache;
|
||||
|
||||
NewObjectCache::EntryIndex entry = -1;
|
||||
if (parentArg->is<GlobalObject>() &&
|
||||
protoKey != JSProto_Null &&
|
||||
newKind == GenericObject &&
|
||||
!cx->compartment()->objectMetadataCallback)
|
||||
{
|
||||
if (cache.lookupGlobal(clasp, &parentArg->as<GlobalObject>(), allocKind, &entry)) {
|
||||
JSObject *obj = cache.newObjectFromHit(cx, entry, GetInitialHeap(newKind, clasp));
|
||||
if (obj)
|
||||
return obj;
|
||||
if (JSContext *cx = cxArg->maybeJSContext()) {
|
||||
NewObjectCache &cache = cx->runtime()->newObjectCache;
|
||||
if (parentArg->is<GlobalObject>() &&
|
||||
protoKey != JSProto_Null &&
|
||||
newKind == GenericObject &&
|
||||
!cx->compartment()->objectMetadataCallback)
|
||||
{
|
||||
if (cache.lookupGlobal(clasp, &parentArg->as<GlobalObject>(), allocKind, &entry)) {
|
||||
JSObject *obj = cache.newObjectFromHit(cx, entry, GetInitialHeap(newKind, clasp));
|
||||
if (obj)
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RootedObject parent(cx, parentArg);
|
||||
RootedObject proto(cx, protoArg);
|
||||
RootedObject parent(cxArg, parentArg);
|
||||
RootedObject proto(cxArg, protoArg);
|
||||
|
||||
if (!FindProto(cx, clasp, &proto))
|
||||
if (!FindProto(cxArg, clasp, &proto))
|
||||
return NULL;
|
||||
|
||||
types::TypeObject *type = proto->getNewType(cx, clasp);
|
||||
types::TypeObject *type = cxArg->getNewType(clasp, proto.get());
|
||||
if (!type)
|
||||
return NULL;
|
||||
|
||||
JSObject *obj = NewObject(cx, clasp, type, parent, allocKind, newKind);
|
||||
JSObject *obj = NewObject(cxArg, clasp, type, parent, allocKind, newKind);
|
||||
if (!obj)
|
||||
return NULL;
|
||||
|
||||
if (entry != -1 && !obj->hasDynamicSlots())
|
||||
cache.fillGlobal(entry, clasp, &parent->as<GlobalObject>(), allocKind, obj);
|
||||
if (entry != -1 && !obj->hasDynamicSlots()) {
|
||||
cxArg->asJSContext()->runtime()->newObjectCache.fillGlobal(entry, clasp,
|
||||
&parent->as<GlobalObject>(),
|
||||
allocKind, obj);
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
@ -1597,7 +1605,7 @@ js::CreateThisForFunctionWithProto(JSContext *cx, HandleObject callee, JSObject
|
||||
RootedObject res(cx);
|
||||
|
||||
if (proto) {
|
||||
RootedTypeObject type(cx, proto->getNewType(cx, &ObjectClass, &callee->as<JSFunction>()));
|
||||
RootedTypeObject type(cx, cx->getNewType(&ObjectClass, proto, &callee->as<JSFunction>()));
|
||||
if (!type)
|
||||
return NULL;
|
||||
res = CreateThisForFunctionWithType(cx, type, callee->getParent(), newKind);
|
||||
@ -1864,7 +1872,7 @@ JSObject *
|
||||
js::CloneObjectLiteral(JSContext *cx, HandleObject parent, HandleObject srcObj)
|
||||
{
|
||||
Rooted<TypeObject*> typeObj(cx);
|
||||
typeObj = cx->global()->getOrCreateObjectPrototype(cx)->getNewType(cx, &ObjectClass);
|
||||
typeObj = cx->getNewType(&ObjectClass, cx->global()->getOrCreateObjectPrototype(cx));
|
||||
|
||||
JS_ASSERT(srcObj->getClass() == &ObjectClass);
|
||||
AllocKind kind = GetBackgroundAllocKind(GuessObjectGCKind(srcObj->numFixedSlots()));
|
||||
@ -2452,7 +2460,8 @@ js_InitClass(JSContext *cx, HandleObject obj, JSObject *protoProto_,
|
||||
}
|
||||
|
||||
/* static */ inline bool
|
||||
JSObject::updateSlotsForSpan(JSContext *cx, HandleObject obj, size_t oldSpan, size_t newSpan)
|
||||
JSObject::updateSlotsForSpan(ExclusiveContext *cx,
|
||||
HandleObject obj, size_t oldSpan, size_t newSpan)
|
||||
{
|
||||
JS_ASSERT(oldSpan != newSpan);
|
||||
|
||||
@ -2480,7 +2489,7 @@ JSObject::updateSlotsForSpan(JSContext *cx, HandleObject obj, size_t oldSpan, si
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
JSObject::setLastProperty(JSContext *cx, HandleObject obj, HandleShape shape)
|
||||
JSObject::setLastProperty(ExclusiveContext *cx, HandleObject obj, HandleShape shape)
|
||||
{
|
||||
JS_ASSERT(!obj->inDictionaryMode());
|
||||
JS_ASSERT(!shape->inDictionary());
|
||||
@ -2503,7 +2512,7 @@ JSObject::setLastProperty(JSContext *cx, HandleObject obj, HandleShape shape)
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
JSObject::setSlotSpan(JSContext *cx, HandleObject obj, uint32_t span)
|
||||
JSObject::setSlotSpan(ExclusiveContext *cx, HandleObject obj, uint32_t span)
|
||||
{
|
||||
JS_ASSERT(obj->inDictionaryMode());
|
||||
|
||||
@ -2519,29 +2528,32 @@ JSObject::setSlotSpan(JSContext *cx, HandleObject obj, uint32_t span)
|
||||
}
|
||||
|
||||
static HeapSlot *
|
||||
AllocateSlots(JSContext *cx, JSObject *obj, uint32_t nslots)
|
||||
AllocateSlots(ExclusiveContext *cx, JSObject *obj, uint32_t nslots)
|
||||
{
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
return cx->runtime()->gcNursery.allocateSlots(cx, obj, nslots);
|
||||
#else
|
||||
return cx->pod_malloc<HeapSlot>(nslots);
|
||||
if (cx->isJSContext())
|
||||
return cx->asJSContext()->runtime()->gcNursery.allocateSlots(cx->asJSContext(), obj, nslots);
|
||||
#endif
|
||||
return cx->pod_malloc<HeapSlot>(nslots);
|
||||
}
|
||||
|
||||
static HeapSlot *
|
||||
ReallocateSlots(JSContext *cx, JSObject *obj, HeapSlot *oldSlots,
|
||||
ReallocateSlots(ExclusiveContext *cx, JSObject *obj, HeapSlot *oldSlots,
|
||||
uint32_t oldCount, uint32_t newCount)
|
||||
{
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
return cx->runtime()->gcNursery.reallocateSlots(cx, obj, oldSlots, oldCount, newCount);
|
||||
#else
|
||||
if (cx->isJSContext()) {
|
||||
return cx->asJSContext()->runtime()->gcNursery.reallocateSlots(cx->asJSContext(),
|
||||
obj, oldSlots,
|
||||
oldCount, newCount);
|
||||
}
|
||||
#endif
|
||||
return (HeapSlot *)cx->realloc_(oldSlots, oldCount * sizeof(HeapSlot),
|
||||
newCount * sizeof(HeapSlot));
|
||||
#endif
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
JSObject::growSlots(JSContext *cx, HandleObject obj, uint32_t oldCount, uint32_t newCount)
|
||||
JSObject::growSlots(ExclusiveContext *cx, HandleObject obj, uint32_t oldCount, uint32_t newCount)
|
||||
{
|
||||
JS_ASSERT(newCount > oldCount);
|
||||
JS_ASSERT(newCount >= SLOT_CAPACITY_MIN);
|
||||
@ -2562,18 +2574,22 @@ JSObject::growSlots(JSContext *cx, HandleObject obj, uint32_t oldCount, uint32_t
|
||||
if (!obj->hasLazyType() && !oldCount && obj->type()->newScript) {
|
||||
gc::AllocKind kind = obj->type()->newScript->allocKind;
|
||||
uint32_t newScriptSlots = gc::GetGCKindSlots(kind);
|
||||
if (newScriptSlots == obj->numFixedSlots() && gc::TryIncrementAllocKind(&kind)) {
|
||||
AutoEnterAnalysis enter(cx);
|
||||
if (newScriptSlots == obj->numFixedSlots() &&
|
||||
gc::TryIncrementAllocKind(&kind) &&
|
||||
cx->isJSContext())
|
||||
{
|
||||
JSContext *ncx = cx->asJSContext();
|
||||
AutoEnterAnalysis enter(ncx);
|
||||
|
||||
Rooted<TypeObject*> typeObj(cx, obj->type());
|
||||
RootedShape shape(cx, typeObj->newScript->shape);
|
||||
JSObject *reshapedObj = NewReshapedObject(cx, typeObj, obj->getParent(), kind, shape);
|
||||
JSObject *reshapedObj = NewReshapedObject(ncx, typeObj, obj->getParent(), kind, shape);
|
||||
if (!reshapedObj)
|
||||
return false;
|
||||
|
||||
typeObj->newScript->allocKind = kind;
|
||||
typeObj->newScript->shape = reshapedObj->lastProperty();
|
||||
typeObj->markStateChange(cx);
|
||||
typeObj->markStateChange(ncx);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2602,16 +2618,16 @@ JSObject::growSlots(JSContext *cx, HandleObject obj, uint32_t oldCount, uint32_t
|
||||
}
|
||||
|
||||
static void
|
||||
FreeSlots(JSContext *cx, HeapSlot *slots)
|
||||
FreeSlots(ExclusiveContext *cx, HeapSlot *slots)
|
||||
{
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
if (!cx->runtime()->gcNursery.isInside(slots))
|
||||
if (!cx->isJSContext() || !cx->asJSContext()->runtime()->gcNursery.isInside(slots))
|
||||
#endif
|
||||
js_free(slots);
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
JSObject::shrinkSlots(JSContext *cx, HandleObject obj, uint32_t oldCount, uint32_t newCount)
|
||||
JSObject::shrinkSlots(ExclusiveContext *cx, HandleObject obj, uint32_t oldCount, uint32_t newCount)
|
||||
{
|
||||
JS_ASSERT(newCount < oldCount);
|
||||
|
||||
@ -2636,7 +2652,7 @@ JSObject::shrinkSlots(JSContext *cx, HandleObject obj, uint32_t oldCount, uint32
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
JSObject::sparsifyDenseElement(JSContext *cx, HandleObject obj, uint32_t index)
|
||||
JSObject::sparsifyDenseElement(ExclusiveContext *cx, HandleObject obj, uint32_t index)
|
||||
{
|
||||
RootedValue value(cx, obj->getDenseElement(index));
|
||||
JS_ASSERT(!value.isMagic(JS_ELEMENTS_HOLE));
|
||||
@ -2656,7 +2672,7 @@ JSObject::sparsifyDenseElement(JSContext *cx, HandleObject obj, uint32_t index)
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
JSObject::sparsifyDenseElements(JSContext *cx, HandleObject obj)
|
||||
JSObject::sparsifyDenseElements(js::ExclusiveContext *cx, HandleObject obj)
|
||||
{
|
||||
uint32_t initialized = obj->getDenseInitializedLength();
|
||||
|
||||
@ -2715,7 +2731,7 @@ JSObject::willBeSparseElements(uint32_t requiredCapacity, uint32_t newElementsHi
|
||||
}
|
||||
|
||||
/* static */ JSObject::EnsureDenseResult
|
||||
JSObject::maybeDensifySparseElements(JSContext *cx, HandleObject obj)
|
||||
JSObject::maybeDensifySparseElements(js::ExclusiveContext *cx, HandleObject obj)
|
||||
{
|
||||
/*
|
||||
* Wait until after the object goes into dictionary mode, which must happen
|
||||
@ -2921,7 +2937,7 @@ JSObject::growElements(ThreadSafeContext *tcx, uint32_t newcap)
|
||||
}
|
||||
|
||||
void
|
||||
JSObject::shrinkElements(JSContext *cx, uint32_t newcap)
|
||||
JSObject::shrinkElements(ThreadSafeContext *cx, uint32_t newcap)
|
||||
{
|
||||
uint32_t oldcap = getDenseCapacity();
|
||||
JS_ASSERT(newcap <= oldcap);
|
||||
@ -3031,7 +3047,7 @@ js::SetClassAndProto(JSContext *cx, HandleObject obj,
|
||||
return false;
|
||||
}
|
||||
|
||||
TypeObject *type = cx->compartment()->getNewType(cx, clasp, proto);
|
||||
TypeObject *type = cx->getNewType(clasp, proto);
|
||||
if (!type)
|
||||
return false;
|
||||
|
||||
@ -3051,9 +3067,9 @@ js::SetClassAndProto(JSContext *cx, HandleObject obj,
|
||||
}
|
||||
|
||||
bool
|
||||
js_GetClassObject(JSContext *cx, JSObject *obj, JSProtoKey key, MutableHandleObject objp)
|
||||
js_GetClassObject(ExclusiveContext *cxArg, JSObject *obj, JSProtoKey key, MutableHandleObject objp)
|
||||
{
|
||||
RootedObject global(cx, &obj->global());
|
||||
RootedObject global(cxArg, &obj->global());
|
||||
if (!global->is<GlobalObject>()) {
|
||||
objp.set(NULL);
|
||||
return true;
|
||||
@ -3065,6 +3081,9 @@ js_GetClassObject(JSContext *cx, JSObject *obj, JSProtoKey key, MutableHandleObj
|
||||
return true;
|
||||
}
|
||||
|
||||
// Classes can only be initialized on the main thread.
|
||||
JSContext *cx = cxArg->asJSContext();
|
||||
|
||||
RootedId name(cx, NameToId(ClassName(key, cx)));
|
||||
AutoResolving resolving(cx, global, name);
|
||||
if (resolving.alreadyStarted()) {
|
||||
@ -3110,7 +3129,7 @@ js_IdentifyClassPrototype(JSObject *obj)
|
||||
}
|
||||
|
||||
bool
|
||||
js_FindClassObject(JSContext *cx, JSProtoKey protoKey, MutableHandleValue vp, Class *clasp)
|
||||
js_FindClassObject(ExclusiveContext *cx, JSProtoKey protoKey, MutableHandleValue vp, Class *clasp)
|
||||
{
|
||||
RootedId id(cx);
|
||||
|
||||
@ -3149,7 +3168,7 @@ js_FindClassObject(JSContext *cx, JSProtoKey protoKey, MutableHandleValue vp, Cl
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
JSObject::allocSlot(JSContext *cx, HandleObject obj, uint32_t *slotp)
|
||||
JSObject::allocSlot(ExclusiveContext *cx, HandleObject obj, uint32_t *slotp)
|
||||
{
|
||||
uint32_t slot = obj->slotSpan();
|
||||
JS_ASSERT(slot >= JSSLOT_FREE(obj->getClass()));
|
||||
@ -3216,7 +3235,7 @@ JSObject::freeSlot(uint32_t slot)
|
||||
}
|
||||
|
||||
static bool
|
||||
PurgeProtoChain(JSContext *cx, JSObject *objArg, HandleId id)
|
||||
PurgeProtoChain(ExclusiveContext *cx, JSObject *objArg, HandleId id)
|
||||
{
|
||||
/* Root locally so we can re-assign. */
|
||||
RootedObject obj(cx, objArg);
|
||||
@ -3242,7 +3261,7 @@ PurgeProtoChain(JSContext *cx, JSObject *objArg, HandleId id)
|
||||
}
|
||||
|
||||
static bool
|
||||
PurgeScopeChainHelper(JSContext *cx, HandleObject objArg, HandleId id)
|
||||
PurgeScopeChainHelper(ExclusiveContext *cx, HandleObject objArg, HandleId id)
|
||||
{
|
||||
/* Re-root locally so we can re-assign. */
|
||||
RootedObject obj(cx, objArg);
|
||||
@ -3279,14 +3298,13 @@ PurgeScopeChainHelper(JSContext *cx, HandleObject objArg, HandleId id)
|
||||
* (i.e., obj has ever been on a prototype or parent chain).
|
||||
*/
|
||||
static inline bool
|
||||
PurgeScopeChain(JSContext *cx, JS::HandleObject obj, JS::HandleId id)
|
||||
PurgeScopeChain(ExclusiveContext *cx, JS::HandleObject obj, JS::HandleId id)
|
||||
{
|
||||
if (obj->isDelegate())
|
||||
return PurgeScopeChainHelper(cx, obj, id);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Shape *
|
||||
js_AddNativeProperty(JSContext *cx, HandleObject obj, HandleId id,
|
||||
PropertyOp getter, StrictPropertyOp setter, uint32_t slot,
|
||||
@ -3312,14 +3330,44 @@ js_AddNativeProperty(JSContext *cx, HandleObject obj, HandleId id,
|
||||
}
|
||||
|
||||
JSBool
|
||||
baseops::DefineGeneric(JSContext *cx, HandleObject obj, HandleId id, HandleValue value,
|
||||
baseops::DefineGeneric(ExclusiveContext *cx, HandleObject obj, HandleId id, HandleValue value,
|
||||
PropertyOp getter, StrictPropertyOp setter, unsigned attrs)
|
||||
{
|
||||
return DefineNativeProperty(cx, obj, id, value, getter, setter, attrs, 0, 0);
|
||||
}
|
||||
|
||||
/* static */ JSBool
|
||||
JSObject::defineGeneric(ExclusiveContext *cx, HandleObject obj,
|
||||
HandleId id, HandleValue value,
|
||||
JSPropertyOp getter, JSStrictPropertyOp setter, unsigned attrs)
|
||||
{
|
||||
JS_ASSERT(!(attrs & JSPROP_NATIVE_ACCESSORS));
|
||||
js::DefineGenericOp op = obj->getOps()->defineGeneric;
|
||||
if (op)
|
||||
return op(cx->asJSContext(), obj, id, value, getter, setter, attrs);
|
||||
return baseops::DefineGeneric(cx, obj, id, value, getter, setter, attrs);
|
||||
}
|
||||
|
||||
/* static */ JSBool
|
||||
JSObject::defineProperty(ExclusiveContext *cx, HandleObject obj,
|
||||
PropertyName *name, HandleValue value,
|
||||
JSPropertyOp getter, JSStrictPropertyOp setter, unsigned attrs)
|
||||
{
|
||||
RootedId id(cx, NameToId(name));
|
||||
return defineGeneric(cx, obj, id, value, getter, setter, attrs);
|
||||
}
|
||||
|
||||
/* static */ JSBool
|
||||
JSObject::defineSpecial(ExclusiveContext *cx, HandleObject obj,
|
||||
SpecialId sid, HandleValue value,
|
||||
JSPropertyOp getter, JSStrictPropertyOp setter, unsigned attrs)
|
||||
{
|
||||
RootedId id(cx, SPECIALID_TO_JSID(sid));
|
||||
return defineGeneric(cx, obj, id, value, getter, setter, attrs);
|
||||
}
|
||||
|
||||
JSBool
|
||||
baseops::DefineElement(JSContext *cx, HandleObject obj, uint32_t index, HandleValue value,
|
||||
baseops::DefineElement(ExclusiveContext *cx, HandleObject obj, uint32_t index, HandleValue value,
|
||||
PropertyOp getter, StrictPropertyOp setter, unsigned attrs)
|
||||
{
|
||||
Rooted<jsid> id(cx);
|
||||
@ -3336,6 +3384,36 @@ baseops::DefineElement(JSContext *cx, HandleObject obj, uint32_t index, HandleVa
|
||||
return DefineNativeProperty(cx, obj, id, value, getter, setter, attrs, 0, 0);
|
||||
}
|
||||
|
||||
/* static */ JSBool
|
||||
JSObject::defineElement(ExclusiveContext *cx, HandleObject obj,
|
||||
uint32_t index, HandleValue value,
|
||||
JSPropertyOp getter, JSStrictPropertyOp setter, unsigned attrs)
|
||||
{
|
||||
js::DefineElementOp op = obj->getOps()->defineElement;
|
||||
if (op)
|
||||
return op(cx->asJSContext(), obj, index, value, getter, setter, attrs);
|
||||
return baseops::DefineElement(cx, obj, index, value, getter, setter, attrs);
|
||||
}
|
||||
|
||||
Shape *
|
||||
JSObject::addDataProperty(ExclusiveContext *cx, jsid idArg, uint32_t slot, unsigned attrs)
|
||||
{
|
||||
JS_ASSERT(!(attrs & (JSPROP_GETTER | JSPROP_SETTER)));
|
||||
RootedObject self(cx, this);
|
||||
RootedId id(cx, idArg);
|
||||
return addProperty(cx, self, id, NULL, NULL, slot, attrs, 0, 0);
|
||||
}
|
||||
|
||||
Shape *
|
||||
JSObject::addDataProperty(ExclusiveContext *cx, HandlePropertyName name,
|
||||
uint32_t slot, unsigned attrs)
|
||||
{
|
||||
JS_ASSERT(!(attrs & (JSPROP_GETTER | JSPROP_SETTER)));
|
||||
RootedObject self(cx, this);
|
||||
RootedId id(cx, NameToId(name));
|
||||
return addProperty(cx, self, id, NULL, NULL, slot, attrs, 0, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Backward compatibility requires allowing addProperty hooks to mutate the
|
||||
* nominal initial value of a slotful property, while GC safety wants that
|
||||
@ -3343,7 +3421,7 @@ baseops::DefineElement(JSContext *cx, HandleObject obj, uint32_t index, HandleVa
|
||||
* both while saving cycles for classes that stub their addProperty hook.
|
||||
*/
|
||||
static inline bool
|
||||
CallAddPropertyHook(JSContext *cx, Class *clasp, HandleObject obj, HandleShape shape,
|
||||
CallAddPropertyHook(ExclusiveContext *cx, Class *clasp, HandleObject obj, HandleShape shape,
|
||||
HandleValue nominal)
|
||||
{
|
||||
if (clasp->addProperty != JS_PropertyStub) {
|
||||
@ -3351,7 +3429,7 @@ CallAddPropertyHook(JSContext *cx, Class *clasp, HandleObject obj, HandleShape s
|
||||
RootedValue value(cx, nominal);
|
||||
|
||||
Rooted<jsid> id(cx, shape->propid());
|
||||
if (!CallJSPropertyOp(cx, clasp->addProperty, obj, id, &value)) {
|
||||
if (!CallJSPropertyOp(cx->asJSContext(), clasp->addProperty, obj, id, &value)) {
|
||||
obj->removeProperty(cx, shape->propid());
|
||||
return false;
|
||||
}
|
||||
@ -3364,7 +3442,7 @@ CallAddPropertyHook(JSContext *cx, Class *clasp, HandleObject obj, HandleShape s
|
||||
}
|
||||
|
||||
static inline bool
|
||||
CallAddPropertyHookDense(JSContext *cx, Class *clasp, HandleObject obj, uint32_t index,
|
||||
CallAddPropertyHookDense(ExclusiveContext *cx, Class *clasp, HandleObject obj, uint32_t index,
|
||||
HandleValue nominal)
|
||||
{
|
||||
/* Inline addProperty for array objects. */
|
||||
@ -3372,7 +3450,7 @@ CallAddPropertyHookDense(JSContext *cx, Class *clasp, HandleObject obj, uint32_t
|
||||
Rooted<ArrayObject*> arr(cx, &obj->as<ArrayObject>());
|
||||
uint32_t length = arr->length();
|
||||
if (index >= length)
|
||||
ArrayObject::setLength(cx, arr, index + 1);
|
||||
ArrayObject::setLength(cx->asJSContext(), arr, index + 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -3381,7 +3459,7 @@ CallAddPropertyHookDense(JSContext *cx, Class *clasp, HandleObject obj, uint32_t
|
||||
RootedValue value(cx, nominal);
|
||||
|
||||
Rooted<jsid> id(cx, INT_TO_JSID(index));
|
||||
if (!CallJSPropertyOp(cx, clasp->addProperty, obj, id, &value)) {
|
||||
if (!CallJSPropertyOp(cx->asJSContext(), clasp->addProperty, obj, id, &value)) {
|
||||
JSObject::setDenseElementHole(cx, obj, index);
|
||||
return false;
|
||||
}
|
||||
@ -3392,7 +3470,7 @@ CallAddPropertyHookDense(JSContext *cx, Class *clasp, HandleObject obj, uint32_t
|
||||
}
|
||||
|
||||
static inline bool
|
||||
DefinePropertyOrElement(JSContext *cx, HandleObject obj, HandleId id,
|
||||
DefinePropertyOrElement(ExclusiveContext *cx, HandleObject obj, HandleId id,
|
||||
PropertyOp getter, StrictPropertyOp setter,
|
||||
unsigned attrs, unsigned flags, int shortid,
|
||||
HandleValue value, bool callSetterAfterwards, bool setterIsStrict)
|
||||
@ -3423,7 +3501,7 @@ DefinePropertyOrElement(JSContext *cx, HandleObject obj, HandleId id,
|
||||
if (obj->is<ArrayObject>()) {
|
||||
Rooted<ArrayObject*> arr(cx, &obj->as<ArrayObject>());
|
||||
if (id == NameToId(cx->names().length))
|
||||
return ArraySetLength(cx, arr, id, attrs, value, setterIsStrict);
|
||||
return ArraySetLength(cx->asJSContext(), arr, id, attrs, value, setterIsStrict);
|
||||
|
||||
uint32_t index;
|
||||
if (js_IdIsIndex(id, &index)) {
|
||||
@ -3467,13 +3545,13 @@ DefinePropertyOrElement(JSContext *cx, HandleObject obj, HandleId id,
|
||||
|
||||
if (callSetterAfterwards && setter != JS_StrictPropertyStub) {
|
||||
RootedValue nvalue(cx, value);
|
||||
return js_NativeSet(cx, obj, obj, shape, setterIsStrict, &nvalue);
|
||||
return js_NativeSet(cx->asJSContext(), obj, obj, shape, setterIsStrict, &nvalue);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
js::DefineNativeProperty(JSContext *cx, HandleObject obj, HandleId id, HandleValue value,
|
||||
js::DefineNativeProperty(ExclusiveContext *cx, HandleObject obj, HandleId id, HandleValue value,
|
||||
PropertyOp getter, StrictPropertyOp setter, unsigned attrs,
|
||||
unsigned flags, int shortid, unsigned defineHow /* = 0 */)
|
||||
{
|
||||
@ -3657,7 +3735,7 @@ CallResolveOp(JSContext *cx, HandleObject obj, HandleId id, unsigned flags,
|
||||
|
||||
template <AllowGC allowGC>
|
||||
static JS_ALWAYS_INLINE bool
|
||||
LookupPropertyWithFlagsInline(JSContext *cx,
|
||||
LookupPropertyWithFlagsInline(ExclusiveContext *cx,
|
||||
typename MaybeRooted<JSObject*, allowGC>::HandleType obj,
|
||||
typename MaybeRooted<jsid, allowGC>::HandleType id,
|
||||
unsigned flags,
|
||||
@ -3694,7 +3772,7 @@ LookupPropertyWithFlagsInline(JSContext *cx,
|
||||
if (!allowGC)
|
||||
return false;
|
||||
bool recursed;
|
||||
if (!CallResolveOp(cx,
|
||||
if (!CallResolveOp(cx->asJSContext(),
|
||||
MaybeRooted<JSObject*, allowGC>::toHandle(current),
|
||||
MaybeRooted<jsid, allowGC>::toHandle(id),
|
||||
flags,
|
||||
@ -3723,7 +3801,7 @@ LookupPropertyWithFlagsInline(JSContext *cx,
|
||||
if (!proto->isNative()) {
|
||||
if (!allowGC)
|
||||
return false;
|
||||
return JSObject::lookupGeneric(cx,
|
||||
return JSObject::lookupGeneric(cx->asJSContext(),
|
||||
MaybeRooted<JSObject*, allowGC>::toHandle(proto),
|
||||
MaybeRooted<jsid, allowGC>::toHandle(id),
|
||||
MaybeRooted<JSObject*, allowGC>::toMutableHandle(objp),
|
||||
@ -3740,7 +3818,7 @@ LookupPropertyWithFlagsInline(JSContext *cx,
|
||||
|
||||
template <AllowGC allowGC>
|
||||
JSBool
|
||||
baseops::LookupProperty(JSContext *cx,
|
||||
baseops::LookupProperty(ExclusiveContext *cx,
|
||||
typename MaybeRooted<JSObject*, allowGC>::HandleType obj,
|
||||
typename MaybeRooted<jsid, allowGC>::HandleType id,
|
||||
typename MaybeRooted<JSObject*, allowGC>::MutableHandleType objp,
|
||||
@ -3750,18 +3828,35 @@ baseops::LookupProperty(JSContext *cx,
|
||||
* |CanEffectlesslyCallLookupGenericOnObject| logic.
|
||||
* If this changes, please remember to update the logic there as well.
|
||||
*/
|
||||
return LookupPropertyWithFlagsInline<allowGC>(cx, obj, id, cx->resolveFlags, objp, propp);
|
||||
uint32_t resolveFlags =
|
||||
cx->isJSContext() ? cx->asJSContext()->resolveFlags : 0;
|
||||
return LookupPropertyWithFlagsInline<allowGC>(cx, obj, id, resolveFlags, objp, propp);
|
||||
}
|
||||
|
||||
template JSBool
|
||||
baseops::LookupProperty<CanGC>(JSContext *cx, HandleObject obj, HandleId id,
|
||||
baseops::LookupProperty<CanGC>(ExclusiveContext *cx, HandleObject obj, HandleId id,
|
||||
MutableHandleObject objp, MutableHandleShape propp);
|
||||
|
||||
template JSBool
|
||||
baseops::LookupProperty<NoGC>(JSContext *cx, JSObject *obj, jsid id,
|
||||
baseops::LookupProperty<NoGC>(ExclusiveContext *cx, JSObject *obj, jsid id,
|
||||
FakeMutableHandle<JSObject*> objp,
|
||||
FakeMutableHandle<Shape*> propp);
|
||||
|
||||
/* static */ JSBool
|
||||
JSObject::lookupGeneric(JSContext *cx, HandleObject obj, js::HandleId id,
|
||||
MutableHandleObject objp, MutableHandleShape propp)
|
||||
{
|
||||
/*
|
||||
* NB: The logic of lookupGeneric is implicitly reflected in IonBuilder.cpp's
|
||||
* |CanEffectlesslyCallLookupGenericOnObject| logic.
|
||||
* If this changes, please remember to update the logic there as well.
|
||||
*/
|
||||
LookupGenericOp op = obj->getOps()->lookupGeneric;
|
||||
if (op)
|
||||
return op(cx, obj, id, objp, propp);
|
||||
return baseops::LookupProperty<js::CanGC>(cx, obj, id, objp, propp);
|
||||
}
|
||||
|
||||
JSBool
|
||||
baseops::LookupElement(JSContext *cx, HandleObject obj, uint32_t index,
|
||||
MutableHandleObject objp, MutableHandleShape propp)
|
||||
@ -3774,7 +3869,7 @@ baseops::LookupElement(JSContext *cx, HandleObject obj, uint32_t index,
|
||||
}
|
||||
|
||||
bool
|
||||
js::LookupPropertyWithFlags(JSContext *cx, HandleObject obj, HandleId id, unsigned flags,
|
||||
js::LookupPropertyWithFlags(ExclusiveContext *cx, HandleObject obj, HandleId id, unsigned flags,
|
||||
MutableHandleObject objp, MutableHandleShape propp)
|
||||
{
|
||||
return LookupPropertyWithFlagsInline<CanGC>(cx, obj, id, flags, objp, propp);
|
||||
@ -4985,7 +5080,8 @@ js::IsDelegate(JSContext *cx, HandleObject obj, const js::Value &v, bool *result
|
||||
* NewBuiltinClassInstance in jsobjinlines.h.
|
||||
*/
|
||||
bool
|
||||
js_GetClassPrototype(JSContext *cx, JSProtoKey protoKey, MutableHandleObject protop, Class *clasp)
|
||||
js_GetClassPrototype(ExclusiveContext *cx, JSProtoKey protoKey,
|
||||
MutableHandleObject protop, Class *clasp)
|
||||
{
|
||||
JS_ASSERT(JSProto_Null <= protoKey);
|
||||
JS_ASSERT(protoKey < JSProto_LIMIT);
|
||||
@ -5004,8 +5100,17 @@ js_GetClassPrototype(JSContext *cx, JSProtoKey protoKey, MutableHandleObject pro
|
||||
|
||||
if (IsFunctionObject(v)) {
|
||||
RootedObject ctor(cx, &v.get().toObject());
|
||||
if (!JSObject::getProperty(cx, ctor, ctor, cx->names().classPrototype, &v))
|
||||
return false;
|
||||
if (cx->isJSContext()) {
|
||||
if (!JSObject::getProperty(cx->asJSContext(),
|
||||
ctor, ctor, cx->names().classPrototype, &v))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
Shape *shape = ctor->nativeLookup(cx, cx->names().classPrototype);
|
||||
if (!shape || !NativeGetPureInline(ctor, shape, v.address()))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protop.set(v.get().isObject() ? &v.get().toObject() : NULL);
|
||||
|
254
js/src/jsobj.h
254
js/src/jsobj.h
@ -102,38 +102,22 @@ namespace baseops {
|
||||
*/
|
||||
template <AllowGC allowGC>
|
||||
extern JSBool
|
||||
LookupProperty(JSContext *cx,
|
||||
LookupProperty(ExclusiveContext *cx,
|
||||
typename MaybeRooted<JSObject*, allowGC>::HandleType obj,
|
||||
typename MaybeRooted<jsid, allowGC>::HandleType id,
|
||||
typename MaybeRooted<JSObject*, allowGC>::MutableHandleType objp,
|
||||
typename MaybeRooted<Shape*, allowGC>::MutableHandleType propp);
|
||||
|
||||
inline bool
|
||||
LookupProperty(JSContext *cx, HandleObject obj, PropertyName *name,
|
||||
MutableHandleObject objp, MutableHandleShape propp)
|
||||
{
|
||||
Rooted<jsid> id(cx, NameToId(name));
|
||||
return LookupProperty<CanGC>(cx, obj, id, objp, propp);
|
||||
}
|
||||
|
||||
extern JSBool
|
||||
LookupElement(JSContext *cx, HandleObject obj, uint32_t index,
|
||||
MutableHandleObject objp, MutableHandleShape propp);
|
||||
|
||||
extern JSBool
|
||||
DefineGeneric(JSContext *cx, HandleObject obj, HandleId id, HandleValue value,
|
||||
DefineGeneric(ExclusiveContext *cx, HandleObject obj, HandleId id, HandleValue value,
|
||||
JSPropertyOp getter, JSStrictPropertyOp setter, unsigned attrs);
|
||||
|
||||
inline JSBool
|
||||
DefineProperty(JSContext *cx, HandleObject obj, PropertyName *name, HandleValue value,
|
||||
JSPropertyOp getter, JSStrictPropertyOp setter, unsigned attrs)
|
||||
{
|
||||
Rooted<jsid> id(cx, NameToId(name));
|
||||
return DefineGeneric(cx, obj, id, value, getter, setter, attrs);
|
||||
}
|
||||
|
||||
extern JSBool
|
||||
DefineElement(JSContext *cx, HandleObject obj, uint32_t index, HandleValue value,
|
||||
DefineElement(ExclusiveContext *cx, HandleObject obj, uint32_t index, HandleValue value,
|
||||
JSPropertyOp getter, JSStrictPropertyOp setter, unsigned attrs);
|
||||
|
||||
extern JSBool
|
||||
@ -246,7 +230,8 @@ class JSObject : public js::ObjectImpl
|
||||
* Update the last property, keeping the number of allocated slots in sync
|
||||
* with the object's new slot span.
|
||||
*/
|
||||
static bool setLastProperty(JSContext *cx, JS::HandleObject obj, js::HandleShape shape);
|
||||
static bool setLastProperty(js::ExclusiveContext *cx,
|
||||
JS::HandleObject obj, js::HandleShape shape);
|
||||
|
||||
/* As above, but does not change the slot span. */
|
||||
inline void setLastPropertyInfallible(js::Shape *shape);
|
||||
@ -255,7 +240,7 @@ class JSObject : public js::ObjectImpl
|
||||
* Make a non-array object with the specified initial state. This method
|
||||
* takes ownership of any extantSlots it is passed.
|
||||
*/
|
||||
static inline JSObject *create(JSContext *cx,
|
||||
static inline JSObject *create(js::ExclusiveContext *cx,
|
||||
js::gc::AllocKind kind,
|
||||
js::gc::InitialHeap heap,
|
||||
js::HandleShape shape,
|
||||
@ -263,32 +248,32 @@ class JSObject : public js::ObjectImpl
|
||||
js::HeapSlot *extantSlots = NULL);
|
||||
|
||||
/* Make an array object with the specified initial state. */
|
||||
static inline JSObject *createArray(JSContext *cx,
|
||||
js::gc::AllocKind kind,
|
||||
js::gc::InitialHeap heap,
|
||||
js::HandleShape shape,
|
||||
js::HandleTypeObject type,
|
||||
uint32_t length);
|
||||
static inline js::ArrayObject *createArray(js::ExclusiveContext *cx,
|
||||
js::gc::AllocKind kind,
|
||||
js::gc::InitialHeap heap,
|
||||
js::HandleShape shape,
|
||||
js::HandleTypeObject type,
|
||||
uint32_t length);
|
||||
|
||||
/*
|
||||
* Remove the last property of an object, provided that it is safe to do so
|
||||
* (the shape and previous shape do not carry conflicting information about
|
||||
* the object itself).
|
||||
*/
|
||||
inline void removeLastProperty(JSContext *cx);
|
||||
inline void removeLastProperty(js::ExclusiveContext *cx);
|
||||
inline bool canRemoveLastProperty();
|
||||
|
||||
/*
|
||||
* Update the slot span directly for a dictionary object, and allocate
|
||||
* slots to cover the new span if necessary.
|
||||
*/
|
||||
static bool setSlotSpan(JSContext *cx, JS::HandleObject obj, uint32_t span);
|
||||
static bool setSlotSpan(js::ExclusiveContext *cx, JS::HandleObject obj, uint32_t span);
|
||||
|
||||
/* Upper bound on the number of elements in an object. */
|
||||
static const uint32_t NELEMENTS_LIMIT = JS_BIT(28);
|
||||
|
||||
public:
|
||||
bool setDelegate(JSContext *cx) {
|
||||
bool setDelegate(js::ExclusiveContext *cx) {
|
||||
return setFlag(cx, js::BaseShape::DELEGATE, GENERATE_SHAPE);
|
||||
}
|
||||
|
||||
@ -301,13 +286,13 @@ class JSObject : public js::ObjectImpl
|
||||
bool watched() const {
|
||||
return lastProperty()->hasObjectFlag(js::BaseShape::WATCHED);
|
||||
}
|
||||
bool setWatched(JSContext *cx) {
|
||||
bool setWatched(js::ExclusiveContext *cx) {
|
||||
return setFlag(cx, js::BaseShape::WATCHED, GENERATE_SHAPE);
|
||||
}
|
||||
|
||||
/* See StackFrame::varObj. */
|
||||
inline bool isVarObj();
|
||||
bool setVarObj(JSContext *cx) {
|
||||
bool setVarObj(js::ExclusiveContext *cx) {
|
||||
return setFlag(cx, js::BaseShape::VAROBJ);
|
||||
}
|
||||
|
||||
@ -320,7 +305,7 @@ class JSObject : public js::ObjectImpl
|
||||
bool hasUncacheableProto() const {
|
||||
return lastProperty()->hasObjectFlag(js::BaseShape::UNCACHEABLE_PROTO);
|
||||
}
|
||||
bool setUncacheableProto(JSContext *cx) {
|
||||
bool setUncacheableProto(js::ExclusiveContext *cx) {
|
||||
return setFlag(cx, js::BaseShape::UNCACHEABLE_PROTO, GENERATE_SHAPE);
|
||||
}
|
||||
|
||||
@ -331,7 +316,7 @@ class JSObject : public js::ObjectImpl
|
||||
bool hadElementsAccess() const {
|
||||
return lastProperty()->hasObjectFlag(js::BaseShape::HAD_ELEMENTS_ACCESS);
|
||||
}
|
||||
bool setHadElementsAccess(JSContext *cx) {
|
||||
bool setHadElementsAccess(js::ExclusiveContext *cx) {
|
||||
return setFlag(cx, js::BaseShape::HAD_ELEMENTS_ACCESS);
|
||||
}
|
||||
|
||||
@ -340,7 +325,7 @@ class JSObject : public js::ObjectImpl
|
||||
return lastProperty()->isEmptyShape();
|
||||
}
|
||||
|
||||
bool shadowingShapeChange(JSContext *cx, const js::Shape &shape);
|
||||
bool shadowingShapeChange(js::ExclusiveContext *cx, const js::Shape &shape);
|
||||
|
||||
/*
|
||||
* Whether there may be indexed properties on this object, excluding any in
|
||||
@ -384,16 +369,16 @@ class JSObject : public js::ObjectImpl
|
||||
* The number of allocated slots is not stored explicitly, and changes to
|
||||
* the slots must track changes in the slot span.
|
||||
*/
|
||||
static bool growSlots(JSContext *cx, js::HandleObject obj, uint32_t oldCount,
|
||||
static bool growSlots(js::ExclusiveContext *cx, js::HandleObject obj, uint32_t oldCount,
|
||||
uint32_t newCount);
|
||||
static void shrinkSlots(JSContext *cx, js::HandleObject obj, uint32_t oldCount,
|
||||
static void shrinkSlots(js::ExclusiveContext *cx, js::HandleObject obj, uint32_t oldCount,
|
||||
uint32_t newCount);
|
||||
|
||||
bool hasDynamicSlots() const { return slots != NULL; }
|
||||
|
||||
protected:
|
||||
static inline bool updateSlotsForSpan(JSContext *cx, js::HandleObject obj, size_t oldSpan,
|
||||
size_t newSpan);
|
||||
static inline bool updateSlotsForSpan(js::ExclusiveContext *cx,
|
||||
js::HandleObject obj, size_t oldSpan, size_t newSpan);
|
||||
|
||||
public:
|
||||
/*
|
||||
@ -406,7 +391,8 @@ class JSObject : public js::ObjectImpl
|
||||
void rollbackProperties(JSContext *cx, uint32_t slotSpan);
|
||||
|
||||
inline void nativeSetSlot(uint32_t slot, const js::Value &value);
|
||||
static inline void nativeSetSlotWithType(JSContext *cx, js::HandleObject, js::Shape *shape,
|
||||
static inline void nativeSetSlotWithType(js::ExclusiveContext *cx,
|
||||
js::HandleObject, js::Shape *shape,
|
||||
const js::Value &value);
|
||||
|
||||
inline const js::Value &getReservedSlot(uint32_t index) const {
|
||||
@ -426,7 +412,7 @@ class JSObject : public js::ObjectImpl
|
||||
* Marks this object as having a singleton type, and leave the type lazy.
|
||||
* Constructs a new, unique shape for the object.
|
||||
*/
|
||||
static inline bool setSingletonType(JSContext *cx, js::HandleObject obj);
|
||||
static inline bool setSingletonType(js::ExclusiveContext *cx, js::HandleObject obj);
|
||||
|
||||
// uninlinedGetType() is the same as getType(), but not inlined.
|
||||
inline js::types::TypeObject* getType(JSContext *cx);
|
||||
@ -461,8 +447,6 @@ class JSObject : public js::ObjectImpl
|
||||
inline void setType(js::types::TypeObject *newType);
|
||||
void uninlinedSetType(js::types::TypeObject *newType);
|
||||
|
||||
js::types::TypeObject *getNewType(JSContext *cx, js::Class *clasp, JSFunction *fun = NULL);
|
||||
|
||||
#ifdef DEBUG
|
||||
bool hasNewType(js::Class *clasp, js::types::TypeObject *newType);
|
||||
#endif
|
||||
@ -472,7 +456,7 @@ class JSObject : public js::ObjectImpl
|
||||
* to recover this information in the object's type information after it
|
||||
* is purged on GC.
|
||||
*/
|
||||
bool setIteratedSingleton(JSContext *cx) {
|
||||
bool setIteratedSingleton(js::ExclusiveContext *cx) {
|
||||
return setFlag(cx, js::BaseShape::ITERATED_SINGLETON);
|
||||
}
|
||||
|
||||
@ -578,9 +562,9 @@ class JSObject : public js::ObjectImpl
|
||||
static const char *className(JSContext *cx, js::HandleObject obj);
|
||||
|
||||
/* Accessors for elements. */
|
||||
inline bool ensureElements(JSContext *cx, uint32_t capacity);
|
||||
inline bool ensureElements(js::ThreadSafeContext *cx, uint32_t capacity);
|
||||
bool growElements(js::ThreadSafeContext *tcx, uint32_t newcap);
|
||||
void shrinkElements(JSContext *cx, uint32_t cap);
|
||||
void shrinkElements(js::ThreadSafeContext *cx, uint32_t cap);
|
||||
void setDynamicElements(js::ObjectElements *header) {
|
||||
JS_ASSERT(!hasDynamicElements());
|
||||
elements = header->elements();
|
||||
@ -594,17 +578,19 @@ class JSObject : public js::ObjectImpl
|
||||
}
|
||||
|
||||
inline void setDenseInitializedLength(uint32_t length);
|
||||
inline void ensureDenseInitializedLength(JSContext *cx, uint32_t index, uint32_t extra);
|
||||
inline void ensureDenseInitializedLength(js::ExclusiveContext *cx,
|
||||
uint32_t index, uint32_t extra);
|
||||
inline void setDenseElement(uint32_t index, const js::Value &val);
|
||||
inline void initDenseElement(uint32_t index, const js::Value &val);
|
||||
inline void setDenseElementMaybeConvertDouble(uint32_t index, const js::Value &val);
|
||||
static inline void setDenseElementWithType(JSContext *cx, js::HandleObject obj,
|
||||
static inline void setDenseElementWithType(js::ExclusiveContext *cx, js::HandleObject obj,
|
||||
uint32_t index, const js::Value &val);
|
||||
static inline void initDenseElementWithType(JSContext *cx, js::HandleObject obj,
|
||||
static inline void initDenseElementWithType(js::ExclusiveContext *cx, js::HandleObject obj,
|
||||
uint32_t index, const js::Value &val);
|
||||
static inline void setDenseElementHole(JSContext *cx, js::HandleObject obj, uint32_t index);
|
||||
static inline void removeDenseElementForSparseIndex(JSContext *cx, js::HandleObject obj,
|
||||
uint32_t index);
|
||||
static inline void setDenseElementHole(js::ExclusiveContext *cx,
|
||||
js::HandleObject obj, uint32_t index);
|
||||
static inline void removeDenseElementForSparseIndex(js::ExclusiveContext *cx,
|
||||
js::HandleObject obj, uint32_t index);
|
||||
inline void copyDenseElements(uint32_t dstStart, const js::Value *src, uint32_t count);
|
||||
inline void initDenseElements(uint32_t dstStart, const js::Value *src, uint32_t count);
|
||||
inline void moveDenseElements(uint32_t dstStart, uint32_t srcStart, uint32_t count);
|
||||
@ -618,7 +604,7 @@ class JSObject : public js::ObjectImpl
|
||||
inline void setShouldConvertDoubleElements();
|
||||
|
||||
/* Packed information for this object's elements. */
|
||||
inline void markDenseElementsNotPacked(JSContext *cx);
|
||||
inline void markDenseElementsNotPacked(js::ExclusiveContext *cx);
|
||||
|
||||
/*
|
||||
* ensureDenseElements ensures that the object can hold at least
|
||||
@ -628,7 +614,8 @@ class JSObject : public js::ObjectImpl
|
||||
* two cases the object is kept intact.
|
||||
*/
|
||||
enum EnsureDenseResult { ED_OK, ED_FAILED, ED_SPARSE };
|
||||
inline EnsureDenseResult ensureDenseElements(JSContext *cx, uint32_t index, uint32_t extra);
|
||||
inline EnsureDenseResult ensureDenseElements(js::ExclusiveContext *cx,
|
||||
uint32_t index, uint32_t extra);
|
||||
inline EnsureDenseResult parExtendDenseElements(js::ThreadSafeContext *tcx, js::Value *v,
|
||||
uint32_t extra);
|
||||
|
||||
@ -636,10 +623,11 @@ class JSObject : public js::ObjectImpl
|
||||
uint32_t requiredCapacity, uint32_t extra);
|
||||
|
||||
/* Convert a single dense element to a sparse property. */
|
||||
static bool sparsifyDenseElement(JSContext *cx, js::HandleObject obj, uint32_t index);
|
||||
static bool sparsifyDenseElement(js::ExclusiveContext *cx,
|
||||
js::HandleObject obj, uint32_t index);
|
||||
|
||||
/* Convert all dense elements to sparse properties. */
|
||||
static bool sparsifyDenseElements(JSContext *cx, js::HandleObject obj);
|
||||
static bool sparsifyDenseElements(js::ExclusiveContext *cx, js::HandleObject obj);
|
||||
|
||||
/* Small objects are dense, no matter what. */
|
||||
static const uint32_t MIN_SPARSE_INDEX = 1000;
|
||||
@ -660,7 +648,7 @@ class JSObject : public js::ObjectImpl
|
||||
* After adding a sparse index to obj, see if it should be converted to use
|
||||
* dense elements.
|
||||
*/
|
||||
static EnsureDenseResult maybeDensifySparseElements(JSContext *cx, js::HandleObject obj);
|
||||
static EnsureDenseResult maybeDensifySparseElements(js::ExclusiveContext *cx, js::HandleObject obj);
|
||||
|
||||
public:
|
||||
/*
|
||||
@ -689,7 +677,7 @@ class JSObject : public js::ObjectImpl
|
||||
* after calling object-parameter-free shape methods, avoiding coupling
|
||||
* logic across the object vs. shape module wall.
|
||||
*/
|
||||
static bool allocSlot(JSContext *cx, JS::HandleObject obj, uint32_t *slotp);
|
||||
static bool allocSlot(js::ExclusiveContext *cx, JS::HandleObject obj, uint32_t *slotp);
|
||||
void freeSlot(uint32_t slot);
|
||||
|
||||
public:
|
||||
@ -707,8 +695,8 @@ class JSObject : public js::ObjectImpl
|
||||
js::MutableHandleValue vp);
|
||||
|
||||
private:
|
||||
static js::Shape *getChildProperty(JSContext *cx, JS::HandleObject obj,
|
||||
js::HandleShape parent, js::StackShape &child);
|
||||
static js::Shape *getChildProperty(js::ExclusiveContext *cx, JS::HandleObject obj,
|
||||
js::HandleShape parent, js::StackShape &child);
|
||||
|
||||
protected:
|
||||
/*
|
||||
@ -718,12 +706,12 @@ class JSObject : public js::ObjectImpl
|
||||
* 1. getter and setter must be normalized based on flags (see jsscope.cpp).
|
||||
* 2. Checks for non-extensibility must be done by callers.
|
||||
*/
|
||||
static js::Shape *addPropertyInternal(JSContext *cx,
|
||||
JS::HandleObject obj, JS::HandleId id,
|
||||
JSPropertyOp getter, JSStrictPropertyOp setter,
|
||||
uint32_t slot, unsigned attrs,
|
||||
unsigned flags, int shortid, js::Shape **spp,
|
||||
bool allowDictionary);
|
||||
static js::Shape *addPropertyInternal(js::ExclusiveContext *cx,
|
||||
JS::HandleObject obj, JS::HandleId id,
|
||||
JSPropertyOp getter, JSStrictPropertyOp setter,
|
||||
uint32_t slot, unsigned attrs,
|
||||
unsigned flags, int shortid, js::Shape **spp,
|
||||
bool allowDictionary);
|
||||
|
||||
private:
|
||||
struct TradeGutsReserved;
|
||||
@ -735,67 +723,44 @@ class JSObject : public js::ObjectImpl
|
||||
|
||||
public:
|
||||
/* Add a property whose id is not yet in this scope. */
|
||||
static js::Shape *addProperty(JSContext *cx, JS::HandleObject, JS::HandleId id,
|
||||
JSPropertyOp getter, JSStrictPropertyOp setter,
|
||||
uint32_t slot, unsigned attrs, unsigned flags,
|
||||
int shortid, bool allowDictionary = true);
|
||||
static js::Shape *addProperty(js::ExclusiveContext *cx, JS::HandleObject, JS::HandleId id,
|
||||
JSPropertyOp getter, JSStrictPropertyOp setter,
|
||||
uint32_t slot, unsigned attrs, unsigned flags,
|
||||
int shortid, bool allowDictionary = true);
|
||||
|
||||
/* Add a data property whose id is not yet in this scope. */
|
||||
js::Shape *addDataProperty(JSContext *cx, jsid id_, uint32_t slot, unsigned attrs) {
|
||||
JS_ASSERT(!(attrs & (JSPROP_GETTER | JSPROP_SETTER)));
|
||||
JS::RootedObject self(cx, this);
|
||||
JS::RootedId id(cx, id_);
|
||||
return addProperty(cx, self, id, NULL, NULL, slot, attrs, 0, 0);
|
||||
}
|
||||
|
||||
js::Shape *addDataProperty(JSContext *cx, js::HandlePropertyName name, uint32_t slot, unsigned attrs) {
|
||||
JS_ASSERT(!(attrs & (JSPROP_GETTER | JSPROP_SETTER)));
|
||||
JS::RootedObject self(cx, this);
|
||||
JS::RootedId id(cx, NameToId(name));
|
||||
return addProperty(cx, self, id, NULL, NULL, slot, attrs, 0, 0);
|
||||
}
|
||||
js::Shape *addDataProperty(js::ExclusiveContext *cx,
|
||||
jsid id_, uint32_t slot, unsigned attrs);
|
||||
js::Shape *addDataProperty(js::ExclusiveContext *cx, js::HandlePropertyName name,
|
||||
uint32_t slot, unsigned attrs);
|
||||
|
||||
/* Add or overwrite a property for id in this scope. */
|
||||
static js::Shape *putProperty(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
|
||||
JSPropertyOp getter, JSStrictPropertyOp setter,
|
||||
uint32_t slot, unsigned attrs,
|
||||
unsigned flags, int shortid);
|
||||
static js::Shape *putProperty(JSContext *cx, JS::HandleObject obj,
|
||||
js::PropertyName *name,
|
||||
JSPropertyOp getter, JSStrictPropertyOp setter,
|
||||
uint32_t slot, unsigned attrs,
|
||||
unsigned flags, int shortid)
|
||||
{
|
||||
JS::RootedId id(cx, js::NameToId(name));
|
||||
return putProperty(cx, obj, id, getter, setter, slot, attrs, flags, shortid);
|
||||
}
|
||||
static js::Shape *putProperty(js::ExclusiveContext *cx, JS::HandleObject obj, JS::HandleId id,
|
||||
JSPropertyOp getter, JSStrictPropertyOp setter,
|
||||
uint32_t slot, unsigned attrs,
|
||||
unsigned flags, int shortid);
|
||||
static inline js::Shape *putProperty(js::ExclusiveContext *cx, JS::HandleObject obj,
|
||||
js::PropertyName *name,
|
||||
JSPropertyOp getter, JSStrictPropertyOp setter,
|
||||
uint32_t slot, unsigned attrs,
|
||||
unsigned flags, int shortid);
|
||||
|
||||
/* Change the given property into a sibling with the same id in this scope. */
|
||||
static js::Shape *changeProperty(JSContext *cx, js::HandleObject obj,
|
||||
js::HandleShape shape, unsigned attrs, unsigned mask,
|
||||
JSPropertyOp getter, JSStrictPropertyOp setter);
|
||||
static js::Shape *changeProperty(js::ExclusiveContext *cx, js::HandleObject obj,
|
||||
js::HandleShape shape, unsigned attrs, unsigned mask,
|
||||
JSPropertyOp getter, JSStrictPropertyOp setter);
|
||||
|
||||
static inline bool changePropertyAttributes(JSContext *cx, js::HandleObject obj,
|
||||
js::HandleShape shape, unsigned attrs);
|
||||
|
||||
/* Remove the property named by id from this object. */
|
||||
bool removeProperty(JSContext *cx, jsid id);
|
||||
bool removeProperty(js::ExclusiveContext *cx, jsid id);
|
||||
|
||||
/* Clear the scope, making it empty. */
|
||||
static void clear(JSContext *cx, js::HandleObject obj);
|
||||
|
||||
static JSBool lookupGeneric(JSContext *cx, js::HandleObject obj, js::HandleId id,
|
||||
js::MutableHandleObject objp, js::MutableHandleShape propp)
|
||||
{
|
||||
/* NB: The logic of lookupGeneric is implicitly reflected in IonBuilder.cpp's
|
||||
* |CanEffectlesslyCallLookupGenericOnObject| logic.
|
||||
* If this changes, please remember to update the logic there as well.
|
||||
*/
|
||||
js::LookupGenericOp op = obj->getOps()->lookupGeneric;
|
||||
if (op)
|
||||
return op(cx, obj, id, objp, propp);
|
||||
return js::baseops::LookupProperty<js::CanGC>(cx, obj, id, objp, propp);
|
||||
}
|
||||
js::MutableHandleObject objp, js::MutableHandleShape propp);
|
||||
|
||||
static JSBool lookupProperty(JSContext *cx, js::HandleObject obj, js::PropertyName *name,
|
||||
js::MutableHandleObject objp, js::MutableHandleShape propp)
|
||||
@ -818,46 +783,29 @@ class JSObject : public js::ObjectImpl
|
||||
return lookupGeneric(cx, obj, id, objp, propp);
|
||||
}
|
||||
|
||||
static JSBool defineGeneric(JSContext *cx, js::HandleObject obj,
|
||||
js::HandleId id, js::HandleValue value,
|
||||
JSPropertyOp getter = JS_PropertyStub,
|
||||
JSStrictPropertyOp setter = JS_StrictPropertyStub,
|
||||
unsigned attrs = JSPROP_ENUMERATE)
|
||||
{
|
||||
JS_ASSERT(!(attrs & JSPROP_NATIVE_ACCESSORS));
|
||||
js::DefineGenericOp op = obj->getOps()->defineGeneric;
|
||||
return (op ? op : js::baseops::DefineGeneric)(cx, obj, id, value, getter, setter, attrs);
|
||||
}
|
||||
static JSBool defineGeneric(js::ExclusiveContext *cx, js::HandleObject obj,
|
||||
js::HandleId id, js::HandleValue value,
|
||||
JSPropertyOp getter = JS_PropertyStub,
|
||||
JSStrictPropertyOp setter = JS_StrictPropertyStub,
|
||||
unsigned attrs = JSPROP_ENUMERATE);
|
||||
|
||||
static JSBool defineProperty(JSContext *cx, js::HandleObject obj,
|
||||
static JSBool defineProperty(js::ExclusiveContext *cx, js::HandleObject obj,
|
||||
js::PropertyName *name, js::HandleValue value,
|
||||
JSPropertyOp getter = JS_PropertyStub,
|
||||
JSStrictPropertyOp setter = JS_StrictPropertyStub,
|
||||
unsigned attrs = JSPROP_ENUMERATE)
|
||||
{
|
||||
JS::RootedId id(cx, js::NameToId(name));
|
||||
return defineGeneric(cx, obj, id, value, getter, setter, attrs);
|
||||
}
|
||||
unsigned attrs = JSPROP_ENUMERATE);
|
||||
|
||||
static JSBool defineElement(JSContext *cx, js::HandleObject obj,
|
||||
static JSBool defineElement(js::ExclusiveContext *cx, js::HandleObject obj,
|
||||
uint32_t index, js::HandleValue value,
|
||||
JSPropertyOp getter = JS_PropertyStub,
|
||||
JSStrictPropertyOp setter = JS_StrictPropertyStub,
|
||||
unsigned attrs = JSPROP_ENUMERATE)
|
||||
{
|
||||
js::DefineElementOp op = obj->getOps()->defineElement;
|
||||
return (op ? op : js::baseops::DefineElement)(cx, obj, index, value, getter, setter, attrs);
|
||||
}
|
||||
unsigned attrs = JSPROP_ENUMERATE);
|
||||
|
||||
static JSBool defineSpecial(JSContext *cx, js::HandleObject obj,
|
||||
static JSBool defineSpecial(js::ExclusiveContext *cx, js::HandleObject obj,
|
||||
js::SpecialId sid, js::HandleValue value,
|
||||
JSPropertyOp getter = JS_PropertyStub,
|
||||
JSStrictPropertyOp setter = JS_StrictPropertyStub,
|
||||
unsigned attrs = JSPROP_ENUMERATE)
|
||||
{
|
||||
JS::RootedId id(cx, SPECIALID_TO_JSID(sid));
|
||||
return defineGeneric(cx, obj, id, value, getter, setter, attrs);
|
||||
}
|
||||
unsigned attrs = JSPROP_ENUMERATE);
|
||||
|
||||
static JSBool getGeneric(JSContext *cx, js::HandleObject obj, js::HandleObject receiver,
|
||||
js::HandleId id, js::MutableHandleValue vp)
|
||||
@ -1201,7 +1149,7 @@ js_PopulateObject(JSContext *cx, js::HandleObject newborn, js::HandleObject prop
|
||||
* Fast access to immutable standard objects (constructors and prototypes).
|
||||
*/
|
||||
extern bool
|
||||
js_GetClassObject(JSContext *cx, JSObject *obj, JSProtoKey key,
|
||||
js_GetClassObject(js::ExclusiveContext *cx, JSObject *obj, JSProtoKey key,
|
||||
js::MutableHandleObject objp);
|
||||
|
||||
/*
|
||||
@ -1216,7 +1164,7 @@ js_IdentifyClassPrototype(JSObject *obj);
|
||||
* JSProto_Null, clasp must non-null.
|
||||
*/
|
||||
bool
|
||||
js_FindClassObject(JSContext *cx, JSProtoKey protoKey, js::MutableHandleValue vp,
|
||||
js_FindClassObject(js::ExclusiveContext *cx, JSProtoKey protoKey, js::MutableHandleValue vp,
|
||||
js::Class *clasp = NULL);
|
||||
|
||||
/*
|
||||
@ -1306,35 +1254,17 @@ const unsigned DNP_SKIP_TYPE = 4; /* Don't update type information */
|
||||
* Return successfully added or changed shape or NULL on error.
|
||||
*/
|
||||
extern bool
|
||||
DefineNativeProperty(JSContext *cx, HandleObject obj, HandleId id, HandleValue value,
|
||||
DefineNativeProperty(ExclusiveContext *cx, HandleObject obj, HandleId id, HandleValue value,
|
||||
PropertyOp getter, StrictPropertyOp setter, unsigned attrs,
|
||||
unsigned flags, int shortid, unsigned defineHow = 0);
|
||||
|
||||
inline bool
|
||||
DefineNativeProperty(JSContext *cx, HandleObject obj, PropertyName *name, HandleValue value,
|
||||
PropertyOp getter, StrictPropertyOp setter, unsigned attrs,
|
||||
unsigned flags, int shortid, unsigned defineHow = 0)
|
||||
{
|
||||
Rooted<jsid> id(cx, NameToId(name));
|
||||
return DefineNativeProperty(cx, obj, id, value, getter, setter, attrs, flags,
|
||||
shortid, defineHow);
|
||||
}
|
||||
|
||||
/*
|
||||
* Specialized subroutine that allows caller to preset JSRESOLVE_* flags.
|
||||
*/
|
||||
extern bool
|
||||
LookupPropertyWithFlags(JSContext *cx, HandleObject obj, HandleId id, unsigned flags,
|
||||
LookupPropertyWithFlags(ExclusiveContext *cx, HandleObject obj, HandleId id, unsigned flags,
|
||||
js::MutableHandleObject objp, js::MutableHandleShape propp);
|
||||
|
||||
inline bool
|
||||
LookupPropertyWithFlags(JSContext *cx, HandleObject obj, PropertyName *name, unsigned flags,
|
||||
js::MutableHandleObject objp, js::MutableHandleShape propp)
|
||||
{
|
||||
Rooted<jsid> id(cx, NameToId(name));
|
||||
return LookupPropertyWithFlags(cx, obj, id, flags, objp, propp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Call the [[DefineOwnProperty]] internal method of obj.
|
||||
*
|
||||
@ -1527,7 +1457,7 @@ js_InferFlags(JSContext *cx, unsigned defaultFlags);
|
||||
* methods instead.
|
||||
*/
|
||||
extern bool
|
||||
js_GetClassPrototype(JSContext *cx, JSProtoKey protoKey, js::MutableHandleObject protop,
|
||||
js_GetClassPrototype(js::ExclusiveContext *cx, JSProtoKey protoKey, js::MutableHandleObject protop,
|
||||
js::Class *clasp = NULL);
|
||||
|
||||
namespace js {
|
||||
|
@ -131,7 +131,7 @@ JSObject::setLastPropertyInfallible(js::Shape *shape)
|
||||
}
|
||||
|
||||
inline void
|
||||
JSObject::removeLastProperty(JSContext *cx)
|
||||
JSObject::removeLastProperty(js::ExclusiveContext *cx)
|
||||
{
|
||||
JS_ASSERT(canRemoveLastProperty());
|
||||
JS::RootedObject self(cx, this);
|
||||
@ -202,7 +202,7 @@ JSObject::setShouldConvertDoubleElements()
|
||||
}
|
||||
|
||||
inline bool
|
||||
JSObject::ensureElements(JSContext *cx, uint32_t capacity)
|
||||
JSObject::ensureElements(js::ThreadSafeContext *cx, uint32_t capacity)
|
||||
{
|
||||
if (capacity > getDenseCapacity())
|
||||
return growElements(cx, capacity);
|
||||
@ -233,7 +233,7 @@ JSObject::initDenseElement(uint32_t index, const js::Value &val)
|
||||
}
|
||||
|
||||
/* static */ inline void
|
||||
JSObject::setDenseElementWithType(JSContext *cx, js::HandleObject obj, uint32_t index,
|
||||
JSObject::setDenseElementWithType(js::ExclusiveContext *cx, js::HandleObject obj, uint32_t index,
|
||||
const js::Value &val)
|
||||
{
|
||||
js::types::AddTypePropertyId(cx, obj, JSID_VOID, val);
|
||||
@ -241,7 +241,7 @@ JSObject::setDenseElementWithType(JSContext *cx, js::HandleObject obj, uint32_t
|
||||
}
|
||||
|
||||
/* static */ inline void
|
||||
JSObject::initDenseElementWithType(JSContext *cx, js::HandleObject obj, uint32_t index,
|
||||
JSObject::initDenseElementWithType(js::ExclusiveContext *cx, js::HandleObject obj, uint32_t index,
|
||||
const js::Value &val)
|
||||
{
|
||||
JS_ASSERT(!obj->shouldConvertDoubleElements());
|
||||
@ -250,14 +250,15 @@ JSObject::initDenseElementWithType(JSContext *cx, js::HandleObject obj, uint32_t
|
||||
}
|
||||
|
||||
/* static */ inline void
|
||||
JSObject::setDenseElementHole(JSContext *cx, js::HandleObject obj, uint32_t index)
|
||||
JSObject::setDenseElementHole(js::ExclusiveContext *cx, js::HandleObject obj, uint32_t index)
|
||||
{
|
||||
js::types::MarkTypeObjectFlags(cx, obj, js::types::OBJECT_FLAG_NON_PACKED);
|
||||
obj->setDenseElement(index, js::MagicValue(JS_ELEMENTS_HOLE));
|
||||
}
|
||||
|
||||
/* static */ inline void
|
||||
JSObject::removeDenseElementForSparseIndex(JSContext *cx, js::HandleObject obj, uint32_t index)
|
||||
JSObject::removeDenseElementForSparseIndex(js::ExclusiveContext *cx,
|
||||
js::HandleObject obj, uint32_t index)
|
||||
{
|
||||
js::types::MarkTypeObjectFlags(cx, obj,
|
||||
js::types::OBJECT_FLAG_NON_PACKED |
|
||||
@ -333,14 +334,14 @@ JSObject::moveDenseElementsUnbarriered(uint32_t dstStart, uint32_t srcStart, uin
|
||||
}
|
||||
|
||||
inline void
|
||||
JSObject::markDenseElementsNotPacked(JSContext *cx)
|
||||
JSObject::markDenseElementsNotPacked(js::ExclusiveContext *cx)
|
||||
{
|
||||
JS_ASSERT(isNative());
|
||||
MarkTypeObjectFlags(cx, this, js::types::OBJECT_FLAG_NON_PACKED);
|
||||
}
|
||||
|
||||
inline void
|
||||
JSObject::ensureDenseInitializedLength(JSContext *cx, uint32_t index, uint32_t extra)
|
||||
JSObject::ensureDenseInitializedLength(js::ExclusiveContext *cx, uint32_t index, uint32_t extra)
|
||||
{
|
||||
/*
|
||||
* Ensure that the array's contents have been initialized up to index, and
|
||||
@ -439,7 +440,7 @@ JSObject::parExtendDenseElements(js::ThreadSafeContext *tcx, js::Value *v, uint3
|
||||
}
|
||||
|
||||
inline JSObject::EnsureDenseResult
|
||||
JSObject::ensureDenseElements(JSContext *cx, uint32_t index, uint32_t extra)
|
||||
JSObject::ensureDenseElements(js::ExclusiveContext *cx, uint32_t index, uint32_t extra)
|
||||
{
|
||||
JS_ASSERT(isNative());
|
||||
|
||||
@ -478,13 +479,15 @@ JSObject::ensureDenseElements(JSContext *cx, uint32_t index, uint32_t extra)
|
||||
}
|
||||
|
||||
/* static */ inline bool
|
||||
JSObject::setSingletonType(JSContext *cx, js::HandleObject obj)
|
||||
JSObject::setSingletonType(js::ExclusiveContext *cxArg, js::HandleObject obj)
|
||||
{
|
||||
JS_ASSERT(!IsInsideNursery(cx->runtime(), obj.get()));
|
||||
|
||||
if (!cx->typeInferenceEnabled())
|
||||
if (!cxArg->typeInferenceEnabled())
|
||||
return true;
|
||||
|
||||
JSContext *cx = cxArg->asJSContext();
|
||||
|
||||
JS_ASSERT(!IsInsideNursery(cx->runtime(), obj.get()));
|
||||
|
||||
js::types::TypeObject *type =
|
||||
cx->compartment()->getLazyType(cx, obj->getClass(), obj->getTaggedProto());
|
||||
if (!type)
|
||||
@ -513,7 +516,7 @@ JSObject::clearType(JSContext *cx, js::HandleObject obj)
|
||||
JS_ASSERT(!obj->hasSingletonType());
|
||||
JS_ASSERT(cx->compartment() == obj->compartment());
|
||||
|
||||
js::types::TypeObject *type = cx->compartment()->getNewType(cx, obj->getClass(), NULL);
|
||||
js::types::TypeObject *type = cx->getNewType(obj->getClass(), NULL);
|
||||
if (!type)
|
||||
return false;
|
||||
|
||||
@ -551,7 +554,7 @@ inline bool JSObject::isVarObj()
|
||||
}
|
||||
|
||||
/* static */ inline JSObject *
|
||||
JSObject::create(JSContext *cx, js::gc::AllocKind kind, js::gc::InitialHeap heap,
|
||||
JSObject::create(js::ExclusiveContext *cx, js::gc::AllocKind kind, js::gc::InitialHeap heap,
|
||||
js::HandleShape shape, js::HandleTypeObject type,
|
||||
js::HeapSlot *extantSlots /* = NULL */)
|
||||
{
|
||||
@ -586,7 +589,8 @@ JSObject::create(JSContext *cx, js::gc::AllocKind kind, js::gc::InitialHeap heap
|
||||
}
|
||||
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
cx->runtime()->gcNursery.notifyInitialSlots(obj, slots);
|
||||
if (heap != js::gc::TenuredHeap)
|
||||
cx->asJSContext()->runtime()->gcNursery.notifyInitialSlots(obj, slots);
|
||||
#endif
|
||||
|
||||
obj->shape_.init(shape);
|
||||
@ -605,8 +609,8 @@ JSObject::create(JSContext *cx, js::gc::AllocKind kind, js::gc::InitialHeap heap
|
||||
return obj;
|
||||
}
|
||||
|
||||
/* static */ inline JSObject *
|
||||
JSObject::createArray(JSContext *cx, js::gc::AllocKind kind, js::gc::InitialHeap heap,
|
||||
/* static */ inline js::ArrayObject *
|
||||
JSObject::createArray(js::ExclusiveContext *cx, js::gc::AllocKind kind, js::gc::InitialHeap heap,
|
||||
js::HandleShape shape, js::HandleTypeObject type,
|
||||
uint32_t length)
|
||||
{
|
||||
@ -631,10 +635,8 @@ JSObject::createArray(JSContext *cx, js::gc::AllocKind kind, js::gc::InitialHeap
|
||||
uint32_t capacity = js::gc::GetGCKindSlots(kind) - js::ObjectElements::VALUES_PER_HEADER;
|
||||
|
||||
JSObject *obj = js_NewGCObject<js::CanGC>(cx, kind, heap);
|
||||
if (!obj) {
|
||||
js_ReportOutOfMemory(cx);
|
||||
if (!obj)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
obj->shape_.init(shape);
|
||||
obj->type_.init(type);
|
||||
@ -642,7 +644,7 @@ JSObject::createArray(JSContext *cx, js::gc::AllocKind kind, js::gc::InitialHeap
|
||||
obj->setFixedElements();
|
||||
new (obj->getElementsHeader()) js::ObjectElements(capacity, length);
|
||||
|
||||
return obj;
|
||||
return &obj->as<js::ArrayObject>();
|
||||
}
|
||||
|
||||
inline void
|
||||
@ -683,7 +685,7 @@ JSObject::nativeSetSlot(uint32_t slot, const js::Value &value)
|
||||
}
|
||||
|
||||
/* static */ inline void
|
||||
JSObject::nativeSetSlotWithType(JSContext *cx, js::HandleObject obj, js::Shape *shape,
|
||||
JSObject::nativeSetSlotWithType(js::ExclusiveContext *cx, js::HandleObject obj, js::Shape *shape,
|
||||
const js::Value &value)
|
||||
{
|
||||
obj->nativeSetSlot(shape->slot(), value);
|
||||
@ -977,11 +979,11 @@ class AutoPropertyDescriptorRooter : private AutoGCRooter, public PropertyDescri
|
||||
* default to the prototype's global if the prototype is non-null.
|
||||
*/
|
||||
JSObject *
|
||||
NewObjectWithGivenProto(JSContext *cx, js::Class *clasp, TaggedProto proto, JSObject *parent,
|
||||
NewObjectWithGivenProto(ExclusiveContext *cx, js::Class *clasp, TaggedProto proto, JSObject *parent,
|
||||
gc::AllocKind allocKind, NewObjectKind newKind);
|
||||
|
||||
inline JSObject *
|
||||
NewObjectWithGivenProto(JSContext *cx, js::Class *clasp, TaggedProto proto, JSObject *parent,
|
||||
NewObjectWithGivenProto(ExclusiveContext *cx, js::Class *clasp, TaggedProto proto, JSObject *parent,
|
||||
NewObjectKind newKind = GenericObject)
|
||||
{
|
||||
gc::AllocKind allocKind = gc::GetGCObjectKind(clasp);
|
||||
@ -989,7 +991,7 @@ NewObjectWithGivenProto(JSContext *cx, js::Class *clasp, TaggedProto proto, JSOb
|
||||
}
|
||||
|
||||
inline JSObject *
|
||||
NewObjectWithGivenProto(JSContext *cx, js::Class *clasp, JSObject *proto, JSObject *parent,
|
||||
NewObjectWithGivenProto(ExclusiveContext *cx, js::Class *clasp, JSObject *proto, JSObject *parent,
|
||||
NewObjectKind newKind = GenericObject)
|
||||
{
|
||||
return NewObjectWithGivenProto(cx, clasp, TaggedProto(proto), parent, newKind);
|
||||
@ -1007,7 +1009,7 @@ GetClassProtoKey(js::Class *clasp)
|
||||
}
|
||||
|
||||
inline bool
|
||||
FindProto(JSContext *cx, js::Class *clasp, MutableHandleObject proto)
|
||||
FindProto(ExclusiveContext *cx, js::Class *clasp, MutableHandleObject proto)
|
||||
{
|
||||
JSProtoKey protoKey = GetClassProtoKey(clasp);
|
||||
if (!js_GetClassPrototype(cx, protoKey, proto, clasp))
|
||||
@ -1035,18 +1037,18 @@ FindProto(JSContext *cx, js::Class *clasp, MutableHandleObject proto)
|
||||
* parent will be that global.
|
||||
*/
|
||||
JSObject *
|
||||
NewObjectWithClassProtoCommon(JSContext *cx, js::Class *clasp, JSObject *proto, JSObject *parent,
|
||||
NewObjectWithClassProtoCommon(ExclusiveContext *cx, js::Class *clasp, JSObject *proto, JSObject *parent,
|
||||
gc::AllocKind allocKind, NewObjectKind newKind);
|
||||
|
||||
inline JSObject *
|
||||
NewObjectWithClassProto(JSContext *cx, js::Class *clasp, JSObject *proto, JSObject *parent,
|
||||
NewObjectWithClassProto(ExclusiveContext *cx, js::Class *clasp, JSObject *proto, JSObject *parent,
|
||||
gc::AllocKind allocKind, NewObjectKind newKind = GenericObject)
|
||||
{
|
||||
return NewObjectWithClassProtoCommon(cx, clasp, proto, parent, allocKind, newKind);
|
||||
}
|
||||
|
||||
inline JSObject *
|
||||
NewObjectWithClassProto(JSContext *cx, js::Class *clasp, JSObject *proto, JSObject *parent,
|
||||
NewObjectWithClassProto(ExclusiveContext *cx, js::Class *clasp, JSObject *proto, JSObject *parent,
|
||||
NewObjectKind newKind = GenericObject)
|
||||
{
|
||||
gc::AllocKind allocKind = gc::GetGCObjectKind(clasp);
|
||||
@ -1058,14 +1060,14 @@ NewObjectWithClassProto(JSContext *cx, js::Class *clasp, JSObject *proto, JSObje
|
||||
* according to the context's active global.
|
||||
*/
|
||||
inline JSObject *
|
||||
NewBuiltinClassInstance(JSContext *cx, Class *clasp, gc::AllocKind allocKind,
|
||||
NewBuiltinClassInstance(ExclusiveContext *cx, Class *clasp, gc::AllocKind allocKind,
|
||||
NewObjectKind newKind = GenericObject)
|
||||
{
|
||||
return NewObjectWithClassProto(cx, clasp, NULL, NULL, allocKind, newKind);
|
||||
}
|
||||
|
||||
inline JSObject *
|
||||
NewBuiltinClassInstance(JSContext *cx, Class *clasp, NewObjectKind newKind = GenericObject)
|
||||
NewBuiltinClassInstance(ExclusiveContext *cx, Class *clasp, NewObjectKind newKind = GenericObject)
|
||||
{
|
||||
gc::AllocKind allocKind = gc::GetGCObjectKind(clasp);
|
||||
return NewBuiltinClassInstance(cx, clasp, allocKind, newKind);
|
||||
@ -1202,20 +1204,60 @@ DefineConstructorAndPrototype(JSContext *cx, HandleObject obj, JSProtoKey key, H
|
||||
gc::AllocKind ctorKind = JSFunction::FinalizeKind);
|
||||
|
||||
static JS_ALWAYS_INLINE bool
|
||||
NewObjectMetadata(JSContext *cx, JSObject **pmetadata)
|
||||
NewObjectMetadata(ExclusiveContext *cxArg, JSObject **pmetadata)
|
||||
{
|
||||
// The metadata callback is invoked before each created object, except when
|
||||
// analysis is active as the callback may reenter JS.
|
||||
JS_ASSERT(!*pmetadata);
|
||||
if (JS_UNLIKELY((size_t)cx->compartment()->objectMetadataCallback) &&
|
||||
!cx->compartment()->activeAnalysis)
|
||||
{
|
||||
gc::AutoSuppressGC suppress(cx);
|
||||
return cx->compartment()->objectMetadataCallback(cx, pmetadata);
|
||||
if (JSContext *cx = cxArg->maybeJSContext()) {
|
||||
if (JS_UNLIKELY((size_t)cx->compartment()->objectMetadataCallback) &&
|
||||
!cx->compartment()->activeAnalysis)
|
||||
{
|
||||
gc::AutoSuppressGC suppress(cx);
|
||||
return cx->compartment()->objectMetadataCallback(cx, pmetadata);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool
|
||||
DefineNativeProperty(ExclusiveContext *cx, HandleObject obj, PropertyName *name, HandleValue value,
|
||||
PropertyOp getter, StrictPropertyOp setter, unsigned attrs,
|
||||
unsigned flags, int shortid, unsigned defineHow = 0)
|
||||
{
|
||||
Rooted<jsid> id(cx, NameToId(name));
|
||||
return DefineNativeProperty(cx, obj, id, value, getter, setter, attrs, flags,
|
||||
shortid, defineHow);
|
||||
}
|
||||
|
||||
inline bool
|
||||
LookupPropertyWithFlags(ExclusiveContext *cx, HandleObject obj, PropertyName *name, unsigned flags,
|
||||
js::MutableHandleObject objp, js::MutableHandleShape propp)
|
||||
{
|
||||
Rooted<jsid> id(cx, NameToId(name));
|
||||
return LookupPropertyWithFlags(cx, obj, id, flags, objp, propp);
|
||||
}
|
||||
|
||||
namespace baseops {
|
||||
|
||||
inline bool
|
||||
LookupProperty(ExclusiveContext *cx, HandleObject obj, PropertyName *name,
|
||||
MutableHandleObject objp, MutableHandleShape propp)
|
||||
{
|
||||
Rooted<jsid> id(cx, NameToId(name));
|
||||
return LookupProperty<CanGC>(cx, obj, id, objp, propp);
|
||||
}
|
||||
|
||||
inline JSBool
|
||||
DefineProperty(ExclusiveContext *cx, HandleObject obj, PropertyName *name, HandleValue value,
|
||||
JSPropertyOp getter, JSStrictPropertyOp setter, unsigned attrs)
|
||||
{
|
||||
Rooted<jsid> id(cx, NameToId(name));
|
||||
return DefineGeneric(cx, obj, id, value, getter, setter, attrs);
|
||||
}
|
||||
|
||||
} /* namespace baseops */
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
extern JSObject *
|
||||
|
@ -25,6 +25,7 @@
|
||||
|
||||
#include "jsatominlines.h"
|
||||
#include "jsboolinlines.h"
|
||||
#include "jsstrinlines.h"
|
||||
|
||||
using namespace js;
|
||||
using namespace js::gc;
|
||||
|
@ -491,7 +491,7 @@ ToDisassemblySource(JSContext *cx, jsval v, JSAutoByteString *bytes)
|
||||
: JSID_TO_ATOM(shape->propid());
|
||||
|
||||
JSAutoByteString bytes;
|
||||
if (!js_AtomToPrintableString(cx, atom, &bytes))
|
||||
if (!AtomToPrintableString(cx, atom, &bytes))
|
||||
return false;
|
||||
|
||||
r.popFront();
|
||||
|
@ -32,11 +32,11 @@ ShapeHasher::match(const Key k, const Lookup &l)
|
||||
}
|
||||
|
||||
Shape *
|
||||
PropertyTree::newShape(JSContext *cx)
|
||||
PropertyTree::newShape(ExclusiveContext *cx)
|
||||
{
|
||||
Shape *shape = js_NewGCShape(cx);
|
||||
if (!shape)
|
||||
JS_ReportOutOfMemory(cx);
|
||||
js_ReportOutOfMemory(cx);
|
||||
return shape;
|
||||
}
|
||||
|
||||
@ -55,13 +55,13 @@ HashChildren(Shape *kid1, Shape *kid2)
|
||||
}
|
||||
|
||||
bool
|
||||
PropertyTree::insertChild(JSContext *cx, Shape *parent, Shape *child)
|
||||
PropertyTree::insertChild(ExclusiveContext *cx, Shape *parent, Shape *child)
|
||||
{
|
||||
JS_ASSERT(!parent->inDictionary());
|
||||
JS_ASSERT(!child->parent);
|
||||
JS_ASSERT(!child->inDictionary());
|
||||
JS_ASSERT(cx->compartment() == compartment);
|
||||
JS_ASSERT(child->compartment() == parent->compartment());
|
||||
JS_ASSERT(cx->isInsideCurrentCompartment(this));
|
||||
|
||||
KidsPointer *kidp = &parent->kids;
|
||||
|
||||
@ -78,7 +78,7 @@ PropertyTree::insertChild(JSContext *cx, Shape *parent, Shape *child)
|
||||
|
||||
KidsHash *hash = HashChildren(shape, child);
|
||||
if (!hash) {
|
||||
JS_ReportOutOfMemory(cx);
|
||||
js_ReportOutOfMemory(cx);
|
||||
return false;
|
||||
}
|
||||
kidp->setHash(hash);
|
||||
@ -87,7 +87,7 @@ PropertyTree::insertChild(JSContext *cx, Shape *parent, Shape *child)
|
||||
}
|
||||
|
||||
if (!kidp->toHash()->putNew(child, child)) {
|
||||
JS_ReportOutOfMemory(cx);
|
||||
js_ReportOutOfMemory(cx);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -127,7 +127,7 @@ Shape::removeChild(Shape *child)
|
||||
}
|
||||
|
||||
Shape *
|
||||
PropertyTree::getChild(JSContext *cx, Shape *parent_, uint32_t nfixed, const StackShape &child)
|
||||
PropertyTree::getChild(ExclusiveContext *cx, Shape *parent_, uint32_t nfixed, const StackShape &child)
|
||||
{
|
||||
{
|
||||
Shape *shape = NULL;
|
||||
|
@ -72,9 +72,9 @@ class PropertyTree
|
||||
{
|
||||
friend class ::JSFunction;
|
||||
|
||||
JSCompartment *compartment;
|
||||
JSCompartment *compartment_;
|
||||
|
||||
bool insertChild(JSContext *cx, Shape *parent, Shape *child);
|
||||
bool insertChild(ExclusiveContext *cx, Shape *parent, Shape *child);
|
||||
|
||||
PropertyTree();
|
||||
|
||||
@ -90,12 +90,14 @@ class PropertyTree
|
||||
};
|
||||
|
||||
PropertyTree(JSCompartment *comp)
|
||||
: compartment(comp)
|
||||
: compartment_(comp)
|
||||
{
|
||||
}
|
||||
|
||||
Shape *newShape(JSContext *cx);
|
||||
Shape *getChild(JSContext *cx, Shape *parent, uint32_t nfixed, const StackShape &child);
|
||||
JSCompartment *compartment() { return compartment_; }
|
||||
|
||||
Shape *newShape(ExclusiveContext *cx);
|
||||
Shape *getChild(ExclusiveContext *cx, Shape *parent, uint32_t nfixed, const StackShape &child);
|
||||
|
||||
#ifdef DEBUG
|
||||
static void dumpShapes(JSRuntime *rt);
|
||||
|
@ -832,7 +832,7 @@ ReturnedValueMustNotBePrimitive(JSContext *cx, HandleObject proxy, JSAtom *atom,
|
||||
{
|
||||
if (v.isPrimitive()) {
|
||||
JSAutoByteString bytes;
|
||||
if (js_AtomToPrintableString(cx, atom, &bytes)) {
|
||||
if (AtomToPrintableString(cx, atom, &bytes)) {
|
||||
RootedValue val(cx, ObjectOrNullValue(proxy));
|
||||
js_ReportValueError2(cx, JSMSG_BAD_TRAP_RETURN_VALUE,
|
||||
JSDVG_SEARCH_STACK, val, NullPtr(), bytes.ptr());
|
||||
@ -1546,7 +1546,7 @@ ReportInvalidTrapResult(JSContext *cx, JSObject *proxy, JSAtom *atom)
|
||||
{
|
||||
RootedValue v(cx, ObjectOrNullValue(proxy));
|
||||
JSAutoByteString bytes;
|
||||
if (!js_AtomToPrintableString(cx, atom, &bytes))
|
||||
if (!AtomToPrintableString(cx, atom, &bytes))
|
||||
return;
|
||||
js_ReportValueError2(cx, JSMSG_INVALID_TRAP_RESULT, JSDVG_IGNORE_STACK, v,
|
||||
NullPtr(), bytes.ptr());
|
||||
@ -1882,7 +1882,7 @@ ScriptedDirectProxyHandler::enumerate(JSContext *cx, HandleObject proxy, AutoIdV
|
||||
// step f
|
||||
if (trapResult.isPrimitive()) {
|
||||
JSAutoByteString bytes;
|
||||
if (!js_AtomToPrintableString(cx, cx->names().enumerate, &bytes))
|
||||
if (!AtomToPrintableString(cx, cx->names().enumerate, &bytes))
|
||||
return false;
|
||||
RootedValue v(cx, ObjectOrNullValue(proxy));
|
||||
js_ReportValueError2(cx, JSMSG_INVALID_TRAP_RESULT, JSDVG_SEARCH_STACK,
|
||||
@ -2202,7 +2202,7 @@ ScriptedDirectProxyHandler::keys(JSContext *cx, HandleObject proxy, AutoIdVector
|
||||
// step f
|
||||
if (trapResult.isPrimitive()) {
|
||||
JSAutoByteString bytes;
|
||||
if (!js_AtomToPrintableString(cx, cx->names().keys, &bytes))
|
||||
if (!AtomToPrintableString(cx, cx->names().keys, &bytes))
|
||||
return false;
|
||||
RootedValue v(cx, ObjectOrNullValue(proxy));
|
||||
js_ReportValueError2(cx, JSMSG_INVALID_TRAP_RESULT, JSDVG_IGNORE_STACK,
|
||||
@ -3379,7 +3379,7 @@ proxy(JSContext *cx, unsigned argc, jsval *vp)
|
||||
RootedObject proto(cx);
|
||||
if (!JSObject::getProto(cx, target, &proto))
|
||||
return false;
|
||||
RootedObject fun(cx, target->isCallable() ? target : (JSObject *) NULL);
|
||||
RootedObject fun(cx, target->isCallable() ? target.get() : (JSObject *) NULL);
|
||||
RootedValue priv(cx, ObjectValue(*target));
|
||||
JSObject *proxy = NewProxyObject(cx, &ScriptedDirectProxyHandler::singleton,
|
||||
priv, proto, cx->global(),
|
||||
|
@ -14,6 +14,8 @@
|
||||
#include "jsprototypes.h"
|
||||
#include "jstypes.h"
|
||||
|
||||
#include "mozilla/PodOperations.h"
|
||||
|
||||
#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING) || defined(DEBUG)
|
||||
# define JSGC_TRACK_EXACT_ROOTS
|
||||
#endif
|
||||
@ -29,6 +31,8 @@ class Value;
|
||||
template <typename T>
|
||||
class Rooted;
|
||||
|
||||
class AutoGCRooter;
|
||||
|
||||
struct Zone;
|
||||
|
||||
} /* namespace JS */
|
||||
@ -231,6 +235,7 @@ struct Runtime
|
||||
namespace js {
|
||||
|
||||
struct ThreadSafeContext;
|
||||
class ExclusiveContext;
|
||||
|
||||
class Allocator;
|
||||
|
||||
@ -289,8 +294,15 @@ struct ContextFriendFields
|
||||
|
||||
public:
|
||||
explicit ContextFriendFields(JSRuntime *rt)
|
||||
: runtime_(rt), compartment_(NULL), zone_(NULL)
|
||||
{ }
|
||||
: runtime_(rt), compartment_(NULL), zone_(NULL), autoGCRooters(NULL)
|
||||
{
|
||||
#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING)
|
||||
mozilla::PodArrayZero(thingGCRooters);
|
||||
#endif
|
||||
#if defined(DEBUG) && defined(JS_GC_ZEAL) && defined(JSGC_ROOT_ANALYSIS) && !defined(JS_THREADSAFE)
|
||||
skipGCRooters = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
static const ContextFriendFields *get(const JSContext *cx) {
|
||||
return reinterpret_cast<const ContextFriendFields *>(cx);
|
||||
@ -320,6 +332,9 @@ struct ContextFriendFields
|
||||
SkipRoot *skipGCRooters;
|
||||
#endif
|
||||
|
||||
/* Stack of thread-stack-allocated GC roots. */
|
||||
JS::AutoGCRooter *autoGCRooters;
|
||||
|
||||
friend JSRuntime *GetRuntime(const JSContext *cx);
|
||||
friend JSCompartment *GetContextCompartment(const JSContext *cx);
|
||||
friend JS::Zone *GetContextZone(const JSContext *cx);
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "vm/RegExpObject.h"
|
||||
|
||||
#include "jsobjinlines.h"
|
||||
#include "jsstrinlines.h"
|
||||
|
||||
using namespace js;
|
||||
using namespace js::frontend;
|
||||
@ -3052,7 +3053,7 @@ reflect_parse(JSContext *cx, uint32_t argc, jsval *vp)
|
||||
CompileOptions options(cx);
|
||||
options.setFileAndLine(filename, lineno);
|
||||
options.setCanLazilyParse(false);
|
||||
Parser<FullParseHandler> parser(cx, options, chars.get(), length,
|
||||
Parser<FullParseHandler> parser(cx, &cx->tempLifoAlloc(), options, chars.get(), length,
|
||||
/* foldConstants = */ false, NULL, NULL);
|
||||
|
||||
serialize.setParser(&parser);
|
||||
|
@ -51,7 +51,7 @@ using mozilla::PodZero;
|
||||
typedef Rooted<GlobalObject *> RootedGlobalObject;
|
||||
|
||||
/* static */ unsigned
|
||||
Bindings::argumentsVarIndex(JSContext *cx, InternalBindingsHandle bindings)
|
||||
Bindings::argumentsVarIndex(ExclusiveContext *cx, InternalBindingsHandle bindings)
|
||||
{
|
||||
HandlePropertyName arguments = cx->names().arguments;
|
||||
BindingIter bi(bindings);
|
||||
@ -61,7 +61,7 @@ Bindings::argumentsVarIndex(JSContext *cx, InternalBindingsHandle bindings)
|
||||
}
|
||||
|
||||
bool
|
||||
Bindings::initWithTemporaryStorage(JSContext *cx, InternalBindingsHandle self,
|
||||
Bindings::initWithTemporaryStorage(ExclusiveContext *cx, InternalBindingsHandle self,
|
||||
unsigned numArgs, unsigned numVars,
|
||||
Binding *bindingArray)
|
||||
{
|
||||
@ -69,10 +69,12 @@ Bindings::initWithTemporaryStorage(JSContext *cx, InternalBindingsHandle self,
|
||||
JS_ASSERT(self->bindingArrayAndFlag_ == TEMPORARY_STORAGE_BIT);
|
||||
|
||||
if (numArgs > UINT16_MAX || numVars > UINT16_MAX) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
self->numArgs_ > self->numVars_ ?
|
||||
JSMSG_TOO_MANY_FUN_ARGS :
|
||||
JSMSG_TOO_MANY_LOCALS);
|
||||
if (cx->isJSContext()) {
|
||||
JS_ReportErrorNumber(cx->asJSContext(), js_GetErrorMessage, NULL,
|
||||
self->numArgs_ > self->numVars_ ?
|
||||
JSMSG_TOO_MANY_FUN_ARGS :
|
||||
JSMSG_TOO_MANY_LOCALS);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -119,7 +121,7 @@ Bindings::initWithTemporaryStorage(JSContext *cx, InternalBindingsHandle self,
|
||||
return false;
|
||||
#endif
|
||||
|
||||
StackBaseShape base(cx->compartment(), &CallObject::class_, cx->global(), NULL,
|
||||
StackBaseShape base(cx, &CallObject::class_, cx->global(), NULL,
|
||||
BaseShape::VAROBJ | BaseShape::DELEGATE);
|
||||
|
||||
UnownedBaseShape *nbase = BaseShape::getUnowned(cx, base);
|
||||
@ -1494,7 +1496,7 @@ ScriptSource::sourceMap()
|
||||
*/
|
||||
|
||||
SharedScriptData *
|
||||
js::SharedScriptData::new_(JSContext *cx, uint32_t codeLength,
|
||||
js::SharedScriptData::new_(ExclusiveContext *cx, uint32_t codeLength,
|
||||
uint32_t srcnotesLength, uint32_t natoms)
|
||||
{
|
||||
uint32_t baseLength = codeLength + srcnotesLength;
|
||||
@ -1513,22 +1515,21 @@ js::SharedScriptData::new_(JSContext *cx, uint32_t codeLength,
|
||||
}
|
||||
|
||||
bool
|
||||
js::SaveSharedScriptData(JSContext *cx, Handle<JSScript *> script, SharedScriptData *ssd)
|
||||
js::SaveSharedScriptData(ExclusiveContext *cx, Handle<JSScript *> script, SharedScriptData *ssd)
|
||||
{
|
||||
ASSERT(script != NULL);
|
||||
ASSERT(ssd != NULL);
|
||||
|
||||
JSRuntime *rt = cx->runtime();
|
||||
ScriptBytecodeHasher::Lookup l(ssd);
|
||||
|
||||
ScriptDataTable::AddPtr p = rt->scriptDataTable.lookupForAdd(l);
|
||||
ScriptDataTable::AddPtr p = cx->scriptDataTable().lookupForAdd(l);
|
||||
if (p) {
|
||||
js_free(ssd);
|
||||
ssd = *p;
|
||||
} else {
|
||||
if (!rt->scriptDataTable.add(p, ssd)) {
|
||||
if (!cx->scriptDataTable().add(p, ssd)) {
|
||||
js_free(ssd);
|
||||
JS_ReportOutOfMemory(cx);
|
||||
js_ReportOutOfMemory(cx);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -1540,8 +1541,11 @@ js::SaveSharedScriptData(JSContext *cx, Handle<JSScript *> script, SharedScriptD
|
||||
* old scripts or exceptions pointing to the bytecode may no longer be
|
||||
* reachable. This is effectively a read barrier.
|
||||
*/
|
||||
if (JS::IsIncrementalGCInProgress(rt) && rt->gcIsFull)
|
||||
ssd->marked = true;
|
||||
if (cx->isJSContext()) {
|
||||
JSRuntime *rt = cx->asJSContext()->runtime();
|
||||
if (JS::IsIncrementalGCInProgress(rt) && rt->gcIsFull)
|
||||
ssd->marked = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
script->code = ssd->data;
|
||||
@ -1687,8 +1691,25 @@ ScriptDataSize(uint32_t nbindings, uint32_t nobjects, uint32_t nregexps,
|
||||
return size;
|
||||
}
|
||||
|
||||
void
|
||||
JSScript::initCompartmentAndPrincipals(ExclusiveContext *cx, const CompileOptions &options)
|
||||
{
|
||||
compartment_ = cx->compartment_;
|
||||
|
||||
/* Establish invariant: principals implies originPrincipals. */
|
||||
if (options.principals) {
|
||||
JS_ASSERT(options.principals == cx->compartment_->principals);
|
||||
originPrincipals
|
||||
= options.originPrincipals ? options.originPrincipals : options.principals;
|
||||
JS_HoldPrincipals(originPrincipals);
|
||||
} else if (options.originPrincipals) {
|
||||
originPrincipals = options.originPrincipals;
|
||||
JS_HoldPrincipals(originPrincipals);
|
||||
}
|
||||
}
|
||||
|
||||
JSScript *
|
||||
JSScript::Create(JSContext *cx, HandleObject enclosingScope, bool savedCallerFun,
|
||||
JSScript::Create(ExclusiveContext *cx, HandleObject enclosingScope, bool savedCallerFun,
|
||||
const CompileOptions &options, unsigned staticLevel,
|
||||
JS::HandleScriptSource sourceObject, uint32_t bufStart, uint32_t bufEnd)
|
||||
{
|
||||
@ -1703,18 +1724,7 @@ JSScript::Create(JSContext *cx, HandleObject enclosingScope, bool savedCallerFun
|
||||
|
||||
script->enclosingScopeOrOriginalFunction_ = enclosingScope;
|
||||
script->savedCallerFun = savedCallerFun;
|
||||
script->compartment_ = cx->compartment();
|
||||
|
||||
/* Establish invariant: principals implies originPrincipals. */
|
||||
if (options.principals) {
|
||||
JS_ASSERT(options.principals == cx->compartment()->principals);
|
||||
script->originPrincipals
|
||||
= options.originPrincipals ? options.originPrincipals : options.principals;
|
||||
JS_HoldPrincipals(script->originPrincipals);
|
||||
} else if (options.originPrincipals) {
|
||||
script->originPrincipals = options.originPrincipals;
|
||||
JS_HoldPrincipals(script->originPrincipals);
|
||||
}
|
||||
script->initCompartmentAndPrincipals(cx, options);
|
||||
|
||||
script->compileAndGo = options.compileAndGo;
|
||||
script->selfHosted = options.selfHostingMode;
|
||||
@ -1728,7 +1738,10 @@ JSScript::Create(JSContext *cx, HandleObject enclosingScope, bool savedCallerFun
|
||||
// stack if we nest functions more than a few hundred deep, so this will
|
||||
// never trigger. Oh well.
|
||||
if (staticLevel > UINT16_MAX) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_TOO_DEEP, js_function_str);
|
||||
if (cx->isJSContext()) {
|
||||
JS_ReportErrorNumber(cx->asJSContext(),
|
||||
js_GetErrorMessage, NULL, JSMSG_TOO_DEEP, js_function_str);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
script->staticLevel = uint16_t(staticLevel);
|
||||
@ -1741,7 +1754,7 @@ JSScript::Create(JSContext *cx, HandleObject enclosingScope, bool savedCallerFun
|
||||
}
|
||||
|
||||
static inline uint8_t *
|
||||
AllocScriptData(JSContext *cx, size_t size)
|
||||
AllocScriptData(ExclusiveContext *cx, size_t size)
|
||||
{
|
||||
uint8_t *data = static_cast<uint8_t *>(cx->calloc_(JS_ROUNDUP(size, sizeof(Value))));
|
||||
if (!data)
|
||||
@ -1753,7 +1766,7 @@ AllocScriptData(JSContext *cx, size_t size)
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
JSScript::partiallyInit(JSContext *cx, Handle<JSScript*> script, uint32_t nobjects,
|
||||
JSScript::partiallyInit(ExclusiveContext *cx, HandleScript script, uint32_t nobjects,
|
||||
uint32_t nregexps, uint32_t ntrynotes, uint32_t nconsts, uint32_t nTypeSets)
|
||||
{
|
||||
size_t size = ScriptDataSize(script->bindings.count(), nobjects, nregexps, ntrynotes, nconsts);
|
||||
@ -1824,7 +1837,7 @@ JSScript::partiallyInit(JSContext *cx, Handle<JSScript*> script, uint32_t nobjec
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
JSScript::fullyInitTrivial(JSContext *cx, Handle<JSScript*> script)
|
||||
JSScript::fullyInitTrivial(ExclusiveContext *cx, Handle<JSScript*> script)
|
||||
{
|
||||
if (!partiallyInit(cx, script, 0, 0, 0, 0, 0))
|
||||
return false;
|
||||
@ -1840,7 +1853,7 @@ JSScript::fullyInitTrivial(JSContext *cx, Handle<JSScript*> script)
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
JSScript::fullyInitFromEmitter(JSContext *cx, Handle<JSScript*> script, BytecodeEmitter *bce)
|
||||
JSScript::fullyInitFromEmitter(ExclusiveContext *cx, HandleScript script, BytecodeEmitter *bce)
|
||||
{
|
||||
/* The counts of indexed things must be checked during code generation. */
|
||||
JS_ASSERT(bce->atomIndices->count() <= INDEX_LIMIT);
|
||||
@ -1874,7 +1887,7 @@ JSScript::fullyInitFromEmitter(JSContext *cx, Handle<JSScript*> script, Bytecode
|
||||
PodCopy<jsbytecode>(code + prologLength, bce->code().begin(), mainLength);
|
||||
if (!FinishTakingSrcNotes(cx, bce, (jssrcnote *)(code + script->length)))
|
||||
return false;
|
||||
InitAtomMap(cx, bce->atomIndices.getMap(), ssd->atoms(script->length, nsrcnotes));
|
||||
InitAtomMap(bce->atomIndices.getMap(), ssd->atoms(script->length, nsrcnotes));
|
||||
|
||||
if (!SaveSharedScriptData(cx, script, ssd))
|
||||
return false;
|
||||
@ -3002,7 +3015,8 @@ LazyScript::sourceObject() const
|
||||
}
|
||||
|
||||
/* static */ LazyScript *
|
||||
LazyScript::Create(JSContext *cx, uint32_t numFreeVariables, uint32_t numInnerFunctions, JSVersion version,
|
||||
LazyScript::Create(ExclusiveContext *cx, uint32_t numFreeVariables, uint32_t numInnerFunctions,
|
||||
JSVersion version,
|
||||
uint32_t begin, uint32_t end, uint32_t lineno, uint32_t column)
|
||||
{
|
||||
JS_ASSERT(begin <= end);
|
||||
|
@ -180,7 +180,7 @@ class Bindings
|
||||
* storage is release, switchToScriptStorage must be called, providing a
|
||||
* pointer into the Binding array stored in script->data.
|
||||
*/
|
||||
static bool initWithTemporaryStorage(JSContext *cx, InternalBindingsHandle self,
|
||||
static bool initWithTemporaryStorage(ExclusiveContext *cx, InternalBindingsHandle self,
|
||||
unsigned numArgs, unsigned numVars,
|
||||
Binding *bindingArray);
|
||||
|
||||
@ -201,7 +201,7 @@ class Bindings
|
||||
Shape *callObjShape() const { return callObjShape_; }
|
||||
|
||||
/* Convenience method to get the var index of 'arguments'. */
|
||||
static unsigned argumentsVarIndex(JSContext *cx, InternalBindingsHandle);
|
||||
static unsigned argumentsVarIndex(ExclusiveContext *cx, InternalBindingsHandle);
|
||||
|
||||
/* Return whether the binding at bindingIndex is aliased. */
|
||||
bool bindingIsAliased(unsigned bindingIndex);
|
||||
@ -586,21 +586,26 @@ class JSScript : public js::gc::Cell
|
||||
//
|
||||
|
||||
public:
|
||||
static JSScript *Create(JSContext *cx, js::HandleObject enclosingScope, bool savedCallerFun,
|
||||
static JSScript *Create(js::ExclusiveContext *cx,
|
||||
js::HandleObject enclosingScope, bool savedCallerFun,
|
||||
const JS::CompileOptions &options, unsigned staticLevel,
|
||||
JS::HandleScriptSource sourceObject, uint32_t sourceStart,
|
||||
uint32_t sourceEnd);
|
||||
|
||||
void initCompartmentAndPrincipals(js::ExclusiveContext *cx,
|
||||
const JS::CompileOptions &options);
|
||||
|
||||
// Three ways ways to initialize a JSScript. Callers of partiallyInit()
|
||||
// and fullyInitTrivial() are responsible for notifying the debugger after
|
||||
// successfully creating any kind (function or other) of new JSScript.
|
||||
// However, callers of fullyInitFromEmitter() do not need to do this.
|
||||
static bool partiallyInit(JSContext *cx, JS::Handle<JSScript*> script,
|
||||
static bool partiallyInit(js::ExclusiveContext *cx, JS::Handle<JSScript*> script,
|
||||
uint32_t nobjects, uint32_t nregexps,
|
||||
uint32_t ntrynotes, uint32_t nconsts, uint32_t nTypeSets);
|
||||
static bool fullyInitTrivial(JSContext *cx, JS::Handle<JSScript*> script); // inits a JSOP_STOP-only script
|
||||
static bool fullyInitFromEmitter(JSContext *cx, JS::Handle<JSScript*> script,
|
||||
static bool fullyInitFromEmitter(js::ExclusiveContext *cx, JS::Handle<JSScript*> script,
|
||||
js::frontend::BytecodeEmitter *bce);
|
||||
// Initialize a no-op script.
|
||||
static bool fullyInitTrivial(js::ExclusiveContext *cx, JS::Handle<JSScript*> script);
|
||||
|
||||
inline JSPrincipals *principals();
|
||||
|
||||
@ -1163,8 +1168,10 @@ class LazyScript : public js::gc::Cell
|
||||
uint32_t begin, uint32_t end, uint32_t lineno, uint32_t column);
|
||||
|
||||
public:
|
||||
static LazyScript *Create(JSContext *cx, uint32_t numFreeVariables, uint32_t numInnerFunctions,
|
||||
JSVersion version, uint32_t begin, uint32_t end, uint32_t lineno, uint32_t column);
|
||||
static LazyScript *Create(ExclusiveContext *cx,
|
||||
uint32_t numFreeVariables, uint32_t numInnerFunctions,
|
||||
JSVersion version, uint32_t begin, uint32_t end,
|
||||
uint32_t lineno, uint32_t column);
|
||||
|
||||
void initScript(JSScript *script);
|
||||
JSScript *maybeScript() {
|
||||
@ -1375,8 +1382,8 @@ struct SharedScriptData
|
||||
uint32_t length;
|
||||
jsbytecode data[1];
|
||||
|
||||
static SharedScriptData *new_(JSContext *cx, uint32_t codeLength,
|
||||
uint32_t srcnotesLength, uint32_t natoms);
|
||||
static SharedScriptData *new_(ExclusiveContext *cx, uint32_t codeLength,
|
||||
uint32_t srcnotesLength, uint32_t natoms);
|
||||
|
||||
HeapPtrAtom *atoms(uint32_t codeLength, uint32_t srcnotesLength) {
|
||||
uint32_t length = codeLength + srcnotesLength;
|
||||
@ -1396,7 +1403,7 @@ struct SharedScriptData
|
||||
* Sets the |code| and |atoms| fields on the given JSScript.
|
||||
*/
|
||||
extern bool
|
||||
SaveSharedScriptData(JSContext *cx, Handle<JSScript *> script, SharedScriptData *ssd);
|
||||
SaveSharedScriptData(ExclusiveContext *cx, Handle<JSScript *> script, SharedScriptData *ssd);
|
||||
|
||||
struct ScriptBytecodeHasher
|
||||
{
|
||||
|
@ -3630,22 +3630,22 @@ js_InitStringClass(JSContext *cx, HandleObject obj)
|
||||
|
||||
template <AllowGC allowGC>
|
||||
JSStableString *
|
||||
js_NewString(ThreadSafeContext *tcx, jschar *chars, size_t length)
|
||||
js_NewString(ThreadSafeContext *cx, jschar *chars, size_t length)
|
||||
{
|
||||
return JSStableString::new_<allowGC>(tcx, chars, length);
|
||||
return JSStableString::new_<allowGC>(cx, chars, length);
|
||||
}
|
||||
|
||||
template JSStableString *
|
||||
js_NewString<CanGC>(ThreadSafeContext *tcx, jschar *chars, size_t length);
|
||||
js_NewString<CanGC>(ThreadSafeContext *cx, jschar *chars, size_t length);
|
||||
|
||||
template JSStableString *
|
||||
js_NewString<NoGC>(ThreadSafeContext *tcx, jschar *chars, size_t length);
|
||||
js_NewString<NoGC>(ThreadSafeContext *cx, jschar *chars, size_t length);
|
||||
|
||||
JSLinearString *
|
||||
js_NewDependentString(JSContext *cx, JSString *baseArg, size_t start, size_t length)
|
||||
{
|
||||
if (length == 0)
|
||||
return cx->runtime()->emptyString;
|
||||
return cx->emptyString();
|
||||
|
||||
JSLinearString *base = baseArg->ensureLinear(cx);
|
||||
if (!base)
|
||||
@ -3664,7 +3664,7 @@ js_NewDependentString(JSContext *cx, JSString *baseArg, size_t start, size_t len
|
||||
|
||||
template <AllowGC allowGC>
|
||||
JSFlatString *
|
||||
js_NewStringCopyN(JSContext *cx, const jschar *s, size_t n)
|
||||
js_NewStringCopyN(ExclusiveContext *cx, const jschar *s, size_t n)
|
||||
{
|
||||
if (JSShortString::lengthFits(n))
|
||||
return NewShortString<allowGC>(cx, TwoByteChars(s, n));
|
||||
@ -3681,36 +3681,36 @@ js_NewStringCopyN(JSContext *cx, const jschar *s, size_t n)
|
||||
}
|
||||
|
||||
template JSFlatString *
|
||||
js_NewStringCopyN<CanGC>(JSContext *cx, const jschar *s, size_t n);
|
||||
js_NewStringCopyN<CanGC>(ExclusiveContext *cx, const jschar *s, size_t n);
|
||||
|
||||
template JSFlatString *
|
||||
js_NewStringCopyN<NoGC>(JSContext *cx, const jschar *s, size_t n);
|
||||
js_NewStringCopyN<NoGC>(ExclusiveContext *cx, const jschar *s, size_t n);
|
||||
|
||||
template <AllowGC allowGC>
|
||||
JSFlatString *
|
||||
js_NewStringCopyN(ThreadSafeContext *tcx, const char *s, size_t n)
|
||||
js_NewStringCopyN(ThreadSafeContext *cx, const char *s, size_t n)
|
||||
{
|
||||
if (JSShortString::lengthFits(n))
|
||||
return NewShortString<allowGC>(tcx, JS::Latin1Chars(s, n));
|
||||
return NewShortString<allowGC>(cx, JS::Latin1Chars(s, n));
|
||||
|
||||
jschar *chars = InflateString(tcx, s, &n);
|
||||
jschar *chars = InflateString(cx, s, &n);
|
||||
if (!chars)
|
||||
return NULL;
|
||||
JSFlatString *str = js_NewString<allowGC>(tcx, chars, n);
|
||||
JSFlatString *str = js_NewString<allowGC>(cx, chars, n);
|
||||
if (!str)
|
||||
js_free(chars);
|
||||
return str;
|
||||
}
|
||||
|
||||
template JSFlatString *
|
||||
js_NewStringCopyN<CanGC>(ThreadSafeContext *tcx, const char *s, size_t n);
|
||||
js_NewStringCopyN<CanGC>(ThreadSafeContext *cx, const char *s, size_t n);
|
||||
|
||||
template JSFlatString *
|
||||
js_NewStringCopyN<NoGC>(ThreadSafeContext *tcx, const char *s, size_t n);
|
||||
js_NewStringCopyN<NoGC>(ThreadSafeContext *cx, const char *s, size_t n);
|
||||
|
||||
template <AllowGC allowGC>
|
||||
JSFlatString *
|
||||
js_NewStringCopyZ(JSContext *cx, const jschar *s)
|
||||
js_NewStringCopyZ(ExclusiveContext *cx, const jschar *s)
|
||||
{
|
||||
size_t n = js_strlen(s);
|
||||
if (JSShortString::lengthFits(n))
|
||||
@ -3728,23 +3728,23 @@ js_NewStringCopyZ(JSContext *cx, const jschar *s)
|
||||
}
|
||||
|
||||
template JSFlatString *
|
||||
js_NewStringCopyZ<CanGC>(JSContext *cx, const jschar *s);
|
||||
js_NewStringCopyZ<CanGC>(ExclusiveContext *cx, const jschar *s);
|
||||
|
||||
template JSFlatString *
|
||||
js_NewStringCopyZ<NoGC>(JSContext *cx, const jschar *s);
|
||||
js_NewStringCopyZ<NoGC>(ExclusiveContext *cx, const jschar *s);
|
||||
|
||||
template <AllowGC allowGC>
|
||||
JSFlatString *
|
||||
js_NewStringCopyZ(ThreadSafeContext *tcx, const char *s)
|
||||
js_NewStringCopyZ(ThreadSafeContext *cx, const char *s)
|
||||
{
|
||||
return js_NewStringCopyN<allowGC>(tcx, s, strlen(s));
|
||||
return js_NewStringCopyN<allowGC>(cx, s, strlen(s));
|
||||
}
|
||||
|
||||
template JSFlatString *
|
||||
js_NewStringCopyZ<CanGC>(ThreadSafeContext *tcx, const char *s);
|
||||
js_NewStringCopyZ<CanGC>(ThreadSafeContext *cx, const char *s);
|
||||
|
||||
template JSFlatString *
|
||||
js_NewStringCopyZ<NoGC>(ThreadSafeContext *tcx, const char *s);
|
||||
js_NewStringCopyZ<NoGC>(ThreadSafeContext *cx, const char *s);
|
||||
|
||||
const char *
|
||||
js_ValueToPrintable(JSContext *cx, const Value &vArg, JSAutoByteString *bytes, bool asSource)
|
||||
@ -3765,7 +3765,7 @@ js_ValueToPrintable(JSContext *cx, const Value &vArg, JSAutoByteString *bytes, b
|
||||
|
||||
template <AllowGC allowGC>
|
||||
JSString *
|
||||
js::ToStringSlow(JSContext *cx, typename MaybeRooted<Value, allowGC>::HandleType arg)
|
||||
js::ToStringSlow(ExclusiveContext *cx, typename MaybeRooted<Value, allowGC>::HandleType arg)
|
||||
{
|
||||
/* As with ToObjectSlow, callers must verify that |arg| isn't a string. */
|
||||
JS_ASSERT(!arg.isString());
|
||||
@ -3775,7 +3775,7 @@ js::ToStringSlow(JSContext *cx, typename MaybeRooted<Value, allowGC>::HandleType
|
||||
if (!allowGC)
|
||||
return NULL;
|
||||
RootedValue v2(cx, v);
|
||||
if (!ToPrimitive(cx, JSTYPE_STRING, &v2))
|
||||
if (!ToPrimitive(cx->asJSContext(), JSTYPE_STRING, &v2))
|
||||
return NULL;
|
||||
v = v2;
|
||||
}
|
||||
@ -3798,10 +3798,10 @@ js::ToStringSlow(JSContext *cx, typename MaybeRooted<Value, allowGC>::HandleType
|
||||
}
|
||||
|
||||
template JSString *
|
||||
js::ToStringSlow<CanGC>(JSContext *cx, HandleValue arg);
|
||||
js::ToStringSlow<CanGC>(ExclusiveContext *cx, HandleValue arg);
|
||||
|
||||
template JSString *
|
||||
js::ToStringSlow<NoGC>(JSContext *cx, Value arg);
|
||||
js::ToStringSlow<NoGC>(ExclusiveContext *cx, Value arg);
|
||||
|
||||
JSString *
|
||||
js::ValueToSource(JSContext *cx, HandleValue v)
|
||||
@ -3972,14 +3972,14 @@ js_strchr_limit(const jschar *s, jschar c, const jschar *limit)
|
||||
}
|
||||
|
||||
jschar *
|
||||
js::InflateString(ThreadSafeContext *tcx, const char *bytes, size_t *lengthp)
|
||||
js::InflateString(ThreadSafeContext *cx, const char *bytes, size_t *lengthp)
|
||||
{
|
||||
size_t nchars;
|
||||
jschar *chars;
|
||||
size_t nbytes = *lengthp;
|
||||
|
||||
nchars = nbytes;
|
||||
chars = tcx->pod_malloc<jschar>(nchars + 1);
|
||||
chars = cx->pod_malloc<jschar>(nchars + 1);
|
||||
if (!chars)
|
||||
goto bad;
|
||||
for (size_t i = 0; i < nchars; i++)
|
||||
|
@ -117,7 +117,7 @@ extern const char js_encodeURIComponent_str[];
|
||||
/* GC-allocate a string descriptor for the given malloc-allocated chars. */
|
||||
template <js::AllowGC allowGC>
|
||||
extern JSStableString *
|
||||
js_NewString(js::ThreadSafeContext *tcx, jschar *chars, size_t length);
|
||||
js_NewString(js::ThreadSafeContext *cx, jschar *chars, size_t length);
|
||||
|
||||
extern JSLinearString *
|
||||
js_NewDependentString(JSContext *cx, JSString *base, size_t start, size_t length);
|
||||
@ -125,20 +125,20 @@ js_NewDependentString(JSContext *cx, JSString *base, size_t start, size_t length
|
||||
/* Copy a counted string and GC-allocate a descriptor for it. */
|
||||
template <js::AllowGC allowGC>
|
||||
extern JSFlatString *
|
||||
js_NewStringCopyN(JSContext *cx, const jschar *s, size_t n);
|
||||
js_NewStringCopyN(js::ExclusiveContext *cx, const jschar *s, size_t n);
|
||||
|
||||
template <js::AllowGC allowGC>
|
||||
extern JSFlatString *
|
||||
js_NewStringCopyN(js::ThreadSafeContext *tcx, const char *s, size_t n);
|
||||
js_NewStringCopyN(js::ThreadSafeContext *cx, const char *s, size_t n);
|
||||
|
||||
/* Copy a C string and GC-allocate a descriptor for it. */
|
||||
template <js::AllowGC allowGC>
|
||||
extern JSFlatString *
|
||||
js_NewStringCopyZ(JSContext *cx, const jschar *s);
|
||||
js_NewStringCopyZ(js::ExclusiveContext *cx, const jschar *s);
|
||||
|
||||
template <js::AllowGC allowGC>
|
||||
extern JSFlatString *
|
||||
js_NewStringCopyZ(js::ThreadSafeContext *tcx, const char *s);
|
||||
js_NewStringCopyZ(js::ThreadSafeContext *cx, const char *s);
|
||||
|
||||
/*
|
||||
* Convert a value to a printable C string.
|
||||
@ -155,7 +155,7 @@ namespace js {
|
||||
*/
|
||||
template <AllowGC allowGC>
|
||||
extern JSString *
|
||||
ToStringSlow(JSContext *cx, typename MaybeRooted<Value, allowGC>::HandleType arg);
|
||||
ToStringSlow(ExclusiveContext *cx, typename MaybeRooted<Value, allowGC>::HandleType arg);
|
||||
|
||||
/*
|
||||
* Convert the given value to a string. This method includes an inline
|
||||
@ -280,7 +280,7 @@ InflateUTF8String(JSContext *cx, const char *bytes, size_t *length);
|
||||
* return, will contain on return the number of copied chars.
|
||||
*/
|
||||
extern bool
|
||||
InflateStringToBuffer(JSContext *cx, const char *bytes, size_t length,
|
||||
InflateStringToBuffer(JSContext *maybecx, const char *bytes, size_t length,
|
||||
jschar *chars, size_t *charsLength);
|
||||
|
||||
extern bool
|
||||
|
@ -3160,7 +3160,7 @@ Parse(JSContext *cx, unsigned argc, jsval *vp)
|
||||
CompileOptions options(cx);
|
||||
options.setFileAndLine("<string>", 1)
|
||||
.setCompileAndGo(false);
|
||||
Parser<FullParseHandler> parser(cx, options,
|
||||
Parser<FullParseHandler> parser(cx, &cx->tempLifoAlloc(), options,
|
||||
JS_GetStringCharsZ(cx, scriptContents),
|
||||
JS_GetStringLength(scriptContents),
|
||||
/* foldConstants = */ true, NULL, NULL);
|
||||
@ -3201,7 +3201,8 @@ SyntaxParse(JSContext *cx, unsigned argc, jsval *vp)
|
||||
|
||||
const jschar *chars = JS_GetStringCharsZ(cx, scriptContents);
|
||||
size_t length = JS_GetStringLength(scriptContents);
|
||||
Parser<frontend::SyntaxParseHandler> parser(cx, options, chars, length, false, NULL, NULL);
|
||||
Parser<frontend::SyntaxParseHandler> parser(cx, &cx->tempLifoAlloc(),
|
||||
options, chars, length, false, NULL, NULL);
|
||||
|
||||
bool succeeded = parser.parse(NULL);
|
||||
if (cx->isExceptionPending())
|
||||
|
@ -180,7 +180,7 @@ ArgumentsObject::create(JSContext *cx, HandleScript script, HandleFunction calle
|
||||
bool strict = callee->strict();
|
||||
Class *clasp = strict ? &StrictArgumentsObject::class_ : &NormalArgumentsObject::class_;
|
||||
|
||||
RootedTypeObject type(cx, proto->getNewType(cx, clasp));
|
||||
RootedTypeObject type(cx, cx->getNewType(clasp, proto.get()));
|
||||
if (!type)
|
||||
return NULL;
|
||||
|
||||
|
@ -233,7 +233,7 @@ FetchName(JSContext *cx, HandleObject obj, HandleObject obj2, HandlePropertyName
|
||||
return true;
|
||||
}
|
||||
JSAutoByteString printable;
|
||||
if (js_AtomToPrintableString(cx, name, &printable))
|
||||
if (AtomToPrintableString(cx, name, &printable))
|
||||
js_ReportIsNotDefined(cx, printable.ptr());
|
||||
return false;
|
||||
}
|
||||
@ -329,7 +329,7 @@ DefVarOrConstOperation(JSContext *cx, HandleObject varobj, HandlePropertyName dn
|
||||
return false;
|
||||
if (attrs & JSPROP_READONLY) {
|
||||
JSAutoByteString bytes;
|
||||
if (js_AtomToPrintableString(cx, dn, &bytes)) {
|
||||
if (AtomToPrintableString(cx, dn, &bytes)) {
|
||||
JS_ALWAYS_FALSE(JS_ReportErrorFlagsAndNumber(cx, JSREPORT_ERROR,
|
||||
js_GetErrorMessage,
|
||||
NULL, JSMSG_REDECLARED_VAR,
|
||||
|
@ -3263,7 +3263,7 @@ js::GetScopeName(JSContext *cx, HandleObject scopeChain, HandlePropertyName name
|
||||
|
||||
if (!shape) {
|
||||
JSAutoByteString printable;
|
||||
if (js_AtomToPrintableString(cx, name, &printable))
|
||||
if (AtomToPrintableString(cx, name, &printable))
|
||||
js_ReportIsNotDefined(cx, printable.ptr());
|
||||
return false;
|
||||
}
|
||||
@ -3392,7 +3392,7 @@ js::DefFunOperation(JSContext *cx, HandleScript script, HandleObject scopeChain,
|
||||
|
||||
if (shape->isAccessorDescriptor() || !shape->writable() || !shape->enumerable()) {
|
||||
JSAutoByteString bytes;
|
||||
if (js_AtomToPrintableString(cx, name, &bytes)) {
|
||||
if (AtomToPrintableString(cx, name, &bytes)) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_REDEFINE_PROP,
|
||||
bytes.ptr());
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ js::ObjectImpl::compartment() const
|
||||
}
|
||||
|
||||
inline bool
|
||||
js::ObjectImpl::nativeContains(JSContext *cx, Shape *shape)
|
||||
js::ObjectImpl::nativeContains(ExclusiveContext *cx, Shape *shape)
|
||||
{
|
||||
return nativeLookup(cx, shape->propid()) == shape;
|
||||
}
|
||||
@ -48,12 +48,12 @@ js::ObjectImpl::nonProxyIsExtensible() const
|
||||
}
|
||||
|
||||
/* static */ inline bool
|
||||
js::ObjectImpl::isExtensible(JSContext *cx, js::Handle<ObjectImpl*> obj, bool *extensible)
|
||||
js::ObjectImpl::isExtensible(ExclusiveContext *cx, js::Handle<ObjectImpl*> obj, bool *extensible)
|
||||
{
|
||||
if (obj->isProxy()) {
|
||||
HandleObject h =
|
||||
HandleObject::fromMarkedLocation(reinterpret_cast<JSObject* const*>(obj.address()));
|
||||
return Proxy::isExtensible(cx, h, extensible);
|
||||
return Proxy::isExtensible(cx->asJSContext(), h, extensible);
|
||||
}
|
||||
|
||||
*extensible = obj->nonProxyIsExtensible();
|
||||
|
@ -322,7 +322,7 @@ js::ObjectImpl::slotInRange(uint32_t slot, SentinelAllowed sentinel) const
|
||||
MOZ_NEVER_INLINE
|
||||
#endif
|
||||
Shape *
|
||||
js::ObjectImpl::nativeLookup(JSContext *cx, jsid id)
|
||||
js::ObjectImpl::nativeLookup(ExclusiveContext *cx, jsid id)
|
||||
{
|
||||
MOZ_ASSERT(isNative());
|
||||
Shape **spp;
|
||||
|
@ -1242,7 +1242,7 @@ class ObjectImpl : public gc::Cell
|
||||
}
|
||||
|
||||
static inline bool
|
||||
isExtensible(JSContext *cx, Handle<ObjectImpl*> obj, bool *extensible);
|
||||
isExtensible(ExclusiveContext *cx, Handle<ObjectImpl*> obj, bool *extensible);
|
||||
|
||||
// Indicates whether a non-proxy is extensible. Don't call on proxies!
|
||||
// This method really shouldn't exist -- but there are a few internal
|
||||
@ -1292,18 +1292,19 @@ class ObjectImpl : public gc::Cell
|
||||
#endif
|
||||
|
||||
Shape *
|
||||
replaceWithNewEquivalentShape(JSContext *cx, Shape *existingShape, Shape *newShape = NULL);
|
||||
replaceWithNewEquivalentShape(ExclusiveContext *cx,
|
||||
Shape *existingShape, Shape *newShape = NULL);
|
||||
|
||||
enum GenerateShape {
|
||||
GENERATE_NONE,
|
||||
GENERATE_SHAPE
|
||||
};
|
||||
|
||||
bool setFlag(JSContext *cx, /*BaseShape::Flag*/ uint32_t flag,
|
||||
bool setFlag(ExclusiveContext *cx, /*BaseShape::Flag*/ uint32_t flag,
|
||||
GenerateShape generateShape = GENERATE_NONE);
|
||||
bool clearFlag(JSContext *cx, /*BaseShape::Flag*/ uint32_t flag);
|
||||
bool clearFlag(ExclusiveContext *cx, /*BaseShape::Flag*/ uint32_t flag);
|
||||
|
||||
bool toDictionaryMode(JSContext *cx);
|
||||
bool toDictionaryMode(ExclusiveContext *cx);
|
||||
|
||||
private:
|
||||
/*
|
||||
@ -1424,7 +1425,7 @@ class ObjectImpl : public gc::Cell
|
||||
return shape_;
|
||||
}
|
||||
|
||||
bool generateOwnShape(JSContext *cx, js::Shape *newShape = NULL) {
|
||||
bool generateOwnShape(ExclusiveContext *cx, js::Shape *newShape = NULL) {
|
||||
return replaceWithNewEquivalentShape(cx, lastProperty(), newShape);
|
||||
}
|
||||
|
||||
@ -1462,21 +1463,21 @@ class ObjectImpl : public gc::Cell
|
||||
/* Compute dynamicSlotsCount() for this object. */
|
||||
inline uint32_t numDynamicSlots() const;
|
||||
|
||||
Shape *nativeLookup(JSContext *cx, jsid id);
|
||||
Shape *nativeLookup(JSContext *cx, PropertyId pid) {
|
||||
Shape *nativeLookup(ExclusiveContext *cx, jsid id);
|
||||
Shape *nativeLookup(ExclusiveContext *cx, PropertyId pid) {
|
||||
return nativeLookup(cx, pid.asId());
|
||||
}
|
||||
Shape *nativeLookup(JSContext *cx, PropertyName *name) {
|
||||
Shape *nativeLookup(ExclusiveContext *cx, PropertyName *name) {
|
||||
return nativeLookup(cx, NameToId(name));
|
||||
}
|
||||
|
||||
bool nativeContains(JSContext *cx, jsid id) {
|
||||
bool nativeContains(ExclusiveContext *cx, jsid id) {
|
||||
return nativeLookup(cx, id) != NULL;
|
||||
}
|
||||
bool nativeContains(JSContext *cx, PropertyName* name) {
|
||||
bool nativeContains(ExclusiveContext *cx, PropertyName* name) {
|
||||
return nativeLookup(cx, name) != NULL;
|
||||
}
|
||||
inline bool nativeContains(JSContext *cx, Shape* shape);
|
||||
inline bool nativeContains(ExclusiveContext *cx, Shape* shape);
|
||||
|
||||
/*
|
||||
* Contextless; can be called from parallel code. Returns false if the
|
||||
|
@ -83,7 +83,7 @@ bool stopExecution(JSScript *script);
|
||||
/*
|
||||
* Object has been created. |obj| must exist (its class and size are read)
|
||||
*/
|
||||
bool createObject(JSContext *cx, JSObject *obj);
|
||||
bool createObject(ExclusiveContext *cx, JSObject *obj);
|
||||
|
||||
/*
|
||||
* Object is about to be finalized. |obj| must still exist (its class is
|
||||
@ -139,7 +139,7 @@ static const char *ObjectClassname(JSObject *obj) {
|
||||
#endif
|
||||
|
||||
inline bool
|
||||
Probes::createObject(JSContext *cx, JSObject *obj)
|
||||
Probes::createObject(ExclusiveContext *cx, JSObject *obj)
|
||||
{
|
||||
bool ok = true;
|
||||
|
||||
|
@ -31,7 +31,7 @@ RegExpObject::shared(RegExpGuard *g) const
|
||||
}
|
||||
|
||||
inline bool
|
||||
RegExpObject::getShared(JSContext *cx, RegExpGuard *g)
|
||||
RegExpObject::getShared(ExclusiveContext *cx, RegExpGuard *g)
|
||||
{
|
||||
if (RegExpShared *shared = maybeShared()) {
|
||||
g->init(*shared);
|
||||
@ -41,7 +41,7 @@ RegExpObject::getShared(JSContext *cx, RegExpGuard *g)
|
||||
}
|
||||
|
||||
inline void
|
||||
RegExpObject::setShared(JSContext *cx, RegExpShared &shared)
|
||||
RegExpObject::setShared(ExclusiveContext *cx, RegExpShared &shared)
|
||||
{
|
||||
shared.prepareForUse(cx);
|
||||
JSObject::setPrivate(&shared);
|
||||
@ -113,17 +113,17 @@ RegExpToShared(JSContext *cx, HandleObject obj, RegExpGuard *g)
|
||||
}
|
||||
|
||||
inline void
|
||||
RegExpShared::prepareForUse(JSContext *cx)
|
||||
RegExpShared::prepareForUse(ExclusiveContext *cx)
|
||||
{
|
||||
gcNumberWhenUsed = cx->runtime()->gcNumber;
|
||||
gcNumberWhenUsed = cx->gcNumber();
|
||||
}
|
||||
|
||||
RegExpGuard::RegExpGuard(JSContext *cx)
|
||||
RegExpGuard::RegExpGuard(ExclusiveContext *cx)
|
||||
: re_(NULL), source_(cx)
|
||||
{
|
||||
}
|
||||
|
||||
RegExpGuard::RegExpGuard(JSContext *cx, RegExpShared &re)
|
||||
RegExpGuard::RegExpGuard(ExclusiveContext *cx, RegExpShared &re)
|
||||
: re_(&re), source_(cx, re.source)
|
||||
{
|
||||
re_->incRef();
|
||||
|
@ -29,7 +29,7 @@ JS_STATIC_ASSERT(StickyFlag == JSREG_STICKY);
|
||||
|
||||
/* RegExpObjectBuilder */
|
||||
|
||||
RegExpObjectBuilder::RegExpObjectBuilder(JSContext *cx, RegExpObject *reobj)
|
||||
RegExpObjectBuilder::RegExpObjectBuilder(ExclusiveContext *cx, RegExpObject *reobj)
|
||||
: cx(cx), reobj_(cx, reobj)
|
||||
{}
|
||||
|
||||
@ -232,7 +232,7 @@ Class RegExpObject::class_ = {
|
||||
};
|
||||
|
||||
RegExpObject *
|
||||
RegExpObject::create(JSContext *cx, RegExpStatics *res, const jschar *chars, size_t length,
|
||||
RegExpObject::create(ExclusiveContext *cx, RegExpStatics *res, const jschar *chars, size_t length,
|
||||
RegExpFlag flags, TokenStream *tokenStream)
|
||||
{
|
||||
RegExpFlag staticsFlags = res->getFlags();
|
||||
@ -240,7 +240,7 @@ RegExpObject::create(JSContext *cx, RegExpStatics *res, const jschar *chars, siz
|
||||
}
|
||||
|
||||
RegExpObject *
|
||||
RegExpObject::createNoStatics(JSContext *cx, const jschar *chars, size_t length, RegExpFlag flags,
|
||||
RegExpObject::createNoStatics(ExclusiveContext *cx, const jschar *chars, size_t length, RegExpFlag flags,
|
||||
TokenStream *tokenStream)
|
||||
{
|
||||
RootedAtom source(cx, AtomizeChars<CanGC>(cx, chars, length));
|
||||
@ -251,7 +251,7 @@ RegExpObject::createNoStatics(JSContext *cx, const jschar *chars, size_t length,
|
||||
}
|
||||
|
||||
RegExpObject *
|
||||
RegExpObject::createNoStatics(JSContext *cx, HandleAtom source, RegExpFlag flags,
|
||||
RegExpObject::createNoStatics(ExclusiveContext *cx, HandleAtom source, RegExpFlag flags,
|
||||
TokenStream *tokenStream)
|
||||
{
|
||||
if (!RegExpShared::checkSyntax(cx, tokenStream, source))
|
||||
@ -262,12 +262,12 @@ RegExpObject::createNoStatics(JSContext *cx, HandleAtom source, RegExpFlag flags
|
||||
}
|
||||
|
||||
bool
|
||||
RegExpObject::createShared(JSContext *cx, RegExpGuard *g)
|
||||
RegExpObject::createShared(ExclusiveContext *cx, RegExpGuard *g)
|
||||
{
|
||||
Rooted<RegExpObject*> self(cx, this);
|
||||
|
||||
JS_ASSERT(!maybeShared());
|
||||
if (!cx->compartment()->regExps.get(cx, getSource(), getFlags(), g))
|
||||
if (!cx->regExps().get(cx, getSource(), getFlags(), g))
|
||||
return false;
|
||||
|
||||
self->setShared(cx, **g);
|
||||
@ -275,7 +275,7 @@ RegExpObject::createShared(JSContext *cx, RegExpGuard *g)
|
||||
}
|
||||
|
||||
Shape *
|
||||
RegExpObject::assignInitialShape(JSContext *cx)
|
||||
RegExpObject::assignInitialShape(ExclusiveContext *cx)
|
||||
{
|
||||
JS_ASSERT(is<RegExpObject>());
|
||||
JS_ASSERT(nativeEmpty());
|
||||
@ -307,7 +307,7 @@ RegExpObject::assignInitialShape(JSContext *cx)
|
||||
}
|
||||
|
||||
bool
|
||||
RegExpObject::init(JSContext *cx, HandleAtom source, RegExpFlag flags)
|
||||
RegExpObject::init(ExclusiveContext *cx, HandleAtom source, RegExpFlag flags)
|
||||
{
|
||||
Rooted<RegExpObject *> self(cx, this);
|
||||
|
||||
@ -382,12 +382,12 @@ RegExpObject::toString(JSContext *cx) const
|
||||
|
||||
/* RegExpShared */
|
||||
|
||||
RegExpShared::RegExpShared(JSRuntime *rt, JSAtom *source, RegExpFlag flags)
|
||||
RegExpShared::RegExpShared(JSAtom *source, RegExpFlag flags, uint64_t gcNumber)
|
||||
: source(source), flags(flags), parenCount(0),
|
||||
#if ENABLE_YARR_JIT
|
||||
codeBlock(),
|
||||
#endif
|
||||
bytecode(NULL), activeUseCount(0), gcNumberWhenUsed(rt->gcNumber)
|
||||
bytecode(NULL), activeUseCount(0), gcNumberWhenUsed(gcNumber)
|
||||
{}
|
||||
|
||||
RegExpShared::~RegExpShared()
|
||||
@ -400,7 +400,7 @@ RegExpShared::~RegExpShared()
|
||||
}
|
||||
|
||||
void
|
||||
RegExpShared::reportYarrError(JSContext *cx, TokenStream *ts, ErrorCode error)
|
||||
RegExpShared::reportYarrError(ExclusiveContext *cx, TokenStream *ts, ErrorCode error)
|
||||
{
|
||||
switch (error) {
|
||||
case JSC::Yarr::NoError:
|
||||
@ -410,7 +410,8 @@ RegExpShared::reportYarrError(JSContext *cx, TokenStream *ts, ErrorCode error)
|
||||
if (ts) \
|
||||
ts->reportError(__msg); \
|
||||
else \
|
||||
JS_ReportErrorFlagsAndNumberUC(cx, JSREPORT_ERROR, js_GetErrorMessage, NULL, __msg); \
|
||||
JS_ReportErrorFlagsAndNumberUC(cx->asJSContext(), \
|
||||
JSREPORT_ERROR, js_GetErrorMessage, NULL, __msg); \
|
||||
return
|
||||
COMPILE_EMSG(PatternTooLarge, JSMSG_REGEXP_TOO_COMPLEX);
|
||||
COMPILE_EMSG(QuantifierOutOfOrder, JSMSG_BAD_QUANTIFIER);
|
||||
@ -430,7 +431,7 @@ RegExpShared::reportYarrError(JSContext *cx, TokenStream *ts, ErrorCode error)
|
||||
}
|
||||
|
||||
bool
|
||||
RegExpShared::checkSyntax(JSContext *cx, TokenStream *tokenStream, JSLinearString *source)
|
||||
RegExpShared::checkSyntax(ExclusiveContext *cx, TokenStream *tokenStream, JSLinearString *source)
|
||||
{
|
||||
ErrorCode error = JSC::Yarr::checkSyntax(*source);
|
||||
if (error == JSC::Yarr::NoError)
|
||||
@ -683,7 +684,7 @@ RegExpCompartment::sweep(JSRuntime *rt)
|
||||
}
|
||||
|
||||
bool
|
||||
RegExpCompartment::get(JSContext *cx, JSAtom *source, RegExpFlag flags, RegExpGuard *g)
|
||||
RegExpCompartment::get(ExclusiveContext *cx, JSAtom *source, RegExpFlag flags, RegExpGuard *g)
|
||||
{
|
||||
Key key(source, flags);
|
||||
Map::AddPtr p = map_.lookupForAdd(key);
|
||||
@ -692,7 +693,7 @@ RegExpCompartment::get(JSContext *cx, JSAtom *source, RegExpFlag flags, RegExpGu
|
||||
return true;
|
||||
}
|
||||
|
||||
ScopedJSDeletePtr<RegExpShared> shared(cx->new_<RegExpShared>(cx->runtime(), source, flags));
|
||||
ScopedJSDeletePtr<RegExpShared> shared(cx->new_<RegExpShared>(source, flags, cx->gcNumber()));
|
||||
if (!shared)
|
||||
return false;
|
||||
|
||||
|
@ -55,14 +55,14 @@ enum RegExpRunStatus
|
||||
|
||||
class RegExpObjectBuilder
|
||||
{
|
||||
JSContext *cx;
|
||||
ExclusiveContext *cx;
|
||||
Rooted<RegExpObject*> reobj_;
|
||||
|
||||
bool getOrCreate();
|
||||
bool getOrCreateClone(RegExpObject *proto);
|
||||
|
||||
public:
|
||||
RegExpObjectBuilder(JSContext *cx, RegExpObject *reobj = NULL);
|
||||
RegExpObjectBuilder(ExclusiveContext *cx, RegExpObject *reobj = NULL);
|
||||
|
||||
RegExpObject *reobj() { return reobj_; }
|
||||
|
||||
@ -150,7 +150,7 @@ class RegExpShared
|
||||
bool compileMatchOnlyIfNecessary(JSContext *cx);
|
||||
|
||||
public:
|
||||
RegExpShared(JSRuntime *rt, JSAtom *source, RegExpFlag flags);
|
||||
RegExpShared(JSAtom *source, RegExpFlag flags, uint64_t gcNumber);
|
||||
~RegExpShared();
|
||||
|
||||
/* Explicit trace function for use by the RegExpStatics and JITs. */
|
||||
@ -160,11 +160,11 @@ class RegExpShared
|
||||
|
||||
/* Static functions to expose some Yarr logic. */
|
||||
static inline bool isJITRuntimeEnabled(JSContext *cx);
|
||||
static void reportYarrError(JSContext *cx, TokenStream *ts, ErrorCode error);
|
||||
static bool checkSyntax(JSContext *cx, TokenStream *tokenStream, JSLinearString *source);
|
||||
static void reportYarrError(ExclusiveContext *cx, TokenStream *ts, ErrorCode error);
|
||||
static bool checkSyntax(ExclusiveContext *cx, TokenStream *tokenStream, JSLinearString *source);
|
||||
|
||||
/* Called when a RegExpShared is installed into a RegExpObject. */
|
||||
inline void prepareForUse(JSContext *cx);
|
||||
inline void prepareForUse(ExclusiveContext *cx);
|
||||
|
||||
/* Primary interface: run this regular expression on the given string. */
|
||||
RegExpRunStatus execute(JSContext *cx, const jschar *chars, size_t length,
|
||||
@ -219,8 +219,8 @@ class RegExpGuard
|
||||
void operator=(const RegExpGuard &) MOZ_DELETE;
|
||||
|
||||
public:
|
||||
inline RegExpGuard(JSContext *cx);
|
||||
inline RegExpGuard(JSContext *cx, RegExpShared &re);
|
||||
inline RegExpGuard(ExclusiveContext *cx);
|
||||
inline RegExpGuard(ExclusiveContext *cx, RegExpShared &re);
|
||||
inline ~RegExpGuard();
|
||||
|
||||
public:
|
||||
@ -275,7 +275,7 @@ class RegExpCompartment
|
||||
bool init(JSContext *cx);
|
||||
void sweep(JSRuntime *rt);
|
||||
|
||||
bool get(JSContext *cx, JSAtom *source, RegExpFlag flags, RegExpGuard *g);
|
||||
bool get(ExclusiveContext *cx, JSAtom *source, RegExpFlag flags, RegExpGuard *g);
|
||||
|
||||
/* Like 'get', but compile 'maybeOpt' (if non-null). */
|
||||
bool get(JSContext *cx, HandleAtom source, JSString *maybeOpt, RegExpGuard *g);
|
||||
@ -303,15 +303,15 @@ class RegExpObject : public JSObject
|
||||
* execution, as opposed to during something like XDR.
|
||||
*/
|
||||
static RegExpObject *
|
||||
create(JSContext *cx, RegExpStatics *res, const jschar *chars, size_t length,
|
||||
create(ExclusiveContext *cx, RegExpStatics *res, const jschar *chars, size_t length,
|
||||
RegExpFlag flags, frontend::TokenStream *ts);
|
||||
|
||||
static RegExpObject *
|
||||
createNoStatics(JSContext *cx, const jschar *chars, size_t length, RegExpFlag flags,
|
||||
createNoStatics(ExclusiveContext *cx, const jschar *chars, size_t length, RegExpFlag flags,
|
||||
frontend::TokenStream *ts);
|
||||
|
||||
static RegExpObject *
|
||||
createNoStatics(JSContext *cx, HandleAtom atom, RegExpFlag flags, frontend::TokenStream *ts);
|
||||
createNoStatics(ExclusiveContext *cx, HandleAtom atom, RegExpFlag flags, frontend::TokenStream *ts);
|
||||
|
||||
/* Accessors. */
|
||||
|
||||
@ -347,8 +347,8 @@ class RegExpObject : public JSObject
|
||||
bool sticky() const { return getSlot(STICKY_FLAG_SLOT).toBoolean(); }
|
||||
|
||||
inline void shared(RegExpGuard *g) const;
|
||||
inline bool getShared(JSContext *cx, RegExpGuard *g);
|
||||
inline void setShared(JSContext *cx, RegExpShared &shared);
|
||||
inline bool getShared(ExclusiveContext *cx, RegExpGuard *g);
|
||||
inline void setShared(ExclusiveContext *cx, RegExpShared &shared);
|
||||
|
||||
private:
|
||||
friend class RegExpObjectBuilder;
|
||||
@ -358,15 +358,15 @@ class RegExpObject : public JSObject
|
||||
* encoding their initial properties. Return the shape after
|
||||
* changing this regular expression object's last property to it.
|
||||
*/
|
||||
Shape *assignInitialShape(JSContext *cx);
|
||||
Shape *assignInitialShape(ExclusiveContext *cx);
|
||||
|
||||
bool init(JSContext *cx, HandleAtom source, RegExpFlag flags);
|
||||
bool init(ExclusiveContext *cx, HandleAtom source, RegExpFlag flags);
|
||||
|
||||
/*
|
||||
* Precondition: the syntax for |source| has already been validated.
|
||||
* Side effect: sets the private field.
|
||||
*/
|
||||
bool createShared(JSContext *cx, RegExpGuard *g);
|
||||
bool createShared(ExclusiveContext *cx, RegExpGuard *g);
|
||||
RegExpShared *maybeShared() const;
|
||||
|
||||
/* Call setShared in preference to setPrivate. */
|
||||
|
@ -577,12 +577,12 @@ RegExpStatics::checkInvariants()
|
||||
#endif /* DEBUG */
|
||||
}
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
inline js::RegExpStatics *
|
||||
JSContext::regExpStatics()
|
||||
inline RegExpStatics *
|
||||
ExclusiveContext::regExpStatics()
|
||||
{
|
||||
return global()->getRegExpStatics();
|
||||
}
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
#endif /* vm_RegExpStatics_inl_h */
|
||||
|
@ -44,10 +44,13 @@
|
||||
struct DtoaState;
|
||||
|
||||
extern void
|
||||
js_ReportOutOfMemory(JSContext *cx);
|
||||
js_ReportOutOfMemory(js::ThreadSafeContext *cx);
|
||||
|
||||
extern void
|
||||
js_ReportAllocationOverflow(JSContext *cx);
|
||||
js_ReportAllocationOverflow(js::ThreadSafeContext *cx);
|
||||
|
||||
extern void
|
||||
js_ReportOverRecursed(js::ThreadSafeContext *cx);
|
||||
|
||||
namespace js {
|
||||
|
||||
@ -1163,9 +1166,6 @@ struct JSRuntime : public JS::shadow::Runtime,
|
||||
ExtraTracerVector gcBlackRootTracers;
|
||||
ExtraTracer gcGrayRootTracer;
|
||||
|
||||
/* Stack of thread-stack-allocated GC roots. */
|
||||
js::AutoGCRooter *autoGCRooters;
|
||||
|
||||
/*
|
||||
* The GC can only safely decommit memory when the page size of the
|
||||
* running process matches the compiled arena size.
|
||||
|
@ -30,7 +30,7 @@ typedef Rooted<ArgumentsObject *> RootedArgumentsObject;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
StaticScopeIter::StaticScopeIter(JSContext *cx, JSObject *objArg)
|
||||
StaticScopeIter::StaticScopeIter(ExclusiveContext *cx, JSObject *objArg)
|
||||
: obj(cx, objArg), onNamedLambda(false)
|
||||
{
|
||||
JS_ASSERT_IF(obj, obj->is<StaticBlockObject>() || obj->is<JSFunction>());
|
||||
@ -200,7 +200,7 @@ CallObject::createTemplateObject(JSContext *cx, HandleScript script, gc::Initial
|
||||
RootedShape shape(cx, script->bindings.callObjShape());
|
||||
JS_ASSERT(shape->getObjectClass() == &class_);
|
||||
|
||||
RootedTypeObject type(cx, cx->compartment()->getNewType(cx, &class_, NULL));
|
||||
RootedTypeObject type(cx, cx->getNewType(&class_, NULL));
|
||||
if (!type)
|
||||
return NULL;
|
||||
|
||||
@ -330,7 +330,7 @@ Class DeclEnvObject::class_ = {
|
||||
DeclEnvObject *
|
||||
DeclEnvObject::createTemplateObject(JSContext *cx, HandleFunction fun, gc::InitialHeap heap)
|
||||
{
|
||||
RootedTypeObject type(cx, cx->compartment()->getNewType(cx, &class_, NULL));
|
||||
RootedTypeObject type(cx, cx->getNewType(&class_, NULL));
|
||||
if (!type)
|
||||
return NULL;
|
||||
|
||||
@ -374,7 +374,7 @@ DeclEnvObject::create(JSContext *cx, HandleObject enclosing, HandleFunction call
|
||||
WithObject *
|
||||
WithObject::create(JSContext *cx, HandleObject proto, HandleObject enclosing, uint32_t depth)
|
||||
{
|
||||
RootedTypeObject type(cx, proto->getNewType(cx, &class_));
|
||||
RootedTypeObject type(cx, cx->getNewType(&class_, proto.get()));
|
||||
if (!type)
|
||||
return NULL;
|
||||
|
||||
@ -653,7 +653,7 @@ ClonedBlockObject::create(JSContext *cx, Handle<StaticBlockObject *> block, Abst
|
||||
assertSameCompartment(cx, frame);
|
||||
JS_ASSERT(block->getClass() == &BlockObject::class_);
|
||||
|
||||
RootedTypeObject type(cx, block->getNewType(cx, &BlockObject::class_));
|
||||
RootedTypeObject type(cx, cx->getNewType(&BlockObject::class_, block.get()));
|
||||
if (!type)
|
||||
return NULL;
|
||||
|
||||
@ -705,9 +705,9 @@ ClonedBlockObject::copyUnaliasedValues(AbstractFramePtr frame)
|
||||
}
|
||||
|
||||
StaticBlockObject *
|
||||
StaticBlockObject::create(JSContext *cx)
|
||||
StaticBlockObject::create(ExclusiveContext *cx)
|
||||
{
|
||||
RootedTypeObject type(cx, cx->compartment()->getNewType(cx, &BlockObject::class_, NULL));
|
||||
RootedTypeObject type(cx, cx->getNewType(&BlockObject::class_, NULL));
|
||||
if (!type)
|
||||
return NULL;
|
||||
|
||||
@ -725,7 +725,7 @@ StaticBlockObject::create(JSContext *cx)
|
||||
}
|
||||
|
||||
/* static */ Shape *
|
||||
StaticBlockObject::addVar(JSContext *cx, Handle<StaticBlockObject*> block, HandleId id,
|
||||
StaticBlockObject::addVar(ExclusiveContext *cx, Handle<StaticBlockObject*> block, HandleId id,
|
||||
int index, bool *redeclared)
|
||||
{
|
||||
JS_ASSERT(JSID_IS_ATOM(id) || (JSID_IS_INT(id) && JSID_TO_INT(id) == index));
|
||||
|
@ -57,7 +57,7 @@ class StaticScopeIter
|
||||
bool onNamedLambda;
|
||||
|
||||
public:
|
||||
explicit StaticScopeIter(JSContext *cx, JSObject *obj);
|
||||
explicit StaticScopeIter(ExclusiveContext *cx, JSObject *obj);
|
||||
|
||||
bool done() const;
|
||||
void operator++(int);
|
||||
@ -345,7 +345,7 @@ class BlockObject : public NestedScopeObject
|
||||
class StaticBlockObject : public BlockObject
|
||||
{
|
||||
public:
|
||||
static StaticBlockObject *create(JSContext *cx);
|
||||
static StaticBlockObject *create(ExclusiveContext *cx);
|
||||
|
||||
/* See StaticScopeIter comment. */
|
||||
JSObject *enclosingStaticScope() const {
|
||||
@ -408,8 +408,8 @@ class StaticBlockObject : public BlockObject
|
||||
void initPrevBlockChainFromParser(StaticBlockObject *prev);
|
||||
void resetPrevBlockChainFromParser();
|
||||
|
||||
static Shape *addVar(JSContext *cx, Handle<StaticBlockObject*> block, HandleId id,
|
||||
int index, bool *redeclared);
|
||||
static Shape *addVar(ExclusiveContext *cx, Handle<StaticBlockObject*> block, HandleId id,
|
||||
int index, bool *redeclared);
|
||||
};
|
||||
|
||||
class ClonedBlockObject : public BlockObject
|
||||
|
@ -662,6 +662,20 @@ JSRuntime::initSelfHosting(JSContext *cx)
|
||||
if (!JS_DefineFunctions(cx, shg, intrinsic_functions))
|
||||
return false;
|
||||
|
||||
/*
|
||||
* In self-hosting mode, scripts emit JSOP_CALLINTRINSIC instead of
|
||||
* JSOP_NAME or JSOP_GNAME to access unbound variables. JSOP_CALLINTRINSIC
|
||||
* does a name lookup in a special object, whose properties are filled in
|
||||
* lazily upon first access for a given global.
|
||||
*
|
||||
* As that object is inaccessible to client code, the lookups are
|
||||
* guaranteed to return the original objects, ensuring safe implementation
|
||||
* of self-hosted builtins.
|
||||
*
|
||||
* Additionally, the special syntax _CallFunction(receiver, ...args, fun)
|
||||
* is supported, for which bytecode is emitted that invokes |fun| with
|
||||
* |receiver| as the this-object and ...args as the arguments..
|
||||
*/
|
||||
CompileOptions options(cx);
|
||||
options.setFileAndLine("self-hosted", 1);
|
||||
options.setSelfHostingMode(true);
|
||||
|
@ -132,6 +132,18 @@ BaseShape::matchesGetterSetter(PropertyOp rawGetter, StrictPropertyOp rawSetter)
|
||||
return rawGetter == this->rawGetter && rawSetter == this->rawSetter;
|
||||
}
|
||||
|
||||
inline
|
||||
StackBaseShape::StackBaseShape(ExclusiveContext *cx, Class *clasp,
|
||||
JSObject *parent, JSObject *metadata, uint32_t objectFlags)
|
||||
: flags(objectFlags),
|
||||
clasp(clasp),
|
||||
parent(parent),
|
||||
metadata(metadata),
|
||||
rawGetter(NULL),
|
||||
rawSetter(NULL),
|
||||
compartment(cx->compartment_)
|
||||
{}
|
||||
|
||||
inline
|
||||
StackBaseShape::StackBaseShape(Shape *shape)
|
||||
: flags(shape->getObjectFlags()),
|
||||
@ -531,6 +543,59 @@ GetShapeAttributes(HandleShape shape)
|
||||
return IsImplicitDenseElement(shape) ? JSPROP_ENUMERATE : shape->attributes();
|
||||
}
|
||||
|
||||
inline
|
||||
AutoRooterGetterSetter::Inner::Inner(ExclusiveContext *cx, uint8_t attrs,
|
||||
PropertyOp *pgetter_, StrictPropertyOp *psetter_)
|
||||
: CustomAutoRooter(cx), attrs(attrs),
|
||||
pgetter(pgetter_), psetter(psetter_),
|
||||
getterRoot(cx, pgetter_), setterRoot(cx, psetter_)
|
||||
{
|
||||
JS_ASSERT_IF(attrs & JSPROP_GETTER, !IsPoisonedPtr(*pgetter));
|
||||
JS_ASSERT_IF(attrs & JSPROP_SETTER, !IsPoisonedPtr(*psetter));
|
||||
}
|
||||
|
||||
inline
|
||||
AutoRooterGetterSetter::AutoRooterGetterSetter(ExclusiveContext *cx, uint8_t attrs,
|
||||
PropertyOp *pgetter, StrictPropertyOp *psetter
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
|
||||
{
|
||||
if (attrs & (JSPROP_GETTER | JSPROP_SETTER))
|
||||
inner.construct(cx, attrs, pgetter, psetter);
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
}
|
||||
|
||||
inline
|
||||
StackBaseShape::AutoRooter::AutoRooter(ExclusiveContext *cx, const StackBaseShape *base_
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
|
||||
: CustomAutoRooter(cx), base(base_), skip(cx, base_)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
}
|
||||
|
||||
inline
|
||||
StackShape::AutoRooter::AutoRooter(ExclusiveContext *cx, const StackShape *shape_
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
|
||||
: CustomAutoRooter(cx), shape(shape_), skip(cx, shape_)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
}
|
||||
|
||||
template <AllowGC allowGC>
|
||||
inline
|
||||
Shape::Range<allowGC>::Range(ExclusiveContext *cx, Shape *shape)
|
||||
: cursor(cx, shape)
|
||||
{
|
||||
JS_STATIC_ASSERT(allowGC == CanGC);
|
||||
}
|
||||
|
||||
template <AllowGC allowGC>
|
||||
inline
|
||||
Shape::Range<allowGC>::Range(Shape *shape)
|
||||
: cursor((ExclusiveContext *) NULL, shape)
|
||||
{
|
||||
JS_STATIC_ASSERT(allowGC == NoGC);
|
||||
}
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
#endif /* vm_Shape_inl_h */
|
||||
|
@ -30,7 +30,7 @@ using mozilla::DebugOnly;
|
||||
using mozilla::PodZero;
|
||||
|
||||
bool
|
||||
ShapeTable::init(JSRuntime *rt, Shape *lastProp)
|
||||
ShapeTable::init(ExclusiveContext *cx, Shape *lastProp)
|
||||
{
|
||||
/*
|
||||
* Either we're creating a table for a large scope that was populated
|
||||
@ -47,7 +47,7 @@ ShapeTable::init(JSRuntime *rt, Shape *lastProp)
|
||||
* Use rt->calloc_ for memory accounting and overpressure handling
|
||||
* without OOM reporting. See ShapeTable::change.
|
||||
*/
|
||||
entries = (Shape **) rt->calloc_(sizeOfEntries(JS_BIT(sizeLog2)));
|
||||
entries = (Shape **) cx->calloc_(sizeOfEntries(JS_BIT(sizeLog2)));
|
||||
if (!entries)
|
||||
return false;
|
||||
|
||||
@ -67,7 +67,7 @@ ShapeTable::init(JSRuntime *rt, Shape *lastProp)
|
||||
}
|
||||
|
||||
bool
|
||||
Shape::makeOwnBaseShape(JSContext *cx)
|
||||
Shape::makeOwnBaseShape(ExclusiveContext *cx)
|
||||
{
|
||||
JS_ASSERT(!base()->isOwned());
|
||||
assertSameCompartmentDebugOnly(cx, compartment());
|
||||
@ -105,19 +105,18 @@ Shape::handoffTableTo(Shape *shape)
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
Shape::hashify(JSContext *cx, Shape *shape)
|
||||
Shape::hashify(ExclusiveContext *cx, Shape *shape)
|
||||
{
|
||||
JS_ASSERT(!shape->hasTable());
|
||||
|
||||
if (!shape->ensureOwnBaseShape(cx))
|
||||
return false;
|
||||
|
||||
JSRuntime *rt = cx->runtime();
|
||||
ShapeTable *table = rt->new_<ShapeTable>(shape->entryCount());
|
||||
ShapeTable *table = cx->new_<ShapeTable>(shape->entryCount());
|
||||
if (!table)
|
||||
return false;
|
||||
|
||||
if (!table->init(rt, shape)) {
|
||||
if (!table->init(cx, shape)) {
|
||||
js_free(table);
|
||||
return false;
|
||||
}
|
||||
@ -212,7 +211,7 @@ ShapeTable::search(jsid id, bool adding)
|
||||
}
|
||||
|
||||
bool
|
||||
ShapeTable::change(int log2Delta, JSContext *cx)
|
||||
ShapeTable::change(int log2Delta, ExclusiveContext *cx)
|
||||
{
|
||||
JS_ASSERT(entries);
|
||||
|
||||
@ -250,7 +249,7 @@ ShapeTable::change(int log2Delta, JSContext *cx)
|
||||
}
|
||||
|
||||
bool
|
||||
ShapeTable::grow(JSContext *cx)
|
||||
ShapeTable::grow(ExclusiveContext *cx)
|
||||
{
|
||||
JS_ASSERT(needsToGrow());
|
||||
|
||||
@ -258,14 +257,14 @@ ShapeTable::grow(JSContext *cx)
|
||||
int delta = removedCount < size >> 2;
|
||||
|
||||
if (!change(delta, cx) && entryCount + removedCount == size - 1) {
|
||||
JS_ReportOutOfMemory(cx);
|
||||
js_ReportOutOfMemory(cx);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Shape *
|
||||
Shape::getChildBinding(JSContext *cx, const StackShape &child)
|
||||
Shape::getChildBinding(ExclusiveContext *cx, const StackShape &child)
|
||||
{
|
||||
JS_ASSERT(!inDictionary());
|
||||
|
||||
@ -278,7 +277,7 @@ Shape::getChildBinding(JSContext *cx, const StackShape &child)
|
||||
}
|
||||
|
||||
/* static */ Shape *
|
||||
Shape::replaceLastProperty(JSContext *cx, const StackBaseShape &base,
|
||||
Shape::replaceLastProperty(ExclusiveContext *cx, const StackBaseShape &base,
|
||||
TaggedProto proto, HandleShape shape)
|
||||
{
|
||||
JS_ASSERT(!shape->inDictionary());
|
||||
@ -310,7 +309,8 @@ Shape::replaceLastProperty(JSContext *cx, const StackBaseShape &base,
|
||||
* one of lastProperty() or lastProperty()->parent.
|
||||
*/
|
||||
/* static */ Shape *
|
||||
JSObject::getChildProperty(JSContext *cx, HandleObject obj, HandleShape parent, StackShape &child)
|
||||
JSObject::getChildProperty(ExclusiveContext *cx,
|
||||
HandleObject obj, HandleShape parent, StackShape &child)
|
||||
{
|
||||
/*
|
||||
* Shared properties have no slot, but slot_ will reflect that of parent.
|
||||
@ -360,12 +360,12 @@ JSObject::getChildProperty(JSContext *cx, HandleObject obj, HandleShape parent,
|
||||
}
|
||||
|
||||
bool
|
||||
js::ObjectImpl::toDictionaryMode(JSContext *cx)
|
||||
js::ObjectImpl::toDictionaryMode(ExclusiveContext *cx)
|
||||
{
|
||||
JS_ASSERT(!inDictionaryMode());
|
||||
|
||||
/* We allocate the shapes from cx->compartment(), so make sure it's right. */
|
||||
JS_ASSERT(compartment() == cx->compartment());
|
||||
JS_ASSERT(cx->isInsideCurrentCompartment(this));
|
||||
|
||||
uint32_t span = slotSpan();
|
||||
|
||||
@ -440,7 +440,7 @@ NormalizeGetterAndSetter(JSObject *obj,
|
||||
}
|
||||
|
||||
/* static */ Shape *
|
||||
JSObject::addProperty(JSContext *cx, HandleObject obj, HandleId id,
|
||||
JSObject::addProperty(ExclusiveContext *cx, HandleObject obj, HandleId id,
|
||||
PropertyOp getter, StrictPropertyOp setter,
|
||||
uint32_t slot, unsigned attrs,
|
||||
unsigned flags, int shortid, bool allowDictionary)
|
||||
@ -451,7 +451,7 @@ JSObject::addProperty(JSContext *cx, HandleObject obj, HandleId id,
|
||||
if (!JSObject::isExtensible(cx, obj, &extensible))
|
||||
return NULL;
|
||||
if (!extensible) {
|
||||
obj->reportNotExtensible(cx);
|
||||
obj->reportNotExtensible(cx->asJSContext());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -478,7 +478,7 @@ ShouldConvertToDictionary(JSObject *obj)
|
||||
}
|
||||
|
||||
/* static */ Shape *
|
||||
JSObject::addPropertyInternal(JSContext *cx, HandleObject obj, HandleId id,
|
||||
JSObject::addPropertyInternal(ExclusiveContext *cx, HandleObject obj, HandleId id,
|
||||
PropertyOp getter, StrictPropertyOp setter,
|
||||
uint32_t slot, unsigned attrs,
|
||||
unsigned flags, int shortid, Shape **spp,
|
||||
@ -567,7 +567,7 @@ JSObject::addPropertyInternal(JSContext *cx, HandleObject obj, HandleId id,
|
||||
* enforce all restrictions from ECMA-262 v5 8.12.9 [[DefineOwnProperty]].
|
||||
*/
|
||||
inline bool
|
||||
CheckCanChangeAttrs(JSContext *cx, JSObject *obj, Shape *shape, unsigned *attrsp)
|
||||
CheckCanChangeAttrs(ExclusiveContext *cx, JSObject *obj, Shape *shape, unsigned *attrsp)
|
||||
{
|
||||
if (shape->configurable())
|
||||
return true;
|
||||
@ -578,7 +578,7 @@ CheckCanChangeAttrs(JSContext *cx, JSObject *obj, Shape *shape, unsigned *attrsp
|
||||
/* Reject attempts to remove a slot from the permanent data property. */
|
||||
if (shape->isDataDescriptor() && shape->hasSlot() &&
|
||||
(*attrsp & (JSPROP_GETTER | JSPROP_SETTER | JSPROP_SHARED))) {
|
||||
obj->reportNotConfigurable(cx, shape->propid());
|
||||
obj->reportNotConfigurable(cx->asJSContext(), shape->propid());
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -586,7 +586,7 @@ CheckCanChangeAttrs(JSContext *cx, JSObject *obj, Shape *shape, unsigned *attrsp
|
||||
}
|
||||
|
||||
/* static */ Shape *
|
||||
JSObject::putProperty(JSContext *cx, HandleObject obj, HandleId id,
|
||||
JSObject::putProperty(ExclusiveContext *cx, HandleObject obj, HandleId id,
|
||||
PropertyOp getter, StrictPropertyOp setter,
|
||||
uint32_t slot, unsigned attrs,
|
||||
unsigned flags, int shortid)
|
||||
@ -618,7 +618,7 @@ JSObject::putProperty(JSContext *cx, HandleObject obj, HandleId id,
|
||||
if (!JSObject::isExtensible(cx, obj, &extensible))
|
||||
return NULL;
|
||||
if (!extensible) {
|
||||
obj->reportNotExtensible(cx);
|
||||
obj->reportNotExtensible(cx->asJSContext());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -740,7 +740,7 @@ JSObject::putProperty(JSContext *cx, HandleObject obj, HandleId id,
|
||||
if (hadSlot && !shape->hasSlot()) {
|
||||
if (oldSlot < obj->slotSpan())
|
||||
obj->freeSlot(oldSlot);
|
||||
++cx->runtime()->propertyRemovals;
|
||||
++cx->asJSContext()->runtime()->propertyRemovals;
|
||||
}
|
||||
|
||||
obj->checkShapeConsistency();
|
||||
@ -749,7 +749,7 @@ JSObject::putProperty(JSContext *cx, HandleObject obj, HandleId id,
|
||||
}
|
||||
|
||||
/* static */ Shape *
|
||||
JSObject::changeProperty(JSContext *cx, HandleObject obj, HandleShape shape, unsigned attrs,
|
||||
JSObject::changeProperty(ExclusiveContext *cx, HandleObject obj, HandleShape shape, unsigned attrs,
|
||||
unsigned mask, PropertyOp getter, StrictPropertyOp setter)
|
||||
{
|
||||
JS_ASSERT(obj->nativeContains(cx, shape));
|
||||
@ -790,7 +790,7 @@ JSObject::changeProperty(JSContext *cx, HandleObject obj, HandleShape shape, uns
|
||||
}
|
||||
|
||||
bool
|
||||
JSObject::removeProperty(JSContext *cx, jsid id_)
|
||||
JSObject::removeProperty(ExclusiveContext *cx, jsid id_)
|
||||
{
|
||||
RootedId id(cx, id_);
|
||||
RootedObject self(cx, this);
|
||||
@ -844,7 +844,7 @@ JSObject::removeProperty(JSContext *cx, jsid id_)
|
||||
/* If shape has a slot, free its slot number. */
|
||||
if (shape->hasSlot()) {
|
||||
self->freeSlot(shape->slot());
|
||||
++cx->runtime()->propertyRemovals;
|
||||
++cx->asJSContext()->runtime()->propertyRemovals;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -943,9 +943,9 @@ JSObject::rollbackProperties(JSContext *cx, uint32_t slotSpan)
|
||||
}
|
||||
|
||||
Shape *
|
||||
js::ObjectImpl::replaceWithNewEquivalentShape(JSContext *cx, Shape *oldShape, Shape *newShape)
|
||||
ObjectImpl::replaceWithNewEquivalentShape(ExclusiveContext *cx, Shape *oldShape, Shape *newShape)
|
||||
{
|
||||
JS_ASSERT(cx->compartment() == oldShape->compartment());
|
||||
JS_ASSERT(cx->isInsideCurrentCompartment(oldShape));
|
||||
JS_ASSERT_IF(oldShape != lastProperty(),
|
||||
inDictionaryMode() &&
|
||||
nativeLookup(cx, oldShape->propidRef()) == oldShape);
|
||||
@ -997,7 +997,7 @@ js::ObjectImpl::replaceWithNewEquivalentShape(JSContext *cx, Shape *oldShape, Sh
|
||||
}
|
||||
|
||||
bool
|
||||
JSObject::shadowingShapeChange(JSContext *cx, const Shape &shape)
|
||||
JSObject::shadowingShapeChange(ExclusiveContext *cx, const Shape &shape)
|
||||
{
|
||||
return generateOwnShape(cx);
|
||||
}
|
||||
@ -1034,7 +1034,7 @@ JSObject::setParent(JSContext *cx, HandleObject obj, HandleObject parent)
|
||||
}
|
||||
|
||||
/* static */ Shape *
|
||||
Shape::setObjectParent(JSContext *cx, JSObject *parent, TaggedProto proto, Shape *last)
|
||||
Shape::setObjectParent(ExclusiveContext *cx, JSObject *parent, TaggedProto proto, Shape *last)
|
||||
{
|
||||
if (last->getObjectParent() == parent)
|
||||
return last;
|
||||
@ -1121,7 +1121,7 @@ js::ObjectImpl::preventExtensions(JSContext *cx, Handle<ObjectImpl*> obj)
|
||||
}
|
||||
|
||||
bool
|
||||
js::ObjectImpl::setFlag(JSContext *cx, /*BaseShape::Flag*/ uint32_t flag_,
|
||||
js::ObjectImpl::setFlag(ExclusiveContext *cx, /*BaseShape::Flag*/ uint32_t flag_,
|
||||
GenerateShape generateShape)
|
||||
{
|
||||
BaseShape::Flag flag = (BaseShape::Flag) flag_;
|
||||
@ -1154,7 +1154,7 @@ js::ObjectImpl::setFlag(JSContext *cx, /*BaseShape::Flag*/ uint32_t flag_,
|
||||
}
|
||||
|
||||
bool
|
||||
js::ObjectImpl::clearFlag(JSContext *cx, /*BaseShape::Flag*/ uint32_t flag)
|
||||
js::ObjectImpl::clearFlag(ExclusiveContext *cx, /*BaseShape::Flag*/ uint32_t flag)
|
||||
{
|
||||
JS_ASSERT(inDictionaryMode());
|
||||
JS_ASSERT(lastProperty()->getObjectFlags() & flag);
|
||||
@ -1172,7 +1172,7 @@ js::ObjectImpl::clearFlag(JSContext *cx, /*BaseShape::Flag*/ uint32_t flag)
|
||||
}
|
||||
|
||||
/* static */ Shape *
|
||||
Shape::setObjectFlag(JSContext *cx, BaseShape::Flag flag, TaggedProto proto, Shape *last)
|
||||
Shape::setObjectFlag(ExclusiveContext *cx, BaseShape::Flag flag, TaggedProto proto, Shape *last)
|
||||
{
|
||||
if (last->getObjectFlags() & flag)
|
||||
return last;
|
||||
@ -1229,9 +1229,9 @@ StackBaseShape::AutoRooter::trace(JSTracer *trc)
|
||||
}
|
||||
|
||||
/* static */ UnownedBaseShape*
|
||||
BaseShape::getUnowned(JSContext *cx, const StackBaseShape &base)
|
||||
BaseShape::getUnowned(ExclusiveContext *cx, const StackBaseShape &base)
|
||||
{
|
||||
BaseShapeSet &table = cx->compartment()->baseShapes;
|
||||
BaseShapeSet &table = cx->baseShapes();
|
||||
|
||||
if (!table.initialized() && !table.init())
|
||||
return NULL;
|
||||
@ -1320,14 +1320,14 @@ InitialShapeEntry::match(const InitialShapeEntry &key, const Lookup &lookup)
|
||||
}
|
||||
|
||||
/* static */ Shape *
|
||||
EmptyShape::getInitialShape(JSContext *cx, Class *clasp, TaggedProto proto,
|
||||
EmptyShape::getInitialShape(ExclusiveContext *cx, Class *clasp, TaggedProto proto,
|
||||
JSObject *parent, JSObject *metadata,
|
||||
size_t nfixed, uint32_t objectFlags)
|
||||
{
|
||||
JS_ASSERT_IF(proto.isObject(), cx->compartment() == proto.toObject()->compartment());
|
||||
JS_ASSERT_IF(parent, cx->compartment() == parent->compartment());
|
||||
JS_ASSERT_IF(proto.isObject(), cx->isInsideCurrentCompartment(proto.toObject()));
|
||||
JS_ASSERT_IF(parent, cx->isInsideCurrentCompartment(parent));
|
||||
|
||||
InitialShapeSet &table = cx->compartment()->initialShapes;
|
||||
InitialShapeSet &table = cx->initialShapes();
|
||||
|
||||
if (!table.initialized() && !table.init())
|
||||
return NULL;
|
||||
@ -1344,7 +1344,7 @@ EmptyShape::getInitialShape(JSContext *cx, Class *clasp, TaggedProto proto,
|
||||
RootedObject parentRoot(cx, parent);
|
||||
RootedObject metadataRoot(cx, metadata);
|
||||
|
||||
StackBaseShape base(cx->compartment(), clasp, parent, metadata, objectFlags);
|
||||
StackBaseShape base(cx, clasp, parent, metadata, objectFlags);
|
||||
Rooted<UnownedBaseShape*> nbase(cx, BaseShape::getUnowned(cx, base));
|
||||
if (!nbase)
|
||||
return NULL;
|
||||
@ -1364,7 +1364,7 @@ EmptyShape::getInitialShape(JSContext *cx, Class *clasp, TaggedProto proto,
|
||||
}
|
||||
|
||||
/* static */ Shape *
|
||||
EmptyShape::getInitialShape(JSContext *cx, Class *clasp, TaggedProto proto,
|
||||
EmptyShape::getInitialShape(ExclusiveContext *cx, Class *clasp, TaggedProto proto,
|
||||
JSObject *parent, JSObject *metadata,
|
||||
AllocKind kind, uint32_t objectFlags)
|
||||
{
|
||||
@ -1381,7 +1381,7 @@ NewObjectCache::invalidateEntriesForShape(JSContext *cx, HandleShape shape, Hand
|
||||
kind = GetBackgroundAllocKind(kind);
|
||||
|
||||
Rooted<GlobalObject *> global(cx, &shape->getObjectParent()->global());
|
||||
Rooted<types::TypeObject *> type(cx, proto->getNewType(cx, clasp));
|
||||
Rooted<types::TypeObject *> type(cx, cx->getNewType(clasp, proto.get()));
|
||||
|
||||
EntryIndex entry;
|
||||
if (lookupGlobal(clasp, global, kind, &entry))
|
||||
@ -1393,17 +1393,16 @@ NewObjectCache::invalidateEntriesForShape(JSContext *cx, HandleShape shape, Hand
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
EmptyShape::insertInitialShape(JSContext *cx, HandleShape shape, HandleObject proto)
|
||||
EmptyShape::insertInitialShape(ExclusiveContext *cx, HandleShape shape, HandleObject proto)
|
||||
{
|
||||
InitialShapeEntry::Lookup lookup(shape->getObjectClass(), TaggedProto(proto),
|
||||
shape->getObjectParent(), shape->getObjectMetadata(),
|
||||
shape->numFixedSlots(), shape->getObjectFlags());
|
||||
|
||||
InitialShapeSet::Ptr p = cx->compartment()->initialShapes.lookup(lookup);
|
||||
InitialShapeSet::Ptr p = cx->initialShapes().lookup(lookup);
|
||||
JS_ASSERT(p);
|
||||
|
||||
InitialShapeEntry &entry = const_cast<InitialShapeEntry &>(*p);
|
||||
JS_ASSERT(entry.shape->isEmptyShape());
|
||||
|
||||
/* The new shape had better be rooted at the old one. */
|
||||
#ifdef DEBUG
|
||||
@ -1418,12 +1417,17 @@ EmptyShape::insertInitialShape(JSContext *cx, HandleShape shape, HandleObject pr
|
||||
/*
|
||||
* This affects the shape that will be produced by the various NewObject
|
||||
* methods, so clear any cache entry referring to the old shape. This is
|
||||
* not required for correctness (though it may bust on the above asserts):
|
||||
* the NewObject must always check for a nativeEmpty() result and generate
|
||||
* the appropriate properties if found. Clearing the cache entry avoids
|
||||
* this duplicate regeneration.
|
||||
* not required for correctness: the NewObject must always check for a
|
||||
* nativeEmpty() result and generate the appropriate properties if found.
|
||||
* Clearing the cache entry avoids this duplicate regeneration.
|
||||
*
|
||||
* Clearing is not necessary when this context is running off the main
|
||||
* thread, as it will not use the new object cache for allocations.
|
||||
*/
|
||||
cx->runtime()->newObjectCache.invalidateEntriesForShape(cx, shape, proto);
|
||||
if (cx->isJSContext()) {
|
||||
JSContext *ncx = cx->asJSContext();
|
||||
ncx->runtime()->newObjectCache.invalidateEntriesForShape(ncx, shape, proto);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -160,15 +160,15 @@ struct ShapeTable {
|
||||
* and returns false. This will make any extant pointers into the
|
||||
* table invalid. Don't call this unless needsToGrow() is true.
|
||||
*/
|
||||
bool grow(JSContext *cx);
|
||||
bool grow(ExclusiveContext *cx);
|
||||
|
||||
/*
|
||||
* NB: init and change are fallible but do not report OOM, so callers can
|
||||
* cope or ignore. They do however use JSRuntime's calloc_ method in order
|
||||
* to update the malloc counter on success.
|
||||
* cope or ignore. They do however use the context's calloc_ method in
|
||||
* order to update the malloc counter on success.
|
||||
*/
|
||||
bool init(JSRuntime *rt, Shape *lastProp);
|
||||
bool change(int log2Delta, JSContext *cx);
|
||||
bool init(ExclusiveContext *cx, Shape *lastProp);
|
||||
bool change(int log2Delta, ExclusiveContext *cx);
|
||||
Shape **search(jsid id, bool adding);
|
||||
};
|
||||
|
||||
@ -339,7 +339,7 @@ class BaseShape : public js::gc::Cell
|
||||
JS::Zone *zone() const { return tenuredZone(); }
|
||||
|
||||
/* Lookup base shapes from the compartment's baseShapes table. */
|
||||
static UnownedBaseShape* getUnowned(JSContext *cx, const StackBaseShape &base);
|
||||
static UnownedBaseShape* getUnowned(ExclusiveContext *cx, const StackBaseShape &base);
|
||||
|
||||
/* Get the canonical base shape. */
|
||||
inline UnownedBaseShape* unowned();
|
||||
@ -414,17 +414,8 @@ struct StackBaseShape
|
||||
compartment(base->compartment())
|
||||
{}
|
||||
|
||||
StackBaseShape(JSCompartment *comp, Class *clasp,
|
||||
JSObject *parent, JSObject *metadata, uint32_t objectFlags)
|
||||
: flags(objectFlags),
|
||||
clasp(clasp),
|
||||
parent(parent),
|
||||
metadata(metadata),
|
||||
rawGetter(NULL),
|
||||
rawSetter(NULL),
|
||||
compartment(comp)
|
||||
{}
|
||||
|
||||
inline StackBaseShape(ExclusiveContext *cx, Class *clasp,
|
||||
JSObject *parent, JSObject *metadata, uint32_t objectFlags);
|
||||
inline StackBaseShape(Shape *shape);
|
||||
|
||||
inline void updateGetterSetter(uint8_t attrs,
|
||||
@ -437,12 +428,8 @@ struct StackBaseShape
|
||||
class AutoRooter : private JS::CustomAutoRooter
|
||||
{
|
||||
public:
|
||||
explicit AutoRooter(JSContext *cx, const StackBaseShape *base_
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: CustomAutoRooter(cx), base(base_), skip(cx, base_)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
}
|
||||
inline AutoRooter(ExclusiveContext *cx, const StackBaseShape *base_
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
|
||||
|
||||
private:
|
||||
virtual void trace(JSTracer *trc);
|
||||
@ -516,8 +503,8 @@ class Shape : public js::gc::Cell
|
||||
last, else to obj->shape_ */
|
||||
};
|
||||
|
||||
static inline Shape *search(JSContext *cx, Shape *start, jsid id,
|
||||
Shape ***pspp, bool adding = false);
|
||||
static inline Shape *search(ExclusiveContext *cx, Shape *start, jsid id,
|
||||
Shape ***pspp, bool adding = false);
|
||||
static inline Shape *searchNoHashify(Shape *start, jsid id);
|
||||
|
||||
inline void removeFromDictionary(ObjectImpl *obj);
|
||||
@ -526,24 +513,24 @@ class Shape : public js::gc::Cell
|
||||
inline void initDictionaryShape(const StackShape &child, uint32_t nfixed,
|
||||
HeapPtrShape *dictp);
|
||||
|
||||
Shape *getChildBinding(JSContext *cx, const StackShape &child);
|
||||
Shape *getChildBinding(ExclusiveContext *cx, const StackShape &child);
|
||||
|
||||
/* Replace the base shape of the last shape in a non-dictionary lineage with base. */
|
||||
static Shape *replaceLastProperty(JSContext *cx, const StackBaseShape &base,
|
||||
TaggedProto proto, HandleShape shape);
|
||||
static Shape *replaceLastProperty(ExclusiveContext *cx, const StackBaseShape &base,
|
||||
TaggedProto proto, HandleShape shape);
|
||||
|
||||
static bool hashify(JSContext *cx, Shape *shape);
|
||||
static bool hashify(ExclusiveContext *cx, Shape *shape);
|
||||
void handoffTableTo(Shape *newShape);
|
||||
|
||||
inline void setParent(Shape *p);
|
||||
|
||||
bool ensureOwnBaseShape(JSContext *cx) {
|
||||
bool ensureOwnBaseShape(ExclusiveContext *cx) {
|
||||
if (base()->isOwned())
|
||||
return true;
|
||||
return makeOwnBaseShape(cx);
|
||||
}
|
||||
|
||||
bool makeOwnBaseShape(JSContext *cx);
|
||||
bool makeOwnBaseShape(ExclusiveContext *cx);
|
||||
|
||||
public:
|
||||
bool hasTable() const { return base()->hasTable(); }
|
||||
@ -573,13 +560,8 @@ class Shape : public js::gc::Cell
|
||||
typename MaybeRooted<Shape*, allowGC>::RootType cursor;
|
||||
|
||||
public:
|
||||
Range(JSContext *cx, Shape *shape) : cursor(cx, shape) {
|
||||
JS_STATIC_ASSERT(allowGC == CanGC);
|
||||
}
|
||||
|
||||
Range(Shape *shape) : cursor(NULL, shape) {
|
||||
JS_STATIC_ASSERT(allowGC == NoGC);
|
||||
}
|
||||
inline Range(ExclusiveContext *cx, Shape *shape);
|
||||
inline Range(Shape *shape);
|
||||
|
||||
bool empty() const {
|
||||
return !cursor || cursor->isEmptyShape();
|
||||
@ -600,9 +582,12 @@ class Shape : public js::gc::Cell
|
||||
JSObject *getObjectParent() const { return base()->parent; }
|
||||
JSObject *getObjectMetadata() const { return base()->metadata; }
|
||||
|
||||
static Shape *setObjectParent(JSContext *cx, JSObject *obj, TaggedProto proto, Shape *last);
|
||||
static Shape *setObjectMetadata(JSContext *cx, JSObject *metadata, TaggedProto proto, Shape *last);
|
||||
static Shape *setObjectFlag(JSContext *cx, BaseShape::Flag flag, TaggedProto proto, Shape *last);
|
||||
static Shape *setObjectParent(ExclusiveContext *cx,
|
||||
JSObject *obj, TaggedProto proto, Shape *last);
|
||||
static Shape *setObjectMetadata(JSContext *cx,
|
||||
JSObject *metadata, TaggedProto proto, Shape *last);
|
||||
static Shape *setObjectFlag(ExclusiveContext *cx,
|
||||
BaseShape::Flag flag, TaggedProto proto, Shape *last);
|
||||
|
||||
uint32_t getObjectFlags() const { return base()->getObjectFlags(); }
|
||||
bool hasObjectFlag(BaseShape::Flag flag) const {
|
||||
@ -845,7 +830,7 @@ class Shape : public js::gc::Cell
|
||||
|
||||
inline void markChildren(JSTracer *trc);
|
||||
|
||||
inline Shape *search(JSContext *cx, jsid id) {
|
||||
inline Shape *search(ExclusiveContext *cx, jsid id) {
|
||||
Shape **_;
|
||||
return search(cx, this, id, &_);
|
||||
}
|
||||
@ -866,15 +851,8 @@ class AutoRooterGetterSetter
|
||||
class Inner : private JS::CustomAutoRooter
|
||||
{
|
||||
public:
|
||||
Inner(JSContext *cx, uint8_t attrs,
|
||||
PropertyOp *pgetter_, StrictPropertyOp *psetter_)
|
||||
: CustomAutoRooter(cx), attrs(attrs),
|
||||
pgetter(pgetter_), psetter(psetter_),
|
||||
getterRoot(cx, pgetter_), setterRoot(cx, psetter_)
|
||||
{
|
||||
JS_ASSERT_IF(attrs & JSPROP_GETTER, !IsPoisonedPtr(*pgetter));
|
||||
JS_ASSERT_IF(attrs & JSPROP_SETTER, !IsPoisonedPtr(*psetter));
|
||||
}
|
||||
inline Inner(ExclusiveContext *cx, uint8_t attrs,
|
||||
PropertyOp *pgetter_, StrictPropertyOp *psetter_);
|
||||
|
||||
private:
|
||||
virtual void trace(JSTracer *trc);
|
||||
@ -886,14 +864,9 @@ class AutoRooterGetterSetter
|
||||
};
|
||||
|
||||
public:
|
||||
explicit AutoRooterGetterSetter(JSContext *cx, uint8_t attrs,
|
||||
PropertyOp *pgetter, StrictPropertyOp *psetter
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
{
|
||||
if (attrs & (JSPROP_GETTER | JSPROP_SETTER))
|
||||
inner.construct(cx, attrs, pgetter, psetter);
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
}
|
||||
inline AutoRooterGetterSetter(ExclusiveContext *cx, uint8_t attrs,
|
||||
PropertyOp *pgetter, StrictPropertyOp *psetter
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
|
||||
|
||||
private:
|
||||
mozilla::Maybe<Inner> inner;
|
||||
@ -908,9 +881,11 @@ struct EmptyShape : public js::Shape
|
||||
* Lookup an initial shape matching the given parameters, creating an empty
|
||||
* shape if none was found.
|
||||
*/
|
||||
static Shape *getInitialShape(JSContext *cx, Class *clasp, TaggedProto proto, JSObject *metadata,
|
||||
static Shape *getInitialShape(ExclusiveContext *cx, Class *clasp,
|
||||
TaggedProto proto, JSObject *metadata,
|
||||
JSObject *parent, size_t nfixed, uint32_t objectFlags = 0);
|
||||
static Shape *getInitialShape(JSContext *cx, Class *clasp, TaggedProto proto, JSObject *metadata,
|
||||
static Shape *getInitialShape(ExclusiveContext *cx, Class *clasp,
|
||||
TaggedProto proto, JSObject *metadata,
|
||||
JSObject *parent, gc::AllocKind kind, uint32_t objectFlags = 0);
|
||||
|
||||
/*
|
||||
@ -918,7 +893,7 @@ struct EmptyShape : public js::Shape
|
||||
* getInitialShape calls, until the new shape becomes unreachable in a GC
|
||||
* and the table entry is purged.
|
||||
*/
|
||||
static void insertInitialShape(JSContext *cx, HandleShape shape, HandleObject proto);
|
||||
static void insertInitialShape(ExclusiveContext *cx, HandleShape shape, HandleObject proto);
|
||||
};
|
||||
|
||||
/*
|
||||
@ -1020,12 +995,8 @@ struct StackShape
|
||||
class AutoRooter : private JS::CustomAutoRooter
|
||||
{
|
||||
public:
|
||||
explicit AutoRooter(JSContext *cx, const StackShape *shape_
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: CustomAutoRooter(cx), shape(shape_), skip(cx, shape_)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
}
|
||||
inline AutoRooter(ExclusiveContext *cx, const StackShape *shape_
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
|
||||
|
||||
private:
|
||||
virtual void trace(JSTracer *trc);
|
||||
@ -1060,7 +1031,7 @@ struct StackShape
|
||||
namespace js {
|
||||
|
||||
inline Shape *
|
||||
Shape::search(JSContext *cx, Shape *start, jsid id, Shape ***pspp, bool adding)
|
||||
Shape::search(ExclusiveContext *cx, Shape *start, jsid id, Shape ***pspp, bool adding)
|
||||
{
|
||||
if (start->inDictionary()) {
|
||||
*pspp = start->table().search(id, adding);
|
||||
|
@ -20,13 +20,13 @@ namespace js {
|
||||
|
||||
template <AllowGC allowGC>
|
||||
static JS_ALWAYS_INLINE JSInlineString *
|
||||
NewShortString(ThreadSafeContext *tcx, JS::Latin1Chars chars)
|
||||
NewShortString(ThreadSafeContext *cx, JS::Latin1Chars chars)
|
||||
{
|
||||
size_t len = chars.length();
|
||||
JS_ASSERT(JSShortString::lengthFits(len));
|
||||
JSInlineString *str = JSInlineString::lengthFits(len)
|
||||
? JSInlineString::new_<allowGC>(tcx)
|
||||
: JSShortString::new_<allowGC>(tcx);
|
||||
? JSInlineString::new_<allowGC>(cx)
|
||||
: JSShortString::new_<allowGC>(cx);
|
||||
if (!str)
|
||||
return NULL;
|
||||
|
||||
@ -39,7 +39,7 @@ NewShortString(ThreadSafeContext *tcx, JS::Latin1Chars chars)
|
||||
|
||||
template <AllowGC allowGC>
|
||||
static JS_ALWAYS_INLINE JSInlineString *
|
||||
NewShortString(JSContext *cx, JS::StableTwoByteChars chars)
|
||||
NewShortString(ExclusiveContext *cx, JS::StableTwoByteChars chars)
|
||||
{
|
||||
size_t len = chars.length();
|
||||
|
||||
@ -62,7 +62,7 @@ NewShortString(JSContext *cx, JS::StableTwoByteChars chars)
|
||||
|
||||
template <AllowGC allowGC>
|
||||
static JS_ALWAYS_INLINE JSInlineString *
|
||||
NewShortString(JSContext *cx, JS::TwoByteChars chars)
|
||||
NewShortString(ExclusiveContext *cx, JS::TwoByteChars chars)
|
||||
{
|
||||
size_t len = chars.length();
|
||||
|
||||
@ -145,10 +145,9 @@ JSString::readBarrier(JSString *str)
|
||||
}
|
||||
|
||||
JS_ALWAYS_INLINE bool
|
||||
JSString::validateLength(js::ThreadSafeContext *maybetcx, size_t length)
|
||||
JSString::validateLength(js::ThreadSafeContext *maybecx, size_t length)
|
||||
{
|
||||
if (JS_UNLIKELY(length > JSString::MAX_LENGTH)) {
|
||||
JSContext *maybecx = maybetcx && maybetcx->isJSContext() ? maybetcx->asJSContext() : NULL;
|
||||
js_ReportAllocationOverflow(maybecx);
|
||||
return false;
|
||||
}
|
||||
@ -168,15 +167,14 @@ JSRope::init(JSString *left, JSString *right, size_t length)
|
||||
|
||||
template <js::AllowGC allowGC>
|
||||
JS_ALWAYS_INLINE JSRope *
|
||||
JSRope::new_(js::ThreadSafeContext *tcx,
|
||||
JSRope::new_(js::ThreadSafeContext *cx,
|
||||
typename js::MaybeRooted<JSString*, allowGC>::HandleType left,
|
||||
typename js::MaybeRooted<JSString*, allowGC>::HandleType right,
|
||||
size_t length)
|
||||
{
|
||||
js::ThreadSafeContext *tcxIfCanGC = allowGC ? tcx : NULL;
|
||||
if (!validateLength(tcxIfCanGC, length))
|
||||
if (!validateLength(cx, length))
|
||||
return NULL;
|
||||
JSRope *str = (JSRope *) js_NewGCString<allowGC>(tcx);
|
||||
JSRope *str = (JSRope *) js_NewGCString<allowGC>(cx);
|
||||
if (!str)
|
||||
return NULL;
|
||||
str->init(left, right, length);
|
||||
@ -201,7 +199,8 @@ JSDependentString::init(JSLinearString *base, const jschar *chars, size_t length
|
||||
}
|
||||
|
||||
JS_ALWAYS_INLINE JSLinearString *
|
||||
JSDependentString::new_(JSContext *cx, JSLinearString *baseArg, const jschar *chars, size_t length)
|
||||
JSDependentString::new_(js::ExclusiveContext *cx,
|
||||
JSLinearString *baseArg, const jschar *chars, size_t length)
|
||||
{
|
||||
/* Try to avoid long chains of dependent strings. */
|
||||
while (baseArg->isDependent())
|
||||
@ -284,13 +283,13 @@ JSStableString::init(const jschar *chars, size_t length)
|
||||
|
||||
template <js::AllowGC allowGC>
|
||||
JS_ALWAYS_INLINE JSStableString *
|
||||
JSStableString::new_(js::ThreadSafeContext *tcx, const jschar *chars, size_t length)
|
||||
JSStableString::new_(js::ThreadSafeContext *cx, const jschar *chars, size_t length)
|
||||
{
|
||||
JS_ASSERT(chars[length] == jschar(0));
|
||||
|
||||
if (!validateLength(tcx->isJSContext() ? tcx->asJSContext() : NULL, length))
|
||||
if (!validateLength(cx, length))
|
||||
return NULL;
|
||||
JSStableString *str = (JSStableString *)js_NewGCString<allowGC>(tcx);
|
||||
JSStableString *str = (JSStableString *)js_NewGCString<allowGC>(cx);
|
||||
if (!str)
|
||||
return NULL;
|
||||
str->init(chars, length);
|
||||
@ -299,9 +298,9 @@ JSStableString::new_(js::ThreadSafeContext *tcx, const jschar *chars, size_t len
|
||||
|
||||
template <js::AllowGC allowGC>
|
||||
JS_ALWAYS_INLINE JSInlineString *
|
||||
JSInlineString::new_(js::ThreadSafeContext *tcx)
|
||||
JSInlineString::new_(js::ThreadSafeContext *cx)
|
||||
{
|
||||
return (JSInlineString *)js_NewGCString<allowGC>(tcx);
|
||||
return (JSInlineString *)js_NewGCString<allowGC>(cx);
|
||||
}
|
||||
|
||||
JS_ALWAYS_INLINE jschar *
|
||||
@ -322,9 +321,9 @@ JSInlineString::resetLength(size_t length)
|
||||
|
||||
template <js::AllowGC allowGC>
|
||||
JS_ALWAYS_INLINE JSShortString *
|
||||
JSShortString::new_(js::ThreadSafeContext *tcx)
|
||||
JSShortString::new_(js::ThreadSafeContext *cx)
|
||||
{
|
||||
return js_NewGCShortString<allowGC>(tcx);
|
||||
return js_NewGCShortString<allowGC>(cx);
|
||||
}
|
||||
|
||||
JS_ALWAYS_INLINE void
|
||||
|
@ -326,12 +326,12 @@ JSRope::flatten(ThreadSafeContext *maybetcx)
|
||||
|
||||
template <AllowGC allowGC>
|
||||
JSString *
|
||||
js::ConcatStrings(ThreadSafeContext *tcx,
|
||||
js::ConcatStrings(ThreadSafeContext *cx,
|
||||
typename MaybeRooted<JSString*, allowGC>::HandleType left,
|
||||
typename MaybeRooted<JSString*, allowGC>::HandleType right)
|
||||
{
|
||||
JS_ASSERT_IF(!left->isAtom(), tcx->isInsideCurrentZone(left));
|
||||
JS_ASSERT_IF(!right->isAtom(), tcx->isInsideCurrentZone(right));
|
||||
JS_ASSERT_IF(!left->isAtom(), cx->isInsideCurrentZone(left));
|
||||
JS_ASSERT_IF(!right->isAtom(), cx->isInsideCurrentZone(right));
|
||||
|
||||
size_t leftLen = left->length();
|
||||
if (leftLen == 0)
|
||||
@ -342,18 +342,17 @@ js::ConcatStrings(ThreadSafeContext *tcx,
|
||||
return left;
|
||||
|
||||
size_t wholeLength = leftLen + rightLen;
|
||||
ThreadSafeContext *tcxIfCanGC = allowGC ? tcx : NULL;
|
||||
if (!JSString::validateLength(tcxIfCanGC, wholeLength))
|
||||
if (!JSString::validateLength(cx, wholeLength))
|
||||
return NULL;
|
||||
|
||||
if (JSShortString::lengthFits(wholeLength)) {
|
||||
JSShortString *str = js_NewGCShortString<allowGC>(tcx);
|
||||
JSShortString *str = js_NewGCShortString<allowGC>(cx);
|
||||
if (!str)
|
||||
return NULL;
|
||||
const jschar *leftChars = left->getChars(tcx);
|
||||
const jschar *leftChars = left->getChars(cx->asJSContext());
|
||||
if (!leftChars)
|
||||
return NULL;
|
||||
const jschar *rightChars = right->getChars(tcx);
|
||||
const jschar *rightChars = right->getChars(cx->asJSContext());
|
||||
if (!rightChars)
|
||||
return NULL;
|
||||
|
||||
@ -364,7 +363,7 @@ js::ConcatStrings(ThreadSafeContext *tcx,
|
||||
return str;
|
||||
}
|
||||
|
||||
return JSRope::new_<allowGC>(tcx, left, right, wholeLength);
|
||||
return JSRope::new_<allowGC>(cx, left, right, wholeLength);
|
||||
}
|
||||
|
||||
template JSString *
|
||||
|
@ -232,7 +232,7 @@ class JSString : public js::gc::Cell
|
||||
* representable by a JSString. An allocation overflow is reported if false
|
||||
* is returned.
|
||||
*/
|
||||
static inline bool validateLength(js::ThreadSafeContext *maybetcx, size_t length);
|
||||
static inline bool validateLength(js::ThreadSafeContext *maybecx, size_t length);
|
||||
|
||||
static void staticAsserts() {
|
||||
JS_STATIC_ASSERT(JS_BITS_PER_WORD >= 32);
|
||||
@ -445,7 +445,7 @@ class JSRope : public JSString
|
||||
|
||||
public:
|
||||
template <js::AllowGC allowGC>
|
||||
static inline JSRope *new_(js::ThreadSafeContext *tcx,
|
||||
static inline JSRope *new_(js::ThreadSafeContext *cx,
|
||||
typename js::MaybeRooted<JSString*, allowGC>::HandleType left,
|
||||
typename js::MaybeRooted<JSString*, allowGC>::HandleType right,
|
||||
size_t length);
|
||||
@ -508,7 +508,7 @@ class JSDependentString : public JSLinearString
|
||||
JSDependentString &asDependent() const MOZ_DELETE;
|
||||
|
||||
public:
|
||||
static inline JSLinearString *new_(JSContext *cx, JSLinearString *base,
|
||||
static inline JSLinearString *new_(js::ExclusiveContext *cx, JSLinearString *base,
|
||||
const jschar *chars, size_t length);
|
||||
};
|
||||
|
||||
@ -565,7 +565,8 @@ class JSStableString : public JSFlatString
|
||||
|
||||
public:
|
||||
template <js::AllowGC allowGC>
|
||||
static inline JSStableString *new_(js::ThreadSafeContext *cx, const jschar *chars, size_t length);
|
||||
static inline JSStableString *new_(js::ThreadSafeContext *cx,
|
||||
const jschar *chars, size_t length);
|
||||
|
||||
JS_ALWAYS_INLINE
|
||||
JS::StableCharPtr chars() const {
|
||||
@ -662,7 +663,7 @@ class JSInlineString : public JSFlatString
|
||||
|
||||
public:
|
||||
template <js::AllowGC allowGC>
|
||||
static inline JSInlineString *new_(js::ThreadSafeContext *tcx);
|
||||
static inline JSInlineString *new_(js::ThreadSafeContext *cx);
|
||||
|
||||
inline jschar *init(size_t length);
|
||||
|
||||
@ -698,7 +699,7 @@ class JSShortString : public JSInlineString
|
||||
|
||||
public:
|
||||
template <js::AllowGC allowGC>
|
||||
static inline JSShortString *new_(js::ThreadSafeContext *tcx);
|
||||
static inline JSShortString *new_(js::ThreadSafeContext *cx);
|
||||
|
||||
static const size_t MAX_SHORT_LENGTH = JSString::NUM_INLINE_CHARS +
|
||||
INLINE_EXTENSION_CHARS
|
||||
|
@ -1728,7 +1728,7 @@ class TypedArrayObjectTemplate : public TypedArrayObject
|
||||
if (!obj)
|
||||
return NULL;
|
||||
|
||||
types::TypeObject *type = proto->getNewType(cx, obj->getClass());
|
||||
types::TypeObject *type = cx->getNewType(obj->getClass(), proto.get());
|
||||
if (!type)
|
||||
return NULL;
|
||||
obj->setType(type);
|
||||
@ -2778,7 +2778,7 @@ DataViewObject::create(JSContext *cx, uint32_t byteOffset, uint32_t byteLength,
|
||||
return NULL;
|
||||
|
||||
if (proto) {
|
||||
types::TypeObject *type = proto->getNewType(cx, &class_);
|
||||
types::TypeObject *type = cx->getNewType(&class_, TaggedProto(proto));
|
||||
if (!type)
|
||||
return NULL;
|
||||
obj->setType(type);
|
||||
|
Loading…
x
Reference in New Issue
Block a user