Skip to content

Commit 8dd2707

Browse files
committed
Preparing for C@ base language and bug fixes
- Fixed compilation issues - Fixed task_rw_mutex unlock - Improve `const` checks - Refactored type casts - Rework global types and values handling - Preparations for console apps handling (some basic console commands and getting start_function to launch app) - First try to implement abstract text language parser to be used for implementing script languages
1 parent adad206 commit 8dd2707

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+3188
-4381
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ FILE(GLOB LIB_SRCFILES
6565
)
6666

6767

68-
find_package(Boost REQUIRED COMPONENTS context)
68+
find_package(Boost REQUIRED COMPONENTS context program_options)
6969
find_package(asmjit REQUIRED)
7070
find_package(utf8cpp CONFIG REQUIRED)
7171

src/base/language/c@.cpp

Lines changed: 307 additions & 1902 deletions
Large diffs are not rendered by default.

src/base/language/c@.hpp

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,18 @@
1+
// Copyright Danyil Melnytskyi 2025-Present
2+
//
3+
// Distributed under the Boost Software License, Version 1.0.
4+
// (See accompanying file LICENSE or copy at
5+
// http://www.boost.org/LICENSE_1_0.txt)
6+
17
#ifndef SRC_BASE_LANGUAGE_C_40
28
#define SRC_BASE_LANGUAGE_C_40
3-
#include <base/language/provider.hpp>
9+
#include <run_time/library/cxx/language.hpp>
410

511
namespace language_parsers {
612

7-
class c_async : public language_handler {
8-
//{path : { function: hash }}...
9-
std::unordered_map<
10-
art::ustring,
11-
std::unordered_map<
12-
art::ustring,
13-
uint64_t,
14-
art::hash<art::ustring>>,
15-
art::hash<art::ustring>>
16-
declared_functions;
17-
art::TaskMutex mutex;
18-
13+
class c_async : public art::language::helpers::text_language_handler {
1914
public:
20-
art::patch_list handle_init(art::files::FileHandle& file) override;
21-
art::patch_list handle_init_complete() override;
22-
art::patch_list handle_create(art::files::FileHandle& file) override;
23-
art::patch_list handle_renamed(const art::ustring& old, art::files::FileHandle& file) override;
24-
art::patch_list handle_changed(art::files::FileHandle& file) override;
25-
art::patch_list handle_removed(const art::ustring& removed) override;
15+
c_async();
2616
};
2717
}
2818

src/base/language/precompiled.cpp

Lines changed: 250 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
1+
// Copyright Danyil Melnytskyi 2025-Present
2+
//
3+
// Distributed under the Boost Software License, Version 1.0.
4+
// (See accompanying file LICENSE or copy at
5+
// http://www.boost.org/LICENSE_1_0.txt)
6+
17
#include <base/language/precompiled.hpp>
28
#include <run_time/AttachA_CXX.hpp>
39
#include <run_time/library/bytes.hpp>
4-
10+
#include <run_time/util/tools.hpp>
11+
#include <util/exceptions.hpp>
512
using namespace art;
613

714
namespace language_parsers {
8-
9-
1015
template <class T>
1116
T read_value(files::FileHandle& file) {
1217
T value;
@@ -26,45 +31,254 @@ namespace language_parsers {
2631
return ustring((char*)string_value.data(), string_value.size());
2732
}
2833

34+
list_array<ustring> read_type_string(files::FileHandle& file) {
35+
uint64_t size = read_value<uint64_t>(file);
36+
list_array<ustring> res;
37+
res.reserve(size);
38+
for (uint64_t i = 0; i < size; i++)
39+
res.push_back(read_string(file));
40+
return res;
41+
}
42+
43+
ValueMeta read_value_meta(files::FileHandle& file) {
44+
union tttt_ {
45+
struct {
46+
VType type;
47+
uint8_t use_gc : 1;
48+
uint8_t allow_edit : 1;
49+
uint8_t as_ref : 1;
50+
uint32_t val_len;
51+
};
52+
53+
uint32_t raw;
54+
55+
tttt_(uint32_t r)
56+
: raw(r) {}
57+
} res(read_value<uint32_t>(file));
58+
59+
return ValueMeta(res.type, res.use_gc, res.allow_edit, res.val_len, res.as_ref);
60+
}
61+
62+
ValueItem readAny(files::FileHandle& file) {
63+
auto data_res = read_byte_arr(file);
64+
size_t read_pointer = 0;
65+
auto res = art::reader::readAny(data_res, data_res.size(), read_pointer);
66+
if (read_pointer != data_res.size())
67+
throw InvalidEncodingException("Value size mismatch, readed less bytes than encoded");
68+
return std::move(res);
69+
}
70+
71+
//symbol, decl, hash
72+
std::tuple<ustring, FuncHandle::inner_handle*, size_t> read_function(files::FileHandle& file) {
73+
ustring symbol = read_string(file);
74+
ustring cross_compiler_version = read_string(file);
75+
std::vector<uint8_t> _opcode = read_byte_arr(file);
76+
bool is_cheap = read_value<bool>(file);
77+
uint64_t hash = art::hash<uint8_t>()(_opcode.data(), _opcode.size());
78+
return {symbol, new FuncHandle::inner_handle(std::move(_opcode), is_cheap, cross_compiler_version.empty() ? nullptr : new ustring(cross_compiler_version)), hash};
79+
}
80+
81+
VirtualTable read_type_info(files::FileHandle& file) {
82+
uint64_t structure_bytes = read_value<uint64_t>(file);
83+
bool allow_auto_copy;
84+
85+
86+
list_array<MethodInfo> methods;
87+
list_array<ValueInfo> values;
88+
art::shared_ptr<FuncEnvironment> destructor;
89+
art::shared_ptr<FuncEnvironment> copy;
90+
art::shared_ptr<FuncEnvironment> move;
91+
art::shared_ptr<FuncEnvironment> compare;
92+
art::shared_ptr<FuncEnvironment> constructor;
93+
{
94+
union ttttt_ {
95+
struct {
96+
bool declared_destructor;
97+
bool declared_copy;
98+
bool declared_move;
99+
bool declared_compare;
100+
bool declared_constructor;
101+
bool allow_auto_copy;
102+
};
103+
104+
uint64_t raw;
105+
106+
ttttt_(uint64_t r)
107+
: raw(r) {}
108+
} flags(read_value<uint64_t>(file));
109+
110+
allow_auto_copy = flags.allow_auto_copy;
111+
if (flags.declared_destructor)
112+
destructor = new FuncEnvironment(std::get<1>(read_function(file)), true);
113+
if (flags.declared_copy)
114+
copy = new FuncEnvironment(std::get<1>(read_function(file)), true);
115+
if (flags.declared_move)
116+
move = new FuncEnvironment(std::get<1>(read_function(file)), true);
117+
if (flags.declared_compare)
118+
compare = new FuncEnvironment(std::get<1>(read_function(file)), true);
119+
if (flags.declared_constructor)
120+
constructor = new FuncEnvironment(std::get<1>(read_function(file)), true);
121+
}
122+
123+
{
124+
uint64_t methods_count = read_value<uint64_t>(file);
125+
methods.reserve(methods_count);
126+
for (uint64_t i = 0; i < methods_count; i++) {
127+
auto [name, decl, hash] = read_function(file);
128+
art::shared_ptr<FuncEnvironment> method = new FuncEnvironment(decl, true);
129+
ClassAccess access = read_value<ClassAccess>(file);
130+
art::ustring owner_name = read_string(file);
131+
list_array<ValueMeta> return_values;
132+
list_array<list_array<std::pair<ValueMeta, art::ustring>>> arguments;
133+
list_array<MethodTag> tags;
134+
{
135+
uint64_t return_values_count = read_value<uint64_t>(file);
136+
return_values.reserve(return_values_count);
137+
for (uint64_t j = 0; j < return_values_count; j++)
138+
return_values.push_back(read_value_meta(file));
139+
}
140+
{
141+
uint64_t arguments_count = read_value<uint64_t>(file);
142+
arguments.reserve(arguments_count);
143+
for (uint64_t j = 0; j < arguments_count; j++) {
144+
list_array<std::pair<ValueMeta, art::ustring>> argument_variant;
145+
uint64_t argument_variant_count = read_value<uint64_t>(file);
146+
argument_variant.reserve(argument_variant_count);
147+
for (uint64_t n = 0; n < argument_variant_count; n++) {
148+
auto meta = read_value_meta(file);
149+
argument_variant.push_back({meta, read_string(file)});
150+
}
151+
arguments.push_back(std::move(argument_variant));
152+
}
153+
}
154+
{
155+
uint64_t tags_count = read_value<uint64_t>(file);
156+
tags.reserve(tags_count);
157+
for (uint64_t j = 0; j < tags_count; j++) {
158+
MethodTag tag;
159+
tag.name = read_string(file);
160+
tag.enviro = new FuncEnvironment(std::get<1>(read_function(file)), true);
161+
tag.value = readAny(file);
162+
tags.push_back(std::move(tag));
163+
}
164+
}
165+
methods.push_back(MethodInfo(name, method, access, std::move(return_values), std::move(arguments), std::move(tags), owner_name));
166+
}
167+
}
168+
{
169+
uint64_t values_count = read_value<uint64_t>(file);
170+
values.reserve(values_count);
171+
for (uint64_t i = 0; i < values_count; i++) {
172+
ustring name = read_string(file);
173+
size_t offset = read_value<uint64_t>(file);
174+
ValueMeta type = read_value_meta(file);
175+
uint16_t bit_used = read_value<uint16_t>(file);
176+
uint8_t bit_offset = read_value<uint8_t>(file);
177+
bool inlined = read_value<bool>(file);
178+
bool allow_abstract_assign = read_value<bool>(file);
179+
ClassAccess access = read_value<ClassAccess>(file);
180+
list_array<ValueTag> tags;
181+
{
182+
uint64_t tags_count = read_value<uint64_t>(file);
183+
tags.reserve(tags_count);
184+
for (uint64_t j = 0; j < tags_count; j++) {
185+
MethodTag tag;
186+
tag.name = read_string(file);
187+
tag.enviro = new FuncEnvironment(std::get<1>(read_function(file)), true);
188+
tag.value = readAny(file);
189+
tags.push_back(std::move(tag));
190+
}
191+
}
192+
bool zero_after_cleanup = read_value<bool>(file);
193+
values.push_back(ValueInfo(name, offset, type, bit_used, bit_offset, inlined, allow_abstract_assign, access, tags, zero_after_cleanup));
194+
}
195+
}
196+
197+
char mode = read_value<char>(file);
198+
switch (mode) {
199+
case 's':
200+
return AttachAVirtualTable::create(methods, values, destructor, copy, move, compare, structure_bytes, allow_auto_copy, constructor);
201+
case 'd': {
202+
auto res = new AttachADynamicVirtualTable(methods, values, destructor, copy, move, compare, structure_bytes, allow_auto_copy);
203+
res->constructor = constructor;
204+
return res;
205+
}
206+
default:
207+
throw InvalidEncodingException("Unrecognized virtual table type: " + std::string(1, mode));
208+
}
209+
}
210+
29211
patch_list precompiled::handle_init(files::FileHandle& file) {
30212
lock_guard guard(mutex);
31213
patch_list build_patch_list;
32-
auto local_functions = declared_functions[file.get_path()];
33-
std::unordered_set<ustring, hash<ustring>> readed_functions;
34-
uint64_t _functions_count;
35-
file.read_fixed((uint8_t*)&_functions_count, (uint32_t)sizeof(uint64_t));
36-
_functions_count = bytes::convert_endian<bytes::Endian::little>(_functions_count);
37-
for (uint64_t i = 0; i < _functions_count; i++) {
38-
ustring symbol = read_string(file);
39-
ustring cross_compiler_version = read_string(file);
40-
std::vector<uint8_t> _opcode = read_byte_arr(file);
41-
bool is_cheap = read_value<bool>(file);
42-
43-
if (symbol.starts_with('\2')) {
44-
CXX::cxxCall(new FuncEnvironment(std::move(_opcode), true, false, cross_compiler_version.empty() ? nullptr : new ustring(cross_compiler_version)));
45-
continue;
46-
}
214+
auto& local_functions = declared_functions[file.get_path()];
215+
auto& local_types = declared_types[file.get_path()];
216+
{
217+
std::unordered_set<ustring, hash<ustring>> readed_functions;
218+
uint64_t _functions_count = read_value<uint64_t>(file);
219+
for (uint64_t i = 0; i < _functions_count; i++) {
220+
auto [symbol, decl, hash] = read_function(file);
47221

48-
uint64_t hash = art::hash<uint8_t>()(_opcode.data(), _opcode.size());
222+
if (symbol.starts_with('\2')) {
223+
CXX::cxxCall(new FuncEnvironment(decl, true));
224+
continue;
225+
}
49226

227+
readed_functions.insert(symbol);
228+
auto it = local_functions.find(symbol);
229+
if (it == local_functions.end())
230+
local_functions[symbol] = hash;
231+
else if (it->second == hash)
232+
continue;
50233

51-
readed_functions.insert(symbol);
52-
auto it = local_functions.find(symbol);
53-
if (it == local_functions.end())
54-
local_functions[symbol] = hash;
55-
else if (it->second == hash)
56-
continue;
234+
if (symbol.starts_with('\3')) {
235+
CXX::cxxCall(new FuncEnvironment(decl, true));
236+
continue;
237+
}
57238

58-
build_patch_list.emplace_back(symbol, new FuncHandle::inner_handle(std::move(_opcode), is_cheap, cross_compiler_version.empty() ? nullptr : new ustring(cross_compiler_version)));
239+
build_patch_list.define_function(symbol, decl);
240+
}
241+
242+
list_array<art::ustring> functions;
243+
for (auto& it : local_functions) {
244+
if (!readed_functions.contains(it.first)) {
245+
build_patch_list.undefine_function(it.first);
246+
functions.push_back(it.first);
247+
}
248+
}
249+
functions.for_each([&](const art::ustring& symbol) {
250+
local_functions.erase(symbol);
251+
});
59252
}
253+
{
254+
std::unordered_set<list_array<art::ustring>, hash<list_array<art::ustring>>> readed_types;
255+
uint64_t _types_count = read_value<uint64_t>(file);
256+
for (uint64_t i = 0; i < _types_count; i++) {
257+
auto type_namespace = read_type_string(file);
258+
uint64_t hash = read_value<uint64_t>(file);
259+
auto type_d = read_type_info(file);
60260

61-
std::remove_if(local_functions.begin(), local_functions.end(), [&](decltype(local_functions)::value_type& it) {
62-
if (!readed_functions.contains(it.first)) {
63-
build_patch_list.emplace_back(it.first, nullptr);
64-
return true;
261+
readed_types.insert(type_namespace);
262+
auto it = local_types.find(type_namespace);
263+
if (it == local_types.end())
264+
local_types[type_namespace] = hash;
265+
else if (it->second == hash)
266+
continue;
267+
build_patch_list.define_type(type_namespace, std::move(type_d));
65268
}
66-
return false;
67-
});
269+
270+
271+
list_array<list_array<art::ustring>> functions;
272+
for (auto& it : local_types) {
273+
if (!readed_types.contains(it.first)) {
274+
build_patch_list.undefine_type(it.first);
275+
functions.push_back(it.first);
276+
}
277+
}
278+
functions.for_each([&](const list_array<art::ustring>& symbol) {
279+
local_types.erase(symbol);
280+
});
281+
}
68282
return build_patch_list;
69283
}
70284

@@ -91,9 +305,10 @@ namespace language_parsers {
91305
patch_list precompiled::handle_removed(const ustring& removed) {
92306
lock_guard guard(mutex);
93307
patch_list build_patch_list;
94-
auto local_functions = declared_functions[removed];
95-
for (auto& it : local_functions)
96-
build_patch_list.emplace_back(it.first, nullptr);
308+
for (auto& it : declared_functions[removed])
309+
build_patch_list.undefine_function(it.first);
310+
for (auto& it : declared_types[removed])
311+
build_patch_list.undefine_type(it.first);
97312
declared_functions.erase(removed);
98313
return build_patch_list;
99314
}

0 commit comments

Comments
 (0)