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

feat: basic test runner support for rust plugin. #713

Merged
merged 12 commits into from
Feb 2, 2025
Merged
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
6 changes: 6 additions & 0 deletions bridge/core/api/document.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
*/

#include "plugin_api/document.h"
#include "binding_call_methods.h"
#include "core/api/exception_state.h"
#include "core/dom/comment.h"
#include "core/dom/document.h"
Expand Down Expand Up @@ -246,4 +247,9 @@ WebFValue<Element, HTMLElementPublicMethods> DocumentPublicMethods::Body(webf::D
return WebFValue<Element, HTMLElementPublicMethods>{body, body->htmlElementPublicMethods(), status_block};
}

void DocumentPublicMethods::ClearCookie(webf::Document* document, webf::SharedExceptionState* shared_exception_state) {
document->InvokeBindingMethod(binding_call_methods::k___clear_cookies__, 0, nullptr,
FlushUICommandReason::kDependentsOnElement, shared_exception_state->exception_state);
}

} // namespace webf
22 changes: 18 additions & 4 deletions bridge/core/api/executing_context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ void ExecutingContextWebFMethods::FinishRecordingUIOperations(webf::ExecutingCon
context->uiCommandBuffer()->AddCommand(UICommand::kFinishRecordingCommand, nullptr, nullptr, nullptr, false);
}

void ExecutingContextWebFMethods::WebFSyncBuffer(webf::ExecutingContext* context) {
context->uiCommandBuffer()->SyncToActive();
}

NativeValue ExecutingContextWebFMethods::WebFInvokeModule(ExecutingContext* context,
const char* module_name,
const char* method,
Expand Down Expand Up @@ -132,12 +136,22 @@ void ExecutingContextWebFMethods::ClearInterval(ExecutingContext* context,
WindowOrWorkerGlobalScope::clearInterval(context, interval_id, shared_exception_state->exception_state);
}

void ExecutingContextWebFMethods::SetRunRustFutureTasks(ExecutingContext* context,
WebFNativeFunctionContext* callback_context,
SharedExceptionState* shared_exception_state) {
void ExecutingContextWebFMethods::AddRustFutureTask(ExecutingContext* context,
WebFNativeFunctionContext* callback_context,
NativeLibrartMetaData* meta_data,
SharedExceptionState* shared_exception_state) {
auto callback_impl = WebFNativeFunction::Create(callback_context, shared_exception_state);

context->AddRustFutureTask(callback_impl, meta_data);
}

void ExecutingContextWebFMethods::RemoveRustFutureTask(ExecutingContext* context,
WebFNativeFunctionContext* callback_context,
NativeLibrartMetaData* meta_data,
SharedExceptionState* shared_exception_state) {
auto callback_impl = WebFNativeFunction::Create(callback_context, shared_exception_state);

context->SetRunRustFutureTasks(callback_impl);
context->RemoveRustFutureTask(callback_impl, meta_data);
}

} // namespace webf
4 changes: 2 additions & 2 deletions bridge/core/api/node.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ WebFValue<Node, NodePublicMethods> NodePublicMethods::RemoveChild(webf::Node* se
webf::Node* target_node,
webf::SharedExceptionState* shared_exception_state) {
MemberMutationScope member_mutation_scope{self_node->GetExecutingContext()};
Node* returned_node = target_node->removeChild(target_node, shared_exception_state->exception_state);
Node* returned_node = self_node->removeChild(target_node, shared_exception_state->exception_state);
if (shared_exception_state->exception_state.HasException()) {
return WebFValue<Node, NodePublicMethods>::Null();
}
Expand All @@ -37,4 +37,4 @@ WebFValue<Node, NodePublicMethods> NodePublicMethods::RemoveChild(webf::Node* se
return WebFValue<Node, NodePublicMethods>(returned_node, returned_node->nodePublicMethods(), status_block);
}

} // namespace webf
} // namespace webf
13 changes: 12 additions & 1 deletion bridge/core/api/window.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,17 @@
*/

#include "plugin_api/window.h"
#include "core/api/exception_state.h"
#include "core/dom/events/event_target.h"
#include "core/frame/window.h"

namespace webf {} // namespace webf
namespace webf {

void WindowPublicMethods::ScrollToWithXAndY(Window* window,
double x,
double y,
SharedExceptionState* shared_exception_state) {
window->scrollTo(x, y, shared_exception_state->exception_state);
}

} // namespace webf
5 changes: 4 additions & 1 deletion bridge/core/dart_methods.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#include <memory>
#include <thread>
#include "core/native/native_loader.h"
#include "foundation/native_string.h"
#include "foundation/native_value.h"
#include "include/dart_api.h"
Expand All @@ -36,8 +37,10 @@ using AsyncModuleCallback = NativeValue* (*)(void* callback_context,
Dart_PersistentHandle persistent_handle,
InvokeModuleResultCallback result_callback);

using PluginLibraryEntryPoint = void* (*)(WebFValue<ExecutingContext, ExecutingContextWebFMethods> handle_context);
using PluginLibraryEntryPoint = void* (*)(WebFValue<ExecutingContext, ExecutingContextWebFMethods> handle_context,
NativeLibrartMetaData* meta_data);
using LoadNativeLibraryCallback = void (*)(PluginLibraryEntryPoint entry_point,
NativeValue* lib_name,
void* initialize_data,
double context_id,
void* imported_data);
Expand Down
37 changes: 34 additions & 3 deletions bridge/core/executing_context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include <utility>
#include "bindings/qjs/converter_impl.h"
#include "bindings/qjs/script_promise_resolver.h"
#include "built_in_string.h"
#include "core/dom/document.h"
#include "core/dom/mutation_observer.h"
Expand Down Expand Up @@ -392,12 +393,42 @@ void ExecutingContext::EnqueueMicrotask(MicrotaskCallback callback, void* data)
JS_FreeValue(ctx(), proxy_data);
}

