RPA Toolkit
Work on RJS interaction with C program.
authorMartin Stoilov <martin@rpasearch.com>
Sat, 14 May 2011 04:39:52 +0000 (21:39 -0700)
committerMartin Stoilov <martin@rpasearch.com>
Sat, 14 May 2011 04:39:52 +0000 (21:39 -0700)
13 files changed:
build/linux/build.mk
rjs/ecma262.rpa
rjs/rjs.c
rjs/rjs.h
rjs/rjscompiler.c
rjs/rjsexec.c
rlib/rstring.c
rlib/rstring.h
rvm/rvmreg.c
rvm/rvmreg.h
testrjs/build/linux/testrjs.mk [new file with mode: 0644]
testrjs/build/linux/x86_64/Makefile [new file with mode: 0644]
testrjs/rjs-simple.c [new file with mode: 0644]

index 05dd358..e9ab87c 100644 (file)
@@ -7,6 +7,7 @@ all:
        +make -C $(SRCDIR)/rjs/build/$(OS)/$(ARCHDIR) all
        +make -C $(SRCDIR)/tests/build/$(OS)/$(ARCHDIR) all
        +make -C $(SRCDIR)/testrpa2/build/$(OS)/$(ARCHDIR) all
+       +make -C $(SRCDIR)/testrjs/build/$(OS)/$(ARCHDIR) all
        +make -C $(SRCDIR)/rgrep/build/$(OS)/$(ARCHDIR) all
 
 distclean: clean
@@ -18,6 +19,7 @@ distclean: clean
        +make -C $(SRCDIR)/rjs/build/$(OS)/$(ARCHDIR) distclean
        +make -C $(SRCDIR)/tests/build/$(OS)/$(ARCHDIR) distclean
        +make -C $(SRCDIR)/testrpa2/build/$(OS)/$(ARCHDIR) distclean
+       +make -C $(SRCDIR)/testrjs/build/$(OS)/$(ARCHDIR) distclean
        +make -C $(SRCDIR)/rgrep/build/$(OS)/$(ARCHDIR) distclean
 
 clean:
@@ -29,5 +31,6 @@ clean:
        +make -C $(SRCDIR)/rjs/build/$(OS)/$(ARCHDIR) clean
        +make -C $(SRCDIR)/tests/build/$(OS)/$(ARCHDIR) clean
        +make -C $(SRCDIR)/testrpa2/build/$(OS)/$(ARCHDIR) clean
+       +make -C $(SRCDIR)/testrjs/build/$(OS)/$(ARCHDIR) clean
        +make -C $(SRCDIR)/rgrep/build/$(OS)/$(ARCHDIR) clean
 
index 7de5eae..264ac12 100644 (file)
@@ -2,9 +2,7 @@
 #!emitnone
 
 
-#!emit DoKeyword
 #!emit FunctionCallName
-#!emit IterationDo
 #!emit LogicalNotExpressionOp
 #!emit PostfixExpressionOp
 #!emit PrefixExpressionOp
@@ -427,11 +425,11 @@ DefaultClauseOp                                           ::= <DefaultKeywordOp> <S>? ':' <S>? <StatementList>?
 
 # 13 Function Definition
 FunctionName                                           ::= <IdentifierNoEmit>
-FunctionDeclaration                                    ::= ('function'-'function'<IdentifierPart>)<S>?<FunctionName><S>?'('<S>?<FormalParameterList>?<S>?')'<S>?'{'<S>?<FunctionBody>?<S>?'}'
-FunctionExpression                                     ::= ('function'-'function'<IdentifierPart>)<S>?<FunctionName>?<S>?'('<S>?<FormalParameterList>?<S>?')'<S>?'{'<S>?<FunctionBody>?<S>?'}'
+FunctionDeclaration                                    ::= ('function'-'function'<IdentifierPart>)<S>?<FunctionName><S>?'('<S>?<FormalParameterList>?<S>?')'<S>?' {' <S>? <FunctionBody>? <S>?'}'
+FunctionExpression                                     ::= ('function'-'function'<IdentifierPart>)<S>?<FunctionName>?<S>?'('<S>?<FormalParameterList>?<S>?')'<S>?'{'<S>? <FunctionBody>? <S>?'}'
 FormalParameterList                            ::= <FunctionParameter> ( <S>? ',' <S>? <FunctionParameter> )*
 FunctionParameter                                      ::= <IdentifierNoEmit>
-FunctionBody                                           ::= <SourceElements>
+FunctionBody                                           ::= (<SourceElement> - '}')+
 FunctionDeclarationStatement           ::= ('function' - 'function' <IdentifierPart>)<S>?<FunctionName><S>?'('<S>?<FormalParameterList>?<S>?')' <SC>
 
 # FunctionName                                         ::= <IdentifierNoEmit>
