2015-09-13 11:32:39 -07:00
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
|
|
#include "uv.h"
|
|
|
|
|
|
|
|
|
|
#include "scheduler.h"
|
|
|
|
|
#include "wren.h"
|
|
|
|
|
#include "vm.h"
|
|
|
|
|
|
|
|
|
|
// This method resumes a fiber that is suspended waiting on an asynchronous
|
|
|
|
|
// operation. The first resumes it with zero arguments, and the second passes
|
|
|
|
|
// one.
|
|
|
|
|
static WrenValue* resume;
|
|
|
|
|
static WrenValue* resumeWithArg;
|
2015-09-30 21:13:36 -07:00
|
|
|
static WrenValue* resumeError;
|
2015-09-13 11:32:39 -07:00
|
|
|
|
2015-09-21 07:58:39 -07:00
|
|
|
void schedulerCaptureMethods(WrenVM* vm)
|
2015-09-13 11:32:39 -07:00
|
|
|
{
|
|
|
|
|
resume = wrenGetMethod(vm, "scheduler", "Scheduler", "resume_(_)");
|
|
|
|
|
resumeWithArg = wrenGetMethod(vm, "scheduler", "Scheduler", "resume_(_,_)");
|
2015-09-30 21:13:36 -07:00
|
|
|
resumeError = wrenGetMethod(vm, "scheduler", "Scheduler", "resumeError_(_,_)");
|
2015-09-13 11:32:39 -07:00
|
|
|
}
|
|
|
|
|
|
2015-09-30 21:13:36 -07:00
|
|
|
static void callResume(WrenValue* resumeMethod, WrenValue* fiber,
|
|
|
|
|
const char* argTypes, ...)
|
2015-09-13 11:32:39 -07:00
|
|
|
{
|
2015-09-30 21:13:36 -07:00
|
|
|
va_list args;
|
|
|
|
|
va_start(args, argTypes);
|
|
|
|
|
WrenInterpretResult result = wrenCallVarArgs(getVM(), resumeMethod, NULL,
|
|
|
|
|
argTypes, args);
|
|
|
|
|
va_end(args);
|
|
|
|
|
|
2015-09-13 11:32:39 -07:00
|
|
|
wrenReleaseValue(getVM(), fiber);
|
2015-09-30 21:13:36 -07:00
|
|
|
|
|
|
|
|
// If a runtime error occurs in response to an async operation and nothing
|
|
|
|
|
// catches the error in the fiber, then exit the CLI.
|
|
|
|
|
if (result == WREN_RESULT_RUNTIME_ERROR)
|
|
|
|
|
{
|
|
|
|
|
uv_stop(getLoop());
|
|
|
|
|
setExitCode(70); // EX_SOFTWARE.
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void schedulerResume(WrenValue* fiber)
|
|
|
|
|
{
|
|
|
|
|
callResume(resume, fiber, "v", fiber);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void schedulerResumeBytes(WrenValue* fiber, const char* bytes, size_t length)
|
|
|
|
|
{
|
|
|
|
|
callResume(resumeWithArg, fiber, "va", fiber, bytes, length);
|
2015-09-13 11:32:39 -07:00
|
|
|
}
|
|
|
|
|
|
2015-09-16 07:34:49 -07:00
|
|
|
void schedulerResumeDouble(WrenValue* fiber, double value)
|
|
|
|
|
{
|
2015-09-30 21:13:36 -07:00
|
|
|
callResume(resumeWithArg, fiber, "vd", fiber, value);
|
2015-09-16 07:34:49 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void schedulerResumeString(WrenValue* fiber, const char* text)
|
|
|
|
|
{
|
2015-09-30 21:13:36 -07:00
|
|
|
callResume(resumeWithArg, fiber, "vs", fiber, text);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void schedulerResumeError(WrenValue* fiber, const char* error)
|
|
|
|
|
{
|
|
|
|
|
callResume(resumeError, fiber, "vs", fiber, error);
|
2015-09-16 07:34:49 -07:00
|
|
|
}
|
|
|
|
|
|
2015-10-16 21:05:24 -07:00
|
|
|
void schedulerShutdown()
|
2015-09-13 11:32:39 -07:00
|
|
|
{
|
|
|
|
|
if (resume != NULL) wrenReleaseValue(getVM(), resume);
|
|
|
|
|
if (resumeWithArg != NULL) wrenReleaseValue(getVM(), resumeWithArg);
|
2015-09-30 21:13:36 -07:00
|
|
|
if (resumeError != NULL) wrenReleaseValue(getVM(), resumeError);
|
2015-09-13 11:32:39 -07:00
|
|
|
}
|