Skip to content

Commit

Permalink
feat(compiler, vm): adding a CALL_BUILTIN <builtin> <arg count> instr…
Browse files Browse the repository at this point in the history
…uction
  • Loading branch information
SuperFola committed Oct 20, 2024
1 parent 0b08238 commit af049e5
Show file tree
Hide file tree
Showing 7 changed files with 52 additions and 8 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@
- if the instruction takes two arguments, they each have 12 bits ; the second one is on byte1 and upper half of byte2, the first on lower half of byte2 and then byte3
- ast-to-json dump now supports macros
- the parser can detect ill-formed macros (that are seen as function macros while being value macros)
- adding a `CALL_BUILTIN <builtin> <arg count>` super instruction

### Removed
- removed unused `NodeType::Closure`
Expand Down
9 changes: 2 additions & 7 deletions include/Ark/Compiler/Instructions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ namespace Ark::internal
FUNC_TYPE = 0x03,
CODE_SEGMENT_START = 0x03,

FIRST_COMMAND = 0x01,
LOAD_SYMBOL = 0x01,
LOAD_CONST = 0x02,
POP_JUMP_IF_TRUE = 0x03,
Expand All @@ -60,7 +59,6 @@ namespace Ark::internal
POP_LIST_IN_PLACE = 0x17,
POP = 0x18,
DUP = 0x19,
LAST_COMMAND = 0x19,

FIRST_OPERATOR = 0x1a,
ADD = 0x1a,
Expand All @@ -86,9 +84,7 @@ namespace Ark::internal
TYPE = 0x2e,
HASFIELD = 0x2f,
NOT = 0x30,
LAST_OPERATOR = 0x30,

FIRST_SUPER_INSTRUCTION = 0x31,
LOAD_CONST_LOAD_CONST = 0x31,
LOAD_CONST_STORE = 0x32,
LOAD_CONST_SET_VAL = 0x33,
Expand All @@ -100,9 +96,7 @@ namespace Ark::internal
STORE_HEAD = 0x39,
SET_VAL_TAIL = 0x3a,
SET_VAL_HEAD = 0x3b,
LAST_SUPER_INSTRUCTION = 0x3b,

LAST_INSTRUCTION = 0x3d
CALL_BUILTIN = 0x3c
};

constexpr std::array InstructionNames = {
Expand Down Expand Up @@ -168,6 +162,7 @@ namespace Ark::internal
"STORE_HEAD",
"SET_VAL_TAIL",
"SET_VAL_HEAD",
"CALL_BUILTIN"
};
}

Expand Down
9 changes: 9 additions & 0 deletions include/Ark/VM/VM.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,15 @@ namespace Ark
* @param argc number of arguments already sent
*/
inline void call(internal::ExecutionContext& context, uint16_t argc);

/**
* @brief Builtin called when the CALL_BUILTIN instruction is met in the bytecode
*
* @param context
* @param builtin the builtin to call
* @param argc number of arguments already sent
*/
inline void callBuiltin(internal::ExecutionContext& context, const Value& builtin, uint16_t argc);
};

#include "VM.inl"
Expand Down
21 changes: 21 additions & 0 deletions include/Ark/VM/VM.inl
Original file line number Diff line number Diff line change
Expand Up @@ -412,3 +412,24 @@ inline void VM::call(internal::ExecutionContext& context, const uint16_t argc)
context.pp, needed_argc, argc));
}
}

inline void VM::callBuiltin(internal::ExecutionContext& context, const Value& builtin, const uint16_t argc)
{
// drop arguments from the stack
std::vector<Value> args;
args.reserve(argc);

for (uint16_t j = 0; j < argc; ++j)
{
// because we pull `argc` from the CALL instruction generated by the compiler,
// we are guaranted to have `argc` values pushed on the stack ; thus we can
// skip the `if (context.sp > 0)` check
Value* val = &context.stack[context.sp - argc + j];
if (val->valueType() == ValueType::Reference)
val = val->reference();
args.emplace_back(*val);
}
context.sp -= argc;
// call proc
push(builtin.proc()(args, this), context);
}
1 change: 1 addition & 0 deletions src/arkreactor/Compiler/BytecodeReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,7 @@ namespace Ark
{ POP_JUMP_IF_FALSE, ArgKind::Raw },
{ JUMP, ArgKind::Raw },
{ CALL, ArgKind::Raw },
{ CALL_BUILTIN, ArgKind::Raw },
{ CAPTURE, ArgKind::Symbol },
{ BUILTIN, ArgKind::Builtin },
{ DEL, ArgKind::Symbol },
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <Ark/Compiler/IntermediateRepresentation/IROptimizer.hpp>

#include <utility>
#include <Ark/Builtins/Builtins.hpp>

namespace Ark::internal
{
Expand Down Expand Up @@ -104,6 +105,11 @@ namespace Ark::internal
return IR::Entity(STORE_FROM, first.primaryArg(), second.primaryArg());
if (first.inst() == LOAD_SYMBOL && second.inst() == SET_VAL)
return IR::Entity(SET_VAL_FROM, first.primaryArg(), second.primaryArg());
// BUILTIN i
// CALL n
// ---> CALL_BUILTIN i n
if (first.inst() == BUILTIN && second.inst() == CALL && Builtins::builtins[first.primaryArg()].second.isFunction())
return IR::Entity(CALL_BUILTIN, first.primaryArg(), second.primaryArg());

return std::nullopt;
}
Expand Down
13 changes: 12 additions & 1 deletion src/arkreactor/VM/VM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,8 @@ namespace Ark
&&TARGET_STORE_TAIL,
&&TARGET_STORE_HEAD,
&&TARGET_SET_VAL_TAIL,
&&TARGET_SET_VAL_HEAD
&&TARGET_SET_VAL_HEAD,
&&TARGET_CALL_BUILTIN
};
# pragma GCC diagnostic pop
#endif
Expand Down Expand Up @@ -1218,6 +1219,16 @@ namespace Ark
}
DISPATCH();
}

TARGET(CALL_BUILTIN)
{
UNPACK_ARGS();
// no stack size check because we do not push IP/PP since we are just calling a builtin
callBuiltin(context, Builtins::builtins[primary_arg].second, secondary_arg);
if (!m_running)
GOTO_HALT();
DISPATCH();
}
#pragma endregion
}
#if ARK_USE_COMPUTED_GOTOS
Expand Down

0 comments on commit af049e5

Please sign in to comment.