void ExecutingContext::SetRunRustFutureTasks(const std::shared_ptr<WebFNativeFunction>& run_future_task) {
run_rust_future_tasks_ = run_future_task;
void ExecutingContext::AddRustFutureTask(const std::shared_ptr<WebFNativeFunction>& run_future_task,
NativeLibrartMetaData* meta_data) {
meta_data->callbacks.push_back(run_future_task);
}

void ExecutingContext::RemoveRustFutureTask(const std::shared_ptr<WebFNativeFunction>& run_future_task,
NativeLibrartMetaData* meta_data) {
// Add the callback to the removed_callbacks list to avoid removing the callback during the iteration.
meta_data->removed_callbacks.push_back(run_future_task);
}

void ExecutingContext::RunRustFutureTasks() {
run_rust_future_tasks_->Invoke(this, 0, nullptr);
for (auto& meta_data : native_library_meta_data_contaner_) {
for (auto& callback : meta_data->callbacks) {
dart_isolate_context_->profiler()->StartTrackAsyncEvaluation();
callback->Invoke(this, 0, nullptr);
dart_isolate_context_->profiler()->FinishTrackAsyncEvaluation();
}
for (auto& removed_callback : meta_data->removed_callbacks) {
meta_data->callbacks.erase(std::remove_if(meta_data->callbacks.begin(), meta_data->callbacks.end(),
[&](const std::shared_ptr<WebFNativeFunction>& callback) {
return callback->Matches(removed_callback);
}),
meta_data->callbacks.end());
}
meta_data->removed_callbacks.clear();
if (meta_data->callbacks.empty() && meta_data->load_context != nullptr) {
meta_data->load_context->promise_resolver->Resolve(JS_NULL);
delete meta_data->load_context;
meta_data->load_context = nullptr;
}
}
}

void ExecutingContext::RegisterNativeLibraryMetaData(NativeLibrartMetaData* meta_data) {
native_library_meta_data_contaner_.push_back(meta_data);
}

void ExecutingContext::DrainPendingPromiseJobs() {
Expand Down
10 changes: 7 additions & 3 deletions bridge/core/executing_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,12 @@ class ExecutingContext {
void ReportError(JSValueConst error, char** rust_errmsg, uint32_t* rust_errmsg_length);
void DrainMicrotasks();
void EnqueueMicrotask(MicrotaskCallback callback, void* data = nullptr);
void SetRunRustFutureTasks(const std::shared_ptr<WebFNativeFunction>& run_rust_future_tasks);
static void AddRustFutureTask(const std::shared_ptr<WebFNativeFunction>& run_rust_future_tasks,
NativeLibrartMetaData* meta_data);
static void RemoveRustFutureTask(const std::shared_ptr<WebFNativeFunction>& run_rust_future_tasks,
NativeLibrartMetaData* meta_data);
void RunRustFutureTasks();
void RegisterNativeLibraryMetaData(NativeLibrartMetaData* meta_data);
void DefineGlobalProperty(const char* prop, JSValueConst value);
ExecutionContextData* contextData();
uint8_t* DumpByteCode(const char* code, uint32_t codeLength, const char* sourceURL, uint64_t* bytecodeLength);
Expand Down Expand Up @@ -228,8 +232,8 @@ class ExecutingContext {
// Rust methods ptr should keep alive when ExecutingContext is disposing.
const std::unique_ptr<ExecutingContextWebFMethods> public_method_ptr_ = nullptr;

// Rust future task queue run trigger
std::shared_ptr<WebFNativeFunction> run_rust_future_tasks_;
// Native library metadata
std::vector<NativeLibrartMetaData*> native_library_meta_data_contaner_;
};

class ObjectProperty {
Expand Down
4 changes: 4 additions & 0 deletions bridge/core/native/native_function.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ class WebFNativeFunction : public Function {
return callback_context_->callback(callback_context_, argc, argv, shared_exception_state_);
}

[[nodiscard]] bool Matches(const std::shared_ptr<WebFNativeFunction>& other) {
return other && other->callback_context_ && other->callback_context_->callback == callback_context_->callback;
}

private:
WebFNativeFunctionContext* callback_context_;
SharedExceptionState* shared_exception_state_;
Expand Down
22 changes: 8 additions & 14 deletions bridge/core/native/native_loader.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,10 @@

namespace webf {

namespace {

struct NativeLibraryLoadContext {
ExecutingContext* context{nullptr};
std::shared_ptr<ScriptPromiseResolver> promise_resolver{nullptr};
};

} // namespace

NativeLoader::NativeLoader(webf::ExecutingContext* context) : ScriptWrappable(context->ctx()) {}

static void ExecuteNativeLibrary(PluginLibraryEntryPoint entry_point,
NativeValue* lib_name,
NativeLibraryLoadContext* native_library_load_context,
void* imported_data) {
// Encounter loading error.
Expand All @@ -33,17 +25,18 @@ static void ExecuteNativeLibrary(PluginLibraryEntryPoint entry_point,
native_library_load_context->promise_resolver->Reject(exception_value);
JS_FreeValue(context->ctx(), exception_value);
} else {
auto* meta_data = new NativeLibrartMetaData{lib_name, native_library_load_context};
auto entry_data = WebFValue<ExecutingContext, ExecutingContextWebFMethods>{
native_library_load_context->context, native_library_load_context->context->publicMethodPtr(),
native_library_load_context->context->status()};
void* result = entry_point(entry_data);
void* result = entry_point(entry_data, meta_data);
native_library_load_context->context->RegisterNativeLibraryMetaData(meta_data);
native_library_load_context->context->RunRustFutureTasks();
}

delete native_library_load_context;
}

static void HandleNativeLibraryLoad(PluginLibraryEntryPoint entry_point,
NativeValue* lib_name,
void* initialize_data_ptr,
double context_id,
void* imported_data) {
Expand All @@ -55,7 +48,8 @@ static void HandleNativeLibraryLoad(PluginLibraryEntryPoint entry_point,
return;

context->dartIsolateContext()->dispatcher()->PostToJs(context->isDedicated(), context_id, ExecuteNativeLibrary,
entry_point, p_native_library_load_context, imported_data);
entry_point, lib_name, p_native_library_load_context,
imported_data);
}

ScriptPromise NativeLoader::loadNativeLibrary(const AtomicString& lib_name,
Expand All @@ -75,4 +69,4 @@ ScriptPromise NativeLoader::loadNativeLibrary(const AtomicString& lib_name,
return resolver->Promise();
}

} // namespace webf
} // namespace webf
15 changes: 15 additions & 0 deletions bridge/core/native/native_loader.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,21 @@

namespace webf {

class ScriptPromiseResolver;
class WebFNativeFunction;

struct NativeLibraryLoadContext {
ExecutingContext* context{nullptr};
std::shared_ptr<ScriptPromiseResolver> promise_resolver{nullptr};
};

struct NativeLibrartMetaData {
NativeValue* lib_name;
NativeLibraryLoadContext* load_context;
std::vector<std::shared_ptr<WebFNativeFunction>> callbacks;
std::vector<std::shared_ptr<WebFNativeFunction>> removed_callbacks;
};

class NativeLoader : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();

Expand Down
3 changes: 3 additions & 0 deletions bridge/include/plugin_api/document.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ using PublicDocumentElementFromPoint =
using PublicDocumentGetDocumentElement = WebFValue<Element, HTMLElementPublicMethods> (*)(Document*);
using PublicDocumentGetDocumentHeader = WebFValue<Element, HTMLElementPublicMethods> (*)(Document*);
using PublicDocumentGetDocumentBody = WebFValue<Element, HTMLElementPublicMethods> (*)(Document*);
using PublicDocumentClearCookie = void (*)(Document*, SharedExceptionState*);

struct DocumentPublicMethods : public WebFPublicMethods {
static WebFValue<Element, ElementPublicMethods> CreateElement(Document* document,
Expand Down Expand Up @@ -113,6 +114,7 @@ struct DocumentPublicMethods : public WebFPublicMethods {
static WebFValue<Element, HTMLElementPublicMethods> DocumentElement(Document* document);
static WebFValue<Element, HTMLElementPublicMethods> Head(Document* document);
static WebFValue<Element, HTMLElementPublicMethods> Body(Document* document);
static void ClearCookie(Document* document, SharedExceptionState* shared_exception_state);

double version{1.0};
ContainerNodePublicMethods container_node;
Expand All @@ -132,6 +134,7 @@ struct DocumentPublicMethods : public WebFPublicMethods {
PublicDocumentGetDocumentElement document_get_document_element{DocumentElement};
PublicDocumentGetDocumentHeader document_get_document_header{Head};
PublicDocumentGetDocumentBody document_get_document_body{Body};
PublicDocumentClearCookie document_clear_cookie{ClearCookie};
};

} // namespace webf
Expand Down
30 changes: 22 additions & 8 deletions bridge/include/plugin_api/executing_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#define WEBF_CORE_RUST_API_EXECUTING_CONTEXT_H_

#include "core/native/native_function.h"
#include "core/native/native_loader.h"
#include "document.h"
#include "exception_state.h"
#include "foundation/native_value.h"
Expand All @@ -21,6 +22,7 @@ using PublicContextGetDocument = WebFValue<Document, DocumentPublicMethods> (*)(
using PublicContextGetWindow = WebFValue<Window, WindowPublicMethods> (*)(ExecutingContext*);
using PublicContextGetExceptionState = WebFValue<SharedExceptionState, ExceptionStatePublicMethods> (*)();
using PublicFinishRecordingUIOperations = void (*)(ExecutingContext* context);
using PublicWebFSyncBuffer = void (*)(ExecutingContext* context);
using PublicWebFInvokeModule = NativeValue (*)(ExecutingContext*, const char*, const char*, SharedExceptionState*);
using PublicWebFInvokeModuleWithParams =
NativeValue (*)(ExecutingContext*, const char*, const char*, NativeValue*, SharedExceptionState*);
Expand All @@ -41,17 +43,22 @@ using PublicContextSetInterval = int32_t (*)(ExecutingContext*,
SharedExceptionState*);
using PublicContextClearTimeout = void (*)(ExecutingContext*, int32_t, SharedExceptionState*);
using PublicContextClearInterval = void (*)(ExecutingContext*, int32_t, SharedExceptionState*);
using PublicContextSetRunRustFutureTasks = void (*)(ExecutingContext*,
WebFNativeFunctionContext*,
SharedExceptionState*);

using PublicContextAddRustFutureTask = void (*)(ExecutingContext*,
WebFNativeFunctionContext*,
NativeLibrartMetaData*,
SharedExceptionState*);
using PublicContextRemoveRustFutureTask = void (*)(ExecutingContext*,
WebFNativeFunctionContext*,
NativeLibrartMetaData*,
SharedExceptionState*);
// Memory aligned and readable from WebF side.
// Only C type member can be included in this class, any C++ type and classes can is not allowed to use here.
struct ExecutingContextWebFMethods {
static WebFValue<Document, DocumentPublicMethods> document(ExecutingContext* context);
static WebFValue<Window, WindowPublicMethods> window(ExecutingContext* context);
static WebFValue<SharedExceptionState, ExceptionStatePublicMethods> CreateExceptionState();
static void FinishRecordingUIOperations(ExecutingContext* context);
static void WebFSyncBuffer(ExecutingContext* context);
static NativeValue WebFInvokeModule(ExecutingContext* context,
const char* module_name,
const char* method,
Expand Down Expand Up @@ -80,15 +87,21 @@ struct ExecutingContextWebFMethods {
static void ClearInterval(ExecutingContext* context,
int32_t interval_id,
SharedExceptionState* shared_exception_state);
static void SetRunRustFutureTasks(ExecutingContext* context,
WebFNativeFunctionContext* callback_context,
SharedExceptionState* shared_exception_state);
static void AddRustFutureTask(ExecutingContext* context,
WebFNativeFunctionContext* callback_context,
NativeLibrartMetaData* meta_data,
SharedExceptionState* shared_exception_state);
static void RemoveRustFutureTask(ExecutingContext* context,
WebFNativeFunctionContext* callback_context,
NativeLibrartMetaData* meta_data,
SharedExceptionState* shared_exception_state);

double version{1.0};
PublicContextGetDocument context_get_document{document};
PublicContextGetWindow context_get_window{window};
PublicContextGetExceptionState context_get_exception_state{CreateExceptionState};
PublicFinishRecordingUIOperations context_finish_recording_ui_operations{FinishRecordingUIOperations};
PublicWebFSyncBuffer context_webf_sync_buffer{WebFSyncBuffer};
PublicWebFInvokeModule context_webf_invoke_module{WebFInvokeModule};
PublicWebFInvokeModuleWithParams context_webf_invoke_module_with_params{WebFInvokeModuleWithParams};
PublicWebFInvokeModuleWithParamsAndCallback context_webf_invoke_module_with_params_and_callback{
Expand All @@ -98,7 +111,8 @@ struct ExecutingContextWebFMethods {
PublicContextSetInterval context_set_interval{SetInterval};
PublicContextClearTimeout context_clear_timeout{ClearTimeout};
PublicContextClearInterval context_clear_interval{ClearInterval};
PublicContextSetRunRustFutureTasks context_set_run_rust_future_tasks{SetRunRustFutureTasks};
PublicContextAddRustFutureTask context_add_rust_future_task{AddRustFutureTask};
PublicContextRemoveRustFutureTask context_remove_rust_future_task{RemoveRustFutureTask};
};

} // namespace webf
Expand Down
Loading
Loading