Skip to content

Commit

Permalink
wip2
Browse files Browse the repository at this point in the history
  • Loading branch information
LeuisKen committed Dec 28, 2024
1 parent f6beb4f commit 3a9020a
Show file tree
Hide file tree
Showing 8 changed files with 89 additions and 46 deletions.
16 changes: 7 additions & 9 deletions bridge/core/executing_context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -393,15 +393,13 @@ void ExecutingContext::EnqueueMicrotask(MicrotaskCallback callback, void* data)
}

void ExecutingContext::DrainWebFNativeFutures() {
for (auto it = native_future_tasks_.begin(); it != native_future_tasks_.end();) {
const WebFNativeFutureData* future_data = *it;
int result = future_data->poll_fn(future_data->future_ptr);
if (result == 0) {
it = native_future_tasks_.erase(it);
delete future_data;
} else {
++it;
}
if (native_future_tasks_.empty()) {
return;
}

for (auto it = native_future_tasks_.begin(); it != native_future_tasks_.end(); ++it) {
WebFNativeFutureData* future_data = *it;
int result = future_data->poll_fn(future_data);
}
}

Expand Down
4 changes: 2 additions & 2 deletions bridge/core/executing_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,13 @@ class ScriptWrappable;

using JSExceptionHandler = std::function<void(ExecutingContext* context, const char* message)>;
using MicrotaskCallback = void (*)(void* data);
using FuturePollFn = int (*)(void*);
using FuturePollFn = int (*)(WebFNativeFutureData*);

bool isContextValid(double contextId);

struct WebFNativeFutureData {
void* future_ptr;
FuturePollFn poll_fn;
void* future_ptr;
};

// An environment in which script can execute. This class exposes the common
Expand Down
3 changes: 2 additions & 1 deletion bridge/core/native/native_loader.cc
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ static void ExecuteNativeLibrary(PluginLibraryEntryPoint entry_point,
native_library_load_context->context, native_library_load_context->context->publicMethodPtr(),
native_library_load_context->context->status()};
void* result = entry_point(entry_data);
native_library_load_context->context->DrainWebFNativeFutures();
}

delete native_library_load_context;
Expand Down Expand Up @@ -74,4 +75,4 @@ ScriptPromise NativeLoader::loadNativeLibrary(const AtomicString& lib_name,
return resolver->Promise();
}

} // namespace webf
} // namespace webf
12 changes: 6 additions & 6 deletions bridge/rusty_webf_sys/src/exception_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,9 @@ impl ExceptionState {
}
}
}

impl Drop for ExceptionState {
fn drop(&mut self) {
safe_free_cpp_ptr(self.ptr)
}
}
//
// impl Drop for ExceptionState {
// fn drop(&mut self) {
// safe_free_cpp_ptr(self.ptr)
// }
// }
20 changes: 14 additions & 6 deletions bridge/rusty_webf_sys/src/executing_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* Copyright (C) 2022-present The WebF authors. All rights reserved.
*/

use std::{ffi::*, future::{self, Future}, pin::Pin};
use std::{ffi::*, future::{self, Future}, pin::Pin, task::Poll};
use native_value::NativeValue;

use crate::*;
Expand Down Expand Up @@ -260,14 +260,22 @@ impl ExecutingContext {
}
}

