Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
f0be56e1
Commit
f0be56e1
authored
Jan 27, 2016
by
Jacek Caban
Committed by
Alexandre Julliard
Jan 28, 2016
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
jscript: Added JSON.parse implementation.
Signed-off-by:
Jacek Caban
<
jacek@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
4e1e2ee4
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
297 additions
and
5 deletions
+297
-5
json.c
dlls/jscript/json.c
+290
-2
lex.c
dlls/jscript/lex.c
+3
-3
parser.h
dlls/jscript/parser.h
+4
-0
No files found.
dlls/jscript/json.c
View file @
f0be56e1
...
@@ -19,6 +19,7 @@
...
@@ -19,6 +19,7 @@
#include <math.h>
#include <math.h>
#include "jscript.h"
#include "jscript.h"
#include "parser.h"
#include "wine/debug.h"
#include "wine/debug.h"
#include "wine/unicode.h"
#include "wine/unicode.h"
...
@@ -28,10 +29,297 @@ WINE_DEFAULT_DEBUG_CHANNEL(jscript);
...
@@ -28,10 +29,297 @@ WINE_DEFAULT_DEBUG_CHANNEL(jscript);
static
const
WCHAR
parseW
[]
=
{
'p'
,
'a'
,
'r'
,
's'
,
'e'
,
0
};
static
const
WCHAR
parseW
[]
=
{
'p'
,
'a'
,
'r'
,
's'
,
'e'
,
0
};
static
const
WCHAR
stringifyW
[]
=
{
's'
,
't'
,
'r'
,
'i'
,
'n'
,
'g'
,
'i'
,
'f'
,
'y'
,
0
};
static
const
WCHAR
stringifyW
[]
=
{
's'
,
't'
,
'r'
,
'i'
,
'n'
,
'g'
,
'i'
,
'f'
,
'y'
,
0
};
static
const
WCHAR
nullW
[]
=
{
'n'
,
'u'
,
'l'
,
'l'
,
0
};
static
const
WCHAR
trueW
[]
=
{
't'
,
'r'
,
'u'
,
'e'
,
0
};
static
const
WCHAR
falseW
[]
=
{
'f'
,
'a'
,
'l'
,
's'
,
'e'
,
0
};
typedef
struct
{
const
WCHAR
*
ptr
;
const
WCHAR
*
end
;
script_ctx_t
*
ctx
;
}
json_parse_ctx_t
;
static
BOOL
is_json_space
(
WCHAR
c
)
{
return
c
==
' '
||
c
==
'\t'
||
c
==
'\n'
||
c
==
'\r'
;
}
static
WCHAR
skip_spaces
(
json_parse_ctx_t
*
ctx
)
{
while
(
is_json_space
(
*
ctx
->
ptr
))
ctx
->
ptr
++
;
return
*
ctx
->
ptr
;
}
static
BOOL
is_keyword
(
json_parse_ctx_t
*
ctx
,
const
WCHAR
*
keyword
)
{
unsigned
i
;
for
(
i
=
0
;
keyword
[
i
];
i
++
)
{
if
(
!
ctx
->
ptr
[
i
]
||
keyword
[
i
]
!=
ctx
->
ptr
[
i
])
return
FALSE
;
}
if
(
is_identifier_char
(
ctx
->
ptr
[
i
]))
return
FALSE
;
ctx
->
ptr
+=
i
;
return
TRUE
;
}
/* ECMA-262 5.1 Edition 15.12.1.1 */
static
HRESULT
parse_json_string
(
json_parse_ctx_t
*
ctx
,
WCHAR
**
r
)
{
const
WCHAR
*
ptr
=
++
ctx
->
ptr
;
size_t
len
;
WCHAR
*
buf
;
while
(
*
ctx
->
ptr
&&
*
ctx
->
ptr
!=
'"'
)
{
if
(
*
ctx
->
ptr
++
==
'\\'
)
ctx
->
ptr
++
;
}
if
(
!*
ctx
->
ptr
)
{
FIXME
(
"unterminated string
\n
"
);
return
E_FAIL
;
}
len
=
ctx
->
ptr
-
ptr
;
buf
=
heap_alloc
((
len
+
1
)
*
sizeof
(
WCHAR
));
if
(
!
buf
)
return
E_OUTOFMEMORY
;
if
(
len
)
memcpy
(
buf
,
ptr
,
len
*
sizeof
(
WCHAR
));
buf
[
len
]
=
0
;
if
(
!
unescape
(
buf
))
{
FIXME
(
"unescape failed
\n
"
);
heap_free
(
buf
);
return
E_FAIL
;
}
ctx
->
ptr
++
;
*
r
=
buf
;
return
S_OK
;
}
/* ECMA-262 5.1 Edition 15.12.1.2 */
static
HRESULT
parse_json_value
(
json_parse_ctx_t
*
ctx
,
jsval_t
*
r
)
{
HRESULT
hres
;
switch
(
skip_spaces
(
ctx
))
{
/* JSONNullLiteral */
case
'n'
:
if
(
!
is_keyword
(
ctx
,
nullW
))
break
;
*
r
=
jsval_null
();
return
S_OK
;
/* JSONBooleanLiteral */
case
't'
:
if
(
!
is_keyword
(
ctx
,
trueW
))
break
;
*
r
=
jsval_bool
(
TRUE
);
return
S_OK
;
case
'f'
:
if
(
!
is_keyword
(
ctx
,
falseW
))
break
;
*
r
=
jsval_bool
(
FALSE
);
return
S_OK
;
/* JSONObject */
case
'{'
:
{
WCHAR
*
prop_name
;
jsdisp_t
*
obj
;
jsval_t
val
;
hres
=
create_object
(
ctx
->
ctx
,
NULL
,
&
obj
);
if
(
FAILED
(
hres
))
return
hres
;
ctx
->
ptr
++
;
if
(
skip_spaces
(
ctx
)
==
'}'
)
{
ctx
->
ptr
++
;
*
r
=
jsval_obj
(
obj
);
return
S_OK
;
}
while
(
1
)
{
if
(
*
ctx
->
ptr
!=
'"'
)
break
;
hres
=
parse_json_string
(
ctx
,
&
prop_name
);
if
(
FAILED
(
hres
))
break
;
if
(
skip_spaces
(
ctx
)
!=
':'
)
{
FIXME
(
"missing ':'
\n
"
);
heap_free
(
prop_name
);
break
;
}
ctx
->
ptr
++
;
hres
=
parse_json_value
(
ctx
,
&
val
);
if
(
SUCCEEDED
(
hres
))
{
hres
=
jsdisp_propput_name
(
obj
,
prop_name
,
val
);
jsval_release
(
val
);
}
heap_free
(
prop_name
);
if
(
FAILED
(
hres
))
break
;
if
(
skip_spaces
(
ctx
)
==
'}'
)
{
ctx
->
ptr
++
;
*
r
=
jsval_obj
(
obj
);
return
S_OK
;
}
if
(
*
ctx
->
ptr
++
!=
','
)
{
FIXME
(
"expected ','
\n
"
);
break
;
}
skip_spaces
(
ctx
);
}
jsdisp_release
(
obj
);
break
;
}
/* JSONString */
case
'"'
:
{
WCHAR
*
string
;
jsstr_t
*
str
;
hres
=
parse_json_string
(
ctx
,
&
string
);
if
(
FAILED
(
hres
))
return
hres
;
/* FIXME: avoid reallocation */
str
=
jsstr_alloc
(
string
);
heap_free
(
string
);
if
(
!
str
)
return
E_OUTOFMEMORY
;
*
r
=
jsval_string
(
str
);
return
S_OK
;
}
/* JSONArray */
case
'['
:
{
jsdisp_t
*
array
;
unsigned
i
=
0
;
jsval_t
val
;
hres
=
create_array
(
ctx
->
ctx
,
0
,
&
array
);
if
(
FAILED
(
hres
))
return
hres
;
ctx
->
ptr
++
;
if
(
skip_spaces
(
ctx
)
==
']'
)
{
ctx
->
ptr
++
;
*
r
=
jsval_obj
(
array
);
return
S_OK
;
}
while
(
1
)
{
hres
=
parse_json_value
(
ctx
,
&
val
);
if
(
FAILED
(
hres
))
break
;
hres
=
jsdisp_propput_idx
(
array
,
i
,
val
);
jsval_release
(
val
);
if
(
FAILED
(
hres
))
break
;
if
(
skip_spaces
(
ctx
)
==
']'
)
{
ctx
->
ptr
++
;
*
r
=
jsval_obj
(
array
);
return
S_OK
;
}
if
(
*
ctx
->
ptr
!=
','
)
{
FIXME
(
"expected ','
\n
"
);
break
;
}
ctx
->
ptr
++
;
i
++
;
}
jsdisp_release
(
array
);
break
;
}
/* JSONNumber */
default:
{
int
sign
=
1
;
double
n
;
if
(
*
ctx
->
ptr
==
'-'
)
{
sign
=
-
1
;
ctx
->
ptr
++
;
skip_spaces
(
ctx
);
}
if
(
!
isdigitW
(
*
ctx
->
ptr
))
break
;
if
(
*
ctx
->
ptr
==
'0'
)
{
ctx
->
ptr
++
;
n
=
0
;
if
(
is_identifier_char
(
*
ctx
->
ptr
))
break
;
}
else
{
hres
=
parse_decimal
(
&
ctx
->
ptr
,
ctx
->
end
,
&
n
);
if
(
FAILED
(
hres
))
return
hres
;
}
*
r
=
jsval_number
(
sign
*
n
);
return
S_OK
;
}
}
FIXME
(
"Syntax error at %s
\n
"
,
debugstr_w
(
ctx
->
ptr
));
return
E_FAIL
;
}
/* ECMA-262 5.1 Edition 15.12.2 */
static
HRESULT
JSON_parse
(
script_ctx_t
*
ctx
,
vdisp_t
*
jsthis
,
WORD
flags
,
unsigned
argc
,
jsval_t
*
argv
,
jsval_t
*
r
)
static
HRESULT
JSON_parse
(
script_ctx_t
*
ctx
,
vdisp_t
*
jsthis
,
WORD
flags
,
unsigned
argc
,
jsval_t
*
argv
,
jsval_t
*
r
)
{
{
FIXME
(
"
\n
"
);
json_parse_ctx_t
parse_ctx
;
return
E_NOTIMPL
;
const
WCHAR
*
buf
;
jsstr_t
*
str
;
jsval_t
ret
;
HRESULT
hres
;
if
(
argc
!=
1
)
{
FIXME
(
"Unsupported args
\n
"
);
return
E_INVALIDARG
;
}
hres
=
to_flat_string
(
ctx
,
argv
[
0
],
&
str
,
&
buf
);
if
(
FAILED
(
hres
))
return
hres
;
TRACE
(
"%s
\n
"
,
debugstr_w
(
buf
));
parse_ctx
.
ptr
=
buf
;
parse_ctx
.
end
=
buf
+
jsstr_length
(
str
);
parse_ctx
.
ctx
=
ctx
;
hres
=
parse_json_value
(
&
parse_ctx
,
&
ret
);
jsstr_release
(
str
);
if
(
FAILED
(
hres
))
return
hres
;
if
(
skip_spaces
(
&
parse_ctx
))
{
FIXME
(
"syntax error
\n
"
);
jsval_release
(
ret
);
return
E_FAIL
;
}
if
(
r
)
*
r
=
ret
;
else
jsval_release
(
ret
);
return
S_OK
;
}
}
static
HRESULT
JSON_stringify
(
script_ctx_t
*
ctx
,
vdisp_t
*
jsthis
,
WORD
flags
,
unsigned
argc
,
jsval_t
*
argv
,
jsval_t
*
r
)
static
HRESULT
JSON_stringify
(
script_ctx_t
*
ctx
,
vdisp_t
*
jsthis
,
WORD
flags
,
unsigned
argc
,
jsval_t
*
argv
,
jsval_t
*
r
)
...
...
dlls/jscript/lex.c
View file @
f0be56e1
...
@@ -109,7 +109,7 @@ static int lex_error(parser_ctx_t *ctx, HRESULT hres)
...
@@ -109,7 +109,7 @@ static int lex_error(parser_ctx_t *ctx, HRESULT hres)
}
}
/* ECMA-262 3rd Edition 7.6 */
/* ECMA-262 3rd Edition 7.6 */
static
BOOL
is_identifier_char
(
WCHAR
c
)
BOOL
is_identifier_char
(
WCHAR
c
)
{
{
return
isalnumW
(
c
)
||
c
==
'$'
||
c
==
'_'
||
c
==
'\\'
;
return
isalnumW
(
c
)
||
c
==
'$'
||
c
==
'_'
||
c
==
'\\'
;
}
}
...
@@ -249,7 +249,7 @@ static BOOL skip_spaces(parser_ctx_t *ctx)
...
@@ -249,7 +249,7 @@ static BOOL skip_spaces(parser_ctx_t *ctx)
return
ctx
->
ptr
!=
ctx
->
end
;
return
ctx
->
ptr
!=
ctx
->
end
;
}
}
static
BOOL
unescape
(
WCHAR
*
str
)
BOOL
unescape
(
WCHAR
*
str
)
{
{
WCHAR
*
pd
,
*
p
,
c
;
WCHAR
*
pd
,
*
p
,
c
;
int
i
;
int
i
;
...
@@ -406,7 +406,7 @@ literal_t *new_boolean_literal(parser_ctx_t *ctx, BOOL bval)
...
@@ -406,7 +406,7 @@ literal_t *new_boolean_literal(parser_ctx_t *ctx, BOOL bval)
return
ret
;
return
ret
;
}
}
static
HRESULT
parse_decimal
(
const
WCHAR
**
iter
,
const
WCHAR
*
end
,
double
*
ret
)
HRESULT
parse_decimal
(
const
WCHAR
**
iter
,
const
WCHAR
*
end
,
double
*
ret
)
{
{
const
WCHAR
*
ptr
=
*
iter
;
const
WCHAR
*
ptr
=
*
iter
;
LONGLONG
d
=
0
,
hlp
;
LONGLONG
d
=
0
,
hlp
;
...
...
dlls/jscript/parser.h
View file @
f0be56e1
...
@@ -62,6 +62,10 @@ static inline void *parser_alloc_tmp(parser_ctx_t *ctx, DWORD size)
...
@@ -62,6 +62,10 @@ static inline void *parser_alloc_tmp(parser_ctx_t *ctx, DWORD size)
return
heap_pool_alloc
(
&
ctx
->
script
->
tmp_heap
,
size
);
return
heap_pool_alloc
(
&
ctx
->
script
->
tmp_heap
,
size
);
}
}
BOOL
is_identifier_char
(
WCHAR
)
DECLSPEC_HIDDEN
;
BOOL
unescape
(
WCHAR
*
)
DECLSPEC_HIDDEN
;
HRESULT
parse_decimal
(
const
WCHAR
**
,
const
WCHAR
*
,
double
*
)
DECLSPEC_HIDDEN
;
typedef
enum
{
typedef
enum
{
LT_DOUBLE
,
LT_DOUBLE
,
LT_STRING
,
LT_STRING
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment