I am using Microsoft's Chakracore from C++, and I've written a basic evaluator that I can repeatedly call from a read-eval-print loop as follows:
void readEvalPrint(const char *prompt, JsSourceContext sourceContext) {
JsValueRef result;
JsValueRef scriptSource;
JsValueRef fileName;
JsErrorCode status;
JsValueRef strResult;
std::string script;
std::cout << prompt;
std::cout.flush();
std::getline(std::cin, script);
JsCreateString("", 0, &fileName);
JsCreateExternalArrayBuffer(const_cast<char*> (script.c_str()), script.length(), nullptr, nullptr, &scriptSource);
status = JsRun(scriptSource, sourceContext, fileName, JsParseScriptAttributeNone, &result);
if (status != JsNoError) {
JsValueRef exception;
// TODO: print stack trace
JsGetAndClearException(&exception);
std::cout << "Error: Could not evaluate expression" << std::endl;
return;
}
status = JsConvertValueToString(result, &strResult);
if (status != JsNoError) {
std::cout << "Could not convert expression to displayable form" << std::endl;
return;
}
size_t written;
size_t bufferSize;
JsCopyString(strResult, nullptr, std::numeric_limits<int>::max(), &bufferSize);
char buffer[bufferSize+1];
JsCopyString(strResult, buffer, bufferSize, &written);
buffer[bufferSize] = 0;
std::cout << buffer << std::endl;
}
This does appear to work for most cases, however when I enter a javascript function declaration, although I can call the function and it produces the correct result, if I simply try and examine the function by name to see its body as I would expect to with any javascript function by calling its toString() method, the result is quite clearly garbage. If I examine other functions such as built-in functions, I see the expected result (ie, 'function function-name() { [native code] }', and if I create an anonymous function, eg, var a = function foo().... and try and display the value for a, I see the anonymous function definition in entirety. However, I cannot seem to figure out how to display named functions that I defined in a previous iteration of JsRun(). I figure I am either doing something wrong or misunderstanding some expected behavior, or else I have found a bug. I am not, however, yet fluent enough using the Jsrt API to be confident of which one it is.