diff --git a/js/src/builtin/Eval.cpp b/js/src/builtin/Eval.cpp index 345a0f95d9e6..59fb11156063 100644 --- a/js/src/builtin/Eval.cpp +++ b/js/src/builtin/Eval.cpp @@ -183,7 +183,7 @@ ParseEvalStringAsJSON(JSContext* cx, const mozilla::Range chars, Mu ? chars : mozilla::Range(chars.start().get() + 1U, len - 2); - JSONParser parser(cx, jsonChars, JSONParserBase::NoError); + Rooted> parser(cx, JSONParser(cx, jsonChars, JSONParserBase::NoError)); if (!parser.parse(rval)) return EvalJSON_Failure; diff --git a/js/src/gc/RootMarking.cpp b/js/src/gc/RootMarking.cpp index 8fade7de3974..9d1e82f31be9 100644 --- a/js/src/gc/RootMarking.cpp +++ b/js/src/gc/RootMarking.cpp @@ -146,10 +146,6 @@ AutoGCRooter::trace(JSTracer* trc) return; } - case JSONPARSER: - static_cast(this)->trace(trc); - return; - case CUSTOM: static_cast(this)->trace(trc); return; diff --git a/js/src/json.cpp b/js/src/json.cpp index 1e36e7516623..f97914a418e0 100644 --- a/js/src/json.cpp +++ b/js/src/json.cpp @@ -822,7 +822,7 @@ js::ParseJSONWithReviver(JSContext* cx, const mozilla::Range chars, MutableHandleValue vp) { /* 15.12.2 steps 2-3. */ - JSONParser parser(cx, chars); + Rooted> parser(cx, JSONParser(cx, chars)); if (!parser.parse(vp)) return false; diff --git a/js/src/jspubtd.h b/js/src/jspubtd.h index aa9b246853e9..ca5fc7cb77a3 100644 --- a/js/src/jspubtd.h +++ b/js/src/jspubtd.h @@ -224,7 +224,6 @@ class JS_PUBLIC_API(AutoGCRooter) IONMASM = -19, /* js::jit::MacroAssembler */ WRAPVECTOR = -20, /* js::AutoWrapperVector */ WRAPPER = -21, /* js::AutoWrapperRooter */ - JSONPARSER = -25, /* js::JSONParser */ CUSTOM = -26 /* js::CustomAutoRooter */ }; diff --git a/js/src/vm/JSONParser.h b/js/src/vm/JSONParser.h index ddeddad6379a..687972392b02 100644 --- a/js/src/vm/JSONParser.h +++ b/js/src/vm/JSONParser.h @@ -20,7 +20,7 @@ namespace js { // JSONParser base class. JSONParser is templatized to work on either Latin1 // or TwoByte input strings, JSONParserBase holds all state and methods that // can be shared between the two encodings. -class MOZ_STACK_CLASS JSONParserBase : private JS::AutoGCRooter +class MOZ_STACK_CLASS JSONParserBase { public: enum ErrorHandling { RaiseError, NoError }; @@ -108,8 +108,7 @@ class MOZ_STACK_CLASS JSONParserBase : private JS::AutoGCRooter #endif JSONParserBase(JSContext* cx, ErrorHandling errorHandling) - : JS::AutoGCRooter(cx, JSONPARSER), - cx(cx), + : cx(cx), errorHandling(errorHandling), stack(cx), freeElements(cx), @@ -120,6 +119,20 @@ class MOZ_STACK_CLASS JSONParserBase : private JS::AutoGCRooter {} ~JSONParserBase(); + // Allow move construction for use with Rooted. + JSONParserBase(JSONParserBase&& other) + : v(other.v), + cx(other.cx), + errorHandling(other.errorHandling), + stack(mozilla::Move(other.stack)), + freeElements(mozilla::Move(other.freeElements)), + freeProperties(mozilla::Move(other.freeProperties)) +#ifdef DEBUG + , lastToken(mozilla::Move(other.lastToken)) +#endif + {} + + Value numberValue() const { MOZ_ASSERT(lastToken == Number); MOZ_ASSERT(v.isNumber()); @@ -169,16 +182,16 @@ class MOZ_STACK_CLASS JSONParserBase : private JS::AutoGCRooter bool finishObject(MutableHandleValue vp, PropertyVector& properties); bool finishArray(MutableHandleValue vp, ElementVector& elements); - private: - friend void AutoGCRooter::trace(JSTracer* trc); void trace(JSTracer* trc); + private: JSONParserBase(const JSONParserBase& other) = delete; void operator=(const JSONParserBase& other) = delete; }; template -class MOZ_STACK_CLASS JSONParser : public JSONParserBase +class MOZ_STACK_CLASS JSONParser : public JSONParserBase, + public JS::Traceable { private: typedef mozilla::RangedPtr CharPtr; @@ -200,6 +213,14 @@ class MOZ_STACK_CLASS JSONParser : public JSONParserBase MOZ_ASSERT(current <= end); } + /* Allow move construction for use with Rooted. */ + JSONParser(JSONParser&& other) + : JSONParserBase(mozilla::Forward(other)), + current(other.current), + begin(other.begin), + end(other.end) + {} + /* * Parse the JSON data specified at construction time. If it parses * successfully, store the prescribed value in *vp and return true. If an @@ -212,6 +233,9 @@ class MOZ_STACK_CLASS JSONParser : public JSONParserBase */ bool parse(MutableHandleValue vp); + static void trace(JSONParser* parser, JSTracer* trc) { parser->trace(trc); } + void trace(JSTracer* trc) { JSONParserBase::trace(trc); } + private: template Token readString(); @@ -233,6 +257,13 @@ class MOZ_STACK_CLASS JSONParser : public JSONParserBase void operator=(const JSONParser& other) = delete; }; +template +struct RootedBase> { + bool parse(MutableHandleValue vp) { + return static_cast>*>(this)->get().parse(vp); + } +}; + } /* namespace js */ #endif /* vm_JSONParser_h */