major restructuring
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
#include "run.h"
|
||||
#include "builtins_api.h"
|
||||
#include "../builtins/basic.h"
|
||||
|
||||
bool Runtime_plugBuiltinsFromStaticMap(Runtime *runtime, StaticMapSlot *bin_table, void (*bin_table_constructor)(StaticMapSlot*), Error *error)
|
||||
{
|
||||
Object *object = Object_NewStaticMap(bin_table, bin_table_constructor, runtime, error);
|
||||
if (object == NULL)
|
||||
return false;
|
||||
return Runtime_plugBuiltins(runtime, object, error);
|
||||
}
|
||||
|
||||
bool Runtime_plugBuiltinsFromSource(Runtime *runtime, Source *source, Error *error)
|
||||
{
|
||||
Object *rets[8];
|
||||
int retc = runSource(runtime, source, rets, error);
|
||||
if(retc < 0)
|
||||
return false;
|
||||
if (retc == 0)
|
||||
return true;
|
||||
return Runtime_plugBuiltins(runtime, rets[0], error);
|
||||
}
|
||||
|
||||
bool Runtime_plugBuiltinsFromFile(Runtime *runtime, const char *file, Error *error)
|
||||
{
|
||||
Source *source = Source_FromFile(file, error);
|
||||
if (source == NULL)
|
||||
return false;
|
||||
|
||||
bool result = Runtime_plugBuiltinsFromSource(runtime, source, error);
|
||||
|
||||
Source_Free(source);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool Runtime_plugBuiltinsFromString(Runtime *runtime, const char *string, Error *error)
|
||||
{
|
||||
Source *source = Source_FromString("<prelude>", string, -1, error);
|
||||
if (source == NULL)
|
||||
return false;
|
||||
|
||||
bool result = Runtime_plugBuiltinsFromSource(runtime, source, error);
|
||||
|
||||
Source_Free(source);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool Runtime_plugDefaultBuiltins(Runtime *runtime, Error *error)
|
||||
{
|
||||
extern char start_noja[];
|
||||
return Runtime_plugBuiltinsFromStaticMap(runtime, bins_basic, bins_basic_init, error)
|
||||
&& Runtime_plugBuiltinsFromString(runtime, start_noja, error)
|
||||
&& Runtime_plugBuiltinsFromString(runtime, "XXX=999;", error);
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
#include "runtime.h"
|
||||
bool Runtime_plugDefaultBuiltins(Runtime *runtime, Error *error);
|
||||
bool Runtime_plugBuiltinsFromString(Runtime *runtime, const char *string, Error *error);
|
||||
bool Runtime_plugBuiltinsFromFile(Runtime *runtime, const char *file, Error *error);
|
||||
bool Runtime_plugBuiltinsFromStaticMap(Runtime *runtime, StaticMapSlot *bin_table, void (*bin_table_constructor)(StaticMapSlot*), Error *error);
|
||||
bool Runtime_plugBuiltinsFromSource(Runtime *runtime, Source *source, Error *error);
|
||||
@@ -1,220 +0,0 @@
|
||||
|
||||
/* +--------------------------------------------------------------------------+
|
||||
** | _ _ _ |
|
||||
** | | \ | | (_) |
|
||||
** | | \| | ___ _ __ _ |
|
||||
** | | . ` |/ _ \| |/ _` | |
|
||||
** | | |\ | (_) | | (_| | |
|
||||
** | |_| \_|\___/| |\__,_| |
|
||||
** | _/ | |
|
||||
** | |__/ |
|
||||
** +--------------------------------------------------------------------------+
|
||||
** | Copyright (c) 2022 Francesco Cozzuto <francesco.cozzuto@gmail.com> |
|
||||
** +--------------------------------------------------------------------------+
|
||||
** | This file is part of The Noja Interpreter. |
|
||||
** | |
|
||||
** | The Noja Interpreter is free software: you can redistribute it and/or |
|
||||
** | modify it under the terms of the GNU General Public License as published |
|
||||
** | by the Free Software Foundation, either version 3 of the License, or (at |
|
||||
** | your option) any later version. |
|
||||
** | |
|
||||
** | The Noja Interpreter is distributed in the hope that it will be useful, |
|
||||
** | but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
** | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General |
|
||||
** | Public License for more details. |
|
||||
** | |
|
||||
** | You should have received a copy of the GNU General Public License along |
|
||||
** | with The Noja Interpreter. If not, see <http://www.gnu.org/licenses/>. |
|
||||
** +--------------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#include <time.h>
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include "../utils/defs.h"
|
||||
#include "../objects/objects.h"
|
||||
#include "timing.h"
|
||||
#include "runtime.h"
|
||||
|
||||
typedef struct {
|
||||
Object base;
|
||||
const char *name;
|
||||
Runtime *runtime;
|
||||
Executable *exe;
|
||||
int index, argc;
|
||||
Object *closure;
|
||||
TimingID timing_id;
|
||||
} FunctionObject;
|
||||
|
||||
static _Bool free_(Object *self, Error *error)
|
||||
{
|
||||
(void) error;
|
||||
|
||||
FunctionObject *func = (FunctionObject*) self;
|
||||
Executable_Free(func->exe);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void walk(Object *self, void (*callback)(Object **referer, void *userp), void *userp)
|
||||
{
|
||||
FunctionObject *func = (FunctionObject*) self;
|
||||
callback(&func->closure, userp);
|
||||
}
|
||||
|
||||
static int call(Object *self, Object **argv, unsigned int argc, Object *rets[static MAX_RETS], Heap *heap, Error *error)
|
||||
{
|
||||
assert(self != NULL && heap != NULL && error != NULL);
|
||||
|
||||
FunctionObject *func = (FunctionObject*) self;
|
||||
|
||||
assert(func->exe != NULL);
|
||||
assert(func->argc >= 0);
|
||||
assert(func->index >= 0);
|
||||
|
||||
// Make sure the right amount of arguments is provided.
|
||||
|
||||
Object **argv2;
|
||||
|
||||
int expected_argc = func->argc;
|
||||
|
||||
if(expected_argc < (int) argc)
|
||||
{
|
||||
// Nothing to be done. By using
|
||||
// the right argc the additional
|
||||
// arguments are ignored implicitly.
|
||||
argv2 = argv;
|
||||
}
|
||||
else if(expected_argc > (int) argc)
|
||||
{
|
||||
// Some arguments are missing.
|
||||
argv2 = malloc(sizeof(Object*) * expected_argc);
|
||||
|
||||
if(argv2 == NULL)
|
||||
{
|
||||
Error_Report(error, ErrorType_INTERNAL, "No memory");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Copy the provided arguments.
|
||||
for(int i = 0; i < (int) argc; i += 1)
|
||||
argv2[i] = argv[i];
|
||||
|
||||
// Set the unspecified arguments to none.
|
||||
for(int i = argc; i < expected_argc; i += 1)
|
||||
{
|
||||
argv2[i] = Object_NewNone(heap, error);
|
||||
|
||||
if(argv2[i] == NULL)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
// The right amount of arguments was provided.
|
||||
argv2 = argv;
|
||||
|
||||
clock_t begin;
|
||||
TimingID timing_id;
|
||||
TimingTable *timing_table = Runtime_GetTimingTable(func->runtime);
|
||||
if (timing_table != NULL) {
|
||||
begin = clock();
|
||||
|
||||
// Need to save the object's member
|
||||
// before the run function since it
|
||||
// may trigger a GC cycle invalidating
|
||||
// the object pointer.
|
||||
timing_id = func->timing_id;
|
||||
}
|
||||
|
||||
int retc = run(func->runtime, error, func->exe, func->index, func->closure, argv2, expected_argc, rets);
|
||||
|
||||
if (timing_table != NULL) {
|
||||
double time = (double) (clock() - begin) / CLOCKS_PER_SEC;
|
||||
TimingTable_sumCallTime(timing_table, timing_id, time);
|
||||
}
|
||||
|
||||
// NOTE: Every object reference is invalidated from here.
|
||||
|
||||
if(argv2 != argv)
|
||||
free(argv2);
|
||||
|
||||
return retc;
|
||||
}
|
||||
|
||||
static TypeObject t_func = {
|
||||
.base = (Object) { .type = &t_type, .flags = Object_STATIC },
|
||||
.name = "function",
|
||||
.size = sizeof (FunctionObject),
|
||||
.call = call,
|
||||
.walk = walk,
|
||||
.free = free_,
|
||||
};
|
||||
|
||||
/* Symbol: Object_FromNojaFunction
|
||||
*
|
||||
* Creates an object from a noja executable structure.
|
||||
*
|
||||
* Args:
|
||||
* - runtime: The reference to an instanciated Runtime.
|
||||
*
|
||||
* - exe: A noja executable.
|
||||
*
|
||||
* - index: The index of the first bytecode instruction
|
||||
* of the noja function within the executable.
|
||||
*
|
||||
* - argc: The number of arguments the function expects.
|
||||
* It must be positive (unlike [Object_FromNativeFunction],
|
||||
* where -1 means variadic).
|
||||
*
|
||||
* - closure: An object containing variables that will be
|
||||
* accessible from the noja function other than
|
||||
* the ones that will be defined inside it.
|
||||
*
|
||||
* - heap: The heap that will be used to allocate the object.
|
||||
* It can't be NULL.
|
||||
*
|
||||
* - error: Output parameter where error information is stored.
|
||||
* It can't be NULL.
|
||||
*
|
||||
* Returns:
|
||||
* The newly created object. If an error occurred, NULL is returned
|
||||
* and information about the error is stored in the [error] argument.
|
||||
*/
|
||||
Object *Object_FromNojaFunction(Runtime *runtime, const char *name, Executable *exe, int index, int argc, Object *closure, Heap *heap, Error *error)
|
||||
{
|
||||
assert(runtime != NULL);
|
||||
assert(exe != NULL);
|
||||
assert(index >= 0);
|
||||
assert(argc >= 0);
|
||||
assert(heap != NULL);
|
||||
assert(error != NULL);
|
||||
|
||||
FunctionObject *func = (FunctionObject*) Heap_Malloc(heap, &t_func, error);
|
||||
|
||||
if(func == NULL)
|
||||
return NULL;
|
||||
|
||||
Executable *exe_copy = Executable_Copy(exe);
|
||||
|
||||
if(exe_copy == NULL)
|
||||
{
|
||||
Error_Report(error, ErrorType_INTERNAL, "Failed to copy executable");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
func->runtime = runtime;
|
||||
func->name = name; // Should this be copied?
|
||||
func->exe = exe_copy;
|
||||
func->index = index;
|
||||
func->argc = argc;
|
||||
func->closure = closure;
|
||||
|
||||
TimingTable *table = Runtime_GetTimingTable(runtime);
|
||||
if (table != NULL) {
|
||||
#warning "TODO: Calculate line number"
|
||||
size_t line = 0;
|
||||
Source *src = Executable_GetSource(exe);
|
||||
func->timing_id = TimingTable_newEntry(table, src, line, name);
|
||||
}
|
||||
|
||||
return (Object*) func;
|
||||
}
|
||||
@@ -1,173 +0,0 @@
|
||||
|
||||
/* +--------------------------------------------------------------------------+
|
||||
** | _ _ _ |
|
||||
** | | \ | | (_) |
|
||||
** | | \| | ___ _ __ _ |
|
||||
** | | . ` |/ _ \| |/ _` | |
|
||||
** | | |\ | (_) | | (_| | |
|
||||
** | |_| \_|\___/| |\__,_| |
|
||||
** | _/ | |
|
||||
** | |__/ |
|
||||
** +--------------------------------------------------------------------------+
|
||||
** | Copyright (c) 2022 Francesco Cozzuto <francesco.cozzuto@gmail.com> |
|
||||
** +--------------------------------------------------------------------------+
|
||||
** | This file is part of The Noja Interpreter. |
|
||||
** | |
|
||||
** | The Noja Interpreter is free software: you can redistribute it and/or |
|
||||
** | modify it under the terms of the GNU General Public License as published |
|
||||
** | by the Free Software Foundation, either version 3 of the License, or (at |
|
||||
** | your option) any later version. |
|
||||
** | |
|
||||
** | The Noja Interpreter is distributed in the hope that it will be useful, |
|
||||
** | but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
** | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General |
|
||||
** | Public License for more details. |
|
||||
** | |
|
||||
** | You should have received a copy of the GNU General Public License along |
|
||||
** | with The Noja Interpreter. If not, see <http://www.gnu.org/licenses/>. |
|
||||
** +--------------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/*
|
||||
* WHAT IS THIS FILE?
|
||||
* This file implements an object that makes it possible
|
||||
* to call native functions from within noja code.
|
||||
*
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include "../utils/defs.h"
|
||||
#include "../objects/objects.h"
|
||||
#include "runtime.h"
|
||||
|
||||
typedef struct {
|
||||
Object base;
|
||||
Runtime *runtime;
|
||||
int (*callback)(Runtime *runtime, Object **argv, unsigned int argc, Object *rets[MAX_RETS], Error *error);
|
||||
int argc;
|
||||
} NativeFunctionObject;
|
||||
|
||||
static int call(Object *self, Object **argv, unsigned int argc, Object *rets[static MAX_RETS], Heap *heap, Error *error)
|
||||
{
|
||||
assert(self != NULL);
|
||||
assert(heap != NULL);
|
||||
assert(error != NULL);
|
||||
|
||||
NativeFunctionObject *func = (NativeFunctionObject*) self;
|
||||
|
||||
// If the function isn't variadic, make sure
|
||||
// the right amount of arguments is provided.
|
||||
|
||||
Object **argv2;
|
||||
int argc2;
|
||||
|
||||
int expected_argc = func->argc;
|
||||
|
||||
if(expected_argc < 0 || expected_argc == (int) argc)
|
||||
{
|
||||
// The function is variadic or the right
|
||||
// amount of arguments was provided.
|
||||
argv2 = argv;
|
||||
argc2 = argc;
|
||||
}
|
||||
else if(expected_argc < (int) argc)
|
||||
{
|
||||
// Nothing to be done. By using
|
||||
// the right argc the additional
|
||||
// arguments are ignored implicitly.
|
||||
argv2 = argv;
|
||||
argc2 = expected_argc;
|
||||
}
|
||||
else if(expected_argc > (int) argc)
|
||||
{
|
||||
// Some arguments are missing.
|
||||
argv2 = malloc(sizeof(Object*) * expected_argc);
|
||||
argc2 = expected_argc;
|
||||
|
||||
if(argv2 == NULL)
|
||||
{
|
||||
Error_Report(error, 1, "No memory");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Copy the provided arguments.
|
||||
for(int i = 0; i < (int) argc; i += 1)
|
||||
argv2[i] = argv[i];
|
||||
|
||||
// Set the unspecified arguments to none.
|
||||
for(int i = argc; i < expected_argc; i += 1)
|
||||
{
|
||||
argv2[i] = Object_NewNone(heap, error);
|
||||
|
||||
if(argv2[i] == NULL)
|
||||
{
|
||||
free(argv2);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
UNREACHABLE;
|
||||
argv2 = NULL;
|
||||
argc2 = -1;
|
||||
}
|
||||
|
||||
assert(func->callback != NULL);
|
||||
int retc = func->callback(func->runtime, argv2, argc2, rets, error);
|
||||
|
||||
// NOTE: Since the callback may have executed some bytecode, a GC
|
||||
// cycle may have been triggered, therefore we must assume
|
||||
// every object reference that was locally saved is invalidated
|
||||
// from here (the returned object is good tho).
|
||||
|
||||
if(argv2 != argv)
|
||||
free(argv2);
|
||||
|
||||
return retc;
|
||||
}
|
||||
|
||||
static TypeObject t_nfunc = {
|
||||
.base = (Object) { .type = &t_type, .flags = Object_STATIC },
|
||||
.name = "native function",
|
||||
.size = sizeof (NativeFunctionObject),
|
||||
.call = call,
|
||||
};
|
||||
|
||||
/* Symbol: Object_FromNativeFunction
|
||||
*
|
||||
* Creates an object from a function pointer.
|
||||
*
|
||||
* Args:
|
||||
* - runtime: The reference to an instanciated Runtime. This must be
|
||||
* provided so that the callback can also access it.
|
||||
*
|
||||
* - callback: The native function to be executed when this object
|
||||
* is called.
|
||||
*
|
||||
* - argc: The number of arguments the function expects. If -1 is
|
||||
* provided, then the function is considered to be variadic.
|
||||
*
|
||||
* - heap: The heap that will be used to allocate the object.
|
||||
* It can't be NULL.
|
||||
*
|
||||
* - error: Output parameter where error information is stored.
|
||||
* It can't be NULL.
|
||||
*
|
||||
* Returns:
|
||||
* The newly created object. If an error occurred, NULL is returned
|
||||
* and information about the error is stored in the [error] argument.
|
||||
*/
|
||||
Object *Object_FromNativeFunction(Runtime *runtime, int (*callback)(Runtime*, Object**, unsigned int, Object*[static MAX_RETS], Error*), int argc, Heap *heap, Error *error)
|
||||
{
|
||||
assert(callback != NULL);
|
||||
|
||||
NativeFunctionObject *func = (NativeFunctionObject*) Heap_Malloc(heap, &t_nfunc, error);
|
||||
|
||||
if(func == NULL)
|
||||
return NULL;
|
||||
|
||||
func->runtime = runtime;
|
||||
func->callback = callback;
|
||||
func->argc = argc;
|
||||
|
||||
return (Object*) func;
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include "path.h"
|
||||
#include "../utils/defs.h"
|
||||
#include "../utils/path.h"
|
||||
|
||||
// Returns the length written in buff (not considering the zero byte)
|
||||
size_t Runtime_GetCurrentScriptFolder(Runtime *runtime, char *buff, size_t buffsize)
|
||||
{
|
||||
const char *path = Runtime_GetCurrentScriptAbsolutePath(runtime);
|
||||
if(path == NULL) {
|
||||
if(getcwd(buff, buffsize) == NULL)
|
||||
return 0;
|
||||
size_t cwdlen = strlen(buff);
|
||||
if (buff[cwdlen-1] == '/')
|
||||
return cwdlen;
|
||||
else {
|
||||
if (cwdlen+1 >= buffsize)
|
||||
return 0;
|
||||
buff[cwdlen] = '/';
|
||||
return cwdlen+1;
|
||||
}
|
||||
}
|
||||
|
||||
// This following block is a custom implementation
|
||||
// of [dirname], which doesn't write into the input
|
||||
// string and is way buggier. It will for sure give
|
||||
// problems in the future!!
|
||||
size_t dir_len;
|
||||
{
|
||||
// This is buggy code!!
|
||||
size_t path_len = strlen(path);
|
||||
ASSERT(path_len > 0); // Not empty
|
||||
ASSERT(Path_IsAbsolute(path)); // Is absolute
|
||||
ASSERT(path[path_len-1] != '/'); // Doesn't end with a slash.
|
||||
|
||||
size_t popped = 0;
|
||||
while(path[path_len-1-popped] != '/')
|
||||
popped += 1;
|
||||
|
||||
ASSERT(path_len > popped);
|
||||
|
||||
dir_len = path_len - popped;
|
||||
|
||||
ASSERT(dir_len < path_len);
|
||||
ASSERT(path[dir_len-1] == '/');
|
||||
}
|
||||
|
||||
if(dir_len >= buffsize)
|
||||
return 0;
|
||||
|
||||
memcpy(buff, path, dir_len);
|
||||
buff[dir_len] = '\0';
|
||||
return dir_len;
|
||||
}
|
||||
|
||||
const char *Runtime_GetCurrentScriptAbsolutePath(Runtime *runtime)
|
||||
{
|
||||
Executable *exe = Runtime_GetMostRecentExecutable(runtime);
|
||||
if (exe == NULL)
|
||||
return NULL;
|
||||
|
||||
Source *src = Executable_GetSource(exe);
|
||||
if(src == NULL)
|
||||
return NULL;
|
||||
|
||||
const char *path = Source_GetAbsolutePath(src);
|
||||
if(path == NULL)
|
||||
return NULL;
|
||||
|
||||
ASSERT(path[0] != '\0');
|
||||
return path;
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
#include <stddef.h>
|
||||
#include "runtime.h"
|
||||
const char *Runtime_GetCurrentScriptAbsolutePath(Runtime *runtime);
|
||||
size_t Runtime_GetCurrentScriptFolder(Runtime *runtime, char *buff, size_t buffsize);
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,12 @@
|
||||
#include "runtime.h"
|
||||
int runSource(Runtime *runtime, Source *source, Object *rets[static MAX_RETS], Error *error);
|
||||
int runBytecodeSource(Runtime *runtime, Source *source, Object *rets[static MAX_RETS], Error *error);
|
||||
bool runFile(Runtime *runtime, const char *file, Error *error);
|
||||
bool runString(Runtime *runtime, const char *string, Error *error);
|
||||
bool runBytecodeFile(Runtime *runtime, const char *file, Error *error);
|
||||
bool runBytecodeString(Runtime *runtime, const char *string, Error *error);
|
||||
int runFileEx(Runtime *runtime, const char *file, Object *rets[static MAX_RETS], Error *error);
|
||||
int runStringEx(Runtime *runtime, const char *name, const char *string, Object *rets[static MAX_RETS], Error *error);
|
||||
int runBytecodeFileEx(Runtime *runtime, const char *file, Object *rets[static MAX_RETS], Error *error);
|
||||
int runBytecodeStringEx(Runtime *runtime, const char *name, const char *string, Object *rets[static MAX_RETS], Error *error);
|
||||
int runFileRelativeToScript(Runtime *runtime, const char *file, Object *rets[static MAX_RETS], Error *error);
|
||||
+448
-1340
File diff suppressed because it is too large
Load Diff
@@ -40,6 +40,7 @@
|
||||
|
||||
typedef struct xRuntime Runtime;
|
||||
typedef struct xSnapshot Snapshot;
|
||||
typedef struct StaticMapSlot StaticMapSlot;
|
||||
|
||||
typedef struct {
|
||||
bool (*func)(Runtime*, void*);
|
||||
@@ -48,31 +49,49 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
bool time;
|
||||
size_t heap;
|
||||
size_t stack;
|
||||
RuntimeCallback callback;
|
||||
} RuntimeConfig;
|
||||
|
||||
Runtime* Runtime_New(int heap_size, RuntimeConfig config);
|
||||
Runtime* Runtime_New2(Heap *heap, bool free_it, RuntimeConfig config);
|
||||
Runtime* Runtime_New(RuntimeConfig config);
|
||||
void Runtime_Free(Runtime *runtime);
|
||||
_Bool Runtime_Pop(Runtime *runtime, Error *error, unsigned int n);
|
||||
_Bool Runtime_Push(Runtime *runtime, Error *error, Object *obj);
|
||||
|
||||
Object *Runtime_Top(Runtime *runtime, int n);
|
||||
bool Runtime_Pop (Runtime *runtime, Error *error, Object **p, unsigned int n);
|
||||
bool Runtime_Push(Runtime *runtime, Error *error, Object *obj);
|
||||
bool Runtime_PushFrame(Runtime *runtime, Error *error, Object *closure, Executable *exe, int index);
|
||||
bool Runtime_PushNativeFrame(Runtime *runtime, Error *error);
|
||||
bool Runtime_PushFailedFrame(Runtime *runtime, Error *error, Source *source, int offset);
|
||||
bool Runtime_PopFrame(Runtime *runtime);
|
||||
void Runtime_SetInstructionIndex(Runtime *runtime, int index);
|
||||
bool Runtime_SetVariable(Runtime *runtime, Error *error, const char *name, Object *value);
|
||||
bool Runtime_GetVariable(Runtime *runtime, Error *error, const char *name, Object **value);
|
||||
Object *Runtime_GetLocals(Runtime *runtime);
|
||||
Object *Runtime_GetClosure(Runtime *runtime);
|
||||
size_t Runtime_GetFrameStackUsage(Runtime *runtime);
|
||||
bool Runtime_WasInterrupted(Runtime *runtime);
|
||||
RuntimeCallback Runtime_GetCallback(Runtime *runtime);
|
||||
bool Runtime_CollectGarbage(Runtime *runtime, Error *error);
|
||||
void Runtime_PrintStackTrace(Runtime *runtime, FILE *stream);
|
||||
void Runtime_Interrupt(Runtime *runtime);
|
||||
Heap* Runtime_GetHeap(Runtime *runtime);
|
||||
Stack* Runtime_GetStack(Runtime *runtime);
|
||||
Object* Runtime_GetBuiltins(Runtime *runtime);
|
||||
void Runtime_SetBuiltins(Runtime *runtime, Object *builtins);
|
||||
int Runtime_GetCurrentIndex(Runtime *runtime);
|
||||
Executable *Runtime_GetCurrentExecutable(Runtime *runtime);
|
||||
Executable *Runtime_GetMostRecentExecutable(Runtime *runtime);
|
||||
size_t Runtime_GetCurrentScriptFolder(Runtime *runtime, char *buff, size_t buffsize);
|
||||
const char *Runtime_GetCurrentScriptAbsolutePath(Runtime *runtime);
|
||||
TimingTable *Runtime_GetTimingTable(Runtime *runtime);
|
||||
RuntimeConfig Runtime_GetDefaultConfigs();
|
||||
|
||||
bool Runtime_plugBuiltins(Runtime *runtime, Object *object, Error *error);
|
||||
int Runtime_runSource(Runtime *runtime, Source *source, Object *rets[static MAX_RETS], Error *error);
|
||||
int Runtime_runBytecodeSource(Runtime *runtime, Source *source, Object *rets[static MAX_RETS], Error *error);
|
||||
|
||||
Snapshot *Snapshot_New(Runtime *runtime);
|
||||
void Snapshot_Free(Snapshot *snapshot);
|
||||
void Snapshot_Print(Snapshot *snapshot, FILE *fp);
|
||||
int run(Runtime *runtime, Error *error, Executable *exe, int index, Object *closure, Object **argv, int argc, Object *rets[static MAX_RETS]);
|
||||
|
||||
typedef enum {
|
||||
SM_END,
|
||||
@@ -87,8 +106,6 @@ typedef enum {
|
||||
SM_OBJECT,
|
||||
} StaticMapSlotKind;
|
||||
|
||||
typedef struct StaticMapSlot StaticMapSlot;
|
||||
|
||||
struct StaticMapSlot {
|
||||
const char *name;
|
||||
StaticMapSlotKind kind;
|
||||
@@ -117,5 +134,6 @@ typedef struct {
|
||||
|
||||
void RuntimeError_Init(RuntimeError *error, Runtime *runtime);
|
||||
void RuntimeError_Free(RuntimeError *error);
|
||||
void RuntimeError_Print(RuntimeError *error, ErrorType type_if_unspecified, FILE *stream);
|
||||
|
||||
#endif
|
||||
@@ -1,59 +0,0 @@
|
||||
|
||||
/* +--------------------------------------------------------------------------+
|
||||
** | _ _ _ |
|
||||
** | | \ | | (_) |
|
||||
** | | \| | ___ _ __ _ |
|
||||
** | | . ` |/ _ \| |/ _` | |
|
||||
** | | |\ | (_) | | (_| | |
|
||||
** | |_| \_|\___/| |\__,_| |
|
||||
** | _/ | |
|
||||
** | |__/ |
|
||||
** +--------------------------------------------------------------------------+
|
||||
** | Copyright (c) 2022 Francesco Cozzuto <francesco.cozzuto@gmail.com> |
|
||||
** +--------------------------------------------------------------------------+
|
||||
** | This file is part of The Noja Interpreter. |
|
||||
** | |
|
||||
** | The Noja Interpreter is free software: you can redistribute it and/or |
|
||||
** | modify it under the terms of the GNU General Public License as published |
|
||||
** | by the Free Software Foundation, either version 3 of the License, or (at |
|
||||
** | your option) any later version. |
|
||||
** | |
|
||||
** | The Noja Interpreter is distributed in the hope that it will be useful, |
|
||||
** | but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
** | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General |
|
||||
** | Public License for more details. |
|
||||
** | |
|
||||
** | You should have received a copy of the GNU General Public License along |
|
||||
** | with The Noja Interpreter. If not, see <http://www.gnu.org/licenses/>. |
|
||||
** +--------------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include "runtime.h"
|
||||
|
||||
static void on_report(Error *error)
|
||||
{
|
||||
assert(error != NULL);
|
||||
|
||||
RuntimeError *error2 = (RuntimeError*) error;
|
||||
|
||||
if(error2->runtime != NULL)
|
||||
error2->snapshot = Snapshot_New(error2->runtime);
|
||||
}
|
||||
|
||||
void RuntimeError_Init(RuntimeError *error, Runtime *runtime)
|
||||
{
|
||||
assert(error != NULL);
|
||||
|
||||
Error_Init2(&error->base, on_report);
|
||||
|
||||
error->runtime = runtime;
|
||||
error->snapshot = NULL;
|
||||
}
|
||||
|
||||
void RuntimeError_Free(RuntimeError *error)
|
||||
{
|
||||
if(error->snapshot)
|
||||
Snapshot_Free(error->snapshot);
|
||||
Error_Free(&error->base);
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
#include "serialize_profiling.h"
|
||||
|
||||
void Runtime_SerializeProfilingResultsToStream(Runtime *runtime, FILE *stream)
|
||||
{
|
||||
TimingTable *table = Runtime_GetTimingTable(runtime);
|
||||
if (table == NULL)
|
||||
return; // Runtime wasn't profiling
|
||||
|
||||
size_t count;
|
||||
const FunctionExecutionSummary *summary = TimingTable_getSummary(table, &count);
|
||||
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
if (summary[i].calls > 0) {
|
||||
fprintf(stream, "%20s - %s - %ld calls - %.2lfus\n",
|
||||
summary[i].name,
|
||||
Source_GetName(summary[i].src),
|
||||
summary[i].calls,
|
||||
summary[i].time * 1000000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Runtime_SerializeProfilingResultsToFile(Runtime *runtime, const char *file)
|
||||
{
|
||||
FILE *stream = fopen(file, "wb");
|
||||
if (stream == NULL)
|
||||
return false;
|
||||
Runtime_SerializeProfilingResultsToStream(runtime, stream);
|
||||
fclose(stream);
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
#include "runtime.h"
|
||||
|
||||
void Runtime_SerializeProfilingResultsToStream(Runtime *runtime, FILE *stream);
|
||||
bool Runtime_SerializeProfilingResultsToFile(Runtime *runtime, const char *file);
|
||||
Reference in New Issue
Block a user