mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
bug 594060, r=cdleary: Reflect.parse(): make source location information optional
This commit is contained in:
parent
f03fe920ff
commit
7488e1af91
@ -60,6 +60,7 @@ CPPSRCS = \
|
||||
testExtendedEq.cpp \
|
||||
testFuncCallback.cpp \
|
||||
testGCChunkAlloc.cpp \
|
||||
testGetPropertyDefault.cpp \
|
||||
testIntString.cpp \
|
||||
testIsAboutToBeFinalized.cpp \
|
||||
testLookup.cpp \
|
||||
|
70
js/src/jsapi-tests/testGetPropertyDefault.cpp
Normal file
70
js/src/jsapi-tests/testGetPropertyDefault.cpp
Normal file
@ -0,0 +1,70 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=8 sw=4 et tw=99:
|
||||
*/
|
||||
|
||||
#include "tests.h"
|
||||
|
||||
#define JSVAL_IS_FALSE(x) ((JSVAL_IS_BOOLEAN(x)) && !(JSVAL_TO_BOOLEAN(x)))
|
||||
#define JSVAL_IS_TRUE(x) ((JSVAL_IS_BOOLEAN(x)) && (JSVAL_TO_BOOLEAN(x)))
|
||||
|
||||
static JSBool
|
||||
stringToId(JSContext *cx, const char *s, jsid *idp)
|
||||
{
|
||||
char *buf = JS_strdup(cx, s);
|
||||
if (!buf)
|
||||
return false;
|
||||
|
||||
JSString *str = JS_NewString(cx, buf, strlen(s));
|
||||
if (!str)
|
||||
return false;
|
||||
|
||||
return JS_ValueToId(cx, STRING_TO_JSVAL(str), idp);
|
||||
}
|
||||
|
||||
BEGIN_TEST(testGetPropertyDefault_bug594060)
|
||||
{
|
||||
{
|
||||
// Check JS_GetPropertyDefault
|
||||
|
||||
JSObject *obj = JS_NewObject(cx, NULL, NULL, NULL);
|
||||
CHECK(obj);
|
||||
|
||||
jsval v0 = JSVAL_TRUE;
|
||||
CHECK(JS_SetProperty(cx, obj, "here", &v0));
|
||||
|
||||
jsval v1;
|
||||
CHECK(JS_GetPropertyDefault(cx, obj, "here", JSVAL_FALSE, &v1));
|
||||
CHECK(JSVAL_IS_TRUE(v1));
|
||||
|
||||
jsval v2;
|
||||
CHECK(JS_GetPropertyDefault(cx, obj, "nothere", JSVAL_FALSE, &v2));
|
||||
CHECK(JSVAL_IS_FALSE(v2));
|
||||
}
|
||||
|
||||
{
|
||||
// Check JS_GetPropertyByIdDefault
|
||||
|
||||
JSObject *obj = JS_NewObject(cx, NULL, NULL, NULL);
|
||||
CHECK(obj);
|
||||
|
||||
jsid hereid;
|
||||
CHECK(stringToId(cx, "here", &hereid));
|
||||
|
||||
jsid nothereid;
|
||||
CHECK(stringToId(cx, "nothere", ¬hereid));
|
||||
|
||||
jsval v0 = JSVAL_TRUE;
|
||||
CHECK(JS_SetPropertyById(cx, obj, hereid, &v0));
|
||||
|
||||
jsval v1;
|
||||
CHECK(JS_GetPropertyByIdDefault(cx, obj, hereid, JSVAL_FALSE, &v1));
|
||||
CHECK(JSVAL_IS_TRUE(v1));
|
||||
|
||||
jsval v2;
|
||||
CHECK(JS_GetPropertyByIdDefault(cx, obj, nothereid, JSVAL_FALSE, &v2));
|
||||
CHECK(JSVAL_IS_FALSE(v2));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
END_TEST(testGetPropertyDefault_bug594060)
|
@ -3752,6 +3752,12 @@ JS_GetPropertyById(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
|
||||
return obj->getProperty(cx, id, Valueify(vp));
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_GetPropertyByIdDefault(JSContext *cx, JSObject *obj, jsid id, jsval def, jsval *vp)
|
||||
{
|
||||
return GetPropertyDefault(cx, obj, id, Valueify(def), Valueify(vp));
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_GetElement(JSContext *cx, JSObject *obj, jsint index, jsval *vp)
|
||||
{
|
||||
@ -3765,6 +3771,13 @@ JS_GetProperty(JSContext *cx, JSObject *obj, const char *name, jsval *vp)
|
||||
return atom && JS_GetPropertyById(cx, obj, ATOM_TO_JSID(atom), vp);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_GetPropertyDefault(JSContext *cx, JSObject *obj, const char *name, jsval def, jsval *vp)
|
||||
{
|
||||
JSAtom *atom = js_Atomize(cx, name, strlen(name), 0);
|
||||
return atom && JS_GetPropertyByIdDefault(cx, obj, ATOM_TO_JSID(atom), def, vp);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_GetUCProperty(JSContext *cx, JSObject *obj, const jschar *name, size_t namelen, jsval *vp)
|
||||
{
|
||||
|
@ -2059,9 +2059,15 @@ JS_GetOwnPropertyDescriptor(JSContext *cx, JSObject *obj, jsid id, jsval *vp);
|
||||
extern JS_PUBLIC_API(JSBool)
|
||||
JS_GetProperty(JSContext *cx, JSObject *obj, const char *name, jsval *vp);
|
||||
|
||||
extern JS_PUBLIC_API(JSBool)
|
||||
JS_GetPropertyDefault(JSContext *cx, JSObject *obj, const char *name, jsval def, jsval *vp);
|
||||
|
||||
extern JS_PUBLIC_API(JSBool)
|
||||
JS_GetPropertyById(JSContext *cx, JSObject *obj, jsid id, jsval *vp);
|
||||
|
||||
extern JS_PUBLIC_API(JSBool)
|
||||
JS_GetPropertyByIdDefault(JSContext *cx, JSObject *obj, jsid id, jsval def, jsval *vp);
|
||||
|
||||
extern JS_PUBLIC_API(JSBool)
|
||||
JS_GetMethodById(JSContext *cx, JSObject *obj, jsid id, JSObject **objp,
|
||||
jsval *vp);
|
||||
|
@ -179,6 +179,8 @@ const char *const js_common_atom_names[] = {
|
||||
js_value_str, /* valueAtom */
|
||||
js_test_str, /* testAtom */
|
||||
"use strict", /* useStrictAtom */
|
||||
"loc", /* locAtom */
|
||||
"line", /* lineAtom */
|
||||
|
||||
#if JS_HAS_XML_SUPPORT
|
||||
js_etago_str, /* etagoAtom */
|
||||
|
@ -372,6 +372,8 @@ struct JSAtomState
|
||||
JSAtom *valueAtom;
|
||||
JSAtom *testAtom;
|
||||
JSAtom *useStrictAtom;
|
||||
JSAtom *locAtom;
|
||||
JSAtom *lineAtom;
|
||||
|
||||
#if JS_HAS_XML_SUPPORT
|
||||
JSAtom *etagoAtom;
|
||||
|
@ -2907,6 +2907,23 @@ class AutoReleasePtr {
|
||||
~AutoReleasePtr() { cx->free(ptr); }
|
||||
};
|
||||
|
||||
/*
|
||||
* FIXME: bug 602774: cleaner API for AutoReleaseNullablePtr
|
||||
*/
|
||||
class AutoReleaseNullablePtr {
|
||||
JSContext *cx;
|
||||
void *ptr;
|
||||
AutoReleaseNullablePtr operator=(const AutoReleaseNullablePtr &other);
|
||||
public:
|
||||
explicit AutoReleaseNullablePtr(JSContext *cx, void *ptr) : cx(cx), ptr(ptr) {}
|
||||
void reset(void *ptr2) {
|
||||
if (ptr)
|
||||
cx->free(ptr);
|
||||
ptr = ptr2;
|
||||
}
|
||||
~AutoReleaseNullablePtr() { if (ptr) cx->free(ptr); }
|
||||
};
|
||||
|
||||
class AutoLocalNameArray {
|
||||
public:
|
||||
explicit AutoLocalNameArray(JSContext *cx, JSFunction *fun
|
||||
|
@ -5151,6 +5151,23 @@ js_GetProperty(JSContext *cx, JSObject *obj, jsid id, Value *vp)
|
||||
return js_GetPropertyHelperInline(cx, obj, id, JSGET_METHOD_BARRIER, vp);
|
||||
}
|
||||
|
||||
JSBool
|
||||
js::GetPropertyDefault(JSContext *cx, JSObject *obj, jsid id, Value def, Value *vp)
|
||||
{
|
||||
JSProperty *prop;
|
||||
JSObject *obj2;
|
||||
if (js_LookupPropertyWithFlags(cx, obj, id, JSRESOLVE_QUALIFIED, &obj2, &prop) < 0)
|
||||
return false;
|
||||
|
||||
if (!prop) {
|
||||
*vp = def;
|
||||
return true;
|
||||
}
|
||||
|
||||
obj2->dropProperty(cx, prop);
|
||||
return js_GetProperty(cx, obj2, id, vp);
|
||||
}
|
||||
|
||||
JSBool
|
||||
js_GetMethod(JSContext *cx, JSObject *obj, jsid id, uintN getHow, Value *vp)
|
||||
{
|
||||
|
@ -212,6 +212,13 @@ js_DefineProperty(JSContext *cx, JSObject *obj, jsid id, const js::Value *value,
|
||||
extern JSBool
|
||||
js_GetProperty(JSContext *cx, JSObject *obj, jsid id, js::Value *vp);
|
||||
|
||||
namespace js {
|
||||
|
||||
extern JSBool
|
||||
GetPropertyDefault(JSContext *cx, JSObject *obj, jsid id, Value def, Value *vp);
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
extern JSBool
|
||||
js_SetProperty(JSContext *cx, JSObject *obj, jsid id, js::Value *vp, JSBool strict);
|
||||
|
||||
|
@ -61,6 +61,7 @@
|
||||
#include "jsval.h"
|
||||
#include "jsvalue.h"
|
||||
#include "jsobjinlines.h"
|
||||
#include "jsobj.h"
|
||||
#include "jsarray.h"
|
||||
#include "jsnum.h"
|
||||
|
||||
@ -160,12 +161,13 @@ typedef Vector<Value, 8> NodeVector;
|
||||
class NodeBuilder
|
||||
{
|
||||
JSContext *cx;
|
||||
char const *src; /* source filename or null */
|
||||
Value srcval; /* source filename JS value or null */
|
||||
bool saveLoc; /* save source location information? */
|
||||
char const *src; /* source filename or null */
|
||||
Value srcval; /* source filename JS value or null */
|
||||
|
||||
public:
|
||||
NodeBuilder(JSContext *c, char const *s)
|
||||
: cx(c), src(s) {
|
||||
NodeBuilder(JSContext *c, bool l, char const *s)
|
||||
: cx(c), saveLoc(l), src(s) {
|
||||
}
|
||||
|
||||
bool init() {
|
||||
@ -533,7 +535,7 @@ NodeBuilder::newArray(NodeVector &elts, Value *dst)
|
||||
bool
|
||||
NodeBuilder::setNodeLoc(JSObject *node, TokenPos *pos)
|
||||
{
|
||||
if (!pos)
|
||||
if (!saveLoc || !pos)
|
||||
return setProperty(node, "loc", NullValue());
|
||||
|
||||
JSObject *loc, *to;
|
||||
@ -1202,7 +1204,7 @@ class ASTSerializer
|
||||
{
|
||||
JSContext *cx;
|
||||
NodeBuilder builder;
|
||||
uintN lineno;
|
||||
uint32 lineno;
|
||||
|
||||
Value atomContents(JSAtom *atom) {
|
||||
return Valueify(ATOM_TO_JSVAL(atom ? atom : cx->runtime->atomState.emptyAtom));
|
||||
@ -1283,8 +1285,8 @@ class ASTSerializer
|
||||
bool xml(JSParseNode *pn, Value *dst);
|
||||
|
||||
public:
|
||||
ASTSerializer(JSContext *c, char const *src, uintN ln)
|
||||
: cx(c), builder(c, src), lineno(ln) {
|
||||
ASTSerializer(JSContext *c, bool l, char const *src, uint32 ln)
|
||||
: cx(c), builder(c, l, src), lineno(ln) {
|
||||
}
|
||||
|
||||
bool init() {
|
||||
@ -2703,7 +2705,7 @@ bool
|
||||
ASTSerializer::functionArgs(JSParseNode *pn, JSParseNode *pnargs, JSParseNode *pndestruct,
|
||||
JSParseNode *pnbody, NodeVector &args)
|
||||
{
|
||||
uintN i = 0;
|
||||
uint32 i = 0;
|
||||
JSParseNode *arg = pnargs ? pnargs->pn_head : NULL;
|
||||
JSParseNode *destruct = pndestruct ? pndestruct->pn_head : NULL;
|
||||
Value node;
|
||||
@ -2777,7 +2779,7 @@ Class js_ReflectClass = {
|
||||
};
|
||||
|
||||
static JSBool
|
||||
reflect_parse(JSContext *cx, uintN argc, jsval *vp)
|
||||
reflect_parse(JSContext *cx, uint32 argc, jsval *vp)
|
||||
{
|
||||
if (argc < 1) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_MORE_ARGS_NEEDED,
|
||||
@ -2789,18 +2791,57 @@ reflect_parse(JSContext *cx, uintN argc, jsval *vp)
|
||||
if (!src)
|
||||
return JS_FALSE;
|
||||
|
||||
const char *filename = NULL;
|
||||
if (argc > 1) {
|
||||
JSString *str = js_ValueToString(cx, Valueify(JS_ARGV(cx, vp)[1]));
|
||||
if (!str)
|
||||
return JS_FALSE;
|
||||
filename = js_GetStringBytes(NULL, str);
|
||||
}
|
||||
char *filename = NULL;
|
||||
AutoReleaseNullablePtr filenamep(cx, filename);
|
||||
uint32 lineno = 1;
|
||||
bool loc = true;
|
||||
|
||||
uintN lineno = 1;
|
||||
if (argc > 2) {
|
||||
if (!ValueToECMAUint32(cx, Valueify(JS_ARGV(cx, vp)[2]), &lineno))
|
||||
if (argc > 1) {
|
||||
Value arg = Valueify(JS_ARGV(cx, vp)[1]);
|
||||
|
||||
if (!arg.isObject()) {
|
||||
js_ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_UNEXPECTED_TYPE,
|
||||
JSDVG_SEARCH_STACK, arg, NULL, "not an object", NULL);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
JSObject *config = &arg.toObject();
|
||||
|
||||
Value prop;
|
||||
|
||||
/* config.loc */
|
||||
if (!GetPropertyDefault(cx, config, ATOM_TO_JSID(cx->runtime->atomState.locAtom),
|
||||
BooleanValue(true), &prop)) {
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
loc = js_ValueToBoolean(prop);
|
||||
|
||||
if (loc) {
|
||||
/* config.source */
|
||||
if (!GetPropertyDefault(cx, config, ATOM_TO_JSID(cx->runtime->atomState.sourceAtom),
|
||||
NullValue(), &prop)) {
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
if (!prop.isNullOrUndefined()) {
|
||||
JSString *str = js_ValueToString(cx, prop);
|
||||
if (!str)
|
||||
return JS_FALSE;
|
||||
|
||||
filename = js_DeflateString(cx, str->chars(), str->length());
|
||||
if (!filename)
|
||||
return JS_FALSE;
|
||||
filenamep.reset(filename);
|
||||
}
|
||||
|
||||
/* config.line */
|
||||
if (!GetPropertyDefault(cx, config, ATOM_TO_JSID(cx->runtime->atomState.lineAtom),
|
||||
Int32Value(1), &prop) ||
|
||||
!ValueToECMAUint32(cx, prop, &lineno)) {
|
||||
return JS_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const jschar *chars;
|
||||
@ -2817,7 +2858,7 @@ reflect_parse(JSContext *cx, uintN argc, jsval *vp)
|
||||
if (!pn)
|
||||
return JS_FALSE;
|
||||
|
||||
ASTSerializer serialize(cx, filename, lineno);
|
||||
ASTSerializer serialize(cx, loc, filename, lineno);
|
||||
if (!serialize.init())
|
||||
return JS_FALSE;
|
||||
|
||||
|
@ -879,25 +879,31 @@ assertExpr("(<x><!-- hello, world --></x>)()", callExpr(xmlElt([xmlStartTag([xml
|
||||
|
||||
|
||||
var withoutFileOrLine = Reflect.parse("42");
|
||||
var withFile = Reflect.parse("42", "foo.js");
|
||||
var withFileAndLine = Reflect.parse("42", "foo.js", 111);
|
||||
var withFile = Reflect.parse("42", {source:"foo.js"});
|
||||
var withFileAndLine = Reflect.parse("42", {source:"foo.js", line:111});
|
||||
|
||||
Pattern({ source: null, start: { line: 1, column: 0 }, end: { line: 1, column: 2 } }).match(withoutFileOrLine.loc);
|
||||
Pattern({ source: "foo.js", start: { line: 1, column: 0 }, end: { line: 1, column: 2 } }).match(withFile.loc);
|
||||
Pattern({ source: "foo.js", start: { line: 111, column: 0 }, end: { line: 111, column: 2 } }).match(withFileAndLine.loc);
|
||||
|
||||
var withoutFileOrLine2 = Reflect.parse("foo +\nbar");
|
||||
var withFile2 = Reflect.parse("foo +\nbar", "foo.js");
|
||||
var withFileAndLine2 = Reflect.parse("foo +\nbar", "foo.js", 111);
|
||||
var withFile2 = Reflect.parse("foo +\nbar", {source:"foo.js"});
|
||||
var withFileAndLine2 = Reflect.parse("foo +\nbar", {source:"foo.js", line:111});
|
||||
|
||||
Pattern({ source: null, start: { line: 1, column: 0 }, end: { line: 2, column: 3 } }).match(withoutFileOrLine2.loc);
|
||||
Pattern({ source: "foo.js", start: { line: 1, column: 0 }, end: { line: 2, column: 3 } }).match(withFile2.loc);
|
||||
Pattern({ source: "foo.js", start: { line: 111, column: 0 }, end: { line: 112, column: 3 } }).match(withFileAndLine2.loc);
|
||||
|
||||
var nested = Reflect.parse("(-b + sqrt(sqr(b) - 4 * a * c)) / (2 * a)", "quad.js");
|
||||
var nested = Reflect.parse("(-b + sqrt(sqr(b) - 4 * a * c)) / (2 * a)", {source:"quad.js"});
|
||||
var fourAC = nested.body[0].expression.left.right.arguments[0].right;
|
||||
|
||||
Pattern({ source: "quad.js", start: { line: 1, column: 20 }, end: { line: 1, column: 29 } }).match(fourAC.loc);
|
||||
|
||||
|
||||
// No source location
|
||||
|
||||
assertEq(Reflect.parse("42", {loc:false}).loc, null);
|
||||
program([exprStmt(lit(42))]).assert(Reflect.parse("42", {loc:false}));
|
||||
|
||||
|
||||
reportCompare(true, true);
|
||||
|
Loading…
Reference in New Issue
Block a user