diff --git a/programs/develop/kosjs/Makefile b/programs/develop/kosjs/Makefile new file mode 100755 index 0000000000..e024d89922 --- /dev/null +++ b/programs/develop/kosjs/Makefile @@ -0,0 +1,23 @@ +CC = kos32-gcc +LD = kos32-ld +OBJCOPY = objcopy +STRIP = strip + +NAME = kosjs + +SDK_DIR = ../../../contrib/sdk + +LDFLAGS = -call_shared -nostdlib -T $(SDK_DIR)/sources/newlib/app-dynamic.lds --image-base 0 +LIBPATH = -L$(SDK_DIR)/lib -L/home/autobuild/tools/win32/mingw32/lib -L libmujs/lib +CFLAGS = -c -fno-ident -O2 -fomit-frame-pointer -fno-ident -U__WIN32__ -U_Win32 -U_WIN32 -U__MINGW32__ -UWIN32 +INCLUDES = -I $(SDK_DIR)/sources/newlib/libc/include -I libmujs/include + +all: + $(CC) $(CFLAGS) $(INCLUDES) kosjs.c import.c + $(LD) $(LDFLAGS) $(LIBPATH) --subsystem native -o $(NAME) $(NAME).o import.o -lmujs -lgcc -lc.dll + $(STRIP) -s $(NAME) -o $(NAME) + $(OBJCOPY) $(NAME) -O binary + +clean: + rm -f $(NAME) *.o + diff --git a/programs/develop/kosjs/examples/example.js b/programs/develop/kosjs/examples/example.js new file mode 100755 index 0000000000..344f3595c8 --- /dev/null +++ b/programs/develop/kosjs/examples/example.js @@ -0,0 +1,40 @@ +var button_text = 0 +var button = 2 + +function Redraw() +{ + StartDraw() + WindowCreate(10, 40, 400, 200, "My window", 0xFFFFFF, 0x14) + WriteText("KolibriOS JS example", 15, 34, 0, 0x90000000, 0xFFFFFF) + ButtonCreate((150 << 16) + 100, (100 << 16) + 50, button, 0x177245) + WriteText("Click!", 155,115, 0, 0x91000000 | 0xFFFFFF) + WriteText(button_text, 15,100, 0, 0x92000000) + EndDraw() +} + +while(1) +{ + var gui_event = GetEvent() + switch(gui_event) + { + case 0: + break + case 1: + Redraw() + break + case 3: + var pressed_button = GetButtonEvent() + switch (pressed_button) + { + case 1: + Exit() + break + case button: + button_text++; + Redraw() + break + } + break + } +} + diff --git a/programs/develop/kosjs/import.c b/programs/develop/kosjs/import.c new file mode 100755 index 0000000000..c18cf2cab1 --- /dev/null +++ b/programs/develop/kosjs/import.c @@ -0,0 +1,79 @@ +#include +#include +#include + +#include + +static void _ButtonCreate() +{ + define_button(js_touint32(J, 1),js_touint32(J,2), js_touint32(J,3), js_touint32(J,4)); +} + +static void _WindowCreate() +{ + sys_create_window(js_toint(J, 1), js_toint(J, 2), js_toint(J, 3), js_toint(J, 4), js_tostring(J,5), js_touint32(J,6), js_touint32(J,7)); +} + +static void _StartDraw() +{ + begin_draw(); +} + +static void _EndDraw() +{ + end_draw(); +} + +static void _DebugPrintS() +{ + puts(js_tostring(J,1)); + +} + +static void _GetEvent() +{ + js_pushnumber(J, get_os_event()); +} + +static void _GetButtonEvent() +{ + js_pushnumber(J,get_os_button()); +} + +static void _WriteText() +{ + draw_text_sys(js_tostring(J,1), js_toint32(J,2), js_toint32(J,3), js_toint32(J,4), js_touint32(J,5)); +} + +void import_functions() +{ + J = js_newstate(NULL, NULL, JS_STRICT); + + js_newcfunction(J, _WindowCreate, "WindowCreate", 7); + js_setglobal(J, "WindowCreate"); + + js_newcfunction(J, _StartDraw, "StartDraw", 0); + js_setglobal(J, "StartDraw"); + + js_newcfunction(J, _EndDraw, "EndDraw", 0); + js_setglobal(J, "EndDraw"); + + js_newcfunction(J, _GetEvent, "GetEvent", 0); + js_setglobal(J, "GetEvent"); + + js_newcfunction(J, _DebugPrintS, "DebugPrintS", 0); + js_setglobal(J, "DebugPrintS"); + + js_newcfunction(J, _ButtonCreate, "ButtonCreate", 4); + js_setglobal(J, "ButtonCreate"); + + js_newcfunction(J, _GetButtonEvent, "GetButtonEvent", 0); + js_setglobal(J, "GetButtonEvent"); + + js_newcfunction(J, (void*)exit, "Exit", 0); + js_setglobal(J, "Exit"); + + js_newcfunction(J, _WriteText, "WriteText", 5); + js_setglobal(J, "WriteText"); + +} diff --git a/programs/develop/kosjs/kosjs.c b/programs/develop/kosjs/kosjs.c new file mode 100755 index 0000000000..4d395a1323 --- /dev/null +++ b/programs/develop/kosjs/kosjs.c @@ -0,0 +1,14 @@ +#include +#include + +#include +#include + + +int main(int argc, char **argv) +{ + import_functions(); + js_dofile(J, argv[1]); + js_freestate (J); + exit(0); +} diff --git a/programs/develop/kosjs/libmujs/include/astnames.h b/programs/develop/kosjs/libmujs/include/astnames.h new file mode 100755 index 0000000000..ab7620fabc --- /dev/null +++ b/programs/develop/kosjs/libmujs/include/astnames.h @@ -0,0 +1,92 @@ +"list", +"fundec", +"identifier", +"exp_identifier", +"exp_number", +"exp_string", +"exp_regexp", +"exp_undef", +"exp_null", +"exp_true", +"exp_false", +"exp_this", +"exp_array", +"exp_object", +"exp_prop_val", +"exp_prop_get", +"exp_prop_set", +"exp_fun", +"exp_index", +"exp_member", +"exp_call", +"exp_new", +"exp_postinc", +"exp_postdec", +"exp_delete", +"exp_void", +"exp_typeof", +"exp_preinc", +"exp_predec", +"exp_pos", +"exp_neg", +"exp_bitnot", +"exp_lognot", +"exp_mod", +"exp_div", +"exp_mul", +"exp_sub", +"exp_add", +"exp_ushr", +"exp_shr", +"exp_shl", +"exp_in", +"exp_instanceof", +"exp_ge", +"exp_le", +"exp_gt", +"exp_lt", +"exp_strictne", +"exp_stricteq", +"exp_ne", +"exp_eq", +"exp_bitand", +"exp_bitxor", +"exp_bitor", +"exp_logand", +"exp_logor", +"exp_cond", +"exp_ass", +"exp_ass_mul", +"exp_ass_div", +"exp_ass_mod", +"exp_ass_add", +"exp_ass_sub", +"exp_ass_shl", +"exp_ass_shr", +"exp_ass_ushr", +"exp_ass_bitand", +"exp_ass_bitxor", +"exp_ass_bitor", +"exp_comma", +"exp_var", +"stm_block", +"stm_empty", +"stm_var", +"stm_if", +"stm_do", +"stm_while", +"stm_for", +"stm_for_var", +"stm_for_in", +"stm_for_in_var", +"stm_continue", +"stm_break", +"stm_return", +"stm_with", +"stm_switch", +"stm_throw", +"stm_try", +"stm_debugger", +"stm_label", +"stm_case", +"stm_default", diff --git a/programs/develop/kosjs/libmujs/include/import.h b/programs/develop/kosjs/libmujs/include/import.h new file mode 100755 index 0000000000..43fa27bb94 --- /dev/null +++ b/programs/develop/kosjs/libmujs/include/import.h @@ -0,0 +1,6 @@ +#include "mujs.h" +#define js_toint(J, idx) js_tointeger(J, idx) + +js_State *J; + +void import_functions(); diff --git a/programs/develop/kosjs/libmujs/include/jsbuiltin.h b/programs/develop/kosjs/libmujs/include/jsbuiltin.h new file mode 100755 index 0000000000..a96d3befdd --- /dev/null +++ b/programs/develop/kosjs/libmujs/include/jsbuiltin.h @@ -0,0 +1,21 @@ +#ifndef js_builtin_h +#define js_builtin_h + +void jsB_init(js_State *J); +void jsB_initobject(js_State *J); +void jsB_initarray(js_State *J); +void jsB_initfunction(js_State *J); +void jsB_initboolean(js_State *J); +void jsB_initnumber(js_State *J); +void jsB_initstring(js_State *J); +void jsB_initregexp(js_State *J); +void jsB_initerror(js_State *J); +void jsB_initmath(js_State *J); +void jsB_initjson(js_State *J); +void jsB_initdate(js_State *J); + +void jsB_propf(js_State *J, const char *name, js_CFunction cfun, int n); +void jsB_propn(js_State *J, const char *name, double number); +void jsB_props(js_State *J, const char *name, const char *string); + +#endif diff --git a/programs/develop/kosjs/libmujs/include/jscompile.h b/programs/develop/kosjs/libmujs/include/jscompile.h new file mode 100755 index 0000000000..172f8fdd58 --- /dev/null +++ b/programs/develop/kosjs/libmujs/include/jscompile.h @@ -0,0 +1,146 @@ +#ifndef js_compile_h +#define js_compile_h + +enum js_OpCode +{ + OP_POP, /* A -- */ + OP_DUP, /* A -- A A */ + OP_DUP2, /* A B -- A B A B */ + OP_ROT2, /* A B -- B A */ + OP_ROT3, /* A B C -- C A B */ + OP_ROT4, /* A B C D -- D A B C */ + + OP_INTEGER, /* -K- (number-32768) */ + OP_NUMBER, /* -N- */ + OP_STRING, /* -S- */ + OP_CLOSURE, /* -F- */ + + OP_NEWARRAY, + OP_NEWOBJECT, + OP_NEWREGEXP, /* -S,opts- */ + + OP_UNDEF, + OP_NULL, + OP_TRUE, + OP_FALSE, + + OP_THIS, + OP_CURRENT, /* currently executing function object */ + + OP_GETLOCAL, /* -K- */ + OP_SETLOCAL, /* -K- */ + OP_DELLOCAL, /* -K- false */ + + OP_HASVAR, /* -S- ( | undefined ) */ + OP_GETVAR, /* -S- */ + OP_SETVAR, /* -S- */ + OP_DELVAR, /* -S- */ + + OP_IN, /* -- */ + + OP_INITPROP, /* -- */ + OP_INITGETTER, /* -- */ + OP_INITSETTER, /* -- */ + + OP_GETPROP, /* -- */ + OP_GETPROP_S, /* -S- */ + OP_SETPROP, /* -- */ + OP_SETPROP_S, /* -S- */ + OP_DELPROP, /* -- */ + OP_DELPROP_S, /* -S- */ + + OP_ITERATOR, /* -- */ + OP_NEXTITER, /* -- ( true | false ) */ + + OP_EVAL, /* -(numargs)- */ + OP_CALL, /* -(numargs)- */ + OP_NEW, /* -(numargs)- */ + + OP_TYPEOF, + OP_POS, + OP_NEG, + OP_BITNOT, + OP_LOGNOT, + OP_INC, /* -- ToNumber(x)+1 */ + OP_DEC, /* -- ToNumber(x)-1 */ + OP_POSTINC, /* -- ToNumber(x)+1 ToNumber(x) */ + OP_POSTDEC, /* -- ToNumber(x)-1 ToNumber(x) */ + + OP_MUL, + OP_DIV, + OP_MOD, + OP_ADD, + OP_SUB, + OP_SHL, + OP_SHR, + OP_USHR, + OP_LT, + OP_GT, + OP_LE, + OP_GE, + OP_EQ, + OP_NE, + OP_STRICTEQ, + OP_STRICTNE, + OP_JCASE, + OP_BITAND, + OP_BITXOR, + OP_BITOR, + + OP_INSTANCEOF, + + OP_THROW, + + OP_TRY, /* -ADDR- /jump/ or -ADDR- */ + OP_ENDTRY, + + OP_CATCH, /* push scope chain with exception variable */ + OP_ENDCATCH, + + OP_WITH, + OP_ENDWITH, + + OP_DEBUGGER, + OP_JUMP, + OP_JTRUE, + OP_JFALSE, + OP_RETURN, +}; + +struct js_Function +{ + const char *name; + int script; + int lightweight; + int strict; + int arguments; + int numparams; + + js_Instruction *code; + int codecap, codelen; + + js_Function **funtab; + int funcap, funlen; + + double *numtab; + int numcap, numlen; + + const char **strtab; + int strcap, strlen; + + const char **vartab; + int varcap, varlen; + + const char *filename; + int line, lastline; + + js_Function *gcnext; + int gcmark; +}; + +js_Function *jsC_compilefunction(js_State *J, js_Ast *prog); +js_Function *jsC_compilescript(js_State *J, js_Ast *prog, int default_strict); +const char *jsC_opcodestring(enum js_OpCode opcode); +void jsC_dumpfunction(js_State *J, js_Function *fun); + +#endif diff --git a/programs/develop/kosjs/libmujs/include/jsi.h b/programs/develop/kosjs/libmujs/include/jsi.h new file mode 100755 index 0000000000..5fb179a606 --- /dev/null +++ b/programs/develop/kosjs/libmujs/include/jsi.h @@ -0,0 +1,255 @@ +#ifndef jsi_h +#define jsi_h + +#include "mujs.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Microsoft Visual C */ +#ifdef _MSC_VER +#pragma warning(disable:4996) /* _CRT_SECURE_NO_WARNINGS */ +#pragma warning(disable:4244) /* implicit conversion from double to int */ +#pragma warning(disable:4267) /* implicit conversion of int to smaller int */ +#define inline __inline +#if _MSC_VER < 1900 /* MSVC 2015 */ +#define snprintf jsW_snprintf +#define vsnprintf jsW_vsnprintf +static int jsW_vsnprintf(char *str, size_t size, const char *fmt, va_list ap) +{ + int n; + n = _vsnprintf(str, size, fmt, ap); + str[size-1] = 0; + return n; +} +static int jsW_snprintf(char *str, size_t size, const char *fmt, ...) +{ + int n; + va_list ap; + va_start(ap, fmt); + n = jsW_vsnprintf(str, size, fmt, ap); + va_end(ap); + return n; +} +#endif +#if _MSC_VER <= 1700 /* <= MSVC 2012 */ +#define isnan(x) _isnan(x) +#define isinf(x) (!_finite(x)) +#define isfinite(x) _finite(x) +static __inline int signbit(double x) { __int64 i; memcpy(&i, &x, 8); return i>>63; } +#define INFINITY (DBL_MAX+DBL_MAX) +#define NAN (INFINITY-INFINITY) +#endif +#endif + +#define soffsetof(x,y) ((int)offsetof(x,y)) +#define nelem(a) (int)(sizeof (a) / sizeof (a)[0]) + +void *js_malloc(js_State *J, int size); +void *js_realloc(js_State *J, void *ptr, int size); +void js_free(js_State *J, void *ptr); + +typedef struct js_Regexp js_Regexp; +typedef struct js_Value js_Value; +typedef struct js_Object js_Object; +typedef struct js_String js_String; +typedef struct js_Ast js_Ast; +typedef struct js_Function js_Function; +typedef struct js_Environment js_Environment; +typedef struct js_StringNode js_StringNode; +typedef struct js_Jumpbuf js_Jumpbuf; +typedef struct js_StackTrace js_StackTrace; + +/* Limits */ + +#ifndef JS_STACKSIZE +#define JS_STACKSIZE 256 /* value stack size */ +#endif +#ifndef JS_ENVLIMIT +#define JS_ENVLIMIT 128 /* environment stack size */ +#endif +#ifndef JS_TRYLIMIT +#define JS_TRYLIMIT 64 /* exception stack size */ +#endif +#ifndef JS_GCLIMIT +#define JS_GCLIMIT 10000 /* run gc cycle every N allocations */ +#endif +#ifndef JS_ASTLIMIT +#define JS_ASTLIMIT 100 /* max nested expressions */ +#endif + +/* instruction size -- change to int if you get integer overflow syntax errors */ + +#ifdef JS_INSTRUCTION +typedef JS_INSTRUCTION js_Instruction; +#else +typedef unsigned short js_Instruction; +#endif + +/* String interning */ + +char *js_strdup(js_State *J, const char *s); +const char *js_intern(js_State *J, const char *s); +void jsS_dumpstrings(js_State *J); +void jsS_freestrings(js_State *J); + +/* Portable strtod and printf float formatting */ + +void js_fmtexp(char *p, int e); +int js_grisu2(double v, char *buffer, int *K); +double js_strtod(const char *as, char **aas); + +/* Private stack functions */ + +void js_newarguments(js_State *J); +void js_newfunction(js_State *J, js_Function *function, js_Environment *scope); +void js_newscript(js_State *J, js_Function *fun, js_Environment *scope, int type); +void js_loadeval(js_State *J, const char *filename, const char *source); + +js_Regexp *js_toregexp(js_State *J, int idx); +int js_isarrayindex(js_State *J, const char *str, int *idx); +int js_runeat(js_State *J, const char *s, int i); +int js_utfptrtoidx(const char *s, const char *p); +const char *js_utfidxtoptr(const char *s, int i); + +void js_dup(js_State *J); +void js_dup2(js_State *J); +void js_rot2(js_State *J); +void js_rot3(js_State *J); +void js_rot4(js_State *J); +void js_rot2pop1(js_State *J); +void js_rot3pop2(js_State *J); +void js_dup1rot3(js_State *J); +void js_dup1rot4(js_State *J); + +void js_RegExp_prototype_exec(js_State *J, js_Regexp *re, const char *text); + +void js_trap(js_State *J, int pc); /* dump stack and environment to stdout */ + +struct js_StackTrace +{ + const char *name; + const char *file; + int line; +}; + +/* Exception handling */ + +struct js_Jumpbuf +{ + jmp_buf buf; + js_Environment *E; + int envtop; + int tracetop; + int top, bot; + int strict; + js_Instruction *pc; +}; + +void *js_savetrypc(js_State *J, js_Instruction *pc); + +#define js_trypc(J, PC) \ + setjmp(js_savetrypc(J, PC)) + +/* String buffer */ + +typedef struct js_Buffer { int n, m; char s[64]; } js_Buffer; + +void js_putc(js_State *J, js_Buffer **sbp, int c); +void js_puts(js_State *J, js_Buffer **sb, const char *s); +void js_putm(js_State *J, js_Buffer **sb, const char *s, const char *e); + +/* State struct */ + +struct js_State +{ + void *actx; + void *uctx; + js_Alloc alloc; + js_Report report; + js_Panic panic; + + js_StringNode *strings; + + int default_strict; + int strict; + + /* parser input source */ + const char *filename; + const char *source; + int line; + + /* lexer state */ + struct { char *text; int len, cap; } lexbuf; + int lexline; + int lexchar; + int lasttoken; + int newline; + + /* parser state */ + int astdepth; + int lookahead; + const char *text; + double number; + js_Ast *gcast; /* list of allocated nodes to free after parsing */ + + /* runtime environment */ + js_Object *Object_prototype; + js_Object *Array_prototype; + js_Object *Function_prototype; + js_Object *Boolean_prototype; + js_Object *Number_prototype; + js_Object *String_prototype; + js_Object *RegExp_prototype; + js_Object *Date_prototype; + + js_Object *Error_prototype; + js_Object *EvalError_prototype; + js_Object *RangeError_prototype; + js_Object *ReferenceError_prototype; + js_Object *SyntaxError_prototype; + js_Object *TypeError_prototype; + js_Object *URIError_prototype; + + unsigned int seed; /* Math.random seed */ + + int nextref; /* for js_ref use */ + js_Object *R; /* registry of hidden values */ + js_Object *G; /* the global object */ + js_Environment *E; /* current environment scope */ + js_Environment *GE; /* global environment scope (at the root) */ + + /* execution stack */ + int top, bot; + js_Value *stack; + + /* garbage collector list */ + int gcpause; + int gcmark; + int gccounter; + js_Environment *gcenv; + js_Function *gcfun; + js_Object *gcobj; + js_String *gcstr; + + /* environments on the call stack but currently not in scope */ + int envtop; + js_Environment *envstack[JS_ENVLIMIT]; + + /* debug info stack trace */ + int tracetop; + js_StackTrace trace[JS_ENVLIMIT]; + + /* exception stack */ + int trytop; + js_Jumpbuf trybuf[JS_TRYLIMIT]; +}; + +#endif diff --git a/programs/develop/kosjs/libmujs/include/jslex.h b/programs/develop/kosjs/libmujs/include/jslex.h new file mode 100755 index 0000000000..e050576d98 --- /dev/null +++ b/programs/develop/kosjs/libmujs/include/jslex.h @@ -0,0 +1,81 @@ +#ifndef js_lex_h +#define js_lex_h + +enum +{ + TK_IDENTIFIER = 256, + TK_NUMBER, + TK_STRING, + TK_REGEXP, + + /* multi-character punctuators */ + TK_LE, + TK_GE, + TK_EQ, + TK_NE, + TK_STRICTEQ, + TK_STRICTNE, + TK_SHL, + TK_SHR, + TK_USHR, + TK_AND, + TK_OR, + TK_ADD_ASS, + TK_SUB_ASS, + TK_MUL_ASS, + TK_DIV_ASS, + TK_MOD_ASS, + TK_SHL_ASS, + TK_SHR_ASS, + TK_USHR_ASS, + TK_AND_ASS, + TK_OR_ASS, + TK_XOR_ASS, + TK_INC, + TK_DEC, + + /* keywords */ + TK_BREAK, + TK_CASE, + TK_CATCH, + TK_CONTINUE, + TK_DEBUGGER, + TK_DEFAULT, + TK_DELETE, + TK_DO, + TK_ELSE, + TK_FALSE, + TK_FINALLY, + TK_FOR, + TK_FUNCTION, + TK_IF, + TK_IN, + TK_INSTANCEOF, + TK_NEW, + TK_NULL, + TK_RETURN, + TK_SWITCH, + TK_THIS, + TK_THROW, + TK_TRUE, + TK_TRY, + TK_TYPEOF, + TK_VAR, + TK_VOID, + TK_WHILE, + TK_WITH, +}; + +int jsY_iswhite(int c); +int jsY_isnewline(int c); +int jsY_ishex(int c); +int jsY_tohex(int c); + +const char *jsY_tokenstring(int token); +int jsY_findword(const char *s, const char **list, int num); + +void jsY_initlex(js_State *J, const char *filename, const char *source); +int jsY_lex(js_State *J); +int jsY_lexjson(js_State *J); + +#endif diff --git a/programs/develop/kosjs/libmujs/include/jsparse.h b/programs/develop/kosjs/libmujs/include/jsparse.h new file mode 100755 index 0000000000..f5df25af2a --- /dev/null +++ b/programs/develop/kosjs/libmujs/include/jsparse.h @@ -0,0 +1,146 @@ +#ifndef js_parse_h +#define js_parse_h + +enum js_AstType +{ + AST_LIST, + AST_FUNDEC, + AST_IDENTIFIER, + + EXP_IDENTIFIER, + EXP_NUMBER, + EXP_STRING, + EXP_REGEXP, + + /* literals */ + EXP_UNDEF, /* for array elisions */ + EXP_NULL, + EXP_TRUE, + EXP_FALSE, + EXP_THIS, + + EXP_ARRAY, + EXP_OBJECT, + EXP_PROP_VAL, + EXP_PROP_GET, + EXP_PROP_SET, + + EXP_FUN, + + /* expressions */ + EXP_INDEX, + EXP_MEMBER, + EXP_CALL, + EXP_NEW, + + EXP_POSTINC, + EXP_POSTDEC, + + EXP_DELETE, + EXP_VOID, + EXP_TYPEOF, + EXP_PREINC, + EXP_PREDEC, + EXP_POS, + EXP_NEG, + EXP_BITNOT, + EXP_LOGNOT, + + EXP_MOD, + EXP_DIV, + EXP_MUL, + EXP_SUB, + EXP_ADD, + EXP_USHR, + EXP_SHR, + EXP_SHL, + EXP_IN, + EXP_INSTANCEOF, + EXP_GE, + EXP_LE, + EXP_GT, + EXP_LT, + EXP_STRICTNE, + EXP_STRICTEQ, + EXP_NE, + EXP_EQ, + EXP_BITAND, + EXP_BITXOR, + EXP_BITOR, + EXP_LOGAND, + EXP_LOGOR, + + EXP_COND, + + EXP_ASS, + EXP_ASS_MUL, + EXP_ASS_DIV, + EXP_ASS_MOD, + EXP_ASS_ADD, + EXP_ASS_SUB, + EXP_ASS_SHL, + EXP_ASS_SHR, + EXP_ASS_USHR, + EXP_ASS_BITAND, + EXP_ASS_BITXOR, + EXP_ASS_BITOR, + + EXP_COMMA, + + EXP_VAR, /* var initializer */ + + /* statements */ + STM_BLOCK, + STM_EMPTY, + STM_VAR, + STM_IF, + STM_DO, + STM_WHILE, + STM_FOR, + STM_FOR_VAR, + STM_FOR_IN, + STM_FOR_IN_VAR, + STM_CONTINUE, + STM_BREAK, + STM_RETURN, + STM_WITH, + STM_SWITCH, + STM_THROW, + STM_TRY, + STM_DEBUGGER, + + STM_LABEL, + STM_CASE, + STM_DEFAULT, +}; + +typedef struct js_JumpList js_JumpList; + +struct js_JumpList +{ + enum js_AstType type; + int inst; + js_JumpList *next; +}; + +struct js_Ast +{ + enum js_AstType type; + int line; + js_Ast *parent, *a, *b, *c, *d; + double number; + const char *string; + js_JumpList *jumps; /* list of break/continue jumps to patch */ + int casejump; /* for switch case clauses */ + js_Ast *gcnext; /* next in alloc list */ +}; + +js_Ast *jsP_parsefunction(js_State *J, const char *filename, const char *params, const char *body); +js_Ast *jsP_parse(js_State *J, const char *filename, const char *source); +void jsP_freeparse(js_State *J); + +const char *jsP_aststring(enum js_AstType type); +void jsP_dumpsyntax(js_State *J, js_Ast *prog, int minify); +void jsP_dumplist(js_State *J, js_Ast *prog); + +#endif diff --git a/programs/develop/kosjs/libmujs/include/jsrun.h b/programs/develop/kosjs/libmujs/include/jsrun.h new file mode 100755 index 0000000000..e1e04a77ce --- /dev/null +++ b/programs/develop/kosjs/libmujs/include/jsrun.h @@ -0,0 +1,15 @@ +#ifndef js_run_h +#define js_run_h + +js_Environment *jsR_newenvironment(js_State *J, js_Object *variables, js_Environment *outer); + +struct js_Environment +{ + js_Environment *outer; + js_Object *variables; + + js_Environment *gcnext; + int gcmark; +}; + +#endif diff --git a/programs/develop/kosjs/libmujs/include/jsvalue.h b/programs/develop/kosjs/libmujs/include/jsvalue.h new file mode 100755 index 0000000000..adfc6f9df8 --- /dev/null +++ b/programs/develop/kosjs/libmujs/include/jsvalue.h @@ -0,0 +1,187 @@ +#ifndef js_value_h +#define js_value_h + +typedef struct js_Property js_Property; +typedef struct js_Iterator js_Iterator; + +/* Hint to ToPrimitive() */ +enum { + JS_HNONE, + JS_HNUMBER, + JS_HSTRING +}; + +enum js_Type { + JS_TSHRSTR, /* type tag doubles as string zero-terminator */ + JS_TUNDEFINED, + JS_TNULL, + JS_TBOOLEAN, + JS_TNUMBER, + JS_TLITSTR, + JS_TMEMSTR, + JS_TOBJECT, +}; + +enum js_Class { + JS_COBJECT, + JS_CARRAY, + JS_CFUNCTION, + JS_CSCRIPT, /* function created from global code */ + JS_CEVAL, /* function created from eval code */ + JS_CCFUNCTION, /* built-in function */ + JS_CERROR, + JS_CBOOLEAN, + JS_CNUMBER, + JS_CSTRING, + JS_CREGEXP, + JS_CDATE, + JS_CMATH, + JS_CJSON, + JS_CARGUMENTS, + JS_CITERATOR, + JS_CUSERDATA, +}; + +/* + Short strings abuse the js_Value struct. By putting the type tag in the + last byte, and using 0 as the tag for short strings, we can use the + entire js_Value as string storage by letting the type tag serve double + purpose as the string zero terminator. +*/ + +struct js_Value +{ + union { + int boolean; + double number; + char shrstr[8]; + const char *litstr; + js_String *memstr; + js_Object *object; + } u; + char pad[7]; /* extra storage for shrstr */ + char type; /* type tag and zero terminator for shrstr */ +}; + +struct js_String +{ + js_String *gcnext; + char gcmark; + char p[1]; +}; + +struct js_Regexp +{ + void *prog; + char *source; + unsigned short flags; + unsigned short last; +}; + +struct js_Object +{ + enum js_Class type; + int extensible; + js_Property *properties; + int count; /* number of properties, for array sparseness check */ + js_Object *prototype; + union { + int boolean; + double number; + struct { + const char *string; + int length; + } s; + struct { + int length; + } a; + struct { + js_Function *function; + js_Environment *scope; + } f; + struct { + const char *name; + js_CFunction function; + js_CFunction constructor; + int length; + } c; + js_Regexp r; + struct { + js_Object *target; + js_Iterator *head; + } iter; + struct { + const char *tag; + void *data; + js_HasProperty has; + js_Put put; + js_Delete delete; + js_Finalize finalize; + } user; + } u; + js_Object *gcnext; + int gcmark; +}; + +struct js_Property +{ + const char *name; + js_Property *left, *right; + int level; + int atts; + js_Value value; + js_Object *getter; + js_Object *setter; +}; + +struct js_Iterator +{ + const char *name; + js_Iterator *next; +}; + +/* jsrun.c */ +js_String *jsV_newmemstring(js_State *J, const char *s, int n); +js_Value *js_tovalue(js_State *J, int idx); +void js_toprimitive(js_State *J, int idx, int hint); +js_Object *js_toobject(js_State *J, int idx); +void js_pushvalue(js_State *J, js_Value v); +void js_pushobject(js_State *J, js_Object *v); + +/* jsvalue.c */ +int jsV_toboolean(js_State *J, js_Value *v); +double jsV_tonumber(js_State *J, js_Value *v); +double jsV_tointeger(js_State *J, js_Value *v); +const char *jsV_tostring(js_State *J, js_Value *v); +js_Object *jsV_toobject(js_State *J, js_Value *v); +void jsV_toprimitive(js_State *J, js_Value *v, int preferred); + +const char *js_itoa(char buf[32], int a); +double js_stringtofloat(const char *s, char **ep); +int jsV_numbertointeger(double n); +int jsV_numbertoint32(double n); +unsigned int jsV_numbertouint32(double n); +short jsV_numbertoint16(double n); +unsigned short jsV_numbertouint16(double n); +const char *jsV_numbertostring(js_State *J, char buf[32], double number); +double jsV_stringtonumber(js_State *J, const char *string); + +/* jsproperty.c */ +js_Object *jsV_newobject(js_State *J, enum js_Class type, js_Object *prototype); +js_Property *jsV_getownproperty(js_State *J, js_Object *obj, const char *name); +js_Property *jsV_getpropertyx(js_State *J, js_Object *obj, const char *name, int *own); +js_Property *jsV_getproperty(js_State *J, js_Object *obj, const char *name); +js_Property *jsV_setproperty(js_State *J, js_Object *obj, const char *name); +js_Property *jsV_nextproperty(js_State *J, js_Object *obj, const char *name); +void jsV_delproperty(js_State *J, js_Object *obj, const char *name); + +js_Object *jsV_newiterator(js_State *J, js_Object *obj, int own); +const char *jsV_nextiterator(js_State *J, js_Object *iter); + +void jsV_resizearray(js_State *J, js_Object *obj, int newlen); + +/* jsdump.c */ +void js_dumpobject(js_State *J, js_Object *obj); +void js_dumpvalue(js_State *J, js_Value v); + +#endif diff --git a/programs/develop/kosjs/libmujs/include/mujs.h b/programs/develop/kosjs/libmujs/include/mujs.h new file mode 100755 index 0000000000..8d0668897b --- /dev/null +++ b/programs/develop/kosjs/libmujs/include/mujs.h @@ -0,0 +1,229 @@ +#ifndef mujs_h +#define mujs_h + +#include /* required for setjmp in fz_try macro */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* noreturn is a GCC extension */ +#ifdef __GNUC__ +#define JS_NORETURN __attribute__((noreturn)) +#else +#ifdef _MSC_VER +#define JS_NORETURN __declspec(noreturn) +#else +#define JS_NORETURN +#endif +#endif + +/* GCC can do type checking of printf strings */ +#ifdef __printflike +#define JS_PRINTFLIKE __printflike +#else +#if __GNUC__ > 2 || __GNUC__ == 2 && __GNUC_MINOR__ >= 7 +#define JS_PRINTFLIKE(fmtarg, firstvararg) \ + __attribute__((__format__ (__printf__, fmtarg, firstvararg))) +#else +#define JS_PRINTFLIKE(fmtarg, firstvararg) +#endif +#endif + +typedef struct js_State js_State; + +typedef void *(*js_Alloc)(void *memctx, void *ptr, int size); +typedef void (*js_Panic)(js_State *J); +typedef void (*js_CFunction)(js_State *J); +typedef void (*js_Finalize)(js_State *J, void *p); +typedef int (*js_HasProperty)(js_State *J, void *p, const char *name); +typedef int (*js_Put)(js_State *J, void *p, const char *name); +typedef int (*js_Delete)(js_State *J, void *p, const char *name); +typedef void (*js_Report)(js_State *J, const char *message); + +/* Basic functions */ +js_State *js_newstate(js_Alloc alloc, void *actx, int flags); +void js_setcontext(js_State *J, void *uctx); +void *js_getcontext(js_State *J); +void js_setreport(js_State *J, js_Report report); +js_Panic js_atpanic(js_State *J, js_Panic panic); +void js_freestate(js_State *J); +void js_gc(js_State *J, int report); + +int js_dostring(js_State *J, const char *source); +int js_dofile(js_State *J, const char *filename); +int js_ploadstring(js_State *J, const char *filename, const char *source); +int js_ploadfile(js_State *J, const char *filename); +int js_pcall(js_State *J, int n); +int js_pconstruct(js_State *J, int n); + +/* Exception handling */ + +void *js_savetry(js_State *J); /* returns a jmp_buf */ + +#define js_try(J) \ + setjmp(js_savetry(J)) + +void js_endtry(js_State *J); + +/* State constructor flags */ +enum { + JS_STRICT = 1, +}; + +/* RegExp flags */ +enum { + JS_REGEXP_G = 1, + JS_REGEXP_I = 2, + JS_REGEXP_M = 4, +}; + +/* Property attribute flags */ +enum { + JS_READONLY = 1, + JS_DONTENUM = 2, + JS_DONTCONF = 4, +}; + +void js_report(js_State *J, const char *message); + +void js_newerror(js_State *J, const char *message); +void js_newevalerror(js_State *J, const char *message); +void js_newrangeerror(js_State *J, const char *message); +void js_newreferenceerror(js_State *J, const char *message); +void js_newsyntaxerror(js_State *J, const char *message); +void js_newtypeerror(js_State *J, const char *message); +void js_newurierror(js_State *J, const char *message); + +JS_NORETURN void js_error(js_State *J, const char *fmt, ...) JS_PRINTFLIKE(2,3); +JS_NORETURN void js_evalerror(js_State *J, const char *fmt, ...) JS_PRINTFLIKE(2,3); +JS_NORETURN void js_rangeerror(js_State *J, const char *fmt, ...) JS_PRINTFLIKE(2,3); +JS_NORETURN void js_referenceerror(js_State *J, const char *fmt, ...) JS_PRINTFLIKE(2,3); +JS_NORETURN void js_syntaxerror(js_State *J, const char *fmt, ...) JS_PRINTFLIKE(2,3); +JS_NORETURN void js_typeerror(js_State *J, const char *fmt, ...) JS_PRINTFLIKE(2,3); +JS_NORETURN void js_urierror(js_State *J, const char *fmt, ...) JS_PRINTFLIKE(2,3); +JS_NORETURN void js_throw(js_State *J); + +void js_loadstring(js_State *J, const char *filename, const char *source); +void js_loadfile(js_State *J, const char *filename); + +void js_eval(js_State *J); +void js_call(js_State *J, int n); +void js_construct(js_State *J, int n); + +const char *js_ref(js_State *J); +void js_unref(js_State *J, const char *ref); + +void js_getregistry(js_State *J, const char *name); +void js_setregistry(js_State *J, const char *name); +void js_delregistry(js_State *J, const char *name); + +void js_getglobal(js_State *J, const char *name); +void js_setglobal(js_State *J, const char *name); +void js_defglobal(js_State *J, const char *name, int atts); +void js_delglobal(js_State *J, const char *name); + +int js_hasproperty(js_State *J, int idx, const char *name); +void js_getproperty(js_State *J, int idx, const char *name); +void js_setproperty(js_State *J, int idx, const char *name); +void js_defproperty(js_State *J, int idx, const char *name, int atts); +void js_delproperty(js_State *J, int idx, const char *name); +void js_defaccessor(js_State *J, int idx, const char *name, int atts); + +int js_getlength(js_State *J, int idx); +void js_setlength(js_State *J, int idx, int len); +int js_hasindex(js_State *J, int idx, int i); +void js_getindex(js_State *J, int idx, int i); +void js_setindex(js_State *J, int idx, int i); +void js_delindex(js_State *J, int idx, int i); + +void js_currentfunction(js_State *J); +void js_pushglobal(js_State *J); +void js_pushundefined(js_State *J); +void js_pushnull(js_State *J); +void js_pushboolean(js_State *J, int v); +void js_pushnumber(js_State *J, double v); +void js_pushstring(js_State *J, const char *v); +void js_pushlstring(js_State *J, const char *v, int n); +void js_pushliteral(js_State *J, const char *v); + +void js_newobjectx(js_State *J); +void js_newobject(js_State *J); +void js_newarray(js_State *J); +void js_newboolean(js_State *J, int v); +void js_newnumber(js_State *J, double v); +void js_newstring(js_State *J, const char *v); +void js_newcfunction(js_State *J, js_CFunction fun, const char *name, int length); +void js_newcconstructor(js_State *J, js_CFunction fun, js_CFunction con, const char *name, int length); +void js_newuserdata(js_State *J, const char *tag, void *data, js_Finalize finalize); +void js_newuserdatax(js_State *J, const char *tag, void *data, js_HasProperty has, js_Put put, js_Delete del, js_Finalize finalize); +void js_newregexp(js_State *J, const char *pattern, int flags); + +void js_pushiterator(js_State *J, int idx, int own); +const char *js_nextiterator(js_State *J, int idx); + +int js_isdefined(js_State *J, int idx); +int js_isundefined(js_State *J, int idx); +int js_isnull(js_State *J, int idx); +int js_isboolean(js_State *J, int idx); +int js_isnumber(js_State *J, int idx); +int js_isstring(js_State *J, int idx); +int js_isprimitive(js_State *J, int idx); +int js_isobject(js_State *J, int idx); +int js_isarray(js_State *J, int idx); +int js_isregexp(js_State *J, int idx); +int js_iscoercible(js_State *J, int idx); +int js_iscallable(js_State *J, int idx); +int js_isuserdata(js_State *J, int idx, const char *tag); +int js_iserror(js_State *J, int idx); +int js_isnumberobject(js_State *J, int idx); +int js_isstringobject(js_State *J, int idx); + +int js_toboolean(js_State *J, int idx); +double js_tonumber(js_State *J, int idx); +const char *js_tostring(js_State *J, int idx); +void *js_touserdata(js_State *J, int idx, const char *tag); + +const char *js_trystring(js_State *J, int idx, const char *error); +double js_trynumber(js_State *J, int idx, double error); +int js_tryinteger(js_State *J, int idx, int error); +int js_tryboolean(js_State *J, int idx, int error); + +int js_tointeger(js_State *J, int idx); +int js_toint32(js_State *J, int idx); +unsigned int js_touint32(js_State *J, int idx); +short js_toint16(js_State *J, int idx); +unsigned short js_touint16(js_State *J, int idx); + +int js_gettop(js_State *J); +void js_pop(js_State *J, int n); +void js_rot(js_State *J, int n); +void js_copy(js_State *J, int idx); +void js_remove(js_State *J, int idx); +void js_insert(js_State *J, int idx); +void js_replace(js_State* J, int idx); + +void js_dup(js_State *J); +void js_dup2(js_State *J); +void js_rot2(js_State *J); +void js_rot3(js_State *J); +void js_rot4(js_State *J); +void js_rot2pop1(js_State *J); +void js_rot3pop2(js_State *J); + +void js_concat(js_State *J); +int js_compare(js_State *J, int *okay); +int js_equal(js_State *J); +int js_strictequal(js_State *J); +int js_instanceof(js_State *J); +const char *js_typeof(js_State *J, int idx); + +void js_repr(js_State *J, int idx); +const char *js_torepr(js_State *J, int idx); +const char *js_tryrepr(js_State *J, int idx, const char *error); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/programs/develop/kosjs/libmujs/include/opnames.h b/programs/develop/kosjs/libmujs/include/opnames.h new file mode 100755 index 0000000000..56e270d269 --- /dev/null +++ b/programs/develop/kosjs/libmujs/include/opnames.h @@ -0,0 +1,83 @@ +"pop", +"dup", +"dup2", +"rot2", +"rot3", +"rot4", +"integer", +"number", +"string", +"closure", +"newarray", +"newobject", +"newregexp", +"undef", +"null", +"true", +"false", +"this", +"current", +"getlocal", +"setlocal", +"dellocal", +"hasvar", +"getvar", +"setvar", +"delvar", +"in", +"initprop", +"initgetter", +"initsetter", +"getprop", +"getprop_s", +"setprop", +"setprop_s", +"delprop", +"delprop_s", +"iterator", +"nextiter", +"eval", +"call", +"new", +"typeof", +"pos", +"neg", +"bitnot", +"lognot", +"inc", +"dec", +"postinc", +"postdec", +"mul", +"div", +"mod", +"add", +"sub", +"shl", +"shr", +"ushr", +"lt", +"gt", +"le", +"ge", +"eq", +"ne", +"stricteq", +"strictne", +"jcase", +"bitand", +"bitxor", +"bitor", +"instanceof", +"throw", +"try", +"endtry", +"catch", +"endcatch", +"with", +"endwith", +"debugger", +"jump", +"jtrue", +"jfalse", +"return", diff --git a/programs/develop/kosjs/libmujs/include/regexp.h b/programs/develop/kosjs/libmujs/include/regexp.h new file mode 100755 index 0000000000..fe7cf71292 --- /dev/null +++ b/programs/develop/kosjs/libmujs/include/regexp.h @@ -0,0 +1,46 @@ +#ifndef regexp_h +#define regexp_h + +#define regcompx js_regcompx +#define regfreex js_regfreex +#define regcomp js_regcomp +#define regexec js_regexec +#define regfree js_regfree + +typedef struct Reprog Reprog; +typedef struct Resub Resub; + +Reprog *regcompx(void *(*alloc)(void *ctx, void *p, int n), void *ctx, + const char *pattern, int cflags, const char **errorp); +void regfreex(void *(*alloc)(void *ctx, void *p, int n), void *ctx, + Reprog *prog); + +Reprog *regcomp(const char *pattern, int cflags, const char **errorp); +int regexec(Reprog *prog, const char *string, Resub *sub, int eflags); +void regfree(Reprog *prog); + +enum { + /* regcomp flags */ + REG_ICASE = 1, + REG_NEWLINE = 2, + + /* regexec flags */ + REG_NOTBOL = 4, +}; + +/* If you redefine REG_MAXSUB, you must make sure both the calling + * code and the regexp.c compilation unit use the same value! + */ +#ifndef REG_MAXSUB +#define REG_MAXSUB 10 +#endif + +struct Resub { + int nsub; + struct { + const char *sp; + const char *ep; + } sub[REG_MAXSUB]; +}; + +#endif diff --git a/programs/develop/kosjs/libmujs/include/utf.h b/programs/develop/kosjs/libmujs/include/utf.h new file mode 100755 index 0000000000..36b299df9b --- /dev/null +++ b/programs/develop/kosjs/libmujs/include/utf.h @@ -0,0 +1,42 @@ +#ifndef js_utf_h +#define js_utf_h + +typedef unsigned short Rune; /* 16 bits */ + +#define chartorune jsU_chartorune +#define runetochar jsU_runetochar +#define runelen jsU_runelen +#define utflen jsU_utflen + +#define isalpharune jsU_isalpharune +#define islowerrune jsU_islowerrune +#define isspacerune jsU_isspacerune +#define istitlerune jsU_istitlerune +#define isupperrune jsU_isupperrune +#define tolowerrune jsU_tolowerrune +#define totitlerune jsU_totitlerune +#define toupperrune jsU_toupperrune + +enum +{ + UTFmax = 3, /* maximum bytes per rune */ + Runesync = 0x80, /* cannot represent part of a UTF sequence (<) */ + Runeself = 0x80, /* rune and UTF sequences are the same (<) */ + Runeerror = 0xFFFD, /* decoding error in UTF */ +}; + +int chartorune(Rune *rune, const char *str); +int runetochar(char *str, const Rune *rune); +int runelen(int c); +int utflen(const char *s); + +int isalpharune(Rune c); +int islowerrune(Rune c); +int isspacerune(Rune c); +int istitlerune(Rune c); +int isupperrune(Rune c); +Rune tolowerrune(Rune c); +Rune totitlerune(Rune c); +Rune toupperrune(Rune c); + +#endif diff --git a/programs/develop/kosjs/libmujs/lib/libmujs.a b/programs/develop/kosjs/libmujs/lib/libmujs.a new file mode 100755 index 0000000000..2f8430f3cc Binary files /dev/null and b/programs/develop/kosjs/libmujs/lib/libmujs.a differ