[JSCRIPT] Sync with Wine Staging 4.18. CORE-16441

This commit is contained in:
Amine Khaldi 2019-11-02 18:38:06 +01:00
parent da0cd273de
commit 3e2d6582b7
31 changed files with 1860 additions and 1411 deletions

View file

@ -16,8 +16,6 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
#include "config.h"
#include "wine/port.h"
#include "jscript.h" #include "jscript.h"
#include "objsafe.h" #include "objsafe.h"

View file

@ -16,8 +16,10 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
#include "config.h" #ifdef __REACTOS__
#include "wine/port.h" #include <wine/config.h>
#include <wine/port.h>
#endif
#include <math.h> #include <math.h>
#include <assert.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 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 unshiftW[] = {'u','n','s','h','i','f','t',0};
static const WCHAR indexOfW[] = {'i','n','d','e','x','O','f',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}; 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); jsstr_release(sep_str);
}else { }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; 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 throw_type_error(ctx, JS_E_ARRAY_EXPECTED, NULL);
return array_join(ctx, &array->dispex, array->length, default_separatorW, 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, 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"); 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); hres = get_length(ctx, vthis, &jsthis, &length);
if(FAILED(hres)) if(FAILED(hres))
return 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++) { for(i = 0; i < length; i++) {
hres = jsdisp_get_idx(jsthis, i, &value); hres = jsdisp_get_idx(jsthis, i, &value);
if(hres == DISP_E_UNKNOWNNAME) 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; 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 */ /* 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, static HRESULT Array_unshift(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigned argc, jsval_t *argv,
jsval_t *r) jsval_t *r)
@ -1114,7 +1184,7 @@ static HRESULT Array_get_value(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t *r)
TRACE("\n"); TRACE("\n");
return array_join(ctx, &array->dispex, array->length, default_separatorW, 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) 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; const WCHAR *ptr = name;
DWORD id = 0; DWORD id = 0;
if(!isdigitW(*ptr)) if(!iswdigit(*ptr))
return; return;
while(*ptr && isdigitW(*ptr)) { while(*ptr && iswdigit(*ptr)) {
id = id*10 + (*ptr-'0'); id = id*10 + (*ptr-'0');
ptr++; ptr++;
} }
@ -1149,6 +1219,7 @@ static const builtin_prop_t Array_props[] = {
{indexOfW, Array_indexOf, PROPF_METHOD|PROPF_ES5|1}, {indexOfW, Array_indexOf, PROPF_METHOD|PROPF_ES5|1},
{joinW, Array_join, PROPF_METHOD|1}, {joinW, Array_join, PROPF_METHOD|1},
{lengthW, NULL,0, Array_get_length, Array_set_length}, {lengthW, NULL,0, Array_get_length, Array_set_length},
{mapW, Array_map, PROPF_METHOD|PROPF_ES5|1},
{popW, Array_pop, PROPF_METHOD}, {popW, Array_pop, PROPF_METHOD},
{pushW, Array_push, PROPF_METHOD|1}, {pushW, Array_push, PROPF_METHOD|1},
{reverseW, Array_reverse, PROPF_METHOD}, {reverseW, Array_reverse, PROPF_METHOD},

View file

@ -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 /* 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 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 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 define necessary library symbols; they are noted "INFRINGES ON
USER NAME SPACE" below. */ 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. */ /* Identify Bison output. */
#define YYBISON 1 #define YYBISON 1
/* Bison version. */ /* Bison version. */
#define YYBISON_VERSION "3.0" #define YYBISON_VERSION "3.4.1"
/* Skeleton name. */ /* Skeleton name. */
#define YYSKELETON_NAME "yacc.c" #define YYSKELETON_NAME "yacc.c"
@ -67,8 +71,8 @@
#define yynerrs cc_parser_nerrs #define yynerrs cc_parser_nerrs
/* Copy the first part of user declarations. */ /* First part of user prologue. */
#line 19 "cc_parser.y" /* yacc.c:339 */ #line 19 "cc_parser.y"
#include "jscript.h" #include "jscript.h"
@ -80,13 +84,17 @@
WINE_DEFAULT_DEBUG_CHANNEL(jscript); WINE_DEFAULT_DEBUG_CHANNEL(jscript);
#line 84 "cc_parser.tab.c" /* yacc.c:339 */ #line 88 "cc_parser.tab.c"
# ifndef YY_NULL # ifndef YY_NULLPTR
# if defined __cplusplus && 201103L <= __cplusplus # if defined __cplusplus
# define YY_NULL nullptr # if 201103L <= __cplusplus
# define YY_NULLPTR nullptr
# else
# define YY_NULLPTR 0
# endif
# else # else
# define YY_NULL 0 # define YY_NULLPTR ((void*)0)
# endif # endif
# endif # endif
@ -98,8 +106,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(jscript);
# define YYERROR_VERBOSE 0 # define YYERROR_VERBOSE 0
#endif #endif
/* In a future release of Bison, this section will be replaced /* Use api.header.include to #include this header
by #include "cc_parser.tab.h". */ instead of duplicating it here. */
#ifndef YY_CC_PARSER_E_REACTOSSYNC_GCC_DLL_WIN32_JSCRIPT_CC_PARSER_TAB_H_INCLUDED #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 # define YY_CC_PARSER_E_REACTOSSYNC_GCC_DLL_WIN32_JSCRIPT_CC_PARSER_TAB_H_INCLUDED
/* Debug traces. */ /* Debug traces. */
@ -132,15 +140,16 @@ extern int cc_parser_debug;
/* Value type. */ /* Value type. */
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE YYSTYPE;
union YYSTYPE union YYSTYPE
{ {
#line 36 "cc_parser.y" /* yacc.c:355 */ #line 36 "cc_parser.y"
ccval_t ccval; 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_TRIVIAL 1
# define YYSTYPE_IS_DECLARED 1 # define YYSTYPE_IS_DECLARED 1
#endif #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 */ #endif /* !YY_CC_PARSER_E_REACTOSSYNC_GCC_DLL_WIN32_JSCRIPT_CC_PARSER_TAB_H_INCLUDED */
/* Copy the second part of user declarations. */ /* Second part of user prologue. */
#line 47 "cc_parser.y" /* yacc.c:358 */ #line 47 "cc_parser.y"
static int cc_parser_error(parser_ctx_t *ctx, const char *str) 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 #ifdef short
# undef short # undef short
@ -267,13 +277,13 @@ typedef signed char yytype_int8;
#ifdef YYTYPE_UINT16 #ifdef YYTYPE_UINT16
typedef YYTYPE_UINT16 yytype_uint16; typedef YYTYPE_UINT16 yytype_uint16;
#else #else
typedef unsigned short int yytype_uint16; typedef unsigned short yytype_uint16;
#endif #endif
#ifdef YYTYPE_INT16 #ifdef YYTYPE_INT16
typedef YYTYPE_INT16 yytype_int16; typedef YYTYPE_INT16 yytype_int16;
#else #else
typedef short int yytype_int16; typedef short yytype_int16;
#endif #endif
#ifndef YYSIZE_T #ifndef YYSIZE_T
@ -285,7 +295,7 @@ typedef short int yytype_int16;
# include <stddef.h> /* INFRINGES ON USER NAME SPACE */ # include <stddef.h> /* INFRINGES ON USER NAME SPACE */
# define YYSIZE_T size_t # define YYSIZE_T size_t
# else # else
# define YYSIZE_T unsigned int # define YYSIZE_T unsigned
# endif # endif
#endif #endif
@ -303,14 +313,24 @@ typedef short int yytype_int16;
# endif # endif
#endif #endif
#ifndef __attribute__ #ifndef YY_ATTRIBUTE
/* This feature is available in gcc versions 2.5 and later. */ # if (defined __GNUC__ \
# if (! defined __GNUC__ || __GNUC__ < 2 \ && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \
|| (__GNUC__ == 2 && __GNUC_MINOR__ < 5)) || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C
# define __attribute__(Spec) /* empty */ # define YY_ATTRIBUTE(Spec) __attribute__(Spec)
# else
# define YY_ATTRIBUTE(Spec) /* empty */
# endif # endif
#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. */ /* Suppress unused-variable warnings by "using" E. */
#if ! defined lint || defined __GNUC__ #if ! defined lint || defined __GNUC__
# define YYUSE(E) ((void) (E)) # define YYUSE(E) ((void) (E))
@ -318,7 +338,7 @@ typedef short int yytype_int16;
# define YYUSE(E) /* empty */ # define YYUSE(E) /* empty */
#endif #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. */ /* Suppress an incorrect diagnostic about yylval being uninitialized. */
# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
_Pragma ("GCC diagnostic push") \ _Pragma ("GCC diagnostic push") \
@ -338,6 +358,8 @@ typedef short int yytype_int16;
#endif #endif
#define YY_ASSERT(E) ((void) (0 && (E)))
#if ! defined yyoverflow || YYERROR_VERBOSE #if ! defined yyoverflow || YYERROR_VERBOSE
/* The parser invokes alloca or malloc; define the necessary symbols. */ /* The parser invokes alloca or malloc; define the necessary symbols. */
@ -480,16 +502,16 @@ union yyalloc
/* YYNSTATES -- Number of states. */ /* YYNSTATES -- Number of states. */
#define YYNSTATES 69 #define YYNSTATES 69
/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
by yylex, with out-of-bounds checking. */
#define YYUNDEFTOK 2 #define YYUNDEFTOK 2
#define YYMAXUTOK 269 #define YYMAXUTOK 269
/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM
as returned by yylex, with out-of-bounds checking. */
#define YYTRANSLATE(YYX) \ #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 /* 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[] = static const yytype_uint8 yytranslate[] =
{ {
0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@ -545,7 +567,7 @@ static const char *const yytname[] =
"CCBitwiseORExpression", "CCBitwiseXORExpression", "CCBitwiseORExpression", "CCBitwiseXORExpression",
"CCBitwiseANDExpression", "CCEqualityExpression", "CCBitwiseANDExpression", "CCEqualityExpression",
"CCRelationalExpression", "CCShiftExpression", "CCAdditiveExpression", "CCRelationalExpression", "CCShiftExpression", "CCAdditiveExpression",
"CCMultiplicativeExpression", YY_NULL "CCMultiplicativeExpression", YY_NULLPTR
}; };
#endif #endif
@ -678,22 +700,22 @@ static const yytype_uint8 yyr2[] =
#define YYRECOVERING() (!!yyerrstatus) #define YYRECOVERING() (!!yyerrstatus)
#define YYBACKUP(Token, Value) \ #define YYBACKUP(Token, Value) \
do \ do \
if (yychar == YYEMPTY) \ if (yychar == YYEMPTY) \
{ \ { \
yychar = (Token); \ yychar = (Token); \
yylval = (Value); \ yylval = (Value); \
YYPOPSTACK (yylen); \ YYPOPSTACK (yylen); \
yystate = *yyssp; \ yystate = *yyssp; \
goto yybackup; \ goto yybackup; \
} \ } \
else \ else \
{ \ { \
yyerror (ctx, YY_("syntax error: cannot back up")); \ yyerror (ctx, YY_("syntax error: cannot back up")); \
YYERROR; \ YYERROR; \
} \ } \
while (0) while (0)
/* Error token number */ /* Error token number */
#define YYTERROR 1 #define YYTERROR 1
@ -733,38 +755,38 @@ do { \
} while (0) } while (0)
/*----------------------------------------. /*-----------------------------------.
| Print this symbol's value on YYOUTPUT. | | Print this symbol's value on YYO. |
`----------------------------------------*/ `-----------------------------------*/
static void 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; FILE *yyoutput = yyo;
YYUSE (yyo); YYUSE (yyoutput);
YYUSE (ctx); YYUSE (ctx);
if (!yyvaluep) if (!yyvaluep)
return; return;
# ifdef YYPRINT # ifdef YYPRINT
if (yytype < YYNTOKENS) if (yytype < YYNTOKENS)
YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); YYPRINT (yyo, yytoknum[yytype], *yyvaluep);
# endif # endif
YYUSE (yytype); YYUSE (yytype);
} }
/*--------------------------------. /*---------------------------.
| Print this symbol on YYOUTPUT. | | Print this symbol on YYO. |
`--------------------------------*/ `---------------------------*/
static void 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]); yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]);
yy_symbol_value_print (yyoutput, yytype, yyvaluep, ctx); yy_symbol_value_print (yyo, yytype, yyvaluep, ctx);
YYFPRINTF (yyoutput, ")"); YYFPRINTF (yyo, ")");
} }
/*------------------------------------------------------------------. /*------------------------------------------------------------------.
@ -798,7 +820,7 @@ do { \
static void static void
yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule, parser_ctx_t *ctx) 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 yynrhs = yyr2[yyrule];
int yyi; int yyi;
YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", 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); YYFPRINTF (stderr, " $%d = ", yyi + 1);
yy_symbol_print (stderr, yy_symbol_print (stderr,
yystos[yyssp[yyi + 1 - yynrhs]], yystos[yyssp[yyi + 1 - yynrhs]],
&(yyvsp[(yyi + 1) - (yynrhs)]) &yyvsp[(yyi + 1) - (yynrhs)]
, ctx); , ctx);
YYFPRINTF (stderr, "\n"); YYFPRINTF (stderr, "\n");
} }
@ -913,7 +935,10 @@ yytnamerr (char *yyres, const char *yystr)
case '\\': case '\\':
if (*++yyp != '\\') if (*++yyp != '\\')
goto do_not_strip_quotes; goto do_not_strip_quotes;
/* Fall through. */ else
goto append;
append:
default: default:
if (yyres) if (yyres)
yyres[yyn] = *yyp; yyres[yyn] = *yyp;
@ -931,7 +956,7 @@ yytnamerr (char *yyres, const char *yystr)
if (! yyres) if (! yyres)
return yystrlen (yystr); return yystrlen (yystr);
return yystpcpy (yyres, yystr) - yyres; return (YYSIZE_T) (yystpcpy (yyres, yystr) - yyres);
} }
# endif # endif
@ -947,11 +972,11 @@ static int
yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
yytype_int16 *yyssp, int yytoken) 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; YYSIZE_T yysize = yysize0;
enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
/* Internationalized format string. */ /* Internationalized format string. */
const char *yyformat = YY_NULL; const char *yyformat = YY_NULLPTR;
/* Arguments of yyformat. */ /* Arguments of yyformat. */
char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
/* Number of reported tokens (one for the "unexpected", one per /* 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]; yyarg[yycount++] = yytname[yyx];
{ {
YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULL, yytname[yyx]); YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]);
if (! (yysize <= yysize1 if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)
&& yysize1 <= YYSTACK_ALLOC_MAXIMUM)) yysize = yysize1;
else
return 2; return 2;
yysize = yysize1;
} }
} }
} }
@ -1024,6 +1049,7 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
case N: \ case N: \
yyformat = S; \ yyformat = S; \
break break
default: /* Avoid compiler warnings. */
YYCASE_(0, YY_("syntax error")); YYCASE_(0, YY_("syntax error"));
YYCASE_(1, YY_("syntax error, unexpected %s")); YYCASE_(1, YY_("syntax error, unexpected %s"));
YYCASE_(2, YY_("syntax error, unexpected %s, expecting %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); 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; return 2;
yysize = yysize1;
} }
if (*yymsg_alloc < yysize) if (*yymsg_alloc < yysize)
@ -1168,23 +1195,33 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
yychar = YYEMPTY; /* Cause a token to be read. */ yychar = YYEMPTY; /* Cause a token to be read. */
goto yysetstate; 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 /* In all cases, when you get here, the value and location stacks
have just been pushed. So pushing a state here evens the stacks. */ have just been pushed. So pushing a state here evens the stacks. */
yyssp++; 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 (yyss + yystacksize - 1 <= yyssp)
#if !defined yyoverflow && !defined YYSTACK_RELOCATE
goto yyexhaustedlab;
#else
{ {
/* Get the current used size of the three stacks, in elements. */ /* 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 /* Give user a chance to reallocate the stack. Use copies of
these so that the &'s don't force the real ones into 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), &yyss1, yysize * sizeof (*yyssp),
&yyvs1, yysize * sizeof (*yyvsp), &yyvs1, yysize * sizeof (*yyvsp),
&yystacksize); &yystacksize);
yyss = yyss1; yyss = yyss1;
yyvs = yyvs1; yyvs = yyvs1;
} }
#else /* no yyoverflow */ # else /* defined YYSTACK_RELOCATE */
# ifndef YYSTACK_RELOCATE
goto yyexhaustedlab;
# else
/* Extend the stack our own way. */ /* Extend the stack our own way. */
if (YYMAXDEPTH <= yystacksize) if (YYMAXDEPTH <= yystacksize)
goto yyexhaustedlab; goto yyexhaustedlab;
@ -1223,35 +1256,33 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
goto yyexhaustedlab; goto yyexhaustedlab;
YYSTACK_RELOCATE (yyss_alloc, yyss); YYSTACK_RELOCATE (yyss_alloc, yyss);
YYSTACK_RELOCATE (yyvs_alloc, yyvs); YYSTACK_RELOCATE (yyvs_alloc, yyvs);
# undef YYSTACK_RELOCATE # undef YYSTACK_RELOCATE
if (yyss1 != yyssa) if (yyss1 != yyssa)
YYSTACK_FREE (yyss1); YYSTACK_FREE (yyss1);
} }
# endif # endif
#endif /* no yyoverflow */
yyssp = yyss + yysize - 1; yyssp = yyss + yysize - 1;
yyvsp = yyvs + yysize - 1; yyvsp = yyvs + yysize - 1;
YYDPRINTF ((stderr, "Stack size increased to %lu\n", YYDPRINTF ((stderr, "Stack size increased to %lu\n",
(unsigned long int) yystacksize)); (unsigned long) yystacksize));
if (yyss + yystacksize - 1 <= yyssp) if (yyss + yystacksize - 1 <= yyssp)
YYABORT; YYABORT;
} }
#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */
YYDPRINTF ((stderr, "Entering state %d\n", yystate));
if (yystate == YYFINAL) if (yystate == YYFINAL)
YYACCEPT; YYACCEPT;
goto yybackup; goto yybackup;
/*-----------. /*-----------.
| yybackup. | | yybackup. |
`-----------*/ `-----------*/
yybackup: yybackup:
/* Do appropriate processing given the current state. Read a /* Do appropriate processing given the current state. Read a
lookahead token if we need one and don't already have one. */ lookahead token if we need one and don't already have one. */
@ -1309,7 +1340,6 @@ yybackup:
YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
*++yyvsp = yylval; *++yyvsp = yylval;
YY_IGNORE_MAYBE_UNINITIALIZED_END YY_IGNORE_MAYBE_UNINITIALIZED_END
goto yynewstate; goto yynewstate;
@ -1324,7 +1354,7 @@ yydefault:
/*-----------------------------. /*-----------------------------.
| yyreduce -- Do a reduction. | | yyreduce -- do a reduction. |
`-----------------------------*/ `-----------------------------*/
yyreduce: yyreduce:
/* yyn is the number of a rule to reduce with. */ /* yyn is the number of a rule to reduce with. */
@ -1344,236 +1374,237 @@ yyreduce:
YY_REDUCE_PRINT (yyn); YY_REDUCE_PRINT (yyn);
switch (yyn) switch (yyn)
{ {
case 2: case 2:
#line 146 "cc_parser.y" /* yacc.c:1646 */ #line 146 "cc_parser.y"
{ ctx->ccval = (yyvsp[0].ccval); YYACCEPT; } { ctx->ccval = (yyvsp[0].ccval); YYACCEPT; }
#line 1351 "cc_parser.tab.c" /* yacc.c:1646 */ #line 1381 "cc_parser.tab.c"
break; break;
case 3: case 3:
#line 149 "cc_parser.y" /* yacc.c:1646 */ #line 149 "cc_parser.y"
{ (yyval.ccval) = (yyvsp[0].ccval); } { (yyval.ccval) = (yyvsp[0].ccval); }
#line 1357 "cc_parser.tab.c" /* yacc.c:1646 */ #line 1387 "cc_parser.tab.c"
break; break;
case 4: case 4:
#line 150 "cc_parser.y" /* yacc.c:1646 */ #line 150 "cc_parser.y"
{ (yyval.ccval) = (yyvsp[-1].ccval); } { (yyval.ccval) = (yyvsp[-1].ccval); }
#line 1363 "cc_parser.tab.c" /* yacc.c:1646 */ #line 1393 "cc_parser.tab.c"
break; break;
case 5: case 5:
#line 151 "cc_parser.y" /* yacc.c:1646 */ #line 151 "cc_parser.y"
{ (yyval.ccval) = ccval_bool(!get_ccbool((yyvsp[0].ccval))); } { (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; break;
case 6: 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; } { 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; break;
case 7: 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; } { 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; break;
case 8: 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; } { 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; break;
case 9: case 9:
#line 157 "cc_parser.y" /* yacc.c:1646 */ #line 157 "cc_parser.y"
{ (yyval.ccval) = (yyvsp[0].ccval); } { (yyval.ccval) = (yyvsp[0].ccval); }
#line 1393 "cc_parser.tab.c" /* yacc.c:1646 */ #line 1423 "cc_parser.tab.c"
break; break;
case 10: 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; } { 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; break;
case 11: case 11:
#line 162 "cc_parser.y" /* yacc.c:1646 */ #line 162 "cc_parser.y"
{ (yyval.ccval) = (yyvsp[0].ccval); } { (yyval.ccval) = (yyvsp[0].ccval); }
#line 1405 "cc_parser.tab.c" /* yacc.c:1646 */ #line 1435 "cc_parser.tab.c"
break; break;
case 12: 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; } { 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; break;
case 13: case 13:
#line 167 "cc_parser.y" /* yacc.c:1646 */ #line 167 "cc_parser.y"
{ (yyval.ccval) = (yyvsp[0].ccval); } { (yyval.ccval) = (yyvsp[0].ccval); }
#line 1417 "cc_parser.tab.c" /* yacc.c:1646 */ #line 1447 "cc_parser.tab.c"
break; break;
case 14: 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; } { 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; break;
case 15: case 15:
#line 172 "cc_parser.y" /* yacc.c:1646 */ #line 172 "cc_parser.y"
{ (yyval.ccval) = (yyvsp[0].ccval); } { (yyval.ccval) = (yyvsp[0].ccval); }
#line 1429 "cc_parser.tab.c" /* yacc.c:1646 */ #line 1459 "cc_parser.tab.c"
break; break;
case 16: 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; } { 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; break;
case 17: case 17:
#line 177 "cc_parser.y" /* yacc.c:1646 */ #line 177 "cc_parser.y"
{ (yyval.ccval) = (yyvsp[0].ccval); } { (yyval.ccval) = (yyvsp[0].ccval); }
#line 1441 "cc_parser.tab.c" /* yacc.c:1646 */ #line 1471 "cc_parser.tab.c"
break; break;
case 18: 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; } { 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; break;
case 19: case 19:
#line 182 "cc_parser.y" /* yacc.c:1646 */ #line 182 "cc_parser.y"
{ (yyval.ccval) = (yyvsp[0].ccval); } { (yyval.ccval) = (yyvsp[0].ccval); }
#line 1453 "cc_parser.tab.c" /* yacc.c:1646 */ #line 1483 "cc_parser.tab.c"
break; break;
case 20: 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))); } { (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; break;
case 21: 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))); } { (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; break;
case 22: 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; } { 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; break;
case 23: 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; } { 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; break;
case 24: case 24:
#line 193 "cc_parser.y" /* yacc.c:1646 */ #line 193 "cc_parser.y"
{ (yyval.ccval) = (yyvsp[0].ccval); } { (yyval.ccval) = (yyvsp[0].ccval); }
#line 1483 "cc_parser.tab.c" /* yacc.c:1646 */ #line 1513 "cc_parser.tab.c"
break; break;
case 25: 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))); } { (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; break;
case 26: 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))); } { (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; break;
case 27: 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))); } { (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; break;
case 28: 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))); } { (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; break;
case 29: case 29:
#line 204 "cc_parser.y" /* yacc.c:1646 */ #line 204 "cc_parser.y"
{ (yyval.ccval) = (yyvsp[0].ccval); } { (yyval.ccval) = (yyvsp[0].ccval); }
#line 1513 "cc_parser.tab.c" /* yacc.c:1646 */ #line 1543 "cc_parser.tab.c"
break; break;
case 30: 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; } { 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; break;
case 31: 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; } { 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; break;
case 32: 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; } { 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; break;
case 33: case 33:
#line 213 "cc_parser.y" /* yacc.c:1646 */ #line 213 "cc_parser.y"
{ (yyval.ccval) = (yyvsp[0].ccval); } { (yyval.ccval) = (yyvsp[0].ccval); }
#line 1537 "cc_parser.tab.c" /* yacc.c:1646 */ #line 1567 "cc_parser.tab.c"
break; break;
case 34: 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))); } { (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; break;
case 35: 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))); } { (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; break;
case 36: case 36:
#line 220 "cc_parser.y" /* yacc.c:1646 */ #line 220 "cc_parser.y"
{ (yyval.ccval) = (yyvsp[0].ccval); } { (yyval.ccval) = (yyvsp[0].ccval); }
#line 1555 "cc_parser.tab.c" /* yacc.c:1646 */ #line 1585 "cc_parser.tab.c"
break; break;
case 37: 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))); } { (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; break;
case 38: 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))); } { (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; break;
case 39: 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; } { 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; break;
#line 1577 "cc_parser.tab.c" /* yacc.c:1646 */ #line 1607 "cc_parser.tab.c"
default: break; default: break;
} }
/* User semantic actions sometimes alter yychar, and that requires /* User semantic actions sometimes alter yychar, and that requires
@ -1598,14 +1629,13 @@ yyreduce:
/* Now 'shift' the result of the reduction. Determine what state /* Now 'shift' the result of the reduction. Determine what state
that goes to, based on the state we popped back to and the rule that goes to, based on the state we popped back to and the rule
number reduced by. */ number reduced by. */
{
yyn = yyr1[yyn]; const int yylhs = yyr1[yyn] - YYNTOKENS;
const int yyi = yypgoto[yylhs] + *yyssp;
yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp
if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) ? yytable[yyi]
yystate = yytable[yystate]; : yydefgoto[yylhs]);
else }
yystate = yydefgoto[yyn - YYNTOKENS];
goto yynewstate; goto yynewstate;
@ -1688,12 +1718,10 @@ yyerrlab:
| yyerrorlab -- error raised explicitly by YYERROR. | | yyerrorlab -- error raised explicitly by YYERROR. |
`---------------------------------------------------*/ `---------------------------------------------------*/
yyerrorlab: yyerrorlab:
/* Pacify compilers when the user code never invokes YYERROR and the
/* Pacify compilers like GCC when the user code never invokes label yyerrorlab therefore never appears in user code. */
YYERROR and the label yyerrorlab therefore never appears in user if (0)
code. */ YYERROR;
if (/*CONSTCOND*/ 0)
goto yyerrorlab;
/* Do not reclaim the symbols of the rule whose action triggered /* Do not reclaim the symbols of the rule whose action triggered
this YYERROR. */ this YYERROR. */
@ -1755,6 +1783,7 @@ yyacceptlab:
yyresult = 0; yyresult = 0;
goto yyreturn; goto yyreturn;
/*-----------------------------------. /*-----------------------------------.
| yyabortlab -- YYABORT comes here. | | yyabortlab -- YYABORT comes here. |
`-----------------------------------*/ `-----------------------------------*/
@ -1762,6 +1791,7 @@ yyabortlab:
yyresult = 1; yyresult = 1;
goto yyreturn; goto yyreturn;
#if !defined yyoverflow || YYERROR_VERBOSE #if !defined yyoverflow || YYERROR_VERBOSE
/*-------------------------------------------------. /*-------------------------------------------------.
| yyexhaustedlab -- memory exhaustion comes here. | | yyexhaustedlab -- memory exhaustion comes here. |
@ -1772,6 +1802,10 @@ yyexhaustedlab:
/* Fall through. */ /* Fall through. */
#endif #endif
/*-----------------------------------------------------.
| yyreturn -- parsing is finished, return the result. |
`-----------------------------------------------------*/
yyreturn: yyreturn:
if (yychar != YYEMPTY) if (yychar != YYEMPTY)
{ {
@ -1801,7 +1835,7 @@ yyreturn:
#endif #endif
return yyresult; return yyresult;
} }
#line 228 "cc_parser.y" /* yacc.c:1906 */ #line 228 "cc_parser.y"
BOOL parse_cc_expr(parser_ctx_t *ctx) BOOL parse_cc_expr(parser_ctx_t *ctx)

View file

@ -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 /* 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 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 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 This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */ 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 #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 # define YY_CC_PARSER_E_REACTOSSYNC_GCC_DLL_WIN32_JSCRIPT_CC_PARSER_TAB_H_INCLUDED
/* Debug traces. */ /* Debug traces. */
@ -62,15 +66,16 @@ extern int cc_parser_debug;
/* Value type. */ /* Value type. */
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE YYSTYPE;
union YYSTYPE union YYSTYPE
{ {
#line 36 "cc_parser.y" /* yacc.c:1909 */ #line 36 "cc_parser.y"
ccval_t ccval; 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_TRIVIAL 1
# define YYSTYPE_IS_DECLARED 1 # define YYSTYPE_IS_DECLARED 1
#endif #endif

View file

@ -30,7 +30,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(jscript);
%lex-param { parser_ctx_t *ctx } %lex-param { parser_ctx_t *ctx }
%parse-param { parser_ctx_t *ctx } %parse-param { parser_ctx_t *ctx }
%pure-parser %define api.pure
%start CCExpr %start CCExpr
%union { %union {

View file

@ -48,7 +48,7 @@ typedef struct {
int ref; int ref;
} function_local_t; } function_local_t;
typedef struct { typedef struct _compiler_ctx_t {
parser_ctx_t *parser; parser_ctx_t *parser;
bytecode_t *code; 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); 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; 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) 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) static BOOL ensure_bstr_slot(compiler_ctx_t *ctx)
@ -245,14 +245,9 @@ static HRESULT push_instr_int(compiler_ctx_t *ctx, jsop_t op, LONG arg)
return S_OK; 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; unsigned instr;
jsstr_t *str;
str = compiler_alloc_string(ctx, arg);
if(!str)
return E_OUTOFMEMORY;
instr = push_instr(ctx, op); instr = push_instr(ctx, op);
if(!instr) if(!instr)
@ -262,6 +257,19 @@ static HRESULT push_instr_str(compiler_ctx_t *ctx, jsop_t op, const WCHAR *arg)
return S_OK; 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[0].str = str;
instr_ptr(ctx, instr)->u.arg[1].uint = arg2;
return S_OK;
}
static HRESULT push_instr_bstr(compiler_ctx_t *ctx, jsop_t op, const WCHAR *arg) static HRESULT push_instr_bstr(compiler_ctx_t *ctx, jsop_t op, const WCHAR *arg)
{ {
unsigned instr; unsigned instr;
@ -477,13 +485,18 @@ static HRESULT compile_memberid_expression(compiler_ctx_t *ctx, expression_t *ex
} }
case EXPR_MEMBER: { case EXPR_MEMBER: {
member_expression_t *member_expr = (member_expression_t*)expr; member_expression_t *member_expr = (member_expression_t*)expr;
jsstr_t *jsstr;
hres = compile_expression(ctx, member_expr->expression, TRUE); hres = compile_expression(ctx, member_expr->expression, TRUE);
if(FAILED(hres)) if(FAILED(hres))
return hres; return hres;
/* FIXME: Potential optimization */ /* 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)) if(FAILED(hres))
return hres; return hres;
@ -676,13 +689,18 @@ static HRESULT compile_delete_expression(compiler_ctx_t *ctx, unary_expression_t
} }
case EXPR_MEMBER: { case EXPR_MEMBER: {
member_expression_t *member_expr = (member_expression_t*)expr->expression; member_expression_t *member_expr = (member_expression_t*)expr->expression;
jsstr_t *jsstr;
hres = compile_expression(ctx, member_expr->expression, TRUE); hres = compile_expression(ctx, member_expr->expression, TRUE);
if(FAILED(hres)) if(FAILED(hres))
return hres; return hres;
/* FIXME: Potential optimization */ /* 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)) if(FAILED(hres))
return 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; call_expression_t *call_expr = (call_expression_t*)expr->expression1;
argument_t *arg; 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) { if(is_memberid_expr(call_expr->expression->type) && call_expr->argument_list) {
hres = compile_memberid_expression(ctx, call_expr->expression, fdexNameEnsure); hres = compile_memberid_expression(ctx, call_expr->expression, fdexNameEnsure);
if(FAILED(hres)) if(FAILED(hres))
@ -734,6 +747,23 @@ static HRESULT compile_assign_expression(compiler_ctx_t *ctx, binary_expression_
return hres; return hres;
arg_cnt++; 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 { }else {
use_throw_path = TRUE; 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); hres = compile_memberid_expression(ctx, expr->expression1, fdexNameEnsure);
if(FAILED(hres)) if(FAILED(hres))
return hres; return hres;
if(op != OP_LAST && !push_instr(ctx, OP_refval))
return E_OUTOFMEMORY;
}else { }else {
use_throw_path = TRUE; 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); 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); hres = compile_expression(ctx, expr->expression2, TRUE);
if(FAILED(hres)) if(FAILED(hres))
return hres; return hres;
@ -811,48 +840,22 @@ static HRESULT compile_literal(compiler_ctx_t *ctx, literal_t *literal)
case LT_NULL: case LT_NULL:
return push_instr(ctx, OP_null) ? S_OK : E_OUTOFMEMORY; return push_instr(ctx, OP_null) ? S_OK : E_OUTOFMEMORY;
case LT_STRING: case LT_STRING:
return push_instr_str(ctx, OP_str, literal->u.wstr); return push_instr_str(ctx, OP_str, literal->u.str);
case LT_REGEXP: { case LT_REGEXP:
unsigned instr; return push_instr_str_uint(ctx, OP_regexp, literal->u.regexp.str, literal->u.regexp.flags);
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;
}
DEFAULT_UNREACHABLE; DEFAULT_UNREACHABLE;
} }
return E_FAIL; 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) { switch(literal->type) {
case LT_STRING: case LT_STRING:
*str = compiler_alloc_bstr(ctx, literal->u.wstr); *str = literal->u.str;
break; break;
case LT_DOUBLE: { case LT_DOUBLE:
jsstr_t *jsstr; return double_to_string(literal->u.dval, str);
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);
break;
}
DEFAULT_UNREACHABLE; 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) static HRESULT compile_object_literal(compiler_ctx_t *ctx, property_value_expression_t *expr)
{ {
property_definition_t *iter; property_definition_t *iter;
BSTR name; jsstr_t *name;
HRESULT hres; HRESULT hres;
if(!push_instr(ctx, OP_new_obj)) if(!push_instr(ctx, OP_new_obj))
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
for(iter = expr->property_list; iter; iter = iter->next) { 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)) if(FAILED(hres))
return hres; return hres;
@ -904,7 +907,7 @@ static HRESULT compile_object_literal(compiler_ctx_t *ctx, property_value_expres
if(FAILED(hres)) if(FAILED(hres))
return 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)) if(FAILED(hres))
return 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) { for(iter = ctx->stat_ctx; iter; iter = iter->next) {
if(iter->continue_label) if(iter->continue_label)
pop_ctx = iter; 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; break;
} }
@ -1473,7 +1476,7 @@ static HRESULT compile_break_statement(compiler_ctx_t *ctx, branch_statement_t *
if(stat->identifier) { if(stat->identifier) {
for(pop_ctx = ctx->stat_ctx; pop_ctx; pop_ctx = pop_ctx->next) { 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); assert(pop_ctx->break_label);
break; break;
} }
@ -1557,7 +1560,7 @@ static HRESULT compile_labelled_statement(compiler_ctx_t *ctx, labelled_statemen
HRESULT hres; HRESULT hres;
for(iter = ctx->stat_ctx; iter; iter = iter->next) { 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)); WARN("Label %s redefined\n", debugstr_w(stat->identifier));
return JS_E_LABEL_REDEFINED; 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) 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); 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) 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; const WCHAR *ptr = args, *ptr2;
unsigned arg_cnt = 0; unsigned arg_cnt = 0;
while(isspaceW(*ptr)) while(iswspace(*ptr))
ptr++; ptr++;
if(!*ptr) { if(!*ptr) {
if(args_size) if(args_size)
@ -2399,16 +2402,16 @@ static HRESULT parse_arguments(compiler_ctx_t *ctx, const WCHAR *args, BSTR *arg
} }
while(1) { while(1) {
if(!isalphaW(*ptr) && *ptr != '_') { if(!iswalpha(*ptr) && *ptr != '_') {
FIXME("expected alpha or '_': %s\n", debugstr_w(ptr)); FIXME("expected alpha or '_': %s\n", debugstr_w(ptr));
return E_FAIL; return E_FAIL;
} }
ptr2 = ptr; ptr2 = ptr;
while(isalnumW(*ptr) || *ptr == '_') while(iswalnum(*ptr) || *ptr == '_')
ptr++; ptr++;
if(*ptr && *ptr != ',' && !isspaceW(*ptr)) { if(*ptr && *ptr != ',' && !iswspace(*ptr)) {
FIXME("unexpected har %s\n", debugstr_w(ptr)); FIXME("unexpected har %s\n", debugstr_w(ptr));
return E_FAIL; return E_FAIL;
} }
@ -2420,7 +2423,7 @@ static HRESULT parse_arguments(compiler_ctx_t *ctx, const WCHAR *args, BSTR *arg
} }
arg_cnt++; arg_cnt++;
while(isspaceW(*ptr)) while(iswspace(*ptr))
ptr++; ptr++;
if(!*ptr) if(!*ptr)
break; break;
@ -2430,7 +2433,7 @@ static HRESULT parse_arguments(compiler_ctx_t *ctx, const WCHAR *args, BSTR *arg
} }
ptr++; ptr++;
while(isspaceW(*ptr)) while(iswspace(*ptr))
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)) { if(FAILED(hres)) {
release_bytecode(compiler.code); release_bytecode(compiler.code);
return hres; return hres;

View file

@ -17,8 +17,10 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
#include "config.h" #ifdef __REACTOS__
#include "wine/port.h" #include <wine/config.h>
#include <wine/port.h>
#endif
#include <limits.h> #include <limits.h>
#include <math.h> #include <math.h>
@ -542,16 +544,16 @@ static inline HRESULT date_to_string(DOUBLE time, BOOL show_offset, int offset,
} }
if(!show_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)hour_from_time(time), (int)min_from_time(time),
(int)sec_from_time(time), year, formatAD?ADW:BCW); (int)sec_from_time(time), year, formatAD?ADW:BCW);
else if(offset) 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)hour_from_time(time), (int)min_from_time(time),
(int)sec_from_time(time), sign, offset/60, offset%60, (int)sec_from_time(time), sign, offset/60, offset%60,
year, formatAD?ADW:BCW); year, formatAD?ADW:BCW);
else else
sprintfW(buf, formatUTCW, week, month, day, swprintf(buf, formatUTCW, week, month, day,
(int)hour_from_time(time), (int)min_from_time(time), (int)hour_from_time(time), (int)min_from_time(time),
(int)sec_from_time(time), year, formatAD?ADW:BCW); (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) { if(year < 0) {
*p++ = '-'; *p++ = '-';
p += sprintfW(p, long_year_formatW, -(int)year); p += swprintf(p, long_year_formatW, -(int)year);
}else if(year > 9999) { }else if(year > 9999) {
*p++ = '+'; *p++ = '+';
p += sprintfW(p, long_year_formatW, (int)year); p += swprintf(p, long_year_formatW, (int)year);
}else { }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)hour_from_time(date->time), (int)min_from_time(date->time),
(int)sec_from_time(date->time), (int)ms_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); 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)hour_from_time(date->time), (int)min_from_time(date->time),
(int)sec_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); 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); date_str = jsstr_alloc(buf);
if(!date_str) if(!date_str)
@ -883,11 +886,11 @@ static HRESULT Date_toTimeString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
else sign = '-'; else sign = '-';
if(offset) 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), (int)min_from_time(time), (int)sec_from_time(time),
sign, offset/60, offset%60); sign, offset/60, offset%60);
else 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)); (int)min_from_time(time), (int)sec_from_time(time));
date_str = jsstr_alloc(buf); 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++) { for(i=0; i<input_len; i++) {
if(input[i] == '(') nest_level++; if(input[i] == '(') nest_level++;
else 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; 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;) { for(i=0; i<parse_len;) {
while(isspaceW(parse[i])) i++; while(iswspace(parse[i])) i++;
if(parse[i] == ',') { if(parse[i] == ',') {
while(parse[i] == ',') i++; while(parse[i] == ',') i++;
continue; continue;
} }
if(parse[i]>='0' && parse[i]<='9') { 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(parse[i]>='0' && parse[i]<='9') i++;
while(isspaceW(parse[i])) i++; while(iswspace(parse[i])) i++;
if(parse[i] == ':') { if(parse[i] == ':') {
/* Time */ /* Time */
@ -2121,17 +2124,17 @@ static inline HRESULT date_parse(jsstr_t *input_str, double *ret) {
hour = tmp; hour = tmp;
while(parse[i] == ':') i++; while(parse[i] == ':') i++;
while(isspaceW(parse[i])) i++; while(iswspace(parse[i])) i++;
if(parse[i]>='0' && parse[i]<='9') { 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(parse[i]>='0' && parse[i]<='9') i++;
} }
while(isspaceW(parse[i])) i++; while(iswspace(parse[i])) i++;
while(parse[i] == ':') i++; while(parse[i] == ':') i++;
while(isspaceW(parse[i])) i++; while(iswspace(parse[i])) i++;
if(parse[i]>='0' && parse[i]<='9') { 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++; 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; month = tmp-1;
while(isspaceW(parse[i])) i++; while(iswspace(parse[i])) i++;
while(parse[i]=='-' || 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; 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]>='0' && parse[i]<='9') i++;
while(parse[i]=='-' || 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; 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++; while(parse[i]>='0' && parse[i]<='9') i++;
if(tmp >= 70){ if(tmp >= 70){
@ -2189,9 +2192,9 @@ static inline HRESULT date_parse(jsstr_t *input_str, double *ret) {
if(parse[i] == '-') positive = FALSE; if(parse[i] == '-') positive = FALSE;
i++; i++;
while(isspaceW(parse[i])) i++; while(iswspace(parse[i])) i++;
if(parse[i]<'0' || parse[i]>'9') break; 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++; while(parse[i]>='0' && parse[i]<='9') i++;
if(offset<24) offset *= 60; if(offset<24) offset *= 60;
@ -2270,7 +2273,7 @@ static inline HRESULT date_parse(jsstr_t *input_str, double *ret) {
size -= i; size -= i;
for(j=0; j<ARRAY_SIZE(string_ids); j++) 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(j < 12) {
if(set_month) break; if(set_month) break;

View file

@ -117,7 +117,7 @@ HRESULT decode_source(WCHAR *code)
static const WCHAR decode_endW[] = {'^','#','~','@'}; static const WCHAR decode_endW[] = {'^','#','~','@'};
while(*src) { 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; DWORD len, i, j=0, csum, s=0;
src += ARRAY_SIZE(decode_beginW); src += ARRAY_SIZE(decode_beginW);
@ -165,7 +165,7 @@ HRESULT decode_source(WCHAR *code)
return JS_E_INVALID_CHAR; return JS_E_INVALID_CHAR;
src += 8; 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; return JS_E_INVALID_CHAR;
src += ARRAY_SIZE(decode_endW); src += ARRAY_SIZE(decode_endW);
}else { }else {

View file

@ -20,7 +20,6 @@
#include "jscript.h" #include "jscript.h"
#include "wine/unicode.h"
#include "wine/debug.h" #include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(jscript); 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) { while(min <= max) {
i = (min+max)/2; i = (min+max)/2;
r = strcmpW(name, This->builtin_info->props[i].name); r = wcscmp(name, This->builtin_info->props[i].name);
if(!r) { if(!r) {
/* Skip prop if it's available only in higher compatibility mode. */ /* Skip prop if it's available only in higher compatibility mode. */
unsigned version = (This->builtin_info->props[i].flags & PROPF_VERSION_MASK) 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; unsigned h = 0;
for(; *name; name++) 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; 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); bucket = get_props_idx(This, hash);
pos = This->props[bucket].bucket_head; pos = This->props[bucket].bucket_head;
while(pos != 0) { while(pos != 0) {
if(!strcmpW(name, This->props[pos].name)) { if(!wcscmp(name, This->props[pos].name)) {
if(prev != 0) { if(prev != 0) {
This->props[prev].bucket_next = This->props[pos].bucket_next; This->props[prev].bucket_next = This->props[pos].bucket_next;
This->props[pos].bucket_next = This->props[bucket].bucket_head; 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; const WCHAR *ptr;
unsigned idx = 0; unsigned idx = 0;
for(ptr = name; isdigitW(*ptr) && idx < 0x10000; ptr++) for(ptr = name; iswdigit(*ptr) && idx < 0x10000; ptr++)
idx = idx*10 + (*ptr-'0'); idx = idx*10 + (*ptr-'0');
if(!*ptr && idx < This->builtin_info->idx_length(This)) { if(!*ptr && idx < This->builtin_info->idx_length(This)) {
prop = alloc_prop(This, name, PROP_IDX, This->builtin_info->idx_put ? PROPF_WRITABLE : 0); 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) static HRESULT WINAPI DispatchEx_GetNextDispID(IDispatchEx *iface, DWORD grfdex, DISPID id, DISPID *pid)
{ {
jsdisp_t *This = impl_from_IDispatchEx(iface); jsdisp_t *This = impl_from_IDispatchEx(iface);
dispex_prop_t *iter;
HRESULT hres; HRESULT hres;
TRACE("(%p)->(%x %x %p)\n", This, grfdex, id, pid); TRACE("(%p)->(%x %x %p)\n", This, grfdex, id, pid);
if(id == DISPID_STARTENUM) { hres = jsdisp_next_prop(This, id, FALSE, pid);
hres = fill_protrefs(This); if(hres == S_FALSE)
if(FAILED(hres))
return hres;
}
if(id+1>=0 && id+1<This->prop_cnt) {
iter = &This->props[id+1];
}else {
*pid = DISPID_STARTENUM; *pid = DISPID_STARTENUM;
return S_FALSE; return hres;
}
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;
} }
static HRESULT WINAPI DispatchEx_GetNameSpaceParent(IDispatchEx *iface, IUnknown **ppunk) 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}; static const WCHAR formatW[] = {'%','d',0};
sprintfW(buf, formatW, idx); swprintf(buf, formatW, idx);
return jsdisp_propput_name(obj, buf, val); 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}; 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); hres = find_prop_name_prot(obj, string_hash(name), name, &prop);
if(FAILED(hres)) if(FAILED(hres))
@ -1520,7 +1499,7 @@ HRESULT jsdisp_delete_idx(jsdisp_t *obj, DWORD idx)
BOOL b; BOOL b;
HRESULT hres; HRESULT hres;
sprintfW(buf, formatW, idx); swprintf(buf, formatW, idx);
hres = find_prop_name(obj, string_hash(buf), buf, &prop); hres = find_prop_name(obj, string_hash(buf), buf, &prop);
if(FAILED(hres) || !prop) if(FAILED(hres) || !prop)
@ -1564,6 +1543,34 @@ HRESULT disp_delete(IDispatch *disp, DISPID id, BOOL *ret)
return S_OK; 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) HRESULT disp_delete_name(script_ctx_t *ctx, IDispatch *disp, jsstr_t *name, BOOL *ret)
{ {
IDispatchEx *dispex; IDispatchEx *dispex;

View file

@ -16,8 +16,10 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
#include "config.h" #ifdef __REACTOS__
#include "wine/port.h" #include <wine/config.h>
#include <wine/port.h>
#endif
#include <math.h> #include <math.h>
#include <assert.h> #include <assert.h>
@ -619,9 +621,9 @@ static BOOL lookup_global_members(script_ctx_t *ctx, BSTR identifier, exprval_t
return FALSE; 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) 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; return S_OK;
} }
if(!strcmpW(identifier, argumentsW)) { if(!wcscmp(identifier, argumentsW)) {
hres = detach_variable_object(ctx, scope->frame, FALSE); hres = detach_variable_object(ctx, scope->frame, FALSE);
if(FAILED(hres)) if(FAILED(hres))
return 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) { 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) { if(!item->disp) {
IUnknown *unk; IUnknown *unk;
@ -1449,16 +1451,20 @@ static HRESULT interp_new_obj(script_ctx_t *ctx)
/* ECMA-262 3rd Edition 11.1.5 */ /* ECMA-262 3rd Edition 11.1.5 */
static HRESULT interp_obj_prop(script_ctx_t *ctx) 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); unsigned type = get_op_uint(ctx, 1);
const WCHAR *name;
jsdisp_t *obj; jsdisp_t *obj;
jsval_t val; jsval_t val;
HRESULT hres; HRESULT hres;
TRACE("%s\n", debugstr_w(name)); TRACE("%s\n", debugstr_jsstr(name_arg));
val = stack_pop(ctx); val = stack_pop(ctx);
/* FIXME: we should pass it as jsstr_t */
name = jsstr_flatten(name_arg);
assert(is_object_instance(stack_top(ctx))); assert(is_object_instance(stack_top(ctx)));
obj = as_jsdisp(get_object(stack_top(ctx))); obj = as_jsdisp(get_object(stack_top(ctx)));

View file

@ -68,7 +68,7 @@
X(new, 1, ARG_UINT, 0) \ X(new, 1, ARG_UINT, 0) \
X(new_obj, 1, 0,0) \ X(new_obj, 1, 0,0) \
X(null, 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(or, 1, 0,0) \
X(pop, 1, ARG_UINT, 0) \ X(pop, 1, ARG_UINT, 0) \
X(pop_except, 0, ARG_ADDR, 0) \ X(pop_except, 0, ARG_ADDR, 0) \

View file

@ -61,7 +61,7 @@ static inline HRESULT enumvar_get_next_item(EnumeratorInstance *This)
if (This->atend) if (This->atend)
return S_OK; return S_OK;
/* dont leak pervious value */ /* don't leak previous value */
jsval_release(This->item); jsval_release(This->item);
/* not at end ... get next item */ /* not at end ... get next item */
@ -73,7 +73,7 @@ static inline HRESULT enumvar_get_next_item(EnumeratorInstance *This)
VariantClear(&nextitem); VariantClear(&nextitem);
if (FAILED(hres)) if (FAILED(hres))
{ {
WARN("failed to convert jsval to variant!"); WARN("failed to convert jsval to variant!\n");
This->item = jsval_undefined(); This->item = jsval_undefined();
return hres; return hres;
} }

View file

@ -16,8 +16,10 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
#include "config.h" #ifdef __REACTOS__
#include "wine/port.h" #include <wine/config.h>
#include <wine/port.h>
#endif
#include <math.h> #include <math.h>
@ -387,10 +389,10 @@ static HRESULT throw_error(script_ctx_t *ctx, HRESULT error, const WCHAR *str, j
buf[0] = '\0'; buf[0] = '\0';
LoadStringW(jscript_hinstance, HRESULT_CODE(error), buf, ARRAY_SIZE(buf)); LoadStringW(jscript_hinstance, HRESULT_CODE(error), buf, ARRAY_SIZE(buf));
if(str) pos = strchrW(buf, '|'); if(str) pos = wcschr(buf, '|');
if(pos) { if(pos) {
int len = strlenW(str); int len = lstrlenW(str);
memmove(pos+len, pos+1, (strlenW(pos+1)+1)*sizeof(WCHAR)); memmove(pos+len, pos+1, (lstrlenW(pos+1)+1)*sizeof(WCHAR));
memcpy(pos, str, len*sizeof(WCHAR)); memcpy(pos, str, len*sizeof(WCHAR));
} }

View file

@ -25,25 +25,52 @@
WINE_DEFAULT_DEBUG_CHANNEL(jscript); WINE_DEFAULT_DEBUG_CHANNEL(jscript);
typedef struct _function_vtbl_t function_vtbl_t;
typedef struct { typedef struct {
jsdisp_t dispex; jsdisp_t dispex;
builtin_invoke_t value_proc; const function_vtbl_t *vtbl;
const WCHAR *name;
DWORD flags; DWORD flags;
scope_chain_t *scope_chain;
bytecode_t *code;
function_code_t *func_code;
DWORD length; DWORD length;
} FunctionInstance; } 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;
} 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 { typedef struct {
jsdisp_t jsdisp; jsdisp_t jsdisp;
FunctionInstance *function; InterpretedFunction *function;
jsval_t *buf; jsval_t *buf;
call_frame_t *frame; call_frame_t *frame;
unsigned argc; unsigned argc;
} ArgumentsInstance; } 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) static inline FunctionInstance *function_from_jsdisp(jsdisp_t *jsdisp)
{ {
return CONTAINING_RECORD(jsdisp, FunctionInstance, dispex); 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 lengthW[] = {'l','e','n','g','t','h',0};
static const WCHAR toStringW[] = {'t','o','S','t','r','i','n','g',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 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 callW[] = {'c','a','l','l',0};
static const WCHAR argumentsW[] = {'a','r','g','u','m','e','n','t','s',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); heap_free(arguments->buf);
} }
jsdisp_release(&arguments->function->dispex); jsdisp_release(&arguments->function->function.dispex);
heap_free(arguments); 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); return jsval_copy(*ref, r);
/* FIXME: Accessing by name won't work for duplicated argument names */ /* 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) 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 */ /* 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 = { 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; 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->argc = frame->argc;
args->frame = frame; args->frame = frame;
@ -184,7 +214,7 @@ HRESULT setup_arguments_object(script_ctx_t *ctx, call_frame_t *frame)
jsval_number(args->argc)); jsval_number(args->argc));
if(SUCCEEDED(hres)) if(SUCCEEDED(hres))
hres = jsdisp_define_data_property(&args->jsdisp, caleeW, PROPF_WRITABLE | PROPF_CONFIGURABLE, 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)) if(SUCCEEDED(hres))
hres = jsdisp_propput(frame->base_scope->jsobj, argumentsW, PROPF_WRITABLE, jsval_obj(&args->jsdisp)); hres = jsdisp_propput(frame->base_scope->jsobj, argumentsW, PROPF_WRITABLE, jsval_obj(&args->jsdisp));
if(FAILED(hres)) { if(FAILED(hres)) {
@ -231,99 +261,8 @@ void detach_arguments_object(jsdisp_t *args_disp)
jsdisp_release(frame->arguments_obj); 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) 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; FunctionInstance *function;
TRACE("func %p this %p\n", func_this, jsthis); 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)); assert(is_class(func_this, JSCLASS_FUNCTION));
function = function_from_jsdisp(func_this); function = function_from_jsdisp(func_this);
flags &= ~DISPATCH_JSCRIPT_INTERNAL_MASK; return function->vtbl->call(function->dispex.ctx, function, jsthis, flags, argc, argv, r);
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);
} }
static HRESULT Function_get_length(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t *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))) if(!(function = function_this(jsthis)))
return throw_type_error(ctx, JS_E_FUNCTION_EXPECTED, NULL); 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)) if(FAILED(hres))
return 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(SUCCEEDED(hres)) {
if(function) { 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 { }else {
jsval_t res; jsval_t res;
hres = disp_call_value(ctx, jsthis->u.disp, this_obj, DISPATCH_METHOD, cnt, args, &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; 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) if(this_obj)
IDispatch_Release(this_obj); IDispatch_Release(this_obj);
return hres; 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, HRESULT Function_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
jsval_t *r) 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); function = function_from_jsdisp(jsthis->u.jsdisp);
return function->vtbl->call(ctx, function, NULL, flags, argc, argv, r);
assert(function->value_proc != NULL);
return invoke_value_proc(ctx, function, NULL, flags, argc, argv, r);
} }
HRESULT Function_get_value(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t *r) HRESULT Function_get_value(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t *r)
{ {
FunctionInstance *function = function_from_jsdisp(jsthis);
jsstr_t *str; jsstr_t *str;
HRESULT hres; HRESULT hres;
TRACE("\n"); TRACE("\n");
hres = function_to_string(function_from_jsdisp(jsthis), &str); hres = function->vtbl->toString(function, &str);
if(FAILED(hres)) if(FAILED(hres))
return 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) static void Function_destructor(jsdisp_t *dispex)
{ {
FunctionInstance *This = function_from_jsdisp(dispex); FunctionInstance *function = function_from_jsdisp(dispex);
function->vtbl->destructor(function);
if(This->code) heap_free(function);
release_bytecode(This->code);
if(This->scope_chain)
scope_release(This->scope_chain);
heap_free(This);
} }
static const builtin_prop_t Function_props[] = { static const builtin_prop_t Function_props[] = {
{applyW, Function_apply, PROPF_METHOD|2}, {applyW, Function_apply, PROPF_METHOD|2},
{argumentsW, NULL, 0, Function_get_arguments}, {argumentsW, NULL, 0, Function_get_arguments},
{bindW, Function_bind, PROPF_METHOD|PROPF_ES5|1},
{callW, Function_call, PROPF_METHOD|1}, {callW, Function_call, PROPF_METHOD|1},
{lengthW, NULL, 0, Function_get_length}, {lengthW, NULL, 0, Function_get_length},
{toStringW, Function_toString, PROPF_METHOD} {toStringW, Function_toString, PROPF_METHOD}
@ -613,13 +563,13 @@ static const builtin_info_t FunctionInst_info = {
NULL NULL
}; };
static HRESULT create_function(script_ctx_t *ctx, const builtin_info_t *builtin_info, DWORD flags, static HRESULT create_function(script_ctx_t *ctx, const builtin_info_t *builtin_info, const function_vtbl_t *vtbl, size_t size,
BOOL funcprot, jsdisp_t *prototype, FunctionInstance **ret) DWORD flags, BOOL funcprot, jsdisp_t *prototype, void **ret)
{ {
FunctionInstance *function; FunctionInstance *function;
HRESULT hres; HRESULT hres;
function = heap_alloc_zero(sizeof(FunctionInstance)); function = heap_alloc_zero(size);
if(!function) if(!function)
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
@ -634,6 +584,7 @@ static HRESULT create_function(script_ctx_t *ctx, const builtin_info_t *builtin_
return hres; return hres;
} }
function->vtbl = vtbl;
function->flags = flags; function->flags = flags;
function->length = flags & PROPF_ARGMASK; 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; 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, 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) const builtin_info_t *builtin_info, DWORD flags, jsdisp_t *prototype, jsdisp_t **ret)
{ {
FunctionInstance *function; NativeFunction *function;
HRESULT hres; 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)) if(FAILED(hres))
return hres; return hres;
if(builtin_info) if(builtin_info)
hres = jsdisp_define_data_property(&function->dispex, lengthW, 0, hres = jsdisp_define_data_property(&function->function.dispex, lengthW, 0,
jsval_number(function->length)); jsval_number(function->function.length));
if(SUCCEEDED(hres)) 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)) { if(FAILED(hres)) {
jsdisp_release(&function->dispex); jsdisp_release(&function->function.dispex);
return hres; return hres;
} }
function->value_proc = value_proc; function->proc = value_proc;
function->name = name; function->name = name;
*ret = &function->dispex; *ret = &function->function.dispex;
return S_OK; return S_OK;
} }
@ -696,10 +703,71 @@ HRESULT create_builtin_constructor(script_ctx_t *ctx, builtin_invoke_t value_pro
return S_OK; 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, HRESULT create_source_function(script_ctx_t *ctx, bytecode_t *code, function_code_t *func_code,
scope_chain_t *scope_chain, jsdisp_t **ret) scope_chain_t *scope_chain, jsdisp_t **ret)
{ {
FunctionInstance *function; InterpretedFunction *function;
jsdisp_t *prototype; jsdisp_t *prototype;
HRESULT hres; HRESULT hres;
@ -707,14 +775,15 @@ HRESULT create_source_function(script_ctx_t *ctx, bytecode_t *code, function_cod
if(FAILED(hres)) if(FAILED(hres))
return 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)) { 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)); jsval_obj(prototype));
if(SUCCEEDED(hres)) if(SUCCEEDED(hres))
hres = set_constructor_prop(ctx, &function->dispex, prototype); hres = set_constructor_prop(ctx, &function->function.dispex, prototype);
if(FAILED(hres)) if(FAILED(hres))
jsdisp_release(&function->dispex); jsdisp_release(&function->function.dispex);
} }
jsdisp_release(prototype); jsdisp_release(prototype);
if(FAILED(hres)) if(FAILED(hres))
@ -728,9 +797,97 @@ HRESULT create_source_function(script_ctx_t *ctx, bytecode_t *code, function_cod
bytecode_addref(code); bytecode_addref(code);
function->code = code; function->code = code;
function->func_code = func_code; function->func_code = func_code;
function->length = function->func_code->param_cnt; function->function.length = function->func_code->param_cnt;
*ret = &function->dispex; *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->function.dispex;
return S_OK; 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) HRESULT init_function_constr(script_ctx_t *ctx, jsdisp_t *object_prototype)
{ {
FunctionInstance *prot, *constr; NativeFunction *prot, *constr;
HRESULT hres; HRESULT hres;
static const WCHAR FunctionW[] = {'F','u','n','c','t','i','o','n',0}; 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)) if(FAILED(hres))
return hres; return hres;
prot->value_proc = FunctionProt_value; prot->proc = FunctionProt_value;
prot->name = prototypeW; 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)) { if(SUCCEEDED(hres)) {
constr->value_proc = FunctionConstr_value; constr->proc = FunctionConstr_value;
constr->name = FunctionW; 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)) 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)) if(FAILED(hres))
jsdisp_release(&constr->dispex); jsdisp_release(&constr->function.dispex);
} }
jsdisp_release(&prot->dispex); jsdisp_release(&prot->function.dispex);
if(FAILED(hres)) if(FAILED(hres))
return hres; return hres;
ctx->function_constr = &constr->dispex; ctx->function_constr = &constr->function.dispex;
return S_OK; return S_OK;
} }

View file

@ -16,8 +16,10 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
#include "config.h" #ifdef __REACTOS__
#include "wine/port.h" #include <wine/config.h>
#include <wine/port.h>
#endif
#include <math.h> #include <math.h>
#include <limits.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, HRESULT JSGlobal_eval(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
jsval_t *r) jsval_t *r)
{ {
call_frame_t *frame; call_frame_t *frame = ctx->call_ctx;
DWORD exec_flags = EXEC_EVAL; DWORD exec_flags = EXEC_EVAL;
bytecode_t *code; bytecode_t *code;
const WCHAR *src; const WCHAR *src;
@ -201,11 +203,6 @@ HRESULT JSGlobal_eval(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned a
return S_OK; return S_OK;
} }
if(!(frame = ctx->call_ctx)) {
FIXME("No active exec_ctx\n");
return E_UNEXPECTED;
}
src = jsstr_flatten(get_string(argv[0])); src = jsstr_flatten(get_string(argv[0]));
if(!src) if(!src)
return E_OUTOFMEMORY; 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); return throw_syntax_error(ctx, hres, NULL);
} }
if(frame->flags & EXEC_GLOBAL) if(!frame || (frame->flags & EXEC_GLOBAL))
exec_flags |= EXEC_GLOBAL; exec_flags |= EXEC_GLOBAL;
if(flags & DISPATCH_JSCRIPT_CALLEREXECSSOURCE) if(flags & DISPATCH_JSCRIPT_CALLEREXECSSOURCE)
exec_flags |= EXEC_RETURN_TO_INTERP; exec_flags |= EXEC_RETURN_TO_INTERP;
hres = exec_source(ctx, exec_flags, code, &code->global_code, frame->scope, hres = exec_source(ctx, exec_flags, code, &code->global_code, frame ? frame->scope : NULL,
frame->this_obj, NULL, frame->variable_obj, 0, NULL, r); frame ? frame->this_obj : NULL, NULL, frame ? frame->variable_obj : ctx->global, 0, NULL, r);
release_bytecode(code); release_bytecode(code);
return hres; return hres;
} }
@ -317,7 +314,7 @@ static HRESULT JSGlobal_parseInt(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
if(FAILED(hres)) if(FAILED(hres))
return hres; return hres;
while(isspaceW(*ptr)) while(iswspace(*ptr))
ptr++; ptr++;
switch(*ptr) { switch(*ptr) {
@ -343,6 +340,8 @@ static HRESULT JSGlobal_parseInt(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
}else { }else {
radix = 10; radix = 10;
} }
}else if(radix == 16 && *ptr == '0' && (ptr[1] == 'x' || ptr[1] == 'X')) {
ptr += 2;
} }
i = char_to_int(*ptr++); 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)) if(FAILED(hres))
return hres; return hres;
while(isspaceW(*str)) str++; while(iswspace(*str)) str++;
if(*str == '+') if(*str == '+')
str++; str++;
@ -394,10 +393,10 @@ static HRESULT JSGlobal_parseFloat(script_ctx_t *ctx, vdisp_t *jsthis, WORD flag
str++; str++;
} }
if(isdigitW(*str)) if(iswdigit(*str))
ret_nan = FALSE; ret_nan = FALSE;
while(isdigitW(*str)) { while(iswdigit(*str)) {
hlp = d*10 + *(str++) - '0'; hlp = d*10 + *(str++) - '0';
if(d>MAXLONGLONG/10 || hlp<0) { if(d>MAXLONGLONG/10 || hlp<0) {
exp++; exp++;
@ -406,17 +405,17 @@ static HRESULT JSGlobal_parseFloat(script_ctx_t *ctx, vdisp_t *jsthis, WORD flag
else else
d = hlp; d = hlp;
} }
while(isdigitW(*str)) { while(iswdigit(*str)) {
exp++; exp++;
str++; str++;
} }
if(*str == '.') str++; if(*str == '.') str++;
if(isdigitW(*str)) if(iswdigit(*str))
ret_nan = FALSE; ret_nan = FALSE;
while(isdigitW(*str)) { while(iswdigit(*str)) {
hlp = d*10 + *(str++) - '0'; hlp = d*10 + *(str++) - '0';
if(d>MAXLONGLONG/10 || hlp<0) if(d>MAXLONGLONG/10 || hlp<0)
break; break;
@ -424,7 +423,7 @@ static HRESULT JSGlobal_parseFloat(script_ctx_t *ctx, vdisp_t *jsthis, WORD flag
d = hlp; d = hlp;
exp--; exp--;
} }
while(isdigitW(*str)) while(iswdigit(*str))
str++; str++;
if(*str && !ret_nan && (*str=='e' || *str=='E')) { 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++; str++;
} }
while(isdigitW(*str)) { while(iswdigit(*str)) {
if(e>INT_MAX/10 || (e = e*10 + *str++ - '0')<0) if(e>INT_MAX/10 || (e = e*10 + *str++ - '0')<0)
e = INT_MAX; 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) { static inline int hex_to_int(const WCHAR wch) {
if(toupperW(wch)>='A' && toupperW(wch)<='F') return toupperW(wch)-'A'+10; if(towupper(wch)>='A' && towupper(wch)<='F') return towupper(wch)-'A'+10;
if(isdigitW(wch)) return wch-'0'; if(iswdigit(wch)) return wch-'0';
return -1; return -1;
} }

View file

@ -20,19 +20,22 @@
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h> #include <stdio.h>
#include <stdint.h>
#define COBJMACROS #define COBJMACROS
#include "windef.h" #include "windef.h"
#include "winbase.h" #include "winbase.h"
#include "winuser.h" #include "winuser.h"
#ifdef __REACTOS__
#include "winnls.h"
#endif
#include "ole2.h" #include "ole2.h"
#include "dispex.h" #include "dispex.h"
#include "activscp.h" #include "activscp.h"
#include "resource.h" #include "resource.h"
#include "wine/unicode.h"
#include "wine/heap.h" #include "wine/heap.h"
#include "wine/list.h" #include "wine/list.h"
@ -77,7 +80,7 @@ static inline LPWSTR heap_strdupW(LPCWSTR str)
if(str) { if(str) {
DWORD size; DWORD size;
size = (strlenW(str)+1)*sizeof(WCHAR); size = (lstrlenW(str)+1)*sizeof(WCHAR);
ret = heap_alloc(size); ret = heap_alloc(size);
if(ret) if(ret)
memcpy(ret, str, size); 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_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_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_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, HRESULT create_builtin_function(script_ctx_t*,builtin_invoke_t,const WCHAR*,const builtin_info_t*,DWORD,
jsdisp_t*,jsdisp_t**) DECLSPEC_HIDDEN; 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); 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) static inline BOOL is_int32(double d)
{ {
return INT32_MIN <= d && d <= INT32_MAX && (double)(int)d == d; return INT32_MIN <= d && d <= INT32_MAX && (double)(int)d == d;

View file

@ -23,7 +23,6 @@
#include "parser.h" #include "parser.h"
#include "wine/debug.h" #include "wine/debug.h"
#include "wine/unicode.h"
WINE_DEFAULT_DEBUG_CHANNEL(jscript); WINE_DEFAULT_DEBUG_CHANNEL(jscript);
@ -89,14 +88,14 @@ static HRESULT parse_json_string(json_parse_ctx_t *ctx, WCHAR **r)
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
if(len) if(len)
memcpy(buf, ptr, len*sizeof(WCHAR)); memcpy(buf, ptr, len*sizeof(WCHAR));
buf[len] = 0;
if(!unescape(buf)) { if(!unescape(buf, &len)) {
FIXME("unescape failed\n"); FIXME("unescape failed\n");
heap_free(buf); heap_free(buf);
return E_FAIL; return E_FAIL;
} }
buf[len] = 0;
ctx->ptr++; ctx->ptr++;
*r = buf; *r = buf;
return S_OK; return S_OK;
@ -261,19 +260,12 @@ static HRESULT parse_json_value(json_parse_ctx_t *ctx, jsval_t *r)
skip_spaces(ctx); skip_spaces(ctx);
} }
if(!isdigitW(*ctx->ptr)) if(*ctx->ptr == '0' && ctx->ptr + 1 < ctx->end && iswdigit(ctx->ptr[1]))
break; break;
if(*ctx->ptr == '0') { hres = parse_decimal(&ctx->ptr, ctx->end, &n);
ctx->ptr++; if(FAILED(hres))
n = 0; break;
if(is_identifier_char(*ctx->ptr))
break;
}else {
hres = parse_decimal(&ctx->ptr, ctx->end, &n);
if(FAILED(hres))
return hres;
}
*r = jsval_number(sign*n); *r = jsval_number(sign*n);
return S_OK; 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) 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) 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 < ' ') { if(*ptr < ' ') {
static const WCHAR formatW[] = {'\\','u','%','0','4','x',0}; static const WCHAR formatW[] = {'\\','u','%','0','4','x',0};
WCHAR buf[7]; WCHAR buf[7];
sprintfW(buf, formatW, *ptr); swprintf(buf, formatW, *ptr);
if(!append_string(ctx, buf)) if(!append_string(ctx, buf))
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
}else { }else {

View file

@ -647,12 +647,12 @@ HRESULT create_regexp(script_ctx_t *ctx, jsstr_t *src, DWORD flags, jsdisp_t **r
const WCHAR *str; const WCHAR *str;
HRESULT hres; HRESULT hres;
TRACE("%s %x\n", debugstr_jsstr(src), flags);
str = jsstr_flatten(src); str = jsstr_flatten(src);
if(!str) if(!str)
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
TRACE("%s %x\n", debugstr_wn(str, jsstr_length(src)), flags);
hres = alloc_regexp(ctx, NULL, &regexp); hres = alloc_regexp(ctx, NULL, &regexp);
if(FAILED(hres)) if(FAILED(hres))
return hres; return hres;

View file

@ -102,7 +102,7 @@ jsstr_t *jsstr_alloc_buf(unsigned,WCHAR**) DECLSPEC_HIDDEN;
static inline jsstr_t *jsstr_alloc(const WCHAR *str) 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; void jsstr_free(jsstr_t*) DECLSPEC_HIDDEN;

View file

@ -16,8 +16,10 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
#include "config.h" #ifdef __REACTOS__
#include "wine/port.h" #include <wine/config.h>
#include <wine/port.h>
#endif
#include <math.h> #include <math.h>
#include <assert.h> #include <assert.h>
@ -294,6 +296,12 @@ HRESULT variant_to_jsval(VARIANT *var, jsval_t *r)
*r = jsval_disp(V_DISPATCH(var)); *r = jsval_disp(V_DISPATCH(var));
return S_OK; 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: case VT_I2:
*r = jsval_number(V_I2(var)); *r = jsval_number(V_I2(var));
return S_OK; return S_OK;
@ -516,7 +524,7 @@ static HRESULT str_to_number(jsstr_t *str, double *ret)
if(!ptr) if(!ptr)
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
while(isspaceW(*ptr)) while(iswspace(*ptr))
ptr++; ptr++;
if(*ptr == '-') { if(*ptr == '-') {
@ -526,9 +534,9 @@ static HRESULT str_to_number(jsstr_t *str, double *ret)
ptr++; ptr++;
} }
if(!strncmpW(ptr, infinityW, ARRAY_SIZE(infinityW))) { if(!wcsncmp(ptr, infinityW, ARRAY_SIZE(infinityW))) {
ptr += ARRAY_SIZE(infinityW); ptr += ARRAY_SIZE(infinityW);
while(*ptr && isspaceW(*ptr)) while(*ptr && iswspace(*ptr))
ptr++; ptr++;
if(*ptr) if(*ptr)
@ -551,7 +559,7 @@ static HRESULT str_to_number(jsstr_t *str, double *ret)
return S_OK; return S_OK;
} }
while(isdigitW(*ptr)) while(iswdigit(*ptr))
d = d*10 + (*ptr++ - '0'); d = d*10 + (*ptr++ - '0');
if(*ptr == 'e' || *ptr == 'E') { if(*ptr == 'e' || *ptr == 'E') {
@ -566,7 +574,7 @@ static HRESULT str_to_number(jsstr_t *str, double *ret)
ptr++; ptr++;
} }
while(isdigitW(*ptr)) while(iswdigit(*ptr))
l = l*10 + (*ptr++ - '0'); l = l*10 + (*ptr++ - '0');
if(eneg) if(eneg)
l = -l; l = -l;
@ -576,13 +584,13 @@ static HRESULT str_to_number(jsstr_t *str, double *ret)
DOUBLE dec = 0.1; DOUBLE dec = 0.1;
ptr++; ptr++;
while(isdigitW(*ptr)) { while(iswdigit(*ptr)) {
d += dec * (*ptr++ - '0'); d += dec * (*ptr++ - '0');
dec *= 0.1; dec *= 0.1;
} }
} }
while(isspaceW(*ptr)) while(iswspace(*ptr))
ptr++; ptr++;
if(*ptr) { if(*ptr) {
@ -894,6 +902,14 @@ HRESULT variant_change_type(script_ctx_t *ctx, VARIANT *dst, VARIANT *src, VARTY
} }
break; break;
} }
case VT_UI2: {
UINT32 i;
hres = to_uint32(ctx, val, &i);
if(SUCCEEDED(hres))
V_UI2(dst) = i;
break;
}
case VT_R8: { case VT_R8: {
double n; double n;
hres = to_number(ctx, val, &n); hres = to_number(ctx, val, &n);

View file

@ -16,10 +16,9 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
#include "config.h"
#include "wine/port.h"
#include <limits.h> #include <limits.h>
#include <math.h>
#include "jscript.h" #include "jscript.h"
#include "activscp.h" #include "activscp.h"
@ -30,86 +29,45 @@
#include "parser.tab.h" #include "parser.tab.h"
#include "wine/debug.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); 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 { static const struct {
const WCHAR *word; const WCHAR *word;
int token; int token;
BOOL no_nl; BOOL no_nl;
unsigned min_version; unsigned min_version;
} keywords[] = { } keywords[] = {
{breakW, kBREAK, TRUE}, {L"break", kBREAK, TRUE},
{caseW, kCASE}, {L"case", kCASE},
{catchW, kCATCH}, {L"catch", kCATCH},
{continueW, kCONTINUE, TRUE}, {L"continue", kCONTINUE, TRUE},
{defaultW, kDEFAULT}, {L"default", kDEFAULT},
{deleteW, kDELETE}, {L"delete", kDELETE},
{doW, kDO}, {L"do", kDO},
{elseW, kELSE}, {L"else", kELSE},
{falseW, kFALSE}, {L"false", kFALSE},
{finallyW, kFINALLY}, {L"finally", kFINALLY},
{forW, kFOR}, {L"for", kFOR},
{functionW, kFUNCTION}, {L"function", kFUNCTION},
{getW, kGET, FALSE, SCRIPTLANGUAGEVERSION_ES5}, {L"get", kGET, FALSE, SCRIPTLANGUAGEVERSION_ES5},
{ifW, kIF}, {L"if", kIF},
{inW, kIN}, {L"in", kIN},
{instanceofW, kINSTANCEOF}, {L"instanceof", kINSTANCEOF},
{newW, kNEW}, {L"new", kNEW},
{nullW, kNULL}, {L"null", kNULL},
{returnW, kRETURN, TRUE}, {L"return", kRETURN, TRUE},
{setW, kSET, FALSE, SCRIPTLANGUAGEVERSION_ES5}, {L"set", kSET, FALSE, SCRIPTLANGUAGEVERSION_ES5},
{switchW, kSWITCH}, {L"switch", kSWITCH},
{thisW, kTHIS}, {L"this", kTHIS},
{throwW, kTHROW}, {L"throw", kTHROW},
{trueW, kTRUE}, {L"true", kTRUE},
{tryW, kTRY}, {L"try", kTRY},
{typeofW, kTYPEOF}, {L"typeof", kTYPEOF},
{varW, kVAR}, {L"var", kVAR},
{voidW, kVOID}, {L"void", kVOID},
{whileW, kWHILE}, {L"while", kWHILE},
{withW, kWITH} {L"with", kWITH}
}; };
static int lex_error(parser_ctx_t *ctx, HRESULT hres) 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 */ /* ECMA-262 3rd Edition 7.6 */
BOOL is_identifier_char(WCHAR c) 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) 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) 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) { if(ctx->script->version < keywords[i].min_version) {
TRACE("ignoring keyword %s in incompatible mode\n", TRACE("ignoring keyword %s in incompatible mode\n",
debugstr_w(keywords[i].word)); debugstr_w(keywords[i].word));
ctx->ptr -= strlenW(keywords[i].word); ctx->ptr -= lstrlenW(keywords[i].word);
return 0; return 0;
} }
ctx->implicit_nl_semicolon = keywords[i].no_nl; 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) 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++)) if(is_endline(*ctx->ptr++))
ctx->nl = TRUE; ctx->nl = TRUE;
} }
@ -266,19 +224,20 @@ static BOOL skip_spaces(parser_ctx_t *ctx)
return ctx->ptr != ctx->end; 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; int i;
pd = p = str; pd = p = str;
while(*p) { while(p < end) {
if(*p != '\\') { if(*p != '\\') {
*pd++ = *p++; *pd++ = *p++;
continue; continue;
} }
p++; if(++p == end)
return FALSE;
switch(*p) { switch(*p) {
case '\'': case '\'':
@ -302,6 +261,8 @@ BOOL unescape(WCHAR *str)
c = '\r'; c = '\r';
break; break;
case 'x': case 'x':
if(p + 2 >= end)
return FALSE;
i = hex_to_int(*++p); i = hex_to_int(*++p);
if(i == -1) if(i == -1)
return FALSE; return FALSE;
@ -313,6 +274,8 @@ BOOL unescape(WCHAR *str)
c += i; c += i;
break; break;
case 'u': case 'u':
if(p + 4 >= end)
return FALSE;
i = hex_to_int(*++p); i = hex_to_int(*++p);
if(i == -1) if(i == -1)
return FALSE; return FALSE;
@ -334,11 +297,11 @@ BOOL unescape(WCHAR *str)
c += i; c += i;
break; break;
default: default:
if(isdigitW(*p)) { if(iswdigit(*p)) {
c = *p++ - '0'; c = *p++ - '0';
if(isdigitW(*p)) { if(p < end && iswdigit(*p)) {
c = c*8 + (*p++ - '0'); c = c*8 + (*p++ - '0');
if(isdigitW(*p)) if(p < end && iswdigit(*p))
c = c*8 + (*p++ - '0'); c = c*8 + (*p++ - '0');
} }
p--; p--;
@ -351,7 +314,7 @@ BOOL unescape(WCHAR *str)
p++; p++;
} }
*pd = 0; *len = pd - str;
return TRUE; return TRUE;
} }
@ -374,33 +337,41 @@ static int parse_identifier(parser_ctx_t *ctx, const WCHAR **ret)
return tIdentifier; 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; const WCHAR *ptr = ++ctx->ptr, *ret_str = ptr;
WCHAR *wstr; BOOL needs_unescape = FALSE;
int len; WCHAR *unescape_str;
size_t len;
while(ctx->ptr < ctx->end && *ctx->ptr != endch) { while(ctx->ptr < ctx->end && *ctx->ptr != endch) {
if(*ctx->ptr++ == '\\') if(*ctx->ptr++ == '\\') {
ctx->ptr++; ctx->ptr++;
needs_unescape = TRUE;
}
} }
if(ctx->ptr == ctx->end) if(ctx->ptr == ctx->end)
return lex_error(ctx, JS_E_UNTERMINATED_STRING); return lex_error(ctx, JS_E_UNTERMINATED_STRING);
len = ctx->ptr-ptr; len = ctx->ptr - ptr;
*ret = wstr = parser_alloc(ctx, (len+1)*sizeof(WCHAR));
memcpy(wstr, ptr, len*sizeof(WCHAR));
wstr[len] = 0;
ctx->ptr++; ctx->ptr++;
if(!unescape(wstr)) { if(needs_unescape) {
WARN("unescape failed\n"); ret_str = unescape_str = parser_alloc(ctx, len * sizeof(WCHAR));
return lex_error(ctx, E_FAIL); 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; return tStringLiteral;
} }
@ -429,7 +400,7 @@ HRESULT parse_decimal(const WCHAR **iter, const WCHAR *end, double *ret)
LONGLONG d = 0, hlp; LONGLONG d = 0, hlp;
int exp = 0; int exp = 0;
while(ptr < end && isdigitW(*ptr)) { while(ptr < end && iswdigit(*ptr)) {
hlp = d*10 + *(ptr++) - '0'; hlp = d*10 + *(ptr++) - '0';
if(d>MAXLONGLONG/10 || hlp<0) { if(d>MAXLONGLONG/10 || hlp<0) {
exp++; exp++;
@ -438,7 +409,7 @@ HRESULT parse_decimal(const WCHAR **iter, const WCHAR *end, double *ret)
else else
d = hlp; d = hlp;
} }
while(ptr < end && isdigitW(*ptr)) { while(ptr < end && iswdigit(*ptr)) {
exp++; exp++;
ptr++; ptr++;
} }
@ -446,7 +417,7 @@ HRESULT parse_decimal(const WCHAR **iter, const WCHAR *end, double *ret)
if(*ptr == '.') { if(*ptr == '.') {
ptr++; ptr++;
while(ptr < end && isdigitW(*ptr)) { while(ptr < end && iswdigit(*ptr)) {
hlp = d*10 + *(ptr++) - '0'; hlp = d*10 + *(ptr++) - '0';
if(d>MAXLONGLONG/10 || hlp<0) if(d>MAXLONGLONG/10 || hlp<0)
break; break;
@ -454,7 +425,7 @@ HRESULT parse_decimal(const WCHAR **iter, const WCHAR *end, double *ret)
d = hlp; d = hlp;
exp--; exp--;
} }
while(ptr < end && isdigitW(*ptr)) while(ptr < end && iswdigit(*ptr))
ptr++; ptr++;
} }
@ -467,7 +438,7 @@ HRESULT parse_decimal(const WCHAR **iter, const WCHAR *end, double *ret)
}else if(*ptr == '-') { }else if(*ptr == '-') {
sign = -1; sign = -1;
ptr++; ptr++;
}else if(!isdigitW(*ptr)) { }else if(!iswdigit(*ptr)) {
WARN("Expected exponent part\n"); WARN("Expected exponent part\n");
return E_FAIL; return E_FAIL;
} }
@ -478,7 +449,7 @@ HRESULT parse_decimal(const WCHAR **iter, const WCHAR *end, double *ret)
return E_FAIL; return E_FAIL;
} }
while(ptr < end && isdigitW(*ptr)) { while(ptr < end && iswdigit(*ptr)) {
if(e > INT_MAX/10 || (e = e*10 + *ptr++ - '0')<0) if(e > INT_MAX/10 || (e = e*10 + *ptr++ - '0')<0)
e = INT_MAX; e = INT_MAX;
} }
@ -529,12 +500,12 @@ static BOOL parse_numeric_literal(parser_ctx_t *ctx, double *ret)
return TRUE; return TRUE;
} }
if(isdigitW(*ctx->ptr)) { if(iswdigit(*ctx->ptr)) {
unsigned base = 8; unsigned base = 8;
const WCHAR *ptr; const WCHAR *ptr;
double val = 0; 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') { if(*ptr > '7') {
base = 10; base = 10;
break; break;
@ -543,7 +514,7 @@ static BOOL parse_numeric_literal(parser_ctx_t *ctx, double *ret)
do { do {
val = val*base + *ctx->ptr-'0'; 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? */ /* FIXME: Do we need it here? */
if(ctx->ptr < ctx->end && (is_identifier_char(*ctx->ptr) || *ctx->ptr == '.')) { 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; ctx->implicit_nl_semicolon = FALSE;
} }
if(isalphaW(*ctx->ptr)) { if(iswalpha(*ctx->ptr)) {
int ret = check_keywords(ctx, lval); int ret = check_keywords(ctx, lval);
if(ret) if(ret)
return ret; return ret;
@ -593,7 +564,7 @@ static int next_token(parser_ctx_t *ctx, void *lval)
return parse_identifier(ctx, lval); return parse_identifier(ctx, lval);
} }
if(isdigitW(*ctx->ptr)) { if(iswdigit(*ctx->ptr)) {
double n; double n;
if(!parse_numeric_literal(ctx, &n)) if(!parse_numeric_literal(ctx, &n))
@ -620,7 +591,7 @@ static int next_token(parser_ctx_t *ctx, void *lval)
return '}'; return '}';
case '.': case '.':
if(ctx->ptr+1 < ctx->end && isdigitW(ctx->ptr[1])) { if(ctx->ptr+1 < ctx->end && iswdigit(ctx->ptr[1])) {
double n; double n;
HRESULT hres; HRESULT hres;
hres = parse_decimal(&ctx->ptr, ctx->end, &n); 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; cc_var_t *new_v;
if(len == -1) if(len == -1)
len = strlenW(name); len = lstrlenW(name);
new_v = heap_alloc(sizeof(cc_var_t) + (len+1)*sizeof(WCHAR)); new_v = heap_alloc(sizeof(cc_var_t) + (len+1)*sizeof(WCHAR));
if(!new_v) if(!new_v)
@ -890,14 +861,6 @@ static BOOL init_cc(parser_ctx_t *ctx)
{ {
cc_ctx_t *cc; 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) if(ctx->script->cc)
return TRUE; return TRUE;
@ -909,11 +872,11 @@ static BOOL init_cc(parser_ctx_t *ctx)
cc->vars = NULL; cc->vars = NULL;
if(!new_cc_var(cc, _jscriptW, -1, ccval_bool(TRUE)) if(!new_cc_var(cc, L"_jscript", -1, ccval_bool(TRUE))
|| !new_cc_var(cc, sizeof(void*) == 8 ? _win64W : _win32W, -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 ? _amd64W : _x86W, -1, ccval_bool(TRUE)) || !new_cc_var(cc, sizeof(void*) == 8 ? L"_amd64" : L"_x86", -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, L"_jscript_version", -1, ccval_num(JSCRIPT_MAJOR_VERSION + (DOUBLE)JSCRIPT_MINOR_VERSION/10.0))
|| !new_cc_var(cc, _jscript_buildW, -1, ccval_num(JSCRIPT_BUILD_VERSION))) { || !new_cc_var(cc, L"_jscript_build", -1, ccval_num(JSCRIPT_BUILD_VERSION))) {
release_cc(cc); release_cc(cc);
lex_error(ctx, E_OUTOFMEMORY); lex_error(ctx, E_OUTOFMEMORY);
return FALSE; return FALSE;
@ -946,7 +909,7 @@ int try_parse_ccval(parser_ctx_t *ctx, ccval_t *r)
if(!skip_spaces(ctx)) if(!skip_spaces(ctx))
return -1; return -1;
if(isdigitW(*ctx->ptr)) { if(iswdigit(*ctx->ptr)) {
double n; double n;
if(!parse_numeric_literal(ctx, &n)) if(!parse_numeric_literal(ctx, &n))
@ -969,12 +932,12 @@ int try_parse_ccval(parser_ctx_t *ctx, ccval_t *r)
return 1; return 1;
} }
if(!check_keyword(ctx, trueW, NULL)) { if(!check_keyword(ctx, L"true", NULL)) {
*r = ccval_bool(TRUE); *r = ccval_bool(TRUE);
return 1; return 1;
} }
if(!check_keyword(ctx, falseW, NULL)) { if(!check_keyword(ctx, L"false", NULL)) {
*r = ccval_bool(FALSE); *r = ccval_bool(FALSE);
return 1; return 1;
} }
@ -988,20 +951,20 @@ static int skip_code(parser_ctx_t *ctx, BOOL exec_else)
const WCHAR *ptr; const WCHAR *ptr;
while(1) { while(1) {
ptr = strchrW(ctx->ptr, '@'); ptr = wcschr(ctx->ptr, '@');
if(!ptr) { if(!ptr) {
WARN("No @end\n"); WARN("No @end\n");
return lex_error(ctx, JS_E_EXPECTED_CCEND); return lex_error(ctx, JS_E_EXPECTED_CCEND);
} }
ctx->ptr = ptr+1; ctx->ptr = ptr+1;
if(!check_keyword(ctx, endW, NULL)) { if(!check_keyword(ctx, L"end", NULL)) {
if(--if_depth) if(--if_depth)
continue; continue;
return 0; return 0;
} }
if(exec_else && !check_keyword(ctx, elifW, NULL)) { if(exec_else && !check_keyword(ctx, L"elif", NULL)) {
if(if_depth > 1) if(if_depth > 1)
continue; continue;
@ -1019,7 +982,7 @@ static int skip_code(parser_ctx_t *ctx, BOOL exec_else)
return 0; return 0;
} }
if(exec_else && !check_keyword(ctx, elseW, NULL)) { if(exec_else && !check_keyword(ctx, L"else", NULL)) {
if(if_depth > 1) if(if_depth > 1)
continue; continue;
@ -1028,7 +991,7 @@ static int skip_code(parser_ctx_t *ctx, BOOL exec_else)
return 0; return 0;
} }
if(!check_keyword(ctx, ifW, NULL)) { if(!check_keyword(ctx, L"if", NULL)) {
if_depth++; if_depth++;
continue; continue;
} }
@ -1042,15 +1005,12 @@ static int cc_token(parser_ctx_t *ctx, void *lval)
unsigned id_len = 0; unsigned id_len = 0;
cc_var_t *var; cc_var_t *var;
static const WCHAR cc_onW[] = {'c','c','_','o','n',0};
static const WCHAR setW[] = {'s','e','t',0};
ctx->ptr++; ctx->ptr++;
if(!check_keyword(ctx, cc_onW, NULL)) if(!check_keyword(ctx, L"cc_on", NULL))
return init_cc(ctx) ? 0 : -1; return init_cc(ctx) ? 0 : -1;
if(!check_keyword(ctx, setW, NULL)) { if(!check_keyword(ctx, L"set", NULL)) {
const WCHAR *ident; const WCHAR *ident;
unsigned ident_len; unsigned ident_len;
cc_var_t *var; cc_var_t *var;
@ -1084,7 +1044,7 @@ static int cc_token(parser_ctx_t *ctx, void *lval)
return 0; return 0;
} }
if(!check_keyword(ctx, ifW, NULL)) { if(!check_keyword(ctx, L"if", NULL)) {
if(!init_cc(ctx)) if(!init_cc(ctx))
return -1; return -1;
@ -1103,14 +1063,14 @@ static int cc_token(parser_ctx_t *ctx, void *lval)
return skip_code(ctx, TRUE); 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) if(!ctx->cc_if_depth)
return lex_error(ctx, JS_E_SYNTAX); return lex_error(ctx, JS_E_SYNTAX);
return skip_code(ctx, FALSE); return skip_code(ctx, FALSE);
} }
if(!check_keyword(ctx, endW, NULL)) { if(!check_keyword(ctx, L"end", NULL)) {
if(!ctx->cc_if_depth) if(!ctx->cc_if_depth)
return lex_error(ctx, JS_E_SYNTAX); return lex_error(ctx, JS_E_SYNTAX);
@ -1193,7 +1153,7 @@ literal_t *parse_regexp(parser_ctx_t *ctx)
re_len = ctx->ptr-re; re_len = ctx->ptr-re;
flags_ptr = ++ctx->ptr; flags_ptr = ++ctx->ptr;
while(ctx->ptr < ctx->end && isalnumW(*ctx->ptr)) while(ctx->ptr < ctx->end && iswalnum(*ctx->ptr))
ctx->ptr++; ctx->ptr++;
hres = parse_regexp_flags(flags_ptr, ctx->ptr-flags_ptr, &flags); 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 = parser_alloc(ctx, sizeof(literal_t));
ret->type = LT_REGEXP; ret->type = LT_REGEXP;
ret->u.regexp.str = re; ret->u.regexp.str = compiler_alloc_string_len(ctx->compiler, re, re_len);
ret->u.regexp.str_len = re_len;
ret->u.regexp.flags = flags; ret->u.regexp.flags = flags;
return ret; return ret;
} }

View file

@ -17,8 +17,10 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
#include "config.h" #ifdef __REACTOS__
#include "wine/port.h" #include <wine/config.h>
#include <wine/port.h>
#endif
#include <math.h> #include <math.h>
#include <limits.h> #include <limits.h>

View file

@ -332,7 +332,7 @@ static HRESULT Number_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, u
ch = '-'; ch = '-';
} }
else ch = '+'; else ch = '+';
sprintfW(&buf[idx], formatW, ch, (int)log_radix); swprintf(&buf[idx], formatW, ch, (int)log_radix);
} }
} }
else buf[idx] = '\0'; else buf[idx] = '\0';

View file

@ -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}; {'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 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[] = 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}; {'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 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}; 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; jsstr_t *ret;
WCHAR *ptr; WCHAR *ptr;
ret = jsstr_alloc_buf(9+strlenW(str), &ptr); ret = jsstr_alloc_buf(9+lstrlenW(str), &ptr);
if(!ret) if(!ret)
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
sprintfW(ptr, formatW, str); swprintf(ptr, formatW, str);
*r = jsval_string(ret); *r = jsval_string(ret);
} }
@ -406,6 +409,57 @@ static HRESULT to_property_descriptor(script_ctx_t *ctx, jsdisp_t *attr_obj, pro
return hres; 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, static HRESULT Object_defineProperty(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
unsigned argc, jsval_t *argv, jsval_t *r) 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); hres = jsdisp_define_property(obj, name, &prop_desc);
release_property_descriptor(&prop_desc); release_property_descriptor(&prop_desc);
if(SUCCEEDED(hres) && r)
*r = jsval_obj(jsdisp_addref(obj));
return hres; return hres;
} }
static HRESULT Object_defineProperties(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, static HRESULT Object_defineProperties(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
unsigned argc, jsval_t *argv, jsval_t *r) unsigned argc, jsval_t *argv, jsval_t *r)
{ {
FIXME("\n"); jsdisp_t *obj;
return E_NOTIMPL; 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, 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; 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[] = { static const builtin_prop_t ObjectConstr_props[] = {
{createW, Object_create, PROPF_ES5|PROPF_METHOD|2},
{definePropertiesW, Object_defineProperties, PROPF_ES5|PROPF_METHOD|2}, {definePropertiesW, Object_defineProperties, PROPF_ES5|PROPF_METHOD|2},
{definePropertyW, Object_defineProperty, 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 = { static const builtin_info_t ObjectConstr_info = {

View file

@ -36,6 +36,7 @@ typedef struct _parser_ctx_t {
const WCHAR *ptr; const WCHAR *ptr;
script_ctx_t *script; script_ctx_t *script;
struct _compiler_ctx_t *compiler;
source_elements_t *source; source_elements_t *source;
BOOL nl; BOOL nl;
BOOL implicit_nl_semicolon; BOOL implicit_nl_semicolon;
@ -49,7 +50,7 @@ typedef struct _parser_ctx_t {
heap_pool_t heap; heap_pool_t heap;
} parser_ctx_t; } 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; void parser_release(parser_ctx_t*) DECLSPEC_HIDDEN;
int parser_lex(void*,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 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; HRESULT parse_decimal(const WCHAR**,const WCHAR*,double*) DECLSPEC_HIDDEN;
typedef enum { typedef enum {
@ -80,11 +81,10 @@ typedef struct {
literal_type_t type; literal_type_t type;
union { union {
double dval; double dval;
const WCHAR *wstr; jsstr_t *str;
BOOL bval; BOOL bval;
struct { struct {
const WCHAR *str; jsstr_t *str;
DWORD str_len;
DWORD flags; DWORD flags;
} regexp; } regexp;
} u; } u;
@ -401,3 +401,5 @@ static inline double get_ccnum(ccval_t v)
{ {
return v.is_num ? v.u.n : v.u.b; 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;

File diff suppressed because it is too large Load diff

View file

@ -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 /* 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 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 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 This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */ 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_PARSER_E_REACTOSSYNC_GCC_DLL_WIN32_JSCRIPT_PARSER_TAB_H_INCLUDED #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 # define YY_PARSER_E_REACTOSSYNC_GCC_DLL_WIN32_JSCRIPT_PARSER_TAB_H_INCLUDED
/* Debug traces. */ /* Debug traces. */
@ -97,14 +101,13 @@ extern int parser_debug;
/* Value type. */ /* Value type. */
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE YYSTYPE;
union YYSTYPE union YYSTYPE
{ {
#line 147 "parser.y" /* yacc.c:1909 */ #line 147 "parser.y"
int ival; int ival;
const WCHAR *srcptr; const WCHAR *srcptr;
LPCWSTR wstr; jsstr_t *str;
literal_t *literal; literal_t *literal;
struct _argument_list_t *argument_list; struct _argument_list_t *argument_list;
case_clausule_t *case_clausule; case_clausule_t *case_clausule;
@ -122,8 +125,10 @@ union YYSTYPE
struct _variable_list_t *variable_list; struct _variable_list_t *variable_list;
variable_declaration_t *variable_declaration; variable_declaration_t *variable_declaration;
#line 126 "parser.tab.h" /* yacc.c:1909 */ #line 129 "parser.tab.h"
}; };
typedef union YYSTYPE YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1 # define YYSTYPE_IS_TRIVIAL 1
# define YYSTYPE_IS_DECLARED 1 # define YYSTYPE_IS_DECLARED 1
#endif #endif

View file

@ -37,7 +37,7 @@ typedef struct _statement_list_t {
statement_t *tail; statement_t *tail;
} statement_list_t; } 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*); static literal_t *new_null_literal(parser_ctx_t*);
typedef struct _property_list_t { typedef struct _property_list_t {
@ -141,13 +141,13 @@ static source_elements_t *source_elements_add_statement(source_elements_t*,state
%lex-param { parser_ctx_t *ctx } %lex-param { parser_ctx_t *ctx }
%parse-param { parser_ctx_t *ctx } %parse-param { parser_ctx_t *ctx }
%pure-parser %define api.pure
%start Program %start Program
%union { %union {
int ival; int ival;
const WCHAR *srcptr; const WCHAR *srcptr;
LPCWSTR wstr; jsstr_t *str;
literal_t *literal; literal_t *literal;
struct _argument_list_t *argument_list; struct _argument_list_t *argument_list;
case_clausule_t *case_clausule; case_clausule_t *case_clausule;
@ -177,7 +177,7 @@ static source_elements_t *source_elements_add_statement(source_elements_t*,state
%token <identifier> tIdentifier %token <identifier> tIdentifier
%token <ival> tAssignOper tEqOper tShiftOper tRelOper %token <ival> tAssignOper tEqOper tShiftOper tRelOper
%token <literal> tNumericLiteral tBooleanLiteral %token <literal> tNumericLiteral tBooleanLiteral
%token <wstr> tStringLiteral %token <str> tStringLiteral
%token tEOF %token tEOF
%type <source_elements> SourceElements %type <source_elements> SourceElements
@ -813,7 +813,7 @@ GetterSetterMethod
/* Ecma-262 3rd Edition 11.1.5 */ /* Ecma-262 3rd Edition 11.1.5 */
PropertyName PropertyName
: IdentifierName { $$ = new_string_literal(ctx, $1); } : IdentifierName { $$ = new_string_literal(ctx, compiler_alloc_string_len(ctx->compiler, $1, lstrlenW($1))); }
| tStringLiteral { $$ = new_string_literal(ctx, $1); } | tStringLiteral { $$ = new_string_literal(ctx, $1); }
| tNumericLiteral { $$ = $1; } | tNumericLiteral { $$ = $1; }
@ -921,12 +921,12 @@ static void *new_statement(parser_ctx_t *ctx, statement_type_t type, size_t size
return stat; return stat;
} }
static literal_t *new_string_literal(parser_ctx_t *ctx, const WCHAR *str) static literal_t *new_string_literal(parser_ctx_t *ctx, jsstr_t *str)
{ {
literal_t *ret = parser_alloc(ctx, sizeof(literal_t)); literal_t *ret = parser_alloc(ctx, sizeof(literal_t));
ret->type = LT_STRING; ret->type = LT_STRING;
ret->u.wstr = str; ret->u.str = str;
return ret; return ret;
} }
@ -1566,7 +1566,7 @@ void parser_release(parser_ctx_t *ctx)
heap_free(ctx); heap_free(ctx);
} }
HRESULT script_parse(script_ctx_t *ctx, const WCHAR *code, const WCHAR *delimiter, BOOL from_eval, HRESULT script_parse(script_ctx_t *ctx, struct _compiler_ctx_t *compiler, const WCHAR *code, const WCHAR *delimiter, BOOL from_eval,
parser_ctx_t **ret) parser_ctx_t **ret)
{ {
parser_ctx_t *parser_ctx; parser_ctx_t *parser_ctx;
@ -1580,10 +1580,10 @@ HRESULT script_parse(script_ctx_t *ctx, const WCHAR *code, const WCHAR *delimite
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
parser_ctx->hres = JS_E_SYNTAX; parser_ctx->hres = JS_E_SYNTAX;
parser_ctx->is_html = delimiter && !strcmpiW(delimiter, html_tagW); parser_ctx->is_html = delimiter && !wcsicmp(delimiter, html_tagW);
parser_ctx->begin = parser_ctx->ptr = code; parser_ctx->begin = parser_ctx->ptr = code;
parser_ctx->end = parser_ctx->begin + strlenW(parser_ctx->begin); parser_ctx->end = parser_ctx->begin + lstrlenW(parser_ctx->begin);
script_addref(ctx); script_addref(ctx);
parser_ctx->script = ctx; parser_ctx->script = ctx;
@ -1591,7 +1591,10 @@ HRESULT script_parse(script_ctx_t *ctx, const WCHAR *code, const WCHAR *delimite
mark = heap_pool_mark(&ctx->tmp_heap); mark = heap_pool_mark(&ctx->tmp_heap);
heap_pool_init(&parser_ctx->heap); heap_pool_init(&parser_ctx->heap);
parser_ctx->compiler = compiler;
parser_parse(parser_ctx); parser_parse(parser_ctx);
parser_ctx->compiler = NULL;
heap_pool_clear(mark); heap_pool_clear(mark);
hres = parser_ctx->hres; hres = parser_ctx->hres;
if(FAILED(hres)) { if(FAILED(hres)) {

View file

@ -1142,8 +1142,8 @@ lexHex:
for (i = rangeStart; i <= localMax; i++) { for (i = rangeStart; i <= localMax; i++) {
WCHAR uch, dch; WCHAR uch, dch;
uch = toupperW(i); uch = towupper(i);
dch = tolowerW(i); dch = towlower(i);
if(maxch < uch) if(maxch < uch)
maxch = uch; maxch = uch;
if(maxch < dch) if(maxch < dch)
@ -1988,7 +1988,7 @@ FlatNIMatcher(REGlobalData *gData, match_state_t *x, const WCHAR *matchChars,
if (length > (size_t)(gData->cpend - x->cp)) if (length > (size_t)(gData->cpend - x->cp))
return NULL; return NULL;
for (i = 0; i != length; i++) { for (i = 0; i != length; i++) {
if (toupperW(matchChars[i]) != toupperW(x->cp[i])) if (towupper(matchChars[i]) != towupper(x->cp[i]))
return NULL; return NULL;
} }
x->cp += length; x->cp += length;
@ -2035,7 +2035,7 @@ BackrefMatcher(REGlobalData *gData, match_state_t *x, size_t parenIndex)
parenContent = &gData->cpbegin[cap->index]; parenContent = &gData->cpbegin[cap->index];
if (gData->regexp->flags & REG_FOLD) { if (gData->regexp->flags & REG_FOLD) {
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
if (toupperW(parenContent[i]) != toupperW(x->cp[i])) if (towupper(parenContent[i]) != towupper(x->cp[i]))
return NULL; return NULL;
} }
} else { } else {
@ -2226,12 +2226,12 @@ ProcessCharSet(REGlobalData *gData, RECharSet *charSet)
continue; continue;
case 's': case 's':
for (i = (INT)charSet->length; i >= 0; i--) for (i = (INT)charSet->length; i >= 0; i--)
if (isspaceW(i)) if (iswspace(i))
AddCharacterToCharSet(charSet, (WCHAR)i); AddCharacterToCharSet(charSet, (WCHAR)i);
continue; continue;
case 'S': case 'S':
for (i = (INT)charSet->length; i >= 0; i--) for (i = (INT)charSet->length; i >= 0; i--)
if (!isspaceW(i)) if (!iswspace(i))
AddCharacterToCharSet(charSet, (WCHAR)i); AddCharacterToCharSet(charSet, (WCHAR)i);
continue; continue;
case 'w': case 'w':
@ -2263,8 +2263,8 @@ ProcessCharSet(REGlobalData *gData, RECharSet *charSet)
WCHAR uch, dch; WCHAR uch, dch;
AddCharacterToCharSet(charSet, i); AddCharacterToCharSet(charSet, i);
uch = toupperW(i); uch = towupper(i);
dch = tolowerW(i); dch = towlower(i);
if (i != uch) if (i != uch)
AddCharacterToCharSet(charSet, uch); AddCharacterToCharSet(charSet, uch);
if (i != dch) if (i != dch)
@ -2276,8 +2276,8 @@ ProcessCharSet(REGlobalData *gData, RECharSet *charSet)
inRange = FALSE; inRange = FALSE;
} else { } else {
if (gData->regexp->flags & REG_FOLD) { if (gData->regexp->flags & REG_FOLD) {
AddCharacterToCharSet(charSet, toupperW(thisCh)); AddCharacterToCharSet(charSet, towupper(thisCh));
AddCharacterToCharSet(charSet, tolowerW(thisCh)); AddCharacterToCharSet(charSet, towlower(thisCh));
} else { } else {
AddCharacterToCharSet(charSet, thisCh); AddCharacterToCharSet(charSet, thisCh);
} }
@ -2411,13 +2411,13 @@ SimpleMatch(REGlobalData *gData, match_state_t *x, REOp op,
} }
break; break;
case REOP_SPACE: case REOP_SPACE:
if (x->cp != gData->cpend && isspaceW(*x->cp)) { if (x->cp != gData->cpend && iswspace(*x->cp)) {
result = x; result = x;
result->cp++; result->cp++;
} }
break; break;
case REOP_NONSPACE: case REOP_NONSPACE:
if (x->cp != gData->cpend && !isspaceW(*x->cp)) { if (x->cp != gData->cpend && !iswspace(*x->cp)) {
result = x; result = x;
result->cp++; result->cp++;
} }
@ -2463,7 +2463,7 @@ SimpleMatch(REGlobalData *gData, match_state_t *x, REOp op,
break; break;
case REOP_FLAT1i: case REOP_FLAT1i:
matchCh = *pc++; matchCh = *pc++;
if (x->cp != gData->cpend && toupperW(*x->cp) == toupperW(matchCh)) { if (x->cp != gData->cpend && towupper(*x->cp) == towupper(matchCh)) {
result = x; result = x;
result->cp++; result->cp++;
} }
@ -2480,7 +2480,7 @@ SimpleMatch(REGlobalData *gData, match_state_t *x, REOp op,
case REOP_UCFLAT1i: case REOP_UCFLAT1i:
matchCh = GET_ARG(pc); matchCh = GET_ARG(pc);
pc += ARG_LEN; pc += ARG_LEN;
if (x->cp != gData->cpend && toupperW(*x->cp) == toupperW(matchCh)) { if (x->cp != gData->cpend && towupper(*x->cp) == towupper(matchCh)) {
result = x; result = x;
result->cp++; result->cp++;
} }

View file

@ -16,8 +16,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
#include "config.h"
#include "wine/port.h" #include <math.h>
#include "jscript.h" #include "jscript.h"
#include "regexp.h" #include "regexp.h"
@ -168,7 +168,7 @@ static HRESULT do_attributeless_tag_format(script_ctx_t *ctx, vdisp_t *jsthis, j
return S_OK; return S_OK;
} }
tagname_len = strlenW(tagname); tagname_len = lstrlenW(tagname);
ret = jsstr_alloc_buf(jsstr_length(str) + 2*tagname_len + 5, &ptr); ret = jsstr_alloc_buf(jsstr_length(str) + 2*tagname_len + 5, &ptr);
if(!ret) { if(!ret) {
@ -215,8 +215,8 @@ static HRESULT do_attribute_tag_format(script_ctx_t *ctx, vdisp_t *jsthis, unsig
} }
if(r) { if(r) {
unsigned attrname_len = strlenW(attrname); unsigned attrname_len = lstrlenW(attrname);
unsigned tagname_len = strlenW(tagname); unsigned tagname_len = lstrlenW(tagname);
jsstr_t *ret; jsstr_t *ret;
WCHAR *ptr; WCHAR *ptr;
@ -853,7 +853,7 @@ static HRESULT String_replace(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un
match->cp = str; match->cp = str;
} }
match->cp = strstrW(match->cp, match_str); match->cp = wcsstr(match->cp, match_str);
if(!match->cp) if(!match->cp)
break; break;
match->match_len = jsstr_length(match_jsstr); match->match_len = jsstr_length(match_jsstr);
@ -879,7 +879,7 @@ static HRESULT String_replace(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un
}else if(rep_str && regexp) { }else if(rep_str && regexp) {
const WCHAR *ptr = rep_str, *ptr2; const WCHAR *ptr = rep_str, *ptr2;
while((ptr2 = strchrW(ptr, '$'))) { while((ptr2 = wcschr(ptr, '$'))) {
hres = strbuf_append(&ret, ptr, ptr2-ptr); hres = strbuf_append(&ret, ptr, ptr2-ptr);
if(FAILED(hres)) if(FAILED(hres))
break; break;
@ -904,14 +904,14 @@ static HRESULT String_replace(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un
default: { default: {
DWORD idx; DWORD idx;
if(!isdigitW(ptr2[1])) { if(!iswdigit(ptr2[1])) {
hres = strbuf_append(&ret, ptr2, 1); hres = strbuf_append(&ret, ptr2, 1);
ptr = ptr2+1; ptr = ptr2+1;
break; break;
} }
idx = ptr2[1] - '0'; idx = ptr2[1] - '0';
if(isdigitW(ptr2[2]) && idx*10 + (ptr2[2]-'0') <= match->paren_count) { if(iswdigit(ptr2[2]) && idx*10 + (ptr2[2]-'0') <= match->paren_count) {
idx = idx*10 + (ptr[2]-'0'); idx = idx*10 + (ptr[2]-'0');
ptr = ptr2+3; ptr = ptr2+3;
}else if(idx && idx <= match->paren_count) { }else if(idx && idx <= match->paren_count) {
@ -1131,21 +1131,20 @@ static HRESULT String_split(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsi
jsval_t *r) jsval_t *r)
{ {
match_state_t match_result, *match_ptr = &match_result; match_state_t match_result, *match_ptr = &match_result;
DWORD length, i, match_len = 0; size_t length, i = 0, match_len = 0;
const WCHAR *ptr, *ptr2, *str, *match_str = NULL; const WCHAR *ptr, *ptr2, *str, *match_str = NULL;
unsigned limit = ~0u; unsigned limit = ~0u;
jsdisp_t *array, *regexp = NULL; jsdisp_t *array, *regexp = NULL;
jsstr_t *jsstr, *match_jsstr, *tmp_str; jsstr_t *jsstr, *match_jsstr, *tmp_str;
HRESULT hres; HRESULT hres;
TRACE("\n");
hres = get_string_flat_val(ctx, jsthis, &jsstr, &str); hres = get_string_flat_val(ctx, jsthis, &jsstr, &str);
if(FAILED(hres)) if(FAILED(hres))
return hres; return hres;
length = jsstr_length(jsstr); length = jsstr_length(jsstr);
TRACE("%s\n", debugstr_wn(str, length));
if(!argc || (is_undefined(argv[0]) && ctx->version >= SCRIPTLANGUAGEVERSION_ES5)) { if(!argc || (is_undefined(argv[0]) && ctx->version >= SCRIPTLANGUAGEVERSION_ES5)) {
if(!r) if(!r)
return S_OK; return S_OK;
@ -1203,14 +1202,32 @@ static HRESULT String_split(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsi
if(SUCCEEDED(hres)) { if(SUCCEEDED(hres)) {
ptr = str; ptr = str;
match_result.cp = str; match_result.cp = str;
for(i=0; i<limit; i++) { while(i < limit) {
if(regexp) { if(regexp) {
hres = regexp_match_next(ctx, regexp, REM_NO_PARENS, jsstr, &match_ptr); hres = regexp_match_next(ctx, regexp, REM_NO_PARENS, jsstr, &match_ptr);
if(hres != S_OK) if(hres != S_OK)
break; break;
TRACE("got match %d %d\n", (int)(match_result.cp - match_result.match_len - str), match_result.match_len);
if(!match_result.match_len) {
/* If an empty string is matched, prevent including any match in the result */
if(!length) {
limit = 0;
break;
}
if(match_result.cp == ptr) {
match_result.cp++;
hres = regexp_match_next(ctx, regexp, REM_NO_PARENS, jsstr, &match_ptr);
if(hres != S_OK)
break;
TRACE("retried, got match %d %d\n", (int)(match_result.cp - match_result.match_len - str),
match_result.match_len);
}
if(!match_result.match_len && match_result.cp == str + length)
break;
}
ptr2 = match_result.cp - match_result.match_len; ptr2 = match_result.cp - match_result.match_len;
}else if(match_str) { }else if(match_str) {
ptr2 = strstrW(ptr, match_str); ptr2 = wcsstr(ptr, match_str);
if(!ptr2) if(!ptr2)
break; break;
}else { }else {
@ -1219,16 +1236,18 @@ static HRESULT String_split(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsi
ptr2 = ptr+1; ptr2 = ptr+1;
} }
tmp_str = jsstr_alloc_len(ptr, ptr2-ptr); if(!regexp || ptr2 > ptr || ctx->version >= SCRIPTLANGUAGEVERSION_ES5) {
if(!tmp_str) { tmp_str = jsstr_alloc_len(ptr, ptr2-ptr);
hres = E_OUTOFMEMORY; if(!tmp_str) {
break; hres = E_OUTOFMEMORY;
} break;
}
hres = jsdisp_propput_idx(array, i, jsval_string(tmp_str)); hres = jsdisp_propput_idx(array, i++, jsval_string(tmp_str));
jsstr_release(tmp_str); jsstr_release(tmp_str);
if(FAILED(hres)) if(FAILED(hres))
break; break;
}
if(regexp) if(regexp)
ptr = match_result.cp; ptr = match_result.cp;
@ -1242,7 +1261,7 @@ static HRESULT String_split(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsi
if(SUCCEEDED(hres) && (match_str || regexp) && i<limit) { if(SUCCEEDED(hres) && (match_str || regexp) && i<limit) {
DWORD len = (str+length) - ptr; DWORD len = (str+length) - ptr;
if(len || match_str) { if(len || match_str || !length || ctx->version >= SCRIPTLANGUAGEVERSION_ES5) {
tmp_str = jsstr_alloc_len(ptr, len); tmp_str = jsstr_alloc_len(ptr, len);
if(tmp_str) { if(tmp_str) {
@ -1427,7 +1446,7 @@ static HRESULT String_toLowerCase(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags
} }
jsstr_flush(str, buf); jsstr_flush(str, buf);
for (; len--; buf++) *buf = tolowerW(*buf); for (; len--; buf++) *buf = towlower(*buf);
*r = jsval_string(ret); *r = jsval_string(ret);
} }
@ -1459,7 +1478,7 @@ static HRESULT String_toUpperCase(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags
} }
jsstr_flush(str, buf); jsstr_flush(str, buf);
for (; len--; buf++) *buf = toupperW(*buf); for (; len--; buf++) *buf = towupper(*buf);
*r = jsval_string(ret); *r = jsval_string(ret);
} }
@ -1497,8 +1516,8 @@ static HRESULT String_trim(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsig
len = jsstr_length(jsstr); len = jsstr_length(jsstr);
TRACE("%s\n", debugstr_wn(str, len)); TRACE("%s\n", debugstr_wn(str, len));
for(begin = str, end = str + len; begin < end && isspaceW(*begin); begin++); for(begin = str, end = str + len; begin < end && iswspace(*begin); begin++);
while(end > begin + 1 && isspaceW(*(end-1))) end--; while(end > begin + 1 && iswspace(*(end-1))) end--;
if(r) { if(r) {
jsstr_t *ret; jsstr_t *ret;

View file

@ -86,7 +86,7 @@ dll/win32/inseng # Synced to WineStaging-4.18
dll/win32/iphlpapi # Out of sync dll/win32/iphlpapi # Out of sync
dll/win32/itircl # Synced to WineStaging-4.18 dll/win32/itircl # Synced to WineStaging-4.18
dll/win32/itss # Synced to WineStaging-4.18 dll/win32/itss # Synced to WineStaging-4.18
dll/win32/jscript # Synced to WineStaging-4.0 dll/win32/jscript # Synced to WineStaging-4.18
dll/win32/jsproxy # Synced to WineStaging-4.0 dll/win32/jsproxy # Synced to WineStaging-4.0
dll/win32/loadperf # Synced to WineStaging-3.3 dll/win32/loadperf # Synced to WineStaging-3.3
dll/win32/lz32 # Synced to WineStaging-3.3 dll/win32/lz32 # Synced to WineStaging-3.3