[runtime] Reset clobbered argument in DefineClass
The caller of DefineClass may not expect its arguments to be mutated, so add an arguments mutation scope which resets the argument clobbered by DefineClass. Bug: chromium:1268738 Change-Id: I03e9cd82535ca1f83353012a92e80f822566e64e Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3283077 Auto-Submit: Leszek Swirski <leszeks@chromium.org> Commit-Queue: Igor Sheludko <ishell@chromium.org> Reviewed-by: Igor Sheludko <ishell@chromium.org> Cr-Commit-Position: refs/heads/main@{#77921}
This commit is contained in:
parent
3eae9d57ef
commit
9b5f398554
@ -33,6 +33,21 @@ namespace internal {
|
||||
template <ArgumentsType arguments_type>
|
||||
class Arguments {
|
||||
public:
|
||||
// Scope to temporarily change the value of an argument.
|
||||
class ChangeValueScope {
|
||||
public:
|
||||
ChangeValueScope(Arguments* args, int index, Object value)
|
||||
: location_(args->address_of_arg_at(index)) {
|
||||
old_value_ = *location_;
|
||||
*location_ = value.ptr();
|
||||
}
|
||||
~ChangeValueScope() { *location_ = old_value_; }
|
||||
|
||||
private:
|
||||
Address* location_;
|
||||
Address old_value_;
|
||||
};
|
||||
|
||||
Arguments(int length, Address* arguments)
|
||||
: length_(length), arguments_(arguments) {
|
||||
DCHECK_GE(length_, 0);
|
||||
@ -51,10 +66,6 @@ class Arguments {
|
||||
|
||||
inline double number_at(int index) const;
|
||||
|
||||
inline void set_at(int index, Object value) {
|
||||
*address_of_arg_at(index) = value.ptr();
|
||||
}
|
||||
|
||||
inline FullObjectSlot slot_at(int index) const {
|
||||
return FullObjectSlot(address_of_arg_at(index));
|
||||
}
|
||||
|
@ -629,7 +629,12 @@ MaybeHandle<Object> DefineClass(Isolate* isolate,
|
||||
|
||||
Handle<JSObject> prototype = CreateClassPrototype(isolate);
|
||||
DCHECK_EQ(*constructor, args[ClassBoilerplate::kConstructorArgumentIndex]);
|
||||
args.set_at(ClassBoilerplate::kPrototypeArgumentIndex, *prototype);
|
||||
// Temporarily change ClassBoilerplate::kPrototypeArgumentIndex for the
|
||||
// subsequent calls, but use a scope to make sure to change it back before
|
||||
// returning, to not corrupt the caller's argument frame (in particular, for
|
||||
// the interpreter, to not clobber the register frame).
|
||||
RuntimeArguments::ChangeValueScope set_prototype_value_scope(
|
||||
&args, ClassBoilerplate::kPrototypeArgumentIndex, *prototype);
|
||||
|
||||
if (!InitClassConstructor(isolate, class_boilerplate, constructor_parent,
|
||||
constructor, args) ||
|
||||
|
Loading…
Reference in New Issue
Block a user