[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:
Leszek Swirski 2021-11-16 13:01:16 +01:00 committed by V8 LUCI CQ
parent 3eae9d57ef
commit 9b5f398554
2 changed files with 21 additions and 5 deletions

View File

@ -33,6 +33,21 @@ namespace internal {
template <ArgumentsType arguments_type> template <ArgumentsType arguments_type>
class Arguments { class Arguments {
public: 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) Arguments(int length, Address* arguments)
: length_(length), arguments_(arguments) { : length_(length), arguments_(arguments) {
DCHECK_GE(length_, 0); DCHECK_GE(length_, 0);
@ -51,10 +66,6 @@ class Arguments {
inline double number_at(int index) const; 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 { inline FullObjectSlot slot_at(int index) const {
return FullObjectSlot(address_of_arg_at(index)); return FullObjectSlot(address_of_arg_at(index));
} }

View File

@ -629,7 +629,12 @@ MaybeHandle<Object> DefineClass(Isolate* isolate,
Handle<JSObject> prototype = CreateClassPrototype(isolate); Handle<JSObject> prototype = CreateClassPrototype(isolate);
DCHECK_EQ(*constructor, args[ClassBoilerplate::kConstructorArgumentIndex]); 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, if (!InitClassConstructor(isolate, class_boilerplate, constructor_parent,
constructor, args) || constructor, args) ||