[web snapshot] Support oddballs

This CL adds support for oddballs false, true, null and undefined.

Bug: v8:11525, v8:11706
Change-Id: I0dc870f05578c0eb9ff06bf2ccd2474e18464566
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2856843
Commit-Queue: Vicky Kontoura <vkont@google.com>
Reviewed-by: Marja Hölttä <marja@chromium.org>
Reviewed-by: Camillo Bruni <cbruni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#74304}
This commit is contained in:
Vicky Kontoura 2021-04-30 13:34:43 +00:00 committed by V8 LUCI CQ
parent a5c321024c
commit f488ad78cb
3 changed files with 70 additions and 2 deletions

View File

@ -398,8 +398,22 @@ void WebSnapshotSerializer::WriteValue(Handle<Object> object,
DCHECK(object->IsHeapObject());
switch (HeapObject::cast(*object).map().instance_type()) {
case ODDBALL_TYPE:
// TODO(v8:11525): Implement.
UNREACHABLE();
switch (Oddball::cast(*object).kind()) {
case Oddball::kFalse:
serializer.WriteUint32(ValueType::FALSE_CONSTANT);
return;
case Oddball::kTrue:
serializer.WriteUint32(ValueType::TRUE_CONSTANT);
return;
case Oddball::kNull:
serializer.WriteUint32(ValueType::NULL_CONSTANT);
return;
case Oddball::kUndefined:
serializer.WriteUint32(ValueType::UNDEFINED_CONSTANT);
return;
default:
UNREACHABLE();
}
case HEAP_NUMBER_TYPE:
// TODO(v8:11525): Handle possible endianness mismatch.
serializer.WriteUint32(ValueType::DOUBLE);
@ -846,6 +860,26 @@ void WebSnapshotDeserializer::ReadValue(Handle<Object>& value,
return;
}
switch (value_type) {
case ValueType::FALSE_CONSTANT: {
value = handle(ReadOnlyRoots(isolate_).false_value(), isolate_);
representation = Representation::Tagged();
break;
}
case ValueType::TRUE_CONSTANT: {
value = handle(ReadOnlyRoots(isolate_).true_value(), isolate_);
representation = Representation::Tagged();
break;
}
case ValueType::NULL_CONSTANT: {
value = handle(ReadOnlyRoots(isolate_).null_value(), isolate_);
representation = Representation::Tagged();
break;
}
case ValueType::UNDEFINED_CONSTANT: {
value = handle(ReadOnlyRoots(isolate_).undefined_value(), isolate_);
representation = Representation::Tagged();
break;
}
case ValueType::INTEGER: {
Maybe<int32_t> number = deserializer_->ReadZigZag<int32_t>();
if (number.IsNothing()) {

View File

@ -39,6 +39,10 @@ class WebSnapshotSerializerDeserializer {
const char* error_message() const { return error_message_; }
enum ValueType : uint8_t {
FALSE_CONSTANT,
TRUE_CONSTANT,
NULL_CONSTANT,
UNDEFINED_CONSTANT,
INTEGER,
DOUBLE,
STRING_ID,

View File

@ -140,6 +140,36 @@ TEST(Numbers) {
kObjectCount);
}
TEST(Oddballs) {
const char* snapshot_source =
"var foo = {'a': false,\n"
" 'b': true,\n"
" 'c': null,\n"
" 'd': undefined,\n"
"}";
const char* test_source = "foo";
uint32_t kStringCount = 5; // 'foo', 'a', ..., 'd'
uint32_t kMapCount = 1;
uint32_t kContextCount = 0;
uint32_t kFunctionCount = 0;
uint32_t kObjectCount = 1;
std::function<void(v8::Isolate*, v8::Local<v8::Context>)> tester =
[test_source](v8::Isolate* isolate, v8::Local<v8::Context> new_context) {
v8::Local<v8::Object> result = CompileRun(test_source).As<v8::Object>();
Local<Value> a = result->Get(new_context, v8_str("a")).ToLocalChecked();
CHECK(a->IsFalse());
Local<Value> b = result->Get(new_context, v8_str("b")).ToLocalChecked();
CHECK(b->IsTrue());
Local<Value> c = result->Get(new_context, v8_str("c")).ToLocalChecked();
CHECK(c->IsNull());
Local<Value> d = result->Get(new_context, v8_str("d")).ToLocalChecked();
CHECK(d->IsUndefined());
};
TestWebSnapshotExtensive(snapshot_source, test_source, tester, kStringCount,
kMapCount, kContextCount, kFunctionCount,
kObjectCount);
}
TEST(Function) {
const char* snapshot_source =
"var foo = {'key': function() { return '11525'; }};";