Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/benchmarks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ jobs:
with:
python-version: '3.11'

- uses: leafo/gh-actions-lua@v10
- uses: leafo/gh-actions-lua@8aace3457a2fcf3f3c4e9007ecc6b869ff6d74d6 # v11
with:
luaVersion: "5.4.1"

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Run clang-format style check for C/C++/Protobuf programs.
uses: jidicula/clang-format-action@v4.11.0
uses: jidicula/clang-format-action@4726374d1aa3c6aecf132e5197e498979588ebc8 # v4.15.0
with:
clang-format-version: '13'
check-path: ${{ matrix.path }}
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
if: ${{ contains(github.event.head_commit.message, '[skip ci]') != true }}

- name: Build and push stable Docker image
uses: docker/build-push-action@v1.1.0
uses: docker/build-push-action@471d1dc4e07e5cdedd4c2171150001c434f0b7a4 # v6.15.0
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
Expand All @@ -28,7 +28,7 @@ jobs:
push: ${{ startsWith(github.ref, 'refs/tags/') }}

- name: Build and push nightly Docker image
uses: docker/build-push-action@v1.1.0
uses: docker/build-push-action@471d1dc4e07e5cdedd4c2171150001c434f0b7a4 # v6.15.0
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
Expand All @@ -39,7 +39,7 @@ jobs:
tags: latest

- name: Build and push harden Docker image
uses: docker/build-push-action@v1.1.0
uses: docker/build-push-action@471d1dc4e07e5cdedd4c2171150001c434f0b7a4 # v6.15.0
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
Expand Down
15 changes: 2 additions & 13 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -140,10 +140,10 @@ jobs:

- name: Extract release notes
id: extract-release-notes
uses: ffurrer2/extract-release-notes@v1
uses: ffurrer2/extract-release-notes@cae32133495112d23e3569ad04fef240ba4e7bc8 # v2.3.0

- name: Create release
uses: softprops/action-gh-release@v2
uses: softprops/action-gh-release@da05d552573ad5aba039eaac05058a918a7bf631 # v2.2.2
id: create_release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Expand All @@ -154,17 +154,6 @@ jobs:
prerelease: false
body: ${{ steps.extract-release-notes.outputs.release_notes }}

- uses: sarisia/actions-status-discord@v1
with:
webhook: ${{ secrets.DISCORD_WEBHOOK }}
title: "A new release (${{ env.RELEASE_VERSION }}) has been drafted"
description: |
Please review it **before publishing it**, as this action would trigger workflows and GitHub webhooks,
notifying everyone of a new release! You want to be sure **everything** is correct
[Release draft URL](${{ steps.create_release.outputs.url }})
nodetail: true
username: GitHub Actions

- name: Upload artifact
uses: actions/upload-release-asset@v1
env:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/setup-compilers/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ runs:
brew install llvm@${{ inputs.compiler_version }}

- name: Setup Windows environment
uses: ilammy/msvc-dev-cmd@v1
uses: ilammy/msvc-dev-cmd@0b201ec74fa43914dc39ae48a89fd1d8cb592756 # v1.13.0
if: startsWith(inputs.os_name, 'windows')

- name: Install MacOS dependencies
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/static_analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,15 @@ jobs:
echo "EOF" >> $GITHUB_ENV

- name: Find Comment
uses: peter-evans/find-comment@v3
uses: peter-evans/find-comment@3eae4d37986fb5a8592848f6a574fdf654e61f9e # v3.1.0
id: fc
with:
issue-number: ${{ github.event.pull_request.number }}
comment-author: 'github-actions[bot]'
body-includes: Static analysis report

- name: Create or update comment
uses: peter-evans/create-or-update-comment@v4
uses: peter-evans/create-or-update-comment@71345be0265236311c031f5c7866368bd1eff043 # v4.0.0
with:
comment-id: ${{ steps.fc.outputs.comment-id }}
issue-number: ${{ github.event.pull_request.number }}
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@
- removed `and` and `or` instructions in favor of a better implementation to support short-circuiting
- removed `LET` and `MUT` instructions in favor of a single new `STORE` instruction
- removed `SAVE_ENV` instruction
- removed `Value VM::resolve(const Value* val, Args&&... args)`, which has been deprecated in ArkScript v3.4.0

## [3.5.0] - 2023-02-19
### Added
Expand Down
2 changes: 1 addition & 1 deletion include/Ark/Compiler/Instructions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ namespace Ark::internal
LOAD_SYMBOL = 0x01,

// @args stack index
// @role Load a symbol from the locals stack by its index
// @role Load a symbol from the locals stack by its index (starting from the end of the current scope)
LOAD_SYMBOL_BY_INDEX = 0x02,

// @args symbol id
Expand Down
60 changes: 48 additions & 12 deletions include/Ark/VM/VM.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,25 +82,14 @@ namespace Ark
// function calling from plugins
// ================================================