@@ -446,12 +444,13 @@ FunctionDeclarationStatement              ::= ('function' - 'function' <IdentifierPart>)<S>?
 
 
 # 14 Program
-SyntaxError                                            ::= (. - <SC>)+ <SC>?
+SyntaxError                                            ::= (. - (<SC> | <S>))+
 SourceElements                                         ::= (<S>? <SourceElement>)+
 SourceElement                                  ::= <FunctionDeclaration> |
                                                                <Statement> |
                                                                <SyntaxError>
-Program                                                        ::= <SourceElements>
+Program                                                        ::= (<FunctionDeclaration> | <Statement> | <S> | <SyntaxError>)*
+
 # The root rule, it is anonymous
 <Program>
 
index b7c6b7a..85fa59d 100644 (file)
--- a/rjs/rjs.c
+++ b/rjs/rjs.c
@@ -28,6 +28,7 @@ rjs_engine_t *rjs_engine_create()
 
        jse->pa = rjs_parser_create();
        jse->cpu = rvm_cpu_create_default();
+       jse->co = rjs_compiler_create(jse->cpu);
        rvm_cpu_addswitable(jse->cpu, "rjsswitable", rjsswitable);
 
        tp = rvm_cpu_alloc_global(jse->cpu);
@@ -67,9 +68,9 @@ static rint rjs_engine_parse(rjs_engine_t *jse, const rchar *script, rsize_t siz
 rint rjs_engine_compile(rjs_engine_t *jse, const rchar *script, rsize_t size)
 {
        rarray_t *records = NULL;
-       if (jse->co)
-               rjs_compiler_destroy(jse->co);
-       jse->co = rjs_compiler_create(jse->cpu);
+//     if (jse->co)
+//             rjs_compiler_destroy(jse->co);
+//     jse->co = rjs_compiler_create(jse->cpu);
        jse->co->debug = jse->debugcompile;
 
        if (rjs_engine_parse(jse, script, size, &records) < 0) {
@@ -141,6 +142,22 @@ rint rjs_engine_run(rjs_engine_t *jse)
 }
 
 
+rvmreg_t * rjs_engine_exec(rjs_engine_t *jse, const rchar *script, rsize_t size)
+{
+       if (rjs_engine_compile(jse, script, size) < 0)
+               return NULL;
+       if (rjs_engine_run(jse) < 0)
+               return NULL;
+       return RVM_CPUREG_PTR(jse->cpu, R0);
+}
+
+
+rvmreg_t *rjs_engine_exec_s(rjs_engine_t *jse, const rchar *script)
+{
+       return rjs_engine_exec(jse, script, r_strlen(script));
+}
+
+
 static void rjs_engine_print(rvmcpu_t *cpu, rvm_asmins_t *ins)
 {
        rvmreg_t *r = (rvmreg_t *)RVM_STACK_ADDR(cpu->stack, RVM_CPUREG_GETU(cpu, FP) + 1);
index 72a67a5..121abd1 100644 (file)
--- a/rjs/rjs.h
+++ b/rjs/rjs.h
@@ -35,6 +35,8 @@ rint rjs_engine_compile_s(rjs_engine_t *jse, const rchar *script);
 rint rjs_engine_close(rjs_engine_t *jse);
 rint rjs_engine_run(rjs_engine_t *jse);
 rint rjs_engine_dumpast(rjs_engine_t *jse, const rchar *script, rsize_t size);
+rvmreg_t *rjs_engine_exec(rjs_engine_t *jse, const rchar *script, rsize_t size);
+rvmreg_t *rjs_engine_exec_s(rjs_engine_t *jse, const rchar *script);
 
 
 #ifdef __cplusplus
index 26695d2..82db4c0 100644 (file)
@@ -239,6 +239,8 @@ rlong rjs_compiler_record2unaryopcode(rparecord_t *prec)
                return RVM_ENEG;
        else if (r_stringncmp("~", input,  size))
                return RVM_ENOT;
+       else if (r_stringncmp("!", input,  size))
+               return RVM_ELNOT;
 
        return -1;
 }
index 58141bf..2483b4c 100644 (file)
@@ -17,6 +17,7 @@ static int debuginfo = 0;
 static int parseinfo = 0;
 static int compileonly = 0;
 static int debugcompileonly = 0;
+static int statinfo = 0;
 
 
 static rchar *errormsg[] = {
@@ -161,8 +162,8 @@ int main(int argc, char *argv[])
                        debugcompileonly = 1;
                } else if (r_strcmp(argv[i], "-c") == 0) {
                        compileonly = 1;
-               } else if (r_strcmp(argv[i], "-m") == 0) {
-
+               } else if (r_strcmp(argv[i], "-t") == 0) {
+                       statinfo = 1;
                }
        }
 
@@ -197,7 +198,7 @@ end:
        rjs_engine_destroy(jse);
        if (unmapscript)
                rjs_unmap_file(unmapscript);
-       if (debuginfo)
+       if (statinfo)
                fprintf(stdout, "\nRJS Version: %s, memory: %ld KB (leaked %ld Bytes)\n", rjs_version(), (rlong)r_debug_get_maxmem()/1000, (rlong)r_debug_get_allocmem());
        return 0;
 }
index 9b9e336..4066db0 100644 (file)
@@ -290,3 +290,11 @@ rstring_t *r_string_create_strsize(const rchar *str, ruint size)
        }
        return r_string_create_from_rstr(&rstr);
 }
+
+
+const char *r_string_ansi(const rstring_t *str)
+{
+       if (!str)
+               return NULL;
+       return str->s.str;
+}
index d06a2c4..1a5d20e 100644 (file)
@@ -58,7 +58,7 @@ rstring_t *r_string_create_from_rstr(const rstr_t *str);
 robject_t *r_string_init(robject_t *obj, ruint32 type, r_object_cleanupfun cleanup, r_object_copyfun copy);
 void r_string_assign(rstring_t *string, const rstr_t *str);
 void r_string_cat(rstring_t *string, const rstr_t *str);
-
+const char *r_string_ansi(const rstring_t *str);
 /*
  * Virtual methods implementation
  */
index b0da906..9897f0d 100644 (file)
@@ -205,6 +205,7 @@ rvmreg_t rvm_reg_create_harray()
        return r;
 }
 
+
 void rvm_reg_setstring(rvmreg_t *r, rstring_t *ptr)
 {
        RVM_REG_SETP(r, ptr);
@@ -431,3 +432,52 @@ int rvm_reg_str2double(rvmreg_t *dst, const rvmreg_t *src)
        rvm_reg_setdouble(dst, d);
        return 0;
 }
+
+
+rint rvm_reg_int(const rvmreg_t *src)
+{
+       R_ASSERT(src);
+       return (int)RVM_REG_GETL(src);
+}
+
+
+rlong rvm_reg_long(const rvmreg_t *src)
+{
+       R_ASSERT(src);
+       return (rlong)RVM_REG_GETL(src);
+}
+
+
+ruchar rvm_reg_boolean(const rvmreg_t *src)
+{
+       R_ASSERT(src);
+       return (ruchar)(RVM_REG_GETL(src) ? 1 : 0);
+}
+
+
+rdouble rvm_reg_double(const rvmreg_t *src)
+{
+       R_ASSERT(src);
+       return (rdouble)RVM_REG_GETL(src);
+}
+
+
+rpointer rvm_reg_pointer(const rvmreg_t *src)
+{
+       R_ASSERT(src);
+       return (rpointer)RVM_REG_GETP(src);
+}
+
+
+rstring_t *rvm_reg_string(const rvmreg_t *src)
+{
+       R_ASSERT(src && rvm_reg_gettype(src) == RVM_DTYPE_STRING);
+       return (rstring_t*)RVM_REG_GETP(src);
+}
+
+
+rjs_object_t *rvm_reg_jsobject(const rvmreg_t *src)
+{
+       R_ASSERT(src && rvm_reg_gettype(src) == RVM_DTYPE_JSOBJECT);
+       return (rjs_object_t*)RVM_REG_GETP(src);
+}
index 8cb8da4..cc66cb1 100644 (file)
@@ -6,6 +6,7 @@
 #include "rarray.h"
 #include "rharray.h"
 #include "rcarray.h"
+#include "rjsobject.h"
 #include "rstring.h"
 
 
@@ -174,6 +175,14 @@ int rvm_reg_str2num(rvmreg_t *dst, const rvmreg_t *src);
 int rvm_reg_str2long(rvmreg_t *dst, const rvmreg_t *ssrc);
 int rvm_reg_str2double(rvmreg_t *dst, const rvmreg_t *ssrc);
 
+rint rvm_reg_int(const rvmreg_t *src);
+rlong rvm_reg_long(const rvmreg_t *src);
+ruchar rvm_reg_boolean(const rvmreg_t *src);
+rdouble rvm_reg_double(const rvmreg_t *src);
+rpointer rvm_reg_pointer(const rvmreg_t *src);
+rstring_t *rvm_reg_string(const rvmreg_t *src);
+rjs_object_t *rvm_reg_jsobject(const rvmreg_t *src);
+
 
 #ifdef __cplusplus
 }
