mirror of
https://github.com/RGBCube/serenity
synced 2025-05-18 10:55:07 +00:00

By using RefPtrs to handle interfaces, the IDL parser could store cyclic references to interfaces that import each other. One main example is the "EventTarget.idl" and the "AbortSignal.idl" files, which both reference each other. This caused huge amounts of memory not to be freed on exit. To fix this, the parsed IDL interfaces are now stored in a HashTable of NonnullOwnPtr<Interface>, which serves as the sole reference for every parsed interface. All other usages of the Interface are changed to use references instead of RefPtrs, or occasionally as raw pointers where references don't fit inside the data structures. This new HashTable is static, and as such will automatically be freed prior to exiting the generator. This ensures that the code generator properly cleans up after itself. With this change, The IDL code generators can properly run on Lagom when compiled with the -DENABLE_ADDRESS_SANITIZER=ON flag, and gets compiled properly on the CI :^)
65 lines
2.2 KiB
C++
65 lines
2.2 KiB
C++
/*
|
|
* Copyright (c) 2020-2021, Andreas Kling <kling@serenityos.org>
|
|
* Copyright (c) 2021, Linus Groh <linusg@serenityos.org>
|
|
* Copyright (c) 2021, Luke Wilde <lukew@serenityos.org>
|
|
* Copyright (c) 2022, Ali Mohammad Pur <mpfard@serenityos.org>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include "IDLTypes.h"
|
|
#include <AK/CharacterTypes.h>
|
|
#include <AK/GenericLexer.h>
|
|
|
|
namespace IDL {
|
|
|
|
class Parser {
|
|
public:
|
|
Parser(String filename, StringView contents, String import_base_path);
|
|
Interface& parse();
|
|
|
|
private:
|
|
// https://webidl.spec.whatwg.org/#dfn-special-operation
|
|
// A special operation is a getter, setter or deleter.
|
|
enum class IsSpecialOperation {
|
|
No,
|
|
Yes,
|
|
};
|
|
|
|
void assert_specific(char ch);
|
|
void assert_string(StringView expected);
|
|
void consume_whitespace();
|
|
Optional<Interface&> resolve_import(auto path);
|
|
|
|
HashMap<String, String> parse_extended_attributes();
|
|
void parse_attribute(HashMap<String, String>& extended_attributes, Interface&);
|
|
void parse_interface(Interface&);
|
|
void parse_non_interface_entities(bool allow_interface, Interface&);
|
|
void parse_enumeration(Interface&);
|
|
void parse_typedef(Interface&);
|
|
void parse_interface_mixin(Interface&);
|
|
void parse_dictionary(Interface&);
|
|
void parse_callback_function(HashMap<String, String>& extended_attributes, Interface&);
|
|
void parse_constructor(Interface&);
|
|
void parse_getter(HashMap<String, String>& extended_attributes, Interface&);
|
|
void parse_setter(HashMap<String, String>& extended_attributes, Interface&);
|
|
void parse_deleter(HashMap<String, String>& extended_attributes, Interface&);
|
|
void parse_stringifier(HashMap<String, String>& extended_attributes, Interface&);
|
|
void parse_iterable(Interface&);
|
|
Function parse_function(HashMap<String, String>& extended_attributes, Interface&, IsSpecialOperation is_special_operation = IsSpecialOperation::No);
|
|
Vector<Parameter> parse_parameters();
|
|
NonnullRefPtr<Type> parse_type();
|
|
void parse_constant(Interface&);
|
|
|
|
static HashTable<NonnullOwnPtr<Interface>> s_interfaces;
|
|
static HashMap<String, Interface*> s_resolved_imports;
|
|
|
|
String import_base_path;
|
|
String filename;
|
|
StringView input;
|
|
GenericLexer lexer;
|
|
};
|
|
|
|
}
|