#pragma once
#ifdef EXPO_RUST_JSI_STANDALONE
#include "jsi_types.h"
#else
#include <jsi/jsi.h>
#endif
#include "rust/cxx.h"
#include <memory>
#include <string>
#include <vector>
#include <functional>
#include <cstdint>
#include <mutex>
#include <unordered_map>
namespace expo {
namespace rust_jsi {
struct FfiValue;
struct RuntimeHandle;
FfiValue jsi_make_undefined();
FfiValue jsi_make_null();
FfiValue jsi_make_bool(bool val);
FfiValue jsi_make_number(double val);
FfiValue jsi_make_string(rust::Str val);
FfiValue jsi_create_object(const RuntimeHandle& rt);
void jsi_object_set_property(const RuntimeHandle& rt, uint64_t obj_handle,
rust::Str name, const FfiValue& value);
FfiValue jsi_object_get_property(const RuntimeHandle& rt, uint64_t obj_handle,
rust::Str name);
FfiValue jsi_create_array(const RuntimeHandle& rt, uint32_t length);
void jsi_array_set_value(const RuntimeHandle& rt, uint64_t arr_handle,
uint32_t index, const FfiValue& value);
FfiValue jsi_array_get_value(const RuntimeHandle& rt, uint64_t arr_handle,
uint32_t index);
uint32_t jsi_array_length(const RuntimeHandle& rt, uint64_t arr_handle);
void jsi_register_module(const RuntimeHandle& rt, rust::Str name,
uint64_t obj_handle);
FfiValue jsi_create_host_function(const RuntimeHandle& rt, rust::Str name,
uint32_t param_count, uint64_t callback_id);
void jsi_object_set_host_function(const RuntimeHandle& rt, uint64_t obj_handle,
rust::Str name, uint64_t fn_handle);
void jsi_throw_error(const RuntimeHandle& rt, rust::Str message);
FfiValue jsi_create_promise(const RuntimeHandle& rt);
void jsi_call_function(const RuntimeHandle& rt, uint64_t fn_handle,
const FfiValue& arg);
using RustPropertyGetter = FfiValue(*)(void* ctx, const char* name, size_t name_len);
using RustPropertySetter = void(*)(void* ctx, const char* name, size_t name_len, const FfiValue& value);
#ifndef EXPO_RUST_JSI_STANDALONE
class RustHostObject : public facebook::jsi::HostObject {
public:
RustHostObject(void* rust_ctx,
RustPropertyGetter getter,
RustPropertySetter setter,
std::vector<std::string> property_names);
~RustHostObject() override;
facebook::jsi::Value get(facebook::jsi::Runtime& rt,
const facebook::jsi::PropNameID& name) override;
void set(facebook::jsi::Runtime& rt,
const facebook::jsi::PropNameID& name,
const facebook::jsi::Value& value) override;
std::vector<facebook::jsi::PropNameID> getPropertyNames(
facebook::jsi::Runtime& rt) override;
private:
void* rust_ctx_;
RustPropertyGetter getter_;
RustPropertySetter setter_;
std::vector<std::string> property_names_;
};
FfiValue jsi_value_to_ffi(facebook::jsi::Runtime& rt,
const facebook::jsi::Value& value);
facebook::jsi::Value ffi_to_jsi_value(facebook::jsi::Runtime& rt,
const FfiValue& value);
#endif
class HandleTable {
public:
static HandleTable& instance();
uint64_t store(std::shared_ptr<void> obj);
std::shared_ptr<void> get(uint64_t handle);
void release(uint64_t handle);
private:
HandleTable() = default;
std::unordered_map<uint64_t, std::shared_ptr<void>> table_;
uint64_t next_handle_ = 1;
std::mutex mutex_;
};
} }