#ifndef CORE_RUNTIME_JS_UTILS_H_
#define CORE_RUNTIME_JS_UTILS_H_
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "base/include/debug/lynx_error.h"
#include "base/include/log/logging.h"
#include "base/include/value/base_value.h"
#include "base/include/vector.h"
#include "core/base/json/json_util.h"
#include "core/runtime/js/jsi/jsi.h"
#include "third_party/rapidjson/document.h"
#include "third_party/rapidjson/error/en.h"
#include "third_party/rapidjson/reader.h"
#include "third_party/rapidjson/stringbuffer.h"
#include "third_party/rapidjson/writer.h"
namespace lynx {
namespace runtime {
namespace js {
class JSIObjectWrapperManager;
std::optional<Value> valueFromLepus(
Runtime& runtime, const lepus::Value& data,
JSIObjectWrapperManager* jsi_object_wrapper_manager = nullptr);
std::optional<Array> arrayFromLepus(Runtime& runtime,
const lepus::CArray& array);
bool EvaluatePreloadSources(
Runtime& runtime,
std::vector<std::pair<std::string, std::shared_ptr<Buffer>>>& sources);
const char* JSRuntimeTypeToString(JSRuntimeType type);
using JSValueCircularArray = base::InlineVector<Object, 32>;
class CircularDataChecker {
public:
explicit CircularDataChecker(Runtime& runtime) : runtime_(runtime) {}
static std::string KeySegment(const std::string& key);
static std::string IndexSegment(size_t index);
bool CheckAndReport(const Object& object, const std::string& segment,
const char* context);
class ScopedPath {
public:
ScopedPath(CircularDataChecker& checker, Object object,
const std::string& segment)
: checker_(checker) {
checker_.frames_.emplace_back(std::move(object), segment);
}
~ScopedPath() { checker_.frames_.pop_back(); }
ScopedPath(const ScopedPath&) = delete;
ScopedPath& operator=(const ScopedPath&) = delete;
private:
CircularDataChecker& checker_;
};
private:
struct Frame {
Frame(Object object, std::string segment)
: object(std::move(object)), segment(std::move(segment)) {}
Object object;
std::string segment;
};
std::string CurrentPath() const;
std::string PathUpTo(size_t index) const;
Runtime& runtime_;
base::InlineVector<Frame, 32> frames_;
};
std::optional<lepus_value> ParseJSValue(
Runtime& runtime, const Value& value,
JSIObjectWrapperManager* jsi_object_wrapper_manager,
const std::string& jsi_object_group_id, const std::string& targetSDKVersion,
CircularDataChecker& checker, const std::string& segment = std::string());
bool IsCircularJSObject(Runtime& runtime, const Object& object,
const JSValueCircularArray& pre_object_vector);
bool ConvertPiperValueToStringVector(Runtime& rt, const Value& input,
std::vector<std::string>& result);
class ScopedJSObjectPushPopHelper {
public:
ScopedJSObjectPushPopHelper(JSValueCircularArray& vector, Object object)
: pre_object_vector_(vector) {
pre_object_vector_.push_back(std::move(object));
};
~ScopedJSObjectPushPopHelper() { pre_object_vector_.pop_back(); }
private:
JSValueCircularArray& pre_object_vector_;
};
}
}
}
#endif