Bug 912337 - Make a new Error subclass: Debugger.DebuggeeWouldRun. (r=jimb)

This commit is contained in:
Shu-yu Guo 2016-02-19 13:46:07 -08:00
parent 7cc6c50643
commit b02fc05d4b
7 changed files with 63 additions and 34 deletions

View File

@ -430,6 +430,7 @@ MSG_DEF(JSMSG_DEBUG_OPTIMIZED_OUT, 1, JSEXN_ERR, "variable `{0}' has been op
MSG_DEF(JSMSG_DEBUG_RESUMPTION_VALUE_DISALLOWED, 0, JSEXN_TYPEERR, "resumption values are disallowed in this hook") MSG_DEF(JSMSG_DEBUG_RESUMPTION_VALUE_DISALLOWED, 0, JSEXN_TYPEERR, "resumption values are disallowed in this hook")
MSG_DEF(JSMSG_DEBUG_VARIABLE_NOT_FOUND,0, JSEXN_TYPEERR, "variable not found in environment") MSG_DEF(JSMSG_DEBUG_VARIABLE_NOT_FOUND,0, JSEXN_TYPEERR, "variable not found in environment")
MSG_DEF(JSMSG_DEBUG_WRAPPER_IN_WAY, 3, JSEXN_TYPEERR, "{0} is {1}{2}a global object, but a direct reference is required") MSG_DEF(JSMSG_DEBUG_WRAPPER_IN_WAY, 3, JSEXN_TYPEERR, "{0} is {1}{2}a global object, but a direct reference is required")
MSG_DEF(JSMSG_DEBUGGEE_WOULD_RUN, 0, JSEXN_DEBUGGEEWOULDRUN, "debuggee would run")
MSG_DEF(JSMSG_NOT_CALLABLE_OR_UNDEFINED, 0, JSEXN_TYPEERR, "value is not a function or undefined") MSG_DEF(JSMSG_NOT_CALLABLE_OR_UNDEFINED, 0, JSEXN_TYPEERR, "value is not a function or undefined")
MSG_DEF(JSMSG_NOT_TRACKING_ALLOCATIONS, 1, JSEXN_ERR, "Cannot call {0} without setting trackingAllocationSites to true") MSG_DEF(JSMSG_NOT_TRACKING_ALLOCATIONS, 1, JSEXN_ERR, "Cannot call {0} without setting trackingAllocationSites to true")
MSG_DEF(JSMSG_NOT_TRACKING_TENURINGS, 1, JSEXN_ERR, "Cannot call {0} without setting trackingTenurePromotions to true") MSG_DEF(JSMSG_NOT_TRACKING_TENURINGS, 1, JSEXN_ERR, "Cannot call {0} without setting trackingTenurePromotions to true")

View File

@ -627,6 +627,7 @@ typedef enum JSExnType {
JSEXN_SYNTAXERR, JSEXN_SYNTAXERR,
JSEXN_TYPEERR, JSEXN_TYPEERR,
JSEXN_URIERR, JSEXN_URIERR,
JSEXN_DEBUGGEEWOULDRUN,
JSEXN_LIMIT JSEXN_LIMIT
} JSExnType; } JSExnType;

View File

