Quasar C++ API: System.InvalidOperationException during function application

Q&ACategory: BugQuasar C++ API: System.InvalidOperationException during function application
Frank Vernaillen asked 3 years ago

The following code snippet crashes with what looks like an unhandled exception from managed code.

#include <cassert>
#include <iostream>

#include "quasar_host.h"
#include "quasar_dsl.h"

using namespace quasar;

int main(int argc, char* argv[])
{
        quasar::IQuasarHost* host = quasar::IQuasarHost::Create(L"cpu", true);
        assert(host != nullptr);

        QValue e(2.718281828f);

        Function ln(L"log()");
        assert(host->FunctionExists(L"log"));

        QValue result = ln(e); // System.InvalidOperationException: Stack empty.

        host->Release();

        return 0;
}

The output is

Load and start the .NET runtime v4.0.30319
Initializing Quasar runtime system...
Initializing Quasar compiler system...
Initializing computation device...
Initializing interpreter...

Unhandled Exception: System.InvalidOperationException: Stack empty.
   at System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource)
   at System.Collections.Generic.Stack`1.Pop()
   at Quasar.Interpreter.DirectInterpreter.PopReturnValues()
   at Quasar.Interpreter.DirectInterpreter.EvaluateIndirectFunctionCall(QValue function, QValue[] args)
   at Quasar.NativeInterface.FunctionCallIndirect(IntPtr functionHandle, IntPtr ptrArgsIn, Int32 nArgsIn, IntPtr ptrArgsOut, Int32 nArgsOut)

Not every function application has this issue though. Applying ‘print’ to the QValue ‘e’ works fine, for example. I tested on Windows 10, running the latest Quasar: Quasar 1.0.6128.24868 – build date 11-Oct-16 1:48:55 PM – 64-bit

2 Answers
bgoossen Staff answered 3 years ago

The constructor for the class ‘Function’ requires the full function signature to be specified, otherwise the external C++ interface attempts to call log() without any parameters. To fix the problem, you can replace

 Function ln(L"log()");

by

 Function ln(L"log(??)");

It is neccessary to specify the full function signature. The error message “Stack Empty” is indeed not very clear. I will try to improve it.
You may have noted that for the print function, specifying the arguments is not required. This is because print is a function with variadic arguments. However, it would be more correct to bind to the function print as follows:
Function print(L”print(…)”);

Frank Vernaillen answered 3 years ago

Providing the correct function signature indeed solves the issue. Thanks!