Bug 1479058 Part 7 - Store time warp target on Error objects, r=jandem.

--HG--
extra : rebase_source : b848b53d363797e2894630b4f9dac59a51481f6d
This commit is contained in:
Brian Hackett 2018-08-02 23:30:54 +00:00
Родитель 9844ce064b
Коммит 49770ee0cf
5 изменённых файлов: 42 добавлений и 1 удалений

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

@ -5587,6 +5587,15 @@ namespace JS {
extern JS_PUBLIC_API(JSObject*) extern JS_PUBLIC_API(JSObject*)
ExceptionStackOrNull(JS::HandleObject obj); ExceptionStackOrNull(JS::HandleObject obj);
/**
* If this process is recording or replaying and the given value is an
* exception object (or an unwrappable cross-compartment wrapper for one),
* return the point where this exception was thrown, for time warping later.
* Returns zero otherwise.
*/
extern JS_PUBLIC_API(uint64_t)
ExceptionTimeWarpTarget(JS::HandleValue exn);
} /* namespace JS */ } /* namespace JS */
/** /**

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

@ -426,6 +426,19 @@ JS::ExceptionStackOrNull(HandleObject objArg)
return obj->as<ErrorObject>().stack(); return obj->as<ErrorObject>().stack();
} }
JS_PUBLIC_API(uint64_t)
JS::ExceptionTimeWarpTarget(JS::HandleValue value)
{
if (!value.isObject())
return 0;
JSObject* obj = CheckedUnwrap(&value.toObject());
if (!obj || !obj->is<ErrorObject>())
return 0;
return obj->as<ErrorObject>().timeWarpTarget();
}
bool bool
Error(JSContext* cx, unsigned argc, Value* vp) Error(JSContext* cx, unsigned argc, Value* vp)
{ {

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

@ -38,4 +38,11 @@ js::ErrorObject::stack() const
return getReservedSlotRef(STACK_SLOT).toObjectOrNull(); return getReservedSlotRef(STACK_SLOT).toObjectOrNull();
} }
inline uint64_t
js::ErrorObject::timeWarpTarget() const
{
const HeapSlot& slot = getReservedSlotRef(TIME_WARP_SLOT);
return slot.isDouble() ? slot.toDouble() : 0;
}
#endif /* vm_ErrorObject_inl_h */ #endif /* vm_ErrorObject_inl_h */

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

@ -84,6 +84,16 @@ js::ErrorObject::init(JSContext* cx, Handle<ErrorObject*> obj, JSExnType type,
if (message) if (message)
obj->setSlotWithType(cx, messageShape, StringValue(message)); obj->setSlotWithType(cx, messageShape, StringValue(message));
// When recording/replaying and running on the main thread, get a counter
// which the devtools can use to warp to this point in the future.
if (mozilla::recordreplay::IsRecordingOrReplaying() && !cx->runtime()->parentRuntime) {
uint64_t timeWarpTarget = mozilla::recordreplay::NewTimeWarpTarget();
// Make sure we don't truncate the time warp target by storing it as a double.
MOZ_RELEASE_ASSERT(timeWarpTarget < uint64_t(DOUBLE_INTEGRAL_PRECISION_LIMIT));
obj->initReservedSlot(TIME_WARP_SLOT, DoubleValue(timeWarpTarget));
}
return true; return true;
} }

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

@ -50,8 +50,9 @@ class ErrorObject : public NativeObject
static const uint32_t LINENUMBER_SLOT = FILENAME_SLOT + 1; static const uint32_t LINENUMBER_SLOT = FILENAME_SLOT + 1;
static const uint32_t COLUMNNUMBER_SLOT = LINENUMBER_SLOT + 1; static const uint32_t COLUMNNUMBER_SLOT = LINENUMBER_SLOT + 1;
static const uint32_t MESSAGE_SLOT = COLUMNNUMBER_SLOT + 1; static const uint32_t MESSAGE_SLOT = COLUMNNUMBER_SLOT + 1;
static const uint32_t TIME_WARP_SLOT = MESSAGE_SLOT + 1;
static const uint32_t RESERVED_SLOTS = MESSAGE_SLOT + 1; static const uint32_t RESERVED_SLOTS = TIME_WARP_SLOT + 1;
public: public:
static const Class classes[JSEXN_ERROR_LIMIT]; static const Class classes[JSEXN_ERROR_LIMIT];
@ -99,6 +100,7 @@ class ErrorObject : public NativeObject
inline uint32_t lineNumber() const; inline uint32_t lineNumber() const;
inline uint32_t columnNumber() const; inline uint32_t columnNumber() const;
inline JSObject * stack() const; inline JSObject * stack() const;
inline uint64_t timeWarpTarget() const;
JSString * getMessage() const { JSString * getMessage() const {
const HeapSlot& slot = getReservedSlotRef(MESSAGE_SLOT); const HeapSlot& slot = getReservedSlotRef(MESSAGE_SLOT);