mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-22 09:45:41 +00:00
Bug 603201 - Implement JS_ForwardSetPropertyTo. r=efaust
This commit is contained in:
parent
cd37d44288
commit
dfb0bb73c0
@ -30,6 +30,7 @@ UNIFIED_SOURCES += [
|
||||
'testExternalStrings.cpp',
|
||||
'testFindSCCs.cpp',
|
||||
'testForOfIterator.cpp',
|
||||
'testForwardSetProperty.cpp',
|
||||
'testFreshGlobalEvalRedefinition.cpp',
|
||||
'testFunctionProperties.cpp',
|
||||
'testGCAllocator.cpp',
|
||||
|
106
js/src/jsapi-tests/testForwardSetProperty.cpp
Normal file
106
js/src/jsapi-tests/testForwardSetProperty.cpp
Normal file
@ -0,0 +1,106 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=8 sts=4 et sw=4 tw=99:
|
||||
*/
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "jsapi-tests/tests.h"
|
||||
|
||||
BEGIN_TEST(testForwardSetProperty)
|
||||
{
|
||||
JS::RootedValue v1(cx);
|
||||
EVAL("var foundValue; \n"
|
||||
"var obj1 = { set prop(val) { foundValue = this; } }; \n"
|
||||
"obj1;",
|
||||
&v1);
|
||||
|
||||
JS::RootedValue v2(cx);
|
||||
EVAL("var obj2 = Object.create(obj1); \n"
|
||||
"obj2;",
|
||||
&v2);
|
||||
|
||||
JS::RootedValue v3(cx);
|
||||
EVAL("var obj3 = {}; \n"
|
||||
"obj3;",
|
||||
&v3);
|
||||
|
||||
JS::RootedObject obj1(cx, &v1.toObject());
|
||||
JS::RootedObject obj2(cx, &v2.toObject());
|
||||
JS::RootedObject obj3(cx, &v3.toObject());
|
||||
|
||||
JS::RootedValue setval(cx, JS::Int32Value(42));
|
||||
|
||||
JS::RootedValue propkey(cx);
|
||||
EVAL("'prop';", &propkey);
|
||||
|
||||
JS::RootedId prop(cx);
|
||||
CHECK(JS_ValueToId(cx, propkey, &prop));
|
||||
|
||||
EXEC("function assertEq(a, b, msg) \n"
|
||||
"{ \n"
|
||||
" if (!Object.is(a, b)) \n"
|
||||
" throw new Error('Assertion failure: ' + msg); \n"
|
||||
"}");
|
||||
|
||||
// Non-strict setter
|
||||
|
||||
CHECK(JS_ForwardSetPropertyTo(cx, obj2, prop, v3, true, setval));
|
||||
|
||||
EXEC("assertEq(foundValue, obj3, 'wrong receiver passed to setter');");
|
||||
|
||||
CHECK(JS_ForwardSetPropertyTo(cx, obj2, prop, setval, true, setval));
|
||||
|
||||
EXEC("assertEq(typeof foundValue === 'object', true, \n"
|
||||
" 'passing 42 as receiver to non-strict setter ' + \n"
|
||||
" 'must box');");
|
||||
|
||||
EXEC("assertEq(foundValue instanceof Number, true, \n"
|
||||
" 'passing 42 as receiver to non-strict setter ' + \n"
|
||||
" 'must box to a Number');");
|
||||
|
||||
EXEC("assertEq(foundValue.valueOf(), 42, \n"
|
||||
" 'passing 42 as receiver to non-strict setter ' + \n"
|
||||
" 'must box to new Number(42)');");
|
||||
|
||||
// Strict setter
|
||||
|
||||
EVAL("obj1 = { set prop(val) { 'use strict'; foundValue = this; } }; \n"
|
||||
"obj1;",
|
||||
&v1);
|
||||
|
||||
CHECK(JS_ForwardSetPropertyTo(cx, obj2, prop, v3, true, setval));
|
||||
|
||||
EXEC("assertEq(foundValue, obj3, 'wrong receiver passed to strict setter');");
|
||||
|
||||
CHECK(JS_ForwardSetPropertyTo(cx, obj2, prop, setval, true, setval));
|
||||
|
||||
|
||||
JS::RootedValue strictSetSupported(cx);
|
||||
EVAL("var strictSetSupported = false; \n"
|
||||
"Object.defineProperty(Object.prototype, \n"
|
||||
" 'strictSetter', \n"
|
||||
" { \n"
|
||||
" set(v) { \n"
|
||||
" 'use strict'; \n"
|
||||
" strictSetSupported = \n"
|
||||
" typeof this === 'number'; \n"
|
||||
" } \n"
|
||||
" }); \n"
|
||||
"17..strictSetter = 42; \n"
|
||||
"strictSetSupported;",
|
||||
&strictSetSupported);
|
||||
CHECK(strictSetSupported.isBoolean());
|
||||
|
||||
if (strictSetSupported.toBoolean()) {
|
||||
// XXX Bug 603201 will fix this.
|
||||
MOZ_ASSERT(false,
|
||||
"remove the support-testing check when bug 603201 is fixt");
|
||||
EXEC("assertEq(foundValue, 42, \n"
|
||||
" '42 passed as receiver to strict setter ' + \n"
|
||||
" 'was mangled');");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
END_TEST(testForwardSetProperty)
|
@ -3054,6 +3054,24 @@ JS_SetPropertyById(JSContext *cx, HandleObject obj, HandleId id, HandleValue v)
|
||||
return JSObject::setGeneric(cx, obj, obj, id, &value, false);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS_ForwardSetPropertyTo(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue onBehalfOf,
|
||||
bool strict, JS::HandleValue v)
|
||||
{
|
||||
AssertHeapIsIdle(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
assertSameCompartment(cx, obj, id);
|
||||
assertSameCompartment(cx, onBehalfOf);
|
||||
|
||||
// XXX Bug 603201 will eliminate this ToObject.
|
||||
RootedObject receiver(cx, ToObject(cx, onBehalfOf));
|
||||
if (!receiver)
|
||||
return false;
|
||||
|
||||
RootedValue value(cx, v);
|
||||
return JSObject::setGeneric(cx, obj, receiver, id, &value, strict);
|
||||
}
|
||||
|
||||
static bool
|
||||
SetElement(JSContext *cx, HandleObject obj, uint32_t index, MutableHandleValue vp)
|
||||
{
|
||||
|
@ -3213,6 +3213,10 @@ JS_SetProperty(JSContext *cx, JS::HandleObject obj, const char *name, JS::Handle
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_SetPropertyById(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue v);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_ForwardSetPropertyTo(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue onBehalfOf,
|
||||
bool strict, JS::HandleValue vp);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_DeleteProperty(JSContext *cx, JS::HandleObject obj, const char *name);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user