mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-26 14:30:27 +00:00
16988569b9
- Bug 1177892 part 1 - Remove BOOLEAN_TO_JSVAL and STRING_TO_JSVAL. r=evilpie (1fac17ff3) - Bug 1177892 part 2 - Remove PRIVATE_TO_JSVAL. r=evilpie (4d7e80200) - pointer style (cd27bd41a) - Bug 1177892 part 3 - Remove OBJECT_TO_JSVAL. r=evilpie (ff66aebe5) - Bug 1155342 - Disallow flagging a [NewObject] method with a [DependsOn] value that implies it might return the same value when called twice. r=bzbarsky (7ba1bb806) - Bug 1129239. Don't require 'optional' keyword on trailing dictionary arguments if the dictionary has a required member. r=smaug (3ee24f57b) - Bug 1152902 part 1. Add a way to flag a method in webidl as being identity-testable, so we'll expose such an identity test from bindings to other C++ code. r=peterv (43e038677) - Bug 1152902 part 2. Add a fast path for the case when a Promise is resolved with another Promise. r=nsm (59f56603e) - Bug 1172785 - Adding StaticClassOverride routing for JS implemented WebIDL, r=peterv (6ae76e198) - Bug 1172785 - Using RTCCertificate for WebRTC, r=ekr (a69ee6167) - fix build, file built twice (04f7e3d75) - Bug 1155942. Treat USVString and ByteString as serializable values. r=bkelly (33e635737) - Bug 913053. Split up IDLTypedef and IDLTypedefType, and likewise for IDLCallback vs IDLCallbackType, so it's clearer whether we're operating on types or objects represented by those types. r=khuey (661f45319) - Bug 1168471 - Implement support for SharedArrayBuffers and SharedArrayViews in WebIDL. r=bz, r=lth, r=luke (77d63babc) - Bug 1151269 - Fix the test used by Ion ICs for whether values can definitely be written to an unboxed object, r=jandem. (0463d6b53) - Bug 1139474 - Watch for unboxed object properties when attaching Ion SETPROP ICs, r=jandem. (67bc9884d) - Bug 1162199 - Use unboxed objects by default, r=jandem. (4dba9da90) - Bug 1166678 - Inline first ObjectGroup::maybeSweep test, r=jandem. (ff179acb3) - Bug 1166709 - After converting unboxed objects created by some initializer to natives, create native objects at that allocation site in the future, r=jandem. (14a5c92b5) - Bug 1166709 - Mark definite properties when replacing the unboxed group used for literals at some pc, r=jandem. (487017105) - Bug 1170372 - Use unboxed arrays for Array() and other functions keyed to allocation sites, r=jandem. (9153a5313) - Bug 1175535 - Don't require objects embedded in MIR nodes to always be tenured, r=jandem. (75399d353) - Bug 1190272 - Improve type checks when storing values into unboxed objects in Ion code, r=jandem. (0a91a08d5) - Bug 1216130 - Fix extra checks for unboxed objects in PropertyWriteNeedsTypeBarrier. r=bhackett (4862b91ca) - Bug 1166700 - Tolerate null failures targets when storing to an unboxed object must fail, r=jandem. (87a07aa3d) - backport of Bug 1389436 - Explicitly instantiate gfxFont::GetShapedWord<uint8_t> for its use in gfxTextRun.cpp. r=jfkthame (5f6fc9f18) - Bug 1164374 - Use StaticMutex in BrowserProcessSubThread. r=froydnj. (b0ad93d17) - Bug 1167771 - Simplify the pre-barrier verifier's tracer use; r=sfink (0fc926804) - Bug 1166037 - Part 2 - Modify common Baseline code for ARM64. r=djvj (739b36d83) - Bug 1168864 followup - Remove unnecessary addProperty check from CheckHasNoSuchProperty. r=bhackett (3a464d07e) - Bug 1166037 - Follow-up - Revert SimulatorType to Simulator. no_r=me (613b095d3) - Bug 1166944 - Inline the only user of TraceObjectSlots; r=jonco (d830d12f0) - pointer style (d567d3be2) - Bug 1167291 - Generalize the marking tracer's cross-compartment check; r=jonco (b5f753147) - Bug 1167318 - Remove GetGCThingTraceKind in favor of the typed Cell variants; r=jonco (f698f3a64) - Bug 1167323 - Use internal interfaces to implement MarkCycleCollectorChildren; r=jonco (4acf85bdb) - Bug 1167433 - AccessorShape is an AllocKind but not a TraceKind; r=jonco (ea92cd26a) - pointer style (403e83b64) - remove namespace hack (e3663d39b) - Bug 1167453 - Rename JSGCTraceKind and make it a C++11 enum class; r=jonco (f7f435a16) - Bug 1165966 - Update destructor assertions to handle failed initalization r=terrence (48237ed24) - pointer style (f637042fc) - Bug 774364 - Part 1: Inline Math.random() in Ion on x86_64. r=sstangl (8379ab0b2) - Bug 1167677 - Try harder to find scratch registers for memory->memory MoveGroup moves, r=sunfish. (14d4b9962) - pointer style (93bb53345) - Bug 1185653 - Fix enumerate hook on unboxed objects to skip non-enume#able properties. r=jorendorff (4ecf41a10) - Bug 1125624, part 1 - Implement ValidateAndApplyPropertyDescriptor steps 3-4, so that (once the corresponding code in StandardDefineProperty is deleted) freezing an already-frozen object with an addProperty class hook will not call the hook. r=Waldo. (f67f98231) - Bug 1125624, part 2 - Change js::StandardDefineProperty to forward to s::DefineProperty. r=Waldo. (3ac5d9e30) - Bug 1148568 - In JSON.parse with a reviver callback, ignore failure when defining properties. r=Waldo. (30c35a758) - pointer style (826d092cf) - Bug 1166950 - Only give constructor functions a prototype. r=efaust (d1b909603) - Bug 1140482 - Add JSPROP_RESOLVING. Give NativeDefineProperty standard behavior in cases where a non-resolving define needs to trigger a resolve hook. r=Waldo. (b2d650abd) - Bug 1140482 followup: Update ResolveInterpretedFunctionPrototype() failure-cases to return false instead of nullptr, now that return type is bool. rs=jorendorff (38eef1812) - Bug 1148188 - part1: defaultShims. r=billm (9eb98a8fa) - pointer style (ec74889f1) - Bug 1101182 - One interpose call for one property access. r=bholley (111afff12) - pointer style (b8dd593e9) - Bug 1148188 - part2: interposeCall. r=billm (6fce5829e) - Bug 1125624, part 3 - Remove js::StandardDefineProperty and js::DefineOwnProperty. r=Waldo. (a8a228f6e) - Bug 1167244 - Handle nullptr return from maybeGetProperty(). r=bhackett (91958bdfc) - pointer style (ebfc629a6) - Bug 1170355 - Watch for indexes that don't fit in a jsid in Array.shift, r=jandem. (6c2f0a8a2) - pointer style (a31367643) - Bug 1165348 - Move Scalar Replacement after GVN. r=jandem (9296335d1) - Bug 1161584 - Add TrackedStrategy::SetProp_InlineCache. r=shu (612ea0b32) - Bug 923717 - Add IC fuzzing mode. r=efaust (a6a6a7460) - Bug 1166711 part 2.1 - Check Scalar Replacement with both unboxed object and without. r=bhackett (e839f034a) - Bug 1172943 - Use unboxed arrays for JSON and script literal arrays, r=jandem. (964d5a42f) - Bug 1162986 - Relax type requirements for using baseline cache information when compiling GETPROP, r=jandem. (68e234a08) - Bug 1168500 - Replace the operator, by variadic templates. r=Waldo (ccb173cb7) - Bug 1166711 part 0.1 - Use JitSpewPrinter instead of stderr. r=bhackett (239022b72) - Bug 1166711 part 0.2 - JitSpew add scope-base indentation level. r=bhackett (89288621e) - Bug 1129313 - Scalar Replacement: Remove PostWriteBarrier at the same time as the stores. r=h4writer (f9df0503e)
386 lines
10 KiB
C++
386 lines
10 KiB
C++
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
|
/* 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 "mozilla/dom/DOMJSProxyHandler.h"
|
|
#include "xpcpublic.h"
|
|
#include "xpcprivate.h"
|
|
#include "XPCWrapper.h"
|
|
#include "WrapperFactory.h"
|
|
#include "nsDOMClassInfo.h"
|
|
#include "nsWrapperCacheInlines.h"
|
|
#include "mozilla/dom/BindingUtils.h"
|
|
|
|
#include "jsapi.h"
|
|
|
|
using namespace JS;
|
|
|
|
namespace mozilla {
|
|
namespace dom {
|
|
|
|
jsid s_length_id = JSID_VOID;
|
|
|
|
bool
|
|
DefineStaticJSVals(JSContext* cx)
|
|
{
|
|
return InternJSString(cx, s_length_id, "length");
|
|
}
|
|
|
|
const char DOMProxyHandler::family = 0;
|
|
|
|
js::DOMProxyShadowsResult
|
|
DOMProxyShadows(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id)
|
|
{
|
|
JS::Rooted<JSObject*> expando(cx, DOMProxyHandler::GetExpandoObject(proxy));
|
|
JS::Value v = js::GetProxyExtra(proxy, JSPROXYSLOT_EXPANDO);
|
|
bool isOverrideBuiltins = !v.isObject() && !v.isUndefined();
|
|
if (expando) {
|
|
bool hasOwn;
|
|
if (!JS_AlreadyHasOwnPropertyById(cx, expando, id, &hasOwn))
|
|
return js::ShadowCheckFailed;
|
|
|
|
if (hasOwn) {
|
|
return isOverrideBuiltins ?
|
|
js::ShadowsViaIndirectExpando : js::ShadowsViaDirectExpando;
|
|
}
|
|
}
|
|
|
|
if (!isOverrideBuiltins) {
|
|
// Our expando, if any, didn't shadow, so we're not shadowing at all.
|
|
return js::DoesntShadow;
|
|
}
|
|
|
|
bool hasOwn;
|
|
if (!GetProxyHandler(proxy)->hasOwn(cx, proxy, id, &hasOwn))
|
|
return js::ShadowCheckFailed;
|
|
|
|
return hasOwn ? js::Shadows : js::DoesntShadowUnique;
|
|
}
|
|
|
|
// Store the information for the specialized ICs.
|
|
struct SetDOMProxyInformation
|
|
{
|
|
SetDOMProxyInformation() {
|
|
js::SetDOMProxyInformation((const void*) &DOMProxyHandler::family,
|
|
JSPROXYSLOT_EXPANDO, DOMProxyShadows);
|
|
}
|
|
};
|
|
|
|
SetDOMProxyInformation gSetDOMProxyInformation;
|
|
|
|
// static
|
|
JSObject*
|
|
DOMProxyHandler::GetAndClearExpandoObject(JSObject* obj)
|
|
{
|
|
MOZ_ASSERT(IsDOMProxy(obj), "expected a DOM proxy object");
|
|
JS::Value v = js::GetProxyExtra(obj, JSPROXYSLOT_EXPANDO);
|
|
if (v.isUndefined()) {
|
|
return nullptr;
|
|
}
|
|
|
|
if (v.isObject()) {
|
|
js::SetProxyExtra(obj, JSPROXYSLOT_EXPANDO, UndefinedValue());
|
|
xpc::ObjectScope(obj)->RemoveDOMExpandoObject(obj);
|
|
} else {
|
|
js::ExpandoAndGeneration* expandoAndGeneration =
|
|
static_cast<js::ExpandoAndGeneration*>(v.toPrivate());
|
|
v = expandoAndGeneration->expando;
|
|
if (v.isUndefined()) {
|
|
return nullptr;
|
|
}
|
|
expandoAndGeneration->expando = UndefinedValue();
|
|
}
|
|
|
|
|
|
return &v.toObject();
|
|
}
|
|
|
|
// static
|
|
JSObject*
|
|
DOMProxyHandler::EnsureExpandoObject(JSContext* cx, JS::Handle<JSObject*> obj)
|
|
{
|
|
NS_ASSERTION(IsDOMProxy(obj), "expected a DOM proxy object");
|
|
JS::Value v = js::GetProxyExtra(obj, JSPROXYSLOT_EXPANDO);
|
|
if (v.isObject()) {
|
|
return &v.toObject();
|
|
}
|
|
|
|
js::ExpandoAndGeneration* expandoAndGeneration;
|
|
if (!v.isUndefined()) {
|
|
expandoAndGeneration = static_cast<js::ExpandoAndGeneration*>(v.toPrivate());
|
|
if (expandoAndGeneration->expando.isObject()) {
|
|
return &expandoAndGeneration->expando.toObject();
|
|
}
|
|
} else {
|
|
expandoAndGeneration = nullptr;
|
|
}
|
|
|
|
JS::Rooted<JSObject*> expando(cx,
|
|
JS_NewObjectWithGivenProto(cx, nullptr, nullptr));
|
|
if (!expando) {
|
|
return nullptr;
|
|
}
|
|
|
|
nsISupports* native = UnwrapDOMObject<nsISupports>(obj);
|
|
nsWrapperCache* cache;
|
|
CallQueryInterface(native, &cache);
|
|
if (!cache) {
|
|
return expando;
|
|
}
|
|
|
|
if (expandoAndGeneration) {
|
|
cache->PreserveWrapper(native);
|
|
expandoAndGeneration->expando.setObject(*expando);
|
|
|
|
return expando;
|
|
}
|
|
|
|
if (!xpc::ObjectScope(obj)->RegisterDOMExpandoObject(obj)) {
|
|
return nullptr;
|
|
}
|
|
|
|
cache->SetPreservingWrapper(true);
|
|
js::SetProxyExtra(obj, JSPROXYSLOT_EXPANDO, ObjectValue(*expando));
|
|
|
|
return expando;
|
|
}
|
|
|
|
bool
|
|
DOMProxyHandler::preventExtensions(JSContext* cx, JS::Handle<JSObject*> proxy,
|
|
JS::ObjectOpResult& result) const
|
|
{
|
|
// always extensible per WebIDL
|
|
return result.failCantPreventExtensions();
|
|
}
|
|
|
|
bool
|
|
DOMProxyHandler::isExtensible(JSContext *cx, JS::Handle<JSObject*> proxy, bool *extensible) const
|
|
{
|
|
*extensible = true;
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
BaseDOMProxyHandler::getPropertyDescriptor(JSContext* cx,
|
|
JS::Handle<JSObject*> proxy,
|
|
JS::Handle<jsid> id,
|
|
MutableHandle<JSPropertyDescriptor> desc) const
|
|
{
|
|
if (!getOwnPropertyDescriptor(cx, proxy, id, desc)) {
|
|
return false;
|
|
}
|
|
if (desc.object()) {
|
|
return true;
|
|
}
|
|
|
|
JS::Rooted<JSObject*> proto(cx);
|
|
if (!js::GetObjectProto(cx, proxy, &proto)) {
|
|
return false;
|
|
}
|
|
if (!proto) {
|
|
desc.object().set(nullptr);
|
|
return true;
|
|
}
|
|
|
|
return JS_GetPropertyDescriptorById(cx, proto, id, desc);
|
|
}
|
|
|
|
bool
|
|
BaseDOMProxyHandler::getOwnPropertyDescriptor(JSContext* cx,
|
|
JS::Handle<JSObject*> proxy,
|
|
JS::Handle<jsid> id,
|
|
MutableHandle<JSPropertyDescriptor> desc) const
|
|
{
|
|
return getOwnPropDescriptor(cx, proxy, id, /* ignoreNamedProps = */ false,
|
|
desc);
|
|
}
|
|
|
|
bool
|
|
DOMProxyHandler::defineProperty(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id,
|
|
Handle<JSPropertyDescriptor> desc,
|
|
JS::ObjectOpResult &result, bool *defined) const
|
|
{
|
|
if (desc.hasGetterObject() && desc.setter() == JS_StrictPropertyStub) {
|
|
return result.failGetterOnly();
|
|
}
|
|
|
|
if (xpc::WrapperFactory::IsXrayWrapper(proxy)) {
|
|
return result.succeed();
|
|
}
|
|
|
|
JS::Rooted<JSObject*> expando(cx, EnsureExpandoObject(cx, proxy));
|
|
if (!expando) {
|
|
return false;
|
|
}
|
|
|
|
if (!JS_DefinePropertyById(cx, expando, id, desc, result)) {
|
|
return false;
|
|
}
|
|
*defined = true;
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
DOMProxyHandler::set(JSContext *cx, Handle<JSObject*> proxy, Handle<jsid> id,
|
|
Handle<JS::Value> v, Handle<JS::Value> receiver,
|
|
ObjectOpResult &result) const
|
|
{
|
|
MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
|
|
"Should not have a XrayWrapper here");
|
|
bool done;
|
|
if (!setCustom(cx, proxy, id, v, &done)) {
|
|
return false;
|
|
}
|
|
if (done) {
|
|
return result.succeed();
|
|
}
|
|
|
|
// Make sure to ignore our named properties when checking for own
|
|
// property descriptors for a set.
|
|
JS::Rooted<JSPropertyDescriptor> desc(cx);
|
|
if (!getOwnPropDescriptor(cx, proxy, id, /* ignoreNamedProps = */ true,
|
|
&desc)) {
|
|
return false;
|
|
}
|
|
if (!desc.object()) {
|
|
// Don't just use getPropertyDescriptor, unlike BaseProxyHandler::set,
|
|
// because that would call getOwnPropertyDescriptor on ourselves. Instead,
|
|
// directly delegate to the proto, if any.
|
|
JS::Rooted<JSObject*> proto(cx);
|
|
if (!js::GetObjectProto(cx, proxy, &proto)) {
|
|
return false;
|
|
}
|
|
if (proto && !JS_GetPropertyDescriptorById(cx, proto, id, &desc)) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return js::SetPropertyIgnoringNamedGetter(cx, proxy, id, v, receiver, desc, result);
|
|
}
|
|
|
|
bool
|
|
DOMProxyHandler::delete_(JSContext* cx, JS::Handle<JSObject*> proxy,
|
|
JS::Handle<jsid> id, JS::ObjectOpResult &result) const
|
|
{
|
|
JS::Rooted<JSObject*> expando(cx);
|
|
if (!xpc::WrapperFactory::IsXrayWrapper(proxy) && (expando = GetExpandoObject(proxy))) {
|
|
return JS_DeletePropertyById(cx, expando, id, result);
|
|
}
|
|
|
|
return result.succeed();
|
|
}
|
|
|
|
bool
|
|
BaseDOMProxyHandler::watch(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id,
|
|
JS::Handle<JSObject*> callable) const
|
|
{
|
|
return js::WatchGuts(cx, proxy, id, callable);
|
|
}
|
|
|
|
bool
|
|
BaseDOMProxyHandler::unwatch(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id) const
|
|
{
|
|
return js::UnwatchGuts(cx, proxy, id);
|
|
}
|
|
|
|
bool
|
|
BaseDOMProxyHandler::ownPropertyKeys(JSContext* cx,
|
|
JS::Handle<JSObject*> proxy,
|
|
JS::AutoIdVector& props) const
|
|
{
|
|
return ownPropNames(cx, proxy, JSITER_OWNONLY | JSITER_HIDDEN | JSITER_SYMBOLS, props);
|
|
}
|
|
|
|
bool
|
|
BaseDOMProxyHandler::getOwnEnumerablePropertyKeys(JSContext* cx,
|
|
JS::Handle<JSObject*> proxy,
|
|
JS::AutoIdVector& props) const
|
|
{
|
|
return ownPropNames(cx, proxy, JSITER_OWNONLY, props);
|
|
}
|
|
|
|
bool
|
|
BaseDOMProxyHandler::enumerate(JSContext *cx, JS::Handle<JSObject*> proxy,
|
|
JS::MutableHandle<JSObject*> objp) const
|
|
{
|
|
return BaseProxyHandler::enumerate(cx, proxy, objp);
|
|
}
|
|
|
|
bool
|
|
DOMProxyHandler::has(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, bool* bp) const
|
|
{
|
|
if (!hasOwn(cx, proxy, id, bp)) {
|
|
return false;
|
|
}
|
|
|
|
if (*bp) {
|
|
// We have the property ourselves; no need to worry about our prototype
|
|
// chain.
|
|
return true;
|
|
}
|
|
|
|
// OK, now we have to look at the proto
|
|
JS::Rooted<JSObject*> proto(cx);
|
|
if (!js::GetObjectProto(cx, proxy, &proto)) {
|
|
return false;
|
|
}
|
|
if (!proto) {
|
|
return true;
|
|
}
|
|
bool protoHasProp;
|
|
bool ok = JS_HasPropertyById(cx, proto, id, &protoHasProp);
|
|
if (ok) {
|
|
*bp = protoHasProp;
|
|
}
|
|
return ok;
|
|
}
|
|
|
|
int32_t
|
|
IdToInt32(JSContext* cx, JS::Handle<jsid> id)
|
|
{
|
|
JS::Rooted<JS::Value> idval(cx);
|
|
double array_index;
|
|
int32_t i;
|
|
if (JSID_IS_SYMBOL(id) ||
|
|
!::JS_IdToValue(cx, id, &idval) ||
|
|
!JS::ToNumber(cx, idval, &array_index) ||
|
|
!::JS_DoubleIsInt32(array_index, &i)) {
|
|
return -1;
|
|
}
|
|
|
|
return i;
|
|
}
|
|
|
|
bool
|
|
DOMProxyHandler::setCustom(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id,
|
|
JS::Handle<JS::Value> v, bool *done) const
|
|
{
|
|
*done = false;
|
|
return true;
|
|
}
|
|
|
|
//static
|
|
JSObject *
|
|
DOMProxyHandler::GetExpandoObject(JSObject *obj)
|
|
{
|
|
MOZ_ASSERT(IsDOMProxy(obj), "expected a DOM proxy object");
|
|
JS::Value v = js::GetProxyExtra(obj, JSPROXYSLOT_EXPANDO);
|
|
if (v.isObject()) {
|
|
return &v.toObject();
|
|
}
|
|
|
|
if (v.isUndefined()) {
|
|
return nullptr;
|
|
}
|
|
|
|
js::ExpandoAndGeneration* expandoAndGeneration =
|
|
static_cast<js::ExpandoAndGeneration*>(v.toPrivate());
|
|
v = expandoAndGeneration->expando;
|
|
return v.isUndefined() ? nullptr : &v.toObject();
|
|
}
|
|
|
|
} // namespace dom
|
|
} // namespace mozilla
|