pub fn spawn_local<F>(&self, future: F)
pub fn spawn_local<F>(&self, mut future: Pin<Box<F>>)
where F: Future<Output = ()> + 'static,
{
let future_pin = Box::pin(future);
let future_ptr = unsafe { Box::into_raw(Box::new(future_pin)) };
let poll_future_callback = Box::new(move || {
let mut future_pin = Box::pin(future);
let mut context = get_future_context();

match future_pin.as_mut().poll(&mut context) {
Poll::Ready(()) => 1,
Poll::Pending => 0,
}
});

let data = Box::new(WebFNativeFutureData {
ptr: future_ptr,
poll_fn: poll_webf_native_future
poll_fn: poll_webf_native_future,
callback: poll_future_callback,
});
let data_ptr = Box::into_raw(data);

Expand Down
40 changes: 22 additions & 18 deletions bridge/rusty_webf_sys/src/webf_future.rs
Original file line number Diff line number Diff line change
@@ -1,35 +1,39 @@
#![feature(noop_waker)]

use std::ffi::*;
use std::rc::Rc;
use std::{ffi::*, future};
use std::future::Future;
use std::task::{Context, Poll, Waker};
use std::pin::Pin;
use std::sync::{Arc, Mutex};
use std::cell::RefCell;

use crate::OpaquePtr;

pub type WebFNativeFutureCallback = Box<dyn FnOnce() -> i32>;

#[repr(C)]
pub struct WebFNativeFutureData<F>
where F: Future<Output = ()> + 'static,
{
pub ptr: *mut Pin<Box<F>>,
pub poll_fn: extern "C" fn(ptr: *mut c_void) -> c_int,
pub struct WebFNativeFutureData {
pub poll_fn: extern "C" fn(ptr: *const OpaquePtr) -> c_int,
pub callback: WebFNativeFutureCallback,
}

pub extern "C" fn poll_webf_native_future(ptr: *mut c_void) -> c_int {
let mut future = unsafe {
Box::from_raw(ptr as *mut Pin<Box<dyn Future<Output = ()>>>)
pub extern "C" fn poll_webf_native_future(ptr: *const OpaquePtr) -> c_int {
let native_future_data = unsafe {
(ptr as *mut WebFNativeFutureData).read()
};
let future_ptr = future.as_mut();
let callback = native_future_data.callback;
callback()
}

pub fn get_future_context<'a>() -> Context<'a> {
let waker = Waker::noop();
let mut context = Context::from_waker(&waker);
match future_ptr.as_mut().poll(&mut context) {
Poll::Ready(()) => 1,
Poll::Pending => 0,
}
context
}

pub struct WebFNativeFuture<T> {
inner: Arc<Mutex<Inner<T>>>,
inner: Rc<RefCell<Inner<T>>>,
}

struct Inner<T> {
Expand All @@ -40,15 +44,15 @@ struct Inner<T> {
impl<T> WebFNativeFuture<T> {
pub fn new() -> WebFNativeFuture<T> {
WebFNativeFuture {
inner: Arc::new(Mutex::new(Inner {
inner: Rc::new(RefCell::new(Inner {
waker: None,
result: None,
})),
}
}

pub fn set_result(&self, result: Result<Option<T>, String>) {
let mut inner = self.inner.lock().unwrap();
let mut inner = self.inner.borrow_mut();
inner.result = Some(result);
if let Some(waker) = inner.waker.take() {
waker.wake();
Expand All @@ -63,7 +67,7 @@ where
type Output = Result<Option<T>, String>;

fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
let mut inner = self.inner.lock().unwrap();
let mut inner = self.inner.borrow_mut();

if let Some(result) = inner.result.take() {
Poll::Ready(result)
Expand Down
30 changes: 30 additions & 0 deletions webf/example/rust_builder/rust/a.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
function longestIncreasingSubsequence(nums) {
const dp = Array(nums.length).fill(1); // dp数组记录每个位置的LIS长度
const prev = Array(nums.length).fill(-1); // prev数组记录每个位置的前一个索引
let maxIndex = 0; // 用于追踪最长序列的结束索引

for (let i = 1; i < nums.length; i++) {
for (let j = 0; j < i; j++) {
if (nums[i] > nums[j] && dp[i] < dp[j] + 1) {
dp[i] = dp[j] + 1;
prev[i] = j; // 更新前一个元素索引
}
}
if (dp[i] > dp[maxIndex]) {
maxIndex = i; // 更新最长序列的结束位置
}
}

// 回溯构造LIS
const lis = [];
while (maxIndex !== -1) {
lis.unshift(nums[maxIndex]);
maxIndex = prev[maxIndex];
}

return lis;
}

// 测试
const nums = [5, 19, 5, 81, 50, 28, 29, 1, 83, 23];
console.log(longestIncreasingSubsequence(nums)); // 输出 [2, 3, 7, 101]
10 changes: 6 additions & 4 deletions webf/example/rust_builder/rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,12 @@ pub extern "C" fn init_webf_app(handle: RustValue<ExecutingContextRustMethods>)

local_storage.clear(&exception_state);

let async_storage = context.async_storage();
let exception_state2 = context.create_exception_state();
let context2 = context.clone();

context.spawn_local(async move {
context.spawn_local(Box::pin(async move {
let context = context2.clone();
let async_storage = context.async_storage();
let exception_state2 = context.create_exception_state();
let set_result = async_storage.set_item("a", "b", &exception_state2).await;
match set_result {
Ok(_) => {
Expand All @@ -58,7 +60,7 @@ pub extern "C" fn init_webf_app(handle: RustValue<ExecutingContextRustMethods>)
println!("Async Storage Set Item Failed: {:?}", err);
}
}
});
}));

let timer_callback = Box::new(move || {
println!("Timer Callback");
Expand Down

0 comments on commit 3a9020a

Please sign in to comment.