/**
* @brief Resolving a function call (called by plugins and builtins)
*
* @tparam Args
* @param val the ArkScript function object
* @param args C++ argument list
* @return Value
*/
template <typename... Args>
[[deprecated("Use resolve(ExecutionContext*, vector<Value>&) instead")]] Value resolve(const Value* val, Args&&... args);

/**
* @brief Resolves a function call (called by plugins and builtins)
*
* @param context the execution context to use
* @param n the function and its arguments
* @return Value
*/
inline Value resolve(internal::ExecutionContext* context, std::vector<Value>& n);
inline Value resolve(internal::ExecutionContext* context, const std::vector<Value>& n);

/**
* @brief Ask the VM to exit with a given exit code
Expand All @@ -109,6 +98,15 @@ namespace Ark
*/
void exit(int code) noexcept;

/**
* @brief Return a pointer to the first execution context, for the main thread of the app
* @return internal::ExecutionContext*
*/
inline internal::ExecutionContext* getDefaultContext()
{
return m_execution_contexts.front().get();
}

/**
* @brief Create an execution context and returns it
* @details This method is thread-safe VM wise.
Expand Down Expand Up @@ -187,10 +185,48 @@ namespace Ark
// instruction helpers
// ================================================

/**
* @brief Load a symbol by its id in the current context. Performs a lookup in the scope stack, in reverse order.
*
* @param id symbol id
* @param context
* @return Value* nullptr if the symbol could not be loaded
*/
[[nodiscard]] inline Value* loadSymbol(uint16_t id, internal::ExecutionContext& context);

/**
* @brief Load a symbol by its (reversed) index in the current scope
*
* @param index index of the symbol to load, starting from the end
* @param context
* @return Value*
*/
[[nodiscard]] inline Value* loadSymbolFromIndex(uint16_t index, internal::ExecutionContext& context);

/**
* @brief Load a constant from the constant table by its id
*
* @param id
* @return Value*
*/
[[nodiscard]] inline Value* loadConstAsPtr(uint16_t id) const;

/**
* @brief Create a new symbol with an associated value in the current scope
*
* @param id
* @param val
* @param context
*/
inline void store(uint16_t id, const Value* val, internal::ExecutionContext& context);

/**
* @brief Change the value of a symbol given its identifier
*
* @param id
* @param val
* @param context
*/
inline void setVal(uint16_t id, const Value* val, internal::ExecutionContext& context);

// ================================================
Expand Down
45 changes: 4 additions & 41 deletions include/Ark/VM/VM.inl
Original file line number Diff line number Diff line change
Expand Up @@ -47,47 +47,7 @@ Value VM::call(const std::string& name, Args&&... args)
return *popAndResolveAsPtr(context);
}

template <typename... Args>
Value VM::resolve(const Value* val, Args&&... args)
{
using namespace internal;

// TODO: deprecate resolve(const Value*, Args&&...) and add a resolve(ExecutionContext*, const Value*, Args&&...)
ExecutionContext& context = *m_execution_contexts.front().get();

if (!val->isFunction())
throw TypeError("Value::resolve couldn't resolve a non-function");

const std::size_t ip = context.ip;
const std::size_t pp = context.pp;

// convert and push arguments in reverse order
std::vector<Value> fnargs { { Value(std::forward<Args>(args))... } };
for (auto it = fnargs.rbegin(), it_end = fnargs.rend(); it != it_end; ++it)
push(*it, context);
// push function
push(*val, context);

const std::size_t frames_count = context.fc;
// call it
call(context, static_cast<uint16_t>(sizeof...(Args)));
// reset instruction pointer, otherwise the safeRun method will start at ip = -1
// without doing context.ip++ as intended (done right after the call() in the loop, but here
// we start outside this loop)
context.ip = 0;

// run until the function returns
safeRun(context, /* untilFrameCount */ frames_count);

// restore VM state
context.ip = ip;
context.pp = pp;

// get result
return *popAndResolveAsPtr(context);
}

inline Value VM::resolve(internal::ExecutionContext* context, std::vector<Value>& n)
inline Value VM::resolve(internal::ExecutionContext* context, const std::vector<Value>& n)
{
if (!n[0].isFunction())
throw TypeError(fmt::format("VM::resolve couldn't resolve a non-function ({})", types_to_str[static_cast<std::size_t>(n[0].valueType())]));
Expand Down Expand Up @@ -138,6 +98,9 @@ inline Value* VM::loadSymbol(const uint16_t id, internal::ExecutionContext& cont

inline Value* VM::loadSymbolFromIndex(const uint16_t index, internal::ExecutionContext& context)
{
// we need to load symbols from the end, because function calls add a reference to the current function
// upon calling it. Which changes the index by 1, making it less clear, because it needs special
// treatment only for function calls.
auto& [id, value] = context.locals.back().atPosReverse(index);
context.last_symbol = id;
return &value;
Expand Down
2 changes: 1 addition & 1 deletion lib/modules
Loading