C: allow to define custom logging functions. Use unified logging function within VM

This commit is contained in:
Alexey Andreev 2020-01-30 18:18:16 +03:00
parent f13a7e6375
commit 374f7c6634
4 changed files with 117 additions and 72 deletions

View File

@ -55,6 +55,10 @@
#define TEAVM_WINDOWS_LOG 0
#endif
#ifndef TEAVM_CUSTOM_LOG
#define TEAVM_CUSTOM_LOG 0
#endif
#ifndef TEAVM_GC_LOG
#define TEAVM_GC_LOG 0
#endif

View File

@ -1,5 +1,6 @@
#include "heaptrace.h"
#include "core.h"
#include "log.h"
#include "definitions.h"
#include "memory.h"
#include "time.h"
@ -12,23 +13,23 @@
#include <wctype.h>
#include <stdbool.h>
#define TEAVM_GC_LOG_BUFFER_SIZE 512
#if TEAVM_WINDOWS
#include <Windows.h>
#endif
#if !TEAVM_WINDOWS_LOG
#define TEAVM_OUTPUT_STRING(s) fprintf(stderr, s)
#else
#define TEAVM_OUTPUT_STRING(s) OutputDebugStringW(L##s)
#endif
#if TEAVM_MEMORY_TRACE
uint8_t* teavm_gc_heapMap = NULL;
uint8_t* teavm_gc_markMap = NULL;
#endif
static inline void teavm_gc_print(wchar_t* s) {
teavm_printWString(s);
}
void teavm_outOfMemory() {
TEAVM_OUTPUT_STRING("Application crashed due to lack of free memory\n");
teavm_gc_print(L"Application crashed due to lack of free memory\n");
teavm_gc_writeHeapDump();
abort();
}
@ -73,16 +74,20 @@ void teavm_gc_allocate(void* address, int32_t size) {
uint8_t* map = teavm_gc_heapMap + (((char*) address - (char*) teavm_gc_heapAddress) / sizeof(void*));
if (*map != 0) {
fprintf(stderr, "[GC] trying allocate at memory in use at: %d\n",
wchar_t buffer[TEAVM_GC_LOG_BUFFER_SIZE];
swprintf(buffer, TEAVM_GC_LOG_BUFFER_SIZE, L"[GC] trying allocate at memory in use at: %d\n",
(int) ((char*) address - (char*) teavm_gc_heapAddress));
teavm_gc_print(buffer);
abort();
}
*map++ = 1;
for (int32_t i = 1; i < size; ++i) {
if (*map != 0) {
fprintf(stderr, "[GC] trying allocate at memory in use at: %d\n",
wchar_t buffer[TEAVM_GC_LOG_BUFFER_SIZE];
swprintf(buffer, TEAVM_GC_LOG_BUFFER_SIZE, L"[GC] trying allocate at memory in use at: %d\n",
(int) ((char*) address - (char*) teavm_gc_heapAddress));
teavm_gc_print(buffer);
abort();
}
*map++ = 2;
@ -104,8 +109,10 @@ void teavm_gc_free(void* address, int32_t size) {
size /= sizeof(void*);
for (int32_t i = 0; i < size; ++i) {
if (markMap[i] != 0) {
fprintf(stderr, "[GC] trying to release reachable object at: %d\n",
wchar_t buffer[TEAVM_GC_LOG_BUFFER_SIZE];
swprintf(buffer, TEAVM_GC_LOG_BUFFER_SIZE, L"[GC] trying to release reachable object at: %d\n",
(int) ((char*) address - (char*) teavm_gc_heapAddress));
teavm_gc_print(buffer);
abort();
}
}
@ -130,8 +137,10 @@ void teavm_gc_assertFree(void* address, int32_t size) {
size /= sizeof(void*);
for (int32_t i = 0; i < size; ++i) {
if (map[i] != 0) {
fprintf(stderr, "[GC] memory supposed to be free at: %d\n",
wchar_t buffer[TEAVM_GC_LOG_BUFFER_SIZE];
swprintf(buffer, TEAVM_GC_LOG_BUFFER_SIZE, L"[GC] memory supposed to be free at: %d\n",
(int) ((char*) address - (char*) teavm_gc_heapAddress));
teavm_gc_print(buffer);
abort();
}
}
@ -186,8 +195,10 @@ void teavm_gc_mark(void* address) {
size /= sizeof(void*);
if (*map++ != 1 || *markMap != 0) {
fprintf(stderr, "[GC] assertion failed marking object at: %d\n",
wchar_t buffer[TEAVM_GC_LOG_BUFFER_SIZE];
swprintf(buffer, TEAVM_GC_LOG_BUFFER_SIZE, L"[GC] assertion failed marking object at: %d\n",
(int) ((char*) address - (char*) teavm_gc_heapAddress));
teavm_gc_print(buffer);
abort();
}
*markMap++ = 1;
@ -218,8 +229,12 @@ void teavm_gc_move(void* from, void* to, int32_t size) {
if (mapFrom > mapTo) {
for (int32_t i = 0; i < size; ++i) {
if (mapFrom[i] == 0 || mapTo[i] != 0) {
fprintf(stderr, "[GC] assertion failed moving object from: %d to %d\n",
(int) ((char*) from - (char*) teavm_gc_heapAddress), (int) ((char*) to - (char*) teavm_gc_heapAddress));
wchar_t buffer[TEAVM_GC_LOG_BUFFER_SIZE];
swprintf(buffer, TEAVM_GC_LOG_BUFFER_SIZE,
L"[GC] assertion failed moving object from: %d to %d\n",
(int) ((char*) from - (char*) teavm_gc_heapAddress),
(int) ((char*) to - (char*) teavm_gc_heapAddress));
teavm_gc_print(buffer);
abort();
}
mapTo[i] = mapFrom[i];
@ -428,17 +443,7 @@ void teavm_gc_defragCompleted() {
#endif
}
#define TEAVM_GC_LOG_BUFFER_SIZE 512
#if TEAVM_GC_STATS
static void teavm_gc_print(wchar_t* s) {
#if TEAVM_WINDOWS_LOG
OutputDebugStringW(s);
#else
fprintf(stderr, "%ls", s);
#endif
}
static void teavm_gc_printStats() {
wchar_t buffer[TEAVM_GC_LOG_BUFFER_SIZE];

View File

@ -9,63 +9,96 @@
#include <Windows.h>
#endif
static char16_t* teavm_utf16ToUtf32(char16_t* source, char32_t* target) {
char16_t c = *source;
if ((c & 0xFC00) == 0xD800) {
char16_t n = *(source + 1);
if ((n & 0xFC00) == 0xDC00) {
*target = (((c & ~0xFC00) << 10) | (n & ~0xFC00)) + 0x10000;
return source + 2;
#if !TEAVM_CUSTOM_LOG
static char16_t* teavm_utf16ToUtf32(char16_t* source, char32_t* target) {
char16_t c = *source;
if ((c & 0xFC00) == 0xD800) {
char16_t n = *(source + 1);
if ((n & 0xFC00) == 0xDC00) {
*target = (((c & ~0xFC00) << 10) | (n & ~0xFC00)) + 0x10000;
return source + 2;
}
}
*target = c;
return source + 1;
}
*target = c;
return source + 1;
}
void teavm_printString(char16_t* s) {
#if !TEAVM_WINDOWS_LOG
#if TEAVM_WINDOWS
void teavm_printString(char16_t* s) {
#if !TEAVM_WINDOWS_LOG
#if TEAVM_WINDOWS
fprintf(stderr, "%ls", s);
#else
int32_t cap = 128;
wchar_t* buf = malloc(sizeof(wchar_t) * cap);
wchar_t* out = buf;
int32_t sz = 0;
while (*s != '\0') {
s = teavm_utf16ToUtf32(s, out++);
if (++sz == cap) {
cap *= 2;
buf = realloc(buf, sizeof(wchar_t) * cap);
out = buf + sz;
}
}
*out = '\0';
fprintf(stderr, "%ls", buf);
free(buf);
#endif
#else
OutputDebugStringW(s);
#endif
}
void teavm_printWString(wchar_t* s) {
#if !TEAVM_WINDOWS_LOG
fprintf(stderr, "%ls", s);
#else
int32_t cap = 128;
wchar_t* buf = malloc(sizeof(wchar_t) * cap);
wchar_t* out = buf;
int32_t sz = 0;
while (*s != '\0') {
s = teavm_utf16ToUtf32(s, out++);
if (++sz == cap) {
cap *= 2;
buf = realloc(buf, sizeof(wchar_t) * cap);
out = buf + sz;
}
}
*out = '\0';
fprintf(stderr, "%ls", buf);
free(buf);
OutputDebugStringW(s);
#endif
#else
OutputDebugStringW(s);
#endif
}
}
void teavm_printInt(int32_t i) {
#if !TEAVM_WINDOWS_LOG
fprintf(stderr, "%" PRId32, i);
#else
wchar_t str[10];
swprintf(str, 10, L"%d", i);
OutputDebugStringW(str);
#endif
}
void teavm_printInt(int32_t i) {
#if !TEAVM_WINDOWS_LOG
fprintf(stderr, "%" PRId32, i);
void teavm_logCodePoint(int32_t c) {
putwchar(c);
}
#else
wchar_t str[10];
swprintf(str, 10, L"%d", i);
OutputDebugStringW(str);
void teavm_logCodePoint(int32_t c) {
char16_t buffer[2] = { (char16_t) c, 0 };
OutputDebugStringW(buffer);
}
#endif
}
#endif
static int32_t teavm_logCharBuffer;
static int teavm_logCharBufferRemaining;
static int teavm_logCharBufferSize;
#if !TEAVM_WINDOWS_LOG
void teavm_logchar(int32_t c) {
putwchar(c);
void teavm_logchar(int32_t c) {
if (teavm_logCharBufferRemaining > 0) {
teavm_logCharBuffer = teavm_logCharBuffer << 6 | (c & 0x3F);
if (--teavm_logCharBufferRemaining == 0) {
teavm_logCodePoint(teavm_logCharBuffer);
}
} else if ((c & 0x80) == 0) {
teavm_logCodePoint(c);
} else if ((c & 0xE0) == 0xC0) {
teavm_logCharBuffer = c & 0x1F;
teavm_logCharBufferRemaining = 1;
} else if ((c & 0xF0) == 0xE0) {
teavm_logCharBuffer = c & 0x0F;
teavm_logCharBufferRemaining = 2;
} else if ((c & 0xF8) == 0xF0) {
teavm_logCharBuffer = c & 0x07;
teavm_logCharBufferRemaining = 3;
}
#else
void teavm_logchar(int32_t c) {
char16_t buffer[2] = { (char16_t) c, 0 };
OutputDebugStringW(buffer);
}
#endif
}

View File

@ -1,7 +1,10 @@
#pragma once
#include <stdint.h>
#include <uchar.h>
#include <wchar.h>
extern void teavm_printString(char16_t*);
extern void teavm_printWString(wchar_t*);
extern void teavm_printInt(int32_t);
extern void teavm_logchar(int32_t);
extern void teavm_logchar(int32_t);
extern void teavm_logCodePoint(int32_t);