mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-27 14:52:16 +00:00
Bug 1885774: Make loadWrapperTarget fallible r=jandem
Differential Revision: https://phabricator.services.mozilla.com/D205654
This commit is contained in:
parent
d274938a4e
commit
c37e2efc87
25
js/src/jit-test/tests/proxy/bug1885774.js
Normal file
25
js/src/jit-test/tests/proxy/bug1885774.js
Normal file
@ -0,0 +1,25 @@
|
||||
// |jit-test| --no-threads; --fast-warmup
|
||||
|
||||
var {proxy, revoke} = Proxy.revocable({x:1}, {});
|
||||
|
||||
function foo(o) {
|
||||
var res = 0;
|
||||
for (var i = 0; i < 2; i++) {
|
||||
res += o.x;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
with ({}) {}
|
||||
for (var i = 0; i < 100; i++) {
|
||||
assertEq(foo(proxy), 2);
|
||||
}
|
||||
|
||||
revoke();
|
||||
var caught = false;
|
||||
try {
|
||||
foo(proxy);
|
||||
} catch {
|
||||
caught = true;
|
||||
}
|
||||
assertEq(caught, true);
|
@ -1199,7 +1199,8 @@ static ObjOperandId GuardAndLoadWindowProxyWindow(CacheIRWriter& writer,
|
||||
ObjOperandId objId,
|
||||
GlobalObject* windowObj) {
|
||||
writer.guardClass(objId, GuardClassKind::WindowProxy);
|
||||
ObjOperandId windowObjId = writer.loadWrapperTarget(objId);
|
||||
ObjOperandId windowObjId = writer.loadWrapperTarget(objId,
|
||||
/*fallible = */ false);
|
||||
writer.guardSpecificObject(windowObjId, windowObj);
|
||||
return windowObjId;
|
||||
}
|
||||
@ -1357,7 +1358,8 @@ AttachDecision GetPropIRGenerator::tryAttachCrossCompartmentWrapper(
|
||||
writer.guardHasProxyHandler(objId, Wrapper::wrapperHandler(obj));
|
||||
|
||||
// Load the object wrapped by the CCW
|
||||
ObjOperandId wrapperTargetId = writer.loadWrapperTarget(objId);
|
||||
ObjOperandId wrapperTargetId =
|
||||
writer.loadWrapperTarget(objId, /*fallible = */ false);
|
||||
|
||||
// If the compartment of the wrapped object is different we should fail.
|
||||
writer.guardCompartment(wrapperTargetId, wrappedTargetGlobal,
|
||||
@ -1468,7 +1470,8 @@ AttachDecision GetPropIRGenerator::tryAttachXrayCrossCompartmentWrapper(
|
||||
writer.guardHasProxyHandler(objId, GetProxyHandler(obj));
|
||||
|
||||
// Load the object wrapped by the CCW
|
||||
ObjOperandId wrapperTargetId = writer.loadWrapperTarget(objId);
|
||||
ObjOperandId wrapperTargetId =
|
||||
writer.loadWrapperTarget(objId, /*fallible = */ false);
|
||||
|
||||
// Test the wrapped object's class. The properties held by xrays or their
|
||||
// prototypes will be invariant for objects of a given class, except for
|
||||
@ -1580,7 +1583,8 @@ AttachDecision GetPropIRGenerator::tryAttachScriptedProxy(
|
||||
writer.guardHasProxyHandler(objId, &ScriptedProxyHandler::singleton);
|
||||
ValOperandId handlerValId = writer.loadScriptedProxyHandler(objId);
|
||||
ObjOperandId handlerObjId = writer.guardToObject(handlerValId);
|
||||
ObjOperandId targetObjId = writer.loadWrapperTarget(objId);
|
||||
ObjOperandId targetObjId =
|
||||
writer.loadWrapperTarget(objId, /*fallible =*/true);
|
||||
|
||||
writer.guardIsNativeObject(targetObjId);
|
||||
|
||||
|
@ -2934,14 +2934,27 @@ bool CacheIRCompiler::emitLoadEnclosingEnvironment(ObjOperandId objId,
|
||||
}
|
||||
|
||||
bool CacheIRCompiler::emitLoadWrapperTarget(ObjOperandId objId,
|
||||
ObjOperandId resultId) {
|
||||
ObjOperandId resultId,
|
||||
bool fallible) {
|
||||
JitSpew(JitSpew_Codegen, "%s", __FUNCTION__);
|
||||
Register obj = allocator.useRegister(masm, objId);
|
||||
Register reg = allocator.defineRegister(masm, resultId);
|
||||
|
||||
FailurePath* failure;
|
||||
if (fallible && !addFailurePath(&failure)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
masm.loadPtr(Address(obj, ProxyObject::offsetOfReservedSlots()), reg);
|
||||
masm.unboxObject(
|
||||
Address(reg, js::detail::ProxyReservedSlots::offsetOfPrivateSlot()), reg);
|
||||
|
||||
Address targetAddr(reg,
|
||||
js::detail::ProxyReservedSlots::offsetOfPrivateSlot());
|
||||
if (fallible) {
|
||||
masm.fallibleUnboxObject(targetAddr, reg, failure->label());
|
||||
} else {
|
||||
masm.unboxObject(targetAddr, reg);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -837,6 +837,7 @@
|
||||
args:
|
||||
obj: ObjId
|
||||
result: ObjId
|
||||
fallible: BoolImm
|
||||
|
||||
- name: LoadValueTag
|
||||
shared: true
|
||||
|
@ -19881,9 +19881,17 @@ void CodeGenerator::visitLoadWrapperTarget(LLoadWrapperTarget* lir) {
|
||||
Register output = ToRegister(lir->output());
|
||||
|
||||
masm.loadPtr(Address(object, ProxyObject::offsetOfReservedSlots()), output);
|
||||
masm.unboxObject(
|
||||
Address(output, js::detail::ProxyReservedSlots::offsetOfPrivateSlot()),
|
||||
output);
|
||||
|
||||
// Bail for revoked proxies.
|
||||
Label bail;
|
||||
Address targetAddr(output,
|
||||
js::detail::ProxyReservedSlots::offsetOfPrivateSlot());
|
||||
if (lir->mir()->fallible()) {
|
||||
masm.fallibleUnboxObject(targetAddr, output, &bail);
|
||||
bailoutFrom(&bail, lir->snapshot());
|
||||
} else {
|
||||
masm.unboxObject(targetAddr, output);
|
||||
}
|
||||
}
|
||||
|
||||
void CodeGenerator::visitGuardHasGetterSetter(LGuardHasGetterSetter* lir) {
|
||||
|
@ -3694,6 +3694,7 @@
|
||||
result_type: WordSized
|
||||
operands:
|
||||
object: WordSized
|
||||
mir_op: true
|
||||
|
||||
- name: GuardHasGetterSetter
|
||||
operands:
|
||||
|
@ -6752,7 +6752,11 @@ void LIRGenerator::visitLoadWrapperTarget(MLoadWrapperTarget* ins) {
|
||||
MDefinition* object = ins->object();
|
||||
MOZ_ASSERT(object->type() == MIRType::Object);
|
||||
|
||||
define(new (alloc()) LLoadWrapperTarget(useRegisterAtStart(object)), ins);
|
||||
auto* lir = new (alloc()) LLoadWrapperTarget(useRegisterAtStart(object));
|
||||
if (ins->fallible()) {
|
||||
assignSnapshot(lir, ins->bailoutKind());
|
||||
}
|
||||
define(lir, ins);
|
||||
}
|
||||
|
||||
void LIRGenerator::visitGuardHasGetterSetter(MGuardHasGetterSetter* ins) {
|
||||
|
@ -7242,6 +7242,16 @@ AliasSet MLoadWrapperTarget::getAliasSet() const {
|
||||
return AliasSet::Load(AliasSet::Any);
|
||||
}
|
||||
|
||||
bool MLoadWrapperTarget::congruentTo(const MDefinition* ins) const {
|
||||
if (!ins->isLoadWrapperTarget()) {
|
||||
return false;
|
||||
}
|
||||
if (ins->toLoadWrapperTarget()->fallible() != fallible()) {
|
||||
return false;
|
||||
}
|
||||
return congruentIfOperandsEqual(ins);
|
||||
}
|
||||
|
||||
AliasSet MGuardHasGetterSetter::getAliasSet() const {
|
||||
return AliasSet::Load(AliasSet::ObjectFields);
|
||||
}
|
||||
|
@ -2810,13 +2810,16 @@
|
||||
alias_set: none
|
||||
|
||||
# Load the target object from a proxy wrapper. The target is stored in the
|
||||
# proxy object's private slot.
|
||||
# proxy object's private slot. This operation is fallible if the proxy can
|
||||
# be revoked.
|
||||
- name: LoadWrapperTarget
|
||||
operands:
|
||||
object: Object
|
||||
arguments:
|
||||
fallible: bool
|
||||
result_type: Object
|
||||
movable: true
|
||||
congruent_to: if_operands_equal
|
||||
congruent_to: custom
|
||||
# Can't use |AliasSet::None| because the target changes on navigation.
|
||||
# TODO: Investigate using a narrower or a custom alias set.
|
||||
alias_set: custom
|
||||
|
@ -5216,10 +5216,14 @@ bool WarpCacheIRTranspiler::emitLoadOperandResult(ValOperandId inputId) {
|
||||
}
|
||||
|
||||
bool WarpCacheIRTranspiler::emitLoadWrapperTarget(ObjOperandId objId,
|
||||
ObjOperandId resultId) {
|
||||
ObjOperandId resultId,
|
||||
bool fallible) {
|
||||
MDefinition* obj = getOperand(objId);
|
||||
|
||||
auto* ins = MLoadWrapperTarget::New(alloc(), obj);
|
||||
auto* ins = MLoadWrapperTarget::New(alloc(), obj, fallible);
|
||||
if (fallible) {
|
||||
ins->setGuard();
|
||||
}
|
||||
add(ins);
|
||||
|
||||
return defineOperand(resultId, ins);
|
||||
|
@ -1373,9 +1373,13 @@ ICInterpretOps(BaselineFrame* frame, VMFrameManager& frameMgr, State& state,
|
||||
CACHEOP_CASE(LoadWrapperTarget) {
|
||||
ObjOperandId objId = icregs.cacheIRReader.objOperandId();
|
||||
ObjOperandId resultId = icregs.cacheIRReader.objOperandId();
|
||||
bool fallible = icregs.cacheIRReader.readBool();
|
||||
BOUNDSCHECK(resultId);
|
||||
JSObject* obj = reinterpret_cast<JSObject*>(icregs.icVals[objId.id()]);
|
||||
JSObject* target = &obj->as<ProxyObject>().private_().toObject();
|
||||
JSObject* target = obj->as<ProxyObject>().private_().toObjectOrNull();
|
||||
if (fallible && !target) {
|
||||
return ICInterpretOpResult::NextIC;
|
||||
}
|
||||
icregs.icVals[resultId.id()] = reinterpret_cast<uintptr_t>(target);
|
||||
DISPATCH_CACHEOP();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user