diff --git a/testrjs/build/linux/testrjs.mk b/testrjs/build/linux/testrjs.mk
new file mode 100644 (file)
index 0000000..40a8e02
--- /dev/null
@@ -0,0 +1,42 @@
+ROBJECT_SRCDIR = $(SRCDIR)/robject
+RLIB_SRCDIR = $(SRCDIR)/rlib
+RVM_SRCDIR = $(SRCDIR)/rvm
+RPA2_SRCDIR = $(SRCDIR)/rpa2
+RJS_SRCDIR = $(SRCDIR)/rjs
+TESTS_SRCDIR = $(SRCDIR)/testrjs
+INCLUDE = -I$(SRCDIR)/arch/$(OS)/$(ARCHDIR) -I$(ROBJECT_SRCDIR) -I$(RLIB_SRCDIR) -I$(RVM_SRCDIR) -I$(RJS_SRCDIR) -I$(RPA2_SRCDIR) 
+
+LIBS =  -L$(ROBJECT_SRCDIR)/build/$(OS)/$(ARCHDIR)/out 
+LIBS += -L$(RLIB_SRCDIR)/build/$(OS)/$(ARCHDIR)/out 
+LIBS += -L$(RVM_SRCDIR)/build/$(OS)/$(ARCHDIR)/out 
+LIBS += -L$(RJS_SRCDIR)/build/$(OS)/$(ARCHDIR)/out 
+LIBS += -L$(RPA2_SRCDIR)/build/$(OS)/$(ARCHDIR)/out 
+LIBS += -lrjs -lrpa2 -lrvm -lrlib -lpthread -lm --static
+
+
+TESTS   += $(OUTDIR)/rjs-simple
+
+
+all : $(OUTDIR) $(TESTS)
+
+
+$(OUTDIR)/%: $(TESTS_SRCDIR)/%.c
+       + $(CC) $(CFLAGS) -o $(OUTDIR)/$* $(TESTS_SRCDIR)/$*.c  $(LIBS) $(INCLUDE)
+
+
+$(OUTDIR)/%.o: $(TESTS_SRCDIR)/%.rpa
+       $(LD) -r -b binary -o $(OUTDIR)/$*.o $(TESTS_SRCDIR)/$*.rpa
+
+
+$(OUTDIR):
+       @mkdir $(OUTDIR)
+
+distclean: clean
+       @rm -f .depend
+       @rm -rf $(OUTDIR)
+
+clean:
+       @rm -f $(TESTS)
+       @rm -f *~
+       @rm -f $(SRCDIR)/*~
+
diff --git a/testrjs/build/linux/x86_64/Makefile b/testrjs/build/linux/x86_64/Makefile
new file mode 100644 (file)
index 0000000..f543b97
--- /dev/null
@@ -0,0 +1,29 @@
+ARCHDIR = x86_64
+OUTDIR = out
+OS = $(shell uname | tr "[:upper:]" "[:lower:]")
+SRCDIR = ../../../..
+
+
+CC = gcc
+AR = ar
+ifeq ($(BLDCFG), release)
+CFLAGS = -O3
+else
+ifeq ($(BLDCFG), profile)
+CFLAGS = -O0 -pg
+else
+CFLAGS = -g -O0 -Wall 
+endif
+endif
+
+ifeq ($(CCBLD), yes)
+CFLAGS += -fprofile-arcs -ftest-coverage
+endif
+
+CFLAGS += $(MACH) $(INCLUDE)
+
+CFLAGS := $(CFLAGS)
+LDFLAGS = $(MACH)
+
+
+include ../testrjs.mk
diff --git a/testrjs/rjs-simple.c b/testrjs/rjs-simple.c
new file mode 100644 (file)
index 0000000..3a9c74b
--- /dev/null
@@ -0,0 +1,28 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/mman.h>
+
+#include "rstring.h"
+#include "rjs.h"
+
+
+int main(int argc, char *argv[])
+{
+       rjs_engine_t *jse = rjs_engine_create();
+       rchar test_script1[] = "(2+3)*3;";
+       rchar test_script2[] = "var person = new Object(); person.name = 'Martin'; person.age = 25; person.job = 'slacker';";
+
+//     jse->debugexec = 1;
+       r_printf("script: %s, result: %ld\n", test_script1, rvm_reg_long(rjs_engine_exec_s(jse, test_script1)));
+       rjs_engine_exec_s(jse, test_script2);
+       r_printf("Name: %s\n", r_string_ansi(rvm_reg_string(rjs_engine_exec_s(jse, "person.name;"))));
+       r_printf("Job: %s\n", r_string_ansi(rvm_reg_string(rjs_engine_exec_s(jse, "person.job;"))));
+
+       rjs_engine_destroy(jse);
+       return 0;
+}