Skip to content

Instantly share code, notes, and snippets.

@gbluma
Last active March 8, 2016 04:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gbluma/1158a1af7a70db3cfce7 to your computer and use it in GitHub Desktop.
Save gbluma/1158a1af7a70db3cfce7 to your computer and use it in GitHub Desktop.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "libtcc.h"
#include "tcc.h"
void repl()
{
char repl_input[1024];
void (*func)();
char repl_name[20];
int index=0;
void *offset = TCC_RELOCATE_AUTO;
TCCState *s;
void *symbol_table[1024];
while(1)
{
/* create a new page of program definitions */
s = tcc_new();
if (!s) {
fprintf(stderr, "Could not create tcc state\n");
exit(1);
}
/* MUST BE CALLED before any compilation */
tcc_set_output_type(s, TCC_OUTPUT_MEMORY);
/* Add the symbols we want to expose to our REPL */
/* as a test, we add a symbol that the compiled program can use.
You may also open a dll with tcc_add_dll() and use symbols from that */
tcc_add_symbol(s, "printf", printf);
/* Add previous REPL symbols back in */
for (int x=0; x<index; x++) {
char tmp_name[20];
sprintf(tmp_name, "repl_%d", x);
printf("re-adding symbol %s to current context\n", tmp_name);
tcc_add_symbol(s, tmp_name, symbol_table[x]);
}
/* generate an index name for the code about to be read */
sprintf(repl_name, "repl_%d", index++);
/* read a string */
printf(">>> ");
fgets(repl_input, 1024, stdin);
/* wrap the input in a function */
char tmp_code[1024];
strcpy(tmp_code, repl_input);
sprintf(repl_input, "void %s(){ %s };", repl_name, tmp_code);
/* try to compile that code */
if (tcc_compile_string(s, repl_input) == -1) {
printf("Error compiling string. Please try again\n");
continue;
}
/* relocate the code and make it executable */
if (tcc_relocate(s, TCC_RELOCATE_AUTO) < 0) {
printf("Error relocating JIT'ed code. Please try again\n");
continue;
}
printf("Offset is: %lu\n", offset);
printf("Current symbol is: %s\n", repl_name);
// ------------------------
// Experiment: list out all of the compiled symbols.
// Status: WIP
printf("number of sections: %d\n", s->nb_sections);
Sym *sym, *esym, *sym_end;
sym_end = (Sym *)(s->symtab->data + s->symtab->data_offset);
for(sym = (Sym *)s->symtab->data + 1;
sym < sym_end;
sym++)
{
//printf(" name: %d\n", get_tok_str(sym->v, NULL));
}
// ------------------------
/* get entry symbol */
func = tcc_get_symbol(s, repl_name);
printf("Func addr: %lu\n", (unsigned long)func);
if (!func) {
printf("Error retrieving symbol %s. Please try again\n", repl_name);
continue;
}
/* track new function for use in later loops */
symbol_table[index-1] = func;
/* TODO: loop over all symbols in the repl micro-session and add them to
the aggregate symbol table. This way we can track everything
from the input instead of wrapping in an ugly function. */
/* run the code */
func();
/* delete the state */
//tcc_delete(s); // TODO: defer to end of program
/* Note: I'm skipping this for now so the later loop iterations
can still access code from the earlier loop. */
}
}
int main(int argc, char **argv)
{
/* disable output buffering so we can see the */
setbuf(stdout, NULL);
/* if tcclib.h and libtcc1.a are not installed, where can we find them
if (argc == 2 && !memcmp(argv[1], "lib_path=",9))
tcc_set_lib_path(s, argv[1]+9);
*/
// enter read-eval-print loop
repl();
return 0;
}
$ tcc -L ./libtcc -llibtcc -I ../tcc-source/tcc-0.9.26/ -run examples/libtcc_test2.c
>>> printf("A\n");
Offset is: 1
Current symbol is: repl_0
number of sections: 10
Func addr: 8722432
A
re-adding symbol repl_0 to current context
>>> printf("B\n");
Offset is: 1
Current symbol is: repl_1
number of sections: 10
Func addr: 8781488
B
re-adding symbol repl_0 to current context
re-adding symbol repl_1 to current context
>>> repl_1();
Offset is: 1
Current symbol is: repl_2
number of sections: 10
Func addr: 9273312
B
re-adding symbol repl_0 to current context
re-adding symbol repl_1 to current context
re-adding symbol repl_2 to current context
>>>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment