Skip to content

Commit

Permalink
Move managed_object_ptr → managed_ptr.h
Browse files Browse the repository at this point in the history
Summary:
These functionality seem generally useful outside of simply interacting with `object.h`.

Indeed in future diff, the (arbitrary) restriction that `T` be `whisker::object` or one of its alternatives is relaxed.

Change is no-op.

Reviewed By: thedavekwon

Differential Revision: D68078565

fbshipit-source-id: ac1422ab63f72deb490e397376952388de2887da
  • Loading branch information
praihan authored and facebook-github-bot committed Jan 13, 2025
1 parent 9cab624 commit 5f2a309
Show file tree
Hide file tree
Showing 10 changed files with 175 additions and 120 deletions.
8 changes: 4 additions & 4 deletions thrift/compiler/whisker/eval_context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ object::ptr find_property(const object& o, std::string_view identifier) {
[](const native_function::ptr&) -> result { return nullptr; },
[identifier](const map& m) -> result {
if (auto it = m.find(identifier); it != m.end()) {
return object::as_static(it->second);
return manage_as_static(it->second);
}
return nullptr;
});
Expand Down Expand Up @@ -74,7 +74,7 @@ class global_scope_object
object::ptr lookup_property(std::string_view identifier) const override {
if (auto property = properties_.find(identifier);
property != properties_.end()) {
return object::as_static(property->second);
return manage_as_static(property->second);
}
return nullptr;
}
Expand All @@ -98,7 +98,7 @@ class global_scope_object
object::ptr eval_context::lexical_scope::lookup_property(
std::string_view identifier) {
if (auto local = locals_.find(identifier); local != locals_.end()) {
return object::as_static(local->second);
return manage_as_static(local->second);
}
return find_property(this_ref_, identifier);
}
Expand Down Expand Up @@ -156,7 +156,7 @@ eval_context::lookup_object(const std::vector<std::string>& path) {

if (path.empty()) {
// Lookup is {{.}}
return object::as_static(stack_.back().this_ref());
return manage_as_static(stack_.back().this_ref());
}

auto current = std::invoke([&]() -> object::ptr {
Expand Down
2 changes: 1 addition & 1 deletion thrift/compiler/whisker/eval_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ class eval_context {
* the chain of resolved whisker::objects.
*/
expected<
managed_object_ptr<>,
object::ptr,
std::variant<eval_scope_lookup_error, eval_property_lookup_error>>
lookup_object(const std::vector<std::string>& path);

Expand Down
100 changes: 100 additions & 0 deletions thrift/compiler/whisker/managed_ptr.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#pragma once

#include <memory>
#include <tuple>
#include <utility>

namespace whisker {

/**
* A managed_ptr<T> represents one of:
* 1. A "static"-ally managed object. See manage_as_static(...).
* 2. An owned instance of T. See manage_owned(...).
* 3. A derived instance of T, that is a sub-object of another managed object.
* See manage_derived(...) and manage_derived_ref(...).
*
* All three cases are represented by shared_ptr. See `folly::MaybeManagedPtr`.
* (1) and (3) use the aliasing constructor of shared_ptr.
*/
template <typename T>
using managed_ptr = std::shared_ptr<const T>;

/**
* Returns a pointer which is an unmanaged reference to the provided
* object.
*
* The caller must guarantee that the provided object is kept alive as long as
* the returned pointer is used.
*/
template <typename T>
managed_ptr<T> manage_as_static(const T& o) {
return managed_ptr<T>(managed_ptr<void>(), std::addressof(o));
}

/**
* Returns a pointer which directly owns an instance of T.
*/
template <typename T, typename... Args>
managed_ptr<T> manage_owned(Args&&... args) {
return std::make_shared<const T>(std::forward<Args>(args)...);
}

/**
* Returns a pointer where the lifetime of `value` depends on one or more other
* objects. This means that `from` must outlive `value`.
*
* The caller must guarantee that the provided object is kept alive as long as
* the returned pointer is used.
*/
template <typename T, typename U>
managed_ptr<T> manage_derived_ref(const managed_ptr<U>& from, const T& value) {
return managed_ptr<T>(from, std::addressof(value));
}
// Same as above except derived from multiple objects.
template <typename T, typename... U>
managed_ptr<T> manage_derived_ref(
std::tuple<managed_ptr<U>...> froms, const T& value) {
return managed_ptr<T>(
std::make_shared<std::tuple<managed_ptr<U>...>>(std::move(froms)),
std::addressof(value));
}

/**
* Returns a pointer where the lifetime of `value` depends on one or more other
* objects. This means that `from` must outlive `value`.
*/
template <typename T, typename U>
managed_ptr<T> manage_derived(
const managed_ptr<U>& from, managed_ptr<T> value_ptr) {
const T& value = *value_ptr;
return manage_derived_ref(
std::tuple<managed_ptr<U>, managed_ptr<T>>(from, std::move(value_ptr)),
value);
}
// Same as above except derived from multiple objects.
template <typename T, typename... U>
managed_ptr<T> manage_derived(
std::tuple<managed_ptr<U>...> froms, managed_ptr<T> value_ptr) {
const T& value = *value_ptr;
return manage_derived_ref(
std::tuple_cat(std::tuple(std::move(value_ptr)), std::move(froms)),
value);
}

} // namespace whisker
8 changes: 4 additions & 4 deletions thrift/compiler/whisker/mstch_compat.cc
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ class mstch_array_proxy final
converted_.emplace_back(from_mstch(std::move(node)));
}
}
return object::derive(shared_from_this(), converted_[index]);
return manage_derived_ref(shared_from_this(), converted_[index]);
}

void print_to(tree_printer::scope scope, const object_print_options& options)
Expand Down Expand Up @@ -105,7 +105,7 @@ class mstch_map_proxy final

object::ptr lookup_property(std::string_view id) const override {
if (auto cached = converted_.find(id); cached != converted_.end()) {
return object::derive(shared_from_this(), cached->second);
return manage_derived_ref(shared_from_this(), cached->second);
}
// mstch does not support heterogenous lookups, so we need a temporary
// std::string.
Expand All @@ -114,7 +114,7 @@ class mstch_map_proxy final
auto [result, inserted] = converted_.insert(
{std::move(id_string), from_mstch(std::move(property->second))});
assert(inserted);
return object::derive(shared_from_this(), result->second);
return manage_derived_ref(shared_from_this(), result->second);
}
return nullptr;
}
Expand Down Expand Up @@ -183,7 +183,7 @@ class mstch_object_proxy

