Merge commit 'goog/master' into merge_master

This commit is contained in:
Mathias Agopian 2009-05-31 01:14:49 -07:00
commit e26cbeacaf
5 changed files with 327 additions and 129 deletions

128
include/android/log.h Normal file
View 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 */

View file

@ -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

View file

@ -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;
}
}

View file

@ -0,0 +1,2 @@
void foo;

View file

@ -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;