AK+LibWeb: Centralize FFI helper functions
This commit creates a central FFIHelpers.h header which implements common conversions from FFI.
This commit is contained in:
parent
7752bc5915
commit
520a7c8ebd
7 changed files with 79 additions and 60 deletions
|
|
@ -7,6 +7,7 @@ set(SOURCES
|
||||||
ConstrainedStream.cpp
|
ConstrainedStream.cpp
|
||||||
CountingStream.cpp
|
CountingStream.cpp
|
||||||
Error.cpp
|
Error.cpp
|
||||||
|
FFIHelpers.cpp
|
||||||
FlyString.cpp
|
FlyString.cpp
|
||||||
Format.cpp
|
Format.cpp
|
||||||
GenericLexer.cpp
|
GenericLexer.cpp
|
||||||
|
|
|
||||||
34
AK/FFIHelpers.cpp
Normal file
34
AK/FFIHelpers.cpp
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2026-present, the Ladybird developers.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <AK/FFIHelpers.h>
|
||||||
|
#include <AK/FlyString.h>
|
||||||
|
#include <AK/Forward.h>
|
||||||
|
#include <AK/String.h>
|
||||||
|
#include <AK/StringView.h>
|
||||||
|
#include <AK/Try.h>
|
||||||
|
|
||||||
|
namespace AK {
|
||||||
|
|
||||||
|
FlyString ffi_fly_string(u8 const* ptr, size_t len)
|
||||||
|
{
|
||||||
|
return MUST(FlyString::from_utf8(ffi_string_view(ptr, len)));
|
||||||
|
}
|
||||||
|
|
||||||
|
String ffi_string(u8 const* ptr, size_t len)
|
||||||
|
{
|
||||||
|
return MUST(String::from_utf8(ffi_string_view(ptr, len)));
|
||||||
|
}
|
||||||
|
|
||||||
|
StringView ffi_string_view(u8 const* ptr, size_t len)
|
||||||
|
{
|
||||||
|
// NOTE: A zero length C string is valid
|
||||||
|
if (ptr == nullptr)
|
||||||
|
return {};
|
||||||
|
return { ptr, len };
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
25
AK/FFIHelpers.h
Normal file
25
AK/FFIHelpers.h
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2026-present, the Ladybird developers.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <AK/Forward.h>
|
||||||
|
|
||||||
|
namespace AK {
|
||||||
|
|
||||||
|
FlyString ffi_fly_string(u8 const* ptr, size_t len);
|
||||||
|
|
||||||
|
String ffi_string(u8 const* ptr, size_t len);
|
||||||
|
|
||||||
|
StringView ffi_string_view(u8 const* ptr, size_t len);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef USING_AK_GLOBALLY
|
||||||
|
using AK::ffi_fly_string;
|
||||||
|
using AK::ffi_string;
|
||||||
|
using AK::ffi_string_view;
|
||||||
|
#endif
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <AK/FFIHelpers.h>
|
||||||
#include <AK/StringBuilder.h>
|
#include <AK/StringBuilder.h>
|
||||||
#include <AK/Utf8View.h>
|
#include <AK/Utf8View.h>
|
||||||
#include <LibTextCodec/Decoder.h>
|
#include <LibTextCodec/Decoder.h>
|
||||||
|
|
@ -88,20 +89,6 @@ static String decode_and_filter_code_points(StringView input, StringView encodin
|
||||||
return builder.to_string_without_validation();
|
return builder.to_string_without_validation();
|
||||||
}
|
}
|
||||||
|
|
||||||
static String string_from_ffi_bytes(u8 const* bytes, size_t length)
|
|
||||||
{
|
|
||||||
if (length == 0)
|
|
||||||
return {};
|
|
||||||
return String::from_utf8_without_validation({ bytes, length });
|
|
||||||
}
|
|
||||||
|
|
||||||
static FlyString fly_string_from_ffi_bytes(u8 const* bytes, size_t length)
|
|
||||||
{
|
|
||||||
if (length == 0)
|
|
||||||
return {};
|
|
||||||
return FlyString::from_utf8_without_validation({ bytes, length });
|
|
||||||
}
|
|
||||||
|
|
||||||
static Number::Type css_number_type_from_ffi(FFI::CssNumberType number_type)
|
static Number::Type css_number_type_from_ffi(FFI::CssNumberType number_type)
|
||||||
{
|
{
|
||||||
switch (number_type) {
|
switch (number_type) {
|
||||||
|
|
@ -122,8 +109,8 @@ static Token::Position position_from_ffi(size_t line, size_t column)
|
||||||
|
|
||||||
Token RustTokenizer::token_from_ffi(FFI::CssToken const& ffi_token)
|
Token RustTokenizer::token_from_ffi(FFI::CssToken const& ffi_token)
|
||||||
{
|
{
|
||||||
auto original_source_text = string_from_ffi_bytes(ffi_token.original_source_ptr, ffi_token.original_source_len);
|
auto original_source_text = ffi_string(ffi_token.original_source_ptr, ffi_token.original_source_len);
|
||||||
auto payload = fly_string_from_ffi_bytes(ffi_token.value_ptr, ffi_token.value_len);
|
auto payload = ffi_fly_string(ffi_token.value_ptr, ffi_token.value_len);
|
||||||
|
|
||||||
Token token;
|
Token token;
|
||||||
switch (ffi_token.token_type) {
|
switch (ffi_token.token_type) {
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
#include <AK/AnyOf.h>
|
#include <AK/AnyOf.h>
|
||||||
#include <AK/Debug.h>
|
#include <AK/Debug.h>
|
||||||
|
#include <AK/FFIHelpers.h>
|
||||||
#include <LibTextCodec/Decoder.h>
|
#include <LibTextCodec/Decoder.h>
|
||||||
#include <LibWeb/Bindings/ExceptionOrUtils.h>
|
#include <LibWeb/Bindings/ExceptionOrUtils.h>
|
||||||
#include <LibWeb/Bindings/MainThreadVM.h>
|
#include <LibWeb/Bindings/MainThreadVM.h>
|
||||||
|
|
@ -1732,27 +1733,10 @@ void HTMLParser::abort()
|
||||||
m_aborted = true;
|
m_aborted = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static StringView html_parser_ffi_string_view(u8 const* ptr, size_t len)
|
|
||||||
{
|
|
||||||
if (ptr == nullptr || len == 0)
|
|
||||||
return {};
|
|
||||||
return { ptr, len };
|
|
||||||
}
|
|
||||||
|
|
||||||
static FlyString fly_string_from_html_parser_ffi(u8 const* ptr, size_t len)
|
|
||||||
{
|
|
||||||
return MUST(FlyString::from_utf8(html_parser_ffi_string_view(ptr, len)));
|
|
||||||
}
|
|
||||||
|
|
||||||
static String string_from_html_parser_ffi(u8 const* ptr, size_t len)
|
|
||||||
{
|
|
||||||
return MUST(String::from_utf8(html_parser_ffi_string_view(ptr, len)));
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" void ladybird_html_parser_log_parse_error(void* parser, u8 const* message_ptr, size_t message_len)
|
extern "C" void ladybird_html_parser_log_parse_error(void* parser, u8 const* message_ptr, size_t message_len)
|
||||||
{
|
{
|
||||||
(void)parser_from_html_parser_ffi(parser);
|
(void)parser_from_html_parser_ffi(parser);
|
||||||
dbgln_if(HTML_PARSER_DEBUG, "Rust parser parse error: {}", html_parser_ffi_string_view(message_ptr, message_len));
|
dbgln_if(HTML_PARSER_DEBUG, "Rust parser parse error: {}", ffi_string_view(message_ptr, message_len));
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void ladybird_html_parser_stop_parsing(void* parser)
|
extern "C" void ladybird_html_parser_stop_parsing(void* parser)
|
||||||
|
|
@ -1784,7 +1768,7 @@ static Optional<FlyString> namespace_from_html_parser_ffi(RustFfiHtmlNamespace n
|
||||||
case RustFfiHtmlNamespace::Other:
|
case RustFfiHtmlNamespace::Other:
|
||||||
if (namespace_uri_len == 0)
|
if (namespace_uri_len == 0)
|
||||||
return {};
|
return {};
|
||||||
return fly_string_from_html_parser_ffi(namespace_uri_ptr, namespace_uri_len);
|
return ffi_fly_string(namespace_uri_ptr, namespace_uri_len);
|
||||||
}
|
}
|
||||||
VERIFY_NOT_REACHED();
|
VERIFY_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
|
@ -1896,16 +1880,16 @@ extern "C" size_t ladybird_html_parser_create_document_type(void* parser, u8 con
|
||||||
{
|
{
|
||||||
auto& html_parser = parser_from_html_parser_ffi(parser);
|
auto& html_parser = parser_from_html_parser_ffi(parser);
|
||||||
auto document_type = html_parser.document().realm().create<DOM::DocumentType>(html_parser.document());
|
auto document_type = html_parser.document().realm().create<DOM::DocumentType>(html_parser.document());
|
||||||
document_type->set_name(string_from_html_parser_ffi(name_ptr, name_len));
|
document_type->set_name(ffi_string(name_ptr, name_len));
|
||||||
document_type->set_public_id(string_from_html_parser_ffi(public_id_ptr, public_id_len));
|
document_type->set_public_id(ffi_string(public_id_ptr, public_id_len));
|
||||||
document_type->set_system_id(string_from_html_parser_ffi(system_id_ptr, system_id_len));
|
document_type->set_system_id(ffi_string(system_id_ptr, system_id_len));
|
||||||
return reinterpret_cast<size_t>(document_type.ptr());
|
return reinterpret_cast<size_t>(document_type.ptr());
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" size_t ladybird_html_parser_create_comment(void* parser, u8 const* data_ptr, size_t data_len)
|
extern "C" size_t ladybird_html_parser_create_comment(void* parser, u8 const* data_ptr, size_t data_len)
|
||||||
{
|
{
|
||||||
auto& html_parser = parser_from_html_parser_ffi(parser);
|
auto& html_parser = parser_from_html_parser_ffi(parser);
|
||||||
auto comment = html_parser.document().realm().create<DOM::Comment>(html_parser.document(), Utf16String::from_utf8(string_from_html_parser_ffi(data_ptr, data_len)));
|
auto comment = html_parser.document().realm().create<DOM::Comment>(html_parser.document(), Utf16String::from_utf8(ffi_string(data_ptr, data_len)));
|
||||||
return reinterpret_cast<size_t>(comment.ptr());
|
return reinterpret_cast<size_t>(comment.ptr());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1915,7 +1899,7 @@ extern "C" void ladybird_html_parser_insert_text(size_t parent, size_t before, u
|
||||||
if (parent_node.is_document())
|
if (parent_node.is_document())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto data = Utf16String::from_utf8(string_from_html_parser_ffi(data_ptr, data_len));
|
auto data = Utf16String::from_utf8(ffi_string(data_ptr, data_len));
|
||||||
if (before) {
|
if (before) {
|
||||||
auto& before_node = node_from_html_parser_ffi(before);
|
auto& before_node = node_from_html_parser_ffi(before);
|
||||||
if (auto* previous_text = as_if<DOM::Text>(before_node.previous_sibling())) {
|
if (auto* previous_text = as_if<DOM::Text>(before_node.previous_sibling())) {
|
||||||
|
|
@ -1939,10 +1923,10 @@ extern "C" void ladybird_html_parser_insert_text(size_t parent, size_t before, u
|
||||||
extern "C" void ladybird_html_parser_add_missing_attribute(size_t element, u8 const* local_name_ptr, size_t local_name_len, u8 const* value_ptr, size_t value_len)
|
extern "C" void ladybird_html_parser_add_missing_attribute(size_t element, u8 const* local_name_ptr, size_t local_name_len, u8 const* value_ptr, size_t value_len)
|
||||||
{
|
{
|
||||||
auto& dom_element = as<DOM::Element>(node_from_html_parser_ffi(element));
|
auto& dom_element = as<DOM::Element>(node_from_html_parser_ffi(element));
|
||||||
auto local_name = fly_string_from_html_parser_ffi(local_name_ptr, local_name_len);
|
auto local_name = ffi_fly_string(local_name_ptr, local_name_len);
|
||||||
if (dom_element.has_attribute(local_name))
|
if (dom_element.has_attribute(local_name))
|
||||||
return;
|
return;
|
||||||
dom_element.append_attribute(local_name, string_from_html_parser_ffi(value_ptr, value_len));
|
dom_element.append_attribute(local_name, ffi_string(value_ptr, value_len));
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void ladybird_html_parser_remove_node(size_t node)
|
extern "C" void ladybird_html_parser_remove_node(size_t node)
|
||||||
|
|
@ -1986,19 +1970,19 @@ extern "C" size_t ladybird_html_parser_parent_node(size_t node)
|
||||||
extern "C" size_t ladybird_html_parser_create_element(void* parser, size_t intended_parent, RustFfiHtmlNamespace namespace_, u8 const* namespace_uri_ptr, size_t namespace_uri_len, u8 const* local_name_ptr, size_t local_name_len, RustFfiHtmlParserAttribute const* attributes, size_t attribute_count, bool had_duplicate_attribute, size_t form_element, bool has_template_element_on_stack)
|
extern "C" size_t ladybird_html_parser_create_element(void* parser, size_t intended_parent, RustFfiHtmlNamespace namespace_, u8 const* namespace_uri_ptr, size_t namespace_uri_len, u8 const* local_name_ptr, size_t local_name_len, RustFfiHtmlParserAttribute const* attributes, size_t attribute_count, bool had_duplicate_attribute, size_t form_element, bool has_template_element_on_stack)
|
||||||
{
|
{
|
||||||
auto& html_parser = parser_from_html_parser_ffi(parser);
|
auto& html_parser = parser_from_html_parser_ffi(parser);
|
||||||
auto local_name = fly_string_from_html_parser_ffi(local_name_ptr, local_name_len);
|
auto local_name = ffi_fly_string(local_name_ptr, local_name_len);
|
||||||
auto token = HTMLToken::make_start_tag(local_name);
|
auto token = HTMLToken::make_start_tag(local_name);
|
||||||
|
|
||||||
for (size_t i = 0; i < attribute_count; ++i) {
|
for (size_t i = 0; i < attribute_count; ++i) {
|
||||||
auto const& attribute = attributes[i];
|
auto const& attribute = attributes[i];
|
||||||
Optional<FlyString> prefix;
|
Optional<FlyString> prefix;
|
||||||
if (attribute.prefix_len != 0)
|
if (attribute.prefix_len != 0)
|
||||||
prefix = fly_string_from_html_parser_ffi(attribute.prefix_ptr, attribute.prefix_len);
|
prefix = ffi_fly_string(attribute.prefix_ptr, attribute.prefix_len);
|
||||||
HTMLToken::Attribute token_attribute;
|
HTMLToken::Attribute token_attribute;
|
||||||
token_attribute.prefix = move(prefix);
|
token_attribute.prefix = move(prefix);
|
||||||
token_attribute.local_name = fly_string_from_html_parser_ffi(attribute.local_name_ptr, attribute.local_name_len);
|
token_attribute.local_name = ffi_fly_string(attribute.local_name_ptr, attribute.local_name_len);
|
||||||
token_attribute.namespace_ = attribute_namespace_from_html_parser_ffi(attribute.namespace_);
|
token_attribute.namespace_ = attribute_namespace_from_html_parser_ffi(attribute.namespace_);
|
||||||
token_attribute.value = string_from_html_parser_ffi(attribute.value_ptr, attribute.value_len);
|
token_attribute.value = ffi_string(attribute.value_ptr, attribute.value_len);
|
||||||
token.add_attribute(move(token_attribute));
|
token.add_attribute(move(token_attribute));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <AK/Debug.h>
|
#include <AK/Debug.h>
|
||||||
|
#include <AK/FFIHelpers.h>
|
||||||
#include <AK/FlyString.h>
|
#include <AK/FlyString.h>
|
||||||
#include <AK/StringBuilder.h>
|
#include <AK/StringBuilder.h>
|
||||||
#include <AK/Utf8View.h>
|
#include <AK/Utf8View.h>
|
||||||
|
|
@ -26,13 +27,6 @@ static Vector<u32> code_points_from_string(String const& string)
|
||||||
return code_points;
|
return code_points;
|
||||||
}
|
}
|
||||||
|
|
||||||
static StringView ffi_string_view(u8 const* ptr, size_t len)
|
|
||||||
{
|
|
||||||
if (ptr == nullptr || len == 0)
|
|
||||||
return {};
|
|
||||||
return { ptr, len };
|
|
||||||
}
|
|
||||||
|
|
||||||
static RustFfiTokenizerHandle* create_tokenizer_from_utf8(StringView utf8_bytes)
|
static RustFfiTokenizerHandle* create_tokenizer_from_utf8(StringView utf8_bytes)
|
||||||
{
|
{
|
||||||
auto* bytes = reinterpret_cast<u8 const*>(utf8_bytes.characters_without_null_termination());
|
auto* bytes = reinterpret_cast<u8 const*>(utf8_bytes.characters_without_null_termination());
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <AK/Assertions.h>
|
#include <AK/Assertions.h>
|
||||||
|
#include <AK/FFIHelpers.h>
|
||||||
#include <LibJS/Runtime/Realm.h>
|
#include <LibJS/Runtime/Realm.h>
|
||||||
#include <LibWeb/DOM/Document.h>
|
#include <LibWeb/DOM/Document.h>
|
||||||
#include <LibWeb/Fetch/Fetching/Fetching.h>
|
#include <LibWeb/Fetch/Fetching/Fetching.h>
|
||||||
|
|
@ -71,13 +72,6 @@ void SpeculativeHTMLParser::run()
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
StringView ffi_string_view(u8 const* ptr, size_t len)
|
|
||||||
{
|
|
||||||
if (ptr == nullptr || len == 0)
|
|
||||||
return {};
|
|
||||||
return { ptr, len };
|
|
||||||
}
|
|
||||||
|
|
||||||
Optional<Fetch::Infrastructure::Request::Destination> destination_from_preload_scanner(RustFfiPreloadScannerDestination destination)
|
Optional<Fetch::Infrastructure::Request::Destination> destination_from_preload_scanner(RustFfiPreloadScannerDestination destination)
|
||||||
{
|
{
|
||||||
switch (destination) {
|
switch (destination) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue