https://git.reactos.org/?p=reactos.git;a=commitdiff;h=3e2d6582b792e09696d1f4...
commit 3e2d6582b792e09696d1f4ff693e58c78129f32c Author: Amine Khaldi amine.khaldi@reactos.org AuthorDate: Sat Nov 2 18:38:06 2019 +0100 Commit: Amine Khaldi amine.khaldi@reactos.org CommitDate: Sat Nov 2 18:38:06 2019 +0100
[JSCRIPT] Sync with Wine Staging 4.18. CORE-16441 --- dll/win32/jscript/activex.c | 2 - dll/win32/jscript/array.c | 97 ++- dll/win32/jscript/cc_parser.tab.c | 406 ++++++------ dll/win32/jscript/cc_parser.tab.h | 15 +- dll/win32/jscript/cc_parser.y | 2 +- dll/win32/jscript/compile.c | 133 ++-- dll/win32/jscript/date.c | 63 +- dll/win32/jscript/decode.c | 4 +- dll/win32/jscript/dispex.c | 69 +- dll/win32/jscript/engine.c | 22 +- dll/win32/jscript/engine.h | 2 +- dll/win32/jscript/enumerator.c | 4 +- dll/win32/jscript/error.c | 12 +- dll/win32/jscript/function.c | 483 +++++++++----- dll/win32/jscript/global.c | 43 +- dll/win32/jscript/jscript.h | 16 +- dll/win32/jscript/json.c | 24 +- dll/win32/jscript/jsregexp.c | 4 +- dll/win32/jscript/jsstr.h | 2 +- dll/win32/jscript/jsutils.c | 34 +- dll/win32/jscript/lex.c | 247 +++---- dll/win32/jscript/math.c | 6 +- dll/win32/jscript/number.c | 2 +- dll/win32/jscript/object.c | 144 ++++- dll/win32/jscript/parser.h | 12 +- dll/win32/jscript/parser.tab.c | 1272 +++++++++++++++++++------------------ dll/win32/jscript/parser.tab.h | 17 +- dll/win32/jscript/parser.y | 23 +- dll/win32/jscript/regexp.c | 28 +- dll/win32/jscript/string.c | 77 ++- media/doc/README.WINE | 2 +- 31 files changed, 1858 insertions(+), 1409 deletions(-)
diff --git a/dll/win32/jscript/activex.c b/dll/win32/jscript/activex.c index c7d9a66911a..1c2631cc774 100644 --- a/dll/win32/jscript/activex.c +++ b/dll/win32/jscript/activex.c @@ -16,8 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
-#include "config.h" -#include "wine/port.h"
#include "jscript.h" #include "objsafe.h" diff --git a/dll/win32/jscript/array.c b/dll/win32/jscript/array.c index 2dbb593bd68..fbd72e84be5 100644 --- a/dll/win32/jscript/array.c +++ b/dll/win32/jscript/array.c @@ -16,8 +16,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
-#include "config.h" -#include "wine/port.h" +#ifdef __REACTOS__ +#include <wine/config.h> +#include <wine/port.h> +#endif
#include <math.h> #include <assert.h> @@ -49,6 +51,7 @@ static const WCHAR toStringW[] = {'t','o','S','t','r','i','n','g',0}; static const WCHAR toLocaleStringW[] = {'t','o','L','o','c','a','l','e','S','t','r','i','n','g',0}; static const WCHAR unshiftW[] = {'u','n','s','h','i','f','t',0}; static const WCHAR indexOfW[] = {'i','n','d','e','x','O','f',0}; +static const WCHAR mapW[] = {'m','a','p',0};
static const WCHAR default_separatorW[] = {',',0};
@@ -355,7 +358,7 @@ static HRESULT Array_join(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigne
jsstr_release(sep_str); }else { - hres = array_join(ctx, jsthis, length, default_separatorW, strlenW(default_separatorW), r); + hres = array_join(ctx, jsthis, length, default_separatorW, lstrlenW(default_separatorW), r); }
return hres; @@ -941,7 +944,7 @@ static HRESULT Array_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un return throw_type_error(ctx, JS_E_ARRAY_EXPECTED, NULL);
return array_join(ctx, &array->dispex, array->length, default_separatorW, - strlenW(default_separatorW), r); + lstrlenW(default_separatorW), r); }
static HRESULT Array_toLocaleString(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigned argc, jsval_t *argv, @@ -961,16 +964,21 @@ static HRESULT Array_forEach(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsi
TRACE("\n");
- /* FIXME: Check IsCallable */ - if(argc != 1 || !is_object_instance(argv[0])) { - FIXME("Unsupported arguments\n"); - return E_NOTIMPL; - } - hres = get_length(ctx, vthis, &jsthis, &length); if(FAILED(hres)) return hres;
+ /* Fixme check IsCallable */ + if(!argc || !is_object_instance(argv[0]) || !get_object(argv[0])) { + FIXME("Invalid arg %s\n", debugstr_jsval(argc ? argv[0] : jsval_undefined())); + return E_INVALIDARG; + } + + if(argc > 1 && !is_undefined(argv[1])) { + FIXME("Unsupported context this %s\n", debugstr_jsval(argv[1])); + return E_NOTIMPL; + } + for(i = 0; i < length; i++) { hres = jsdisp_get_idx(jsthis, i, &value); if(hres == DISP_E_UNKNOWNNAME) @@ -1047,6 +1055,68 @@ static HRESULT Array_indexOf(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsi return S_OK; }
+static HRESULT Array_map(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) +{ + IDispatch *context_this = NULL, *callback; + jsval_t callback_args[3], mapped_value; + jsdisp_t *jsthis, *array; + DWORD length, k; + HRESULT hres; + + TRACE("\n"); + + hres = get_length(ctx, vthis, &jsthis, &length); + if(FAILED(hres)) { + FIXME("Could not get length\n"); + return hres; + } + + /* Fixme check IsCallable */ + if(!argc || !is_object_instance(argv[0]) || !get_object(argv[0])) { + FIXME("Invalid arg %s\n", debugstr_jsval(argc ? argv[0] : jsval_undefined())); + return E_INVALIDARG; + } + callback = get_object(argv[0]); + + if(argc > 1) { + if(is_object_instance(argv[1]) && get_object(argv[1])) { + context_this = get_object(argv[1]); + }else if(!is_undefined(argv[1])) { + FIXME("Unsupported context this %s\n", debugstr_jsval(argv[1])); + return E_NOTIMPL; + } + } + + hres = create_array(ctx, length, &array); + if(FAILED(hres)) + return hres; + + for(k = 0; k < length; k++) { + hres = jsdisp_get_idx(jsthis, k, &callback_args[0]); + if(hres == DISP_E_UNKNOWNNAME) + continue; + if(FAILED(hres)) + break; + + callback_args[1] = jsval_number(k); + callback_args[2] = jsval_obj(jsthis); + hres = disp_call_value(ctx, callback, context_this, DISPATCH_METHOD, 3, callback_args, &mapped_value); + jsval_release(callback_args[0]); + if(FAILED(hres)) + break; + + hres = jsdisp_propput_idx(array, k, mapped_value); + if(FAILED(hres)) + break; + } + + if(SUCCEEDED(hres) && r) + *r = jsval_obj(array); + else + jsdisp_release(array); + return hres; +} + /* ECMA-262 3rd Edition 15.4.4.13 */ static HRESULT Array_unshift(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) @@ -1114,7 +1184,7 @@ static HRESULT Array_get_value(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t *r) TRACE("\n");
return array_join(ctx, &array->dispex, array->length, default_separatorW, - strlenW(default_separatorW), r); + lstrlenW(default_separatorW), r); }
static void Array_destructor(jsdisp_t *dispex) @@ -1128,10 +1198,10 @@ static void Array_on_put(jsdisp_t *dispex, const WCHAR *name) const WCHAR *ptr = name; DWORD id = 0;
- if(!isdigitW(*ptr)) + if(!iswdigit(*ptr)) return;
- while(*ptr && isdigitW(*ptr)) { + while(*ptr && iswdigit(*ptr)) { id = id*10 + (*ptr-'0'); ptr++; } @@ -1149,6 +1219,7 @@ static const builtin_prop_t Array_props[] = { {indexOfW, Array_indexOf, PROPF_METHOD|PROPF_ES5|1}, {joinW, Array_join, PROPF_METHOD|1}, {lengthW, NULL,0, Array_get_length, Array_set_length}, + {mapW, Array_map, PROPF_METHOD|PROPF_ES5|1}, {popW, Array_pop, PROPF_METHOD}, {pushW, Array_push, PROPF_METHOD|1}, {reverseW, Array_reverse, PROPF_METHOD}, diff --git a/dll/win32/jscript/cc_parser.tab.c b/dll/win32/jscript/cc_parser.tab.c index 2e46c119532..beafd15e5c2 100644 --- a/dll/win32/jscript/cc_parser.tab.c +++ b/dll/win32/jscript/cc_parser.tab.c @@ -1,8 +1,9 @@ -/* A Bison parser, made by GNU Bison 3.0. */ +/* A Bison parser, made by GNU Bison 3.4.1. */
/* Bison implementation for Yacc-like parsers in C
- Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. + Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2019 Free Software Foundation, + Inc.
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -40,11 +41,14 @@ define necessary library symbols; they are noted "INFRINGES ON USER NAME SPACE" below. */
+/* Undocumented macros, especially those whose name start with YY_, + are private implementation details. Do not rely on them. */ + /* Identify Bison output. */ #define YYBISON 1
/* Bison version. */ -#define YYBISON_VERSION "3.0" +#define YYBISON_VERSION "3.4.1"
/* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" @@ -67,8 +71,8 @@ #define yynerrs cc_parser_nerrs
-/* Copy the first part of user declarations. */ -#line 19 "cc_parser.y" /* yacc.c:339 */ +/* First part of user prologue. */ +#line 19 "cc_parser.y"
#include "jscript.h" @@ -80,13 +84,17 @@ WINE_DEFAULT_DEBUG_CHANNEL(jscript);
-#line 84 "cc_parser.tab.c" /* yacc.c:339 */ +#line 88 "cc_parser.tab.c"
-# ifndef YY_NULL -# if defined __cplusplus && 201103L <= __cplusplus -# define YY_NULL nullptr +# ifndef YY_NULLPTR +# if defined __cplusplus +# if 201103L <= __cplusplus +# define YY_NULLPTR nullptr +# else +# define YY_NULLPTR 0 +# endif # else -# define YY_NULL 0 +# define YY_NULLPTR ((void*)0) # endif # endif
@@ -98,8 +106,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(jscript); # define YYERROR_VERBOSE 0 #endif
-/* In a future release of Bison, this section will be replaced - by #include "cc_parser.tab.h". */ +/* Use api.header.include to #include this header + instead of duplicating it here. */ #ifndef YY_CC_PARSER_E_REACTOSSYNC_GCC_DLL_WIN32_JSCRIPT_CC_PARSER_TAB_H_INCLUDED # define YY_CC_PARSER_E_REACTOSSYNC_GCC_DLL_WIN32_JSCRIPT_CC_PARSER_TAB_H_INCLUDED /* Debug traces. */ @@ -132,15 +140,16 @@ extern int cc_parser_debug;
/* Value type. */ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -typedef union YYSTYPE YYSTYPE; union YYSTYPE { -#line 36 "cc_parser.y" /* yacc.c:355 */ +#line 36 "cc_parser.y"
ccval_t ccval;
-#line 143 "cc_parser.tab.c" /* yacc.c:355 */ +#line 150 "cc_parser.tab.c" + }; +typedef union YYSTYPE YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 # define YYSTYPE_IS_DECLARED 1 #endif @@ -151,8 +160,8 @@ int cc_parser_parse (parser_ctx_t *ctx);
#endif /* !YY_CC_PARSER_E_REACTOSSYNC_GCC_DLL_WIN32_JSCRIPT_CC_PARSER_TAB_H_INCLUDED */
-/* Copy the second part of user declarations. */ -#line 47 "cc_parser.y" /* yacc.c:358 */ +/* Second part of user prologue. */ +#line 47 "cc_parser.y"
static int cc_parser_error(parser_ctx_t *ctx, const char *str) @@ -246,7 +255,8 @@ static int cc_parser_lex(void *lval, parser_ctx_t *ctx) }
-#line 250 "cc_parser.tab.c" /* yacc.c:358 */ +#line 259 "cc_parser.tab.c" +
#ifdef short # undef short @@ -267,13 +277,13 @@ typedef signed char yytype_int8; #ifdef YYTYPE_UINT16 typedef YYTYPE_UINT16 yytype_uint16; #else -typedef unsigned short int yytype_uint16; +typedef unsigned short yytype_uint16; #endif
#ifdef YYTYPE_INT16 typedef YYTYPE_INT16 yytype_int16; #else -typedef short int yytype_int16; +typedef short yytype_int16; #endif
#ifndef YYSIZE_T @@ -285,7 +295,7 @@ typedef short int yytype_int16; # include <stddef.h> /* INFRINGES ON USER NAME SPACE */ # define YYSIZE_T size_t # else -# define YYSIZE_T unsigned int +# define YYSIZE_T unsigned # endif #endif
@@ -303,14 +313,24 @@ typedef short int yytype_int16; # endif #endif
-#ifndef __attribute__ -/* This feature is available in gcc versions 2.5 and later. */ -# if (! defined __GNUC__ || __GNUC__ < 2 \ - || (__GNUC__ == 2 && __GNUC_MINOR__ < 5)) -# define __attribute__(Spec) /* empty */ +#ifndef YY_ATTRIBUTE +# if (defined __GNUC__ \ + && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \ + || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C +# define YY_ATTRIBUTE(Spec) __attribute__(Spec) +# else +# define YY_ATTRIBUTE(Spec) /* empty */ # endif #endif
+#ifndef YY_ATTRIBUTE_PURE +# define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__)) +#endif + +#ifndef YY_ATTRIBUTE_UNUSED +# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__)) +#endif + /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ # define YYUSE(E) ((void) (E)) @@ -318,7 +338,7 @@ typedef short int yytype_int16; # define YYUSE(E) /* empty */ #endif
-#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ +#if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ /* Suppress an incorrect diagnostic about yylval being uninitialized. */ # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ _Pragma ("GCC diagnostic push") \ @@ -338,6 +358,8 @@ typedef short int yytype_int16; #endif
+#define YY_ASSERT(E) ((void) (0 && (E))) + #if ! defined yyoverflow || YYERROR_VERBOSE
/* The parser invokes alloca or malloc; define the necessary symbols. */ @@ -480,16 +502,16 @@ union yyalloc /* YYNSTATES -- Number of states. */ #define YYNSTATES 69
-/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned - by yylex, with out-of-bounds checking. */ #define YYUNDEFTOK 2 #define YYMAXUTOK 269
+/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM + as returned by yylex, with out-of-bounds checking. */ #define YYTRANSLATE(YYX) \ - ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + ((unsigned) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM - as returned by yylex, without out-of-bounds checking. */ + as returned by yylex. */ static const yytype_uint8 yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -545,7 +567,7 @@ static const char *const yytname[] = "CCBitwiseORExpression", "CCBitwiseXORExpression", "CCBitwiseANDExpression", "CCEqualityExpression", "CCRelationalExpression", "CCShiftExpression", "CCAdditiveExpression", - "CCMultiplicativeExpression", YY_NULL + "CCMultiplicativeExpression", YY_NULLPTR }; #endif
@@ -678,22 +700,22 @@ static const yytype_uint8 yyr2[] =
#define YYRECOVERING() (!!yyerrstatus)
-#define YYBACKUP(Token, Value) \ -do \ - if (yychar == YYEMPTY) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - YYPOPSTACK (yylen); \ - yystate = *yyssp; \ - goto yybackup; \ - } \ - else \ - { \ - yyerror (ctx, YY_("syntax error: cannot back up")); \ - YYERROR; \ - } \ -while (0) +#define YYBACKUP(Token, Value) \ + do \ + if (yychar == YYEMPTY) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + YYPOPSTACK (yylen); \ + yystate = *yyssp; \ + goto yybackup; \ + } \ + else \ + { \ + yyerror (ctx, YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ + while (0)
/* Error token number */ #define YYTERROR 1 @@ -733,38 +755,38 @@ do { \ } while (0)
-/*----------------------------------------. -| Print this symbol's value on YYOUTPUT. | -`----------------------------------------*/ +/*-----------------------------------. +| Print this symbol's value on YYO. | +`-----------------------------------*/
static void -yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, parser_ctx_t *ctx) +yy_symbol_value_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep, parser_ctx_t *ctx) { - FILE *yyo = yyoutput; - YYUSE (yyo); + FILE *yyoutput = yyo; + YYUSE (yyoutput); YYUSE (ctx); if (!yyvaluep) return; # ifdef YYPRINT if (yytype < YYNTOKENS) - YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); + YYPRINT (yyo, yytoknum[yytype], *yyvaluep); # endif YYUSE (yytype); }
-/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ +/*---------------------------. +| Print this symbol on YYO. | +`---------------------------*/
static void -yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, parser_ctx_t *ctx) +yy_symbol_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep, parser_ctx_t *ctx) { - YYFPRINTF (yyoutput, "%s %s (", + YYFPRINTF (yyo, "%s %s (", yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]);
- yy_symbol_value_print (yyoutput, yytype, yyvaluep, ctx); - YYFPRINTF (yyoutput, ")"); + yy_symbol_value_print (yyo, yytype, yyvaluep, ctx); + YYFPRINTF (yyo, ")"); }
/*------------------------------------------------------------------. @@ -798,7 +820,7 @@ do { \ static void yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule, parser_ctx_t *ctx) { - unsigned long int yylno = yyrline[yyrule]; + unsigned long yylno = yyrline[yyrule]; int yynrhs = yyr2[yyrule]; int yyi; YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", @@ -809,7 +831,7 @@ yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule, parser_ctx_t * YYFPRINTF (stderr, " $%d = ", yyi + 1); yy_symbol_print (stderr, yystos[yyssp[yyi + 1 - yynrhs]], - &(yyvsp[(yyi + 1) - (yynrhs)]) + &yyvsp[(yyi + 1) - (yynrhs)] , ctx); YYFPRINTF (stderr, "\n"); } @@ -913,7 +935,10 @@ yytnamerr (char *yyres, const char *yystr) case '\': if (*++yyp != '\') goto do_not_strip_quotes; - /* Fall through. */ + else + goto append; + + append: default: if (yyres) yyres[yyn] = *yyp; @@ -931,7 +956,7 @@ yytnamerr (char *yyres, const char *yystr) if (! yyres) return yystrlen (yystr);
- return yystpcpy (yyres, yystr) - yyres; + return (YYSIZE_T) (yystpcpy (yyres, yystr) - yyres); } # endif
@@ -947,11 +972,11 @@ static int yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, yytype_int16 *yyssp, int yytoken) { - YYSIZE_T yysize0 = yytnamerr (YY_NULL, yytname[yytoken]); + YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]); YYSIZE_T yysize = yysize0; enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; /* Internationalized format string. */ - const char *yyformat = YY_NULL; + const char *yyformat = YY_NULLPTR; /* Arguments of yyformat. */ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; /* Number of reported tokens (one for the "unexpected", one per @@ -1008,11 +1033,11 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, } yyarg[yycount++] = yytname[yyx]; { - YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULL, yytname[yyx]); - if (! (yysize <= yysize1 - && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); + if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM) + yysize = yysize1; + else return 2; - yysize = yysize1; } } } @@ -1024,6 +1049,7 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, case N: \ yyformat = S; \ break + default: /* Avoid compiler warnings. */ YYCASE_(0, YY_("syntax error")); YYCASE_(1, YY_("syntax error, unexpected %s")); YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); @@ -1035,9 +1061,10 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
{ YYSIZE_T yysize1 = yysize + yystrlen (yyformat); - if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM) + yysize = yysize1; + else return 2; - yysize = yysize1; }
if (*yymsg_alloc < yysize) @@ -1168,23 +1195,33 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); yychar = YYEMPTY; /* Cause a token to be read. */ goto yysetstate;
+ /*------------------------------------------------------------. -| yynewstate -- Push a new state, which is found in yystate. | +| yynewstate -- push a new state, which is found in yystate. | `------------------------------------------------------------*/ - yynewstate: +yynewstate: /* In all cases, when you get here, the value and location stacks have just been pushed. So pushing a state here evens the stacks. */ yyssp++;
- yysetstate: - *yyssp = yystate; + +/*--------------------------------------------------------------------. +| yynewstate -- set current state (the top of the stack) to yystate. | +`--------------------------------------------------------------------*/ +yysetstate: + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + YY_ASSERT (0 <= yystate && yystate < YYNSTATES); + *yyssp = (yytype_int16) yystate;
if (yyss + yystacksize - 1 <= yyssp) +#if !defined yyoverflow && !defined YYSTACK_RELOCATE + goto yyexhaustedlab; +#else { /* Get the current used size of the three stacks, in elements. */ - YYSIZE_T yysize = yyssp - yyss + 1; + YYSIZE_T yysize = (YYSIZE_T) (yyssp - yyss + 1);
-#ifdef yyoverflow +# if defined yyoverflow { /* Give user a chance to reallocate the stack. Use copies of these so that the &'s don't force the real ones into @@ -1200,14 +1237,10 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); &yyss1, yysize * sizeof (*yyssp), &yyvs1, yysize * sizeof (*yyvsp), &yystacksize); - yyss = yyss1; yyvs = yyvs1; } -#else /* no yyoverflow */ -# ifndef YYSTACK_RELOCATE - goto yyexhaustedlab; -# else +# else /* defined YYSTACK_RELOCATE */ /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) goto yyexhaustedlab; @@ -1223,35 +1256,33 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); goto yyexhaustedlab; YYSTACK_RELOCATE (yyss_alloc, yyss); YYSTACK_RELOCATE (yyvs_alloc, yyvs); -# undef YYSTACK_RELOCATE +# undef YYSTACK_RELOCATE if (yyss1 != yyssa) YYSTACK_FREE (yyss1); } # endif -#endif /* no yyoverflow */
yyssp = yyss + yysize - 1; yyvsp = yyvs + yysize - 1;
YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long int) yystacksize)); + (unsigned long) yystacksize));
if (yyss + yystacksize - 1 <= yyssp) YYABORT; } - - YYDPRINTF ((stderr, "Entering state %d\n", yystate)); +#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */
if (yystate == YYFINAL) YYACCEPT;
goto yybackup;
+ /*-----------. | yybackup. | `-----------*/ yybackup: - /* Do appropriate processing given the current state. Read a lookahead token if we need one and don't already have one. */
@@ -1309,7 +1340,6 @@ yybackup: YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN *++yyvsp = yylval; YY_IGNORE_MAYBE_UNINITIALIZED_END - goto yynewstate;
@@ -1324,7 +1354,7 @@ yydefault:
/*-----------------------------. -| yyreduce -- Do a reduction. | +| yyreduce -- do a reduction. | `-----------------------------*/ yyreduce: /* yyn is the number of a rule to reduce with. */ @@ -1344,236 +1374,237 @@ yyreduce: YY_REDUCE_PRINT (yyn); switch (yyn) { - case 2: -#line 146 "cc_parser.y" /* yacc.c:1646 */ + case 2: +#line 146 "cc_parser.y" { ctx->ccval = (yyvsp[0].ccval); YYACCEPT; } -#line 1351 "cc_parser.tab.c" /* yacc.c:1646 */ +#line 1381 "cc_parser.tab.c" break;
case 3: -#line 149 "cc_parser.y" /* yacc.c:1646 */ +#line 149 "cc_parser.y" { (yyval.ccval) = (yyvsp[0].ccval); } -#line 1357 "cc_parser.tab.c" /* yacc.c:1646 */ +#line 1387 "cc_parser.tab.c" break;
case 4: -#line 150 "cc_parser.y" /* yacc.c:1646 */ +#line 150 "cc_parser.y" { (yyval.ccval) = (yyvsp[-1].ccval); } -#line 1363 "cc_parser.tab.c" /* yacc.c:1646 */ +#line 1393 "cc_parser.tab.c" break;
case 5: -#line 151 "cc_parser.y" /* yacc.c:1646 */ +#line 151 "cc_parser.y" { (yyval.ccval) = ccval_bool(!get_ccbool((yyvsp[0].ccval))); } -#line 1369 "cc_parser.tab.c" /* yacc.c:1646 */ +#line 1399 "cc_parser.tab.c" break;
case 6: -#line 152 "cc_parser.y" /* yacc.c:1646 */ +#line 152 "cc_parser.y" { FIXME("'~' expression not implemented\n"); ctx->hres = E_NOTIMPL; YYABORT; } -#line 1375 "cc_parser.tab.c" /* yacc.c:1646 */ +#line 1405 "cc_parser.tab.c" break;
case 7: -#line 153 "cc_parser.y" /* yacc.c:1646 */ +#line 153 "cc_parser.y" { FIXME("'+' expression not implemented\n"); ctx->hres = E_NOTIMPL; YYABORT; } -#line 1381 "cc_parser.tab.c" /* yacc.c:1646 */ +#line 1411 "cc_parser.tab.c" break;
case 8: -#line 154 "cc_parser.y" /* yacc.c:1646 */ +#line 154 "cc_parser.y" { FIXME("'-' expression not implemented\n"); ctx->hres = E_NOTIMPL; YYABORT; } -#line 1387 "cc_parser.tab.c" /* yacc.c:1646 */ +#line 1417 "cc_parser.tab.c" break;
case 9: -#line 157 "cc_parser.y" /* yacc.c:1646 */ +#line 157 "cc_parser.y" { (yyval.ccval) = (yyvsp[0].ccval); } -#line 1393 "cc_parser.tab.c" /* yacc.c:1646 */ +#line 1423 "cc_parser.tab.c" break;
case 10: -#line 159 "cc_parser.y" /* yacc.c:1646 */ +#line 159 "cc_parser.y" { FIXME("'||' expression not implemented\n"); ctx->hres = E_NOTIMPL; YYABORT; } -#line 1399 "cc_parser.tab.c" /* yacc.c:1646 */ +#line 1429 "cc_parser.tab.c" break;
case 11: -#line 162 "cc_parser.y" /* yacc.c:1646 */ +#line 162 "cc_parser.y" { (yyval.ccval) = (yyvsp[0].ccval); } -#line 1405 "cc_parser.tab.c" /* yacc.c:1646 */ +#line 1435 "cc_parser.tab.c" break;
case 12: -#line 164 "cc_parser.y" /* yacc.c:1646 */ +#line 164 "cc_parser.y" { FIXME("'&&' expression not implemented\n"); ctx->hres = E_NOTIMPL; YYABORT; } -#line 1411 "cc_parser.tab.c" /* yacc.c:1646 */ +#line 1441 "cc_parser.tab.c" break;
case 13: -#line 167 "cc_parser.y" /* yacc.c:1646 */ +#line 167 "cc_parser.y" { (yyval.ccval) = (yyvsp[0].ccval); } -#line 1417 "cc_parser.tab.c" /* yacc.c:1646 */ +#line 1447 "cc_parser.tab.c" break;
case 14: -#line 169 "cc_parser.y" /* yacc.c:1646 */ +#line 169 "cc_parser.y" { FIXME("'|' expression not implemented\n"); ctx->hres = E_NOTIMPL; YYABORT; } -#line 1423 "cc_parser.tab.c" /* yacc.c:1646 */ +#line 1453 "cc_parser.tab.c" break;
case 15: -#line 172 "cc_parser.y" /* yacc.c:1646 */ +#line 172 "cc_parser.y" { (yyval.ccval) = (yyvsp[0].ccval); } -#line 1429 "cc_parser.tab.c" /* yacc.c:1646 */ +#line 1459 "cc_parser.tab.c" break;
case 16: -#line 174 "cc_parser.y" /* yacc.c:1646 */ +#line 174 "cc_parser.y" { FIXME("'^' expression not implemented\n"); ctx->hres = E_NOTIMPL; YYABORT; } -#line 1435 "cc_parser.tab.c" /* yacc.c:1646 */ +#line 1465 "cc_parser.tab.c" break;
case 17: -#line 177 "cc_parser.y" /* yacc.c:1646 */ +#line 177 "cc_parser.y" { (yyval.ccval) = (yyvsp[0].ccval); } -#line 1441 "cc_parser.tab.c" /* yacc.c:1646 */ +#line 1471 "cc_parser.tab.c" break;
case 18: -#line 179 "cc_parser.y" /* yacc.c:1646 */ +#line 179 "cc_parser.y" { FIXME("'&' expression not implemented\n"); ctx->hres = E_NOTIMPL; YYABORT; } -#line 1447 "cc_parser.tab.c" /* yacc.c:1646 */ +#line 1477 "cc_parser.tab.c" break;
case 19: -#line 182 "cc_parser.y" /* yacc.c:1646 */ +#line 182 "cc_parser.y" { (yyval.ccval) = (yyvsp[0].ccval); } -#line 1453 "cc_parser.tab.c" /* yacc.c:1646 */ +#line 1483 "cc_parser.tab.c" break;
case 20: -#line 184 "cc_parser.y" /* yacc.c:1646 */ +#line 184 "cc_parser.y" { (yyval.ccval) = ccval_bool(get_ccnum((yyvsp[-2].ccval)) == get_ccnum((yyvsp[0].ccval))); } -#line 1459 "cc_parser.tab.c" /* yacc.c:1646 */ +#line 1489 "cc_parser.tab.c" break;
case 21: -#line 186 "cc_parser.y" /* yacc.c:1646 */ +#line 186 "cc_parser.y" { (yyval.ccval) = ccval_bool(get_ccnum((yyvsp[-2].ccval)) != get_ccnum((yyvsp[0].ccval))); } -#line 1465 "cc_parser.tab.c" /* yacc.c:1646 */ +#line 1495 "cc_parser.tab.c" break;
case 22: -#line 188 "cc_parser.y" /* yacc.c:1646 */ +#line 188 "cc_parser.y" { FIXME("'===' expression not implemented\n"); ctx->hres = E_NOTIMPL; YYABORT; } -#line 1471 "cc_parser.tab.c" /* yacc.c:1646 */ +#line 1501 "cc_parser.tab.c" break;
case 23: -#line 190 "cc_parser.y" /* yacc.c:1646 */ +#line 190 "cc_parser.y" { FIXME("'!==' expression not implemented\n"); ctx->hres = E_NOTIMPL; YYABORT; } -#line 1477 "cc_parser.tab.c" /* yacc.c:1646 */ +#line 1507 "cc_parser.tab.c" break;
case 24: -#line 193 "cc_parser.y" /* yacc.c:1646 */ +#line 193 "cc_parser.y" { (yyval.ccval) = (yyvsp[0].ccval); } -#line 1483 "cc_parser.tab.c" /* yacc.c:1646 */ +#line 1513 "cc_parser.tab.c" break;
case 25: -#line 195 "cc_parser.y" /* yacc.c:1646 */ +#line 195 "cc_parser.y" { (yyval.ccval) = ccval_bool(get_ccnum((yyvsp[-2].ccval)) < get_ccnum((yyvsp[0].ccval))); } -#line 1489 "cc_parser.tab.c" /* yacc.c:1646 */ +#line 1519 "cc_parser.tab.c" break;
case 26: -#line 197 "cc_parser.y" /* yacc.c:1646 */ +#line 197 "cc_parser.y" { (yyval.ccval) = ccval_bool(get_ccnum((yyvsp[-2].ccval)) <= get_ccnum((yyvsp[0].ccval))); } -#line 1495 "cc_parser.tab.c" /* yacc.c:1646 */ +#line 1525 "cc_parser.tab.c" break;
case 27: -#line 199 "cc_parser.y" /* yacc.c:1646 */ +#line 199 "cc_parser.y" { (yyval.ccval) = ccval_bool(get_ccnum((yyvsp[-2].ccval)) > get_ccnum((yyvsp[0].ccval))); } -#line 1501 "cc_parser.tab.c" /* yacc.c:1646 */ +#line 1531 "cc_parser.tab.c" break;
case 28: -#line 201 "cc_parser.y" /* yacc.c:1646 */ +#line 201 "cc_parser.y" { (yyval.ccval) = ccval_bool(get_ccnum((yyvsp[-2].ccval)) >= get_ccnum((yyvsp[0].ccval))); } -#line 1507 "cc_parser.tab.c" /* yacc.c:1646 */ +#line 1537 "cc_parser.tab.c" break;
case 29: -#line 204 "cc_parser.y" /* yacc.c:1646 */ +#line 204 "cc_parser.y" { (yyval.ccval) = (yyvsp[0].ccval); } -#line 1513 "cc_parser.tab.c" /* yacc.c:1646 */ +#line 1543 "cc_parser.tab.c" break;
case 30: -#line 206 "cc_parser.y" /* yacc.c:1646 */ +#line 206 "cc_parser.y" { FIXME("'<<' expression not implemented\n"); ctx->hres = E_NOTIMPL; YYABORT; } -#line 1519 "cc_parser.tab.c" /* yacc.c:1646 */ +#line 1549 "cc_parser.tab.c" break;
case 31: -#line 208 "cc_parser.y" /* yacc.c:1646 */ +#line 208 "cc_parser.y" { FIXME("'>>' expression not implemented\n"); ctx->hres = E_NOTIMPL; YYABORT; } -#line 1525 "cc_parser.tab.c" /* yacc.c:1646 */ +#line 1555 "cc_parser.tab.c" break;
case 32: -#line 210 "cc_parser.y" /* yacc.c:1646 */ +#line 210 "cc_parser.y" { FIXME("'>>>' expression not implemented\n"); ctx->hres = E_NOTIMPL; YYABORT; } -#line 1531 "cc_parser.tab.c" /* yacc.c:1646 */ +#line 1561 "cc_parser.tab.c" break;
case 33: -#line 213 "cc_parser.y" /* yacc.c:1646 */ +#line 213 "cc_parser.y" { (yyval.ccval) = (yyvsp[0].ccval); } -#line 1537 "cc_parser.tab.c" /* yacc.c:1646 */ +#line 1567 "cc_parser.tab.c" break;
case 34: -#line 215 "cc_parser.y" /* yacc.c:1646 */ +#line 215 "cc_parser.y" { (yyval.ccval) = ccval_num(get_ccnum((yyvsp[-2].ccval)) + get_ccnum((yyvsp[0].ccval))); } -#line 1543 "cc_parser.tab.c" /* yacc.c:1646 */ +#line 1573 "cc_parser.tab.c" break;
case 35: -#line 217 "cc_parser.y" /* yacc.c:1646 */ +#line 217 "cc_parser.y" { (yyval.ccval) = ccval_num(get_ccnum((yyvsp[-2].ccval)) - get_ccnum((yyvsp[0].ccval))); } -#line 1549 "cc_parser.tab.c" /* yacc.c:1646 */ +#line 1579 "cc_parser.tab.c" break;
case 36: -#line 220 "cc_parser.y" /* yacc.c:1646 */ +#line 220 "cc_parser.y" { (yyval.ccval) = (yyvsp[0].ccval); } -#line 1555 "cc_parser.tab.c" /* yacc.c:1646 */ +#line 1585 "cc_parser.tab.c" break;
case 37: -#line 222 "cc_parser.y" /* yacc.c:1646 */ +#line 222 "cc_parser.y" { (yyval.ccval) = ccval_num(get_ccnum((yyvsp[-2].ccval)) * get_ccnum((yyvsp[0].ccval))); } -#line 1561 "cc_parser.tab.c" /* yacc.c:1646 */ +#line 1591 "cc_parser.tab.c" break;
case 38: -#line 224 "cc_parser.y" /* yacc.c:1646 */ +#line 224 "cc_parser.y" { (yyval.ccval) = ccval_num(get_ccnum((yyvsp[-2].ccval)) / get_ccnum((yyvsp[0].ccval))); } -#line 1567 "cc_parser.tab.c" /* yacc.c:1646 */ +#line 1597 "cc_parser.tab.c" break;
case 39: -#line 226 "cc_parser.y" /* yacc.c:1646 */ +#line 226 "cc_parser.y" { FIXME("'%%' expression not implemented\n"); ctx->hres = E_NOTIMPL; YYABORT; } -#line 1573 "cc_parser.tab.c" /* yacc.c:1646 */ +#line 1603 "cc_parser.tab.c" break;
-#line 1577 "cc_parser.tab.c" /* yacc.c:1646 */ +#line 1607 "cc_parser.tab.c" + default: break; } /* User semantic actions sometimes alter yychar, and that requires @@ -1598,14 +1629,13 @@ yyreduce: /* Now 'shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ - - yyn = yyr1[yyn]; - - yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; - if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) - yystate = yytable[yystate]; - else - yystate = yydefgoto[yyn - YYNTOKENS]; + { + const int yylhs = yyr1[yyn] - YYNTOKENS; + const int yyi = yypgoto[yylhs] + *yyssp; + yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp + ? yytable[yyi] + : yydefgoto[yylhs]); + }
goto yynewstate;
@@ -1688,12 +1718,10 @@ yyerrlab: | yyerrorlab -- error raised explicitly by YYERROR. | `---------------------------------------------------*/ yyerrorlab: - - /* Pacify compilers like GCC when the user code never invokes - YYERROR and the label yyerrorlab therefore never appears in user - code. */ - if (/*CONSTCOND*/ 0) - goto yyerrorlab; + /* Pacify compilers when the user code never invokes YYERROR and the + label yyerrorlab therefore never appears in user code. */ + if (0) + YYERROR;
/* Do not reclaim the symbols of the rule whose action triggered this YYERROR. */ @@ -1755,6 +1783,7 @@ yyacceptlab: yyresult = 0; goto yyreturn;
+ /*-----------------------------------. | yyabortlab -- YYABORT comes here. | `-----------------------------------*/ @@ -1762,6 +1791,7 @@ yyabortlab: yyresult = 1; goto yyreturn;
+ #if !defined yyoverflow || YYERROR_VERBOSE /*-------------------------------------------------. | yyexhaustedlab -- memory exhaustion comes here. | @@ -1772,6 +1802,10 @@ yyexhaustedlab: /* Fall through. */ #endif
+ +/*-----------------------------------------------------. +| yyreturn -- parsing is finished, return the result. | +`-----------------------------------------------------*/ yyreturn: if (yychar != YYEMPTY) { @@ -1801,7 +1835,7 @@ yyreturn: #endif return yyresult; } -#line 228 "cc_parser.y" /* yacc.c:1906 */ +#line 228 "cc_parser.y"
BOOL parse_cc_expr(parser_ctx_t *ctx) diff --git a/dll/win32/jscript/cc_parser.tab.h b/dll/win32/jscript/cc_parser.tab.h index 275e13edfa0..d09ec5e3e0a 100644 --- a/dll/win32/jscript/cc_parser.tab.h +++ b/dll/win32/jscript/cc_parser.tab.h @@ -1,8 +1,9 @@ -/* A Bison parser, made by GNU Bison 3.0. */ +/* A Bison parser, made by GNU Bison 3.4.1. */
/* Bison interface for Yacc-like parsers in C
- Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. + Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2019 Free Software Foundation, + Inc.
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -30,6 +31,9 @@ This special exception was added by the Free Software Foundation in version 2.2 of Bison. */
+/* Undocumented macros, especially those whose name start with YY_, + are private implementation details. Do not rely on them. */ + #ifndef YY_CC_PARSER_E_REACTOSSYNC_GCC_DLL_WIN32_JSCRIPT_CC_PARSER_TAB_H_INCLUDED # define YY_CC_PARSER_E_REACTOSSYNC_GCC_DLL_WIN32_JSCRIPT_CC_PARSER_TAB_H_INCLUDED /* Debug traces. */ @@ -62,15 +66,16 @@ extern int cc_parser_debug;
/* Value type. */ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -typedef union YYSTYPE YYSTYPE; union YYSTYPE { -#line 36 "cc_parser.y" /* yacc.c:1909 */ +#line 36 "cc_parser.y"
ccval_t ccval;
-#line 73 "cc_parser.tab.h" /* yacc.c:1909 */ +#line 76 "cc_parser.tab.h" + }; +typedef union YYSTYPE YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 # define YYSTYPE_IS_DECLARED 1 #endif diff --git a/dll/win32/jscript/cc_parser.y b/dll/win32/jscript/cc_parser.y index 18c1cb1c38e..4bc6260f194 100644 --- a/dll/win32/jscript/cc_parser.y +++ b/dll/win32/jscript/cc_parser.y @@ -30,7 +30,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(jscript);
%lex-param { parser_ctx_t *ctx } %parse-param { parser_ctx_t *ctx } -%pure-parser +%define api.pure %start CCExpr
%union { diff --git a/dll/win32/jscript/compile.c b/dll/win32/jscript/compile.c index 006386a4e99..db05d3c3600 100644 --- a/dll/win32/jscript/compile.c +++ b/dll/win32/jscript/compile.c @@ -48,7 +48,7 @@ typedef struct { int ref; } function_local_t;
-typedef struct { +typedef struct _compiler_ctx_t { parser_ctx_t *parser; bytecode_t *code;
@@ -130,7 +130,7 @@ static inline void *compiler_alloc(bytecode_t *code, size_t size) return heap_pool_alloc(&code->heap, size); }
-static jsstr_t *compiler_alloc_string_len(compiler_ctx_t *ctx, const WCHAR *str, unsigned len) +jsstr_t *compiler_alloc_string_len(compiler_ctx_t *ctx, const WCHAR *str, unsigned len) { jsstr_t *new_str;
@@ -160,7 +160,7 @@ static jsstr_t *compiler_alloc_string_len(compiler_ctx_t *ctx, const WCHAR *str,
static jsstr_t *compiler_alloc_string(compiler_ctx_t *ctx, const WCHAR *str) { - return compiler_alloc_string_len(ctx, str, strlenW(str)); + return compiler_alloc_string_len(ctx, str, lstrlenW(str)); }
static BOOL ensure_bstr_slot(compiler_ctx_t *ctx) @@ -245,20 +245,28 @@ static HRESULT push_instr_int(compiler_ctx_t *ctx, jsop_t op, LONG arg) return S_OK; }
-static HRESULT push_instr_str(compiler_ctx_t *ctx, jsop_t op, const WCHAR *arg) +static HRESULT push_instr_str(compiler_ctx_t *ctx, jsop_t op, jsstr_t *str) { unsigned instr; - jsstr_t *str;
- str = compiler_alloc_string(ctx, arg); - if(!str) + instr = push_instr(ctx, op); + if(!instr) return E_OUTOFMEMORY;
+ instr_ptr(ctx, instr)->u.arg->str = str; + return S_OK; +} + +static HRESULT push_instr_str_uint(compiler_ctx_t *ctx, jsop_t op, jsstr_t *str, unsigned arg2) +{ + unsigned instr; + instr = push_instr(ctx, op); if(!instr) return E_OUTOFMEMORY;
- instr_ptr(ctx, instr)->u.arg->str = str; + instr_ptr(ctx, instr)->u.arg[0].str = str; + instr_ptr(ctx, instr)->u.arg[1].uint = arg2; return S_OK; }
@@ -477,13 +485,18 @@ static HRESULT compile_memberid_expression(compiler_ctx_t *ctx, expression_t *ex } case EXPR_MEMBER: { member_expression_t *member_expr = (member_expression_t*)expr; + jsstr_t *jsstr;
hres = compile_expression(ctx, member_expr->expression, TRUE); if(FAILED(hres)) return hres;
/* FIXME: Potential optimization */ - hres = push_instr_str(ctx, OP_str, member_expr->identifier); + jsstr = compiler_alloc_string(ctx, member_expr->identifier); + if(!jsstr) + return E_OUTOFMEMORY; + + hres = push_instr_str(ctx, OP_str, jsstr); if(FAILED(hres)) return hres;
@@ -676,13 +689,18 @@ static HRESULT compile_delete_expression(compiler_ctx_t *ctx, unary_expression_t } case EXPR_MEMBER: { member_expression_t *member_expr = (member_expression_t*)expr->expression; + jsstr_t *jsstr;
hres = compile_expression(ctx, member_expr->expression, TRUE); if(FAILED(hres)) return hres;
/* FIXME: Potential optimization */ - hres = push_instr_str(ctx, OP_str, member_expr->identifier); + jsstr = compiler_alloc_string(ctx, member_expr->identifier); + if(!jsstr) + return E_OUTOFMEMORY; + + hres = push_instr_str(ctx, OP_str, jsstr); if(FAILED(hres)) return hres;
@@ -718,11 +736,6 @@ static HRESULT compile_assign_expression(compiler_ctx_t *ctx, binary_expression_ call_expression_t *call_expr = (call_expression_t*)expr->expression1; argument_t *arg;
- if(op != OP_LAST) { - FIXME("op %d not supported on parametrized assign expressions\n", op); - return E_NOTIMPL; - } - if(is_memberid_expr(call_expr->expression->type) && call_expr->argument_list) { hres = compile_memberid_expression(ctx, call_expr->expression, fdexNameEnsure); if(FAILED(hres)) @@ -734,6 +747,23 @@ static HRESULT compile_assign_expression(compiler_ctx_t *ctx, binary_expression_ return hres; arg_cnt++; } + + if(op != OP_LAST) { + unsigned instr; + + /* We need to call the functions twice: to get the value and to set it. + * JavaScript interpreted functions may to modify value on the stack, + * but assignment calls are allowed only on external functions, so we + * may reuse the stack here. */ + instr = push_instr(ctx, OP_call_member); + if(!instr) + return E_OUTOFMEMORY; + instr_ptr(ctx, instr)->u.arg[0].uint = arg_cnt; + instr_ptr(ctx, instr)->u.arg[1].lng = 1; + + if(!push_instr(ctx, OP_push_acc)) + return E_OUTOFMEMORY; + } }else { use_throw_path = TRUE; } @@ -741,6 +771,8 @@ static HRESULT compile_assign_expression(compiler_ctx_t *ctx, binary_expression_ hres = compile_memberid_expression(ctx, expr->expression1, fdexNameEnsure); if(FAILED(hres)) return hres; + if(op != OP_LAST && !push_instr(ctx, OP_refval)) + return E_OUTOFMEMORY; }else { use_throw_path = TRUE; } @@ -761,9 +793,6 @@ static HRESULT compile_assign_expression(compiler_ctx_t *ctx, binary_expression_ return push_instr_uint(ctx, OP_throw_ref, JS_E_ILLEGAL_ASSIGN); }
- if(op != OP_LAST && !push_instr(ctx, OP_refval)) - return E_OUTOFMEMORY; - hres = compile_expression(ctx, expr->expression2, TRUE); if(FAILED(hres)) return hres; @@ -811,48 +840,22 @@ static HRESULT compile_literal(compiler_ctx_t *ctx, literal_t *literal) case LT_NULL: return push_instr(ctx, OP_null) ? S_OK : E_OUTOFMEMORY; case LT_STRING: - return push_instr_str(ctx, OP_str, literal->u.wstr); - case LT_REGEXP: { - unsigned instr; - jsstr_t *str; - - str = compiler_alloc_string_len(ctx, literal->u.regexp.str, literal->u.regexp.str_len); - if(!str) - return E_OUTOFMEMORY; - - instr = push_instr(ctx, OP_regexp); - if(!instr) - return E_OUTOFMEMORY; - - instr_ptr(ctx, instr)->u.arg[0].str = str; - instr_ptr(ctx, instr)->u.arg[1].uint = literal->u.regexp.flags; - return S_OK; - } + return push_instr_str(ctx, OP_str, literal->u.str); + case LT_REGEXP: + return push_instr_str_uint(ctx, OP_regexp, literal->u.regexp.str, literal->u.regexp.flags); DEFAULT_UNREACHABLE; } return E_FAIL; }
-static HRESULT literal_as_bstr(compiler_ctx_t *ctx, literal_t *literal, BSTR *str) +static HRESULT literal_as_string(compiler_ctx_t *ctx, literal_t *literal, jsstr_t **str) { switch(literal->type) { case LT_STRING: - *str = compiler_alloc_bstr(ctx, literal->u.wstr); - break; - case LT_DOUBLE: { - jsstr_t *jsstr; - HRESULT hres; - - hres = double_to_string(literal->u.dval, &jsstr); - if(FAILED(hres)) - return hres; - - *str = compiler_alloc_bstr_len(ctx, NULL, jsstr_length(jsstr)); - if(*str) - jsstr_flush(jsstr, *str); - jsstr_release(jsstr); + *str = literal->u.str; break; - } + case LT_DOUBLE: + return double_to_string(literal->u.dval, str); DEFAULT_UNREACHABLE; }
@@ -889,14 +892,14 @@ static HRESULT compile_array_literal(compiler_ctx_t *ctx, array_literal_expressi static HRESULT compile_object_literal(compiler_ctx_t *ctx, property_value_expression_t *expr) { property_definition_t *iter; - BSTR name; + jsstr_t *name; HRESULT hres;
if(!push_instr(ctx, OP_new_obj)) return E_OUTOFMEMORY;
for(iter = expr->property_list; iter; iter = iter->next) { - hres = literal_as_bstr(ctx, iter->name, &name); + hres = literal_as_string(ctx, iter->name, &name); if(FAILED(hres)) return hres;
@@ -904,7 +907,7 @@ static HRESULT compile_object_literal(compiler_ctx_t *ctx, property_value_expres if(FAILED(hres)) return hres;
- hres = push_instr_bstr_uint(ctx, OP_obj_prop, name, iter->type); + hres = push_instr_str_uint(ctx, OP_obj_prop, name, iter->type); if(FAILED(hres)) return hres; } @@ -1427,7 +1430,7 @@ static HRESULT compile_continue_statement(compiler_ctx_t *ctx, branch_statement_ for(iter = ctx->stat_ctx; iter; iter = iter->next) { if(iter->continue_label) pop_ctx = iter; - if(iter->labelled_stat && !strcmpW(iter->labelled_stat->identifier, stat->identifier)) + if(iter->labelled_stat && !wcscmp(iter->labelled_stat->identifier, stat->identifier)) break; }
@@ -1473,7 +1476,7 @@ static HRESULT compile_break_statement(compiler_ctx_t *ctx, branch_statement_t *
if(stat->identifier) { for(pop_ctx = ctx->stat_ctx; pop_ctx; pop_ctx = pop_ctx->next) { - if(pop_ctx->labelled_stat && !strcmpW(pop_ctx->labelled_stat->identifier, stat->identifier)) { + if(pop_ctx->labelled_stat && !wcscmp(pop_ctx->labelled_stat->identifier, stat->identifier)) { assert(pop_ctx->break_label); break; } @@ -1557,7 +1560,7 @@ static HRESULT compile_labelled_statement(compiler_ctx_t *ctx, labelled_statemen HRESULT hres;
for(iter = ctx->stat_ctx; iter; iter = iter->next) { - if(iter->labelled_stat && !strcmpW(iter->labelled_stat->identifier, stat->identifier)) { + if(iter->labelled_stat && !wcscmp(iter->labelled_stat->identifier, stat->identifier)) { WARN("Label %s redefined\n", debugstr_w(stat->identifier)); return JS_E_LABEL_REDEFINED; } @@ -1833,7 +1836,7 @@ static HRESULT compile_statement(compiler_ctx_t *ctx, statement_ctx_t *stat_ctx, static int function_local_cmp(const void *key, const struct wine_rb_entry *entry) { function_local_t *local = WINE_RB_ENTRY_VALUE(entry, function_local_t, entry); - return strcmpW(key, local->name); + return wcscmp(key, local->name); }
static inline function_local_t *find_local(compiler_ctx_t *ctx, const WCHAR *name) @@ -2390,7 +2393,7 @@ static HRESULT parse_arguments(compiler_ctx_t *ctx, const WCHAR *args, BSTR *arg const WCHAR *ptr = args, *ptr2; unsigned arg_cnt = 0;
- while(isspaceW(*ptr)) + while(iswspace(*ptr)) ptr++; if(!*ptr) { if(args_size) @@ -2399,16 +2402,16 @@ static HRESULT parse_arguments(compiler_ctx_t *ctx, const WCHAR *args, BSTR *arg }
while(1) { - if(!isalphaW(*ptr) && *ptr != '_') { + if(!iswalpha(*ptr) && *ptr != '_') { FIXME("expected alpha or '_': %s\n", debugstr_w(ptr)); return E_FAIL; }
ptr2 = ptr; - while(isalnumW(*ptr) || *ptr == '_') + while(iswalnum(*ptr) || *ptr == '_') ptr++;
- if(*ptr && *ptr != ',' && !isspaceW(*ptr)) { + if(*ptr && *ptr != ',' && !iswspace(*ptr)) { FIXME("unexpected har %s\n", debugstr_w(ptr)); return E_FAIL; } @@ -2420,7 +2423,7 @@ static HRESULT parse_arguments(compiler_ctx_t *ctx, const WCHAR *args, BSTR *arg } arg_cnt++;
- while(isspaceW(*ptr)) + while(iswspace(*ptr)) ptr++; if(!*ptr) break; @@ -2430,7 +2433,7 @@ static HRESULT parse_arguments(compiler_ctx_t *ctx, const WCHAR *args, BSTR *arg }
ptr++; - while(isspaceW(*ptr)) + while(iswspace(*ptr)) ptr++; }
@@ -2479,7 +2482,7 @@ HRESULT compile_script(script_ctx_t *ctx, const WCHAR *code, const WCHAR *args, } }
- hres = script_parse(ctx, compiler.code->source, delimiter, from_eval, &compiler.parser); + hres = script_parse(ctx, &compiler, compiler.code->source, delimiter, from_eval, &compiler.parser); if(FAILED(hres)) { release_bytecode(compiler.code); return hres; diff --git a/dll/win32/jscript/date.c b/dll/win32/jscript/date.c index 2676cd1cb1c..74d436f447d 100644 --- a/dll/win32/jscript/date.c +++ b/dll/win32/jscript/date.c @@ -17,8 +17,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
-#include "config.h" -#include "wine/port.h" +#ifdef __REACTOS__ +#include <wine/config.h> +#include <wine/port.h> +#endif
#include <limits.h> #include <math.h> @@ -542,16 +544,16 @@ static inline HRESULT date_to_string(DOUBLE time, BOOL show_offset, int offset, }
if(!show_offset) - sprintfW(buf, formatNoOffsetW, week, month, day, + swprintf(buf, formatNoOffsetW, week, month, day, (int)hour_from_time(time), (int)min_from_time(time), (int)sec_from_time(time), year, formatAD?ADW:BCW); else if(offset) - sprintfW(buf, formatW, week, month, day, + swprintf(buf, formatW, week, month, day, (int)hour_from_time(time), (int)min_from_time(time), (int)sec_from_time(time), sign, offset/60, offset%60, year, formatAD?ADW:BCW); else - sprintfW(buf, formatUTCW, week, month, day, + swprintf(buf, formatUTCW, week, month, day, (int)hour_from_time(time), (int)min_from_time(time), (int)sec_from_time(time), year, formatAD?ADW:BCW);
@@ -658,15 +660,16 @@ static HRESULT Date_toISOString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
if(year < 0) { *p++ = '-'; - p += sprintfW(p, long_year_formatW, -(int)year); + p += swprintf(p, long_year_formatW, -(int)year); }else if(year > 9999) { *p++ = '+'; - p += sprintfW(p, long_year_formatW, (int)year); + p += swprintf(p, long_year_formatW, (int)year); }else { - p += sprintfW(p, short_year_formatW, (int)year); + p += swprintf(p, short_year_formatW, (int)year); }
- sprintfW(p, formatW, (int)month_from_time(date->time) + 1, (int)date_from_time(date->time), + swprintf(p, formatW, + (int)month_from_time(date->time) + 1, (int)date_from_time(date->time), (int)hour_from_time(date->time), (int)min_from_time(date->time), (int)sec_from_time(date->time), (int)ms_from_time(date->time));
@@ -745,7 +748,7 @@ static inline HRESULT create_utc_string(script_ctx_t *ctx, vdisp_t *jsthis, jsva
day = date_from_time(date->time);
- sprintfW(buf, formatAD ? formatADW : formatBCW, week, day, month, year, + swprintf(buf, formatAD ? formatADW : formatBCW, week, day, month, year, (int)hour_from_time(date->time), (int)min_from_time(date->time), (int)sec_from_time(date->time));
@@ -822,7 +825,7 @@ static HRESULT dateobj_to_date_string(DateInstance *date, jsval_t *r)
day = date_from_time(time);
- sprintfW(buf, formatAD ? formatADW : formatBCW, week, month, day, year); + swprintf(buf, formatAD ? formatADW : formatBCW, week, month, day, year);
date_str = jsstr_alloc(buf); if(!date_str) @@ -883,11 +886,11 @@ static HRESULT Date_toTimeString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, else sign = '-';
if(offset) - sprintfW(buf, formatW, (int)hour_from_time(time), + swprintf(buf, formatW, (int)hour_from_time(time), (int)min_from_time(time), (int)sec_from_time(time), sign, offset/60, offset%60); else - sprintfW(buf, formatUTCW, (int)hour_from_time(time), + swprintf(buf, formatUTCW, (int)hour_from_time(time), (int)min_from_time(time), (int)sec_from_time(time));
date_str = jsstr_alloc(buf); @@ -2075,7 +2078,7 @@ static inline HRESULT date_parse(jsstr_t *input_str, double *ret) { for(i=0; i<input_len; i++) { if(input[i] == '(') nest_level++; else if(input[i] == ')') nest_level--; - else if(!nest_level) parse[parse_len++] = toupperW(input[i]); + else if(!nest_level) parse[parse_len++] = towupper(input[i]); } parse[parse_len] = 0;
@@ -2102,16 +2105,16 @@ static inline HRESULT date_parse(jsstr_t *input_str, double *ret) { }
for(i=0; i<parse_len;) { - while(isspaceW(parse[i])) i++; + while(iswspace(parse[i])) i++; if(parse[i] == ',') { while(parse[i] == ',') i++; continue; }
if(parse[i]>='0' && parse[i]<='9') { - int tmp = atoiW(&parse[i]); + int tmp = wcstol(&parse[i], NULL, 10); while(parse[i]>='0' && parse[i]<='9') i++; - while(isspaceW(parse[i])) i++; + while(iswspace(parse[i])) i++;
if(parse[i] == ':') { /* Time */ @@ -2121,17 +2124,17 @@ static inline HRESULT date_parse(jsstr_t *input_str, double *ret) { hour = tmp;
while(parse[i] == ':') i++; - while(isspaceW(parse[i])) i++; + while(iswspace(parse[i])) i++; if(parse[i]>='0' && parse[i]<='9') { - min = atoiW(&parse[i]); + min = wcstol(&parse[i], NULL, 10); while(parse[i]>='0' && parse[i]<='9') i++; }
- while(isspaceW(parse[i])) i++; + while(iswspace(parse[i])) i++; while(parse[i] == ':') i++; - while(isspaceW(parse[i])) i++; + while(iswspace(parse[i])) i++; if(parse[i]>='0' && parse[i]<='9') { - sec = atoiW(&parse[i]); + sec = wcstol(&parse[i], NULL, 10); while(parse[i]>='0' && parse[i]<='9') i++; } } @@ -2144,17 +2147,17 @@ static inline HRESULT date_parse(jsstr_t *input_str, double *ret) {
month = tmp-1;
- while(isspaceW(parse[i])) i++; + while(iswspace(parse[i])) i++; while(parse[i]=='-' || parse[i]=='/') i++; - while(isspaceW(parse[i])) i++; + while(iswspace(parse[i])) i++; if(parse[i]<'0' || parse[i]>'9') break; - day = atoiW(&parse[i]); + day = wcstol(&parse[i], NULL, 10); while(parse[i]>='0' && parse[i]<='9') i++;
while(parse[i]=='-' || parse[i]=='/') i++; - while(isspaceW(parse[i])) i++; + while(iswspace(parse[i])) i++; if(parse[i]<'0' || parse[i]>'9') break; - year = atoiW(&parse[i]); + year = wcstol(&parse[i], NULL, 10); while(parse[i]>='0' && parse[i]<='9') i++;
if(tmp >= 70){ @@ -2189,9 +2192,9 @@ static inline HRESULT date_parse(jsstr_t *input_str, double *ret) { if(parse[i] == '-') positive = FALSE;
i++; - while(isspaceW(parse[i])) i++; + while(iswspace(parse[i])) i++; if(parse[i]<'0' || parse[i]>'9') break; - offset = atoiW(&parse[i]); + offset = wcstol(&parse[i], NULL, 10); while(parse[i]>='0' && parse[i]<='9') i++;
if(offset<24) offset *= 60; @@ -2270,7 +2273,7 @@ static inline HRESULT date_parse(jsstr_t *input_str, double *ret) { size -= i;
for(j=0; j<ARRAY_SIZE(string_ids); j++) - if(!strncmpiW(&parse[i], strings[j], size)) break; + if(!_wcsnicmp(&parse[i], strings[j], size)) break;
if(j < 12) { if(set_month) break; diff --git a/dll/win32/jscript/decode.c b/dll/win32/jscript/decode.c index ccbd04c05b9..283aa2ed947 100644 --- a/dll/win32/jscript/decode.c +++ b/dll/win32/jscript/decode.c @@ -117,7 +117,7 @@ HRESULT decode_source(WCHAR *code) static const WCHAR decode_endW[] = {'^','#','~','@'};
while(*src) { - if(!strncmpW(src, decode_beginW, ARRAY_SIZE(decode_beginW))) { + if(!wcsncmp(src, decode_beginW, ARRAY_SIZE(decode_beginW))) { DWORD len, i, j=0, csum, s=0;
src += ARRAY_SIZE(decode_beginW); @@ -165,7 +165,7 @@ HRESULT decode_source(WCHAR *code) return JS_E_INVALID_CHAR; src += 8;
- if(strncmpW(src, decode_endW, ARRAY_SIZE(decode_endW))) + if(wcsncmp(src, decode_endW, ARRAY_SIZE(decode_endW))) return JS_E_INVALID_CHAR; src += ARRAY_SIZE(decode_endW); }else { diff --git a/dll/win32/jscript/dispex.c b/dll/win32/jscript/dispex.c index bc02aa4d67f..8b45bebb082 100644 --- a/dll/win32/jscript/dispex.c +++ b/dll/win32/jscript/dispex.c @@ -20,7 +20,6 @@
#include "jscript.h"
-#include "wine/unicode.h" #include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(jscript); @@ -94,7 +93,7 @@ static const builtin_prop_t *find_builtin_prop(jsdisp_t *This, const WCHAR *name while(min <= max) { i = (min+max)/2;
- r = strcmpW(name, This->builtin_info->props[i].name); + r = wcscmp(name, This->builtin_info->props[i].name); if(!r) { /* Skip prop if it's available only in higher compatibility mode. */ unsigned version = (This->builtin_info->props[i].flags & PROPF_VERSION_MASK) @@ -122,7 +121,7 @@ static inline unsigned string_hash(const WCHAR *name) { unsigned h = 0; for(; *name; name++) - h = (h>>(sizeof(unsigned)*8-4)) ^ (h<<4) ^ tolowerW(*name); + h = (h>>(sizeof(unsigned)*8-4)) ^ (h<<4) ^ towlower(*name); return h; }
@@ -204,7 +203,7 @@ static HRESULT find_prop_name(jsdisp_t *This, unsigned hash, const WCHAR *name, bucket = get_props_idx(This, hash); pos = This->props[bucket].bucket_head; while(pos != 0) { - if(!strcmpW(name, This->props[pos].name)) { + if(!wcscmp(name, This->props[pos].name)) { if(prev != 0) { This->props[prev].bucket_next = This->props[pos].bucket_next; This->props[pos].bucket_next = This->props[bucket].bucket_head; @@ -240,7 +239,7 @@ static HRESULT find_prop_name(jsdisp_t *This, unsigned hash, const WCHAR *name, const WCHAR *ptr; unsigned idx = 0;
- for(ptr = name; isdigitW(*ptr) && idx < 0x10000; ptr++) + for(ptr = name; iswdigit(*ptr) && idx < 0x10000; ptr++) idx = idx*10 + (*ptr-'0'); if(!*ptr && idx < This->builtin_info->idx_length(This)) { prop = alloc_prop(This, name, PROP_IDX, This->builtin_info->idx_put ? PROPF_WRITABLE : 0); @@ -871,34 +870,14 @@ static HRESULT WINAPI DispatchEx_GetMemberName(IDispatchEx *iface, DISPID id, BS static HRESULT WINAPI DispatchEx_GetNextDispID(IDispatchEx *iface, DWORD grfdex, DISPID id, DISPID *pid) { jsdisp_t *This = impl_from_IDispatchEx(iface); - dispex_prop_t *iter; HRESULT hres;
TRACE("(%p)->(%x %x %p)\n", This, grfdex, id, pid);
- if(id == DISPID_STARTENUM) { - hres = fill_protrefs(This); - if(FAILED(hres)) - return hres; - } - - if(id+1>=0 && id+1<This->prop_cnt) { - iter = &This->props[id+1]; - }else { + hres = jsdisp_next_prop(This, id, FALSE, pid); + if(hres == S_FALSE) *pid = DISPID_STARTENUM; - return S_FALSE; - } - - while(iter < This->props + This->prop_cnt) { - if(iter->name && (get_flags(This, iter) & PROPF_ENUMERABLE) && iter->type!=PROP_DELETED) { - *pid = prop_to_id(This, iter); - return S_OK; - } - iter++; - } - - *pid = DISPID_STARTENUM; - return S_FALSE; + return hres; }
static HRESULT WINAPI DispatchEx_GetNameSpaceParent(IDispatchEx *iface, IUnknown **ppunk) @@ -1373,7 +1352,7 @@ HRESULT jsdisp_propput_idx(jsdisp_t *obj, DWORD idx, jsval_t val)
static const WCHAR formatW[] = {'%','d',0};
- sprintfW(buf, formatW, idx); + swprintf(buf, formatW, idx); return jsdisp_propput_name(obj, buf, val); }
@@ -1451,7 +1430,7 @@ HRESULT jsdisp_get_idx(jsdisp_t *obj, DWORD idx, jsval_t *r)
static const WCHAR formatW[] = {'%','d',0};
- sprintfW(name, formatW, idx); + swprintf(name, formatW, idx);
hres = find_prop_name_prot(obj, string_hash(name), name, &prop); if(FAILED(hres)) @@ -1520,7 +1499,7 @@ HRESULT jsdisp_delete_idx(jsdisp_t *obj, DWORD idx) BOOL b; HRESULT hres;
- sprintfW(buf, formatW, idx); + swprintf(buf, formatW, idx);
hres = find_prop_name(obj, string_hash(buf), buf, &prop); if(FAILED(hres) || !prop) @@ -1564,6 +1543,34 @@ HRESULT disp_delete(IDispatch *disp, DISPID id, BOOL *ret) return S_OK; }
+HRESULT jsdisp_next_prop(jsdisp_t *obj, DISPID id, BOOL own_only, DISPID *ret) +{ + dispex_prop_t *iter; + HRESULT hres; + + if(id == DISPID_STARTENUM && !own_only) { + hres = fill_protrefs(obj); + if(FAILED(hres)) + return hres; + } + + if(id + 1 < 0 || id+1 >= obj->prop_cnt) + return S_FALSE; + + for(iter = &obj->props[id + 1]; iter < obj->props + obj->prop_cnt; iter++) { + if(!iter->name || iter->type == PROP_DELETED) + continue; + if(own_only && iter->type == PROP_PROTREF) + continue; + if(!(get_flags(obj, iter) & PROPF_ENUMERABLE)) + continue; + *ret = prop_to_id(obj, iter); + return S_OK; + } + + return S_FALSE; +} + HRESULT disp_delete_name(script_ctx_t *ctx, IDispatch *disp, jsstr_t *name, BOOL *ret) { IDispatchEx *dispex; diff --git a/dll/win32/jscript/engine.c b/dll/win32/jscript/engine.c index bed8c64a052..4d11db981eb 100644 --- a/dll/win32/jscript/engine.c +++ b/dll/win32/jscript/engine.c @@ -16,8 +16,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
-#include "config.h" -#include "wine/port.h" +#ifdef __REACTOS__ +#include <wine/config.h> +#include <wine/port.h> +#endif
#include <math.h> #include <assert.h> @@ -619,9 +621,9 @@ static BOOL lookup_global_members(script_ctx_t *ctx, BSTR identifier, exprval_t return FALSE; }
-static int local_ref_cmp(const void *key, const void *ref) +static int __cdecl local_ref_cmp(const void *key, const void *ref) { - return strcmpW((const WCHAR*)key, ((const local_ref_t*)ref)->name); + return wcscmp((const WCHAR*)key, ((const local_ref_t*)ref)->name); }
local_ref_t *lookup_local(const function_code_t *function, const WCHAR *identifier) @@ -653,7 +655,7 @@ static HRESULT identifier_eval(script_ctx_t *ctx, BSTR identifier, exprval_t *re return S_OK; }
- if(!strcmpW(identifier, argumentsW)) { + if(!wcscmp(identifier, argumentsW)) { hres = detach_variable_object(ctx, scope->frame, FALSE); if(FAILED(hres)) return hres; @@ -677,7 +679,7 @@ static HRESULT identifier_eval(script_ctx_t *ctx, BSTR identifier, exprval_t *re }
for(item = ctx->named_items; item; item = item->next) { - if((item->flags & SCRIPTITEM_ISVISIBLE) && !strcmpW(item->name, identifier)) { + if((item->flags & SCRIPTITEM_ISVISIBLE) && !wcscmp(item->name, identifier)) { if(!item->disp) { IUnknown *unk;
@@ -1449,16 +1451,20 @@ static HRESULT interp_new_obj(script_ctx_t *ctx) /* ECMA-262 3rd Edition 11.1.5 */ static HRESULT interp_obj_prop(script_ctx_t *ctx) { - const BSTR name = get_op_bstr(ctx, 0); + jsstr_t *name_arg = get_op_str(ctx, 0); unsigned type = get_op_uint(ctx, 1); + const WCHAR *name; jsdisp_t *obj; jsval_t val; HRESULT hres;
- TRACE("%s\n", debugstr_w(name)); + TRACE("%s\n", debugstr_jsstr(name_arg));
val = stack_pop(ctx);
+ /* FIXME: we should pass it as jsstr_t */ + name = jsstr_flatten(name_arg); + assert(is_object_instance(stack_top(ctx))); obj = as_jsdisp(get_object(stack_top(ctx)));
diff --git a/dll/win32/jscript/engine.h b/dll/win32/jscript/engine.h index 6ee8f062df9..0920f6f1d5f 100644 --- a/dll/win32/jscript/engine.h +++ b/dll/win32/jscript/engine.h @@ -68,7 +68,7 @@ X(new, 1, ARG_UINT, 0) \ X(new_obj, 1, 0,0) \ X(null, 1, 0,0) \ - X(obj_prop, 1, ARG_BSTR, ARG_UINT) \ + X(obj_prop, 1, ARG_STR, ARG_UINT) \ X(or, 1, 0,0) \ X(pop, 1, ARG_UINT, 0) \ X(pop_except, 0, ARG_ADDR, 0) \ diff --git a/dll/win32/jscript/enumerator.c b/dll/win32/jscript/enumerator.c index 5c06efd1f9b..5f5b135cb50 100644 --- a/dll/win32/jscript/enumerator.c +++ b/dll/win32/jscript/enumerator.c @@ -61,7 +61,7 @@ static inline HRESULT enumvar_get_next_item(EnumeratorInstance *This) if (This->atend) return S_OK;
- /* dont leak pervious value */ + /* don't leak previous value */ jsval_release(This->item);
/* not at end ... get next item */ @@ -73,7 +73,7 @@ static inline HRESULT enumvar_get_next_item(EnumeratorInstance *This) VariantClear(&nextitem); if (FAILED(hres)) { - WARN("failed to convert jsval to variant!"); + WARN("failed to convert jsval to variant!\n"); This->item = jsval_undefined(); return hres; } diff --git a/dll/win32/jscript/error.c b/dll/win32/jscript/error.c index ef855dce309..fcdeddbfd90 100644 --- a/dll/win32/jscript/error.c +++ b/dll/win32/jscript/error.c @@ -16,8 +16,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
-#include "config.h" -#include "wine/port.h" +#ifdef __REACTOS__ +#include <wine/config.h> +#include <wine/port.h> +#endif
#include <math.h>
@@ -387,10 +389,10 @@ static HRESULT throw_error(script_ctx_t *ctx, HRESULT error, const WCHAR *str, j buf[0] = '\0'; LoadStringW(jscript_hinstance, HRESULT_CODE(error), buf, ARRAY_SIZE(buf));
- if(str) pos = strchrW(buf, '|'); + if(str) pos = wcschr(buf, '|'); if(pos) { - int len = strlenW(str); - memmove(pos+len, pos+1, (strlenW(pos+1)+1)*sizeof(WCHAR)); + int len = lstrlenW(str); + memmove(pos+len, pos+1, (lstrlenW(pos+1)+1)*sizeof(WCHAR)); memcpy(pos, str, len*sizeof(WCHAR)); }
diff --git a/dll/win32/jscript/function.c b/dll/win32/jscript/function.c index 9795f77e904..7a44f5092b8 100644 --- a/dll/win32/jscript/function.c +++ b/dll/win32/jscript/function.c @@ -25,25 +25,52 @@
WINE_DEFAULT_DEBUG_CHANNEL(jscript);
+typedef struct _function_vtbl_t function_vtbl_t; + typedef struct { jsdisp_t dispex; - builtin_invoke_t value_proc; - const WCHAR *name; + const function_vtbl_t *vtbl; DWORD flags; + DWORD length; +} FunctionInstance; + +struct _function_vtbl_t { + HRESULT (*call)(script_ctx_t*,FunctionInstance*,IDispatch*,unsigned,unsigned,jsval_t*,jsval_t*); + HRESULT (*toString)(FunctionInstance*,jsstr_t**); + void (*destructor)(FunctionInstance*); +}; + +typedef struct { + FunctionInstance function; scope_chain_t *scope_chain; bytecode_t *code; function_code_t *func_code; - DWORD length; -} FunctionInstance; +} InterpretedFunction; + +typedef struct { + FunctionInstance function; + builtin_invoke_t proc; + const WCHAR *name; +} NativeFunction; + +typedef struct { + FunctionInstance function; + FunctionInstance *target; + IDispatch *this; + unsigned argc; + jsval_t args[1]; +} BindFunction;
typedef struct { jsdisp_t jsdisp; - FunctionInstance *function; + InterpretedFunction *function; jsval_t *buf; call_frame_t *frame; unsigned argc; } ArgumentsInstance;
+static HRESULT create_bind_function(script_ctx_t*,FunctionInstance*,IDispatch*,unsigned,jsval_t*,jsdisp_t**r); + static inline FunctionInstance *function_from_jsdisp(jsdisp_t *jsdisp) { return CONTAINING_RECORD(jsdisp, FunctionInstance, dispex); @@ -69,6 +96,7 @@ static const WCHAR prototypeW[] = {'p','r','o','t','o','t', 'y', 'p','e',0}; static const WCHAR lengthW[] = {'l','e','n','g','t','h',0}; static const WCHAR toStringW[] = {'t','o','S','t','r','i','n','g',0}; static const WCHAR applyW[] = {'a','p','p','l','y',0}; +static const WCHAR bindW[] = {'b','i','n','d',0}; static const WCHAR callW[] = {'c','a','l','l',0}; static const WCHAR argumentsW[] = {'a','r','g','u','m','e','n','t','s',0};
@@ -92,7 +120,7 @@ static void Arguments_destructor(jsdisp_t *jsdisp) heap_free(arguments->buf); }
- jsdisp_release(&arguments->function->dispex); + jsdisp_release(&arguments->function->function.dispex); heap_free(arguments); }
@@ -122,7 +150,8 @@ static HRESULT Arguments_idx_get(jsdisp_t *jsdisp, unsigned idx, jsval_t *r) return jsval_copy(*ref, r);
/* FIXME: Accessing by name won't work for duplicated argument names */ - return jsdisp_propget_name(arguments->frame->base_scope->jsobj, arguments->function->func_code->params[idx], r); + return jsdisp_propget_name(arguments->frame->base_scope->jsobj, + arguments->function->func_code->params[idx], r); }
static HRESULT Arguments_idx_put(jsdisp_t *jsdisp, unsigned idx, jsval_t val) @@ -145,7 +174,8 @@ static HRESULT Arguments_idx_put(jsdisp_t *jsdisp, unsigned idx, jsval_t val) }
/* FIXME: Accessing by name won't work for duplicated argument names */ - return jsdisp_propput_name(arguments->frame->base_scope->jsobj, arguments->function->func_code->params[idx], val); + return jsdisp_propput_name(arguments->frame->base_scope->jsobj, + arguments->function->func_code->params[idx], val); }
static const builtin_info_t Arguments_info = { @@ -176,7 +206,7 @@ HRESULT setup_arguments_object(script_ctx_t *ctx, call_frame_t *frame) return hres; }
- args->function = function_from_jsdisp(jsdisp_addref(frame->function_instance)); + args->function = (InterpretedFunction*)function_from_jsdisp(jsdisp_addref(frame->function_instance)); args->argc = frame->argc; args->frame = frame;
@@ -184,7 +214,7 @@ HRESULT setup_arguments_object(script_ctx_t *ctx, call_frame_t *frame) jsval_number(args->argc)); if(SUCCEEDED(hres)) hres = jsdisp_define_data_property(&args->jsdisp, caleeW, PROPF_WRITABLE | PROPF_CONFIGURABLE, - jsval_obj(&args->function->dispex)); + jsval_obj(&args->function->function.dispex)); if(SUCCEEDED(hres)) hres = jsdisp_propput(frame->base_scope->jsobj, argumentsW, PROPF_WRITABLE, jsval_obj(&args->jsdisp)); if(FAILED(hres)) { @@ -231,99 +261,8 @@ void detach_arguments_object(jsdisp_t *args_disp) jsdisp_release(frame->arguments_obj); }
-static HRESULT invoke_source(script_ctx_t *ctx, FunctionInstance *function, IDispatch *this_obj, unsigned argc, jsval_t *argv, - BOOL is_constructor, BOOL caller_execs_source, jsval_t *r) -{ - jsdisp_t *var_disp; - DWORD exec_flags = 0; - HRESULT hres; - - if(ctx->state == SCRIPTSTATE_UNINITIALIZED || ctx->state == SCRIPTSTATE_CLOSED) { - WARN("Script engine state does not allow running code.\n"); - return E_UNEXPECTED; - } - - if(!function->func_code) { - FIXME("no source\n"); - return E_FAIL; - } - - hres = create_dispex(ctx, NULL, NULL, &var_disp); - if(FAILED(hres)) - return hres; - - if(caller_execs_source) - exec_flags |= EXEC_RETURN_TO_INTERP; - if(is_constructor) - exec_flags |= EXEC_CONSTRUCTOR; - hres = exec_source(ctx, exec_flags, function->code, function->func_code, function->scope_chain, this_obj, - &function->dispex, var_disp, argc, argv, r); - - jsdisp_release(var_disp); - return hres; -} - -static HRESULT invoke_value_proc(script_ctx_t *ctx, FunctionInstance *function, IDispatch *this_disp, WORD flags, - unsigned argc, jsval_t *argv, jsval_t *r) -{ - vdisp_t vthis; - HRESULT hres; - - if(this_disp) - set_disp(&vthis, this_disp); - else if(ctx->host_global) - set_disp(&vthis, ctx->host_global); - else - set_jsdisp(&vthis, ctx->global); - - hres = function->value_proc(ctx, &vthis, flags, argc, argv, r); - - vdisp_release(&vthis); - return hres; -} - -static HRESULT call_function(script_ctx_t *ctx, FunctionInstance *function, IDispatch *this_obj, - unsigned argc, jsval_t *argv, BOOL caller_execs_source, jsval_t *r) -{ - if(function->value_proc) - return invoke_value_proc(ctx, function, this_obj, DISPATCH_METHOD, argc, argv, r); - - return invoke_source(ctx, function, this_obj, argc, argv, FALSE, caller_execs_source, r); -} - -static HRESULT function_to_string(FunctionInstance *function, jsstr_t **ret) -{ - jsstr_t *str; - - static const WCHAR native_prefixW[] = {'\n','f','u','n','c','t','i','o','n',' '}; - static const WCHAR native_suffixW[] = - {'(',')',' ','{','\n',' ',' ',' ',' ','[','n','a','t','i','v','e',' ','c','o','d','e',']','\n','}','\n'}; - - if(function->value_proc) { - DWORD name_len; - WCHAR *ptr; - - name_len = strlenW(function->name); - str = jsstr_alloc_buf(ARRAY_SIZE(native_prefixW) + ARRAY_SIZE(native_suffixW) + name_len, &ptr); - if(!str) - return E_OUTOFMEMORY; - - memcpy(ptr, native_prefixW, sizeof(native_prefixW)); - memcpy(ptr += ARRAY_SIZE(native_prefixW), function->name, name_len*sizeof(WCHAR)); - memcpy(ptr + name_len, native_suffixW, sizeof(native_suffixW)); - }else { - str = jsstr_alloc_len(function->func_code->source, function->func_code->source_len); - if(!str) - return E_OUTOFMEMORY; - } - - *ret = str; - return S_OK; -} - HRESULT Function_invoke(jsdisp_t *func_this, IDispatch *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) { - const BOOL caller_execs_source = (flags & DISPATCH_JSCRIPT_CALLEREXECSSOURCE) != 0; FunctionInstance *function;
TRACE("func %p this %p\n", func_this, jsthis); @@ -331,25 +270,7 @@ HRESULT Function_invoke(jsdisp_t *func_this, IDispatch *jsthis, WORD flags, unsi assert(is_class(func_this, JSCLASS_FUNCTION)); function = function_from_jsdisp(func_this);
- flags &= ~DISPATCH_JSCRIPT_INTERNAL_MASK; - if(function->value_proc) - return invoke_value_proc(function->dispex.ctx, function, jsthis, flags, argc, argv, r); - - if(flags == DISPATCH_CONSTRUCT) { - jsdisp_t *this_obj; - HRESULT hres; - - hres = create_object(function->dispex.ctx, &function->dispex, &this_obj); - if(FAILED(hres)) - return hres; - - hres = invoke_source(function->dispex.ctx, function, to_disp(this_obj), argc, argv, TRUE, caller_execs_source, r); - jsdisp_release(this_obj); - return hres; - } - - assert(flags == DISPATCH_METHOD); - return invoke_source(function->dispex.ctx, function, jsthis, argc, argv, FALSE, caller_execs_source, r); + return function->vtbl->call(function->dispex.ctx, function, jsthis, flags, argc, argv, r); }
static HRESULT Function_get_length(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t *r) @@ -372,7 +293,7 @@ static HRESULT Function_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, if(!(function = function_this(jsthis))) return throw_type_error(ctx, JS_E_FUNCTION_EXPECTED, NULL);
- hres = function_to_string(function, &str); + hres = function->vtbl->toString(function, &str); if(FAILED(hres)) return hres;
@@ -463,7 +384,7 @@ static HRESULT Function_apply(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un
if(SUCCEEDED(hres)) { if(function) { - hres = call_function(ctx, function, this_obj, cnt, args, (flags & DISPATCH_JSCRIPT_CALLEREXECSSOURCE) != 0, r); + hres = function->vtbl->call(ctx, function, this_obj, flags, cnt, args, r); }else { jsval_t res; hres = disp_call_value(ctx, jsthis->u.disp, this_obj, DISPATCH_METHOD, cnt, args, &res); @@ -507,13 +428,46 @@ static HRESULT Function_call(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, uns cnt = argc-1; }
- hres = call_function(ctx, function, this_obj, cnt, argv+1, (flags & DISPATCH_JSCRIPT_CALLEREXECSSOURCE) != 0, r); + hres = function->vtbl->call(ctx, function, this_obj, flags, cnt, argv + 1, r);
if(this_obj) IDispatch_Release(this_obj); return hres; }
+static HRESULT Function_bind(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, + jsval_t *r) +{ + FunctionInstance *function; + jsdisp_t *new_function; + HRESULT hres; + + TRACE("\n"); + + if(!(function = function_this(jsthis))) + return throw_type_error(ctx, JS_E_FUNCTION_EXPECTED, NULL); + + if(argc < 1) { + FIXME("no this argument\n"); + return E_NOTIMPL; + } + + if(!is_object_instance(argv[0]) || !get_object(argv[0])) { + FIXME("%s is not an object instance\n", debugstr_jsval(argv[0])); + return E_NOTIMPL; + } + + hres = create_bind_function(ctx, function, get_object(argv[0]), argc - 1, argv + 1, &new_function); + if(FAILED(hres)) + return hres; + + if(r) + *r = jsval_obj(new_function); + else + jsdisp_release(new_function); + return S_OK; +} + HRESULT Function_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) { @@ -527,19 +481,18 @@ HRESULT Function_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned }
function = function_from_jsdisp(jsthis->u.jsdisp); - - assert(function->value_proc != NULL); - return invoke_value_proc(ctx, function, NULL, flags, argc, argv, r); + return function->vtbl->call(ctx, function, NULL, flags, argc, argv, r); }
HRESULT Function_get_value(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t *r) { + FunctionInstance *function = function_from_jsdisp(jsthis); jsstr_t *str; HRESULT hres;
TRACE("\n");
- hres = function_to_string(function_from_jsdisp(jsthis), &str); + hres = function->vtbl->toString(function, &str); if(FAILED(hres)) return hres;
@@ -573,18 +526,15 @@ static HRESULT Function_get_arguments(script_ctx_t *ctx, jsdisp_t *jsthis, jsval
static void Function_destructor(jsdisp_t *dispex) { - FunctionInstance *This = function_from_jsdisp(dispex); - - if(This->code) - release_bytecode(This->code); - if(This->scope_chain) - scope_release(This->scope_chain); - heap_free(This); + FunctionInstance *function = function_from_jsdisp(dispex); + function->vtbl->destructor(function); + heap_free(function); }
static const builtin_prop_t Function_props[] = { {applyW, Function_apply, PROPF_METHOD|2}, {argumentsW, NULL, 0, Function_get_arguments}, + {bindW, Function_bind, PROPF_METHOD|PROPF_ES5|1}, {callW, Function_call, PROPF_METHOD|1}, {lengthW, NULL, 0, Function_get_length}, {toStringW, Function_toString, PROPF_METHOD} @@ -613,13 +563,13 @@ static const builtin_info_t FunctionInst_info = { NULL };
-static HRESULT create_function(script_ctx_t *ctx, const builtin_info_t *builtin_info, DWORD flags, - BOOL funcprot, jsdisp_t *prototype, FunctionInstance **ret) +static HRESULT create_function(script_ctx_t *ctx, const builtin_info_t *builtin_info, const function_vtbl_t *vtbl, size_t size, + DWORD flags, BOOL funcprot, jsdisp_t *prototype, void **ret) { FunctionInstance *function; HRESULT hres;
- function = heap_alloc_zero(sizeof(FunctionInstance)); + function = heap_alloc_zero(size); if(!function) return E_OUTOFMEMORY;
@@ -634,6 +584,7 @@ static HRESULT create_function(script_ctx_t *ctx, const builtin_info_t *builtin_ return hres; }
+ function->vtbl = vtbl; function->flags = flags; function->length = flags & PROPF_ARGMASK;
@@ -641,30 +592,86 @@ static HRESULT create_function(script_ctx_t *ctx, const builtin_info_t *builtin_ return S_OK; }
+static HRESULT NativeFunction_call(script_ctx_t *ctx, FunctionInstance *func, IDispatch *this_disp, unsigned flags, + unsigned argc, jsval_t *argv, jsval_t *r) +{ + NativeFunction *function = (NativeFunction*)func; + vdisp_t vthis; + HRESULT hres; + + if(this_disp) + set_disp(&vthis, this_disp); + else if(ctx->host_global) + set_disp(&vthis, ctx->host_global); + else + set_jsdisp(&vthis, ctx->global); + + hres = function->proc(ctx, &vthis, flags & ~DISPATCH_JSCRIPT_INTERNAL_MASK, argc, argv, r); + + vdisp_release(&vthis); + return hres; +} + +static HRESULT NativeFunction_toString(FunctionInstance *func, jsstr_t **ret) +{ + NativeFunction *function = (NativeFunction*)func; + DWORD name_len; + jsstr_t *str; + WCHAR *ptr; + + static const WCHAR native_prefixW[] = {'\n','f','u','n','c','t','i','o','n',' '}; + static const WCHAR native_suffixW[] = + {'(',')',' ','{','\n',' ',' ',' ',' ','[','n','a','t','i','v','e',' ','c','o','d','e',']','\n','}','\n'}; + + name_len = function->name ? lstrlenW(function->name) : 0; + str = jsstr_alloc_buf(ARRAY_SIZE(native_prefixW) + ARRAY_SIZE(native_suffixW) + name_len, &ptr); + if(!str) + return E_OUTOFMEMORY; + + memcpy(ptr, native_prefixW, sizeof(native_prefixW)); + ptr += ARRAY_SIZE(native_prefixW); + memcpy(ptr, function->name, name_len*sizeof(WCHAR)); + ptr += name_len; + memcpy(ptr, native_suffixW, sizeof(native_suffixW)); + + *ret = str; + return S_OK; +} + +static void NativeFunction_destructor(FunctionInstance *function) +{ +} + +static const function_vtbl_t NativeFunctionVtbl = { + NativeFunction_call, + NativeFunction_toString, + NativeFunction_destructor +}; + HRESULT create_builtin_function(script_ctx_t *ctx, builtin_invoke_t value_proc, const WCHAR *name, const builtin_info_t *builtin_info, DWORD flags, jsdisp_t *prototype, jsdisp_t **ret) { - FunctionInstance *function; + NativeFunction *function; HRESULT hres;
- hres = create_function(ctx, builtin_info, flags, FALSE, NULL, &function); + hres = create_function(ctx, builtin_info, &NativeFunctionVtbl, sizeof(NativeFunction), flags, FALSE, NULL, (void**)&function); if(FAILED(hres)) return hres;
if(builtin_info) - hres = jsdisp_define_data_property(&function->dispex, lengthW, 0, - jsval_number(function->length)); + hres = jsdisp_define_data_property(&function->function.dispex, lengthW, 0, + jsval_number(function->function.length)); if(SUCCEEDED(hres)) - hres = jsdisp_define_data_property(&function->dispex, prototypeW, 0, jsval_obj(prototype)); + hres = jsdisp_define_data_property(&function->function.dispex, prototypeW, 0, jsval_obj(prototype)); if(FAILED(hres)) { - jsdisp_release(&function->dispex); + jsdisp_release(&function->function.dispex); return hres; }
- function->value_proc = value_proc; + function->proc = value_proc; function->name = name;
- *ret = &function->dispex; + *ret = &function->function.dispex; return S_OK; }
@@ -696,10 +703,71 @@ HRESULT create_builtin_constructor(script_ctx_t *ctx, builtin_invoke_t value_pro return S_OK; }
+static HRESULT InterpretedFunction_call(script_ctx_t *ctx, FunctionInstance *func, IDispatch *this_obj, unsigned flags, + unsigned argc, jsval_t *argv, jsval_t *r) +{ + InterpretedFunction *function = (InterpretedFunction*)func; + jsdisp_t *var_disp, *new_obj = NULL; + DWORD exec_flags = 0; + HRESULT hres; + + TRACE("%p\n", function); + + if(ctx->state == SCRIPTSTATE_UNINITIALIZED || ctx->state == SCRIPTSTATE_CLOSED) { + WARN("Script engine state does not allow running code.\n"); + return E_UNEXPECTED; + } + + if(flags & DISPATCH_CONSTRUCT) { + hres = create_object(ctx, &function->function.dispex, &new_obj); + if(FAILED(hres)) + return hres; + this_obj = to_disp(new_obj); + } + + if(flags & DISPATCH_JSCRIPT_CALLEREXECSSOURCE) + exec_flags |= EXEC_RETURN_TO_INTERP; + if(flags & DISPATCH_CONSTRUCT) + exec_flags |= EXEC_CONSTRUCTOR; + + hres = create_dispex(ctx, NULL, NULL, &var_disp); + if(SUCCEEDED(hres)) + hres = exec_source(ctx, exec_flags, function->code, function->func_code, function->scope_chain, this_obj, + &function->function.dispex, var_disp, argc, argv, r); + if(new_obj) + jsdisp_release(new_obj); + + jsdisp_release(var_disp); + return hres; +} + +static HRESULT InterpretedFunction_toString(FunctionInstance *func, jsstr_t **ret) +{ + InterpretedFunction *function = (InterpretedFunction*)func; + + *ret = jsstr_alloc_len(function->func_code->source, function->func_code->source_len); + return *ret ? S_OK : E_OUTOFMEMORY; +} + +static void InterpretedFunction_destructor(FunctionInstance *func) +{ + InterpretedFunction *function = (InterpretedFunction*)func; + + release_bytecode(function->code); + if(function->scope_chain) + scope_release(function->scope_chain); +} + +static const function_vtbl_t InterpretedFunctionVtbl = { + InterpretedFunction_call, + InterpretedFunction_toString, + InterpretedFunction_destructor +}; + HRESULT create_source_function(script_ctx_t *ctx, bytecode_t *code, function_code_t *func_code, scope_chain_t *scope_chain, jsdisp_t **ret) { - FunctionInstance *function; + InterpretedFunction *function; jsdisp_t *prototype; HRESULT hres;
@@ -707,14 +775,15 @@ HRESULT create_source_function(script_ctx_t *ctx, bytecode_t *code, function_cod if(FAILED(hres)) return hres;
- hres = create_function(ctx, NULL, PROPF_CONSTR, FALSE, NULL, &function); + hres = create_function(ctx, NULL, &InterpretedFunctionVtbl, sizeof(InterpretedFunction), PROPF_CONSTR, + FALSE, NULL, (void**)&function); if(SUCCEEDED(hres)) { - hres = jsdisp_define_data_property(&function->dispex, prototypeW, PROPF_WRITABLE, + hres = jsdisp_define_data_property(&function->function.dispex, prototypeW, PROPF_WRITABLE, jsval_obj(prototype)); if(SUCCEEDED(hres)) - hres = set_constructor_prop(ctx, &function->dispex, prototype); + hres = set_constructor_prop(ctx, &function->function.dispex, prototype); if(FAILED(hres)) - jsdisp_release(&function->dispex); + jsdisp_release(&function->function.dispex); } jsdisp_release(prototype); if(FAILED(hres)) @@ -728,9 +797,97 @@ HRESULT create_source_function(script_ctx_t *ctx, bytecode_t *code, function_cod bytecode_addref(code); function->code = code; function->func_code = func_code; - function->length = function->func_code->param_cnt; + function->function.length = function->func_code->param_cnt; + + *ret = &function->function.dispex; + return S_OK; +} + +static HRESULT BindFunction_call(script_ctx_t *ctx, FunctionInstance *func, IDispatch *this_obj, unsigned flags, + unsigned argc, jsval_t *argv, jsval_t *r) +{ + BindFunction *function = (BindFunction*)func; + jsval_t *call_args = NULL; + unsigned call_argc; + HRESULT hres; + + TRACE("%p\n", function); + + call_argc = function->argc + argc; + if(call_argc) { + call_args = heap_alloc(function->argc * sizeof(*function->args)); + if(!call_args) + return E_OUTOFMEMORY; + + if(function->argc) + memcpy(call_args, function->args, function->argc * sizeof(*call_args)); + if(argc) + memcpy(call_args + function->argc, argv, argc * sizeof(*call_args)); + } + + hres = function->target->vtbl->call(ctx, function->target, function->this, flags, call_argc, call_args, r); + + heap_free(call_args); + return hres; +} + +static HRESULT BindFunction_toString(FunctionInstance *function, jsstr_t **ret) +{ + static const WCHAR native_functionW[] = + {'\n','f','u','n','c','t','i','o','n','(',')',' ','{','\n', + ' ',' ',' ',' ','[','n','a','t','i','v','e',' ','c','o','d','e',']','\n', + '}','\n',0}; + + *ret = jsstr_alloc(native_functionW); + return *ret ? S_OK : E_OUTOFMEMORY; +} + +static void BindFunction_destructor(FunctionInstance *func) +{ + BindFunction *function = (BindFunction*)func; + unsigned i; + + TRACE("%p\n", function); + + for(i = 0; i < function->argc; i++) + jsval_release(function->args[i]); + jsdisp_release(&function->target->dispex); + IDispatch_Release(function->this); +} + +static const function_vtbl_t BindFunctionVtbl = { + BindFunction_call, + BindFunction_toString, + BindFunction_destructor +}; + +static HRESULT create_bind_function(script_ctx_t *ctx, FunctionInstance *target, IDispatch *bound_this, unsigned argc, + jsval_t *argv, jsdisp_t **ret) +{ + BindFunction *function; + HRESULT hres; + + hres = create_function(ctx, NULL, &BindFunctionVtbl, FIELD_OFFSET(BindFunction, args[argc]), PROPF_METHOD, + FALSE, NULL, (void**)&function); + if(FAILED(hres)) + return hres; + + jsdisp_addref(&target->dispex); + function->target = target; + + IDispatch_AddRef(function->this = bound_this); + + for(function->argc = 0; function->argc < argc; function->argc++) { + hres = jsval_copy(argv[function->argc], function->args + function->argc); + if(FAILED(hres)) { + jsdisp_release(&function->function.dispex); + return hres; + } + } + + function->function.length = target->length > argc ? target->length - argc : 0;
- *ret = &function->dispex; + *ret = &function->function.dispex; return S_OK; }
@@ -852,32 +1009,34 @@ static HRESULT FunctionProt_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags
HRESULT init_function_constr(script_ctx_t *ctx, jsdisp_t *object_prototype) { - FunctionInstance *prot, *constr; + NativeFunction *prot, *constr; HRESULT hres;
static const WCHAR FunctionW[] = {'F','u','n','c','t','i','o','n',0};
- hres = create_function(ctx, &Function_info, PROPF_CONSTR, TRUE, object_prototype, &prot); + hres = create_function(ctx, &Function_info, &NativeFunctionVtbl, sizeof(NativeFunction), PROPF_CONSTR, + TRUE, object_prototype, (void**)&prot); if(FAILED(hres)) return hres;
- prot->value_proc = FunctionProt_value; + prot->proc = FunctionProt_value; prot->name = prototypeW;
- hres = create_function(ctx, &FunctionInst_info, PROPF_CONSTR|1, TRUE, &prot->dispex, &constr); + hres = create_function(ctx, &FunctionInst_info, &NativeFunctionVtbl, sizeof(NativeFunction), PROPF_CONSTR|1, + TRUE, &prot->function.dispex, (void**)&constr); if(SUCCEEDED(hres)) { - constr->value_proc = FunctionConstr_value; + constr->proc = FunctionConstr_value; constr->name = FunctionW; - hres = jsdisp_define_data_property(&constr->dispex, prototypeW, 0, jsval_obj(&prot->dispex)); + hres = jsdisp_define_data_property(&constr->function.dispex, prototypeW, 0, jsval_obj(&prot->function.dispex)); if(SUCCEEDED(hres)) - hres = set_constructor_prop(ctx, &constr->dispex, &prot->dispex); + hres = set_constructor_prop(ctx, &constr->function.dispex, &prot->function.dispex); if(FAILED(hres)) - jsdisp_release(&constr->dispex); + jsdisp_release(&constr->function.dispex); } - jsdisp_release(&prot->dispex); + jsdisp_release(&prot->function.dispex); if(FAILED(hres)) return hres;
- ctx->function_constr = &constr->dispex; + ctx->function_constr = &constr->function.dispex; return S_OK; } diff --git a/dll/win32/jscript/global.c b/dll/win32/jscript/global.c index 92b146c83ac..24c4eebf1db 100644 --- a/dll/win32/jscript/global.c +++ b/dll/win32/jscript/global.c @@ -16,8 +16,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
-#include "config.h" -#include "wine/port.h" +#ifdef __REACTOS__ +#include <wine/config.h> +#include <wine/port.h> +#endif
#include <math.h> #include <limits.h> @@ -181,7 +183,7 @@ static HRESULT JSGlobal_escape(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, u HRESULT JSGlobal_eval(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) { - call_frame_t *frame; + call_frame_t *frame = ctx->call_ctx; DWORD exec_flags = EXEC_EVAL; bytecode_t *code; const WCHAR *src; @@ -201,11 +203,6 @@ HRESULT JSGlobal_eval(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned a return S_OK; }
- if(!(frame = ctx->call_ctx)) { - FIXME("No active exec_ctx\n"); - return E_UNEXPECTED; - } - src = jsstr_flatten(get_string(argv[0])); if(!src) return E_OUTOFMEMORY; @@ -217,12 +214,12 @@ HRESULT JSGlobal_eval(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned a return throw_syntax_error(ctx, hres, NULL); }
- if(frame->flags & EXEC_GLOBAL) + if(!frame || (frame->flags & EXEC_GLOBAL)) exec_flags |= EXEC_GLOBAL; if(flags & DISPATCH_JSCRIPT_CALLEREXECSSOURCE) exec_flags |= EXEC_RETURN_TO_INTERP; - hres = exec_source(ctx, exec_flags, code, &code->global_code, frame->scope, - frame->this_obj, NULL, frame->variable_obj, 0, NULL, r); + hres = exec_source(ctx, exec_flags, code, &code->global_code, frame ? frame->scope : NULL, + frame ? frame->this_obj : NULL, NULL, frame ? frame->variable_obj : ctx->global, 0, NULL, r); release_bytecode(code); return hres; } @@ -317,7 +314,7 @@ static HRESULT JSGlobal_parseInt(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, if(FAILED(hres)) return hres;
- while(isspaceW(*ptr)) + while(iswspace(*ptr)) ptr++;
switch(*ptr) { @@ -343,6 +340,8 @@ static HRESULT JSGlobal_parseInt(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, }else { radix = 10; } + }else if(radix == 16 && *ptr == '0' && (ptr[1] == 'x' || ptr[1] == 'X')) { + ptr += 2; }
i = char_to_int(*ptr++); @@ -385,7 +384,7 @@ static HRESULT JSGlobal_parseFloat(script_ctx_t *ctx, vdisp_t *jsthis, WORD flag if(FAILED(hres)) return hres;
- while(isspaceW(*str)) str++; + while(iswspace(*str)) str++;
if(*str == '+') str++; @@ -394,10 +393,10 @@ static HRESULT JSGlobal_parseFloat(script_ctx_t *ctx, vdisp_t *jsthis, WORD flag str++; }
- if(isdigitW(*str)) + if(iswdigit(*str)) ret_nan = FALSE;
- while(isdigitW(*str)) { + while(iswdigit(*str)) { hlp = d*10 + *(str++) - '0'; if(d>MAXLONGLONG/10 || hlp<0) { exp++; @@ -406,17 +405,17 @@ static HRESULT JSGlobal_parseFloat(script_ctx_t *ctx, vdisp_t *jsthis, WORD flag else d = hlp; } - while(isdigitW(*str)) { + while(iswdigit(*str)) { exp++; str++; }
if(*str == '.') str++;
- if(isdigitW(*str)) + if(iswdigit(*str)) ret_nan = FALSE;
- while(isdigitW(*str)) { + while(iswdigit(*str)) { hlp = d*10 + *(str++) - '0'; if(d>MAXLONGLONG/10 || hlp<0) break; @@ -424,7 +423,7 @@ static HRESULT JSGlobal_parseFloat(script_ctx_t *ctx, vdisp_t *jsthis, WORD flag d = hlp; exp--; } - while(isdigitW(*str)) + while(iswdigit(*str)) str++;
if(*str && !ret_nan && (*str=='e' || *str=='E')) { @@ -438,7 +437,7 @@ static HRESULT JSGlobal_parseFloat(script_ctx_t *ctx, vdisp_t *jsthis, WORD flag str++; }
- while(isdigitW(*str)) { + while(iswdigit(*str)) { if(e>INT_MAX/10 || (e = e*10 + *str++ - '0')<0) e = INT_MAX; } @@ -465,8 +464,8 @@ static HRESULT JSGlobal_parseFloat(script_ctx_t *ctx, vdisp_t *jsthis, WORD flag }
static inline int hex_to_int(const WCHAR wch) { - if(toupperW(wch)>='A' && toupperW(wch)<='F') return toupperW(wch)-'A'+10; - if(isdigitW(wch)) return wch-'0'; + if(towupper(wch)>='A' && towupper(wch)<='F') return towupper(wch)-'A'+10; + if(iswdigit(wch)) return wch-'0'; return -1; }
diff --git a/dll/win32/jscript/jscript.h b/dll/win32/jscript/jscript.h index 5149d0d4a3f..427ddf59cb9 100644 --- a/dll/win32/jscript/jscript.h +++ b/dll/win32/jscript/jscript.h @@ -20,19 +20,22 @@
#include <stdarg.h> #include <stdio.h> +#include <stdint.h>
#define COBJMACROS
#include "windef.h" #include "winbase.h" #include "winuser.h" +#ifdef __REACTOS__ +#include "winnls.h" +#endif #include "ole2.h" #include "dispex.h" #include "activscp.h"
#include "resource.h"
-#include "wine/unicode.h" #include "wine/heap.h" #include "wine/list.h"
@@ -77,7 +80,7 @@ static inline LPWSTR heap_strdupW(LPCWSTR str) if(str) { DWORD size;
- size = (strlenW(str)+1)*sizeof(WCHAR); + size = (lstrlenW(str)+1)*sizeof(WCHAR); ret = heap_alloc(size); if(ret) memcpy(ret, str, size); @@ -299,6 +302,7 @@ HRESULT jsdisp_delete_idx(jsdisp_t*,DWORD) DECLSPEC_HIDDEN; HRESULT jsdisp_get_own_property(jsdisp_t*,const WCHAR*,BOOL,property_desc_t*) DECLSPEC_HIDDEN; HRESULT jsdisp_define_property(jsdisp_t*,const WCHAR*,property_desc_t*) DECLSPEC_HIDDEN; HRESULT jsdisp_define_data_property(jsdisp_t*,const WCHAR*,unsigned,jsval_t) DECLSPEC_HIDDEN; +HRESULT jsdisp_next_prop(jsdisp_t*,DISPID,BOOL,DISPID*) DECLSPEC_HIDDEN;
HRESULT create_builtin_function(script_ctx_t*,builtin_invoke_t,const WCHAR*,const builtin_info_t*,DWORD, jsdisp_t*,jsdisp_t**) DECLSPEC_HIDDEN; @@ -507,14 +511,6 @@ static inline BOOL is_vclass(vdisp_t *vdisp, jsclass_t class) return is_jsdisp(vdisp) && is_class(vdisp->u.jsdisp, class); }
-#ifndef INT32_MIN -#define INT32_MIN (-2147483647-1) -#endif - -#ifndef INT32_MAX -#define INT32_MAX (2147483647) -#endif - static inline BOOL is_int32(double d) { return INT32_MIN <= d && d <= INT32_MAX && (double)(int)d == d; diff --git a/dll/win32/jscript/json.c b/dll/win32/jscript/json.c index d4405436907..608237f32a9 100644 --- a/dll/win32/jscript/json.c +++ b/dll/win32/jscript/json.c @@ -23,7 +23,6 @@ #include "parser.h"
#include "wine/debug.h" -#include "wine/unicode.h"
WINE_DEFAULT_DEBUG_CHANNEL(jscript);
@@ -89,14 +88,14 @@ static HRESULT parse_json_string(json_parse_ctx_t *ctx, WCHAR **r) return E_OUTOFMEMORY; if(len) memcpy(buf, ptr, len*sizeof(WCHAR)); - buf[len] = 0;
- if(!unescape(buf)) { + if(!unescape(buf, &len)) { FIXME("unescape failed\n"); heap_free(buf); return E_FAIL; }
+ buf[len] = 0; ctx->ptr++; *r = buf; return S_OK; @@ -261,19 +260,12 @@ static HRESULT parse_json_value(json_parse_ctx_t *ctx, jsval_t *r) skip_spaces(ctx); }
- if(!isdigitW(*ctx->ptr)) + if(*ctx->ptr == '0' && ctx->ptr + 1 < ctx->end && iswdigit(ctx->ptr[1])) break;
- if(*ctx->ptr == '0') { - ctx->ptr++; - n = 0; - if(is_identifier_char(*ctx->ptr)) - break; - }else { - hres = parse_decimal(&ctx->ptr, ctx->end, &n); - if(FAILED(hres)) - return hres; - } + hres = parse_decimal(&ctx->ptr, ctx->end, &n); + if(FAILED(hres)) + break;
*r = jsval_number(sign*n); return S_OK; @@ -402,7 +394,7 @@ static BOOL append_string_len(stringify_ctx_t *ctx, const WCHAR *str, size_t len
static inline BOOL append_string(stringify_ctx_t *ctx, const WCHAR *str) { - return append_string_len(ctx, str, strlenW(str)); + return append_string_len(ctx, str, lstrlenW(str)); }
static inline BOOL append_char(stringify_ctx_t *ctx, WCHAR c) @@ -489,7 +481,7 @@ static HRESULT json_quote(stringify_ctx_t *ctx, const WCHAR *ptr, size_t len) if(*ptr < ' ') { static const WCHAR formatW[] = {'\','u','%','0','4','x',0}; WCHAR buf[7]; - sprintfW(buf, formatW, *ptr); + swprintf(buf, formatW, *ptr); if(!append_string(ctx, buf)) return E_OUTOFMEMORY; }else { diff --git a/dll/win32/jscript/jsregexp.c b/dll/win32/jscript/jsregexp.c index 84360694eed..d4ee506f03b 100644 --- a/dll/win32/jscript/jsregexp.c +++ b/dll/win32/jscript/jsregexp.c @@ -647,12 +647,12 @@ HRESULT create_regexp(script_ctx_t *ctx, jsstr_t *src, DWORD flags, jsdisp_t **r const WCHAR *str; HRESULT hres;
- TRACE("%s %x\n", debugstr_jsstr(src), flags); - str = jsstr_flatten(src); if(!str) return E_OUTOFMEMORY;
+ TRACE("%s %x\n", debugstr_wn(str, jsstr_length(src)), flags); + hres = alloc_regexp(ctx, NULL, ®exp); if(FAILED(hres)) return hres; diff --git a/dll/win32/jscript/jsstr.h b/dll/win32/jscript/jsstr.h index d9506861241..e55fef23584 100644 --- a/dll/win32/jscript/jsstr.h +++ b/dll/win32/jscript/jsstr.h @@ -102,7 +102,7 @@ jsstr_t *jsstr_alloc_buf(unsigned,WCHAR**) DECLSPEC_HIDDEN;
static inline jsstr_t *jsstr_alloc(const WCHAR *str) { - return jsstr_alloc_len(str, strlenW(str)); + return jsstr_alloc_len(str, lstrlenW(str)); }
void jsstr_free(jsstr_t*) DECLSPEC_HIDDEN; diff --git a/dll/win32/jscript/jsutils.c b/dll/win32/jscript/jsutils.c index b653e525d81..33a61c2d856 100644 --- a/dll/win32/jscript/jsutils.c +++ b/dll/win32/jscript/jsutils.c @@ -16,8 +16,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
-#include "config.h" -#include "wine/port.h" +#ifdef __REACTOS__ +#include <wine/config.h> +#include <wine/port.h> +#endif
#include <math.h> #include <assert.h> @@ -294,6 +296,12 @@ HRESULT variant_to_jsval(VARIANT *var, jsval_t *r) *r = jsval_disp(V_DISPATCH(var)); return S_OK; } + case VT_I1: + *r = jsval_number(V_I1(var)); + return S_OK; + case VT_UI1: + *r = jsval_number(V_UI1(var)); + return S_OK; case VT_I2: *r = jsval_number(V_I2(var)); return S_OK; @@ -516,7 +524,7 @@ static HRESULT str_to_number(jsstr_t *str, double *ret) if(!ptr) return E_OUTOFMEMORY;
- while(isspaceW(*ptr)) + while(iswspace(*ptr)) ptr++;
if(*ptr == '-') { @@ -526,9 +534,9 @@ static HRESULT str_to_number(jsstr_t *str, double *ret) ptr++; }
- if(!strncmpW(ptr, infinityW, ARRAY_SIZE(infinityW))) { + if(!wcsncmp(ptr, infinityW, ARRAY_SIZE(infinityW))) { ptr += ARRAY_SIZE(infinityW); - while(*ptr && isspaceW(*ptr)) + while(*ptr && iswspace(*ptr)) ptr++;
if(*ptr) @@ -551,7 +559,7 @@ static HRESULT str_to_number(jsstr_t *str, double *ret) return S_OK; }
- while(isdigitW(*ptr)) + while(iswdigit(*ptr)) d = d*10 + (*ptr++ - '0');
if(*ptr == 'e' || *ptr == 'E') { @@ -566,7 +574,7 @@ static HRESULT str_to_number(jsstr_t *str, double *ret) ptr++; }
- while(isdigitW(*ptr)) + while(iswdigit(*ptr)) l = l*10 + (*ptr++ - '0'); if(eneg) l = -l; @@ -576,13 +584,13 @@ static HRESULT str_to_number(jsstr_t *str, double *ret) DOUBLE dec = 0.1;
ptr++; - while(isdigitW(*ptr)) { + while(iswdigit(*ptr)) { d += dec * (*ptr++ - '0'); dec *= 0.1; } }
- while(isspaceW(*ptr)) + while(iswspace(*ptr)) ptr++;
if(*ptr) { @@ -894,6 +902,14 @@ HRESULT variant_change_type(script_ctx_t *ctx, VARIANT *dst, VARIANT *src, VARTY } break; } + case VT_UI2: { + UINT32 i; + + hres = to_uint32(ctx, val, &i); + if(SUCCEEDED(hres)) + V_UI2(dst) = i; + break; + } case VT_R8: { double n; hres = to_number(ctx, val, &n); diff --git a/dll/win32/jscript/lex.c b/dll/win32/jscript/lex.c index cbaebdbfa52..4f0ea45362e 100644 --- a/dll/win32/jscript/lex.c +++ b/dll/win32/jscript/lex.c @@ -16,10 +16,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
-#include "config.h" -#include "wine/port.h"
#include <limits.h> +#include <math.h>
#include "jscript.h" #include "activscp.h" @@ -30,86 +29,45 @@ #include "parser.tab.h"
#include "wine/debug.h" -#include "wine/unicode.h" - -#ifdef __REACTOS__ -/* FIXME: Inspect - For some reason these exist in the generated header but are not picked up */ -#define kGET (270) -#define kSET (272) -#endif
WINE_DEFAULT_DEBUG_CHANNEL(jscript);
-static const WCHAR breakW[] = {'b','r','e','a','k',0}; -static const WCHAR caseW[] = {'c','a','s','e',0}; -static const WCHAR catchW[] = {'c','a','t','c','h',0}; -static const WCHAR continueW[] = {'c','o','n','t','i','n','u','e',0}; -static const WCHAR defaultW[] = {'d','e','f','a','u','l','t',0}; -static const WCHAR deleteW[] = {'d','e','l','e','t','e',0}; -static const WCHAR doW[] = {'d','o',0}; -static const WCHAR elseW[] = {'e','l','s','e',0}; -static const WCHAR falseW[] = {'f','a','l','s','e',0}; -static const WCHAR finallyW[] = {'f','i','n','a','l','l','y',0}; -static const WCHAR forW[] = {'f','o','r',0}; -static const WCHAR functionW[] = {'f','u','n','c','t','i','o','n',0}; -static const WCHAR getW[] = {'g','e','t',0}; -static const WCHAR ifW[] = {'i','f',0}; -static const WCHAR inW[] = {'i','n',0}; -static const WCHAR instanceofW[] = {'i','n','s','t','a','n','c','e','o','f',0}; -static const WCHAR newW[] = {'n','e','w',0}; -static const WCHAR nullW[] = {'n','u','l','l',0}; -static const WCHAR returnW[] = {'r','e','t','u','r','n',0}; -static const WCHAR setW[] = {'s','e','t',0}; -static const WCHAR switchW[] = {'s','w','i','t','c','h',0}; -static const WCHAR thisW[] = {'t','h','i','s',0}; -static const WCHAR throwW[] = {'t','h','r','o','w',0}; -static const WCHAR trueW[] = {'t','r','u','e',0}; -static const WCHAR tryW[] = {'t','r','y',0}; -static const WCHAR typeofW[] = {'t','y','p','e','o','f',0}; -static const WCHAR varW[] = {'v','a','r',0}; -static const WCHAR voidW[] = {'v','o','i','d',0}; -static const WCHAR whileW[] = {'w','h','i','l','e',0}; -static const WCHAR withW[] = {'w','i','t','h',0}; - -static const WCHAR elifW[] = {'e','l','i','f',0}; -static const WCHAR endW[] = {'e','n','d',0}; - static const struct { const WCHAR *word; int token; BOOL no_nl; unsigned min_version; } keywords[] = { - {breakW, kBREAK, TRUE}, - {caseW, kCASE}, - {catchW, kCATCH}, - {continueW, kCONTINUE, TRUE}, - {defaultW, kDEFAULT}, - {deleteW, kDELETE}, - {doW, kDO}, - {elseW, kELSE}, - {falseW, kFALSE}, - {finallyW, kFINALLY}, - {forW, kFOR}, - {functionW, kFUNCTION}, - {getW, kGET, FALSE, SCRIPTLANGUAGEVERSION_ES5}, - {ifW, kIF}, - {inW, kIN}, - {instanceofW, kINSTANCEOF}, - {newW, kNEW}, - {nullW, kNULL}, - {returnW, kRETURN, TRUE}, - {setW, kSET, FALSE, SCRIPTLANGUAGEVERSION_ES5}, - {switchW, kSWITCH}, - {thisW, kTHIS}, - {throwW, kTHROW}, - {trueW, kTRUE}, - {tryW, kTRY}, - {typeofW, kTYPEOF}, - {varW, kVAR}, - {voidW, kVOID}, - {whileW, kWHILE}, - {withW, kWITH} + {L"break", kBREAK, TRUE}, + {L"case", kCASE}, + {L"catch", kCATCH}, + {L"continue", kCONTINUE, TRUE}, + {L"default", kDEFAULT}, + {L"delete", kDELETE}, + {L"do", kDO}, + {L"else", kELSE}, + {L"false", kFALSE}, + {L"finally", kFINALLY}, + {L"for", kFOR}, + {L"function", kFUNCTION}, + {L"get", kGET, FALSE, SCRIPTLANGUAGEVERSION_ES5}, + {L"if", kIF}, + {L"in", kIN}, + {L"instanceof", kINSTANCEOF}, + {L"new", kNEW}, + {L"null", kNULL}, + {L"return", kRETURN, TRUE}, + {L"set", kSET, FALSE, SCRIPTLANGUAGEVERSION_ES5}, + {L"switch", kSWITCH}, + {L"this", kTHIS}, + {L"throw", kTHROW}, + {L"true", kTRUE}, + {L"try", kTRY}, + {L"typeof", kTYPEOF}, + {L"var", kVAR}, + {L"void", kVOID}, + {L"while", kWHILE}, + {L"with", kWITH} };
static int lex_error(parser_ctx_t *ctx, HRESULT hres) @@ -122,12 +80,12 @@ static int lex_error(parser_ctx_t *ctx, HRESULT hres) /* ECMA-262 3rd Edition 7.6 */ BOOL is_identifier_char(WCHAR c) { - return isalnumW(c) || c == '$' || c == '_' || c == '\'; + return iswalnum(c) || c == '$' || c == '_' || c == '\'; }
static BOOL is_identifier_first_char(WCHAR c) { - return isalphaW(c) || c == '$' || c == '_' || c == '\'; + return iswalpha(c) || c == '$' || c == '_' || c == '\'; }
static int check_keyword(parser_ctx_t *ctx, const WCHAR *word, const WCHAR **lval) @@ -183,7 +141,7 @@ static int check_keywords(parser_ctx_t *ctx, const WCHAR **lval) if(ctx->script->version < keywords[i].min_version) { TRACE("ignoring keyword %s in incompatible mode\n", debugstr_w(keywords[i].word)); - ctx->ptr -= strlenW(keywords[i].word); + ctx->ptr -= lstrlenW(keywords[i].word); return 0; } ctx->implicit_nl_semicolon = keywords[i].no_nl; @@ -258,7 +216,7 @@ static BOOL skip_comment(parser_ctx_t *ctx)
static BOOL skip_spaces(parser_ctx_t *ctx) { - while(ctx->ptr < ctx->end && (isspaceW(*ctx->ptr) || *ctx->ptr == 0xFEFF /* UTF16 BOM */)) { + while(ctx->ptr < ctx->end && (iswspace(*ctx->ptr) || *ctx->ptr == 0xFEFF /* UTF16 BOM */)) { if(is_endline(*ctx->ptr++)) ctx->nl = TRUE; } @@ -266,19 +224,20 @@ static BOOL skip_spaces(parser_ctx_t *ctx) return ctx->ptr != ctx->end; }
-BOOL unescape(WCHAR *str) +BOOL unescape(WCHAR *str, size_t *len) { - WCHAR *pd, *p, c; + WCHAR *pd, *p, c, *end = str + *len; int i;
pd = p = str; - while(*p) { + while(p < end) { if(*p != '\') { *pd++ = *p++; continue; }
- p++; + if(++p == end) + return FALSE;
switch(*p) { case ''': @@ -302,6 +261,8 @@ BOOL unescape(WCHAR *str) c = '\r'; break; case 'x': + if(p + 2 >= end) + return FALSE; i = hex_to_int(*++p); if(i == -1) return FALSE; @@ -313,6 +274,8 @@ BOOL unescape(WCHAR *str) c += i; break; case 'u': + if(p + 4 >= end) + return FALSE; i = hex_to_int(*++p); if(i == -1) return FALSE; @@ -334,11 +297,11 @@ BOOL unescape(WCHAR *str) c += i; break; default: - if(isdigitW(*p)) { + if(iswdigit(*p)) { c = *p++ - '0'; - if(isdigitW(*p)) { + if(p < end && iswdigit(*p)) { c = c*8 + (*p++ - '0'); - if(isdigitW(*p)) + if(p < end && iswdigit(*p)) c = c*8 + (*p++ - '0'); } p--; @@ -351,7 +314,7 @@ BOOL unescape(WCHAR *str) p++; }
- *pd = 0; + *len = pd - str; return TRUE; }
@@ -374,33 +337,41 @@ static int parse_identifier(parser_ctx_t *ctx, const WCHAR **ret) return tIdentifier; }
-static int parse_string_literal(parser_ctx_t *ctx, const WCHAR **ret, WCHAR endch) +static int parse_string_literal(parser_ctx_t *ctx, jsstr_t **ret, WCHAR endch) { - const WCHAR *ptr = ++ctx->ptr; - WCHAR *wstr; - int len; + const WCHAR *ptr = ++ctx->ptr, *ret_str = ptr; + BOOL needs_unescape = FALSE; + WCHAR *unescape_str; + size_t len;
while(ctx->ptr < ctx->end && *ctx->ptr != endch) { - if(*ctx->ptr++ == '\') + if(*ctx->ptr++ == '\') { ctx->ptr++; + needs_unescape = TRUE; + } }
if(ctx->ptr == ctx->end) return lex_error(ctx, JS_E_UNTERMINATED_STRING);
- len = ctx->ptr-ptr; - - *ret = wstr = parser_alloc(ctx, (len+1)*sizeof(WCHAR)); - memcpy(wstr, ptr, len*sizeof(WCHAR)); - wstr[len] = 0; - + len = ctx->ptr - ptr; ctx->ptr++;
- if(!unescape(wstr)) { - WARN("unescape failed\n"); - return lex_error(ctx, E_FAIL); + if(needs_unescape) { + ret_str = unescape_str = parser_alloc(ctx, len * sizeof(WCHAR)); + if(!unescape_str) + return lex_error(ctx, E_OUTOFMEMORY); + memcpy(unescape_str, ptr, len * sizeof(WCHAR)); + if(!unescape(unescape_str, &len)) { + WARN("unescape failed\n"); + return lex_error(ctx, E_FAIL); + } }
+ if(!(*ret = compiler_alloc_string_len(ctx->compiler, ret_str, len))) + return lex_error(ctx, E_OUTOFMEMORY); + + /* FIXME: leaking string */ return tStringLiteral; }
@@ -429,7 +400,7 @@ HRESULT parse_decimal(const WCHAR **iter, const WCHAR *end, double *ret) LONGLONG d = 0, hlp; int exp = 0;
- while(ptr < end && isdigitW(*ptr)) { + while(ptr < end && iswdigit(*ptr)) { hlp = d*10 + *(ptr++) - '0'; if(d>MAXLONGLONG/10 || hlp<0) { exp++; @@ -438,7 +409,7 @@ HRESULT parse_decimal(const WCHAR **iter, const WCHAR *end, double *ret) else d = hlp; } - while(ptr < end && isdigitW(*ptr)) { + while(ptr < end && iswdigit(*ptr)) { exp++; ptr++; } @@ -446,7 +417,7 @@ HRESULT parse_decimal(const WCHAR **iter, const WCHAR *end, double *ret) if(*ptr == '.') { ptr++;
- while(ptr < end && isdigitW(*ptr)) { + while(ptr < end && iswdigit(*ptr)) { hlp = d*10 + *(ptr++) - '0'; if(d>MAXLONGLONG/10 || hlp<0) break; @@ -454,7 +425,7 @@ HRESULT parse_decimal(const WCHAR **iter, const WCHAR *end, double *ret) d = hlp; exp--; } - while(ptr < end && isdigitW(*ptr)) + while(ptr < end && iswdigit(*ptr)) ptr++; }
@@ -467,7 +438,7 @@ HRESULT parse_decimal(const WCHAR **iter, const WCHAR *end, double *ret) }else if(*ptr == '-') { sign = -1; ptr++; - }else if(!isdigitW(*ptr)) { + }else if(!iswdigit(*ptr)) { WARN("Expected exponent part\n"); return E_FAIL; } @@ -478,7 +449,7 @@ HRESULT parse_decimal(const WCHAR **iter, const WCHAR *end, double *ret) return E_FAIL; }
- while(ptr < end && isdigitW(*ptr)) { + while(ptr < end && iswdigit(*ptr)) { if(e > INT_MAX/10 || (e = e*10 + *ptr++ - '0')<0) e = INT_MAX; } @@ -529,12 +500,12 @@ static BOOL parse_numeric_literal(parser_ctx_t *ctx, double *ret) return TRUE; }
- if(isdigitW(*ctx->ptr)) { + if(iswdigit(*ctx->ptr)) { unsigned base = 8; const WCHAR *ptr; double val = 0;
- for(ptr = ctx->ptr; ptr < ctx->end && isdigitW(*ptr); ptr++) { + for(ptr = ctx->ptr; ptr < ctx->end && iswdigit(*ptr); ptr++) { if(*ptr > '7') { base = 10; break; @@ -543,7 +514,7 @@ static BOOL parse_numeric_literal(parser_ctx_t *ctx, double *ret)
do { val = val*base + *ctx->ptr-'0'; - }while(++ctx->ptr < ctx->end && isdigitW(*ctx->ptr)); + }while(++ctx->ptr < ctx->end && iswdigit(*ctx->ptr));
/* FIXME: Do we need it here? */ if(ctx->ptr < ctx->end && (is_identifier_char(*ctx->ptr) || *ctx->ptr == '.')) { @@ -585,7 +556,7 @@ static int next_token(parser_ctx_t *ctx, void *lval) ctx->implicit_nl_semicolon = FALSE; }
- if(isalphaW(*ctx->ptr)) { + if(iswalpha(*ctx->ptr)) { int ret = check_keywords(ctx, lval); if(ret) return ret; @@ -593,7 +564,7 @@ static int next_token(parser_ctx_t *ctx, void *lval) return parse_identifier(ctx, lval); }
- if(isdigitW(*ctx->ptr)) { + if(iswdigit(*ctx->ptr)) { double n;
if(!parse_numeric_literal(ctx, &n)) @@ -620,7 +591,7 @@ static int next_token(parser_ctx_t *ctx, void *lval) return '}';
case '.': - if(ctx->ptr+1 < ctx->end && isdigitW(ctx->ptr[1])) { + if(ctx->ptr+1 < ctx->end && iswdigit(ctx->ptr[1])) { double n; HRESULT hres; hres = parse_decimal(&ctx->ptr, ctx->end, &n); @@ -860,7 +831,7 @@ static BOOL new_cc_var(cc_ctx_t *cc, const WCHAR *name, int len, ccval_t v) cc_var_t *new_v;
if(len == -1) - len = strlenW(name); + len = lstrlenW(name);
new_v = heap_alloc(sizeof(cc_var_t) + (len+1)*sizeof(WCHAR)); if(!new_v) @@ -890,14 +861,6 @@ static BOOL init_cc(parser_ctx_t *ctx) { cc_ctx_t *cc;
- static const WCHAR _win32W[] = {'_','w','i','n','3','2',0}; - static const WCHAR _win64W[] = {'_','w','i','n','6','4',0}; - static const WCHAR _x86W[] = {'_','x','8','6',0}; - static const WCHAR _amd64W[] = {'_','a','m','d','6','4',0}; - static const WCHAR _jscriptW[] = {'_','j','s','c','r','i','p','t',0}; - static const WCHAR _jscript_buildW[] = {'_','j','s','c','r','i','p','t','_','b','u','i','l','d',0}; - static const WCHAR _jscript_versionW[] = {'_','j','s','c','r','i','p','t','_','v','e','r','s','i','o','n',0}; - if(ctx->script->cc) return TRUE;
@@ -909,11 +872,11 @@ static BOOL init_cc(parser_ctx_t *ctx)
cc->vars = NULL;
- if(!new_cc_var(cc, _jscriptW, -1, ccval_bool(TRUE)) - || !new_cc_var(cc, sizeof(void*) == 8 ? _win64W : _win32W, -1, ccval_bool(TRUE)) - || !new_cc_var(cc, sizeof(void*) == 8 ? _amd64W : _x86W, -1, ccval_bool(TRUE)) - || !new_cc_var(cc, _jscript_versionW, -1, ccval_num(JSCRIPT_MAJOR_VERSION + (DOUBLE)JSCRIPT_MINOR_VERSION/10.0)) - || !new_cc_var(cc, _jscript_buildW, -1, ccval_num(JSCRIPT_BUILD_VERSION))) { + if(!new_cc_var(cc, L"_jscript", -1, ccval_bool(TRUE)) + || !new_cc_var(cc, sizeof(void*) == 8 ? L"_win64" : L"_win32", -1, ccval_bool(TRUE)) + || !new_cc_var(cc, sizeof(void*) == 8 ? L"_amd64" : L"_x86", -1, ccval_bool(TRUE)) + || !new_cc_var(cc, L"_jscript_version", -1, ccval_num(JSCRIPT_MAJOR_VERSION + (DOUBLE)JSCRIPT_MINOR_VERSION/10.0)) + || !new_cc_var(cc, L"_jscript_build", -1, ccval_num(JSCRIPT_BUILD_VERSION))) { release_cc(cc); lex_error(ctx, E_OUTOFMEMORY); return FALSE; @@ -946,7 +909,7 @@ int try_parse_ccval(parser_ctx_t *ctx, ccval_t *r) if(!skip_spaces(ctx)) return -1;
- if(isdigitW(*ctx->ptr)) { + if(iswdigit(*ctx->ptr)) { double n;
if(!parse_numeric_literal(ctx, &n)) @@ -969,12 +932,12 @@ int try_parse_ccval(parser_ctx_t *ctx, ccval_t *r) return 1; }
- if(!check_keyword(ctx, trueW, NULL)) { + if(!check_keyword(ctx, L"true", NULL)) { *r = ccval_bool(TRUE); return 1; }
- if(!check_keyword(ctx, falseW, NULL)) { + if(!check_keyword(ctx, L"false", NULL)) { *r = ccval_bool(FALSE); return 1; } @@ -988,20 +951,20 @@ static int skip_code(parser_ctx_t *ctx, BOOL exec_else) const WCHAR *ptr;
while(1) { - ptr = strchrW(ctx->ptr, '@'); + ptr = wcschr(ctx->ptr, '@'); if(!ptr) { WARN("No @end\n"); return lex_error(ctx, JS_E_EXPECTED_CCEND); } ctx->ptr = ptr+1;
- if(!check_keyword(ctx, endW, NULL)) { + if(!check_keyword(ctx, L"end", NULL)) { if(--if_depth) continue; return 0; }
- if(exec_else && !check_keyword(ctx, elifW, NULL)) { + if(exec_else && !check_keyword(ctx, L"elif", NULL)) { if(if_depth > 1) continue;
@@ -1019,7 +982,7 @@ static int skip_code(parser_ctx_t *ctx, BOOL exec_else) return 0; }
- if(exec_else && !check_keyword(ctx, elseW, NULL)) { + if(exec_else && !check_keyword(ctx, L"else", NULL)) { if(if_depth > 1) continue;
@@ -1028,7 +991,7 @@ static int skip_code(parser_ctx_t *ctx, BOOL exec_else) return 0; }
- if(!check_keyword(ctx, ifW, NULL)) { + if(!check_keyword(ctx, L"if", NULL)) { if_depth++; continue; } @@ -1042,15 +1005,12 @@ static int cc_token(parser_ctx_t *ctx, void *lval) unsigned id_len = 0; cc_var_t *var;
- static const WCHAR cc_onW[] = {'c','c','_','o','n',0}; - static const WCHAR setW[] = {'s','e','t',0}; - ctx->ptr++;
- if(!check_keyword(ctx, cc_onW, NULL)) + if(!check_keyword(ctx, L"cc_on", NULL)) return init_cc(ctx) ? 0 : -1;
- if(!check_keyword(ctx, setW, NULL)) { + if(!check_keyword(ctx, L"set", NULL)) { const WCHAR *ident; unsigned ident_len; cc_var_t *var; @@ -1084,7 +1044,7 @@ static int cc_token(parser_ctx_t *ctx, void *lval) return 0; }
- if(!check_keyword(ctx, ifW, NULL)) { + if(!check_keyword(ctx, L"if", NULL)) { if(!init_cc(ctx)) return -1;
@@ -1103,14 +1063,14 @@ static int cc_token(parser_ctx_t *ctx, void *lval) return skip_code(ctx, TRUE); }
- if(!check_keyword(ctx, elifW, NULL) || !check_keyword(ctx, elseW, NULL)) { + if(!check_keyword(ctx, L"elif", NULL) || !check_keyword(ctx, L"else", NULL)) { if(!ctx->cc_if_depth) return lex_error(ctx, JS_E_SYNTAX);
return skip_code(ctx, FALSE); }
- if(!check_keyword(ctx, endW, NULL)) { + if(!check_keyword(ctx, L"end", NULL)) { if(!ctx->cc_if_depth) return lex_error(ctx, JS_E_SYNTAX);
@@ -1193,7 +1153,7 @@ literal_t *parse_regexp(parser_ctx_t *ctx) re_len = ctx->ptr-re;
flags_ptr = ++ctx->ptr; - while(ctx->ptr < ctx->end && isalnumW(*ctx->ptr)) + while(ctx->ptr < ctx->end && iswalnum(*ctx->ptr)) ctx->ptr++;
hres = parse_regexp_flags(flags_ptr, ctx->ptr-flags_ptr, &flags); @@ -1202,8 +1162,7 @@ literal_t *parse_regexp(parser_ctx_t *ctx)
ret = parser_alloc(ctx, sizeof(literal_t)); ret->type = LT_REGEXP; - ret->u.regexp.str = re; - ret->u.regexp.str_len = re_len; + ret->u.regexp.str = compiler_alloc_string_len(ctx->compiler, re, re_len); ret->u.regexp.flags = flags; return ret; } diff --git a/dll/win32/jscript/math.c b/dll/win32/jscript/math.c index dc07a97758a..caceb6d94c7 100644 --- a/dll/win32/jscript/math.c +++ b/dll/win32/jscript/math.c @@ -17,8 +17,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
-#include "config.h" -#include "wine/port.h" +#ifdef __REACTOS__ +#include <wine/config.h> +#include <wine/port.h> +#endif
#include <math.h> #include <limits.h> diff --git a/dll/win32/jscript/number.c b/dll/win32/jscript/number.c index 3d9890b36ab..bf67dfa0415 100644 --- a/dll/win32/jscript/number.c +++ b/dll/win32/jscript/number.c @@ -332,7 +332,7 @@ static HRESULT Number_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, u ch = '-'; } else ch = '+'; - sprintfW(&buf[idx], formatW, ch, (int)log_radix); + swprintf(&buf[idx], formatW, ch, (int)log_radix); } } else buf[idx] = '\0'; diff --git a/dll/win32/jscript/object.c b/dll/win32/jscript/object.c index 6ba99db108b..206f12a1afc 100644 --- a/dll/win32/jscript/object.c +++ b/dll/win32/jscript/object.c @@ -32,8 +32,11 @@ static const WCHAR propertyIsEnumerableW[] = {'p','r','o','p','e','r','t','y','I','s','E','n','u','m','e','r','a','b','l','e',0}; static const WCHAR isPrototypeOfW[] = {'i','s','P','r','o','t','o','t','y','p','e','O','f',0};
+static const WCHAR createW[] = {'c','r','e','a','t','e',0}; static const WCHAR getOwnPropertyDescriptorW[] = {'g','e','t','O','w','n','P','r','o','p','e','r','t','y','D','e','s','c','r','i','p','t','o','r',0}; +static const WCHAR getPrototypeOfW[] = + {'g','e','t','P','r','o','t','o','t','y','p','e','O','f',0}; static const WCHAR definePropertyW[] = {'d','e','f','i','n','e','P','r','o','p','e','r','t','y',0};
static const WCHAR definePropertiesW[] = {'d','e','f','i','n','e','P','r','o','p','e','r','t','i','e','s',0}; @@ -86,11 +89,11 @@ static HRESULT Object_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, u jsstr_t *ret; WCHAR *ptr;
- ret = jsstr_alloc_buf(9+strlenW(str), &ptr); + ret = jsstr_alloc_buf(9+lstrlenW(str), &ptr); if(!ret) return E_OUTOFMEMORY;
- sprintfW(ptr, formatW, str); + swprintf(ptr, formatW, str); *r = jsval_string(ret); }
@@ -406,6 +409,57 @@ static HRESULT to_property_descriptor(script_ctx_t *ctx, jsdisp_t *attr_obj, pro return hres; }
+static HRESULT jsdisp_define_properties(script_ctx_t *ctx, jsdisp_t *obj, jsval_t list_val) +{ + DISPID id = DISPID_STARTENUM; + property_desc_t prop_desc; + IDispatch *list_disp; + jsdisp_t *list_obj, *desc_obj; + jsval_t desc_val; + BSTR name; + HRESULT hres; + + hres = to_object(ctx, list_val, &list_disp); + if(FAILED(hres)) + return hres; + + if(!(list_obj = to_jsdisp(list_disp))) { + FIXME("non-JS list obj\n"); + IDispatch_Release(list_disp); + return E_NOTIMPL; + } + + while(1) { + hres = jsdisp_next_prop(list_obj, id, TRUE, &id); + if(hres != S_OK) + break; + + hres = jsdisp_propget(list_obj, id, &desc_val); + if(FAILED(hres)) + break; + + if(!is_object_instance(desc_val) || !get_object(desc_val) || !(desc_obj = to_jsdisp(get_object(desc_val)))) { + jsval_release(desc_val); + break; + } + + hres = to_property_descriptor(ctx, desc_obj, &prop_desc); + jsdisp_release(desc_obj); + if(FAILED(hres)) + break; + + hres = IDispatchEx_GetMemberName(&list_obj->IDispatchEx_iface, id, &name); + if(SUCCEEDED(hres)) + hres = jsdisp_define_property(obj, name, &prop_desc); + release_property_descriptor(&prop_desc); + if(FAILED(hres)) + break; + } + + jsdisp_release(list_obj); + return FAILED(hres) ? hres : S_OK; +} + static HRESULT Object_defineProperty(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) { @@ -446,14 +500,28 @@ static HRESULT Object_defineProperty(script_ctx_t *ctx, vdisp_t *jsthis, WORD fl
hres = jsdisp_define_property(obj, name, &prop_desc); release_property_descriptor(&prop_desc); + if(SUCCEEDED(hres) && r) + *r = jsval_obj(jsdisp_addref(obj)); return hres; }
static HRESULT Object_defineProperties(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) { - FIXME("\n"); - return E_NOTIMPL; + jsdisp_t *obj; + HRESULT hres; + + if(argc < 1 || !is_object_instance(argv[0]) || !get_object(argv[0]) || !(obj = to_jsdisp(get_object(argv[0])))) { + FIXME("not an object\n"); + return E_NOTIMPL; + } + + TRACE("%p\n", obj); + + hres = jsdisp_define_properties(ctx, obj, argc >= 2 ? argv[1] : jsval_undefined()); + if(SUCCEEDED(hres) && r) + *r = jsval_obj(jsdisp_addref(obj)); + return hres; }
static HRESULT Object_getOwnPropertyDescriptor(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, @@ -519,10 +587,76 @@ static HRESULT Object_getOwnPropertyDescriptor(script_ctx_t *ctx, vdisp_t *jsthi return hres; }
+static HRESULT Object_create(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, + unsigned argc, jsval_t *argv, jsval_t *r) +{ + jsdisp_t *proto = NULL, *obj; + HRESULT hres; + + if(!argc || (!is_object_instance(argv[0]) && !is_null(argv[0]))) { + FIXME("Invalid arg\n"); + return E_INVALIDARG; + } + + TRACE("(%s)\n", debugstr_jsval(argv[0])); + + if(argc && is_object_instance(argv[0])) { + if(get_object(argv[0])) + proto = to_jsdisp(get_object(argv[0])); + if(!proto) { + FIXME("Non-JS prototype\n"); + return E_NOTIMPL; + } + }else if(!is_null(argv[0])) { + FIXME("Invalid arg %s\n", debugstr_jsval(argc ? argv[0] : jsval_undefined())); + return E_INVALIDARG; + } + + hres = create_dispex(ctx, NULL, proto, &obj); + if(FAILED(hres)) + return hres; + + if(argc >= 2 && !is_undefined(argv[1])) + hres = jsdisp_define_properties(ctx, obj, argv[1]); + + if(SUCCEEDED(hres) && r) + *r = jsval_obj(obj); + else + jsdisp_release(obj); + return hres; +} + +static HRESULT Object_getPrototypeOf(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, + unsigned argc, jsval_t *argv, jsval_t *r) +{ + jsdisp_t *obj; + + if(!argc || !is_object_instance(argv[0])) { + FIXME("invalid arguments\n"); + return E_NOTIMPL; + } + + TRACE("(%s)\n", debugstr_jsval(argv[1])); + + obj = to_jsdisp(get_object(argv[0])); + if(!obj) { + FIXME("Non-JS object\n"); + return E_NOTIMPL; + } + + if(r) + *r = obj->prototype + ? jsval_obj(jsdisp_addref(obj->prototype)) + : jsval_null(); + return S_OK; +} + static const builtin_prop_t ObjectConstr_props[] = { + {createW, Object_create, PROPF_ES5|PROPF_METHOD|2}, {definePropertiesW, Object_defineProperties, PROPF_ES5|PROPF_METHOD|2}, {definePropertyW, Object_defineProperty, PROPF_ES5|PROPF_METHOD|2}, - {getOwnPropertyDescriptorW, Object_getOwnPropertyDescriptor, PROPF_ES5|PROPF_METHOD|2} + {getOwnPropertyDescriptorW, Object_getOwnPropertyDescriptor, PROPF_ES5|PROPF_METHOD|2}, + {getPrototypeOfW, Object_getPrototypeOf, PROPF_ES5|PROPF_METHOD|1} };
static const builtin_info_t ObjectConstr_info = { diff --git a/dll/win32/jscript/parser.h b/dll/win32/jscript/parser.h index f19db5bd5e6..b7a9f72ae8f 100644 --- a/dll/win32/jscript/parser.h +++ b/dll/win32/jscript/parser.h @@ -36,6 +36,7 @@ typedef struct _parser_ctx_t { const WCHAR *ptr;
script_ctx_t *script; + struct _compiler_ctx_t *compiler; source_elements_t *source; BOOL nl; BOOL implicit_nl_semicolon; @@ -49,7 +50,7 @@ typedef struct _parser_ctx_t { heap_pool_t heap; } parser_ctx_t;
-HRESULT script_parse(script_ctx_t*,const WCHAR*,const WCHAR*,BOOL,parser_ctx_t**) DECLSPEC_HIDDEN; +HRESULT script_parse(script_ctx_t*,struct _compiler_ctx_t*,const WCHAR*,const WCHAR*,BOOL,parser_ctx_t**) DECLSPEC_HIDDEN; void parser_release(parser_ctx_t*) DECLSPEC_HIDDEN;
int parser_lex(void*,parser_ctx_t*) DECLSPEC_HIDDEN; @@ -65,7 +66,7 @@ static inline void *parser_alloc_tmp(parser_ctx_t *ctx, DWORD size) }
BOOL is_identifier_char(WCHAR) DECLSPEC_HIDDEN; -BOOL unescape(WCHAR*) DECLSPEC_HIDDEN; +BOOL unescape(WCHAR*,size_t*) DECLSPEC_HIDDEN; HRESULT parse_decimal(const WCHAR**,const WCHAR*,double*) DECLSPEC_HIDDEN;
typedef enum { @@ -80,11 +81,10 @@ typedef struct { literal_type_t type; union { double dval; - const WCHAR *wstr; + jsstr_t *str; BOOL bval; struct { - const WCHAR *str; - DWORD str_len; + jsstr_t *str; DWORD flags; } regexp; } u; @@ -401,3 +401,5 @@ static inline double get_ccnum(ccval_t v) { return v.is_num ? v.u.n : v.u.b; } + +jsstr_t *compiler_alloc_string_len(struct _compiler_ctx_t*,const WCHAR *,unsigned) DECLSPEC_HIDDEN; diff --git a/dll/win32/jscript/parser.tab.c b/dll/win32/jscript/parser.tab.c index 43d616134d5..246a38ce53c 100644 --- a/dll/win32/jscript/parser.tab.c +++ b/dll/win32/jscript/parser.tab.c @@ -1,8 +1,9 @@ -/* A Bison parser, made by GNU Bison 3.0. */ +/* A Bison parser, made by GNU Bison 3.4.1. */
/* Bison implementation for Yacc-like parsers in C
- Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. + Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2019 Free Software Foundation, + Inc.
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -40,11 +41,14 @@ define necessary library symbols; they are noted "INFRINGES ON USER NAME SPACE" below. */
+/* Undocumented macros, especially those whose name start with YY_, + are private implementation details. Do not rely on them. */ + /* Identify Bison output. */ #define YYBISON 1
/* Bison version. */ -#define YYBISON_VERSION "3.0" +#define YYBISON_VERSION "3.4.1"
/* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" @@ -67,8 +71,8 @@ #define yynerrs parser_nerrs
-/* Copy the first part of user declarations. */ -#line 19 "parser.y" /* yacc.c:339 */ +/* First part of user prologue. */ +#line 19 "parser.y"
#include "jscript.h" @@ -90,7 +94,7 @@ typedef struct _statement_list_t { statement_t *tail; } statement_list_t;
-static literal_t *new_string_literal(parser_ctx_t*,const WCHAR*); +static literal_t *new_string_literal(parser_ctx_t*,jsstr_t*); static literal_t *new_null_literal(parser_ctx_t*);
typedef struct _property_list_t { @@ -191,13 +195,17 @@ static source_elements_t *new_source_elements(parser_ctx_t*); static source_elements_t *source_elements_add_statement(source_elements_t*,statement_t*);
-#line 195 "parser.tab.c" /* yacc.c:339 */ +#line 199 "parser.tab.c"
-# ifndef YY_NULL -# if defined __cplusplus && 201103L <= __cplusplus -# define YY_NULL nullptr +# ifndef YY_NULLPTR +# if defined __cplusplus +# if 201103L <= __cplusplus +# define YY_NULLPTR nullptr +# else +# define YY_NULLPTR 0 +# endif # else -# define YY_NULL 0 +# define YY_NULLPTR ((void*)0) # endif # endif
@@ -209,8 +217,8 @@ static source_elements_t *source_elements_add_statement(source_elements_t*,state # define YYERROR_VERBOSE 0 #endif
-/* In a future release of Bison, this section will be replaced - by #include "parser.tab.h". */ +/* Use api.header.include to #include this header + instead of duplicating it here. */ #ifndef YY_PARSER_E_REACTOSSYNC_GCC_DLL_WIN32_JSCRIPT_PARSER_TAB_H_INCLUDED # define YY_PARSER_E_REACTOSSYNC_GCC_DLL_WIN32_JSCRIPT_PARSER_TAB_H_INCLUDED /* Debug traces. */ @@ -278,14 +286,13 @@ extern int parser_debug;
/* Value type. */ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -typedef union YYSTYPE YYSTYPE; union YYSTYPE { -#line 147 "parser.y" /* yacc.c:355 */ +#line 147 "parser.y"
int ival; const WCHAR *srcptr; - LPCWSTR wstr; + jsstr_t *str; literal_t *literal; struct _argument_list_t *argument_list; case_clausule_t *case_clausule; @@ -303,8 +310,10 @@ union YYSTYPE struct _variable_list_t *variable_list; variable_declaration_t *variable_declaration;
-#line 307 "parser.tab.c" /* yacc.c:355 */ +#line 314 "parser.tab.c" + }; +typedef union YYSTYPE YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 # define YYSTYPE_IS_DECLARED 1 #endif @@ -315,9 +324,7 @@ int parser_parse (parser_ctx_t *ctx);
#endif /* !YY_PARSER_E_REACTOSSYNC_GCC_DLL_WIN32_JSCRIPT_PARSER_TAB_H_INCLUDED */
-/* Copy the second part of user declarations. */
-#line 321 "parser.tab.c" /* yacc.c:358 */
#ifdef short # undef short @@ -338,13 +345,13 @@ typedef signed char yytype_int8; #ifdef YYTYPE_UINT16 typedef YYTYPE_UINT16 yytype_uint16; #else -typedef unsigned short int yytype_uint16; +typedef unsigned short yytype_uint16; #endif
#ifdef YYTYPE_INT16 typedef YYTYPE_INT16 yytype_int16; #else -typedef short int yytype_int16; +typedef short yytype_int16; #endif
#ifndef YYSIZE_T @@ -356,7 +363,7 @@ typedef short int yytype_int16; # include <stddef.h> /* INFRINGES ON USER NAME SPACE */ # define YYSIZE_T size_t # else -# define YYSIZE_T unsigned int +# define YYSIZE_T unsigned # endif #endif
@@ -374,14 +381,24 @@ typedef short int yytype_int16; # endif #endif
-#ifndef __attribute__ -/* This feature is available in gcc versions 2.5 and later. */ -# if (! defined __GNUC__ || __GNUC__ < 2 \ - || (__GNUC__ == 2 && __GNUC_MINOR__ < 5)) -# define __attribute__(Spec) /* empty */ +#ifndef YY_ATTRIBUTE +# if (defined __GNUC__ \ + && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \ + || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C +# define YY_ATTRIBUTE(Spec) __attribute__(Spec) +# else +# define YY_ATTRIBUTE(Spec) /* empty */ # endif #endif
+#ifndef YY_ATTRIBUTE_PURE +# define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__)) +#endif + +#ifndef YY_ATTRIBUTE_UNUSED +# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__)) +#endif + /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ # define YYUSE(E) ((void) (E)) @@ -389,7 +406,7 @@ typedef short int yytype_int16; # define YYUSE(E) /* empty */ #endif
-#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ +#if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ /* Suppress an incorrect diagnostic about yylval being uninitialized. */ # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ _Pragma ("GCC diagnostic push") \ @@ -409,6 +426,8 @@ typedef short int yytype_int16; #endif
+#define YY_ASSERT(E) ((void) (0 && (E))) + #if ! defined yyoverflow || YYERROR_VERBOSE
/* The parser invokes alloca or malloc; define the necessary symbols. */ @@ -551,16 +570,16 @@ union yyalloc /* YYNSTATES -- Number of states. */ #define YYNSTATES 454
-/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned - by yylex, with out-of-bounds checking. */ #define YYUNDEFTOK 2 #define YYMAXUTOK 304
+/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM + as returned by yylex, with out-of-bounds checking. */ #define YYTRANSLATE(YYX) \ - ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + ((unsigned) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM - as returned by yylex, without out-of-bounds checking. */ + as returned by yylex. */ static const yytype_uint8 yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -674,7 +693,7 @@ static const char *const yytname[] = "PropertyNameAndValueList", "PropertyDefinition", "GetterSetterMethod", "PropertyName", "Identifier_opt", "IdentifierName", "ReservedAsIdentifier", "Literal", "BooleanLiteral", "semicolon_opt", - "left_bracket", "right_bracket", "semicolon", YY_NULL + "left_bracket", "right_bracket", "semicolon", YY_NULLPTR }; #endif
@@ -1257,22 +1276,22 @@ static const yytype_uint8 yyr2[] =
#define YYRECOVERING() (!!yyerrstatus)
-#define YYBACKUP(Token, Value) \ -do \ - if (yychar == YYEMPTY) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - YYPOPSTACK (yylen); \ - yystate = *yyssp; \ - goto yybackup; \ - } \ - else \ - { \ - yyerror (ctx, YY_("syntax error: cannot back up")); \ - YYERROR; \ - } \ -while (0) +#define YYBACKUP(Token, Value) \ + do \ + if (yychar == YYEMPTY) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + YYPOPSTACK (yylen); \ + yystate = *yyssp; \ + goto yybackup; \ + } \ + else \ + { \ + yyerror (ctx, YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ + while (0)
/* Error token number */ #define YYTERROR 1 @@ -1312,38 +1331,38 @@ do { \ } while (0)
-/*----------------------------------------. -| Print this symbol's value on YYOUTPUT. | -`----------------------------------------*/ +/*-----------------------------------. +| Print this symbol's value on YYO. | +`-----------------------------------*/
static void -yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, parser_ctx_t *ctx) +yy_symbol_value_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep, parser_ctx_t *ctx) { - FILE *yyo = yyoutput; - YYUSE (yyo); + FILE *yyoutput = yyo; + YYUSE (yyoutput); YYUSE (ctx); if (!yyvaluep) return; # ifdef YYPRINT if (yytype < YYNTOKENS) - YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); + YYPRINT (yyo, yytoknum[yytype], *yyvaluep); # endif YYUSE (yytype); }
-/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ +/*---------------------------. +| Print this symbol on YYO. | +`---------------------------*/
static void -yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, parser_ctx_t *ctx) +yy_symbol_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep, parser_ctx_t *ctx) { - YYFPRINTF (yyoutput, "%s %s (", + YYFPRINTF (yyo, "%s %s (", yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]);
- yy_symbol_value_print (yyoutput, yytype, yyvaluep, ctx); - YYFPRINTF (yyoutput, ")"); + yy_symbol_value_print (yyo, yytype, yyvaluep, ctx); + YYFPRINTF (yyo, ")"); }
/*------------------------------------------------------------------. @@ -1377,7 +1396,7 @@ do { \ static void yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule, parser_ctx_t *ctx) { - unsigned long int yylno = yyrline[yyrule]; + unsigned long yylno = yyrline[yyrule]; int yynrhs = yyr2[yyrule]; int yyi; YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", @@ -1388,7 +1407,7 @@ yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule, parser_ctx_t * YYFPRINTF (stderr, " $%d = ", yyi + 1); yy_symbol_print (stderr, yystos[yyssp[yyi + 1 - yynrhs]], - &(yyvsp[(yyi + 1) - (yynrhs)]) + &yyvsp[(yyi + 1) - (yynrhs)] , ctx); YYFPRINTF (stderr, "\n"); } @@ -1492,7 +1511,10 @@ yytnamerr (char *yyres, const char *yystr) case '\': if (*++yyp != '\') goto do_not_strip_quotes; - /* Fall through. */ + else + goto append; + + append: default: if (yyres) yyres[yyn] = *yyp; @@ -1510,7 +1532,7 @@ yytnamerr (char *yyres, const char *yystr) if (! yyres) return yystrlen (yystr);
- return yystpcpy (yyres, yystr) - yyres; + return (YYSIZE_T) (yystpcpy (yyres, yystr) - yyres); } # endif
@@ -1526,11 +1548,11 @@ static int yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, yytype_int16 *yyssp, int yytoken) { - YYSIZE_T yysize0 = yytnamerr (YY_NULL, yytname[yytoken]); + YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]); YYSIZE_T yysize = yysize0; enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; /* Internationalized format string. */ - const char *yyformat = YY_NULL; + const char *yyformat = YY_NULLPTR; /* Arguments of yyformat. */ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; /* Number of reported tokens (one for the "unexpected", one per @@ -1587,11 +1609,11 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, } yyarg[yycount++] = yytname[yyx]; { - YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULL, yytname[yyx]); - if (! (yysize <= yysize1 - && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); + if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM) + yysize = yysize1; + else return 2; - yysize = yysize1; } } } @@ -1603,6 +1625,7 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, case N: \ yyformat = S; \ break + default: /* Avoid compiler warnings. */ YYCASE_(0, YY_("syntax error")); YYCASE_(1, YY_("syntax error, unexpected %s")); YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); @@ -1614,9 +1637,10 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
{ YYSIZE_T yysize1 = yysize + yystrlen (yyformat); - if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM) + yysize = yysize1; + else return 2; - yysize = yysize1; }
if (*yymsg_alloc < yysize) @@ -1747,23 +1771,33 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); yychar = YYEMPTY; /* Cause a token to be read. */ goto yysetstate;
+ /*------------------------------------------------------------. -| yynewstate -- Push a new state, which is found in yystate. | +| yynewstate -- push a new state, which is found in yystate. | `------------------------------------------------------------*/ - yynewstate: +yynewstate: /* In all cases, when you get here, the value and location stacks have just been pushed. So pushing a state here evens the stacks. */ yyssp++;
- yysetstate: - *yyssp = yystate; + +/*--------------------------------------------------------------------. +| yynewstate -- set current state (the top of the stack) to yystate. | +`--------------------------------------------------------------------*/ +yysetstate: + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + YY_ASSERT (0 <= yystate && yystate < YYNSTATES); + *yyssp = (yytype_int16) yystate;
if (yyss + yystacksize - 1 <= yyssp) +#if !defined yyoverflow && !defined YYSTACK_RELOCATE + goto yyexhaustedlab; +#else { /* Get the current used size of the three stacks, in elements. */ - YYSIZE_T yysize = yyssp - yyss + 1; + YYSIZE_T yysize = (YYSIZE_T) (yyssp - yyss + 1);
-#ifdef yyoverflow +# if defined yyoverflow { /* Give user a chance to reallocate the stack. Use copies of these so that the &'s don't force the real ones into @@ -1779,14 +1813,10 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); &yyss1, yysize * sizeof (*yyssp), &yyvs1, yysize * sizeof (*yyvsp), &yystacksize); - yyss = yyss1; yyvs = yyvs1; } -#else /* no yyoverflow */ -# ifndef YYSTACK_RELOCATE - goto yyexhaustedlab; -# else +# else /* defined YYSTACK_RELOCATE */ /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) goto yyexhaustedlab; @@ -1802,35 +1832,33 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); goto yyexhaustedlab; YYSTACK_RELOCATE (yyss_alloc, yyss); YYSTACK_RELOCATE (yyvs_alloc, yyvs); -# undef YYSTACK_RELOCATE +# undef YYSTACK_RELOCATE if (yyss1 != yyssa) YYSTACK_FREE (yyss1); } # endif -#endif /* no yyoverflow */
yyssp = yyss + yysize - 1; yyvsp = yyvs + yysize - 1;
YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long int) yystacksize)); + (unsigned long) yystacksize));
if (yyss + yystacksize - 1 <= yyssp) YYABORT; } - - YYDPRINTF ((stderr, "Entering state %d\n", yystate)); +#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */
if (yystate == YYFINAL) YYACCEPT;
goto yybackup;
+ /*-----------. | yybackup. | `-----------*/ yybackup: - /* Do appropriate processing given the current state. Read a lookahead token if we need one and don't already have one. */
@@ -1888,7 +1916,6 @@ yybackup: YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN *++yyvsp = yylval; YY_IGNORE_MAYBE_UNINITIALIZED_END - goto yynewstate;
@@ -1903,7 +1930,7 @@ yydefault:
/*-----------------------------. -| yyreduce -- Do a reduction. | +| yyreduce -- do a reduction. | `-----------------------------*/ yyreduce: /* yyn is the number of a rule to reduce with. */ @@ -1923,1160 +1950,1160 @@ yyreduce: YY_REDUCE_PRINT (yyn); switch (yyn) { - case 2: -#line 259 "parser.y" /* yacc.c:1646 */ + case 2: +#line 259 "parser.y" { program_parsed(ctx, (yyvsp[-2].source_elements)); } -#line 1930 "parser.tab.c" /* yacc.c:1646 */ +#line 1957 "parser.tab.c" break;
case 3: -#line 262 "parser.y" /* yacc.c:1646 */ +#line 262 "parser.y" {} -#line 1936 "parser.tab.c" /* yacc.c:1646 */ +#line 1963 "parser.tab.c" break;
case 4: -#line 263 "parser.y" /* yacc.c:1646 */ +#line 263 "parser.y" {} -#line 1942 "parser.tab.c" /* yacc.c:1646 */ +#line 1969 "parser.tab.c" break;
case 5: -#line 267 "parser.y" /* yacc.c:1646 */ +#line 267 "parser.y" { (yyval.source_elements) = new_source_elements(ctx); } -#line 1948 "parser.tab.c" /* yacc.c:1646 */ +#line 1975 "parser.tab.c" break;
case 6: -#line 269 "parser.y" /* yacc.c:1646 */ +#line 269 "parser.y" { (yyval.source_elements) = source_elements_add_statement((yyvsp[-1].source_elements), (yyvsp[0].statement)); } -#line 1954 "parser.tab.c" /* yacc.c:1646 */ +#line 1981 "parser.tab.c" break;
case 7: -#line 274 "parser.y" /* yacc.c:1646 */ +#line 274 "parser.y" { (yyval.expr) = new_function_expression(ctx, NULL, (yyvsp[-4].parameter_list), (yyvsp[-1].source_elements), NULL, (yyvsp[-6].srcptr), (yyvsp[0].srcptr)-(yyvsp[-6].srcptr)+1); } -#line 1960 "parser.tab.c" /* yacc.c:1646 */ +#line 1987 "parser.tab.c" break;
case 8: -#line 276 "parser.y" /* yacc.c:1646 */ +#line 276 "parser.y" { (yyval.expr) = new_function_expression(ctx, (yyvsp[-6].identifier), (yyvsp[-4].parameter_list), (yyvsp[-1].source_elements), NULL, (yyvsp[-7].srcptr), (yyvsp[0].srcptr)-(yyvsp[-7].srcptr)+1); } -#line 1966 "parser.tab.c" /* yacc.c:1646 */ +#line 1993 "parser.tab.c" break;
case 9: -#line 278 "parser.y" /* yacc.c:1646 */ +#line 278 "parser.y" { (yyval.expr) = new_function_expression(ctx, (yyvsp[-6].identifier), (yyvsp[-4].parameter_list), (yyvsp[-1].source_elements), (yyvsp[-8].identifier), (yyvsp[-9].srcptr), (yyvsp[0].srcptr)-(yyvsp[-9].srcptr)+1); } -#line 1972 "parser.tab.c" /* yacc.c:1646 */ +#line 1999 "parser.tab.c" break;
case 10: -#line 281 "parser.y" /* yacc.c:1646 */ +#line 281 "parser.y" { (yyval.srcptr) = ctx->ptr - 8; } -#line 1978 "parser.tab.c" /* yacc.c:1646 */ +#line 2005 "parser.tab.c" break;
case 11: -#line 285 "parser.y" /* yacc.c:1646 */ +#line 285 "parser.y" { (yyval.source_elements) = (yyvsp[0].source_elements); } -#line 1984 "parser.tab.c" /* yacc.c:1646 */ +#line 2011 "parser.tab.c" break;
case 12: -#line 289 "parser.y" /* yacc.c:1646 */ +#line 289 "parser.y" { (yyval.parameter_list) = new_parameter_list(ctx, (yyvsp[0].identifier)); } -#line 1990 "parser.tab.c" /* yacc.c:1646 */ +#line 2017 "parser.tab.c" break;
case 13: -#line 291 "parser.y" /* yacc.c:1646 */ +#line 291 "parser.y" { (yyval.parameter_list) = parameter_list_add(ctx, (yyvsp[-2].parameter_list), (yyvsp[0].identifier)); } -#line 1996 "parser.tab.c" /* yacc.c:1646 */ +#line 2023 "parser.tab.c" break;
case 14: -#line 295 "parser.y" /* yacc.c:1646 */ +#line 295 "parser.y" { (yyval.parameter_list) = NULL; } -#line 2002 "parser.tab.c" /* yacc.c:1646 */ +#line 2029 "parser.tab.c" break;
case 15: -#line 296 "parser.y" /* yacc.c:1646 */ +#line 296 "parser.y" { (yyval.parameter_list) = (yyvsp[0].parameter_list); } -#line 2008 "parser.tab.c" /* yacc.c:1646 */ +#line 2035 "parser.tab.c" break;
case 16: -#line 300 "parser.y" /* yacc.c:1646 */ +#line 300 "parser.y" { (yyval.statement) = (yyvsp[0].statement); } -#line 2014 "parser.tab.c" /* yacc.c:1646 */ +#line 2041 "parser.tab.c" break;
case 17: -#line 301 "parser.y" /* yacc.c:1646 */ +#line 301 "parser.y" { (yyval.statement) = (yyvsp[0].statement); } -#line 2020 "parser.tab.c" /* yacc.c:1646 */ +#line 2047 "parser.tab.c" break;
case 18: -#line 302 "parser.y" /* yacc.c:1646 */ +#line 302 "parser.y" { (yyval.statement) = (yyvsp[0].statement); } -#line 2026 "parser.tab.c" /* yacc.c:1646 */ +#line 2053 "parser.tab.c" break;
case 19: -#line 303 "parser.y" /* yacc.c:1646 */ +#line 303 "parser.y" { (yyval.statement) = new_expression_statement(ctx, (yyvsp[0].expr)); } -#line 2032 "parser.tab.c" /* yacc.c:1646 */ +#line 2059 "parser.tab.c" break;
case 20: -#line 304 "parser.y" /* yacc.c:1646 */ +#line 304 "parser.y" { (yyval.statement) = (yyvsp[0].statement); } -#line 2038 "parser.tab.c" /* yacc.c:1646 */ +#line 2065 "parser.tab.c" break;
case 21: -#line 305 "parser.y" /* yacc.c:1646 */ +#line 305 "parser.y" { (yyval.statement) = (yyvsp[0].statement); } -#line 2044 "parser.tab.c" /* yacc.c:1646 */ +#line 2071 "parser.tab.c" break;
case 22: -#line 306 "parser.y" /* yacc.c:1646 */ +#line 306 "parser.y" { (yyval.statement) = (yyvsp[0].statement); } -#line 2050 "parser.tab.c" /* yacc.c:1646 */ +#line 2077 "parser.tab.c" break;
case 23: -#line 307 "parser.y" /* yacc.c:1646 */ +#line 307 "parser.y" { (yyval.statement) = (yyvsp[0].statement); } -#line 2056 "parser.tab.c" /* yacc.c:1646 */ +#line 2083 "parser.tab.c" break;
case 24: -#line 308 "parser.y" /* yacc.c:1646 */ +#line 308 "parser.y" { (yyval.statement) = (yyvsp[0].statement); } -#line 2062 "parser.tab.c" /* yacc.c:1646 */ +#line 2089 "parser.tab.c" break;
case 25: -#line 309 "parser.y" /* yacc.c:1646 */ +#line 309 "parser.y" { (yyval.statement) = (yyvsp[0].statement); } -#line 2068 "parser.tab.c" /* yacc.c:1646 */ +#line 2095 "parser.tab.c" break;
case 26: -#line 310 "parser.y" /* yacc.c:1646 */ +#line 310 "parser.y" { (yyval.statement) = (yyvsp[0].statement); } -#line 2074 "parser.tab.c" /* yacc.c:1646 */ +#line 2101 "parser.tab.c" break;
case 27: -#line 311 "parser.y" /* yacc.c:1646 */ +#line 311 "parser.y" { (yyval.statement) = (yyvsp[0].statement); } -#line 2080 "parser.tab.c" /* yacc.c:1646 */ +#line 2107 "parser.tab.c" break;
case 28: -#line 312 "parser.y" /* yacc.c:1646 */ +#line 312 "parser.y" { (yyval.statement) = (yyvsp[0].statement); } -#line 2086 "parser.tab.c" /* yacc.c:1646 */ +#line 2113 "parser.tab.c" break;
case 29: -#line 313 "parser.y" /* yacc.c:1646 */ +#line 313 "parser.y" { (yyval.statement) = (yyvsp[0].statement); } -#line 2092 "parser.tab.c" /* yacc.c:1646 */ +#line 2119 "parser.tab.c" break;
case 30: -#line 314 "parser.y" /* yacc.c:1646 */ +#line 314 "parser.y" { (yyval.statement) = (yyvsp[0].statement); } -#line 2098 "parser.tab.c" /* yacc.c:1646 */ +#line 2125 "parser.tab.c" break;
case 31: -#line 318 "parser.y" /* yacc.c:1646 */ +#line 318 "parser.y" { (yyval.statement_list) = new_statement_list(ctx, (yyvsp[0].statement)); } -#line 2104 "parser.tab.c" /* yacc.c:1646 */ +#line 2131 "parser.tab.c" break;
case 32: -#line 320 "parser.y" /* yacc.c:1646 */ +#line 320 "parser.y" { (yyval.statement_list) = statement_list_add((yyvsp[-1].statement_list), (yyvsp[0].statement)); } -#line 2110 "parser.tab.c" /* yacc.c:1646 */ +#line 2137 "parser.tab.c" break;
case 33: -#line 324 "parser.y" /* yacc.c:1646 */ +#line 324 "parser.y" { (yyval.statement_list) = NULL; } -#line 2116 "parser.tab.c" /* yacc.c:1646 */ +#line 2143 "parser.tab.c" break;
case 34: -#line 325 "parser.y" /* yacc.c:1646 */ +#line 325 "parser.y" { (yyval.statement_list) = (yyvsp[0].statement_list); } -#line 2122 "parser.tab.c" /* yacc.c:1646 */ +#line 2149 "parser.tab.c" break;
case 35: -#line 329 "parser.y" /* yacc.c:1646 */ +#line 329 "parser.y" { (yyval.statement) = new_block_statement(ctx, (yyvsp[-1].statement_list)); } -#line 2128 "parser.tab.c" /* yacc.c:1646 */ +#line 2155 "parser.tab.c" break;
case 36: -#line 330 "parser.y" /* yacc.c:1646 */ +#line 330 "parser.y" { (yyval.statement) = new_block_statement(ctx, NULL); } -#line 2134 "parser.tab.c" /* yacc.c:1646 */ +#line 2161 "parser.tab.c" break;
case 37: -#line 335 "parser.y" /* yacc.c:1646 */ +#line 335 "parser.y" { (yyval.statement) = new_var_statement(ctx, (yyvsp[-1].variable_list)); } -#line 2140 "parser.tab.c" /* yacc.c:1646 */ +#line 2167 "parser.tab.c" break;
case 38: -#line 339 "parser.y" /* yacc.c:1646 */ +#line 339 "parser.y" { (yyval.variable_list) = new_variable_list(ctx, (yyvsp[0].variable_declaration)); } -#line 2146 "parser.tab.c" /* yacc.c:1646 */ +#line 2173 "parser.tab.c" break;
case 39: -#line 341 "parser.y" /* yacc.c:1646 */ +#line 341 "parser.y" { (yyval.variable_list) = variable_list_add(ctx, (yyvsp[-2].variable_list), (yyvsp[0].variable_declaration)); } -#line 2152 "parser.tab.c" /* yacc.c:1646 */ +#line 2179 "parser.tab.c" break;
case 40: -#line 346 "parser.y" /* yacc.c:1646 */ +#line 346 "parser.y" { (yyval.variable_list) = new_variable_list(ctx, (yyvsp[0].variable_declaration)); } -#line 2158 "parser.tab.c" /* yacc.c:1646 */ +#line 2185 "parser.tab.c" break;
case 41: -#line 348 "parser.y" /* yacc.c:1646 */ +#line 348 "parser.y" { (yyval.variable_list) = variable_list_add(ctx, (yyvsp[-2].variable_list), (yyvsp[0].variable_declaration)); } -#line 2164 "parser.tab.c" /* yacc.c:1646 */ +#line 2191 "parser.tab.c" break;
case 42: -#line 353 "parser.y" /* yacc.c:1646 */ +#line 353 "parser.y" { (yyval.variable_declaration) = new_variable_declaration(ctx, (yyvsp[-1].identifier), (yyvsp[0].expr)); } -#line 2170 "parser.tab.c" /* yacc.c:1646 */ +#line 2197 "parser.tab.c" break;
case 43: -#line 358 "parser.y" /* yacc.c:1646 */ +#line 358 "parser.y" { (yyval.variable_declaration) = new_variable_declaration(ctx, (yyvsp[-1].identifier), (yyvsp[0].expr)); } -#line 2176 "parser.tab.c" /* yacc.c:1646 */ +#line 2203 "parser.tab.c" break;
case 44: -#line 362 "parser.y" /* yacc.c:1646 */ +#line 362 "parser.y" { (yyval.expr) = NULL; } -#line 2182 "parser.tab.c" /* yacc.c:1646 */ +#line 2209 "parser.tab.c" break;
case 45: -#line 363 "parser.y" /* yacc.c:1646 */ +#line 363 "parser.y" { (yyval.expr) = (yyvsp[0].expr); } -#line 2188 "parser.tab.c" /* yacc.c:1646 */ +#line 2215 "parser.tab.c" break;
case 46: -#line 368 "parser.y" /* yacc.c:1646 */ +#line 368 "parser.y" { (yyval.expr) = (yyvsp[0].expr); } -#line 2194 "parser.tab.c" /* yacc.c:1646 */ +#line 2221 "parser.tab.c" break;
case 47: -#line 372 "parser.y" /* yacc.c:1646 */ +#line 372 "parser.y" { (yyval.expr) = NULL; } -#line 2200 "parser.tab.c" /* yacc.c:1646 */ +#line 2227 "parser.tab.c" break;
case 48: -#line 373 "parser.y" /* yacc.c:1646 */ +#line 373 "parser.y" { (yyval.expr) = (yyvsp[0].expr); } -#line 2206 "parser.tab.c" /* yacc.c:1646 */ +#line 2233 "parser.tab.c" break;
case 49: -#line 378 "parser.y" /* yacc.c:1646 */ +#line 378 "parser.y" { (yyval.expr) = (yyvsp[0].expr); } -#line 2212 "parser.tab.c" /* yacc.c:1646 */ +#line 2239 "parser.tab.c" break;
case 50: -#line 382 "parser.y" /* yacc.c:1646 */ +#line 382 "parser.y" { (yyval.statement) = new_statement(ctx, STAT_EMPTY, 0); } -#line 2218 "parser.tab.c" /* yacc.c:1646 */ +#line 2245 "parser.tab.c" break;
case 51: -#line 387 "parser.y" /* yacc.c:1646 */ +#line 387 "parser.y" { (yyval.statement) = new_expression_statement(ctx, (yyvsp[-1].expr)); } -#line 2224 "parser.tab.c" /* yacc.c:1646 */ +#line 2251 "parser.tab.c" break;
case 52: -#line 392 "parser.y" /* yacc.c:1646 */ +#line 392 "parser.y" { (yyval.statement) = new_if_statement(ctx, (yyvsp[-4].expr), (yyvsp[-2].statement), (yyvsp[0].statement)); } -#line 2230 "parser.tab.c" /* yacc.c:1646 */ +#line 2257 "parser.tab.c" break;
case 53: -#line 394 "parser.y" /* yacc.c:1646 */ +#line 394 "parser.y" { (yyval.statement) = new_if_statement(ctx, (yyvsp[-2].expr), (yyvsp[0].statement), NULL); } -#line 2236 "parser.tab.c" /* yacc.c:1646 */ +#line 2263 "parser.tab.c" break;
case 54: -#line 399 "parser.y" /* yacc.c:1646 */ +#line 399 "parser.y" { (yyval.statement) = new_while_statement(ctx, TRUE, (yyvsp[-2].expr), (yyvsp[-5].statement)); } -#line 2242 "parser.tab.c" /* yacc.c:1646 */ +#line 2269 "parser.tab.c" break;
case 55: -#line 401 "parser.y" /* yacc.c:1646 */ +#line 401 "parser.y" { (yyval.statement) = new_while_statement(ctx, FALSE, (yyvsp[-2].expr), (yyvsp[0].statement)); } -#line 2248 "parser.tab.c" /* yacc.c:1646 */ +#line 2275 "parser.tab.c" break;
case 56: -#line 403 "parser.y" /* yacc.c:1646 */ +#line 403 "parser.y" { if(!explicit_error(ctx, (yyvsp[0].expr), ';')) YYABORT; } -#line 2254 "parser.tab.c" /* yacc.c:1646 */ +#line 2281 "parser.tab.c" break;
case 57: -#line 405 "parser.y" /* yacc.c:1646 */ +#line 405 "parser.y" { if(!explicit_error(ctx, (yyvsp[0].expr), ';')) YYABORT; } -#line 2260 "parser.tab.c" /* yacc.c:1646 */ +#line 2287 "parser.tab.c" break;
case 58: -#line 407 "parser.y" /* yacc.c:1646 */ +#line 407 "parser.y" { (yyval.statement) = new_for_statement(ctx, NULL, (yyvsp[-8].expr), (yyvsp[-5].expr), (yyvsp[-2].expr), (yyvsp[0].statement)); } -#line 2266 "parser.tab.c" /* yacc.c:1646 */ +#line 2293 "parser.tab.c" break;
case 59: -#line 409 "parser.y" /* yacc.c:1646 */ +#line 409 "parser.y" { if(!explicit_error(ctx, (yyvsp[0].variable_list), ';')) YYABORT; } -#line 2272 "parser.tab.c" /* yacc.c:1646 */ +#line 2299 "parser.tab.c" break;
case 60: -#line 411 "parser.y" /* yacc.c:1646 */ +#line 411 "parser.y" { if(!explicit_error(ctx, (yyvsp[0].expr), ';')) YYABORT; } -#line 2278 "parser.tab.c" /* yacc.c:1646 */ +#line 2305 "parser.tab.c" break;
case 61: -#line 413 "parser.y" /* yacc.c:1646 */ +#line 413 "parser.y" { (yyval.statement) = new_for_statement(ctx, (yyvsp[-8].variable_list), NULL, (yyvsp[-5].expr), (yyvsp[-2].expr), (yyvsp[0].statement)); } -#line 2284 "parser.tab.c" /* yacc.c:1646 */ +#line 2311 "parser.tab.c" break;
case 62: -#line 415 "parser.y" /* yacc.c:1646 */ +#line 415 "parser.y" { (yyval.statement) = new_forin_statement(ctx, NULL, (yyvsp[-4].expr), (yyvsp[-2].expr), (yyvsp[0].statement)); } -#line 2290 "parser.tab.c" /* yacc.c:1646 */ +#line 2317 "parser.tab.c" break;
case 63: -#line 417 "parser.y" /* yacc.c:1646 */ +#line 417 "parser.y" { (yyval.statement) = new_forin_statement(ctx, (yyvsp[-4].variable_declaration), NULL, (yyvsp[-2].expr), (yyvsp[0].statement)); } -#line 2296 "parser.tab.c" /* yacc.c:1646 */ +#line 2323 "parser.tab.c" ... 2116 lines suppressed ...