@ -65,7 +65,7 @@ static const JSFunctionSpec exception_methods[] = {
JS_FS_END JS_FS_END
}; };
#define IMPLEMENT_ERROR_SUBCLASS(name) \ #define IMPLEMENT_ERROR_SUBCLASS_EXTRA_FLAGS(name, extraClassSpecFlags) \
{ \ { \
js_Error_str, /* yes, really */ \ js_Error_str, /* yes, really */ \
JSCLASS_HAS_CACHED_PROTO(JSProto_##name) | \ JSCLASS_HAS_CACHED_PROTO(JSProto_##name) | \
@ -90,10 +90,13 @@ static const JSFunctionSpec exception_methods[] = {
exception_methods, \ exception_methods, \
exception_properties, \ exception_properties, \
nullptr, \ nullptr, \
JSProto_Error \ JSProto_Error | extraClassSpecFlags \
} \ } \
} }
#define IMPLEMENT_ERROR_SUBCLASS(name) \
IMPLEMENT_ERROR_SUBCLASS_EXTRA_FLAGS(name, 0)
const Class const Class
ErrorObject::classes[JSEXN_LIMIT] = { ErrorObject::classes[JSEXN_LIMIT] = {
{ {
@ -128,7 +131,11 @@ ErrorObject::classes[JSEXN_LIMIT] = {
IMPLEMENT_ERROR_SUBCLASS(ReferenceError), IMPLEMENT_ERROR_SUBCLASS(ReferenceError),
IMPLEMENT_ERROR_SUBCLASS(SyntaxError), IMPLEMENT_ERROR_SUBCLASS(SyntaxError),
IMPLEMENT_ERROR_SUBCLASS(TypeError), IMPLEMENT_ERROR_SUBCLASS(TypeError),
IMPLEMENT_ERROR_SUBCLASS(URIError) IMPLEMENT_ERROR_SUBCLASS(URIError),
// DebuggeeWouldRun is a subclass of Error but is accessible via the
// Debugger constructor, not the global.
IMPLEMENT_ERROR_SUBCLASS_EXTRA_FLAGS(DebuggeeWouldRun, ClassSpec::DontDefineConstructor),
}; };
JSErrorReport* JSErrorReport*

View File

@ -94,7 +94,8 @@ static_assert(JSEXN_ERR == 0 &&
JSProto_Error + JSEXN_SYNTAXERR == JSProto_SyntaxError && JSProto_Error + JSEXN_SYNTAXERR == JSProto_SyntaxError &&
JSProto_Error + JSEXN_TYPEERR == JSProto_TypeError && JSProto_Error + JSEXN_TYPEERR == JSProto_TypeError &&
JSProto_Error + JSEXN_URIERR == JSProto_URIError && JSProto_Error + JSEXN_URIERR == JSProto_URIError &&
JSEXN_URIERR + 1 == JSEXN_LIMIT, JSProto_Error + JSEXN_DEBUGGEEWOULDRUN == JSProto_DebuggeeWouldRun &&
JSEXN_DEBUGGEEWOULDRUN + 1 == JSEXN_LIMIT,
"GetExceptionProtoKey and ExnTypeFromProtoKey require that " "GetExceptionProtoKey and ExnTypeFromProtoKey require that "
"each corresponding JSExnType and JSProtoKey value be separated " "each corresponding JSExnType and JSProtoKey value be separated "
"by the same constant value"); "by the same constant value");

View File

@ -81,33 +81,34 @@
real(SyntaxError, 16, InitViaClassSpec, ERROR_CLASP(JSEXN_SYNTAXERR)) \ real(SyntaxError, 16, InitViaClassSpec, ERROR_CLASP(JSEXN_SYNTAXERR)) \
real(TypeError, 17, InitViaClassSpec, ERROR_CLASP(JSEXN_TYPEERR)) \ real(TypeError, 17, InitViaClassSpec, ERROR_CLASP(JSEXN_TYPEERR)) \
real(URIError, 18, InitViaClassSpec, ERROR_CLASP(JSEXN_URIERR)) \ real(URIError, 18, InitViaClassSpec, ERROR_CLASP(JSEXN_URIERR)) \
real(Iterator, 19, InitLegacyIteratorClass,OCLASP(PropertyIterator)) \ real(DebuggeeWouldRun, 19, InitViaClassSpec, ERROR_CLASP(JSEXN_DEBUGGEEWOULDRUN)) \
real(StopIteration, 20, InitStopIterationClass, OCLASP(StopIteration)) \ real(Iterator, 20, InitLegacyIteratorClass,OCLASP(PropertyIterator)) \
real(ArrayBuffer, 21, InitArrayBufferClass, &js::ArrayBufferObject::protoClass) \ real(StopIteration, 21, InitStopIterationClass, OCLASP(StopIteration)) \
real(Int8Array, 22, InitViaClassSpec, TYPED_ARRAY_CLASP(Int8)) \ real(ArrayBuffer, 22, InitArrayBufferClass, &js::ArrayBufferObject::protoClass) \
real(Uint8Array, 23, InitViaClassSpec, TYPED_ARRAY_CLASP(Uint8)) \ real(Int8Array, 23, InitViaClassSpec, TYPED_ARRAY_CLASP(Int8)) \
real(Int16Array, 24, InitViaClassSpec, TYPED_ARRAY_CLASP(Int16)) \ real(Uint8Array, 24, InitViaClassSpec, TYPED_ARRAY_CLASP(Uint8)) \
real(Uint16Array, 25, InitViaClassSpec, TYPED_ARRAY_CLASP(Uint16)) \ real(Int16Array, 25, InitViaClassSpec, TYPED_ARRAY_CLASP(Int16)) \
real(Int32Array, 26, InitViaClassSpec, TYPED_ARRAY_CLASP(Int32)) \ real(Uint16Array, 26, InitViaClassSpec, TYPED_ARRAY_CLASP(Uint16)) \
real(Uint32Array, 27, InitViaClassSpec, TYPED_ARRAY_CLASP(Uint32)) \ real(Int32Array, 27, InitViaClassSpec, TYPED_ARRAY_CLASP(Int32)) \
real(Float32Array, 28, InitViaClassSpec, TYPED_ARRAY_CLASP(Float32)) \ real(Uint32Array, 28, InitViaClassSpec, TYPED_ARRAY_CLASP(Uint32)) \
real(Float64Array, 29, InitViaClassSpec, TYPED_ARRAY_CLASP(Float64)) \ real(Float32Array, 29, InitViaClassSpec, TYPED_ARRAY_CLASP(Float32)) \
real(Uint8ClampedArray, 30, InitViaClassSpec, TYPED_ARRAY_CLASP(Uint8Clamped)) \ real(Float64Array, 30, InitViaClassSpec, TYPED_ARRAY_CLASP(Float64)) \
real(Proxy, 31, InitProxyClass, js::ProxyClassPtr) \ real(Uint8ClampedArray, 31, InitViaClassSpec, TYPED_ARRAY_CLASP(Uint8Clamped)) \
real(WeakMap, 32, InitWeakMapClass, OCLASP(WeakMap)) \ real(Proxy, 32, InitProxyClass, js::ProxyClassPtr) \
real(Map, 33, InitMapClass, OCLASP(Map)) \ real(WeakMap, 33, InitWeakMapClass, OCLASP(WeakMap)) \
real(Set, 34, InitSetClass, OCLASP(Set)) \ real(Map, 34, InitMapClass, OCLASP(Map)) \
real(DataView, 35, InitDataViewClass, OCLASP(DataView)) \ real(Set, 35, InitSetClass, OCLASP(Set)) \
real(Symbol, 36, InitSymbolClass, OCLASP(Symbol)) \ real(DataView, 36, InitDataViewClass, OCLASP(DataView)) \
IF_SAB(real,imaginary)(SharedArrayBuffer, 37, InitSharedArrayBufferClass, &js::SharedArrayBufferObject::protoClass) \ real(Symbol, 37, InitSymbolClass, OCLASP(Symbol)) \
IF_INTL(real,imaginary) (Intl, 38, InitIntlClass, CLASP(Intl)) \ IF_SAB(real,imaginary)(SharedArrayBuffer, 38, InitSharedArrayBufferClass, &js::SharedArrayBufferObject::protoClass) \
IF_BDATA(real,imaginary)(TypedObject, 39, InitTypedObjectModuleObject, OCLASP(TypedObjectModule)) \ IF_INTL(real,imaginary) (Intl, 39, InitIntlClass, CLASP(Intl)) \
real(Reflect, 40, InitReflect, nullptr) \ IF_BDATA(real,imaginary)(TypedObject, 40, InitTypedObjectModuleObject, OCLASP(TypedObjectModule)) \
IF_SIMD(real,imaginary)(SIMD, 41, InitSimdClass, OCLASP(Simd)) \ real(Reflect, 41, InitReflect, nullptr) \
real(WeakSet, 42, InitWeakSetClass, OCLASP(WeakSet)) \ IF_SIMD(real,imaginary)(SIMD, 42, InitSimdClass, OCLASP(Simd)) \
real(TypedArray, 43, InitViaClassSpec, &js::TypedArrayObject::sharedTypedArrayPrototypeClass) \ real(WeakSet, 43, InitWeakSetClass, OCLASP(WeakSet)) \
IF_SAB(real,imaginary)(Atomics, 44, InitAtomicsClass, OCLASP(Atomics)) \ real(TypedArray, 44, InitViaClassSpec, &js::TypedArrayObject::sharedTypedArrayPrototypeClass) \
real(SavedFrame, 45, InitViaClassSpec, &js::SavedFrame::class_) \ IF_SAB(real,imaginary)(Atomics, 45, InitAtomicsClass, OCLASP(Atomics)) \
real(SavedFrame, 46, InitViaClassSpec, &js::SavedFrame::class_) \
#define JS_FOR_EACH_PROTOTYPE(macro) JS_FOR_PROTOTYPES(macro,macro) #define JS_FOR_EACH_PROTOTYPE(macro) JS_FOR_PROTOTYPES(macro,macro)

View File

@ -8465,7 +8465,11 @@ JS_DefineDebuggerObject(JSContext* cx, HandleObject obj)
objectProto(cx), objectProto(cx),
envProto(cx), envProto(cx),
memoryProto(cx); memoryProto(cx);
objProto = obj->as<GlobalObject>().getOrCreateObjectPrototype(cx); RootedObject debuggeeWouldRunProto(cx);
RootedValue debuggeeWouldRunCtor(cx);
Rooted<GlobalObject*> global(cx, &obj->as<GlobalObject>());
objProto = global->getOrCreateObjectPrototype(cx);
if (!objProto) if (!objProto)
return false; return false;
debugProto = InitClass(cx, obj, debugProto = InitClass(cx, obj,
@ -8502,18 +8506,32 @@ JS_DefineDebuggerObject(JSContext* cx, HandleObject obj)
nullptr, nullptr); nullptr, nullptr);
if (!objectProto) if (!objectProto)
return false; return false;
envProto = InitClass(cx, debugCtor, objProto, &DebuggerEnv_class, envProto = InitClass(cx, debugCtor, objProto, &DebuggerEnv_class,
DebuggerEnv_construct, 0, DebuggerEnv_construct, 0,
DebuggerEnv_properties, DebuggerEnv_methods, DebuggerEnv_properties, DebuggerEnv_methods,
nullptr, nullptr); nullptr, nullptr);
if (!envProto) if (!envProto)
return false; return false;
memoryProto = InitClass(cx, debugCtor, objProto, &DebuggerMemory::class_, memoryProto = InitClass(cx, debugCtor, objProto, &DebuggerMemory::class_,
DebuggerMemory::construct, 0, DebuggerMemory::properties, DebuggerMemory::construct, 0, DebuggerMemory::properties,
DebuggerMemory::methods, nullptr, nullptr); DebuggerMemory::methods, nullptr, nullptr);
if (!memoryProto) if (!memoryProto)
return false; return false;
debuggeeWouldRunProto =
GlobalObject::getOrCreateCustomErrorPrototype(cx, global, JSEXN_DEBUGGEEWOULDRUN);
if (!debuggeeWouldRunProto)
return false;
debuggeeWouldRunCtor = global->getConstructor(JSProto_DebuggeeWouldRun);
RootedId debuggeeWouldRunId(cx, NameToId(ClassName(JSProto_DebuggeeWouldRun, cx)));
if (!DefineProperty(cx, debugCtor, debuggeeWouldRunId, debuggeeWouldRunCtor,
nullptr, nullptr, 0))
{
return false;
}
debugProto->setReservedSlot(Debugger::JSSLOT_DEBUG_FRAME_PROTO, ObjectValue(*frameProto)); debugProto->setReservedSlot(Debugger::JSSLOT_DEBUG_FRAME_PROTO, ObjectValue(*frameProto));
debugProto->setReservedSlot(Debugger::JSSLOT_DEBUG_OBJECT_PROTO, ObjectValue(*objectProto)); debugProto->setReservedSlot(Debugger::JSSLOT_DEBUG_OBJECT_PROTO, ObjectValue(*objectProto));
debugProto->setReservedSlot(Debugger::JSSLOT_DEBUG_SCRIPT_PROTO, ObjectValue(*scriptProto)); debugProto->setReservedSlot(Debugger::JSSLOT_DEBUG_SCRIPT_PROTO, ObjectValue(*scriptProto));

View File

@ -31,11 +31,11 @@ namespace js {
* *
* (If you're wondering, 0xb973c0de is used because it looks like "bytecode".) * (If you're wondering, 0xb973c0de is used because it looks like "bytecode".)
*/ */
static const uint32_t XDR_BYTECODE_VERSION_SUBTRAHEND = 346; static const uint32_t XDR_BYTECODE_VERSION_SUBTRAHEND = 347;
static const uint32_t XDR_BYTECODE_VERSION = static const uint32_t XDR_BYTECODE_VERSION =
uint32_t(0xb973c0de - XDR_BYTECODE_VERSION_SUBTRAHEND); uint32_t(0xb973c0de - XDR_BYTECODE_VERSION_SUBTRAHEND);
static_assert(JSErr_Limit == 445, static_assert(JSErr_Limit == 446,
"GREETINGS, POTENTIAL SUBTRAHEND INCREMENTER! If you added or " "GREETINGS, POTENTIAL SUBTRAHEND INCREMENTER! If you added or "
"removed MSG_DEFs from js.msg, you should increment " "removed MSG_DEFs from js.msg, you should increment "
"XDR_BYTECODE_VERSION_SUBTRAHEND and update this assertion's " "XDR_BYTECODE_VERSION_SUBTRAHEND and update this assertion's "