@@ -275,17 +275,23 @@ void ByteCodeEmitter::process(const std::shared_ptr<AST::Node>& node, bool hasCo
275275 } else {
276276 loadIdentifier (call->getIdentifier ()); // Bring the function addr on the stack
277277
278+ const auto & returnType = fnDataType.getReturn ();
279+ ASSURE_NOT_NULL (returnType);
280+
281+ // CALL consumes the arguments from the stack, so we don't need to pop them
282+ // If we don't have a consumer, we have to pop the result. We assume only one result.
283+ // Only if the function is not void, of course.
278284 if (functionType.isExtern ) {
279285 code ().push_back (executor::Instruction (executor::Op::CALL_FFI));
286+
287+ // CALL_FFI always pushes a result, so we need to get rid of it
288+ // if we don't have a consumer or the return type is None.
289+ if (!hasConsumer || *returnType == DataType::Primitive::None) {
290+ code ().push_back (executor::Instruction (executor::Op::POP));
291+ }
280292 } else {
281293 code ().push_back (executor::Instruction (executor::Op::CALL, call->getArguments ().size ()));
282294
283- // CALL consumes the arguments from the stack, so we don't need to pop them
284- // If we don't have a consumer, we have to pop the result. We assume only one result.
285- // Only if the function is not void, of course.
286-
287- const auto & returnType = fnDataType.getReturn ();
288- ASSURE_NOT_NULL (returnType);
289295 if (!hasConsumer && *returnType != DataType::Primitive::None) {
290296 code ().push_back (executor::Instruction (executor::Op::POP));
291297 }
@@ -299,7 +305,7 @@ void ByteCodeEmitter::process(const std::shared_ptr<AST::Node>& node, bool hasCo
299305 auto literal = std::dynamic_pointer_cast<AST::Literal>(node);
300306 if (literal->getDataType () == DataType::Primitive::String) {
301307 auto strIdx = program.data .addString (literal->getStringValue ());
302- code ().push_back (executor::Instruction (executor::Op::PUSH , strIdx));
308+ code ().push_back (executor::Instruction (executor::Op::DATA_ADDR , strIdx));
303309 } else if (literal->getDataType () == DataType::Primitive::Bool) {
304310 code ().push_back (executor::Instruction (
305311 executor::Op::PUSH, literal->getBoolValue () ? 1 : 0 ));
0 commit comments