Commit 38c90161 authored by Michael Lippautz's avatar Michael Lippautz Committed by Commit Bot

GCExtension: Properly support exceptions

Fix corner case where we would try to read a property when having a
pending or scheduled exception.

Re-add tests.

Bug: chromium:1006640
Change-Id: I2fc84ee0f6145db2d200a8b9abf57fdc4b12a5a3
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1835531Reviewed-by: 's avatarUlan Degenbaev <ulan@chromium.org>
Commit-Queue: Michael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#64083}
parent 483a5e94
......@@ -22,34 +22,40 @@ struct GCOptions {
ExecutionType execution;
};
bool IsProperty(v8::Isolate* isolate, v8::Local<v8::Context> ctx,
v8::Local<v8::Object> object, const char* key,
const char* value) {
Maybe<bool> IsProperty(v8::Isolate* isolate, v8::Local<v8::Context> ctx,
v8::Local<v8::Object> object, const char* key,
const char* value) {
auto k = v8::String::NewFromUtf8(isolate, key).ToLocalChecked();
// Get will return undefined for non-existing keys which will make
// StrictEquals fail.
auto maybe_property = object->Get(ctx, k);
if (maybe_property.IsEmpty()) return false;
return maybe_property.ToLocalChecked()->StrictEquals(
v8::String::NewFromUtf8(isolate, value).ToLocalChecked());
if (maybe_property.IsEmpty()) return Nothing<bool>();
return Just<bool>(maybe_property.ToLocalChecked()->StrictEquals(
v8::String::NewFromUtf8(isolate, value).ToLocalChecked()));
}
GCOptions Parse(v8::Isolate* isolate, v8::Local<v8::Context> ctx,
const v8::FunctionCallbackInfo<v8::Value>& args) {
Maybe<GCOptions> Parse(v8::Isolate* isolate, v8::Local<v8::Context> ctx,
const v8::FunctionCallbackInfo<v8::Value>& args) {
// Default values.
auto options =
GCOptions{v8::Isolate::GarbageCollectionType::kFullGarbageCollection,
ExecutionType::kSync};
bool found_options_object = false;
if (args[0]->IsObject() && !args[0]->IsProxy()) {
if (args[0]->IsObject()) {
auto param = v8::Local<v8::Object>::Cast(args[0]);
if (IsProperty(isolate, ctx, param, "type", "minor")) {
auto maybe_type = IsProperty(isolate, ctx, param, "type", "minor");
if (maybe_type.IsNothing()) return Nothing<GCOptions>();
if (maybe_type.ToChecked()) {
found_options_object = true;
options.type =
v8::Isolate::GarbageCollectionType::kMinorGarbageCollection;
}
if (IsProperty(isolate, ctx, param, "execution", "async")) {
auto maybe_execution =
IsProperty(isolate, ctx, param, "execution", "async");
if (maybe_execution.IsNothing()) return Nothing<GCOptions>();
if (maybe_execution.ToChecked()) {
found_options_object = true;
options.execution = ExecutionType::kAsync;
}
......@@ -63,7 +69,7 @@ GCOptions Parse(v8::Isolate* isolate, v8::Local<v8::Context> ctx,
: v8::Isolate::GarbageCollectionType::kFullGarbageCollection;
}
return options;
return Just<GCOptions>(options);
}
void InvokeGC(v8::Isolate* isolate, v8::Isolate::GarbageCollectionType type,
......@@ -126,7 +132,9 @@ void GCExtension::GC(const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::HandleScope scope(isolate);
auto ctx = isolate->GetCurrentContext();
auto options = Parse(isolate, ctx, args);
auto maybe_options = Parse(isolate, ctx, args);
if (maybe_options.IsNothing()) return;
GCOptions options = maybe_options.ToChecked();
switch (options.execution) {
case ExecutionType::kSync:
InvokeGC(isolate, options.type,
......
// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax --expose-gc
var PI = new Proxy(this, {
get() {
PI();
}
});
assertThrows(() => new gc(PI, {}), TypeError);
// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --expose-gc
function main() {
const v2 = [1337,1337,1337,1337,1337];
function v9() {
const v15 = {get:RegExp};
Object.defineProperty(v2,501,v15);
const v18 = RegExp();
const v19 = 1337 instanceof v18;
}
const v30 = {defineProperty:Function,get:v9,getPrototypeOf:Object};
const v32 = new Proxy(ArrayBuffer,v30);
const v34 = gc(v32);
}
assertThrows(() => main(), TypeError);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment