Skip to content

Commit 0744f9a

Browse files
authored
Merge pull request #214 from ArkScript-lang/refacto
Bumping to 3.0.15 + a few nice enhancements
2 parents 968316b + a646c3e commit 0744f9a

File tree

15 files changed

+103
-119
lines changed

15 files changed

+103
-119
lines changed

CHANGELOG.md

+9-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@
22

33
## Unreleased changes
44
### Added
5+
6+
### Changed
7+
8+
### Removed
9+
10+
## 3.0.15
11+
### Added
512
- new submodule, plasma-umass/coz (a profiler)
613
- macros for profiling, enabled only if `ARK_PROFILE` is defined
714
- cmake flags using -D to turn on/off sys:exec and the coz profiler
@@ -20,8 +27,8 @@
2027
- replaced the thirdparty/ folder with a git submodule in thirdparties/
2128
- now checking that a scope doesn't have our symbol before doing a `mut` operation (in dichotomic mode it was automatically handled, but not in linear mode)
2229
- enhancing the cmake defines (`-DARK_XYZ`) and the code using them
23-
24-
### Removed
30+
- lighter Frame (from 40B to 32B), moved some unrelated logic from the frame to the virtual machine
31+
- `(sys:exec)` now returns the stdout output of the given command
2532

2633
## 3.0.14
2734
### Added

CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ set(REPLXX_INCLUDE_DIR "${ark_SOURCE_DIR}/submodules/replxx/include")
3434
# VERSION
3535
set(ARK_VERSION_MAJOR 3)
3636
set(ARK_VERSION_MINOR 0)
37-
set(ARK_VERSION_PATCH 14)
37+
set(ARK_VERSION_PATCH 15)
3838

3939
message(STATUS "ArkScript version ${ARK_VERSION_MAJOR}.${ARK_VERSION_MINOR}.${ARK_VERSION_PATCH}")
4040
if (ARK_PROFILER)

README.md

+2-4
Original file line numberDiff line numberDiff line change
@@ -146,14 +146,12 @@ For performance reasons, some functions might be written in C++, in `include/Ark
146146
* Install a newer compiler using [Homebrew](https://docs.brew.sh/): `brew install gcc && brew link gcc`
147147
* Pass compiler path to `cmake` in the build step: `-DCMAKE_CXX_COMPILER=/usr/local/bin/g++-9`
148148

149-
Libs already included:
150-
* [CLIPP](https://github.com/muellan/clipp), MIT licence
151-
* [termcolor](https://github.com/ikalnytskyi/termcolor), BSD (3-clause) licence
149+
Some libs already included un [thirdparties](https://github.com/ArkScript-lang/thirdparties).
152150

153151
## Building
154152

155153
Different CMake switches are available to customize the build:
156-
* `-DARK_BUILD_EXE` to generate an executable, defaults to Off, building a shared library
154+
* `-DARK_BUILD_EXE` to generate an executable, defaults to Off, building a shared library only
157155
* `-DARK_ENABLE_SYSTEM` to enable `sys:exec` (execute shell commands without restrictions), defaults to On
158156
* `-DARK_PROFILER` to enable the [coz](https://github.com/plasma-umass/coz) profiler, defaults to Off
159157
* `-DARK_PROFILER_COUNT` to count every creation/copy/move of the internal value type, defaults to Off

include/Ark/VM/Closure.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ namespace Ark::internal
8484
friend inline bool operator==(const Closure& A, const Closure& B) noexcept;
8585
friend inline bool operator<(const Closure& A, const Closure& B) noexcept;
8686
friend std::ostream& operator<<(std::ostream& os, const Closure& C) noexcept;
87-
87+
8888
private:
8989
Scope_t m_scope;
9090
// keep track of the code page number, in case we need it later

include/Ark/VM/Frame.hpp

+4-43
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,8 @@ namespace Ark::internal
4949
*
5050
* @param caller_addr the address of the caller, to return to it afterward
5151
* @param caller_page_addr the page address of the caller
52-
* @param new_pp the new page address where we're going
5352
*/
54-
Frame(uint16_t caller_addr, uint16_t caller_page_addr, uint16_t new_pp) noexcept;
53+
Frame(uint16_t caller_addr, uint16_t caller_page_addr) noexcept;
5554

5655
// stack related
5756

@@ -99,50 +98,12 @@ namespace Ark::internal
9998
*/
10099
inline uint16_t callerPageAddr() const noexcept;
101100

102-
/**
103-
* @brief Get the current page address
104-
*
105-
* @return uint16_t
106-
*/
107-
inline uint16_t currentPageAddr() const noexcept;
108-
109-
// related to scope deletion
110-
111-
/**
112-
* @brief Increment the number of scopes linked to this frame
113-
*
114-
* Needed for the primitive garbage collecting system.
115-
*
116-
*/
117-
inline void incScopeCountToDelete() noexcept;
118-
119-
/**
120-
* @brief Reset the number of scopes linked to this frame
121-
*
122-
* Needed for the primitive garbage collecting system.
123-
*
124-
*/
125-
inline void resetScopeCountToDelete() noexcept;
126-
127-
/**
128-
* @brief Get the number of scopes linked to this frame
129-
*
130-
* Needed for the primitive garbage collecting system.
131-
*
132-
* @return uint8_t
133-
*/
134-
inline uint8_t scopeCountToDelete() const noexcept;
135-
136-
friend std::ostream& operator<<(std::ostream& os, const Frame& F) noexcept;
137-
138101
private:
139-
// IP, PP EXC_PP
140-
uint16_t m_addr, m_page_addr, m_new_pp;
141-
142-
std::vector<Value> m_stack;
102+
uint16_t m_addr; ///< Instruction pointer
103+
uint16_t m_page_addr; ///< Page pointer
143104
int16_t m_i;
144105

145-
uint8_t m_scope_to_delete;
106+
std::vector<Value> m_stack;
146107
};
147108

148109
#include "inline/Frame.inl"

include/Ark/VM/VM.hpp

+1
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ namespace Ark
128128

129129
// related to the execution
130130
std::vector<internal::Frame> m_frames;
131+
std::vector<uint8_t> m_scope_count_to_delete;
131132
std::optional<internal::Scope_t> m_saved_scope;
132133
std::vector<internal::Scope_t> m_locals;
133134
std::vector<std::shared_ptr<internal::SharedLibrary>> m_shared_lib_objects;

include/Ark/VM/Value.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -287,8 +287,8 @@ namespace Ark::internal
287287
friend class Ark::internal::Frame;
288288

289289
private:
290-
Value_t m_value;
291290
uint8_t m_constType; ///< First bit if for constness, right most bits are for type
291+
Value_t m_value;
292292

293293
// private getters only for the virtual machine
294294

include/Ark/VM/inline/Frame.inl

-22
Original file line numberDiff line numberDiff line change
@@ -40,26 +40,4 @@ inline uint16_t Frame::callerAddr() const noexcept
4040
inline uint16_t Frame::callerPageAddr() const noexcept
4141
{
4242
return m_page_addr;
43-
}
44-
45-
inline uint16_t Frame::currentPageAddr() const noexcept
46-
{
47-
return m_new_pp;
48-
}
49-
50-
// related to scope deletion
51-
52-
inline void Frame::incScopeCountToDelete() noexcept
53-
{
54-
m_scope_to_delete++;
55-
}
56-
57-
inline void Frame::resetScopeCountToDelete() noexcept
58-
{
59-
m_scope_to_delete = 0;
60-
}
61-
62-
inline uint8_t Frame::scopeCountToDelete() const noexcept
63-
{
64-
return m_scope_to_delete;
6543
}

include/Ark/VM/inline/VM.inl

+7-5
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
#define createNewScope() m_locals.emplace_back(std::make_shared<internal::Scope>());
66
#define resolveRef(valptr) (((valptr)->valueType() == ValueType::Reference) ? *((valptr)->reference()) : *(valptr))
7+
#define createNewFrame(ip, pp) m_frames.emplace_back(ip, pp); m_scope_count_to_delete.emplace_back(0)
78

89
// profiler
910
#include <Ark/Profiling.hpp>
@@ -94,7 +95,8 @@ inline void VM::returnFromFuncCall()
9495

9596
// remove frame
9697
m_frames.pop_back();
97-
uint8_t del_counter = m_frames.back().scopeCountToDelete();
98+
m_scope_count_to_delete.pop_back();
99+
uint8_t del_counter = m_scope_count_to_delete.back();
98100

99101
// PERF high cpu cost because destroying variants cost
100102
m_locals.pop_back();
@@ -105,7 +107,7 @@ inline void VM::returnFromFuncCall()
105107
del_counter--;
106108
}
107109

108-
m_frames.back().resetScopeCountToDelete();
110+
m_scope_count_to_delete.back() = 0;
109111

110112
// stop the executing if we reach the wanted frame count
111113
if (m_frames.size() == m_until_frame_count)
@@ -164,7 +166,7 @@ inline void VM::call(int16_t argc_)
164166

165167
// create dedicated frame
166168
createNewScope();
167-
m_frames.emplace_back(m_ip, static_cast<uint16_t>(m_pp), new_page_pointer);
169+
createNewFrame(m_ip, static_cast<uint16_t>(m_pp));
168170
// store "reference" to the function to speed the recursive functions
169171
if (m_last_sym_loaded < m_state->m_symbols.size())
170172
m_locals.back()->push_back(m_last_sym_loaded, function);
@@ -187,8 +189,8 @@ inline void VM::call(int16_t argc_)
187189
m_locals.push_back(c.scope());
188190
// create dedicated frame
189191
createNewScope();
190-
m_frames.back().incScopeCountToDelete();
191-
m_frames.emplace_back(m_ip, static_cast<uint16_t>(m_pp), new_page_pointer);
192+
++m_scope_count_to_delete.back();
193+
createNewFrame(m_ip, static_cast<uint16_t>(m_pp));
192194

193195
m_pp = new_page_pointer;
194196
m_ip = -1; // because we are doing a m_ip++ right after that

src/Builtins/IO.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ namespace Ark::internal::Builtins::IO
3333
{
3434
if (n[0].valueType() != ValueType::String)
3535
throw Ark::TypeError(IO_INPUT_TE);
36-
std::printf(n[0].string().c_str());
36+
std::printf("%s", n[0].string().c_str());
3737
}
3838

3939
std::string line = "";

src/Builtins/System.cpp

+16-4
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
11
#include <Ark/Builtins/Builtins.hpp>
22

3+
#include <stdio.h>
4+
#include <memory>
5+
#include <cstdlib>
36
#include <thread>
47

8+
#ifdef _MSC_VER
9+
#define popen _popen
10+
#define pclose _pclose
11+
#endif
12+
513
#undef abs
614
#include <chrono>
715

8-
#include <cstdlib>
916
#include <Ark/Constants.hpp>
10-
1117
#include <Ark/Builtins/BuiltinsErrors.inl>
1218
#include <Ark/VM/VM.hpp>
1319

@@ -21,8 +27,14 @@ namespace Ark::internal::Builtins::System
2127
throw Ark::TypeError(SYS_SYS_TE0);
2228

2329
#ifdef ARK_ENABLE_SYSTEM
24-
int output = std::system(n[0].string().c_str());
25-
return Value(output);
30+
std::array<char, 128> buffer;
31+
std::string result;
32+
std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(n[0].string().c_str(), "r"), pclose);
33+
if (!pipe)
34+
throw std::runtime_error("sys:exec: couldn't retrieve command output");
35+
while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr)
36+
result += buffer.data();
37+
return Value(result);
2638
#endif // ARK_ENABLE_SYSTEM
2739

2840
return nil;

src/VM/Frame.cpp

+5-11
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,16 @@
33
namespace Ark::internal
44
{
55
Frame::Frame() noexcept :
6-
m_addr(0), m_page_addr(0), m_new_pp(0),
6+
m_addr(0), m_page_addr(0),
77
// PERF costs a lot
88
m_stack(4, Value(ValueType::Undefined)),
9-
m_i(0), m_scope_to_delete(0)
9+
m_i(0)
1010
{}
1111

12-
Frame::Frame(uint16_t caller_addr, uint16_t caller_page_addr, uint16_t new_pp) noexcept :
13-
m_addr(caller_addr), m_page_addr(caller_page_addr), m_new_pp(new_pp),
12+
Frame::Frame(uint16_t caller_addr, uint16_t caller_page_addr) noexcept :
13+
m_addr(caller_addr), m_page_addr(caller_page_addr),
1414
// PERF costs a lot
1515
m_stack(4, Value(ValueType::Undefined)),
16-
m_i(0), m_scope_to_delete(0)
16+
m_i(0)
1717
{}
18-
19-
std::ostream& operator<<(std::ostream& os, const Frame& F) noexcept
20-
{
21-
os << "Frame";
22-
return os;
23-
}
2418
}

src/VM/VM.cpp

+16-8
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,17 @@ namespace Ark
4444
{
4545
m_frames.clear();
4646
m_frames.emplace_back();
47+
4748
m_shared_lib_objects.clear();
49+
m_scope_count_to_delete.clear();
50+
m_scope_count_to_delete.emplace_back(0);
4851
}
4952
else if (m_frames.size() == 0)
5053
{
5154
// if persistance is set but no frames are present, add one
5255
// it usually happens on the first run
5356
m_frames.emplace_back();
57+
m_scope_count_to_delete.emplace_back(0);
5458
}
5559

5660
m_saved_scope.reset();
@@ -512,7 +516,7 @@ namespace Ark
512516
if (m_ip + 1 < m_state->m_pages[m_pp].size() && m_state->m_pages[m_pp][m_ip + 1] == Instruction::CALL)
513517
{
514518
m_locals.push_back(var->closure_ref().scope());
515-
m_frames.back().incScopeCountToDelete();
519+
++m_scope_count_to_delete.back();
516520
}
517521

518522
push(*field);
@@ -964,11 +968,11 @@ namespace Ark
964968
++m_ip;
965969
}
966970
} catch (const std::exception& e) {
967-
std::cerr << e.what() << "\n";
971+
std::printf("%s\n", e.what());
968972
backtrace();
969973
return 1;
970974
} catch (...) {
971-
std::cerr << "Unknown error" << std::endl;
975+
std::printf("Unknown error\n");
972976
backtrace();
973977
return 1;
974978
}
@@ -1001,33 +1005,37 @@ namespace Ark
10011005

10021006
if (m_frames.size() > 1)
10031007
{
1008+
uint16_t curr_pp = m_pp;
1009+
10041010
// display call stack trace
10051011
for (auto&& it=m_frames.rbegin(), it_end=m_frames.rend(); it != it_end; ++it)
10061012
{
10071013
std::cerr << "[" << termcolor::cyan << std::distance(it, m_frames.rend()) << termcolor::reset << "] ";
1008-
if (it->currentPageAddr() != 0)
1014+
if (curr_pp != 0)
10091015
{
10101016
uint16_t id = findNearestVariableIdWithValue(
1011-
Value(static_cast<PageAddr_t>(it->currentPageAddr()))
1017+
Value(static_cast<PageAddr_t>(curr_pp))
10121018
);
10131019

10141020
if (id < m_state->m_symbols.size())
10151021
std::cerr << "In function `" << termcolor::green << m_state->m_symbols[id] << termcolor::reset << "'\n";
10161022
else // should never happen
10171023
std::cerr << "In function `" << termcolor::green << "???" << termcolor::reset << "'\n";
1024+
1025+
curr_pp = it->callerPageAddr();
10181026
}
10191027
else
1020-
std::cerr << "In global scope\n";
1028+
std::printf("In global scope\n");
10211029

10221030
if (std::distance(m_frames.rbegin(), it) > 7)
10231031
{
1024-
std::cerr << "...\n";
1032+
std::printf("...\n");
10251033
break;
10261034
}
10271035
}
10281036

10291037
// display variables values in the current scope
1030-
std::cerr << "\nCurrent scope variables values:\n";
1038+
std::printf("\nCurrent scope variables values:\n");
10311039
for (std::size_t i=0, size=m_locals.back()->size(); i < size; ++i)
10321040
std::cerr << termcolor::cyan << m_state->m_symbols[m_locals.back()->m_data[i].first] << termcolor::reset
10331041
<< " = " << m_locals.back()->m_data[i].second << "\n";

0 commit comments

Comments
 (0)