• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

system/corennnnn


Commit MetaInfo

Revision8c246a9dc294760f2a981cf5144fe4939d1554e6 (tree)
Time2009-07-15 13:14:10
AuthorJack Palevich <jackpal@goog...>
CommiterJack Palevich

Log Message

Add accRegisterSymbolCallback API to control external symbol linkage.

Until now dlsym was used to lookup external symbols. Now you can
register your own function to be called when an undefined symbol is
used.

Change Summary

Incremental Difference

--- a/include/acc/acc.h
+++ b/include/acc/acc.h
@@ -48,6 +48,11 @@ ACCscript* accCreateScript();
4848
4949 void accDeleteScript(ACCscript* script);
5050
51+typedef ACCvoid* (*ACCSymbolLookupFn)(ACCvoid* pContext, const ACCchar * name);
52+
53+void accRegisterSymbolCallback(ACCscript* script, ACCSymbolLookupFn pFn,
54+ ACCvoid* pContext);
55+
5156 ACCenum accGetError( ACCscript* script );
5257
5358 void accScriptSource(ACCscript* script,
--- a/libacc/acc.cpp
+++ b/libacc/acc.cpp
@@ -3232,6 +3232,8 @@ class Compiler : public ErrorSink {
32323232 char* dptr; // Macro state: Points to macro text during macro playback.
32333233 int dch; // Macro state: Saves old value of ch during a macro playback.
32343234 char* pGlobalBase;
3235+ ACCSymbolLookupFn mpSymbolLookupFn;
3236+ void* mpSymbolLookupContext;
32353237
32363238 // Arena for the duration of the compile
32373239 Arena mGlobalArena;
@@ -3792,6 +3794,7 @@ class Compiler : public ErrorSink {
37923794 }
37933795 return false;
37943796 }
3797+
37953798 /* Parse and evaluate a unary expression.
37963799 * allowAssignment is true if '=' parsing wanted (quick hack)
37973800 */
@@ -3880,9 +3883,12 @@ class Compiler : public ErrorSink {
38803883 }
38813884 VariableInfo* pVI = VI(t);
38823885 n = (intptr_t) pVI->pAddress;
3883- /* forward reference: try dlsym */
3886+ /* forward reference: try our lookup function */
38843887 if (!n) {
3885- n = (intptr_t) dlsym(RTLD_DEFAULT, nameof(t));
3888+ if (mpSymbolLookupFn) {
3889+ n = (intptr_t) mpSymbolLookupFn(
3890+ mpSymbolLookupContext, nameof(t));
3891+ }
38863892 if (pVI->pType == NULL) {
38873893 if (tok == '(') {
38883894 pVI->pType = mkpIntFn;
@@ -4613,6 +4619,12 @@ class Compiler : public ErrorSink {
46134619 }
46144620 }
46154621
4622+ // One-time initialization, when class is constructed.
4623+ void init() {
4624+ mpSymbolLookupFn = 0;
4625+ mpSymbolLookupContext = 0;
4626+ }
4627+
46164628 void clear() {
46174629 tok = 0;
46184630 tokc = 0;
@@ -4673,6 +4685,7 @@ public:
46734685 };
46744686
46754687 Compiler() {
4688+ init();
46764689 clear();
46774690 }
46784691
@@ -4680,6 +4693,11 @@ public:
46804693 cleanup();
46814694 }
46824695
4696+ void registerSymbolCallback(ACCSymbolLookupFn pFn, ACCvoid* pContext) {
4697+ mpSymbolLookupFn = pFn;
4698+ mpSymbolLookupContext = pContext;
4699+ }
4700+
46834701 int compile(const char* text, size_t textLength) {
46844702 int result;
46854703
@@ -4848,6 +4866,10 @@ struct ACCscript {
48484866 delete text;
48494867 }
48504868
4869+ void registerSymbolCallback(ACCSymbolLookupFn pFn, ACCvoid* pContext) {
4870+ compiler.registerSymbolCallback(pFn, pContext);
4871+ }
4872+
48514873 void setError(ACCenum error) {
48524874 if (accError == ACC_NO_ERROR && error != ACC_NO_ERROR) {
48534875 accError = error;
@@ -4883,6 +4905,12 @@ void accDeleteScript(ACCscript* script) {
48834905 }
48844906
48854907 extern "C"
4908+void accRegisterSymbolCallback(ACCscript* script, ACCSymbolLookupFn pFn,
4909+ ACCvoid* pContext) {
4910+ script->registerSymbolCallback(pFn, pContext);
4911+}
4912+
4913+extern "C"
48864914 void accScriptSource(ACCscript* script,
48874915 ACCsizei count,
48884916 const ACCchar ** string,
--- a/libacc/tests/Android.mk
+++ b/libacc/tests/Android.mk
@@ -31,3 +31,35 @@ LOCAL_CFLAGS := -O0 -g
3131 LOCAL_MODULE_TAGS := tests
3232
3333 include $(BUILD_EXECUTABLE)
34+
35+# Runtime tests for host
36+# ========================================================
37+include $(CLEAR_VARS)
38+LOCAL_MODULE:= accRuntimeTest
39+
40+LOCAL_SRC_FILES:= \
41+ runtimeTest.cpp
42+
43+LOCAL_SHARED_LIBRARIES := \
44+ libacc
45+
46+LOCAL_MODULE_TAGS := tests
47+
48+include $(BUILD_HOST_EXECUTABLE)
49+
50+# Runtime tests for target
51+# ========================================================
52+include $(CLEAR_VARS)
53+LOCAL_MODULE:= accRuntimeTest
54+
55+LOCAL_SRC_FILES:= \
56+ runtimeTest.cpp
57+
58+LOCAL_SHARED_LIBRARIES := \
59+ libacc
60+
61+LOCAL_CFLAGS := -O0 -g
62+
63+LOCAL_MODULE_TAGS := tests
64+
65+include $(BUILD_EXECUTABLE)
--- a/libacc/tests/main.cpp
+++ b/libacc/tests/main.cpp
@@ -34,6 +34,10 @@ int run(MainPtr mainFunc, int argc, char** argv) {
3434 extern "C"
3535 void accDisassemble(ACCscript* script);
3636
37+ACCvoid* symbolLookup(ACCvoid* pContext, const ACCchar* name) {
38+ return (ACCvoid*) dlsym(RTLD_DEFAULT, name);
39+}
40+
3741 int main(int argc, char** argv) {
3842 const char* inFile = NULL;
3943 bool printListing;
@@ -91,6 +95,8 @@ int main(int argc, char** argv) {
9195 accScriptSource(script, 1, scriptSource, NULL);
9296 delete[] text;
9397
98+ accRegisterSymbolCallback(script, symbolLookup, NULL);
99+
94100 accCompileScript(script);
95101 int result = accGetError(script);
96102 MainPtr mainPointer = 0;
--- /dev/null
+++ b/libacc/tests/runtimeTest.cpp
@@ -0,0 +1,110 @@
1+/*
2+ * RuntimeTest for ACC compiler.
3+ *
4+ */
5+
6+#include <ctype.h>
7+#include <dlfcn.h>
8+#include <stdarg.h>
9+#include <stdint.h>
10+#include <stdio.h>
11+#include <stdlib.h>
12+#include <string.h>
13+
14+#if defined(__arm__)
15+#include <unistd.h>
16+#endif
17+
18+#include <acc/acc.h>
19+
20+
21+typedef void (*ScriptPtr)();
22+
23+// This is a separate function so it can easily be set by breakpoint in gdb.
24+void run(ScriptPtr scriptFn) {
25+ scriptFn();
26+}
27+
28+// Private API for development:
29+
30+extern "C"
31+void accDisassemble(ACCscript* script);
32+
33+void op_int(int a) {
34+ printf("op_int(%d)\n", a);
35+}
36+
37+void op_float12(float a, float b, float c, float d,
38+ float e, float f, float g, float h,
39+ float i, float j, float k, float l) {
40+ printf("op_float12(%g, %g, %g, %g, %g, %g, %g, %g, %g, %g, %g, %g)\n",
41+ a, b, c, d, e, f, g, h, i, j, k, l);
42+}
43+
44+const char* text = "void op_int(int a);\n"
45+ "void op_float12(float a, float b, float c, float d,\n"
46+ " float e, float f, float g, float h,\n"
47+ " float i, float j, float k, float l);\n"
48+ "void script() {\n"
49+ " op_int(123);\n"
50+ " op_float12(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0);\n"
51+ "}\n";
52+
53+ACCvoid* symbolLookup(ACCvoid* pContext, const ACCchar* name) {
54+ if (strcmp("op_int", name) == 0) {
55+ return (ACCvoid*) op_int;
56+ }
57+ if (strcmp("op_float12", name) == 0) {
58+ return (ACCvoid*) op_float12;
59+ }
60+ return (ACCvoid*) dlsym(RTLD_DEFAULT, name);
61+}
62+
63+int main(int argc, char** argv) {
64+ ACCscript* script = accCreateScript();
65+
66+ accRegisterSymbolCallback(script, symbolLookup, NULL);
67+
68+ const ACCchar* scriptSource[] = {text};
69+ accScriptSource(script, 1, scriptSource, NULL);
70+
71+ accCompileScript(script);
72+ int result = accGetError(script);
73+ ScriptPtr scriptPointer = 0;
74+ if (result != 0) {
75+ char buf[1024];
76+ accGetScriptInfoLog(script, sizeof(buf), NULL, buf);
77+ fprintf(stderr, "%s", buf);
78+ goto exit;
79+ }
80+
81+ {
82+ ACCsizei numPragmaStrings;
83+ accGetPragmas(script, &numPragmaStrings, 0, NULL);
84+ if (numPragmaStrings) {
85+ char** strings = new char*[numPragmaStrings];
86+ accGetPragmas(script, NULL, numPragmaStrings, strings);
87+ for(ACCsizei i = 0; i < numPragmaStrings; i += 2) {
88+ fprintf(stderr, "#pragma %s(%s)\n", strings[i], strings[i+1]);
89+ }
90+ delete[] strings;
91+ }
92+ }
93+
94+ accGetScriptLabel(script, "script", (ACCvoid**) & scriptPointer);
95+
96+ result = accGetError(script);
97+ if (result != ACC_NO_ERROR) {
98+ fprintf(stderr, "Could not find script: %d\n", result);
99+ } else {
100+ fprintf(stderr, "Executing script:\n");
101+ run(scriptPointer);
102+ }
103+
104+
105+exit:
106+
107+ accDeleteScript(script);
108+
109+ return result;
110+}