Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions maldoca/astgen/ast_source_printer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,9 @@ void AstSourcePrinter::PrintGetterBody(const Symbol& field_name,
{"field_name", field_name.ToCcVarName()},
});

// TODO: Avoid redundant has_value checks for primitive/value types
// where the getter returns the optional directly
// (e.g. std::optional<int64_t>).
Println("if (!$field_name$_.has_value()) {");
Println(" return std::nullopt;");
Println("} else {");
Expand Down
18 changes: 16 additions & 2 deletions maldoca/js/ast/ast.generated.cc
Original file line number Diff line number Diff line change
Expand Up @@ -468,9 +468,11 @@ JsCommentLine::JsCommentLine(

JsSymbolId::JsSymbolId(
std::string name,
std::optional<int64_t> def_scope_uid)
std::optional<int64_t> def_scope_uid,
std::optional<int64_t> binding_uid)
: name_(std::move(name)),
def_scope_uid_(std::move(def_scope_uid)) {}
def_scope_uid_(std::move(def_scope_uid)),
binding_uid_(std::move(binding_uid)) {}

absl::string_view JsSymbolId::name() const {
return name_;
Expand All @@ -492,6 +494,18 @@ void JsSymbolId::set_def_scope_uid(std::optional<int64_t> def_scope_uid) {
def_scope_uid_ = std::move(def_scope_uid);
}

std::optional<int64_t> JsSymbolId::binding_uid() const {
if (!binding_uid_.has_value()) {
return std::nullopt;
} else {
return binding_uid_.value();
}
}

void JsSymbolId::set_binding_uid(std::optional<int64_t> binding_uid) {
binding_uid_ = std::move(binding_uid);
}

// =============================================================================
// JsNode
// =============================================================================
Expand Down
8 changes: 7 additions & 1 deletion maldoca/js/ast/ast.generated.h
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,8 @@ class JsSymbolId {
public:
explicit JsSymbolId(
std::string name,
std::optional<int64_t> def_scope_uid);
std::optional<int64_t> def_scope_uid,
std::optional<int64_t> binding_uid);

void Serialize(std::ostream& os) const;

Expand All @@ -307,6 +308,9 @@ class JsSymbolId {
std::optional<int64_t> def_scope_uid() const;
void set_def_scope_uid(std::optional<int64_t> def_scope_uid);

std::optional<int64_t> binding_uid() const;
void set_binding_uid(std::optional<int64_t> binding_uid);

protected:
// Internal function used by Serialize().
// Sets the fields defined in this class.
Expand All @@ -317,10 +321,12 @@ class JsSymbolId {
// Extracts a field from a JSON object.
static absl::StatusOr<std::string> GetName(const nlohmann::json& json);
static absl::StatusOr<std::optional<int64_t>> GetDefScopeUid(const nlohmann::json& json);
static absl::StatusOr<std::optional<int64_t>> GetBindingUid(const nlohmann::json& json);

private:
std::string name_;
std::optional<int64_t> def_scope_uid_;
std::optional<int64_t> binding_uid_;
};

enum class JsNodeType {
Expand Down
13 changes: 12 additions & 1 deletion maldoca/js/ast/ast_from_json.generated.cc
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,15 @@ JsSymbolId::GetDefScopeUid(const nlohmann::json& json) {
);
}

absl::StatusOr<std::optional<int64_t>>
JsSymbolId::GetBindingUid(const nlohmann::json& json) {
return GetOptionalField<int64_t>(
json,
"bindingUid",
JsonToInt64
);
}

absl::StatusOr<std::unique_ptr<JsSymbolId>>
JsSymbolId::FromJson(const nlohmann::json& json) {
if (!json.is_object()) {
Expand All @@ -254,10 +263,12 @@ JsSymbolId::FromJson(const nlohmann::json& json) {

MALDOCA_ASSIGN_OR_RETURN(auto name, JsSymbolId::GetName(json));
MALDOCA_ASSIGN_OR_RETURN(auto def_scope_uid, JsSymbolId::GetDefScopeUid(json));
MALDOCA_ASSIGN_OR_RETURN(auto binding_uid, JsSymbolId::GetBindingUid(json));

return absl::make_unique<JsSymbolId>(
std::move(name),
std::move(def_scope_uid));
std::move(def_scope_uid),
std::move(binding_uid));
}

// =============================================================================
Expand Down
4 changes: 4 additions & 0 deletions maldoca/js/ast/ast_to_json.generated.cc
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,10 @@ void JsSymbolId::SerializeFields(std::ostream& os, bool &needs_comma) const {
MaybeAddComma(os, needs_comma);
os << "\"defScopeUid\":" << (nlohmann::json(def_scope_uid_.value())).dump();
}
if (binding_uid_.has_value()) {
MaybeAddComma(os, needs_comma);
os << "\"bindingUid\":" << (nlohmann::json(binding_uid_.value())).dump();
}
}

void JsSymbolId::Serialize(std::ostream& os) const {
Expand Down
6 changes: 5 additions & 1 deletion maldoca/js/babel/babel.proto
Original file line number Diff line number Diff line change
Expand Up @@ -204,14 +204,18 @@ message BabelBinding {

optional Kind kind = 1;
optional string name = 2;
optional int32 uid = 3;
}

message BabelScope {
optional int32 uid = 1;
optional int32 parent_uid = 2;
map<string, BabelBinding> bindings = 3;
// Deprecated: use binding_uids instead.
map<string, BabelBinding> bindings = 3 [deprecated = true];
map<string, int32> binding_uids = 4;
}

message BabelScopes {
map<int32, BabelScope> scopes = 1;
map<int32, BabelBinding> bindings = 2;
}
18 changes: 12 additions & 6 deletions maldoca/js/babel/babel_json_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,10 @@ TEST(BabelJsonTest, BabelScopes) {
BabelBinding binding;
binding.set_kind(BabelBinding::KIND_VAR);
binding.set_name("global");
binding.set_uid(1);

scope.mutable_bindings()->insert({binding.name(), binding});
scopes.mutable_bindings()->insert({binding.uid(), binding});
scope.mutable_binding_uids()->insert({binding.name(), binding.uid()});
}

scopes.mutable_scopes()->insert({scope.uid(), scope});
Expand All @@ -73,13 +75,17 @@ TEST(BabelJsonTest, BabelScopes) {
"scopes": {
"0": {
"uid": 0,
"bindings": {
"global": {
"kind": "KIND_VAR",
"name": "global"
}
"bindingUids": {
"global": 1
}
}
},
"bindings": {
"1": {
"kind": "KIND_VAR",
"name": "global",
"uid": 1
}
}
}
)json";
Expand Down
29 changes: 26 additions & 3 deletions maldoca/js/babel/scope.cc
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,13 @@ std::optional<int64_t> FindSymbol(const BabelScopes &scopes,
}
const auto &scope = scope_it->second;

auto binding_it = scope.bindings().find(name);
if (binding_it != scope.bindings().end()) {
auto binding_it = scope.binding_uids().find(std::string(name));
if (binding_it != scope.binding_uids().end()) {
return use_scope_uid;
}

auto old_binding_it = scope.bindings().find(std::string(name));
if (old_binding_it != scope.bindings().end()) {
return use_scope_uid;
}

Expand All @@ -54,7 +59,25 @@ std::optional<int64_t> FindSymbol(const BabelScopes &scopes,

JsSymbolId GetSymbolId(const BabelScopes &scopes, int64_t use_scope_uid,
absl::string_view name) {
return JsSymbolId{std::string(name), FindSymbol(scopes, use_scope_uid, name)};
auto def_scope_uid = FindSymbol(scopes, use_scope_uid, name);
std::optional<int64_t> binding_uid = std::nullopt;
if (def_scope_uid.has_value()) {
auto scope_it = scopes.scopes().find(*def_scope_uid);
if (scope_it != scopes.scopes().end()) {
auto binding_it = scope_it->second.binding_uids().find(std::string(name));
if (binding_it != scope_it->second.binding_uids().end()) {
binding_uid = binding_it->second;
} else {
auto old_binding_it =
scope_it->second.bindings().find(std::string(name));
if (old_binding_it != scope_it->second.bindings().end() &&
old_binding_it->second.has_uid()) {
binding_uid = old_binding_it->second.uid();
}
}
}
}
return JsSymbolId{std::string(name), def_scope_uid, binding_uid};
}

} // namespace maldoca
24 changes: 15 additions & 9 deletions maldoca/js/babel/scope.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,25 +31,31 @@ namespace maldoca {

template <typename H>
H AbslHashValue(H h, const JsSymbolId& s) {
return H::combine(std::move(h), s.name(), s.def_scope_uid());
return H::combine(std::move(h), s.name(), s.def_scope_uid(),
s.binding_uid().value_or(-1));
}

inline bool operator==(const JsSymbolId& lhs, const JsSymbolId& rhs) {
return std::forward_as_tuple(lhs.name(), lhs.def_scope_uid()) ==
std::forward_as_tuple(rhs.name(), rhs.def_scope_uid());
return lhs.name() == rhs.name() &&
lhs.def_scope_uid() == rhs.def_scope_uid() &&
lhs.binding_uid().value_or(-1) == rhs.binding_uid().value_or(-1);
}

inline bool operator<(const JsSymbolId& lhs, const JsSymbolId& rhs) {
return std::forward_as_tuple(lhs.def_scope_uid(), lhs.name()) <
std::forward_as_tuple(rhs.def_scope_uid(), rhs.name());
return std::make_tuple(lhs.binding_uid().value_or(-1),
lhs.def_scope_uid(), lhs.name()) <
std::make_tuple(rhs.binding_uid().value_or(-1),
rhs.def_scope_uid(), rhs.name());
}

template <typename Sink>
void AbslStringify(Sink& sink, const JsSymbolId& s) {
std::string def_scope_uid = s.def_scope_uid().has_value()
? absl::StrCat(*s.def_scope_uid())
: "undeclared";
absl::Format(&sink, "%s#%s", s.name(), def_scope_uid);
std::string id = s.binding_uid().has_value()
? absl::StrCat("b", *s.binding_uid())
: (s.def_scope_uid().has_value()
? absl::StrCat("s", *s.def_scope_uid())
: "undeclared");
absl::Format(&sink, "%s#%s", s.name(), id);
}

inline std::ostream& operator<<(std::ostream& os, const JsSymbolId& s) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ class JsirConditionalForwardPerVarDataFlowAnalysis
void WriteDenseAfterState(mlir::Operation *op, llvm::StringRef name,
const ValueT &value, const StateT *before,
JsirStateRef<StateT> after) {
JsSymbolId target_symbol{std::string(name), FindSymbol(scopes_, op, name)};
JsSymbolId target_symbol = GetSymbolId(scopes_, op, name);

after.Join(*before);
after.Write([&](StateT *after) {
Expand All @@ -112,8 +112,7 @@ class JsirConditionalForwardPerVarDataFlowAnalysis
void VisitIdentifier(JsirIdentifierOp op,
OperandStates<JsirIdentifierOp> operands,
const StateT *before, JsirStateRef<ValueT> result) {
absl::string_view name = op.getName();
JsSymbolId symbol{std::string(name), FindSymbol(scopes_, op, name)};
JsSymbolId symbol = GetSymbolId(scopes_, op);
ValueT value = before->Get(symbol);
result.Join(value);
}
Expand All @@ -124,7 +123,7 @@ class JsirConditionalForwardPerVarDataFlowAnalysis
llvm::MutableArrayRef<JsirStateRef<ValueT>> results,
JsirStateRef<StateT> after) {
absl::string_view name = op.getId().getName().strref();
JsSymbolId symbol{std::string(name), FindSymbol(scopes_, op, name)};
JsSymbolId symbol = GetSymbolId(scopes_, op, name);
ValueT value = before->Get(symbol);

assert(results.size() == 1);
Expand Down
Loading
Loading