Bug 1329321 - Add a soft-fail mechanism for JS ObjectOpResult. r=jorendorff

--HG--
extra : rebase_source : 168a0a678d62879dce0075ecedb8fb0703ceb8c1
This commit is contained in:
Tom Schuster 2018-05-16 22:11:25 +02:00
parent f7c7d0f881
commit 9aeac2c930
3 changed files with 31 additions and 7 deletions

View File

@ -132,16 +132,24 @@ class ObjectOpResult
Uninitialized = uintptr_t(-1)
};
static const uintptr_t SoftFailBit = uintptr_t(1) << (sizeof(uintptr_t) * 8 - 1);
ObjectOpResult() : code_(Uninitialized) {}
/* Return true if succeed() was called. */
/* Return true if succeed() or failSoft() was called. */
bool ok() const {
MOZ_ASSERT(code_ != Uninitialized);
return code_ == OkCode;
return code_ == OkCode || (code_ & SoftFailBit);
}
explicit operator bool() const { return ok(); }
/* Return true if succeed() was called. */
bool reallyOk() const {
MOZ_ASSERT(code_ != Uninitialized);
return code_ == OkCode;
}
/* Set this ObjectOpResult to true and return true. */
bool succeed() {
code_ = OkCode;
@ -161,10 +169,26 @@ class ObjectOpResult
*/
bool fail(uint32_t msg) {
MOZ_ASSERT(msg != OkCode);
MOZ_ASSERT((msg & SoftFailBit) == 0);
code_ = msg;
return true;
}
/*
* DEPRECATED: This is a non-standard compatibility hack.
*
* Set this ObjectOpResult to true, but remembers an error code.
* This is used for situations where we really want to fail,
* but can't for legacy reasons.
*
* Always returns true, as a convenience.
*/
bool failSoft(uint32_t msg) {
// The msg code is currently never extracted again.
code_ = msg | SoftFailBit;
return true;
}
JS_PUBLIC_API(bool) failCantRedefineProp();
JS_PUBLIC_API(bool) failReadOnly();
JS_PUBLIC_API(bool) failGetterOnly();

View File

@ -42,7 +42,7 @@ Reflect_deleteProperty(JSContext* cx, unsigned argc, Value* vp)
ObjectOpResult result;
if (!DeleteProperty(cx, target, key, result))
return false;
args.rval().setBoolean(bool(result));
args.rval().setBoolean(result.reallyOk());
return true;
}
@ -118,7 +118,7 @@ Reflect_preventExtensions(JSContext* cx, unsigned argc, Value* vp)
ObjectOpResult result;
if (!PreventExtensions(cx, target, result))
return false;
args.rval().setBoolean(bool(result));
args.rval().setBoolean(result.reallyOk());
return true;
}
@ -147,7 +147,7 @@ Reflect_set(JSContext* cx, unsigned argc, Value* vp)
RootedValue value(cx, args.get(2));
if (!SetProperty(cx, target, key, value, receiver, result))
return false;
args.rval().setBoolean(bool(result));
args.rval().setBoolean(result.reallyOk());
return true;
}
@ -180,7 +180,7 @@ Reflect_setPrototypeOf(JSContext* cx, unsigned argc, Value* vp)
ObjectOpResult result;
if (!SetPrototype(cx, obj, proto, result))
return false;
args.rval().setBoolean(bool(result));
args.rval().setBoolean(result.reallyOk());
return true;
}

View File

@ -650,7 +650,7 @@ intrinsic_DefineProperty(JSContext* cx, unsigned argc, Value* vp)
if (strict && !result.checkStrict(cx, obj, id))
return false;
args.rval().setBoolean(bool(result));
args.rval().setBoolean(result.reallyOk());
return true;
}