Open linsmod opened 3 months ago
@linsmod
The binding from C++ to Dart with FormData class finished
The binding from C++ to Dart with FormData class finished
Got! Awesome job!
The implementation of Chrome's FormData support is an good reference.
绑定到Dart的代码,是否可以通过直接传递entries的引用/指针来简化?因为FormData已经在C++层面实现了,如果再通过dart实现就重复了。
我就想投机取巧一下: 比如C++一边createBindingObject传递entries_:
FormData::FormData(JSContext* ctx) : BindingObject(ctx) {
GetExecutingContext()->dartMethodPtr()->createBindingObject(GetExecutingContext()->isDedicated(),
GetExecutingContext()->contextId(), bindingObject(),
CreateBindingObjectType::kCreateFormData, &entries_, 0);
}
private:
std::vector<std::shared_ptr<FormDataEntry>> entries_;
Dart一边在某种构造函数内把C++传递的entries_指针取出来, 伪代码如下:
class FormData extends DynamicBindingObject {
List<FormDataEntry> entries = [];
FormData(BindingContext context, List<dynamic> domMatrixInit): super(context){
entries=context.args;
}
关于创建绑定,还有一个疑问。我看到有一个创建绑定的初始化函数,但是没有看到被调用方的具体实现,只有测试代码中有一个空函数, 从Dart创建NativeBindingObject不是必要的吗?: void TEST_CreateBindingObject(double context_id, void native_binding_object, int32_t type, void args, int32_t argc) {}
绑定到Dart的代码,是否可以通过直接传递entries的引用/指针来简化?因为FormData已经在C++层面实现了,如果再通过dart实现就重复了。
我就想投机取巧一下: 比如C++一边createBindingObject传递entries_:
FormData::FormData(JSContext* ctx) : BindingObject(ctx) { GetExecutingContext()->dartMethodPtr()->createBindingObject(GetExecutingContext()->isDedicated(), GetExecutingContext()->contextId(), bindingObject(), CreateBindingObjectType::kCreateFormData, &entries_, 0); } private: std::vector<std::shared_ptr<FormDataEntry>> entries_;
Dart一边在某种构造函数内把C++传递的entries_指针取出来, 伪代码如下:
class FormData extends DynamicBindingObject { List<FormDataEntry> entries = []; FormData(BindingContext context, List<dynamic> domMatrixInit): super(context){ entries=context.args; }
关于创建绑定,还有一个疑问。我看到有一个创建绑定的初始化函数,但是没有看到被调用方的具体实现,只有测试代码中有一个空函数, 从Dart创建NativeBindingObject不是必要的吗?: void TEST_CreateBindingObject(double context_id, void native_binding_object, int32_t type, void args, int32_t argc) {}
这么搞的话,问题可多了。跨线程问题,跨 VM 内存管理,Dart FFI 本身的性能问题,内存回收问题。
别瞎想了,再写一遍吧
js 里面 new FormData()并添加数据, 在 dart 里面成了空的Map。
readonly forEach: JSArrayProtoMethod; 被改成这样了之后我就不会了,没有找到任何具体实现例子。
我理解如果要实现JSArrayProtoMethod是缺少一个Iterator的模板的,如果有那个模板,那么代码生成那里改一下,让生成的代码去调用目标的Converter::ToIterator,是不是就行了。
因为我现在想在js那边直接把FormData转成普通JS对象,也就是dart里面的Map,为什么想这么做?因为js传递的FormData在fetch.dart里面就变成了一个空Map,即使js那边添加了数据,在Dart那边看也是空的,那不如将计就计直接用JS对象{}。如果要转{}就需要遍历内容,但因为现在改成了readonly forEach: JSArrayProtoMethod; 我在js那边forEach就取不到内容,空空如也。
(PS:注意到你们似乎在移植blink,那个能搞完,就省很多实现Web标准的功夫了)
估计哪里搞错了,预期 new FormData 传到 dart 是会变成昨天搞的 FormData Dart 对象的,我来看看为啥
readonly forEach: JSArrayProtoMethod; 被改成这样了之后我就不会了,没有找到任何具体实现例子。
我理解如果要实现JSArrayProtoMethod是缺少一个Iterator的模板的,如果有那个模板,那么代码生成那里改一下,让生成的代码去调用目标的Converter::ToIterator,是不是就行了。
因为我现在想在js那边直接把FormData转成普通JS对象,也就是dart里面的Map,为什么想这么做?因为js传递的FormData在fetch.dart里面就变成了一个空Map,即使js那边添加了数据,在Dart那边看也是空的,那不如将计就计直接用JS对象{}。如果要转{}就需要遍历内容,但因为现在改成了readonly forEach: JSArrayProtoMethod; 我在js那边forEach就取不到内容,空空如也。
(PS:注意到你们似乎在移植blink,那个能搞完,就省很多实现Web标准的功夫了)
你说的没错,是得单独写个 iterator 才能完整实现这个。readonly forEach: JSArrayProtoMethod;
依赖了 quickjs 自身的特定,类数组的对象能 work,但是对于 FormData 就不凑效了
@linsmod 重写了 FormData,并重新实现了 Iterator 功能,现在 Foreach 和返回 interator 的函数都 work 了。
估计哪里搞错了,预期 new FormData 传到 dart 是会变成昨天搞的 FormData Dart 对象的,我来看看为啥
现在把 formData 传给 fetch API 已经能在 C++ 那边收到了,接下来就是把这个 FormData 当成指针传递给 Dart。
绑定到Dart的代码,是否可以通过直接传递entries的引用/指针来简化?因为FormData已经在C++层面实现了,如果再通过dart实现就重复了。
这个我想了一下,是可以通过一种简单的方式实现的,Dart FormData 只需要实现一个功能 —— 反向通过 Dart FFI 把 FormData 的 bytes 读回 Dart 环境,然后再这个 bytes 传给 http 模块,这样就搞定了。
所以接下来的任务是:
@linsmod 接下来就交给你了,我得去搞别人的事情了,加油。
出差了,得过段时间。
编译不过,好像是改动了这里原因:
NativeValue* invokeModule(bool is_dedicated,
void* callback_context,
double context_id,
int64_t profile_link_id,
SharedNativeString* moduleName,
SharedNativeString* method,
NativeValue* params,
uint32_t argc,
AsyncModuleCallback callback);
dart_methods.h:143:16: note: candidate expects 9 arguments, 8 provided
/home/wulin/webf_copy/bridge/core/frame/module_manager.cc:186:52: error: no matching function for call to ‘webf::DartMethodPointer::invokeModule(bool, std::nullptr_t, double, int64_t, std::unique_ptr<webf::SharedNativeString>::pointer, std::unique_ptr<webf::SharedNativeString>::pointer, webf::NativeValue*, webf::NativeValue* (&)(void*, double, const char*, webf::NativeValue*, Dart_Handle, webf::InvokeModuleResultCallback))’
186 | result = context->dartMethodPtr()->invokeModule(
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
187 | context->isDedicated(), nullptr, context->contextId(), context->dartIsolateContext()->profiler()->link_id(),
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
188 | module_name_string.get(), method_name_string.get(), ¶ms, handleInvokeModuleUnexpectedCallback);
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /home/wulin/webf_copy/bridge/core/dart_isolate_context.h:11,
from /home/wulin/webf_copy/bridge/core/executing_context.h:26,
from /home/wulin/webf_copy/bridge/bindings/qjs/qjs_interface_bridge.h:9,
from /home/wulin/webf_copy/bridge/bindings/qjs/generated_code_helper.h:11,
from /home/wulin/webf_copy/bridge/out/qjs_module_manager_options.h:9,
from /home/wulin/webf_copy/bridge/core/frame/module_manager.h:12,
from /home/wulin/webf_copy/bridge/core/frame/module_manager.cc:5:
编译不过,好像是改动了这里原因:
修好了
@linsmod 可以留个联系方式吗,我开个会议给你讲讲后面怎么搞。 如果可以的话,可以把微信二维码发我邮箱一下
dongtiangche@outlook.com
In this pull request, FormData Web API and it's qjs binding is implmented.
For prototype, see below:
Todo: Making FetchModule support FormData body.
Todo: Should using fileName parameter in append/set implementation, we do NOT using it currently.