Merge commit 'goog/master' into merge_master
This commit is contained in:
commit
e26cbeacaf
5 changed files with 327 additions and 129 deletions
128
include/android/log.h
Normal file
128
include/android/log.h
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
/*
|
||||
* Copyright (C) 2009 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef _ANDROID_LOG_H
|
||||
#define _ANDROID_LOG_H
|
||||
|
||||
/******************************************************************
|
||||
*
|
||||
* IMPORTANT NOTICE:
|
||||
*
|
||||
* This file is part of Android's set of stable system headers
|
||||
* exposed by the Android NDK (Native Development Kit) since
|
||||
* platform release 1.5
|
||||
*
|
||||
* Third-party source AND binary code relies on the definitions
|
||||
* here to be FROZEN ON ALL UPCOMING PLATFORM RELEASES.
|
||||
*
|
||||
* - DO NOT MODIFY ENUMS (EXCEPT IF YOU ADD NEW 32-BIT VALUES)
|
||||
* - DO NOT MODIFY CONSTANTS OR FUNCTIONAL MACROS
|
||||
* - DO NOT CHANGE THE SIGNATURE OF FUNCTIONS IN ANY WAY
|
||||
* - DO NOT CHANGE THE LAYOUT OR SIZE OF STRUCTURES
|
||||
*/
|
||||
|
||||
/*
|
||||
* Support routines to send messages to the Android in-kernel log buffer,
|
||||
* which can later be accessed through the 'logcat' utility.
|
||||
*
|
||||
* Each log message must have
|
||||
* - a priority
|
||||
* - a log tag
|
||||
* - some text
|
||||
*
|
||||
* The tag normally corresponds to the component that emits the log message,
|
||||
* and should be reasonably small.
|
||||
*
|
||||
* Log message text may be truncated to less than an implementation-specific
|
||||
* limit (e.g. 1023 characters max).
|
||||
*
|
||||
* Note that a newline character ("\n") will be appended automatically to your
|
||||
* log message, if not already there. It is not possible to send several messages
|
||||
* and have them appear on a single line in logcat.
|
||||
*
|
||||
* PLEASE USE LOGS WITH MODERATION:
|
||||
*
|
||||
* - Sending log messages eats CPU and slow down your application and the
|
||||
* system.
|
||||
*
|
||||
* - The circular log buffer is pretty small (<64KB), sending many messages
|
||||
* might push off other important log messages from the rest of the system.
|
||||
*
|
||||
* - In release builds, only send log messages to account for exceptional
|
||||
* conditions.
|
||||
*
|
||||
* NOTE: These functions MUST be implemented by /system/lib/liblog.so
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Android log priority values, in ascending priority order.
|
||||
*/
|
||||
typedef enum android_LogPriority {
|
||||
ANDROID_LOG_UNKNOWN = 0,
|
||||
ANDROID_LOG_DEFAULT, /* only for SetMinPriority() */
|
||||
ANDROID_LOG_VERBOSE,
|
||||
ANDROID_LOG_DEBUG,
|
||||
ANDROID_LOG_INFO,
|
||||
ANDROID_LOG_WARN,
|
||||
ANDROID_LOG_ERROR,
|
||||
ANDROID_LOG_FATAL,
|
||||
ANDROID_LOG_SILENT, /* only for SetMinPriority(); must be last */
|
||||
} android_LogPriority;
|
||||
|
||||
/*
|
||||
* Send a simple string to the log.
|
||||
*/
|
||||
int __android_log_write(int prio, const char *tag, const char *text);
|
||||
|
||||
/*
|
||||
* Send a formatted string to the log, used like printf(fmt,...)
|
||||
*/
|
||||
int __android_log_print(int prio, const char *tag, const char *fmt, ...)
|
||||
#if defined(__GNUC__)
|
||||
__attribute__ ((format(printf, 3, 4)))
|
||||
#endif
|
||||
;
|
||||
|
||||
/*
|
||||
* A variant of __android_log_print() that takes a va_list to list
|
||||
* additional parameters.
|
||||
*/
|
||||
int __android_log_vprint(int prio, const char *tag,
|
||||
const char *fmt, va_list ap);
|
||||
|
||||
/*
|
||||
* Log an assertion failure and SIGTRAP the process to have a chance
|
||||
* to inspect it, if a debugger is attached. This uses the FATAL priority.
|
||||
*/
|
||||
void __android_log_assert(const char *cond, const char *tag,
|
||||
const char *fmt, ...)
|
||||
#if defined(__GNUC__)
|
||||
__attribute__ ((noreturn))
|
||||
__attribute__ ((format(printf, 3, 4)))
|
||||
#endif
|
||||
;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _ANDROID_LOG_H */
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
* Copyright (C) 2009 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -17,6 +17,12 @@
|
|||
#ifndef _ANDROID_CUTILS_LOGD_H
|
||||
#define _ANDROID_CUTILS_LOGD_H
|
||||
|
||||
/* the stable/frozen log-related definitions have been
|
||||
* moved to this header, which is exposed by the NDK
|
||||
*/
|
||||
#include <android/log.h>
|
||||
|
||||
/* the rest is only used internally by the system */
|
||||
#include <time.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
|
@ -32,45 +38,10 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Priority values, in ascending priority order.
|
||||
*/
|
||||
typedef enum android_LogPriority {
|
||||
ANDROID_LOG_UNKNOWN = 0,
|
||||
ANDROID_LOG_DEFAULT, /* only for SetMinPriority() */
|
||||
ANDROID_LOG_VERBOSE,
|
||||
ANDROID_LOG_DEBUG,
|
||||
ANDROID_LOG_INFO,
|
||||
ANDROID_LOG_WARN,
|
||||
ANDROID_LOG_ERROR,
|
||||
ANDROID_LOG_FATAL,
|
||||
ANDROID_LOG_SILENT, /* only for SetMinPriority(); must be last */
|
||||
} android_LogPriority;
|
||||
|
||||
int __android_log_write(int prio, const char *tag, const char *text);
|
||||
|
||||
int __android_log_vprint(int prio, const char *tag,
|
||||
const char *fmt, va_list ap);
|
||||
|
||||
int __android_log_bwrite(int32_t tag, const void *payload, size_t len);
|
||||
int __android_log_btwrite(int32_t tag, char type, const void *payload,
|
||||
size_t len);
|
||||
|
||||
int __android_log_print(int prio, const char *tag, const char *fmt, ...)
|
||||
#if defined(__GNUC__)
|
||||
__attribute__ ((format(printf, 3, 4)))
|
||||
#endif
|
||||
;
|
||||
|
||||
|
||||
void __android_log_assert(const char *cond, const char *tag,
|
||||
const char *fmt, ...)
|
||||
#if defined(__GNUC__)
|
||||
__attribute__ ((noreturn))
|
||||
__attribute__ ((format(printf, 3, 4)))
|
||||
#endif
|
||||
;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
271
libacc/acc.cpp
271
libacc/acc.cpp
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include <ctype.h>
|
||||
#include <dlfcn.h>
|
||||
#include <setjmp.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
|
@ -45,10 +46,24 @@
|
|||
|
||||
namespace acc {
|
||||
|
||||
class Compiler {
|
||||
class ErrorSink {
|
||||
public:
|
||||
void error(const char *fmt, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
verror(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
virtual void verror(const char* fmt, va_list ap) = 0;
|
||||
};
|
||||
|
||||
class Compiler : public ErrorSink {
|
||||
class CodeBuf {
|
||||
char* ind;
|
||||
char* ind; // Output code pointer
|
||||
char* pProgramBase;
|
||||
ErrorSink* mErrorSink;
|
||||
int mSize;
|
||||
|
||||
void release() {
|
||||
if (pProgramBase != 0) {
|
||||
|
|
@ -57,10 +72,21 @@ class Compiler {
|
|||
}
|
||||
}
|
||||
|
||||
void check(int n) {
|
||||
int newSize = ind - pProgramBase + n;
|
||||
if (newSize > mSize) {
|
||||
if (mErrorSink) {
|
||||
mErrorSink->error("Code too large: %d bytes", newSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
CodeBuf() {
|
||||
pProgramBase = 0;
|
||||
ind = 0;
|
||||
mErrorSink = 0;
|
||||
mSize = 0;
|
||||
}
|
||||
|
||||
~CodeBuf() {
|
||||
|
|
@ -69,11 +95,17 @@ class Compiler {
|
|||
|
||||
void init(int size) {
|
||||
release();
|
||||
mSize = size;
|
||||
pProgramBase = (char*) calloc(1, size);
|
||||
ind = pProgramBase;
|
||||
}
|
||||
|
||||
void setErrorSink(ErrorSink* pErrorSink) {
|
||||
mErrorSink = pErrorSink;
|
||||
}
|
||||
|
||||
int o4(int n) {
|
||||
check(4);
|
||||
intptr_t result = (intptr_t) ind;
|
||||
* (int*) ind = n;
|
||||
ind += 4;
|
||||
|
|
@ -84,6 +116,7 @@ class Compiler {
|
|||
* Output a byte. Handles all values, 0..ff.
|
||||
*/
|
||||
void ob(int n) {
|
||||
check(1);
|
||||
*ind++ = n;
|
||||
}
|
||||
|
||||
|
|
@ -123,11 +156,22 @@ class Compiler {
|
|||
|
||||
class CodeGenerator {
|
||||
public:
|
||||
CodeGenerator() {}
|
||||
CodeGenerator() {
|
||||
mErrorSink = 0;
|
||||
pCodeBuf = 0;
|
||||
}
|
||||
virtual ~CodeGenerator() {}
|
||||
|
||||
virtual void init(CodeBuf* pCodeBuf) {
|
||||
this->pCodeBuf = pCodeBuf;
|
||||
pCodeBuf->setErrorSink(mErrorSink);
|
||||
}
|
||||
|
||||
void setErrorSink(ErrorSink* pErrorSink) {
|
||||
mErrorSink = pErrorSink;
|
||||
if (pCodeBuf) {
|
||||
pCodeBuf->setErrorSink(mErrorSink);
|
||||
}
|
||||
}
|
||||
|
||||
/* Emit a function prolog.
|
||||
|
|
@ -323,8 +367,16 @@ class Compiler {
|
|||
intptr_t getSize() {
|
||||
return pCodeBuf->getSize();
|
||||
}
|
||||
|
||||
void error(const char* fmt,...) {
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
mErrorSink->verror(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
private:
|
||||
CodeBuf* pCodeBuf;
|
||||
ErrorSink* mErrorSink;
|
||||
};
|
||||
|
||||
#ifdef PROVIDE_ARM_CODEGEN
|
||||
|
|
@ -643,7 +695,7 @@ class Compiler {
|
|||
virtual void callRelative(int t) {
|
||||
LOG_API("callRelative(%d);\n", t);
|
||||
int abs = t + getPC() + jumpOffset();
|
||||
fprintf(stderr, "abs=%d (0x%08x)\n", abs, abs);
|
||||
LOG_API("abs=%d (0x%08x)\n", abs, abs);
|
||||
if (t >= - (1 << 25) && t < (1 << 25)) {
|
||||
o4(0xEB000000 | encodeAddress(t));
|
||||
} else {
|
||||
|
|
@ -791,14 +843,6 @@ class Compiler {
|
|||
static int runtime_MOD(int a, int b) {
|
||||
return b % a;
|
||||
}
|
||||
|
||||
void error(const char* fmt,...) {
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
vfprintf(stderr, fmt, ap);
|
||||
va_end(ap);
|
||||
exit(12);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // PROVIDE_ARM_CODEGEN
|
||||
|
|
@ -980,8 +1024,7 @@ class Compiler {
|
|||
|
||||
int decodeOp(int op) {
|
||||
if (op < 0 || op > OP_COUNT) {
|
||||
fprintf(stderr, "Out-of-range operator: %d\n", op);
|
||||
exit(1);
|
||||
error("Out-of-range operator: %d\n", op);
|
||||
}
|
||||
return operatorHelper[op];
|
||||
}
|
||||
|
|
@ -1027,26 +1070,31 @@ class Compiler {
|
|||
size_t mPosition;
|
||||
};
|
||||
|
||||
/* vars: value of variables
|
||||
loc : local variable index
|
||||
glo : global variable index
|
||||
ind : output code ptr
|
||||
rsym: return symbol
|
||||
prog: output code
|
||||
dstk: define stack
|
||||
dptr, dch: macro state
|
||||
*/
|
||||
intptr_t tok, tokc, tokl, ch, vars, rsym, loc, glo, sym_stk, dstk,
|
||||
dptr, dch, last_id;
|
||||
int ch; // Current input character, or EOF
|
||||
intptr_t tok; // token
|
||||
intptr_t tokc; // token extra info
|
||||
int tokl; // token operator level
|
||||
intptr_t rsym; // return symbol
|
||||
intptr_t loc; // local variable index
|
||||
char* glo; // global variable index
|
||||
char* sym_stk;
|
||||
char* dstk; // Define stack
|
||||
char* dptr; // Macro state: Points to macro text during macro playback.
|
||||
int dch; // Macro state: Saves old value of ch during a macro playback.
|
||||
char* last_id;
|
||||
void* pSymbolBase;
|
||||
void* pGlobalBase;
|
||||
void* pVarsBase;
|
||||
char* pGlobalBase;
|
||||
char* pVarsBase; // Value of variables
|
||||
|
||||
InputStream* file;
|
||||
|
||||
CodeBuf codeBuf;
|
||||
CodeGenerator* pGen;
|
||||
|
||||
static const int ERROR_BUF_SIZE = 512;
|
||||
char mErrorBuf[ERROR_BUF_SIZE];
|
||||
jmp_buf mErrorRecoveryJumpBuf;
|
||||
|
||||
static const int ALLOC_SIZE = 99999;
|
||||
|
||||
/* depends on the init string */
|
||||
|
|
@ -1106,12 +1154,15 @@ class Compiler {
|
|||
static const char operatorLevel[];
|
||||
|
||||
void pdef(int t) {
|
||||
*(char *) dstk++ = t;
|
||||
if (dstk - sym_stk >= ALLOC_SIZE) {
|
||||
error("Symbol table exhausted");
|
||||
}
|
||||
*dstk++ = t;
|
||||
}
|
||||
|
||||
void inp() {
|
||||
if (dptr) {
|
||||
ch = *(char *) dptr++;
|
||||
ch = *dptr++;
|
||||
if (ch == TAG_MACRO) {
|
||||
dptr = 0;
|
||||
ch = dch;
|
||||
|
|
@ -1145,7 +1196,7 @@ class Compiler {
|
|||
next();
|
||||
pdef(TAG_TOK); /* fill last ident tag */
|
||||
*(int *) tok = SYM_DEFINE;
|
||||
*(int *) (tok + 4) = dstk; /* define stack */
|
||||
*(char* *) (tok + 4) = dstk; /* define stack */
|
||||
}
|
||||
/* well we always save the values ! */
|
||||
while (ch != '\n') {
|
||||
|
|
@ -1168,21 +1219,27 @@ class Compiler {
|
|||
inp();
|
||||
}
|
||||
if (isdigit(tok)) {
|
||||
tokc = strtol((char*) last_id, 0, 0);
|
||||
tokc = strtol(last_id, 0, 0);
|
||||
tok = TOK_NUM;
|
||||
} else {
|
||||
*(char *) dstk = TAG_TOK; /* no need to mark end of string (we
|
||||
if (dstk - sym_stk + 1 > ALLOC_SIZE) {
|
||||
error("symbol stack overflow");
|
||||
}
|
||||
* dstk = TAG_TOK; /* no need to mark end of string (we
|
||||
suppose data is initialized to zero by calloc) */
|
||||
tok = (intptr_t) (strstr((char*) sym_stk, (char*) (last_id - 1))
|
||||
tok = (intptr_t) (strstr(sym_stk, (last_id - 1))
|
||||
- sym_stk);
|
||||
*(char *) dstk = 0; /* mark real end of ident for dlsym() */
|
||||
* dstk = 0; /* mark real end of ident for dlsym() */
|
||||
tok = tok * 8 + TOK_IDENT;
|
||||
if (tok > TOK_DEFINE) {
|
||||
tok = vars + tok;
|
||||
if (tok + 8 > ALLOC_SIZE) {
|
||||
error("Variable Table overflow.");
|
||||
}
|
||||
tok = (intptr_t) (pVarsBase + tok);
|
||||
/* printf("tok=%s %x\n", last_id, tok); */
|
||||
/* define handling */
|
||||
if (*(int *) tok == SYM_DEFINE) {
|
||||
dptr = *(int *) (tok + 4);
|
||||
dptr = *(char* *) (tok + 4);
|
||||
dch = ch;
|
||||
inp();
|
||||
next();
|
||||
|
|
@ -1243,17 +1300,17 @@ class Compiler {
|
|||
}
|
||||
#if 0
|
||||
{
|
||||
int p;
|
||||
char* p;
|
||||
|
||||
printf("tok=0x%x ", tok);
|
||||
if (tok >= TOK_IDENT) {
|
||||
printf("'");
|
||||
if (tok> TOK_DEFINE)
|
||||
p = sym_stk + 1 + (tok - vars - TOK_IDENT) / 8;
|
||||
p = sym_stk + 1 + ((char*) tok - pVarsBase - TOK_IDENT) / 8;
|
||||
else
|
||||
p = sym_stk + 1 + (tok - TOK_IDENT) / 8;
|
||||
while (*(char *)p != TAG_TOK && *(char *)p)
|
||||
printf("%c", *(char *)p++);
|
||||
while (*p != TAG_TOK && *p)
|
||||
printf("%c", *p++);
|
||||
printf("'\n");
|
||||
} else if (tok == TOK_NUM) {
|
||||
printf("%d\n", tokc);
|
||||
|
|
@ -1264,15 +1321,24 @@ class Compiler {
|
|||
#endif
|
||||
}
|
||||
|
||||
void error(const char *fmt, ...) {
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
fprintf(stderr, "%ld: ", file->tell());
|
||||
vfprintf(stderr, fmt, ap);
|
||||
fprintf(stderr, "\n");
|
||||
va_end(ap);
|
||||
exit(1);
|
||||
virtual void verror(const char* fmt, va_list ap) {
|
||||
char* pBase = mErrorBuf;
|
||||
int bytesLeft = sizeof(mErrorBuf);
|
||||
int bytesAdded = snprintf(pBase, bytesLeft, "%ld: ", file->tell());
|
||||
bytesLeft -= bytesAdded;
|
||||
pBase += bytesAdded;
|
||||
if (bytesLeft > 0) {
|
||||
bytesAdded = vsnprintf(pBase, bytesLeft, fmt, ap);
|
||||
bytesLeft -= bytesAdded;
|
||||
pBase += bytesAdded;
|
||||
}
|
||||
if (bytesLeft > 0) {
|
||||
bytesAdded = snprintf(pBase, bytesLeft, "\n");
|
||||
bytesLeft -= bytesAdded;
|
||||
pBase += bytesAdded;
|
||||
}
|
||||
longjmp(mErrorRecoveryJumpBuf, 1);
|
||||
}
|
||||
|
||||
void skip(intptr_t c) {
|
||||
|
|
@ -1284,19 +1350,21 @@ class Compiler {
|
|||
|
||||
/* l is one if '=' parsing wanted (quick hack) */
|
||||
void unary(intptr_t l) {
|
||||
intptr_t n, t, a, c;
|
||||
intptr_t n, t, a;
|
||||
int c;
|
||||
t = 0;
|
||||
n = 1; /* type of expression 0 = forward, 1 = value, other =
|
||||
lvalue */
|
||||
if (tok == '\"') {
|
||||
pGen->li(glo);
|
||||
pGen->li((int) glo);
|
||||
while (ch != '\"') {
|
||||
getq();
|
||||
*(char *) glo++ = ch;
|
||||
*allocGlobalSpace(1) = ch;
|
||||
inp();
|
||||
}
|
||||
*(char *) glo = 0;
|
||||
glo = (glo + 4) & -4; /* align heap */
|
||||
*glo = 0;
|
||||
/* align heap */
|
||||
allocGlobalSpace((char*) (((intptr_t) glo + 4) & -4) - glo);
|
||||
inp();
|
||||
next();
|
||||
} else {
|
||||
|
|
@ -1349,7 +1417,7 @@ class Compiler {
|
|||
n = *(int *) t;
|
||||
/* forward reference: try dlsym */
|
||||
if (!n) {
|
||||
n = (intptr_t) dlsym(RTLD_DEFAULT, (char*) last_id);
|
||||
n = (intptr_t) dlsym(RTLD_DEFAULT, last_id);
|
||||
}
|
||||
if ((tok == '=') & l) {
|
||||
/* assignment */
|
||||
|
|
@ -1398,7 +1466,7 @@ class Compiler {
|
|||
}
|
||||
}
|
||||
|
||||
void sum(intptr_t l) {
|
||||
void sum(int l) {
|
||||
intptr_t t, n, a;
|
||||
t = 0;
|
||||
if (l-- == 1)
|
||||
|
|
@ -1518,7 +1586,7 @@ class Compiler {
|
|||
void decl(bool l) {
|
||||
intptr_t a;
|
||||
|
||||
while ((tok == TOK_INT) | ((tok != -1) & (!l))) {
|
||||
while ((tok == TOK_INT) | ((tok != EOF) & (!l))) {
|
||||
if (tok == TOK_INT) {
|
||||
next();
|
||||
while (tok != ';') {
|
||||
|
|
@ -1526,8 +1594,7 @@ class Compiler {
|
|||
loc = loc + 4;
|
||||
*(int *) tok = -loc;
|
||||
} else {
|
||||
*(int *) tok = glo;
|
||||
glo = glo + 4;
|
||||
*(int* *) tok = (int*) allocGlobalSpace(4);
|
||||
}
|
||||
next();
|
||||
if (tok == ',')
|
||||
|
|
@ -1563,13 +1630,22 @@ class Compiler {
|
|||
}
|
||||
}
|
||||
|
||||
char* allocGlobalSpace(int bytes) {
|
||||
if (glo - pGlobalBase + bytes > ALLOC_SIZE) {
|
||||
error("Global space exhausted");
|
||||
}
|
||||
char* result = glo;
|
||||
glo += bytes;
|
||||
return result;
|
||||
}
|
||||
|
||||
void cleanup() {
|
||||
if (sym_stk != 0) {
|
||||
free((void*) sym_stk);
|
||||
free(sym_stk);
|
||||
sym_stk = 0;
|
||||
}
|
||||
if (pGlobalBase != 0) {
|
||||
free((void*) pGlobalBase);
|
||||
free(pGlobalBase);
|
||||
pGlobalBase = 0;
|
||||
}
|
||||
if (pVarsBase != 0) {
|
||||
|
|
@ -1591,7 +1667,7 @@ class Compiler {
|
|||
tokc = 0;
|
||||
tokl = 0;
|
||||
ch = 0;
|
||||
vars = 0;
|
||||
pVarsBase = 0;
|
||||
rsym = 0;
|
||||
loc = 0;
|
||||
glo = 0;
|
||||
|
|
@ -1604,6 +1680,7 @@ class Compiler {
|
|||
pGlobalBase = 0;
|
||||
pVarsBase = 0;
|
||||
pGen = 0;
|
||||
mErrorBuf[0] = 0;
|
||||
}
|
||||
|
||||
void setArchitecture(const char* architecture) {
|
||||
|
|
@ -1622,7 +1699,7 @@ class Compiler {
|
|||
}
|
||||
#endif
|
||||
if (!pGen ) {
|
||||
fprintf(stderr, "Unknown architecture %s\n", architecture);
|
||||
error("Unknown architecture %s\n", architecture);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1634,8 +1711,9 @@ class Compiler {
|
|||
#endif
|
||||
}
|
||||
if (pGen == NULL) {
|
||||
fprintf(stderr, "No code generator defined.\n");
|
||||
error("No code generator defined.");
|
||||
}
|
||||
pGen->setErrorSink(this);
|
||||
}
|
||||
|
||||
public:
|
||||
|
|
@ -1655,33 +1733,35 @@ public:
|
|||
}
|
||||
|
||||
int compile(const char* text, size_t textLength) {
|
||||
cleanup();
|
||||
clear();
|
||||
codeBuf.init(ALLOC_SIZE);
|
||||
setArchitecture(NULL);
|
||||
if (!pGen) {
|
||||
return -1;
|
||||
int result;
|
||||
if (! (result = setjmp(mErrorRecoveryJumpBuf))) {
|
||||
cleanup();
|
||||
clear();
|
||||
codeBuf.init(ALLOC_SIZE);
|
||||
setArchitecture(NULL);
|
||||
if (!pGen) {
|
||||
return -1;
|
||||
}
|
||||
pGen->init(&codeBuf);
|
||||
file = new TextInputStream(text, textLength);
|
||||
sym_stk = (char*) calloc(1, ALLOC_SIZE);
|
||||
dstk = strcpy(sym_stk,
|
||||
" int if else while break return for define main ")
|
||||
+ TOK_STR_SIZE;
|
||||
pGlobalBase = (char*) calloc(1, ALLOC_SIZE);
|
||||
glo = pGlobalBase;
|
||||
pVarsBase = (char*) calloc(1, ALLOC_SIZE);
|
||||
inp();
|
||||
next();
|
||||
decl(0);
|
||||
pGen->finishCompile();
|
||||
}
|
||||
pGen->init(&codeBuf);
|
||||
file = new TextInputStream(text, textLength);
|
||||
sym_stk = (intptr_t) calloc(1, ALLOC_SIZE);
|
||||
dstk = (intptr_t) strcpy((char*) sym_stk,
|
||||
" int if else while break return for define main ")
|
||||
+ TOK_STR_SIZE;
|
||||
pGlobalBase = calloc(1, ALLOC_SIZE);
|
||||
glo = (intptr_t) pGlobalBase;
|
||||
pVarsBase = calloc(1, ALLOC_SIZE);
|
||||
vars = (intptr_t) pVarsBase;
|
||||
inp();
|
||||
next();
|
||||
decl(0);
|
||||
pGen->finishCompile();
|
||||
return 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
int run(int argc, char** argv) {
|
||||
typedef int (*mainPtr)(int argc, char** argv);
|
||||
mainPtr aMain = (mainPtr) *(int*) (vars + TOK_MAIN);
|
||||
mainPtr aMain = (mainPtr) *(int*) (pVarsBase + TOK_MAIN);
|
||||
if (!aMain) {
|
||||
fprintf(stderr, "Could not find function \"main\".\n");
|
||||
return -1;
|
||||
|
|
@ -1706,7 +1786,7 @@ public:
|
|||
return NULL;
|
||||
}
|
||||
size_t nameLen = strlen(name);
|
||||
char* pSym = (char*) sym_stk;
|
||||
char* pSym = sym_stk;
|
||||
char c;
|
||||
for(;;) {
|
||||
c = *pSym++;
|
||||
|
|
@ -1716,12 +1796,12 @@ public:
|
|||
if (c == TAG_TOK) {
|
||||
if (memcmp(pSym, name, nameLen) == 0
|
||||
&& pSym[nameLen] == TAG_TOK) {
|
||||
int tok = pSym - 1 - (char*) sym_stk;
|
||||
int tok = pSym - 1 - sym_stk;
|
||||
tok = tok * 8 + TOK_IDENT;
|
||||
if (tok <= TOK_DEFINE) {
|
||||
return 0;
|
||||
} else {
|
||||
tok = vars + tok;
|
||||
tok = (intptr_t) (pVarsBase + tok);
|
||||
return * (void**) tok;
|
||||
}
|
||||
}
|
||||
|
|
@ -1730,6 +1810,10 @@ public:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
char* getErrorMessage() {
|
||||
return mErrorBuf;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
const char* Compiler::operatorChars =
|
||||
|
|
@ -1880,11 +1964,16 @@ void accGetScriptInfoLog(ACCscript* script,
|
|||
ACCsizei maxLength,
|
||||
ACCsizei * length,
|
||||
ACCchar * infoLog) {
|
||||
char* message = script->compiler.getErrorMessage();
|
||||
int messageLength = strlen(message) + 1;
|
||||
if (length) {
|
||||
*length = 0;
|
||||
*length = messageLength;
|
||||
}
|
||||
if (maxLength > 0 && infoLog) {
|
||||
*infoLog = 0;
|
||||
if (infoLog && maxLength > 0) {
|
||||
int trimmedLength = maxLength < messageLength ?
|
||||
maxLength : messageLength;
|
||||
memcpy(infoLog, message, trimmedLength);
|
||||
infoLog[trimmedLength] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
2
libacc/tests/data/error.c
Normal file
2
libacc/tests/data/error.c
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
void foo;
|
||||
|
||||
|
|
@ -81,12 +81,18 @@ int main(int argc, char** argv) {
|
|||
delete[] text;
|
||||
|
||||
accCompileScript(script);
|
||||
|
||||
int result = accGetError(script);
|
||||
MainPtr mainPointer = 0;
|
||||
if (result != 0) {
|
||||
char buf[1024];
|
||||
accGetScriptInfoLog(script, sizeof(buf), NULL, buf);
|
||||
fprintf(stderr, "%ss", buf);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
accGetScriptLabel(script, "main", (ACCvoid**) & mainPointer);
|
||||
|
||||
int result = accGetError(script);
|
||||
result = accGetError(script);
|
||||
if (result == ACC_NO_ERROR) {
|
||||
fprintf(stderr, "Executing compiled code:\n");
|
||||
int codeArgc = argc - i + 1;
|
||||
|
|
@ -96,6 +102,8 @@ int main(int argc, char** argv) {
|
|||
fprintf(stderr, "result: %d\n", result);
|
||||
}
|
||||
|
||||
exit:
|
||||
|
||||
accDeleteScript(script);
|
||||
|
||||
return result;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue