Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow serializing undefined in object literals #1314

Open
wants to merge 6 commits into
base: static_h
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion include/hermes/BCGen/HBC/BytecodeGenerator.h
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,7 @@ class BytecodeModuleGenerator {

/// Serializes the array of literals given into a compact char buffer.
/// The serialization format can be found in:
/// include/hermes/VM/SerializedLiteralParser.h
/// include/hermes/BCGen/SerializedLiteralGenerator.h
/// This function serializes the literals, and checks to see if the exact
/// byte pattern is already present in \buff. If it is, it simply returns
/// its offset in \buff. If it isn't, the function appends it and returns
Expand Down
4 changes: 3 additions & 1 deletion include/hermes/BCGen/SerializedLiteralGenerator.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,9 @@ class SerializedLiteralGenerator {
static constexpr TagType NumberTag = 3 << 4;
static constexpr TagType LongStringTag = 4 << 4;
static constexpr TagType ShortStringTag = 5 << 4;
static constexpr TagType ByteStringTag = 6 << 4;
// TODO: Evaluate restoring ByteStringTag by using a different serialization
// scheme.
static constexpr TagType UndefinedTag = 6 << 4;
static constexpr TagType IntegerTag = 7 << 4;
static constexpr TagType TagMask = 0x70;

Expand Down
99 changes: 99 additions & 0 deletions include/hermes/BCGen/SerializedLiteralParser.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

#ifndef HERMES_BCGEN_SERIALIZEDLITERALPARSER_H
#define HERMES_BCGEN_SERIALIZEDLITERALPARSER_H

#include "hermes/BCGen/SerializedLiteralGenerator.h"
#include "hermes/Support/Conversions.h"
#include "llvh/ADT/ArrayRef.h"
#include "llvh/Support/Endian.h"

namespace hermes::SerializedLiteralParser {

/// Visit \p totalLen elements serialized in the buffer \p buf with the given
/// visitor \p v.
/// The visitor should define the following methods, which will be invoked
/// when an element of the corresponding type is encountered.
/// void visitStringID(StringID);
/// void visitNumber(double);
/// void visitNull();
/// void visitBool(bool);
template <typename Visitor>
static void
parse(llvh::ArrayRef<uint8_t> buf, unsigned int totalLen, Visitor &v) {
size_t bufIdx = 0;

while (totalLen) {
auto tag = buf[bufIdx++];
// If the first bit in the tag is set to 1, it is an indication that the
// sequence is longer than 15 elements, and that the tag is two bytes
// long.
size_t leftInSeq;
if (tag & 0x80)
leftInSeq = ((tag & 0x0f) << 8) | (buf[bufIdx++]);
else
leftInSeq = tag & 0x0f;

SerializedLiteralGenerator::TagType type =
tag & SerializedLiteralGenerator::TagMask;
switch (type) {
case SerializedLiteralGenerator::ShortStringTag:
while (leftInSeq-- && totalLen--) {
uint16_t val = llvh::support::endian::read<uint16_t, 1>(
&buf[bufIdx], llvh::support::endianness::little);
v.visitStringID(val);
bufIdx += 2;
}
break;
case SerializedLiteralGenerator::LongStringTag:
while (leftInSeq-- && totalLen--) {
uint32_t val = llvh::support::endian::read<uint32_t, 1>(
&buf[bufIdx], llvh::support::endianness::little);
v.visitStringID(val);
bufIdx += 4;
}
break;
case SerializedLiteralGenerator::NumberTag:
while (leftInSeq-- && totalLen--) {
double val = llvh::support::endian::read<double, 1>(
&buf[bufIdx], llvh::support::endianness::little);
v.visitNumber(val);
bufIdx += 8;
}
break;
case SerializedLiteralGenerator::IntegerTag:
while (leftInSeq-- && totalLen--) {
int32_t val = llvh::support::endian::read<int32_t, 1>(
&buf[bufIdx], llvh::support::endianness::little);
v.visitNumber(val);
bufIdx += 4;
}
break;
case SerializedLiteralGenerator::NullTag:
while (leftInSeq-- && totalLen--)
v.visitNull();
break;
case SerializedLiteralGenerator::UndefinedTag:
while (leftInSeq-- && totalLen--)
v.visitUndefined();
break;
case SerializedLiteralGenerator::TrueTag:
while (leftInSeq-- && totalLen--)
v.visitBool(true);
break;
case SerializedLiteralGenerator::FalseTag:
while (leftInSeq-- && totalLen--)
v.visitBool(false);
break;
}
}
}

} // namespace hermes::SerializedLiteralParser

#endif // HERMES_BCGEN_SERIALIZEDLITERALPARSER_H
152 changes: 0 additions & 152 deletions include/hermes/BCGen/SerializedLiteralParserBase.h

This file was deleted.

13 changes: 0 additions & 13 deletions include/hermes/VM/CodeBlock.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
#include "hermes/VM/IdentifierTable.h"
#include "hermes/VM/Profiler.h"
#include "hermes/VM/PropertyCache.h"
#include "hermes/VM/SerializedLiteralParser.h"
#include "llvh/ADT/DenseSet.h"
#include "llvh/ADT/Optional.h"
#include "llvh/Support/TrailingObjects.h"
Expand Down Expand Up @@ -144,18 +143,6 @@ class CodeBlock final
/// backtraces when debug info is not present.
uint32_t getVirtualOffset() const;

SerializedLiteralParser getArrayBufferIter(
uint32_t idx,
unsigned int numLiterals) const;

SerializedLiteralParser getObjectBufferKeyIter(
uint32_t idx,
unsigned int numLiterals) const;

SerializedLiteralParser getObjectBufferValueIter(
uint32_t idx,
unsigned int numLiterals) const;

RuntimeModule *getRuntimeModule() const {
return runtimeModule_;
}
Expand Down
2 changes: 0 additions & 2 deletions include/hermes/VM/SerializedLiteralParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@

#ifndef HERMES_VM_SERIALIZEDLITERALPARSER_H
#define HERMES_VM_SERIALIZEDLITERALPARSER_H

#include "hermes/BCGen/SerializedLiteralParserBase.h"
#include "hermes/Support/Conversions.h"
#include "hermes/VM/HermesValue.h"
#include "llvh/ADT/ArrayRef.h"
Expand Down
10 changes: 0 additions & 10 deletions lib/BCGen/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,8 @@ add_hermes_library(hermesBackend
LowerBuiltinCalls.cpp
Exceptions.cpp
SerializedLiteralGenerator.cpp
SerializedLiteralParserBase.cpp
LINK_OBJLIBS hermesFrontend hermesOptimizer
)

add_hermes_library(hermesBackendLean
SerializedLiteralParserBase.cpp
LINK_OBJLIBS
hermesSupport
hermesPublic
)

target_compile_definitions(hermesBackendLean_obj PUBLIC HERMESVM_LEAN)

add_subdirectory(HBC)
add_subdirectory(SH)
8 changes: 2 additions & 6 deletions lib/BCGen/HBC/BytecodeDisassembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,12 +108,6 @@ namespace {
std::string SLPToString(SLG::TagType tag, const unsigned char *buff, int *ind) {
std::string rBracket{"]"};
switch (tag) {
case SLG::ByteStringTag: {
uint8_t val = llvh::support::endian::read<uint8_t, 1>(
buff + *ind, llvh::support::endianness::little);
*ind += 1;
return std::string("[String ") + std::to_string(val) + rBracket;
}
case SLG::ShortStringTag: {
uint16_t val = llvh::support::endian::read<uint16_t, 1>(
buff + *ind, llvh::support::endianness::little);
Expand All @@ -140,6 +134,8 @@ std::string SLPToString(SLG::TagType tag, const unsigned char *buff, int *ind) {
}
case SLG::NullTag:
return "null";
case SLG::UndefinedTag:
return "undefined";
case SLG::TrueTag:
return "true";
case SLG::FalseTag:
Expand Down
15 changes: 8 additions & 7 deletions lib/BCGen/SerializedLiteralGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ void serializeValueToBuffer(
bool SerializedLiteralGenerator::isSerializableLiteral(Value *V) {
return V &&
(llvh::isa<LiteralNull>(V) || llvh::isa<LiteralBool>(V) ||
llvh::isa<LiteralNumber>(V) || llvh::isa<LiteralString>(V));
llvh::isa<LiteralUndefined>(V) || llvh::isa<LiteralNumber>(V) ||
llvh::isa<LiteralString>(V));
}

uint32_t SerializedLiteralGenerator::serializeBuffer(
Expand Down Expand Up @@ -97,10 +98,8 @@ uint32_t SerializedLiteralGenerator::serializeBuffer(

if (ind > UINT16_MAX) {
newTag = LongStringTag;
} else if (ind > UINT8_MAX) {
newTag = ShortStringTag;
} else {
newTag = ByteStringTag;
newTag = ShortStringTag;
}
break;
}
Expand All @@ -111,6 +110,9 @@ uint32_t SerializedLiteralGenerator::serializeBuffer(
case ValueKind::LiteralNullKind:
newTag = NullTag;
break;
case ValueKind::LiteralUndefinedKind:
newTag = UndefinedTag;
break;
default:
hermes_fatal("Invalid Literal Kind");
}
Expand Down Expand Up @@ -148,14 +150,13 @@ uint32_t SerializedLiteralGenerator::serializeBuffer(

if (stringID > UINT16_MAX) {
serializeValueToBuffer<uint32_t>(stringID, tmpSeqBuffer);
} else if (stringID > UINT8_MAX) {
serializeValueToBuffer<uint16_t>(stringID, tmpSeqBuffer);
} else {
serializeValueToBuffer<uint8_t>(stringID, tmpSeqBuffer);
serializeValueToBuffer<uint16_t>(stringID, tmpSeqBuffer);
}
break;
}
case ValueKind::LiteralBoolKind:
case ValueKind::LiteralUndefinedKind:
case ValueKind::LiteralNullKind:
/* no-op */
break;
Expand Down