auto [result, _] = keep_alive_.insert_or_assign(
id_string, from_mstch(proxied_->at(id_string)));
return object::derive(shared_from_this(), result->second);
return manage_derived_ref(shared_from_this(), result->second);
}

std::optional<std::vector<std::string>> keys() const override {
Expand Down
19 changes: 9 additions & 10 deletions thrift/compiler/whisker/object.cc
Original file line number Diff line number Diff line change
Expand Up @@ -179,8 +179,7 @@ bool native_object::operator==(const native_object& other) const {
native_function::context::array_like::array_like(
native_object::array_like::ptr&& arr)
: which_(std::move(arr)) {}
native_function::context::array_like::array_like(
managed_object_ptr<array>&& arr)
native_function::context::array_like::array_like(managed_ptr<array>&& arr)
: which_(std::move(arr)) {}

native_function::context::array_like::~array_like() noexcept = default;
Expand Down Expand Up @@ -208,20 +207,20 @@ object::ptr native_function::context::array_like::at(std::size_t index) const {
[&](const native_object::array_like::ptr& arr) -> object::ptr {
return arr->at(index);
},
[&](const managed_object_ptr<array>& arr) -> object::ptr {
return object::derive(arr, (*arr)[index]);
[&](const managed_ptr<array>& arr) -> object::ptr {
return manage_derived_ref(arr, (*arr)[index]);
});
}

native_function::context::map_like::map_like(native_object::map_like::ptr&& m)
: which_(std::move(m)) {}
native_function::context::map_like::map_like(managed_object_ptr<map>&& m)
native_function::context::map_like::map_like(managed_ptr<map>&& m)
: which_(std::move(m)) {}

/* static */ std::optional<native_function::context::array_like>
native_function::context::array_like::try_from(const object::ptr& o) {
if (o->is_array()) {
return array_like(object::derive(o, o->as_array()));
return array_like(manage_derived_ref(o, o->as_array()));
}
if (o->is_native_object()) {
if (native_object::array_like::ptr arr =
Expand Down Expand Up @@ -251,9 +250,9 @@ object::ptr native_function::context::map_like::lookup_property(
[&](const native_object::map_like::ptr& m) -> object::ptr {
return m->lookup_property(identifier);
},
[&](const managed_object_ptr<map>& m) -> object::ptr {
[&](const managed_ptr<map>& m) -> object::ptr {
if (auto it = m->find(identifier); it != m->end()) {
return object::as_static(it->second);
return manage_as_static(it->second);
}
return nullptr;
});
Expand All @@ -267,7 +266,7 @@ native_function::context::map_like::keys() const {
[&](const native_object::map_like::ptr& m) -> result {
return m->keys();
},
[&](const managed_object_ptr<map>& m) -> result {
[&](const managed_ptr<map>& m) -> result {
std::vector<std::string> keys;
keys.reserve(m->size());
for (const auto& [key, _] : *m) {
Expand All @@ -280,7 +279,7 @@ native_function::context::map_like::keys() const {
/* static */ std::optional<native_function::context::map_like>
native_function::context::map_like::try_from(const object::ptr& o) {
if (o->is_map()) {
return map_like(object::derive(o, o->as_map()));
return map_like(manage_derived_ref(o, o->as_map()));
}
if (o->is_native_object()) {
if (native_object::map_like::ptr m = o->as_native_object()->as_map_like()) {
Expand Down
Loading

0 comments on commit 5f2a309

Please sign in to comment.