Merge inbound to mozilla-central. a=merge

This commit is contained in:
Csoregi Natalia 2018-06-22 00:50:23 +03:00
Родитель ddf211b35e 13c58b163c
Коммит ed1521707f
85 изменённых файлов: 1350 добавлений и 879 удалений

Просмотреть файл

@ -4701,7 +4701,7 @@ var XULBrowserWindow = {
url = url.replace(/[\u200e\u200f\u202a\u202b\u202c\u202d\u202e]/g,
encodeURIComponent);
if (gURLBar && gURLBar._mayTrimURLs /* corresponds to browser.urlbar.trimURLs */)
if (gURLBar._mayTrimURLs /* corresponds to browser.urlbar.trimURLs */)
url = trimURL(url);
}

Просмотреть файл

@ -547,9 +547,7 @@ namespace module_getter {
js::SetFunctionNativeReserved(getter, SLOT_URI, uri);
return JS_DefinePropertyById(aCx, aTarget, id,
JS_DATA_TO_FUNC_PTR(JSNative, getter.get()),
JS_DATA_TO_FUNC_PTR(JSNative, setter.get()),
return JS_DefinePropertyById(aCx, aTarget, id, getter, setter,
JSPROP_GETTER | JSPROP_SETTER | JSPROP_ENUMERATE);
}
} // namespace module_getter

Просмотреть файл

@ -189,7 +189,7 @@ public:
/**
* Holds any SMIL override style declaration for this element.
*/
RefPtr<mozilla::DeclarationBlock> mSMILOverrideStyleDeclaration;
RefPtr<DeclarationBlock> mSMILOverrideStyleDeclaration;
/**
* The controllers of the XUL Element.

Просмотреть файл

@ -186,7 +186,7 @@ NS_NewElement(Element** aResult,
{
RefPtr<mozilla::dom::NodeInfo> ni = aNodeInfo;
int32_t ns = ni->NamespaceID();
RefPtr<nsAtom> isAtom = aIs ? NS_Atomize(*aIs) : nullptr;
RefPtr<nsAtom> isAtom = aIs ? NS_AtomizeMainThread(*aIs) : nullptr;
if (ns == kNameSpaceID_XHTML) {
return NS_NewHTMLElement(aResult, ni.forget(), aFromParser, isAtom);
}

Просмотреть файл

@ -1974,8 +1974,7 @@ Console::PopulateConsoleNotificationInTheTargetScope(JSContext* aCx,
JS::PrivateValue(aData->mStack.get()));
if (NS_WARN_IF(!JS_DefineProperty(aCx, eventObj, "stacktrace",
JS_DATA_TO_FUNC_PTR(JSNative, funObj.get()),
nullptr,
funObj, nullptr,
JSPROP_ENUMERATE |
JSPROP_GETTER | JSPROP_SETTER))) {
return false;

Просмотреть файл

@ -3228,6 +3228,9 @@ TabChild::ReinitRendering()
gfx::VRManagerChild::IdentifyTextureHost(mTextureFactoryIdentifier);
InitAPZState();
RefPtr<LayerManager> lm = mPuppetWidget->GetLayerManager();
MOZ_ASSERT(lm);
lm->SetLayerObserverEpoch(mLayerObserverEpoch);
nsCOMPtr<nsIDocument> doc(GetDocument());
doc->NotifyLayerManagerRecreated();

Просмотреть файл

@ -94,5 +94,7 @@ BlockSubresourceFTP=Loading FTP subresource within http(s) page not allowed (Blo
# LOCALIZATION NOTE (BrowserUpgradeInsecureDisplayRequest):
# %1$S is the browser name "brandShortName"; %2$S is the URL of the upgraded request; %1$S is the upgraded scheme.
BrowserUpgradeInsecureDisplayRequest = %1$S is upgrading an insecure display request %2$S to use %3$S
RunningClearSiteDataValue=Clear-Site-Data header forces the clean up of “%S” data.
# LOCALIZATION NOTE (RunningClearSiteDataValue):
# %S is the URI of the resource whose data was cleaned up
RunningClearSiteDataValue=Clear-Site-Data header forced the clean up of “%S” data.
UnknownClearSiteDataValue=Clear-Site-Data header found. Unknown value “%S”.

Просмотреть файл

@ -7,6 +7,9 @@
* http://dev.w3.org/csswg/cssom/
*/
// Because of getComputedStyle, many CSSStyleDeclaration objects can be
// short-living.
[ProbablyShortLivingWrapper]
interface CSSStyleDeclaration {
[CEReactions, SetterNeedsSubjectPrincipal=NonSystem, SetterThrows]
attribute DOMString cssText;

Просмотреть файл

@ -361,9 +361,7 @@ nsXBLProtoImplField::InstallAccessors(JSContext* aCx,
return NS_ERROR_OUT_OF_MEMORY;
}
if (!::JS_DefinePropertyById(aCx, aTargetClassObject, id,
JS_DATA_TO_FUNC_PTR(JSNative, get.get()),
JS_DATA_TO_FUNC_PTR(JSNative, set.get()),
if (!::JS_DefinePropertyById(aCx, aTargetClassObject, id, get, set,
AccessorAttributes())) {
return NS_ERROR_OUT_OF_MEMORY;
}

Просмотреть файл

@ -151,8 +151,7 @@ nsXBLProtoImplProperty::InstallMember(JSContext *aCx,
if (!::JS_DefineUCProperty(aCx, aTargetClassObject,
static_cast<const char16_t*>(mName),
name.Length(),
JS_DATA_TO_FUNC_PTR(JSNative, getter.get()),
JS_DATA_TO_FUNC_PTR(JSNative, setter.get()),
getter, setter,
mJSAttributes))
return NS_ERROR_OUT_OF_MEMORY;
}

Просмотреть файл

@ -17,7 +17,8 @@
* Creates a new ExprLexer
*/
txExprLexer::txExprLexer()
: mCurrentItem(nullptr),
: mPosition(nullptr),
mCurrentItem(nullptr),
mFirstItem(nullptr),
mLastItem(nullptr),
mTokenCount(0)

Просмотреть файл

@ -56,6 +56,7 @@ txExecutionState::txExecutionState(txStylesheet* aStylesheet,
bool aDisableLoads)
: mOutputHandler(nullptr),
mResultHandler(nullptr),
mOutputHandlerFactory(nullptr),
mStylesheet(aStylesheet),
mNextInstruction(nullptr),
mLocalVariables(nullptr),

Просмотреть файл

@ -523,9 +523,11 @@ txStylesheetCompilerState::txStylesheetCompilerState(txACompileObserver* aObserv
mDisAllowed(0),
mObserver(aObserver),
mEmbedStatus(eNoEmbed),
mIsTopCompiler(false),
mDoneWithThisStylesheet(false),
mNextInstrPtr(nullptr),
mToplevelIterator(nullptr)
mToplevelIterator(nullptr),
mReferrerPolicy(mozilla::net::RP_Unset)
{
// Embedded stylesheets have another handler, which is set in
// txStylesheetCompiler::init if the baseURI has a fragment identifier.

Просмотреть файл

@ -682,10 +682,6 @@ WebRenderBridgeParent::RecvSetDisplayList(const gfx::IntSize& aSize,
// build is done, so we don't need to do it here.
ScheduleGenerateFrame();
}
if (ShouldParentObserveEpoch()) {
mCompositorBridge->ObserveLayerUpdate(GetLayersId(), GetChildLayerObserverEpoch(), true);
}
}
HoldPendingTransactionId(wrEpoch, aTransactionId, aTxnStartTime, aFwdTime);
@ -697,6 +693,10 @@ WebRenderBridgeParent::RecvSetDisplayList(const gfx::IntSize& aSize,
mCompositorBridge->DidComposite(GetLayersId(), now, now);
}
if (ShouldParentObserveEpoch()) {
mCompositorBridge->ObserveLayerUpdate(GetLayersId(), GetChildLayerObserverEpoch(), true);
}
wr::IpcResourceUpdateQueue::ReleaseShmems(this, aSmallShmems);
wr::IpcResourceUpdateQueue::ReleaseShmems(this, aLargeShmems);
return IPC_OK();
@ -771,6 +771,10 @@ WebRenderBridgeParent::RecvEmptyTransaction(const FocusTarget& aFocusTarget,
mCompositorBridge->DidComposite(GetLayersId(), now, now);
}
if (ShouldParentObserveEpoch()) {
mCompositorBridge->ObserveLayerUpdate(GetLayersId(), GetChildLayerObserverEpoch(), true);
}
return IPC_OK();
}

Просмотреть файл

@ -1027,7 +1027,7 @@ AddLengthProperty(JSContext* cx, HandleArrayObject obj)
return NativeObject::addAccessorProperty(cx, obj, lengthId,
array_length_getter, array_length_setter,
JSPROP_PERMANENT | JSPROP_SHADOWABLE);
JSPROP_PERMANENT);
}
static bool

Просмотреть файл

@ -6163,8 +6163,7 @@ StructType::DefineInternal(JSContext* cx, JSObject* typeObj_, JSObject* fieldsOb
if (!JS_DefineUCProperty(cx, prototype,
nameChars.twoByteChars(), name->length(),
JS_DATA_TO_FUNC_PTR(JSNative, getterObj.get()),
JS_DATA_TO_FUNC_PTR(JSNative, setterObj.get()),
getterObj, setterObj,
JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_GETTER | JSPROP_SETTER))
{
return false;

Просмотреть файл

@ -281,8 +281,8 @@ const v2vSigSection = sigSection([v2vSig]);
const i2vSig = {args:[I32Code], ret:VoidCode};
const v2vBody = funcBody({locals:[], body:[]});
assertErrorMessage(() => wasmEval(moduleWithSections([ {name: typeId, body: U32MAX_LEB } ])), CompileError, /too many signatures/);
assertErrorMessage(() => wasmEval(moduleWithSections([ {name: typeId, body: [1, 0], } ])), CompileError, /expected function form/);
assertErrorMessage(() => wasmEval(moduleWithSections([ {name: typeId, body: U32MAX_LEB } ])), CompileError, /too many types/);
assertErrorMessage(() => wasmEval(moduleWithSections([ {name: typeId, body: [1, 0], } ])), CompileError, /expected type form/);
assertErrorMessage(() => wasmEval(moduleWithSections([ {name: typeId, body: [1, FuncCode, ...U32MAX_LEB], } ])), CompileError, /too many arguments in signature/);
assertThrowsInstanceOf(() => wasmEval(moduleWithSections([{name: typeId, body: [1]}])), CompileError);

Просмотреть файл

@ -0,0 +1,162 @@
if (!wasmGcEnabled()) {
assertErrorMessage(() => wasmEvalText(`(module (type $s (struct)))`),
WebAssembly.CompileError, /Structure types not enabled/);
quit();
}
var bin = wasmTextToBinary(
`(module
(table 2 anyfunc)
(elem (i32.const 0) $doit $doitagain)
;; Type array has a mix of types
(type $f1 (func (param i32) (result i32)))
(type $point (struct
(field $point_x i32)
(field $point_y i32)))
(type $f2 (func (param f64) (result f64)))
(type $int_node (struct
(field $intbox_val (mut i32))
(field $intbox_next (mut anyref))))
;; Test all the types.
(type $omni (struct
(field $omni_i32 i32)
(field $omni_i32m (mut i32))
(field $omni_i64 i64)
(field $omni_i64m (mut i64))
(field $omni_f32 f32)
(field $omni_f32m (mut f32))
(field $omni_f64 f64)
(field $omni_f64m (mut f64))
(field $omni_anyref anyref)
(field $omni_anyrefm (mut anyref))))
;; Various ways to reference a type in the middle of the
;; type array, make sure we get the right one
(func $x1 (import "m" "x1") (type $f1))
(func $x2 (import "m" "x2") (type $f2))
(func (export "hello") (param f64) (param i32) (result f64)
(call_indirect $f2 (get_local 0) (get_local 1)))
(func $doit (param f64) (result f64)
(f64.sqrt (get_local 0)))
(func $doitagain (param f64) (result f64)
(f64.mul (get_local 0) (get_local 0)))
(func (export "x1") (param i32) (result i32)
(call $x1 (get_local 0)))
(func (export "x2") (param f64) (result f64)
(call $x2 (get_local 0)))
)`)
var mod = new WebAssembly.Module(bin);
var ins = new WebAssembly.Instance(mod, {m:{x1(x){ return x*3 }, x2(x){ return Math.PI }}}).exports;
assertEq(ins.hello(4.0, 0), 2.0)
assertEq(ins.hello(4.0, 1), 16.0)
assertEq(ins.x1(12), 36)
assertEq(ins.x2(8), Math.PI)
// Crude but at least checks that we have *something*.
var txt = wasmBinaryToText(bin);
var re = /\(type\s+\$[a-z0-9]+\s+\(struct/gm;
assertEq(Array.isArray(re.exec(txt)), true);
assertEq(Array.isArray(re.exec(txt)), true);
assertEq(Array.isArray(re.exec(txt)), true);
assertEq(Array.isArray(re.exec(txt)), false);
// The field name is optional, so this should work.
wasmEvalText(`
(module
(type $s (struct (field i32))))
`)
// Empty structs are OK.
wasmEvalText(`
(module
(type $s (struct)))
`)
// Bogus type definition syntax.
assertErrorMessage(() => wasmEvalText(`
(module
(type $s))
`),
SyntaxError, /parsing wasm text/);
assertErrorMessage(() => wasmEvalText(`
(module
(type $s (field $x i32)))
`),
SyntaxError, /bad type definition/);
assertErrorMessage(() => wasmEvalText(`
(module
(type $s (struct (field $x i31))))
`),
SyntaxError, /parsing wasm text/);
assertErrorMessage(() => wasmEvalText(`
(module
(type $s (struct (fjeld $x i32))))
`),
SyntaxError, /parsing wasm text/);
assertErrorMessage(() => wasmEvalText(`
(module
(type $s (struct abracadabra)))
`),
SyntaxError, /parsing wasm text/);
// Function should not reference struct type: syntactic test
assertErrorMessage(() => wasmEvalText(`
(module
(type $s (struct))
(type $f (func (param i32) (result i32)))
(func (type 0) (param i32) (result i32) (unreachable)))
`),
WebAssembly.CompileError, /signature index references non-signature/);
// Function should not reference struct type: binary test
var bad = new Uint8Array([0x00, 0x61, 0x73, 0x6d,
0x01, 0x00, 0x00, 0x00,
0x01, // Type section
0x03, // Section size
0x01, // One type
0x50, // Struct
0x00, // Zero fields
0x03, // Function section
0x02, // Section size
0x01, // One function
0x00, // Type of function
0x0a, // Code section
0x05, // Section size
0x01, // One body
0x03, // Body size
0x00, // Zero locals
0x00, // UNREACHABLE
0x0b]); // END
assertErrorMessage(() => new WebAssembly.Module(bad),
WebAssembly.CompileError, /signature index references non-signature/);

Просмотреть файл

@ -34,13 +34,11 @@ BEGIN_TEST(testDefineGetterSetterNonEnumerable)
JS::RootedObject vObject(cx, vobj.toObjectOrNull());
CHECK(JS_DefineProperty(cx, vObject, PROPERTY_NAME,
JS_DATA_TO_FUNC_PTR(JSNative, (JSObject*) funGetObj),
JS_DATA_TO_FUNC_PTR(JSNative, (JSObject*) funSetObj),
funGetObj, funSetObj,
JSPROP_GETTER | JSPROP_SETTER | JSPROP_ENUMERATE));
CHECK(JS_DefineProperty(cx, vObject, PROPERTY_NAME,
JS_DATA_TO_FUNC_PTR(JSNative, (JSObject*) funGetObj),
JS_DATA_TO_FUNC_PTR(JSNative, (JSObject*) funSetObj),
funGetObj, funSetObj,
JSPROP_GETTER | JSPROP_SETTER | JSPROP_PERMANENT));
JS::Rooted<JS::PropertyDescriptor> desc(cx);

Просмотреть файл

@ -7,61 +7,6 @@
#include "jsapi-tests/tests.h"
BEGIN_TEST(testSetProperty_NativeGetterStubSetter)
{
JS::RootedObject obj(cx, JS_NewPlainObject(cx));
CHECK(obj);
CHECK(JS_DefineProperty(cx, global, "globalProp", obj, JSPROP_ENUMERATE));
CHECK(JS_DefineProperty(cx, obj, "prop",
JS_PROPERTYOP_GETTER(NativeGet), nullptr,
JSPROP_PROPOP_ACCESSORS));
EXEC("'use strict'; \n"
"var error, passed = false; \n"
"try \n"
"{ \n"
" this.globalProp.prop = 42; \n"
" throw new Error('setting property succeeded!'); \n"
"} \n"
"catch (e) \n"
"{ \n"
" error = e; \n"
" if (e instanceof TypeError) \n"
" passed = true; \n"
"} \n"
" \n"
"if (!passed) \n"
" throw error; \n");
EXEC("var error, passed = false; \n"
"try \n"
"{ \n"
" this.globalProp.prop = 42; \n"
" if (this.globalProp.prop === 17) \n"
" passed = true; \n"
" else \n"
" throw new Error('bad value after set!'); \n"
"} \n"
"catch (e) \n"
"{ \n"
" error = e; \n"
"} \n"
" \n"
"if (!passed) \n"
" throw error; \n");
return true;
}
static bool
NativeGet(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::MutableHandleValue vp)
{
vp.setInt32(17);
return true;
}
END_TEST(testSetProperty_NativeGetterStubSetter)
BEGIN_TEST(testSetProperty_InheritedGlobalSetter)
{
// This is a JSAPI test because jsapi-test globals do not have a resolve

Просмотреть файл

@ -2099,11 +2099,10 @@ JS_DefinePropertyById(JSContext* cx, HandleObject obj, HandleId id,
static bool
DefineAccessorPropertyById(JSContext* cx, HandleObject obj, HandleId id,
const JSNativeWrapper& get, const JSNativeWrapper& set,
unsigned attrs)
HandleObject getter, HandleObject setter, unsigned attrs)
{
JSGetterOp getter = JS_CAST_NATIVE_TO(get.op, JSGetterOp);
JSSetterOp setter = JS_CAST_NATIVE_TO(set.op, JSSetterOp);
MOZ_ASSERT_IF(getter, attrs & JSPROP_GETTER);
MOZ_ASSERT_IF(setter, attrs & JSPROP_SETTER);
// JSPROP_READONLY has no meaning when accessors are involved. Ideally we'd
// throw if this happens, but we've accepted it for long enough that it's
@ -2112,67 +2111,61 @@ DefineAccessorPropertyById(JSContext* cx, HandleObject obj, HandleId id,
if (attrs & (JSPROP_GETTER | JSPROP_SETTER))
attrs &= ~JSPROP_READONLY;
// When we use DefineProperty, we need full scriptable Function objects rather
// than JSNatives. However, we might be pulling this property descriptor off
// of something with JSNative property descriptors. If we are, wrap them in
// JS Function objects.
// If !(attrs & JSPROP_PROPOP_ACCESSORS), then getter/setter are both
// possibly-null JSNatives (or possibly-null JSFunction* if JSPROP_GETTER or
// JSPROP_SETTER is appropriately set).
if (!(attrs & JSPROP_PROPOP_ACCESSORS)) {
if (getter && !(attrs & JSPROP_GETTER)) {
RootedAtom atom(cx, IdToFunctionName(cx, id, FunctionPrefixKind::Get));
if (!atom)
return false;
JSFunction* getobj = NewNativeFunction(cx, (Native) getter, 0, atom);
if (!getobj)
return false;
if (get.info)
getobj->setJitInfo(get.info);
getter = JS_DATA_TO_FUNC_PTR(GetterOp, getobj);
attrs |= JSPROP_GETTER;
}
if (setter && !(attrs & JSPROP_SETTER)) {
// Root just the getter, since the setter is not yet a JSObject.
AutoRooterGetterSetter getRoot(cx, JSPROP_GETTER, &getter, nullptr);
RootedAtom atom(cx, IdToFunctionName(cx, id, FunctionPrefixKind::Set));
if (!atom)
return false;
JSFunction* setobj = NewNativeFunction(cx, (Native) setter, 1, atom);
if (!setobj)
return false;
if (set.info)
setobj->setJitInfo(set.info);
setter = JS_DATA_TO_FUNC_PTR(SetterOp, setobj);
attrs |= JSPROP_SETTER;
}
} else {
attrs &= ~JSPROP_PROPOP_ACCESSORS;
}
AssertHeapIsIdle();
CHECK_REQUEST(cx);
assertSameCompartment(cx, obj, id,
(attrs & JSPROP_GETTER)
? JS_FUNC_TO_DATA_PTR(JSObject*, getter)
: nullptr,
(attrs & JSPROP_SETTER)
? JS_FUNC_TO_DATA_PTR(JSObject*, setter)
: nullptr);
assertSameCompartment(cx, obj, id, getter, setter);
return js::DefineAccessorProperty(cx, obj, id, getter, setter, attrs);
}
static bool
DefineAccessorPropertyById(JSContext* cx, HandleObject obj, HandleId id,
const JSNativeWrapper& get, const JSNativeWrapper& set,
unsigned attrs)
{
// Getter/setter are both possibly-null JSNatives. Wrap them in JSFunctions.
MOZ_ASSERT(!(attrs & (JSPROP_GETTER | JSPROP_SETTER)));
RootedFunction getter(cx);
if (get.op) {
RootedAtom atom(cx, IdToFunctionName(cx, id, FunctionPrefixKind::Get));
if (!atom)
return false;
getter = NewNativeFunction(cx, get.op, 0, atom);
if (!getter)
return false;
if (get.info)
getter->setJitInfo(get.info);
attrs |= JSPROP_GETTER;
}
RootedFunction setter(cx);
if (set.op) {
RootedAtom atom(cx, IdToFunctionName(cx, id, FunctionPrefixKind::Set));
if (!atom)
return false;
setter = NewNativeFunction(cx, set.op, 1, atom);
if (!setter)
return false;
if (set.info)
setter->setJitInfo(set.info);
attrs |= JSPROP_SETTER;
}
return DefineAccessorPropertyById(cx, obj, id, getter, setter, attrs);
}
static bool
DefineDataPropertyById(JSContext* cx, HandleObject obj, HandleId id, HandleValue value,
unsigned attrs)
{
MOZ_ASSERT(!(attrs & (JSPROP_GETTER | JSPROP_SETTER | JSPROP_PROPOP_ACCESSORS)));
MOZ_ASSERT(!(attrs & (JSPROP_GETTER | JSPROP_SETTER)));
AssertHeapIsIdle();
CHECK_REQUEST(cx);
@ -2210,6 +2203,13 @@ JS_DefinePropertyById(JSContext* cx, HandleObject obj, HandleId id, Native gette
attrs);
}
JS_PUBLIC_API(bool)
JS_DefinePropertyById(JSContext* cx, HandleObject obj, HandleId id, HandleObject getter,
HandleObject setter, unsigned attrs)
{
return DefineAccessorPropertyById(cx, obj, id, getter, setter, attrs);
}
JS_PUBLIC_API(bool)
JS_DefinePropertyById(JSContext* cx, HandleObject obj, HandleId id, HandleObject valueArg,
unsigned attrs)
@ -2250,22 +2250,6 @@ JS_DefinePropertyById(JSContext* cx, HandleObject obj, HandleId id, double value
return DefineDataPropertyById(cx, obj, id, HandleValue::fromMarkedLocation(&value), attrs);
}
static bool
DefineAccessorProperty(JSContext* cx, HandleObject obj, const char* name,
const JSNativeWrapper& getter, const JSNativeWrapper& setter,
unsigned attrs)
{
AutoRooterGetterSetter gsRoot(cx, attrs, const_cast<JSNative*>(&getter.op),
const_cast<JSNative*>(&setter.op));
JSAtom* atom = Atomize(cx, name, strlen(name));
if (!atom)
return false;
RootedId id(cx, AtomToId(atom));
return DefineAccessorPropertyById(cx, obj, id, getter, setter, attrs);
}
static bool
DefineDataProperty(JSContext* cx, HandleObject obj, const char* name, HandleValue value,
unsigned attrs)
@ -2289,8 +2273,24 @@ JS_PUBLIC_API(bool)
JS_DefineProperty(JSContext* cx, HandleObject obj, const char* name, Native getter, Native setter,
unsigned attrs)
{
return DefineAccessorProperty(cx, obj, name, NativeOpWrapper(getter), NativeOpWrapper(setter),
attrs);
JSAtom* atom = Atomize(cx, name, strlen(name));
if (!atom)
return false;
RootedId id(cx, AtomToId(atom));
return DefineAccessorPropertyById(cx, obj, id, NativeOpWrapper(getter),
NativeOpWrapper(setter), attrs);
}
JS_PUBLIC_API(bool)
JS_DefineProperty(JSContext* cx, HandleObject obj, const char* name, HandleObject getter,
HandleObject setter, unsigned attrs)
{
JSAtom* atom = Atomize(cx, name, strlen(name));
if (!atom)
return false;
RootedId id(cx, AtomToId(atom));
return DefineAccessorPropertyById(cx, obj, id, getter, setter, attrs);
}
JS_PUBLIC_API(bool)
@ -2360,20 +2360,6 @@ JS_DefineUCProperty(JSContext* cx, HandleObject obj, const char16_t* name, size_
result.checkStrict(cx, obj, id);
}
static bool
DefineUCAccessorProperty(JSContext* cx, HandleObject obj, const char16_t* name, size_t namelen,
Native getter, Native setter, unsigned attrs)
{
AutoRooterGetterSetter gsRoot(cx, attrs, &getter, &setter);
JSAtom* atom = AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
if (!atom)
return false;
RootedId id(cx, AtomToId(atom));
return DefineAccessorPropertyById(cx, obj, id,
NativeOpWrapper(getter), NativeOpWrapper(setter),
attrs);
}
static bool
DefineUCDataProperty(JSContext* cx, HandleObject obj, const char16_t* name, size_t namelen,
HandleValue value, unsigned attrs)
@ -2394,9 +2380,13 @@ JS_DefineUCProperty(JSContext* cx, HandleObject obj, const char16_t* name, size_
JS_PUBLIC_API(bool)
JS_DefineUCProperty(JSContext* cx, HandleObject obj, const char16_t* name, size_t namelen,
Native getter, Native setter, unsigned attrs)
HandleObject getter, HandleObject setter, unsigned attrs)
{
return DefineUCAccessorProperty(cx, obj, name, namelen, getter, setter, attrs);
JSAtom* atom = AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
if (!atom)
return false;
RootedId id(cx, AtomToId(atom));
return DefineAccessorPropertyById(cx, obj, id, getter, setter, attrs);
}
JS_PUBLIC_API(bool)
@ -2442,22 +2432,6 @@ JS_DefineUCProperty(JSContext* cx, HandleObject obj, const char16_t* name, size_
attrs);
}
static bool
DefineAccessorElement(JSContext* cx, HandleObject obj, uint32_t index, unsigned attrs,
Native getter, Native setter)
{
assertSameCompartment(cx, obj);
AutoRooterGetterSetter gsRoot(cx, attrs, &getter, &setter);
AssertHeapIsIdle();
CHECK_REQUEST(cx);
RootedId id(cx);
if (!IndexToId(cx, index, &id))
return false;
return DefineAccessorPropertyById(cx, obj, id,
NativeOpWrapper(getter), NativeOpWrapper(setter),
attrs);
}
static bool
DefineDataElement(JSContext* cx, HandleObject obj, uint32_t index, HandleValue value,
unsigned attrs)
@ -2479,10 +2453,13 @@ JS_DefineElement(JSContext* cx, HandleObject obj, uint32_t index, HandleValue va
}
JS_PUBLIC_API(bool)
JS_DefineElement(JSContext* cx, HandleObject obj, uint32_t index, Native getter, Native setter,
unsigned attrs)
JS_DefineElement(JSContext* cx, HandleObject obj, uint32_t index, HandleObject getter,
HandleObject setter, unsigned attrs)
{
return DefineAccessorElement(cx, obj, index, attrs, getter, setter);
RootedId id(cx);
if (!IndexToId(cx, index, &id))
return false;
return DefineAccessorPropertyById(cx, obj, id, getter, setter, attrs);
}
JS_PUBLIC_API(bool)
@ -3081,7 +3058,6 @@ DefineSelfHostedProperty(JSContext* cx, HandleObject obj, HandleId id,
}
MOZ_ASSERT(getterValue.isObject() && getterValue.toObject().is<JSFunction>());
RootedFunction getterFunc(cx, &getterValue.toObject().as<JSFunction>());
JSNative getterOp = JS_DATA_TO_FUNC_PTR(JSNative, getterFunc.get());
RootedFunction setterFunc(cx);
if (setterName) {
@ -3099,11 +3075,8 @@ DefineSelfHostedProperty(JSContext* cx, HandleObject obj, HandleId id,
MOZ_ASSERT(setterValue.isObject() && setterValue.toObject().is<JSFunction>());
setterFunc = &setterValue.toObject().as<JSFunction>();
}
JSNative setterOp = JS_DATA_TO_FUNC_PTR(JSNative, setterFunc.get());
return DefineAccessorPropertyById(cx, obj, id,
NativeOpWrapper(getterOp), NativeOpWrapper(setterOp),
attrs);
return DefineAccessorPropertyById(cx, obj, id, getterFunc, setterFunc, attrs);
}
JS_PUBLIC_API(JSObject*)

Просмотреть файл

@ -476,9 +476,7 @@ static const uint8_t JSPROP_READONLY = 0x02;
/* property cannot be deleted */
static const uint8_t JSPROP_PERMANENT = 0x04;
/* Passed to JS_Define(UC)Property* and JS_DefineElement if getters/setters are
JSGetterOp/JSSetterOp */
static const uint8_t JSPROP_PROPOP_ACCESSORS = 0x08;
/* (0x08 is unused) */
/* property holds getter function */
static const uint8_t JSPROP_GETTER = 0x10;
@ -1462,9 +1460,6 @@ private:
namespace JS {
namespace detail {
/* NEVER DEFINED, DON'T USE. For use by JS_CAST_NATIVE_TO only. */
inline int CheckIsNative(JSNative native);
/* NEVER DEFINED, DON'T USE. For use by JS_CAST_STRING_TO only. */
template<size_t N>
inline int
@ -1473,19 +1468,9 @@ CheckIsCharacterLiteral(const char (&arr)[N]);
/* NEVER DEFINED, DON'T USE. For use by JS_CAST_INT32_TO only. */
inline int CheckIsInt32(int32_t value);
/* NEVER DEFINED, DON'T USE. For use by JS_PROPERTYOP_GETTER only. */
inline int CheckIsGetterOp(JSGetterOp op);
/* NEVER DEFINED, DON'T USE. For use by JS_PROPERTYOP_SETTER only. */
inline int CheckIsSetterOp(JSSetterOp op);
} // namespace detail
} // namespace JS
#define JS_CAST_NATIVE_TO(v, To) \
(static_cast<void>(sizeof(JS::detail::CheckIsNative(v))), \
reinterpret_cast<To>(v))
#define JS_CAST_STRING_TO(s, To) \
(static_cast<void>(sizeof(JS::detail::CheckIsCharacterLiteral(s))), \
reinterpret_cast<To>(s))
@ -1498,14 +1483,6 @@ inline int CheckIsSetterOp(JSSetterOp op);
(static_cast<mozilla::EnableIf<((flags) & ~(JSPROP_ENUMERATE | JSPROP_PERMANENT)) == 0>::Type>(0), \
(flags))
#define JS_PROPERTYOP_GETTER(v) \
(static_cast<void>(sizeof(JS::detail::CheckIsGetterOp(v))), \
reinterpret_cast<JSNative>(v))
#define JS_PROPERTYOP_SETTER(v) \
(static_cast<void>(sizeof(JS::detail::CheckIsSetterOp(v))), \
reinterpret_cast<JSNative>(v))
#define JS_PS_ACCESSOR_SPEC(name, getter, setter, flags, extraFlags) \
{ name, uint8_t(JS_CHECK_ACCESSOR_FLAGS(flags) | extraFlags), \
{ { getter, setter } } }
@ -2039,9 +2016,6 @@ class WrappedPtrOperations<JS::PropertyDescriptor, Wrapper>
return (desc().attrs & bits) == bits;
}
// Non-API attributes bit used internally for arguments objects.
enum { SHADOWABLE = JSPROP_INTERNAL_USE_BIT };
public:
// Descriptors with JSGetterOp/JSSetterOp are considered data
// descriptors. It's complicated.
@ -2098,14 +2072,14 @@ class WrappedPtrOperations<JS::PropertyDescriptor, Wrapper>
JSPROP_GETTER |
JSPROP_SETTER |
JSPROP_RESOLVING |
SHADOWABLE)) == 0);
JSPROP_INTERNAL_USE_BIT)) == 0);
MOZ_ASSERT(!hasAll(JSPROP_IGNORE_ENUMERATE | JSPROP_ENUMERATE));
MOZ_ASSERT(!hasAll(JSPROP_IGNORE_PERMANENT | JSPROP_PERMANENT));
if (isAccessorDescriptor()) {
MOZ_ASSERT(!has(JSPROP_READONLY));
MOZ_ASSERT(!has(JSPROP_IGNORE_READONLY));
MOZ_ASSERT(!has(JSPROP_IGNORE_VALUE));
MOZ_ASSERT(!has(SHADOWABLE));
MOZ_ASSERT(!has(JSPROP_INTERNAL_USE_BIT));
MOZ_ASSERT(value().isUndefined());
MOZ_ASSERT_IF(!has(JSPROP_GETTER), !getter());
MOZ_ASSERT_IF(!has(JSPROP_SETTER), !setter());
@ -2130,7 +2104,7 @@ class WrappedPtrOperations<JS::PropertyDescriptor, Wrapper>
JSPROP_GETTER |
JSPROP_SETTER |
JSPROP_RESOLVING |
SHADOWABLE)) == 0);
JSPROP_INTERNAL_USE_BIT)) == 0);
MOZ_ASSERT_IF(isAccessorDescriptor(), has(JSPROP_GETTER) && has(JSPROP_SETTER));
#endif
}
@ -2420,6 +2394,10 @@ extern JS_PUBLIC_API(bool)
JS_DefinePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JSNative getter,
JSNative setter, unsigned attrs);
extern JS_PUBLIC_API(bool)
JS_DefinePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleObject getter,
JS::HandleObject setter, unsigned attrs);
extern JS_PUBLIC_API(bool)
JS_DefinePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleObject value,
unsigned attrs);
@ -2448,6 +2426,10 @@ extern JS_PUBLIC_API(bool)
JS_DefineProperty(JSContext* cx, JS::HandleObject obj, const char* name, JSNative getter,
JSNative setter, unsigned attrs);
extern JS_PUBLIC_API(bool)
JS_DefineProperty(JSContext* cx, JS::HandleObject obj, const char* name, JS::HandleObject getter,
JS::HandleObject setter, unsigned attrs);
extern JS_PUBLIC_API(bool)
JS_DefineProperty(JSContext* cx, JS::HandleObject obj, const char* name, JS::HandleObject value,
unsigned attrs);
@ -2483,7 +2465,7 @@ JS_DefineUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, s
extern JS_PUBLIC_API(bool)
JS_DefineUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
JSNative getter, JSNative setter, unsigned attrs);
JS::HandleObject getter, JS::HandleObject setter, unsigned attrs);
extern JS_PUBLIC_API(bool)
JS_DefineUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
@ -2510,8 +2492,8 @@ JS_DefineElement(JSContext* cx, JS::HandleObject obj, uint32_t index, JS::Handle
unsigned attrs);
extern JS_PUBLIC_API(bool)
JS_DefineElement(JSContext* cx, JS::HandleObject obj, uint32_t index, JSNative getter,
JSNative setter, unsigned attrs);
JS_DefineElement(JSContext* cx, JS::HandleObject obj, uint32_t index, JS::HandleObject getter,
JS::HandleObject setter, unsigned attrs);
extern JS_PUBLIC_API(bool)
JS_DefineElement(JSContext* cx, JS::HandleObject obj, uint32_t index, JS::HandleObject value,

Просмотреть файл

@ -576,7 +576,7 @@ MappedArgumentsObject::obj_resolve(JSContext* cx, HandleObject obj, HandleId id,
return true;
}
unsigned attrs = JSPROP_SHADOWABLE | JSPROP_RESOLVING;
unsigned attrs = JSPROP_RESOLVING;
if (JSID_IS_INT(id)) {
uint32_t arg = uint32_t(JSID_TO_INT(id));
if (arg >= argsobj->initialLength() || argsobj->isElementDeleted(arg))
@ -776,10 +776,20 @@ UnmappedArgumentsObject::obj_resolve(JSContext* cx, HandleObject obj, HandleId i
return true;
}
unsigned attrs = JSPROP_SHADOWABLE;
GetterOp getter = UnmappedArgGetter;
SetterOp setter = UnmappedArgSetter;
if (JSID_IS_ATOM(id, cx->names().callee)) {
RootedObject throwTypeError(cx, GlobalObject::getOrCreateThrowTypeError(cx, cx->global()));
if (!throwTypeError)
return false;
unsigned attrs = JSPROP_RESOLVING | JSPROP_PERMANENT | JSPROP_GETTER | JSPROP_SETTER;
if (!NativeDefineAccessorProperty(cx, argsobj, id, throwTypeError, throwTypeError, attrs))
return false;
*resolvedp = true;
return true;
}
unsigned attrs = JSPROP_RESOLVING;
if (JSID_IS_INT(id)) {
uint32_t arg = uint32_t(JSID_TO_INT(id));
if (arg >= argsobj->initialLength() || argsobj->isElementDeleted(arg))
@ -790,21 +800,14 @@ UnmappedArgumentsObject::obj_resolve(JSContext* cx, HandleObject obj, HandleId i
if (argsobj->hasOverriddenLength())
return true;
} else {
if (!JSID_IS_ATOM(id, cx->names().callee))
return true;
JSObject* throwTypeError = GlobalObject::getOrCreateThrowTypeError(cx, cx->global());
if (!throwTypeError)
return false;
attrs = JSPROP_PERMANENT | JSPROP_GETTER | JSPROP_SETTER;
getter = CastAsGetterOp(throwTypeError);
setter = CastAsSetterOp(throwTypeError);
return true;
}
attrs |= JSPROP_RESOLVING;
if (!NativeDefineAccessorProperty(cx, argsobj, id, getter, setter, attrs))
if (!NativeDefineAccessorProperty(cx, argsobj, id, UnmappedArgGetter, UnmappedArgSetter,
attrs))
{
return false;
}
*resolvedp = true;
return true;

Просмотреть файл

@ -8431,8 +8431,7 @@ DebuggerArguments::create(JSContext* cx, HandleObject proto, HandleDebuggerFrame
return nullptr;
id = INT_TO_JSID(i);
if (!getobj ||
!NativeDefineAccessorProperty(cx, obj, id,
JS_DATA_TO_FUNC_PTR(GetterOp, getobj.get()), nullptr,
!NativeDefineAccessorProperty(cx, obj, id, getobj, nullptr,
JSPROP_ENUMERATE | JSPROP_GETTER))
{
return nullptr;

Просмотреть файл

@ -4834,8 +4834,6 @@ js::InitGetterSetterOperation(JSContext* cx, jsbytecode* pc, HandleObject obj, H
HandleObject val)
{
MOZ_ASSERT(val->isCallable());
GetterOp getter;
SetterOp setter;
JSOp op = JSOp(*pc);
@ -4846,18 +4844,14 @@ js::InitGetterSetterOperation(JSContext* cx, jsbytecode* pc, HandleObject obj, H
if (op == JSOP_INITPROP_GETTER || op == JSOP_INITELEM_GETTER ||
op == JSOP_INITHIDDENPROP_GETTER || op == JSOP_INITHIDDENELEM_GETTER)
{
getter = CastAsGetterOp(val);
setter = nullptr;
attrs |= JSPROP_GETTER;
} else {
MOZ_ASSERT(op == JSOP_INITPROP_SETTER || op == JSOP_INITELEM_SETTER ||
op == JSOP_INITHIDDENPROP_SETTER || op == JSOP_INITHIDDENELEM_SETTER);
getter = nullptr;
setter = CastAsSetterOp(val);
attrs |= JSPROP_SETTER;
return DefineAccessorProperty(cx, obj, id, val, nullptr, attrs);
}
return DefineAccessorProperty(cx, obj, id, getter, setter, attrs);
MOZ_ASSERT(op == JSOP_INITPROP_SETTER || op == JSOP_INITELEM_SETTER ||
op == JSOP_INITHIDDENPROP_SETTER || op == JSOP_INITHIDDENELEM_SETTER);
attrs |= JSPROP_SETTER;
return DefineAccessorProperty(cx, obj, id, nullptr, val, attrs);
}
bool

Просмотреть файл

@ -2803,13 +2803,17 @@ js::DefineProperty(JSContext* cx, HandleObject obj, HandleId id, Handle<Property
bool
js::DefineAccessorProperty(JSContext* cx, HandleObject obj, HandleId id,
JSGetterOp getter, JSSetterOp setter, unsigned attrs,
HandleObject getter, HandleObject setter, unsigned attrs,
ObjectOpResult& result)
{
MOZ_ASSERT(!(attrs & JSPROP_PROPOP_ACCESSORS));
Rooted<PropertyDescriptor> desc(cx);
desc.initFields(nullptr, UndefinedHandleValue, attrs, getter, setter);
{
GetterOp getterOp = JS_DATA_TO_FUNC_PTR(GetterOp, getter.get());
SetterOp setterOp = JS_DATA_TO_FUNC_PTR(SetterOp, setter.get());
desc.initFields(nullptr, UndefinedHandleValue, attrs, getterOp, setterOp);
}
if (DefinePropertyOp op = obj->getOpsDefineProperty()) {
MOZ_ASSERT(!cx->helperThread());
return op(cx, obj, id, desc, result);
@ -2830,15 +2834,6 @@ js::DefineDataProperty(JSContext* cx, HandleObject obj, HandleId id, HandleValue
return NativeDefineProperty(cx, obj.as<NativeObject>(), id, desc, result);
}
bool
js::DefineAccessorProperty(JSContext* cx, HandleObject obj, PropertyName* name,
JSGetterOp getter, JSSetterOp setter, unsigned attrs,
ObjectOpResult& result)
{
RootedId id(cx, NameToId(name));
return DefineAccessorProperty(cx, obj, id, getter, setter, attrs, result);
}
bool
js::DefineDataProperty(JSContext* cx, HandleObject obj, PropertyName* name, HandleValue value,
unsigned attrs, ObjectOpResult& result)
@ -2847,17 +2842,6 @@ js::DefineDataProperty(JSContext* cx, HandleObject obj, PropertyName* name, Hand
return DefineDataProperty(cx, obj, id, value, attrs, result);
}
bool
js::DefineAccessorElement(JSContext* cx, HandleObject obj, uint32_t index,
JSGetterOp getter, JSSetterOp setter, unsigned attrs,
ObjectOpResult& result)
{
RootedId id(cx);
if (!IndexToId(cx, index, &id))
return false;
return DefineAccessorProperty(cx, obj, id, getter, setter, attrs, result);
}
bool
js::DefineDataElement(JSContext* cx, HandleObject obj, uint32_t index, HandleValue value,
unsigned attrs, ObjectOpResult& result)
@ -2870,7 +2854,7 @@ js::DefineDataElement(JSContext* cx, HandleObject obj, uint32_t index, HandleVal
bool
js::DefineAccessorProperty(JSContext* cx, HandleObject obj, HandleId id,
JSGetterOp getter, JSSetterOp setter, unsigned attrs)
HandleObject getter, HandleObject setter, unsigned attrs)
{
ObjectOpResult result;
if (!DefineAccessorProperty(cx, obj, id, getter, setter, attrs, result))
@ -2898,14 +2882,6 @@ js::DefineDataProperty(JSContext* cx, HandleObject obj, HandleId id, HandleValue
return true;
}
bool
js::DefineAccessorProperty(JSContext* cx, HandleObject obj, PropertyName* name,
JSGetterOp getter, JSSetterOp setter, unsigned attrs)
{
RootedId id(cx, NameToId(name));
return DefineAccessorProperty(cx, obj, id, getter, setter, attrs);
}
bool
js::DefineDataProperty(JSContext* cx, HandleObject obj, PropertyName* name, HandleValue value,
unsigned attrs)
@ -2914,16 +2890,6 @@ js::DefineDataProperty(JSContext* cx, HandleObject obj, PropertyName* name, Hand
return DefineDataProperty(cx, obj, id, value, attrs);
}
bool
js::DefineAccessorElement(JSContext* cx, HandleObject obj, uint32_t index,
JSGetterOp getter, JSSetterOp setter, unsigned attrs)
{
RootedId id(cx);
if (!IndexToId(cx, index, &id))
return false;
return DefineAccessorProperty(cx, obj, id, getter, setter, attrs);
}
bool
js::DefineDataElement(JSContext* cx, HandleObject obj, uint32_t index, HandleValue value,
unsigned attrs)

Просмотреть файл

@ -716,27 +716,17 @@ DefineProperty(JSContext* cx, HandleObject obj, HandleId id,
extern bool
DefineAccessorProperty(JSContext* cx, HandleObject obj, HandleId id,
JSGetterOp getter, JSSetterOp setter, unsigned attrs,
HandleObject getter, HandleObject setter, unsigned attrs,
ObjectOpResult& result);
extern bool
DefineDataProperty(JSContext* cx, HandleObject obj, HandleId id, HandleValue value,
unsigned attrs, ObjectOpResult& result);
extern bool
DefineAccessorProperty(JSContext* cx, HandleObject obj, PropertyName* name,
JSGetterOp getter, JSSetterOp setter, unsigned attrs,
ObjectOpResult& result);
extern bool
DefineDataProperty(JSContext* cx, HandleObject obj, PropertyName* name, HandleValue value,
unsigned attrs, ObjectOpResult& result);
extern bool
DefineAccessorElement(JSContext* cx, HandleObject obj, uint32_t index,
JSGetterOp getter, JSSetterOp setter, unsigned attrs,
ObjectOpResult& result);
extern bool
DefineDataElement(JSContext* cx, HandleObject obj, uint32_t index, HandleValue value,
unsigned attrs, ObjectOpResult& result);
@ -750,24 +740,17 @@ DefineProperty(JSContext* cx, HandleObject obj, HandleId id, Handle<JS::Property
extern bool
DefineAccessorProperty(JSContext* cx, HandleObject obj, HandleId id,
JSGetterOp getter, JSSetterOp setter, unsigned attrs = JSPROP_ENUMERATE);
HandleObject getter, HandleObject setter,
unsigned attrs = JSPROP_ENUMERATE);
extern bool
DefineDataProperty(JSContext* cx, HandleObject obj, HandleId id, HandleValue value,
unsigned attrs = JSPROP_ENUMERATE);
extern bool
DefineAccessorProperty(JSContext* cx, HandleObject obj, PropertyName* name,
JSGetterOp getter, JSSetterOp setter, unsigned attrs = JSPROP_ENUMERATE);
extern bool
DefineDataProperty(JSContext* cx, HandleObject obj, PropertyName* name, HandleValue value,
unsigned attrs = JSPROP_ENUMERATE);
extern bool
DefineAccessorElement(JSContext* cx, HandleObject obj, uint32_t index,
JSGetterOp getter, JSSetterOp setter, unsigned attrs = JSPROP_ENUMERATE);
extern bool
DefineDataElement(JSContext* cx, HandleObject obj, uint32_t index, HandleValue value,
unsigned attrs = JSPROP_ENUMERATE);
@ -1094,18 +1077,6 @@ CloneObject(JSContext* cx, HandleObject obj, Handle<js::TaggedProto> proto);
extern JSObject*
DeepCloneObjectLiteral(JSContext* cx, HandleObject obj, NewObjectKind newKind = GenericObject);
inline JSGetterOp
CastAsGetterOp(JSObject* object)
{
return JS_DATA_TO_FUNC_PTR(JSGetterOp, object);
}
inline JSSetterOp
CastAsSetterOp(JSObject* object)
{
return JS_DATA_TO_FUNC_PTR(JSSetterOp, object);
}
/* ES6 draft rev 32 (2015 Feb 2) 6.2.4.5 ToPropertyDescriptor(Obj) */
bool
ToPropertyDescriptor(JSContext* cx, HandleValue descval, bool checkAccessors,

Просмотреть файл

@ -1823,16 +1823,6 @@ js::NativeDefineProperty(JSContext* cx, HandleNativeObject obj, HandleId id,
return result.succeed();
}
bool
js::NativeDefineAccessorProperty(JSContext* cx, HandleNativeObject obj, HandleId id,
GetterOp getter, SetterOp setter, unsigned attrs,
ObjectOpResult& result)
{
Rooted<PropertyDescriptor> desc(cx);
desc.initFields(nullptr, UndefinedHandleValue, attrs, getter, setter);
return NativeDefineProperty(cx, obj, id, desc, result);
}
bool
js::NativeDefineDataProperty(JSContext* cx, HandleNativeObject obj, HandleId id,
HandleValue value, unsigned attrs, ObjectOpResult& result)
@ -1844,11 +1834,15 @@ js::NativeDefineDataProperty(JSContext* cx, HandleNativeObject obj, HandleId id,
bool
js::NativeDefineAccessorProperty(JSContext* cx, HandleNativeObject obj, HandleId id,
JSGetterOp getter, JSSetterOp setter, unsigned attrs)
GetterOp getter, SetterOp setter, unsigned attrs)
{
Rooted<PropertyDescriptor> desc(cx);
desc.initFields(nullptr, UndefinedHandleValue, attrs, getter, setter);
ObjectOpResult result;
if (!NativeDefineAccessorProperty(cx, obj, id, getter, setter, attrs, result))
if (!NativeDefineProperty(cx, obj, id, desc, result))
return false;
if (!result) {
// Off-thread callers should not get here: they must call this
// function only with known-valid arguments. Populating a new
@ -1857,6 +1851,34 @@ js::NativeDefineAccessorProperty(JSContext* cx, HandleNativeObject obj, HandleId
result.reportError(cx, obj, id);
return false;
}
return true;
}
bool
js::NativeDefineAccessorProperty(JSContext* cx, HandleNativeObject obj, HandleId id,
HandleObject getter, HandleObject setter, unsigned attrs)
{
Rooted<PropertyDescriptor> desc(cx);
{
GetterOp getterOp = JS_DATA_TO_FUNC_PTR(GetterOp, getter.get());
SetterOp setterOp = JS_DATA_TO_FUNC_PTR(SetterOp, setter.get());
desc.initFields(nullptr, UndefinedHandleValue, attrs, getterOp, setterOp);
}
ObjectOpResult result;
if (!NativeDefineProperty(cx, obj, id, desc, result))
return false;
if (!result) {
// Off-thread callers should not get here: they must call this
// function only with known-valid arguments. Populating a new
// PlainObject with configurable properties is fine.
MOZ_ASSERT(!cx->helperThread());
result.reportError(cx, obj, id);
return false;
}
return true;
}
@ -1878,14 +1900,6 @@ js::NativeDefineDataProperty(JSContext* cx, HandleNativeObject obj, HandleId id,
return true;
}
bool
js::NativeDefineAccessorProperty(JSContext* cx, HandleNativeObject obj, PropertyName* name,
JSGetterOp getter, JSSetterOp setter, unsigned attrs)
{
RootedId id(cx, NameToId(name));
return NativeDefineAccessorProperty(cx, obj, id, getter, setter, attrs);
}
bool
js::NativeDefineDataProperty(JSContext* cx, HandleNativeObject obj, PropertyName* name,
HandleValue value, unsigned attrs)
@ -2687,25 +2701,9 @@ SetExistingProperty(JSContext* cx, HandleNativeObject obj, HandleId id, HandleVa
// result is |shape|.
// Steps 5.e.i-ii.
if (pobj->is<ArrayObject>() && id == NameToId(cx->names().length)) {
Rooted<ArrayObject*> arr(cx, &pobj->as<ArrayObject>());
return ArraySetLength(cx, arr, id, shape->attributes(), v, result);
}
return NativeSetExistingDataProperty(cx, pobj, shape, v, result);
}
// SpiderMonkey special case: assigning to an inherited slotless
// property causes the setter to be called, instead of shadowing,
// unless the existing property is JSPROP_SHADOWABLE (see bug 552432).
if (!shape->isDataProperty() && !shape->hasShadowable()) {
// Even weirder sub-special-case: inherited slotless data property
// with default setter. Wut.
if (shape->hasDefaultSetter())
return result.succeed();
return CallJSSetterOp(cx, shape->setterOp(), obj, id, v, result);
}
// Shadow pobj[id] by defining a new data property receiver[id].
// Delegate everything to SetPropertyByDefining.
return SetPropertyByDefining(cx, id, v, receiver, result);

Просмотреть файл

@ -1528,11 +1528,6 @@ NativeDefineProperty(JSContext* cx, HandleNativeObject obj, HandleId id,
Handle<JS::PropertyDescriptor> desc,
ObjectOpResult& result);
extern bool
NativeDefineAccessorProperty(JSContext* cx, HandleNativeObject obj, HandleId id,
JSGetterOp getter, JSSetterOp setter, unsigned attrs,
ObjectOpResult& result);
extern bool
NativeDefineDataProperty(JSContext* cx, HandleNativeObject obj, HandleId id, HandleValue value,
unsigned attrs, ObjectOpResult& result);
@ -1540,16 +1535,16 @@ NativeDefineDataProperty(JSContext* cx, HandleNativeObject obj, HandleId id, Han
/* If the result out-param is omitted, throw on failure. */
extern bool
NativeDefineAccessorProperty(JSContext* cx, HandleNativeObject obj, HandleId id,
JSGetterOp getter, JSSetterOp setter, unsigned attrs);
GetterOp getter, SetterOp setter, unsigned attrs);
extern bool
NativeDefineAccessorProperty(JSContext* cx, HandleNativeObject obj, HandleId id,
HandleObject getter, HandleObject setter, unsigned attrs);
extern bool
NativeDefineDataProperty(JSContext* cx, HandleNativeObject obj, HandleId id, HandleValue value,
unsigned attrs);
extern bool
NativeDefineAccessorProperty(JSContext* cx, HandleNativeObject obj, PropertyName* name,
JSGetterOp getter, JSSetterOp setter, unsigned attrs);
extern bool
NativeDefineDataProperty(JSContext* cx, HandleNativeObject obj, PropertyName* name,
HandleValue value, unsigned attrs);

Просмотреть файл

@ -238,18 +238,6 @@ AutoRooterGetterSetter::AutoRooterGetterSetter(JSContext* cx, uint8_t attrs,
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
}
inline
AutoRooterGetterSetter::AutoRooterGetterSetter(JSContext* cx, uint8_t attrs,
JSNative* pgetter, JSNative* psetter
MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
{
if (attrs & (JSPROP_GETTER | JSPROP_SETTER)) {
inner.emplace(cx, attrs, reinterpret_cast<GetterOp*>(pgetter),
reinterpret_cast<SetterOp*>(psetter));
}
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
}
static inline uint8_t
GetPropertyAttributes(JSObject* obj, PropertyResult prop)
{

Просмотреть файл

@ -541,6 +541,21 @@ Shape::updateDictionaryTable(ShapeTable* table, ShapeTable::Entry* entry,
parent->handoffTableTo(this);
}
static void
AssertValidPropertyOp(NativeObject* obj, GetterOp getter, SetterOp setter, unsigned attrs)
{
// We only support PropertyOp accessors on ArrayObject and ArgumentsObject
// and we don't want to add more of these properties (bug 1404885).
#ifdef DEBUG
if ((getter && !(attrs & JSPROP_GETTER)) ||
(setter && !(attrs & JSPROP_SETTER)))
{
MOZ_ASSERT(obj->is<ArrayObject>() || obj->is<ArgumentsObject>());
}
#endif
}
/* static */ Shape*
NativeObject::addAccessorPropertyInternal(JSContext* cx,
HandleNativeObject obj, HandleId id,
@ -551,6 +566,8 @@ NativeObject::addAccessorPropertyInternal(JSContext* cx,
AutoCheckShapeConsistency check(obj);
AutoRooterGetterSetter gsRoot(cx, attrs, &getter, &setter);
AssertValidPropertyOp(obj, getter, setter, attrs);
if (!maybeConvertToOrGrowDictionaryForAdd(cx, obj, id, &table, &entry, keep))
return nullptr;
@ -972,6 +989,7 @@ NativeObject::putAccessorProperty(JSContext* cx, HandleNativeObject obj, HandleI
AutoCheckShapeConsistency check(obj);
AssertValidArrayIndex(obj, id);
AssertValidPropertyOp(obj, getter, setter, attrs);
AutoRooterGetterSetter gsRoot(cx, attrs, &getter, &setter);

Просмотреть файл

@ -387,11 +387,6 @@ class MOZ_RAII AutoKeepShapeTables
inline ~AutoKeepShapeTables();
};
/*
* Use the reserved attribute bit to mean shadowability.
*/
#define JSPROP_SHADOWABLE JSPROP_INTERNAL_USE_BIT
/*
* Shapes encode information about both a property lineage *and* a particular
* property. This information is split across the Shape and the BaseShape
@ -1078,8 +1073,6 @@ class Shape : public gc::TenuredCell
return (attrs & (JSPROP_SETTER | JSPROP_GETTER)) != 0;
}
bool hasShadowable() const { return attrs & JSPROP_SHADOWABLE; }
uint32_t entryCount() {
JS::AutoCheckCannotGC nogc;
if (ShapeTable* table = maybeTable(nogc))
@ -1216,9 +1209,6 @@ class MOZ_RAII AutoRooterGetterSetter
inline AutoRooterGetterSetter(JSContext* cx, uint8_t attrs,
GetterOp* pgetter, SetterOp* psetter
MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
inline AutoRooterGetterSetter(JSContext* cx, uint8_t attrs,
JSNative* pgetter, JSNative* psetter
MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
private:
mozilla::Maybe<Inner> inner;

Просмотреть файл

@ -1638,17 +1638,17 @@ class MOZ_STACK_CLASS JS_HAZ_ROOTED ModuleValidator
class HashableSig
{
uint32_t sigIndex_;
const SigWithIdVector& sigs_;
const TypeDefVector& types_;
public:
HashableSig(uint32_t sigIndex, const SigWithIdVector& sigs)
: sigIndex_(sigIndex), sigs_(sigs)
HashableSig(uint32_t sigIndex, const TypeDefVector& types)
: sigIndex_(sigIndex), types_(types)
{}
uint32_t sigIndex() const {
return sigIndex_;
}
const Sig& sig() const {
return sigs_[sigIndex_];
return types_[sigIndex_].funcType();
}
// Implement HashPolicy:
@ -1666,8 +1666,8 @@ class MOZ_STACK_CLASS JS_HAZ_ROOTED ModuleValidator
PropertyName* name_;
public:
NamedSig(PropertyName* name, uint32_t sigIndex, const SigWithIdVector& sigs)
: HashableSig(sigIndex, sigs), name_(name)
NamedSig(PropertyName* name, uint32_t sigIndex, const TypeDefVector& types)
: HashableSig(sigIndex, types), name_(name)
{}
PropertyName* name() const {
return name_;
@ -1755,22 +1755,22 @@ class MOZ_STACK_CLASS JS_HAZ_ROOTED ModuleValidator
return standardLibrarySimdOpNames_.putNew(atom->asPropertyName(), op);
}
bool newSig(Sig&& sig, uint32_t* sigIndex) {
if (env_.sigs.length() >= MaxTypes)
if (env_.types.length() >= MaxTypes)
return failCurrentOffset("too many signatures");
*sigIndex = env_.sigs.length();
return env_.sigs.append(std::move(sig));
*sigIndex = env_.types.length();
return env_.types.append(std::move(sig));
}
bool declareSig(Sig&& sig, uint32_t* sigIndex) {
SigSet::AddPtr p = sigSet_.lookupForAdd(sig);
if (p) {
*sigIndex = p->sigIndex();
MOZ_ASSERT(env_.sigs[*sigIndex] == sig);
MOZ_ASSERT(env_.types[*sigIndex].funcType() == sig);
return true;
}
return newSig(std::move(sig), sigIndex) &&
sigSet_.add(p, HashableSig(*sigIndex, env_.sigs));
sigSet_.add(p, HashableSig(*sigIndex, env_.types));
}
public:
@ -2308,7 +2308,7 @@ class MOZ_STACK_CLASS JS_HAZ_ROOTED ModuleValidator
if (!declareSig(std::move(sig), &sigIndex))
return false;
return funcImportMap_.add(p, NamedSig(name, sigIndex, env_.sigs), *importIndex);
return funcImportMap_.add(p, NamedSig(name, sigIndex, env_.types), *importIndex);
}
bool tryConstantAccess(uint64_t start, uint64_t width) {
@ -2457,12 +2457,12 @@ class MOZ_STACK_CLASS JS_HAZ_ROOTED ModuleValidator
for (FuncImportMap::Range r = funcImportMap_.all(); !r.empty(); r.popFront()) {
uint32_t funcIndex = r.front().value();
MOZ_ASSERT(!env_.funcSigs[funcIndex]);
env_.funcSigs[funcIndex] = &env_.sigs[r.front().key().sigIndex()];
env_.funcSigs[funcIndex] = &env_.types[r.front().key().sigIndex()].funcType();
}
for (const Func& func : funcDefs_) {
uint32_t funcIndex = funcImportMap_.count() + func.funcDefIndex();
MOZ_ASSERT(!env_.funcSigs[funcIndex]);
env_.funcSigs[funcIndex] = &env_.sigs[func.sigIndex()];
env_.funcSigs[funcIndex] = &env_.types[func.sigIndex()].funcType();
}
if (!env_.funcImportGlobalDataOffsets.resize(funcImportMap_.count()))
@ -4893,7 +4893,7 @@ CheckFunctionSignature(ModuleValidator& m, ParseNode* usepn, Sig&& sig, Property
return m.addFuncDef(name, usepn->pn_pos.begin, std::move(sig), func);
}
const SigWithId& existingSig = m.env().sigs[existing->sigIndex()];
const SigWithId& existingSig = m.env().types[existing->sigIndex()].funcType();
if (!CheckSignatureAgainstExisting(m, usepn, sig, existingSig))
return false;
@ -4951,7 +4951,7 @@ CheckFuncPtrTableAgainstExisting(ModuleValidator& m, ParseNode* usepn, PropertyN
if (mask != table.mask())
return m.failf(usepn, "mask does not match previous value (%u)", table.mask());
if (!CheckSignatureAgainstExisting(m, usepn, sig, m.env().sigs[table.sigIndex()]))
if (!CheckSignatureAgainstExisting(m, usepn, sig, m.env().types[table.sigIndex()].funcType()))
return false;
*tableIndex = existing->tableIndex();
@ -7376,7 +7376,7 @@ CheckFuncPtrTable(ModuleValidator& m, ParseNode* var)
if (!func)
return m.fail(elem, "function-pointer table's elements must be names of functions");
const Sig& funcSig = m.env().sigs[func->sigIndex()];
const Sig& funcSig = m.env().types[func->sigIndex()].funcType();
if (sig) {
if (*sig != funcSig)
return m.fail(elem, "all functions in table must have same signature");

Просмотреть файл

@ -126,7 +126,29 @@ struct AstBase
}
};
class AstSig : public AstBase
class AstSig;
class AstStruct;
class AstTypeDef : public AstBase
{
protected:
enum class Which { IsSig, IsStruct };
private:
Which which_;
public:
explicit AstTypeDef(Which which) : which_(which) {}
bool isSig() const { return which_ == Which::IsSig; }
bool isStruct() const { return which_ == Which::IsStruct; }
inline AstSig& asSig();
inline AstStruct& asStruct();
inline const AstSig& asSig() const;
inline const AstStruct& asStruct() const;
};
class AstSig : public AstTypeDef
{
AstName name_;
AstValTypeVector args_;
@ -134,15 +156,18 @@ class AstSig : public AstBase
public:
explicit AstSig(LifoAlloc& lifo)
: args_(lifo),
: AstTypeDef(Which::IsSig),
args_(lifo),
ret_(ExprType::Void)
{}
AstSig(AstValTypeVector&& args, ExprType ret)
: args_(std::move(args)),
: AstTypeDef(Which::IsSig),
args_(std::move(args)),
ret_(ret)
{}
AstSig(AstName name, AstSig&& rhs)
: name_(name),
: AstTypeDef(Which::IsSig),
name_(name),
args_(std::move(rhs.args_)),
ret_(rhs.ret_)
{}
@ -171,6 +196,68 @@ class AstSig : public AstBase
}
};
class AstStruct : public AstTypeDef
{
AstName name_;
AstNameVector fieldNames_;
AstValTypeVector fieldTypes_;
public:
explicit AstStruct(LifoAlloc& lifo)
: AstTypeDef(Which::IsStruct),
fieldNames_(lifo),
fieldTypes_(lifo)
{}
AstStruct(AstNameVector&& names, AstValTypeVector&& types)
: AstTypeDef(Which::IsStruct),
fieldNames_(std::move(names)),
fieldTypes_(std::move(types))
{}
AstStruct(AstName name, AstStruct&& rhs)
: AstTypeDef(Which::IsStruct),
name_(name),
fieldNames_(std::move(rhs.fieldNames_)),
fieldTypes_(std::move(rhs.fieldTypes_))
{}
AstName name() const {
return name_;
}
const AstNameVector& fieldNames() const {
return fieldNames_;
}
const AstValTypeVector& fieldTypes() const {
return fieldTypes_;
}
};
inline AstSig&
AstTypeDef::asSig()
{
MOZ_ASSERT(isSig());
return *static_cast<AstSig*>(this);
}
inline AstStruct&
AstTypeDef::asStruct()
{
MOZ_ASSERT(isStruct());
return *static_cast<AstStruct*>(this);
}
inline const AstSig&
AstTypeDef::asSig() const
{
MOZ_ASSERT(isSig());
return *static_cast<const AstSig*>(this);
}
inline const AstStruct&
AstTypeDef::asStruct() const
{
MOZ_ASSERT(isStruct());
return *static_cast<const AstStruct*>(this);
}
const uint32_t AstNodeUnknownOffset = 0;
class AstNode : public AstBase
@ -948,7 +1035,7 @@ class AstModule : public AstNode
typedef AstVector<AstFunc*> FuncVector;
typedef AstVector<AstImport*> ImportVector;
typedef AstVector<AstExport*> ExportVector;
typedef AstVector<AstSig*> SigVector;
typedef AstVector<AstTypeDef*> TypeDefVector;
typedef AstVector<AstName> NameVector;
typedef AstVector<AstResizable> AstResizableVector;
@ -956,7 +1043,7 @@ class AstModule : public AstNode
typedef AstHashMap<AstSig*, uint32_t, AstSig> SigMap;
LifoAlloc& lifo_;
SigVector sigs_;
TypeDefVector types_;
SigMap sigMap_;
ImportVector imports_;
NameVector funcImportNames_;
@ -974,7 +1061,7 @@ class AstModule : public AstNode
public:
explicit AstModule(LifoAlloc& lifo)
: lifo_(lifo),
sigs_(lifo),
types_(lifo),
sigMap_(lifo),
imports_(lifo),
funcImportNames_(lifo),
@ -1038,21 +1125,21 @@ class AstModule : public AstNode
*sigIndex = p->value();
return true;
}
*sigIndex = sigs_.length();
*sigIndex = types_.length();
auto* lifoSig = new (lifo_) AstSig(AstName(), std::move(sig));
return lifoSig &&
sigs_.append(lifoSig) &&
sigMap_.add(p, sigs_.back(), *sigIndex);
types_.append(lifoSig) &&
sigMap_.add(p, static_cast<AstSig*>(types_.back()), *sigIndex);
}
bool append(AstSig* sig) {
uint32_t sigIndex = sigs_.length();
if (!sigs_.append(sig))
uint32_t sigIndex = types_.length();
if (!types_.append(sig))
return false;
SigMap::AddPtr p = sigMap_.lookupForAdd(*sig);
return p || sigMap_.add(p, sig, sigIndex);
}
const SigVector& sigs() const {
return sigs_;
const TypeDefVector& types() const {
return types_;
}
bool append(AstFunc* func) {
return funcs_.append(func);
@ -1060,6 +1147,9 @@ class AstModule : public AstNode
const FuncVector& funcs() const {
return funcs_;
}
bool append(AstStruct* str) {
return types_.append(str);
}
bool append(AstImport* imp) {
switch (imp->kind()) {
case DefinitionKind::Function:

Просмотреть файл

@ -3762,7 +3762,7 @@ class BaseCompiler final : public BaseCompilerInterface
void callIndirect(uint32_t sigIndex, const Stk& indexVal, const FunctionCall& call)
{
const SigWithId& sig = env_.sigs[sigIndex];
const SigWithId& sig = env_.types[sigIndex].funcType();
MOZ_ASSERT(sig.id.kind() != SigIdDesc::Kind::None);
MOZ_ASSERT(env_.tables.length() == 1);
@ -7861,7 +7861,7 @@ BaseCompiler::emitCallIndirect()
sync();
const SigWithId& sig = env_.sigs[sigIndex];
const SigWithId& sig = env_.types[sigIndex].funcType();
// Stack: ... arg1 .. argn callee
@ -8830,6 +8830,9 @@ BaseCompiler::emitInstanceCall(uint32_t lineOrBytecode, const MIRTypeVector& sig
popValueStackBy(numArgs);
// Note, a number of clients of emitInstanceCall currently assume that the
// following operation does not destroy ReturnReg.
pushReturnedIfNonVoid(baselineCall, retType);
}

Просмотреть файл

@ -68,6 +68,9 @@ enum class TypeCode
// Type constructor for function types
Func = 0x60, // SLEB128(-0x20)
// Type constructor for structure types - unofficial
Struct = 0x50, // SLEB128(-0x30)
// Special code representing the block signature ()->()
BlockVoid = 0x40, // SLEB128(-0x40)
@ -603,6 +606,7 @@ static const unsigned MaxElemSegments = 10000000;
static const unsigned MaxTableMaximumLength = 10000000;
static const unsigned MaxLocals = 50000;
static const unsigned MaxParams = 1000;
static const unsigned MaxStructFields = 1000;
static const unsigned MaxMemoryMaximumPages = 65536;
static const unsigned MaxStringBytes = 100000;
static const unsigned MaxModuleBytes = 1024 * 1024 * 1024;

Просмотреть файл

@ -97,12 +97,12 @@ class AstDecodeContext
public:
AstDecodeContext(JSContext* cx, LifoAlloc& lifo, Decoder& d, AstModule& module,
bool generateNames)
bool generateNames, HasGcTypes hasGcTypes)
: cx(cx),
lifo(lifo),
d(d),
generateNames(generateNames),
env_(CompileMode::Once, Tier::Ion, DebugEnabled::False, HasGcTypes::False,
env_(CompileMode::Once, Tier::Ion, DebugEnabled::False, hasGcTypes,
cx->realm()->creationOptions().getSharedMemoryAndAtomicsEnabled()
? Shareable::True
: Shareable::False),
@ -351,7 +351,7 @@ AstDecodeCallIndirect(AstDecodeContext& c)
if (!GenerateRef(c, AstName(u"type"), sigIndex, &sigRef))
return false;
const SigWithId& sig = c.env().sigs[sigIndex];
const SigWithId& sig = c.env().types[sigIndex].funcType();
AstExprVector args(c.lifo);
if (!AstDecodeCallArgs(c, sig, &args))
return false;
@ -1958,26 +1958,59 @@ AstDecodeFunctionBody(AstDecodeContext &c, uint32_t funcIndex, AstFunc** func)
// wasm decoding and generation
static bool
AstCreateSignatures(AstDecodeContext& c)
AstCreateTypes(AstDecodeContext& c)
{
SigWithIdVector& sigs = c.env().sigs;
uint32_t typeIndexForNames = 0;
for (const TypeDef& td : c.env().types) {
if (td.isFuncType()) {
const Sig& sig = td.funcType();
for (size_t sigIndex = 0; sigIndex < sigs.length(); sigIndex++) {
const Sig& sig = sigs[sigIndex];
AstValTypeVector args(c.lifo);
if (!args.appendAll(sig.args()))
return false;
AstValTypeVector args(c.lifo);
if (!args.appendAll(sig.args()))
return false;
AstSig sigNoName(std::move(args), sig.ret());
AstSig sigNoName(std::move(args), sig.ret());
AstName sigName;
if (!GenerateName(c, AstName(u"type"), typeIndexForNames, &sigName))
return false;
AstName sigName;
if (!GenerateName(c, AstName(u"type"), sigIndex, &sigName))
return false;
AstSig* astSig = new(c.lifo) AstSig(sigName, std::move(sigNoName));
if (!astSig || !c.module().append(astSig))
return false;
} else if (td.isStructType()) {
const StructType& str = td.structType();
AstSig* astSig = new(c.lifo) AstSig(sigName, std::move(sigNoName));
if (!astSig || !c.module().append(astSig))
return false;
AstValTypeVector fieldTypes(c.lifo);
if (!fieldTypes.appendAll(str.fields_))
return false;
AstNameVector fieldNames(c.lifo);
if (!fieldNames.resize(fieldTypes.length()))
return false;
// The multiplication ensures that generated field names are unique
// within the module, though the resulting namespace is very sparse.
for (size_t fieldIndex = 0; fieldIndex < fieldTypes.length(); fieldIndex++) {
size_t idx = (typeIndexForNames * MaxStructFields) + fieldIndex;
if (!GenerateName(c, AstName(u"f"), idx, &fieldNames[fieldIndex]))
return false;
}
AstStruct structNoName(std::move(fieldNames), std::move(fieldTypes));
AstName structName;
if (!GenerateName(c, AstName(u"type"), typeIndexForNames, &structName))
return false;
AstStruct* astStruct = new(c.lifo) AstStruct(structName, std::move(structNoName));
if (!astStruct || !c.module().append(astStruct))
return false;
} else {
MOZ_CRASH();
}
typeIndexForNames++;
}
return true;
@ -2230,7 +2263,7 @@ AstDecodeEnvironment(AstDecodeContext& c)
if (!DecodeModuleEnvironment(c.d, &c.env()))
return false;
if (!AstCreateSignatures(c))
if (!AstCreateTypes(c))
return false;
if (!AstCreateImports(c))
@ -2333,7 +2366,7 @@ wasm::BinaryToAst(JSContext* cx, const uint8_t* bytes, uint32_t length, LifoAllo
UniqueChars error;
Decoder d(bytes, bytes + length, 0, &error, nullptr, /* resilient */ true);
AstDecodeContext c(cx, lifo, d, *result, true);
AstDecodeContext c(cx, lifo, d, *result, /* generateNames */ true, HasGcTypes::True);
if (!AstDecodeEnvironment(c) ||
!AstDecodeCodeSection(c) ||

Просмотреть файл

@ -191,6 +191,7 @@ RenderExprType(WasmRenderContext& c, ExprType type)
case ExprType::I64: return c.buffer.append("i64");
case ExprType::F32: return c.buffer.append("f32");
case ExprType::F64: return c.buffer.append("f64");
case ExprType::AnyRef: return c.buffer.append("anyref");
default:;
}
@ -209,6 +210,12 @@ RenderName(WasmRenderContext& c, const AstName& name)
return c.buffer.append(name.begin(), name.end());
}
static bool
RenderNonemptyName(WasmRenderContext& c, const AstName& name)
{
return name.empty() || (RenderName(c, name) && c.buffer.append(' '));
}
static bool
RenderRef(WasmRenderContext& c, const AstRef& ref)
{
@ -1481,12 +1488,8 @@ RenderSignature(WasmRenderContext& c, const AstSig& sig, const AstNameVector* ma
if (!c.buffer.append(" (param "))
return false;
const AstName& name = (*maybeLocals)[i];
if (!name.empty()) {
if (!RenderName(c, name))
return false;
if (!c.buffer.append(" "))
return false;
}
if (!RenderNonemptyName(c, name))
return false;
ValType arg = sig.args()[i];
if (!RenderValType(c, arg))
return false;
@ -1518,34 +1521,76 @@ RenderSignature(WasmRenderContext& c, const AstSig& sig, const AstNameVector* ma
}
static bool
RenderTypeSection(WasmRenderContext& c, const AstModule::SigVector& sigs)
RenderFields(WasmRenderContext& c, const AstStruct& str)
{
uint32_t numSigs = sigs.length();
if (!numSigs)
return true;
const AstNameVector& fieldNames = str.fieldNames();
const AstValTypeVector& fieldTypes = str.fieldTypes();
for (uint32_t sigIndex = 0; sigIndex < numSigs; sigIndex++) {
const AstSig* sig = sigs[sigIndex];
for (uint32_t fieldIndex = 0; fieldIndex < fieldTypes.length(); fieldIndex++) {
if (!c.buffer.append("\n"))
return false;
if (!RenderIndent(c))
return false;
if (!c.buffer.append("(type"))
if (!c.buffer.append("(field "))
return false;
if (!sig->name().empty()) {
if (!c.buffer.append(" "))
return false;
if (!RenderName(c, sig->name()))
return false;
}
if (!c.buffer.append(" (func"))
if (!RenderNonemptyName(c, fieldNames[fieldIndex]))
return false;
if (!RenderSignature(c, *sig))
if (!RenderValType(c, fieldTypes[fieldIndex]))
return false;
if (!c.buffer.append("))\n"))
if (!c.buffer.append(')'))
return false;
}
return true;
}
template<size_t ArrayLength>
static bool
RenderTypeStart(WasmRenderContext& c, const AstName& name, const char (&keyword)[ArrayLength])
{
if (!RenderIndent(c))
return false;
if (!c.buffer.append("(type "))
return false;
if (!RenderNonemptyName(c, name))
return false;
if (!c.buffer.append("("))
return false;
return c.buffer.append(keyword);
}
static bool
RenderTypeEnd(WasmRenderContext& c)
{
return c.buffer.append("))\n");
}
static bool
RenderTypeSection(WasmRenderContext& c, const AstModule::TypeDefVector& types)
{
for (uint32_t typeIndex = 0; typeIndex < types.length(); typeIndex++) {
const AstTypeDef* type = types[typeIndex];
if (type->isSig()) {
const AstSig* sig = &type->asSig();
if (!RenderTypeStart(c, sig->name(), "func"))
return false;
if (!RenderSignature(c, *sig))
return false;
} else {
const AstStruct* strukt = &type->asStruct();
if (!RenderTypeStart(c, strukt->name(), "struct"))
return false;
c.indent++;
if (!RenderFields(c, *strukt))
return false;
c.indent--;
}
if (!RenderTypeEnd(c))
return false;
}
return true;
}
static bool
RenderLimits(WasmRenderContext& c, const Limits& limits)
{
@ -1755,7 +1800,7 @@ RenderImport(WasmRenderContext& c, AstImport& import, const AstModule& module)
case DefinitionKind::Function: {
if (!c.buffer.append("(func"))
return false;
const AstSig* sig = module.sigs()[import.funcSig().index()];
const AstSig* sig = &module.types()[import.funcSig().index()]->asSig();
if (!RenderSignature(c, *sig))
return false;
if (!c.buffer.append(")"))
@ -1858,9 +1903,9 @@ RenderExportSection(WasmRenderContext& c, const AstModule::ExportVector& exports
}
static bool
RenderFunctionBody(WasmRenderContext& c, AstFunc& func, const AstModule::SigVector& sigs)
RenderFunctionBody(WasmRenderContext& c, AstFunc& func, const AstModule::TypeDefVector& types)
{
const AstSig* sig = sigs[func.sig().index()];
const AstSig* sig = &types[func.sig().index()]->asSig();
uint32_t argsNum = sig->args().length();
uint32_t localsNum = func.vars().length();
@ -1904,13 +1949,13 @@ RenderFunctionBody(WasmRenderContext& c, AstFunc& func, const AstModule::SigVect
static bool
RenderCodeSection(WasmRenderContext& c, const AstModule::FuncVector& funcs,
const AstModule::SigVector& sigs)
const AstModule::TypeDefVector& types)
{
uint32_t numFuncBodies = funcs.length();
for (uint32_t funcIndex = 0; funcIndex < numFuncBodies; funcIndex++) {
AstFunc* func = funcs[funcIndex];
uint32_t sigIndex = func->sig().index();
AstSig* sig = sigs[sigIndex];
AstSig* sig = &types[sigIndex]->asSig();
if (!RenderIndent(c))
return false;
@ -1929,7 +1974,7 @@ RenderCodeSection(WasmRenderContext& c, const AstModule::FuncVector& funcs,
c.currentFuncIndex = funcIndex;
c.indent++;
if (!RenderFunctionBody(c, *func, sigs))
if (!RenderFunctionBody(c, *func, types))
return false;
c.indent--;
if (!RenderIndent(c))
@ -2026,7 +2071,7 @@ RenderModule(WasmRenderContext& c, AstModule& module)
c.indent++;
if (!RenderTypeSection(c, module.sigs()))
if (!RenderTypeSection(c, module.types()))
return false;
if (!RenderImportSection(c, module))
@ -2050,7 +2095,7 @@ RenderModule(WasmRenderContext& c, AstModule& module)
if (!RenderElemSection(c, module))
return false;
if (!RenderCodeSection(c, module.funcs(), module.sigs()))
if (!RenderCodeSection(c, module.funcs(), module.types()))
return false;
if (!RenderDataSection(c, module))

Просмотреть файл

@ -243,7 +243,11 @@ ModuleGenerator::init(Metadata* maybeAsmJSMetadata)
}
if (!isAsmJS()) {
for (SigWithId& sig : env_->sigs) {
for (TypeDef& td : env_->types) {
if (!td.isFuncType())
continue;
SigWithId& sig = td.funcType();
if (SigIdDesc::isGlobal(sig)) {
uint32_t globalDataOffset;
if (!allocateGlobalBytes(sizeof(void*), sizeof(void*), &globalDataOffset))
@ -979,6 +983,12 @@ ModuleGenerator::finishModule(const ShareableBytes& bytecode)
if (!code || !code->initialize(bytecode, *linkDataTier_))
return nullptr;
StructTypeVector structTypes;
for (TypeDef& td : env_->types) {
if (td.isStructType() && !structTypes.append(std::move(td.structType())))
return nullptr;
}
SharedModule module(js_new<Module>(std::move(assumptions_),
*code,
std::move(maybeDebuggingBytes),
@ -987,6 +997,7 @@ ModuleGenerator::finishModule(const ShareableBytes& bytecode)
std::move(env_->exports),
std::move(env_->dataSegments),
std::move(env_->elemSegments),
std::move(structTypes),
bytecode));
if (!module)
return nullptr;

Просмотреть файл

@ -1212,7 +1212,7 @@ class FunctionCompiler
return true;
}
const SigWithId& sig = env_.sigs[sigIndex];
const SigWithId& sig = env_.types[sigIndex].funcType();
CalleeDesc callee;
if (env_.isAsmJS()) {
@ -2235,7 +2235,7 @@ EmitCallIndirect(FunctionCompiler& f, bool oldStyle)
if (f.inDeadCode())
return true;
const Sig& sig = f.env().sigs[sigIndex];
const Sig& sig = f.env().types[sigIndex].funcType();
CallCompileState call(f, lineOrBytecode);
if (!EmitCallArgs(f, sig, args, &call))

Просмотреть файл

@ -398,6 +398,7 @@ Module::compiledSerializedSize() const
SerializedVectorSize(exports_) +
SerializedPodVectorSize(dataSegments_) +
SerializedVectorSize(elemSegments_) +
SerializedVectorSize(structTypes_) +
code_->serializedSize();
}
@ -423,6 +424,7 @@ Module::compiledSerialize(uint8_t* compiledBegin, size_t compiledSize) const
cursor = SerializeVector(cursor, exports_);
cursor = SerializePodVector(cursor, dataSegments_);
cursor = SerializeVector(cursor, elemSegments_);
cursor = SerializeVector(cursor, structTypes_);
cursor = code_->serialize(cursor, linkData_);
MOZ_RELEASE_ASSERT(cursor == compiledBegin + compiledSize);
}
@ -486,6 +488,11 @@ Module::deserialize(const uint8_t* bytecodeBegin, size_t bytecodeSize,
if (!cursor)
return nullptr;
StructTypeVector structTypes;
cursor = DeserializeVector(cursor, &structTypes);
if (!cursor)
return nullptr;
SharedCode code;
cursor = Code::deserialize(cursor, *bytecode, linkData, *metadata, &code);
if (!cursor)
@ -502,6 +509,7 @@ Module::deserialize(const uint8_t* bytecodeBegin, size_t bytecodeSize,
std::move(exports),
std::move(dataSegments),
std::move(elemSegments),
std::move(structTypes),
*bytecode);
}
@ -627,6 +635,7 @@ Module::addSizeOfMisc(MallocSizeOf mallocSizeOf,
SizeOfVectorExcludingThis(exports_, mallocSizeOf) +
dataSegments_.sizeOfExcludingThis(mallocSizeOf) +
SizeOfVectorExcludingThis(elemSegments_, mallocSizeOf) +
SizeOfVectorExcludingThis(structTypes_, mallocSizeOf) +
bytecode_->sizeOfIncludingThisIfNotSeen(mallocSizeOf, seenBytes);
if (unlinkedCodeForDebugging_)
*data += unlinkedCodeForDebugging_->sizeOfExcludingThis(mallocSizeOf);

Просмотреть файл

@ -135,6 +135,7 @@ class Module : public JS::WasmModule
const ExportVector exports_;
const DataSegmentVector dataSegments_;
const ElemSegmentVector elemSegments_;
const StructTypeVector structTypes_;
const SharedBytes bytecode_;
ExclusiveTiering tiering_;
@ -170,6 +171,7 @@ class Module : public JS::WasmModule
ExportVector&& exports,
DataSegmentVector&& dataSegments,
ElemSegmentVector&& elemSegments,
StructTypeVector&& structTypes,
const ShareableBytes& bytecode)
: assumptions_(std::move(assumptions)),
code_(&code),
@ -179,6 +181,7 @@ class Module : public JS::WasmModule
exports_(std::move(exports)),
dataSegments_(std::move(dataSegments)),
elemSegments_(std::move(elemSegments)),
structTypes_(std::move(structTypes)),
bytecode_(&bytecode),
tiering_(mutexid::WasmModuleTieringLock),
codeIsBusy_(false)

Просмотреть файл

@ -1732,7 +1732,7 @@ OpIter<Policy>::readCallIndirect(uint32_t* sigIndex, Value* callee, ValueVector*
if (!readVarU32(sigIndex))
return fail("unable to read call_indirect signature index");
if (*sigIndex >= env_.numSigs())
if (*sigIndex >= env_.numTypes())
return fail("signature index out of range");
uint8_t flags;
@ -1745,7 +1745,10 @@ OpIter<Policy>::readCallIndirect(uint32_t* sigIndex, Value* callee, ValueVector*
if (!popWithType(ValType::I32, callee))
return false;
const Sig& sig = env_.sigs[*sigIndex];
if (!env_.types[*sigIndex].isFuncType())
return fail("expected signature type");
const Sig& sig = env_.types[*sigIndex].funcType();
if (!popCallArgs(sig.args(), argValues))
return false;
@ -1789,10 +1792,13 @@ OpIter<Policy>::readOldCallIndirect(uint32_t* sigIndex, Value* callee, ValueVect
if (!readVarU32(sigIndex))
return fail("unable to read call_indirect signature index");
if (*sigIndex >= env_.numSigs())
if (*sigIndex >= env_.numTypes())
return fail("signature index out of range");
const Sig& sig = env_.sigs[*sigIndex];
if (!env_.types[*sigIndex].isFuncType())
return fail("expected signature type");
const Sig& sig = env_.types[*sigIndex].funcType();
if (!popCallArgs(sig.args(), argValues))
return false;

Просмотреть файл

@ -94,6 +94,7 @@ class WasmToken
#ifdef ENABLE_WASM_SATURATING_TRUNC_OPS
ExtraConversionOpcode,
#endif
Field,
Float,
Func,
GetGlobal,
@ -127,6 +128,7 @@ class WasmToken
Shared,
SignedInteger,
Start,
Struct,
Store,
Table,
TeeLocal,
@ -364,6 +366,7 @@ class WasmToken
case End:
case Error:
case Export:
case Field:
case Float:
case Func:
case Global:
@ -382,6 +385,7 @@ class WasmToken
case Shared:
case SignedInteger:
case Start:
case Struct:
case Table:
case Text:
case Then:
@ -951,6 +955,9 @@ WasmTokenStream::next()
break;
case 'f':
if (consume(u"field"))
return WasmToken(WasmToken::Field, begin, cur_);
if (consume(u"func"))
return WasmToken(WasmToken::Func, begin, cur_);
@ -1708,6 +1715,8 @@ WasmTokenStream::next()
#endif
if (consume(u"start"))
return WasmToken(WasmToken::Start, begin, cur_);
if (consume(u"struct"))
return WasmToken(WasmToken::Struct, begin, cur_);
break;
case 't':
@ -3331,24 +3340,71 @@ ParseFunc(WasmParseContext& c, AstModule* module)
return func && module->append(func);
}
static AstSig*
static bool
ParseGlobalType(WasmParseContext& c, WasmToken* typeToken, bool* isMutable);
static bool
ParseStructFields(WasmParseContext& c, AstStruct* str)
{
AstNameVector names(c.lifo);
AstValTypeVector types(c.lifo);
while (true) {
if (!c.ts.getIf(WasmToken::OpenParen))
break;
if (!c.ts.match(WasmToken::Field, c.error))
return false;
AstName name = c.ts.getIfName();
WasmToken typeToken;
bool isMutable;
if (!ParseGlobalType(c, &typeToken, &isMutable))
return false;
if (!c.ts.match(WasmToken::CloseParen, c.error))
return false;
if (!names.append(name))
return false;
if (!types.append(typeToken.valueType()))
return false;
}
*str = AstStruct(std::move(names), std::move(types));
return true;
}
static AstTypeDef*
ParseTypeDef(WasmParseContext& c)
{
AstName name = c.ts.getIfName();
if (!c.ts.match(WasmToken::OpenParen, c.error))
return nullptr;
if (!c.ts.match(WasmToken::Func, c.error))
return nullptr;
AstSig sig(c.lifo);
if (!ParseFuncSig(c, &sig))
AstTypeDef* type = nullptr;
if (c.ts.getIf(WasmToken::Func)) {
AstSig sig(c.lifo);
if (!ParseFuncSig(c, &sig))
return nullptr;
type = new(c.lifo) AstSig(name, std::move(sig));
} else if (c.ts.getIf(WasmToken::Struct)) {
AstStruct str(c.lifo);
if (!ParseStructFields(c, &str))
return nullptr;
type = new(c.lifo) AstStruct(name, std::move(str));
} else {
c.ts.generateError(c.ts.peek(), "bad type definition", c.error);
return nullptr;
}
if (!c.ts.match(WasmToken::CloseParen, c.error))
return nullptr;
return new(c.lifo) AstSig(name, std::move(sig));
return type;
}
static bool
@ -3922,8 +3978,10 @@ ParseModule(const char16_t* text, uintptr_t stackLimit, LifoAlloc& lifo, UniqueC
switch (section.kind()) {
case WasmToken::Type: {
AstSig* sig = ParseTypeDef(c);
if (!sig || !module->append(sig))
AstTypeDef* typeDef = ParseTypeDef(c);
if (!typeDef)
return nullptr;
if (!module->append(static_cast<AstSig*>(typeDef)))
return nullptr;
break;
}
@ -4008,6 +4066,7 @@ class Resolver
AstNameMap importMap_;
AstNameMap tableMap_;
AstNameMap memoryMap_;
AstNameMap typeMap_;
AstNameVector targetStack_;
bool registerName(AstNameMap& map, AstName name, size_t index) {
@ -4045,6 +4104,7 @@ class Resolver
importMap_(lifo),
tableMap_(lifo),
memoryMap_(lifo),
typeMap_(lifo),
targetStack_(lifo)
{}
bool init() {
@ -4053,6 +4113,7 @@ class Resolver
importMap_.init() &&
tableMap_.init() &&
memoryMap_.init() &&
typeMap_.init() &&
varMap_.init() &&
globalMap_.init();
}
@ -4072,6 +4133,7 @@ class Resolver
REGISTER(Global, globalMap_)
REGISTER(Table, tableMap_)
REGISTER(Memory, memoryMap_)
REGISTER(Type, typeMap_)
#undef REGISTER
@ -4097,6 +4159,7 @@ class Resolver
RESOLVE(globalMap_, Global)
RESOLVE(tableMap_, Table)
RESOLVE(memoryMap_, Memory)
RESOLVE(typeMap_, Type)
#undef RESOLVE
@ -4538,11 +4601,18 @@ ResolveModule(LifoAlloc& lifo, AstModule* module, UniqueChars* error)
if (!r.init())
return false;
size_t numSigs = module->sigs().length();
for (size_t i = 0; i < numSigs; i++) {
AstSig* sig = module->sigs()[i];
if (!r.registerSigName(sig->name(), i))
return r.fail("duplicate signature");
size_t numTypes = module->types().length();
for (size_t i = 0; i < numTypes; i++) {
AstTypeDef* ty = module->types()[i];
if (ty->isSig()) {
AstSig* sig = static_cast<AstSig*>(ty);
if (!r.registerSigName(sig->name(), i))
return r.fail("duplicate signature");
} else if (ty->isStruct()) {
AstStruct* str = static_cast<AstStruct*>(ty);
if (!r.registerTypeName(str->name(), i))
return r.fail("duplicate struct");
}
}
size_t lastFuncIndex = 0;
@ -5169,34 +5239,51 @@ EncodeExpr(Encoder& e, AstExpr& expr)
static bool
EncodeTypeSection(Encoder& e, AstModule& module)
{
if (module.sigs().empty())
if (module.types().empty())
return true;
size_t offset;
if (!e.startSection(SectionId::Type, &offset))
return false;
if (!e.writeVarU32(module.sigs().length()))
if (!e.writeVarU32(module.types().length()))
return false;
for (AstSig* sig : module.sigs()) {
if (!e.writeVarU32(uint32_t(TypeCode::Func)))
return false;
if (!e.writeVarU32(sig->args().length()))
return false;
for (ValType t : sig->args()) {
if (!e.writeValType(t))
for (AstTypeDef* ty : module.types()) {
if (ty->isSig()) {
AstSig* sig = static_cast<AstSig*>(ty);
if (!e.writeVarU32(uint32_t(TypeCode::Func)))
return false;
}
if (!e.writeVarU32(!IsVoid(sig->ret())))
return false;
if (!IsVoid(sig->ret())) {
if (!e.writeValType(NonVoidToValType(sig->ret())))
if (!e.writeVarU32(sig->args().length()))
return false;
for (ValType t : sig->args()) {
if (!e.writeValType(t))
return false;
}
if (!e.writeVarU32(!IsVoid(sig->ret())))
return false;
if (!IsVoid(sig->ret())) {
if (!e.writeValType(NonVoidToValType(sig->ret())))
return false;
}
} else if (ty->isStruct()) {
AstStruct* str = static_cast<AstStruct*>(ty);
if (!e.writeVarU32(uint32_t(TypeCode::Struct)))
return false;
if (!e.writeVarU32(str->fieldTypes().length()))
return false;
for (ValType t : str->fieldTypes()) {
if (!e.writeValType(t))
return false;
}
} else {
MOZ_CRASH();
}
}

Просмотреть файл

@ -327,6 +327,36 @@ SigWithId::sizeOfExcludingThis(MallocSizeOf mallocSizeOf) const
return Sig::sizeOfExcludingThis(mallocSizeOf);
}
size_t
StructType::serializedSize() const
{
return SerializedPodVectorSize(fields_) +
SerializedPodVectorSize(fieldOffsets_);
}
uint8_t*
StructType::serialize(uint8_t* cursor) const
{
cursor = SerializePodVector(cursor, fields_);
cursor = SerializePodVector(cursor, fieldOffsets_);
return cursor;
}
const uint8_t*
StructType::deserialize(const uint8_t* cursor)
{
(cursor = DeserializePodVector(cursor, &fields_));
(cursor = DeserializePodVector(cursor, &fieldOffsets_));
return cursor;
}
size_t
StructType::sizeOfExcludingThis(MallocSizeOf mallocSizeOf) const
{
return fields_.sizeOfExcludingThis(mallocSizeOf) +
fieldOffsets_.sizeOfExcludingThis(mallocSizeOf);
}
size_t
Import::serializedSize() const
{

Просмотреть файл

@ -24,7 +24,6 @@
#include "mozilla/EnumeratedArray.h"
#include "mozilla/HashFunctions.h"
#include "mozilla/Maybe.h"
#include "mozilla/Move.h"
#include "mozilla/RefPtr.h"
#include "mozilla/Unused.h"
@ -753,6 +752,31 @@ struct SigHashPolicy
static bool match(const Sig* lhs, Lookup rhs) { return *lhs == rhs; }
};
// Structure type.
//
// The Module owns a dense array of Struct values that represent the structure
// types that the module knows about. It is created from the sparse array of
// types in the ModuleEnvironment when the Module is created.
class StructType
{
public:
ValTypeVector fields_; // Scalar types of fields
Uint32Vector fieldOffsets_; // Byte offsets into an object for corresponding field
public:
StructType() : fields_(), fieldOffsets_() {}
StructType(ValTypeVector&& fields, Uint32Vector&& fieldOffsets)
: fields_(std::move(fields)),
fieldOffsets_(std::move(fieldOffsets))
{}
WASM_DECLARE_SERIALIZABLE(StructType)
};
typedef Vector<StructType, 0, SystemAllocPolicy> StructTypeVector;
// An InitExpr describes a deferred initializer expression, used to initialize
// a global or a table element offset. Such expressions are created during
// decoding and actually executed on module instantiation.
@ -1113,6 +1137,97 @@ struct SigWithId : Sig
typedef Vector<SigWithId, 0, SystemAllocPolicy> SigWithIdVector;
typedef Vector<const SigWithId*, 0, SystemAllocPolicy> SigWithIdPtrVector;
// A tagged container for the various types that can be present in a wasm
// module's type section.
class TypeDef
{
enum { IsFuncType, IsStructType, IsNone } tag_;
union {
SigWithId funcType_;
StructType structType_;
};
public:
TypeDef() : tag_(IsNone), structType_(StructType()) {}
explicit TypeDef(Sig&& sig) : tag_(IsFuncType), funcType_(SigWithId(std::move(sig))) {}
explicit TypeDef(StructType&& structType) : tag_(IsStructType), structType_(std::move(structType)) {}
TypeDef(TypeDef&& td) : tag_(td.tag_), structType_(StructType()) {
switch (tag_) {
case IsFuncType: funcType_ = std::move(td.funcType_); break;
case IsStructType: structType_ = std::move(td.structType_); break;
case IsNone: break;
}
}
~TypeDef() {
switch (tag_) {
case IsFuncType: funcType_.~SigWithId(); break;
case IsStructType: structType_.~StructType(); break;
case IsNone: break;
}
}
TypeDef& operator=(TypeDef&& that) {
tag_ = that.tag_;
switch (tag_) {
case IsFuncType: funcType_ = std::move(that.funcType_); break;
case IsStructType: structType_ = std::move(that.structType_); break;
case IsNone: break;
}
return *this;
}
bool isFuncType() const {
return tag_ == IsFuncType;
}
bool isStructType() const {
return tag_ == IsStructType;
}
const SigWithId& funcType() const {
MOZ_ASSERT(isFuncType());
return funcType_;
}
SigWithId& funcType() {
MOZ_ASSERT(isFuncType());
return funcType_;
}
// p has to point to the sig_ embedded within a TypeDef for this to be
// valid.
static const TypeDef* fromSigWithIdPtr(const SigWithId* p) {
const TypeDef* q = (const TypeDef*)((char*)p - offsetof(TypeDef, funcType_));
MOZ_ASSERT(q->tag_ == IsFuncType);
return q;
}
const StructType& structType() const {
MOZ_ASSERT(isStructType());
return structType_;
}
StructType& structType() {
MOZ_ASSERT(isStructType());
return structType_;
}
// p has to point to the struct_ embedded within a TypeDef for this to be
// valid.
static const TypeDef* fromStructPtr(const StructType* p) {
const TypeDef* q = (const TypeDef*)((char*)p - offsetof(TypeDef, structType_));
MOZ_ASSERT(q->tag_ == IsStructType);
return q;
}
};
typedef Vector<TypeDef, 0, SystemAllocPolicy> TypeDefVector;
// A wasm::Trap represents a wasm-defined trap that can occur during execution
// which triggers a WebAssembly.RuntimeError. Generated code may jump to a Trap
// symbolically, passing the bytecode offset to report as the trap offset. The

Просмотреть файл

@ -1063,6 +1063,78 @@ DecodePreamble(Decoder& d)
return true;
}
static bool
DecodeFuncType(Decoder& d, ModuleEnvironment* env, uint32_t typeIndex)
{
uint32_t numArgs;
if (!d.readVarU32(&numArgs))
return d.fail("bad number of function args");
if (numArgs > MaxParams)
return d.fail("too many arguments in signature");
ValTypeVector args;
if (!args.resize(numArgs))
return false;
for (uint32_t i = 0; i < numArgs; i++) {
if (!DecodeValType(d, ModuleKind::Wasm, env->gcTypesEnabled, &args[i]))
return false;
}
uint32_t numRets;
if (!d.readVarU32(&numRets))
return d.fail("bad number of function returns");
if (numRets > 1)
return d.fail("too many returns in signature");
ExprType result = ExprType::Void;
if (numRets == 1) {
ValType type;
if (!DecodeValType(d, ModuleKind::Wasm, env->gcTypesEnabled, &type))
return false;
result = ToExprType(type);
}
env->types[typeIndex] = TypeDef(Sig(std::move(args), result));
return true;
}
static bool
DecodeStructType(Decoder& d, ModuleEnvironment* env, uint32_t typeIndex)
{
if (env->gcTypesEnabled == HasGcTypes::False)
return d.fail("Structure types not enabled");
uint32_t numFields;
if (!d.readVarU32(&numFields))
return d.fail("Bad number of fields");
if (numFields > MaxStructFields)
return d.fail("too many fields in structure");
ValTypeVector fields;
if (!fields.resize(numFields))
return false;
Uint32Vector fieldOffsets;
if (!fieldOffsets.resize(numFields))
return false;
// TODO (subsequent patch): lay out the fields.
for (uint32_t i = 0; i < numFields; i++) {
if (!DecodeValType(d, ModuleKind::Wasm, env->gcTypesEnabled, &fields[i]))
return false;
}
env->types[typeIndex] = TypeDef(StructType(std::move(fields), std::move(fieldOffsets)));
return true;
}
static bool
DecodeTypeSection(Decoder& d, ModuleEnvironment* env)
{
@ -1072,55 +1144,33 @@ DecodeTypeSection(Decoder& d, ModuleEnvironment* env)
if (!range)
return true;
uint32_t numSigs;
if (!d.readVarU32(&numSigs))
return d.fail("expected number of signatures");
uint32_t numTypes;
if (!d.readVarU32(&numTypes))
return d.fail("expected number of types");
if (numSigs > MaxTypes)
return d.fail("too many signatures");
if (numTypes > MaxTypes)
return d.fail("too many types");
if (!env->sigs.resize(numSigs))
if (!env->types.resize(numTypes))
return false;
for (uint32_t sigIndex = 0; sigIndex < numSigs; sigIndex++) {
for (uint32_t typeIndex = 0; typeIndex < numTypes; typeIndex++) {
uint8_t form;
if (!d.readFixedU8(&form) || form != uint8_t(TypeCode::Func))
return d.fail("expected function form");
if (!d.readFixedU8(&form))
return d.fail("expected type form");
uint32_t numArgs;
if (!d.readVarU32(&numArgs))
return d.fail("bad number of function args");
if (numArgs > MaxParams)
return d.fail("too many arguments in signature");
ValTypeVector args;
if (!args.resize(numArgs))
return false;
for (uint32_t i = 0; i < numArgs; i++) {
if (!DecodeValType(d, ModuleKind::Wasm, env->gcTypesEnabled, &args[i]))
switch (form) {
case uint8_t(TypeCode::Func):
if (!DecodeFuncType(d, env, typeIndex))
return false;
}
uint32_t numRets;
if (!d.readVarU32(&numRets))
return d.fail("bad number of function returns");
if (numRets > 1)
return d.fail("too many returns in signature");
ExprType result = ExprType::Void;
if (numRets == 1) {
ValType type;
if (!DecodeValType(d, ModuleKind::Wasm, env->gcTypesEnabled, &type))
break;
case uint8_t(TypeCode::Struct):
if (!DecodeStructType(d, env, typeIndex))
return false;
result = ToExprType(type);
break;
default:
return d.fail("expected type form");
}
env->sigs[sigIndex] = Sig(std::move(args), result);
}
return d.finishSection(*range, "type");
@ -1154,14 +1204,17 @@ DecodeName(Decoder& d)
}
static bool
DecodeSignatureIndex(Decoder& d, const SigWithIdVector& sigs, uint32_t* sigIndex)
DecodeSignatureIndex(Decoder& d, const TypeDefVector& types, uint32_t* sigIndex)
{
if (!d.readVarU32(sigIndex))
return d.fail("expected signature index");
if (*sigIndex >= sigs.length())
if (*sigIndex >= types.length())
return d.fail("signature index out of range");
if (!types[*sigIndex].isFuncType())
return d.fail("signature index references non-signature");
return true;
}
@ -1335,9 +1388,9 @@ DecodeImport(Decoder& d, ModuleEnvironment* env)
switch (importKind) {
case DefinitionKind::Function: {
uint32_t sigIndex;
if (!DecodeSignatureIndex(d, env->sigs, &sigIndex))
if (!DecodeSignatureIndex(d, env->types, &sigIndex))
return false;
if (!env->funcSigs.append(&env->sigs[sigIndex]))
if (!env->funcSigs.append(&env->types[sigIndex].funcType()))
return false;
if (env->funcSigs.length() > MaxFuncs)
return d.fail("too many functions");
@ -1428,9 +1481,9 @@ DecodeFunctionSection(Decoder& d, ModuleEnvironment* env)
for (uint32_t i = 0; i < numDefs; i++) {
uint32_t sigIndex;
if (!DecodeSignatureIndex(d, env->sigs, &sigIndex))
if (!DecodeSignatureIndex(d, env->types, &sigIndex))
return false;
env->funcSigs.infallibleAppend(&env->sigs[sigIndex]);
env->funcSigs.infallibleAppend(&env->types[sigIndex].funcType());
}
return d.finishSection(*range, "function");

Просмотреть файл

@ -68,7 +68,7 @@ struct ModuleEnvironment
MemoryUsage memoryUsage;
uint32_t minMemoryLength;
Maybe<uint32_t> maxMemoryLength;
SigWithIdVector sigs;
TypeDefVector types;
SigWithIdPtrVector funcSigs;
Uint32Vector funcImportGlobalDataOffsets;
GlobalDescVector globals;
@ -105,8 +105,8 @@ struct ModuleEnvironment
size_t numTables() const {
return tables.length();
}
size_t numSigs() const {
return sigs.length();
size_t numTypes() const {
return types.length();
}
size_t numFuncs() const {
return funcSigs.length();
@ -133,7 +133,7 @@ struct ModuleEnvironment
return funcIndex < funcImportGlobalDataOffsets.length();
}
uint32_t funcIndexToSigIndex(uint32_t funcIndex) const {
return funcSigs[funcIndex] - sigs.begin();
return TypeDef::fromSigWithIdPtr(funcSigs[funcIndex]) - types.begin();
}
};

Просмотреть файл

@ -49,6 +49,8 @@ public:
, mGlobalObject(aGlobal)
, mPromise(aPromise)
, mCharset(aOptions.mCharset)
, mToken(nullptr)
, mScriptLength(0)
{
mOptions.setNoScriptRval(!aOptions.mHasReturnValue)
.setCanLazilyParse(aOptions.mLazilyParse)

Просмотреть файл

@ -41,7 +41,8 @@ public:
void SetGlobalObject(JSObject* global);
explicit BackstagePass(nsIPrincipal* prin) :
mPrincipal(prin)
mPrincipal(prin),
mWrapper(nullptr)
{
}

Просмотреть файл

@ -34,7 +34,12 @@ XPCCallContext::XPCCallContext(JSContext* cx,
mJSContext(cx),
mWrapper(nullptr),
mTearOff(nullptr),
mName(cx)
mMember(nullptr),
mName(cx),
mStaticMemberIsLocal(false),
mArgc(0),
mArgv(nullptr),
mRetVal(nullptr)
{
MOZ_ASSERT(cx);
MOZ_ASSERT(cx == nsContentUtils::GetCurrentJSContext());

Просмотреть файл

@ -340,10 +340,7 @@ DefinePropertyIfFound(XPCCallContext& ccx,
AutoResolveName arn(ccx, id);
if (resolved)
*resolved = true;
return JS_DefinePropertyById(ccx, obj, id,
JS_DATA_TO_FUNC_PTR(JSNative, funobj.get()),
nullptr,
propFlags);
return JS_DefinePropertyById(ccx, obj, id, funobj, nullptr, propFlags);
}
if (resolved)
@ -406,21 +403,18 @@ DefinePropertyIfFound(XPCCallContext& ccx,
propFlags |= JSPROP_GETTER;
propFlags &= ~JSPROP_READONLY;
JSObject* funobj = funval.toObjectOrNull();
JSNative getter = JS_DATA_TO_FUNC_PTR(JSNative, funobj);
JSNative setter;
RootedObject funobjGetter(ccx, funval.toObjectOrNull());
RootedObject funobjSetter(ccx);
if (member->IsWritableAttribute()) {
propFlags |= JSPROP_SETTER;
setter = JS_DATA_TO_FUNC_PTR(JSNative, funobj);
} else {
setter = nullptr;
funobjSetter = funobjGetter;
}
AutoResolveName arn(ccx, id);
if (resolved)
*resolved = true;
return JS_DefinePropertyById(ccx, obj, id, getter, setter, propFlags);
return JS_DefinePropertyById(ccx, obj, id, funobjGetter, funobjSetter, propFlags);
}
/***************************************************************************/

Просмотреть файл

@ -293,12 +293,10 @@ public:
class XPCRootSetElem
{
public:
XPCRootSetElem()
XPCRootSetElem() :
mNext(nullptr),
mSelfp(nullptr)
{
#ifdef DEBUG
mNext = nullptr;
mSelfp = nullptr;
#endif
}
~XPCRootSetElem()

Просмотреть файл

@ -421,37 +421,29 @@ TryResolvePropertyFromSpecs(JSContext* cx, HandleId id, HandleObject holder,
desc.value().setUndefined();
unsigned flags = psMatch->flags;
if (psMatch->isAccessor()) {
RootedFunction getterObj(cx);
RootedFunction setterObj(cx);
if (psMatch->isSelfHosted()) {
getterObj = JS::GetSelfHostedFunction(cx, psMatch->accessors.getter.selfHosted.funname, id, 0);
if (!getterObj)
JSFunction* getterFun = JS::GetSelfHostedFunction(cx, psMatch->accessors.getter.selfHosted.funname, id, 0);
if (!getterFun)
return false;
desc.setGetterObject(JS_GetFunctionObject(getterObj));
RootedObject getterObj(cx, JS_GetFunctionObject(getterFun));
RootedObject setterObj(cx);
if (psMatch->accessors.setter.selfHosted.funname) {
MOZ_ASSERT(flags & JSPROP_SETTER);
setterObj = JS::GetSelfHostedFunction(cx, psMatch->accessors.setter.selfHosted.funname, id, 0);
if (!setterObj)
JSFunction* setterFun = JS::GetSelfHostedFunction(cx, psMatch->accessors.setter.selfHosted.funname, id, 0);
if (!setterFun)
return false;
desc.setSetterObject(JS_GetFunctionObject(setterObj));
setterObj = JS_GetFunctionObject(setterFun);
}
if (!JS_DefinePropertyById(cx, holder, id, getterObj, setterObj, flags))
return false;
} else {
desc.setGetter(JS_CAST_NATIVE_TO(psMatch->accessors.getter.native.op,
JSGetterOp));
desc.setSetter(JS_CAST_NATIVE_TO(psMatch->accessors.setter.native.op,
JSSetterOp));
}
desc.setAttributes(flags);
if (!JS_DefinePropertyById(cx, holder, id,
JS_PROPERTYOP_GETTER(desc.getter()),
JS_PROPERTYOP_SETTER(desc.setter()),
// This particular descriptor, unlike most,
// actually stores JSNatives directly,
// since we just set it up. Do NOT pass
// JSPROP_PROPOP_ACCESSORS here!
desc.attributes()))
{
return false;
if (!JS_DefinePropertyById(cx, holder, id,
psMatch->accessors.getter.native.op,
psMatch->accessors.setter.native.op,
flags))
{
return false;
}
}
} else {
RootedValue v(cx);

Просмотреть файл

@ -396,6 +396,4 @@ nsLayoutStatics::Shutdown()
PromiseDebugging::Shutdown();
BlobURLProtocolHandler::RemoveDataEntries();
ClearSiteData::Shutdown();
}

Просмотреть файл

@ -339,7 +339,8 @@ nsComputedDOMStyle::nsComputedDOMStyle(dom::Element* aElement,
nsComputedDOMStyle::~nsComputedDOMStyle()
{
ClearComputedStyle();
MOZ_ASSERT(!mResolvedComputedStyle,
"Should have called ClearComputedStyle() during last release.");
}
NS_IMPL_CYCLE_COLLECTION_CLASS(nsComputedDOMStyle)
@ -375,8 +376,9 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsComputedDOMStyle)
NS_INTERFACE_MAP_END_INHERITING(nsDOMCSSDeclaration)
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsComputedDOMStyle)
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsComputedDOMStyle)
NS_IMPL_MAIN_THREAD_ONLY_CYCLE_COLLECTING_ADDREF(nsComputedDOMStyle)
NS_IMPL_MAIN_THREAD_ONLY_CYCLE_COLLECTING_RELEASE_WITH_LAST_RELEASE(
nsComputedDOMStyle, ClearComputedStyle())
nsresult
nsComputedDOMStyle::GetPropertyValue(const nsCSSPropertyID aPropID,

Просмотреть файл

@ -9343,7 +9343,11 @@ class CopyNonDefaultHeaderVisitor final : public nsIHttpHeaderVisitor
NS_IMETHOD
VisitHeader(const nsACString& aHeader, const nsACString& aValue) override
{
return mTarget->SetRequestHeader(aHeader, aValue, false /* merge */);
if (aValue.IsEmpty()) {
return mTarget->SetEmptyRequestHeader(aHeader);
} else {
return mTarget->SetRequestHeader(aHeader, aValue, false /* merge */);
}
}
public:

Просмотреть файл

@ -1 +1 @@
30a4b03cd9d1
NSS_3_38_RTM

Просмотреть файл

@ -10,4 +10,3 @@
*/
#error "Do not include this header file."

Просмотреть файл

@ -22,12 +22,12 @@
* The format of the version string should be
* "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]"
*/
#define NSS_VERSION "3.38" _NSS_CUSTOMIZED " Beta"
#define NSS_VERSION "3.38" _NSS_CUSTOMIZED
#define NSS_VMAJOR 3
#define NSS_VMINOR 38
#define NSS_VPATCH 0
#define NSS_VBUILD 0
#define NSS_BETA PR_TRUE
#define NSS_BETA PR_FALSE
#ifndef RC_INVOKED

Просмотреть файл

@ -17,11 +17,11 @@
* The format of the version string should be
* "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]"
*/
#define SOFTOKEN_VERSION "3.38" SOFTOKEN_ECC_STRING " Beta"
#define SOFTOKEN_VERSION "3.38" SOFTOKEN_ECC_STRING
#define SOFTOKEN_VMAJOR 3
#define SOFTOKEN_VMINOR 38
#define SOFTOKEN_VPATCH 0
#define SOFTOKEN_VBUILD 0
#define SOFTOKEN_BETA PR_TRUE
#define SOFTOKEN_BETA PR_FALSE
#endif /* _SOFTKVER_H_ */

Просмотреть файл

@ -19,12 +19,12 @@
* The format of the version string should be
* "<major version>.<minor version>[.<patch level>[.<build number>]][ <Beta>]"
*/
#define NSSUTIL_VERSION "3.38 Beta"
#define NSSUTIL_VERSION "3.38"
#define NSSUTIL_VMAJOR 3
#define NSSUTIL_VMINOR 38
#define NSSUTIL_VPATCH 0
#define NSSUTIL_VBUILD 0
#define NSSUTIL_BETA PR_TRUE
#define NSSUTIL_BETA PR_FALSE
SEC_BEGIN_PROTOS

Просмотреть файл

@ -9,8 +9,8 @@
use Atom;
use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser};
use cssparser::{CowRcStr, Parser, SourceLocation, Token};
use error_reporting::{ContextualParseError, ParseErrorReporter};
use parser::{Parse, ParserContext, ParserErrorContext};
use error_reporting::ContextualParseError;
use parser::{Parse, ParserContext};
use selectors::parser::SelectorParseErrorKind;
use shared_lock::{SharedRwLockReadGuard, ToCssWithGuard};
use std::fmt::{self, Write};
@ -73,16 +73,12 @@ pub fn parse_counter_style_name_definition<'i, 't>(
}
/// Parse the body (inside `{}`) of an @counter-style rule
pub fn parse_counter_style_body<'i, 't, R>(
pub fn parse_counter_style_body<'i, 't>(
name: CustomIdent,
context: &ParserContext,
error_context: &ParserErrorContext<R>,
input: &mut Parser<'i, 't>,
location: SourceLocation,
) -> Result<CounterStyleRuleData, ParseError<'i>>
where
R: ParseErrorReporter,
{
) -> Result<CounterStyleRuleData, ParseError<'i>> {
let start = input.current_source_location();
let mut rule = CounterStyleRuleData::empty(name, location);
{
@ -98,7 +94,7 @@ where
slice,
error,
);
context.log_css_error(error_context, location, error)
context.log_css_error(location, error)
}
}
}
@ -134,7 +130,7 @@ where
_ => None,
};
if let Some(error) = error {
context.log_css_error(error_context, start, error);
context.log_css_error(start, error);
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
} else {
Ok(rule)

Просмотреть файл

@ -249,17 +249,3 @@ impl ParseErrorReporter for RustLogReporter {
}
}
}
/// Error reporter which silently forgets errors
pub struct NullReporter;
impl ParseErrorReporter for NullReporter {
fn report_error(
&self,
_url: &UrlExtraData,
_location: SourceLocation,
_error: ContextualParseError,
) {
// do nothing
}
}

Просмотреть файл

@ -10,8 +10,8 @@ use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser, Parser};
use cssparser::{CowRcStr, SourceLocation};
#[cfg(feature = "gecko")]
use cssparser::UnicodeRange;
use error_reporting::{ContextualParseError, ParseErrorReporter};
use parser::{Parse, ParserContext, ParserErrorContext};
use error_reporting::ContextualParseError;
use parser::{Parse, ParserContext};
#[cfg(feature = "gecko")]
use properties::longhands::font_language_override;
use selectors::parser::SelectorParseErrorKind;
@ -186,15 +186,11 @@ impl ToCss for FontStyle {
/// Parse the block inside a `@font-face` rule.
///
/// Note that the prelude parsing code lives in the `stylesheets` module.
pub fn parse_font_face_block<R>(
pub fn parse_font_face_block(
context: &ParserContext,
error_context: &ParserErrorContext<R>,
input: &mut Parser,
location: SourceLocation,
) -> FontFaceRuleData
where
R: ParseErrorReporter,
{
) -> FontFaceRuleData {
let mut rule = FontFaceRuleData::empty(location);
{
let parser = FontFaceRuleParser {
@ -206,7 +202,7 @@ where
if let Err((error, slice)) = declaration {
let location = error.location;
let error = ContextualParseError::UnsupportedFontFaceDescriptor(slice, error);
context.log_css_error(error_context, location, error)
context.log_css_error(location, error)
}
}
}

Просмотреть файл

@ -9,8 +9,8 @@
use context::QuirksMode;
use cssparser::{Delimiter, Parser};
use cssparser::{ParserInput, Token};
use error_reporting::{ContextualParseError, ParseErrorReporter};
use parser::{ParserContext, ParserErrorContext};
use error_reporting::ContextualParseError;
use parser::ParserContext;
use super::{Device, MediaQuery, Qualifier};
/// A type that encapsulates a media query list.
@ -30,14 +30,10 @@ impl MediaList {
/// "not all", see:
///
/// <https://drafts.csswg.org/mediaqueries/#error-handling>
pub fn parse<R>(
pub fn parse(
context: &ParserContext,
input: &mut Parser,
error_reporter: &R,
) -> MediaList
where
R: ParseErrorReporter,
{
) -> Self {
if input.is_exhausted() {
return Self::empty();
}
@ -54,8 +50,7 @@ impl MediaList {
let location = err.location;
let error =
ContextualParseError::InvalidMediaRule(input.slice_from(start_position), err);
let error_context = ParserErrorContext { error_reporter };
context.log_css_error(&error_context, location, error);
context.log_css_error(location, error);
},
}

Просмотреть файл

@ -36,12 +36,6 @@ pub fn assert_parsing_mode_match() {
}
}
/// The context required to report a parse error.
pub struct ParserErrorContext<'a, R: 'a> {
/// An error reporter to report syntax errors.
pub error_reporter: &'a R,
}
/// The data that the parser needs from outside in order to parse a stylesheet.
pub struct ParserContext<'a> {
/// The `Origin` of the stylesheet, whether it's a user, author or
@ -55,6 +49,8 @@ pub struct ParserContext<'a> {
pub parsing_mode: ParsingMode,
/// The quirks mode of this stylesheet.
pub quirks_mode: QuirksMode,
/// The active error reporter, or none if error reporting is disabled.
error_reporter: Option<&'a ParseErrorReporter>,
/// The currently active namespaces.
pub namespaces: Option<&'a Namespaces>,
}
@ -68,6 +64,7 @@ impl<'a> ParserContext<'a> {
rule_type: Option<CssRuleType>,
parsing_mode: ParsingMode,
quirks_mode: QuirksMode,
error_reporter: Option<&'a ParseErrorReporter>,
) -> Self {
ParserContext {
stylesheet_origin,
@ -75,6 +72,7 @@ impl<'a> ParserContext<'a> {
rule_type,
parsing_mode,
quirks_mode,
error_reporter,
namespaces: None,
}
}
@ -86,6 +84,7 @@ impl<'a> ParserContext<'a> {
rule_type: Option<CssRuleType>,
parsing_mode: ParsingMode,
quirks_mode: QuirksMode,
error_reporter: Option<&'a ParseErrorReporter>,
) -> Self {
Self::new(
Origin::Author,
@ -93,6 +92,7 @@ impl<'a> ParserContext<'a> {
rule_type,
parsing_mode,
quirks_mode,
error_reporter,
)
}
@ -110,6 +110,7 @@ impl<'a> ParserContext<'a> {
parsing_mode: context.parsing_mode,
quirks_mode: context.quirks_mode,
namespaces: Some(namespaces),
error_reporter: context.error_reporter,
}
}
@ -127,21 +128,17 @@ impl<'a> ParserContext<'a> {
}
/// Record a CSS parse error with this contexts error reporting.
pub fn log_css_error<R>(
pub fn log_css_error(
&self,
context: &ParserErrorContext<R>,
location: SourceLocation,
error: ContextualParseError,
) where
R: ParseErrorReporter,
{
let location = SourceLocation {
line: location.line,
column: location.column,
) {
let error_reporter = match self.error_reporter {
Some(r) => r,
None => return,
};
context
.error_reporter
.report_error(self.url_data, location, error)
error_reporter.report_error(self.url_data, location, error)
}
/// Returns whether chrome-only rules should be parsed.

Просмотреть файл

@ -11,7 +11,7 @@ use cssparser::{DeclarationListParser, parse_important, ParserInput, CowRcStr};
use cssparser::{Parser, AtRuleParser, DeclarationParser, Delimiter, ParseErrorKind};
use custom_properties::CustomPropertiesBuilder;
use error_reporting::{ParseErrorReporter, ContextualParseError};
use parser::{ParserContext, ParserErrorContext};
use parser::ParserContext;
use properties::animated_properties::AnimationValue;
use shared_lock::Locked;
use smallbitvec::{self, SmallBitVec};
@ -1077,50 +1077,49 @@ where
/// A helper to parse the style attribute of an element, in order for this to be
/// shared between Servo and Gecko.
pub fn parse_style_attribute<R>(
///
/// Inline because we call this cross-crate.
#[inline]
pub fn parse_style_attribute(
input: &str,
url_data: &UrlExtraData,
error_reporter: &R,
error_reporter: Option<&ParseErrorReporter>,
quirks_mode: QuirksMode,
) -> PropertyDeclarationBlock
where
R: ParseErrorReporter
{
) -> PropertyDeclarationBlock {
let context = ParserContext::new(
Origin::Author,
url_data,
Some(CssRuleType::Style),
ParsingMode::DEFAULT,
quirks_mode,
error_reporter,
);
let error_context = ParserErrorContext { error_reporter: error_reporter };
let mut input = ParserInput::new(input);
parse_property_declaration_list(&context, &error_context, &mut Parser::new(&mut input))
parse_property_declaration_list(&context, &mut Parser::new(&mut input))
}
/// Parse a given property declaration. Can result in multiple
/// `PropertyDeclaration`s when expanding a shorthand, for example.
///
/// This does not attempt to parse !important at all.
pub fn parse_one_declaration_into<R>(
#[inline]
pub fn parse_one_declaration_into(
declarations: &mut SourcePropertyDeclaration,
id: PropertyId,
input: &str,
url_data: &UrlExtraData,
error_reporter: &R,
error_reporter: Option<&ParseErrorReporter>,
parsing_mode: ParsingMode,
quirks_mode: QuirksMode
) -> Result<(), ()>
where
R: ParseErrorReporter
{
) -> Result<(), ()> {
let context = ParserContext::new(
Origin::Author,
url_data,
Some(CssRuleType::Style),
parsing_mode,
quirks_mode,
error_reporter,
);
let mut input = ParserInput::new(input);
@ -1131,9 +1130,10 @@ where
}).map_err(|err| {
let location = err.location;
let error = ContextualParseError::UnsupportedPropertyDeclaration(
parser.slice_from(start_position), err);
let error_context = ParserErrorContext { error_reporter: error_reporter };
context.log_css_error(&error_context, location, error);
parser.slice_from(start_position),
err,
);
context.log_css_error(location, error);
})
}
@ -1193,14 +1193,10 @@ impl<'a, 'b, 'i> DeclarationParser<'i> for PropertyDeclarationParser<'a, 'b> {
/// Parse a list of property declarations and return a property declaration
/// block.
pub fn parse_property_declaration_list<R>(
pub fn parse_property_declaration_list(
context: &ParserContext,
error_context: &ParserErrorContext<R>,
input: &mut Parser,
) -> PropertyDeclarationBlock
where
R: ParseErrorReporter
{
) -> PropertyDeclarationBlock {
let mut declarations = SourcePropertyDeclaration::new();
let mut block = PropertyDeclarationBlock::new();
let parser = PropertyDeclarationParser {
@ -1228,7 +1224,7 @@ where
let location = error.location;
let error = ContextualParseError::UnsupportedPropertyDeclaration(slice, error);
context.log_css_error(error_context, location, error);
context.log_css_error(location, error);
}
}
}

Просмотреть файл

@ -1442,6 +1442,7 @@ impl UnparsedValue {
None,
ParsingMode::DEFAULT,
quirks_mode,
None,
);
let mut input = ParserInput::new(&css);

Просмотреть файл

@ -10,12 +10,12 @@ use Atom;
use cssparser::{AtRuleParser, AtRuleType, BasicParseErrorKind, CowRcStr};
use cssparser::{DeclarationListParser, DeclarationParser, Parser};
use cssparser::{QualifiedRuleParser, RuleListParser, SourceLocation, Token};
use error_reporting::{ContextualParseError, ParseErrorReporter};
use error_reporting::ContextualParseError;
#[cfg(feature = "gecko")]
use gecko_bindings::bindings::Gecko_AppendFeatureValueHashEntry;
#[cfg(feature = "gecko")]
use gecko_bindings::structs::{self, gfxFontFeatureValueSet, nsTArray};
use parser::{Parse, ParserContext, ParserErrorContext};
use parser::{Parse, ParserContext};
use shared_lock::{SharedRwLockReadGuard, ToCssWithGuard};
use std::fmt::{self, Write};
use str::CssStringWriter;
@ -267,27 +267,24 @@ macro_rules! font_feature_values_blocks {
}
/// Parses a `FontFeatureValuesRule`.
pub fn parse<R>(context: &ParserContext,
error_context: &ParserErrorContext<R>,
input: &mut Parser,
family_names: Vec<FamilyName>,
location: SourceLocation)
-> FontFeatureValuesRule
where R: ParseErrorReporter
{
pub fn parse(
context: &ParserContext,
input: &mut Parser,
family_names: Vec<FamilyName>,
location: SourceLocation,
) -> Self {
let mut rule = FontFeatureValuesRule::new(family_names, location);
{
let mut iter = RuleListParser::new_for_nested_rule(input, FontFeatureValuesRuleParser {
context: context,
error_context: error_context,
rule: &mut rule,
});
while let Some(result) = iter.next() {
if let Err((error, slice)) = result {
let location = error.location;
let error = ContextualParseError::UnsupportedRule(slice, error);
context.log_css_error(error_context, location, error);
context.log_css_error(location, error);
}
}
}
@ -398,20 +395,19 @@ macro_rules! font_feature_values_blocks {
/// }
/// <feature-type> = @stylistic | @historical-forms | @styleset |
/// @character-variant | @swash | @ornaments | @annotation
struct FontFeatureValuesRuleParser<'a, R: 'a> {
struct FontFeatureValuesRuleParser<'a> {
context: &'a ParserContext<'a>,
error_context: &'a ParserErrorContext<'a, R>,
rule: &'a mut FontFeatureValuesRule,
}
/// Default methods reject all qualified rules.
impl<'a, 'i, R: ParseErrorReporter> QualifiedRuleParser<'i> for FontFeatureValuesRuleParser<'a, R> {
impl<'a, 'i> QualifiedRuleParser<'i> for FontFeatureValuesRuleParser<'a> {
type Prelude = ();
type QualifiedRule = ();
type Error = StyleParseErrorKind<'i>;
}
impl<'a, 'i, R: ParseErrorReporter> AtRuleParser<'i> for FontFeatureValuesRuleParser<'a, R> {
impl<'a, 'i> AtRuleParser<'i> for FontFeatureValuesRuleParser<'a> {
type PreludeNoBlock = ();
type PreludeBlock = BlockType;
type AtRule = ();
@ -450,7 +446,7 @@ macro_rules! font_feature_values_blocks {
let error = ContextualParseError::UnsupportedKeyframePropertyDeclaration(
slice, error
);
self.context.log_css_error(self.error_context, location, error);
self.context.log_css_error(location, error);
}
}
},

Просмотреть файл

@ -6,8 +6,8 @@
use cssparser::{AtRuleParser, CowRcStr, Parser, ParserInput, QualifiedRuleParser, RuleListParser};
use cssparser::{parse_one_rule, DeclarationListParser, DeclarationParser, SourceLocation, Token};
use error_reporting::{ContextualParseError, NullReporter, ParseErrorReporter};
use parser::{ParserContext, ParserErrorContext};
use error_reporting::ContextualParseError;
use parser::ParserContext;
use properties::{DeclarationSource, Importance, PropertyDeclaration};
use properties::{LonghandId, PropertyDeclarationBlock, PropertyId};
use properties::{PropertyDeclarationId, SourcePropertyDeclaration};
@ -211,7 +211,6 @@ impl Keyframe {
lock: &SharedRwLock,
) -> Result<Arc<Locked<Self>>, ParseError<'i>> {
let url_data = parent_stylesheet_contents.url_data.read();
let error_reporter = NullReporter;
let namespaces = parent_stylesheet_contents.namespaces.read();
let mut context = ParserContext::new(
parent_stylesheet_contents.origin,
@ -219,10 +218,8 @@ impl Keyframe {
Some(CssRuleType::Keyframe),
ParsingMode::DEFAULT,
parent_stylesheet_contents.quirks_mode,
None,
);
let error_context = ParserErrorContext {
error_reporter: &error_reporter,
};
context.namespaces = Some(&*namespaces);
let mut input = ParserInput::new(css);
let mut input = Parser::new(&mut input);
@ -230,7 +227,6 @@ impl Keyframe {
let mut declarations = SourcePropertyDeclaration::new();
let mut rule_parser = KeyframeListParser {
context: &context,
error_context: &error_context,
shared_lock: &lock,
declarations: &mut declarations,
};
@ -477,23 +473,18 @@ impl KeyframesAnimation {
/// 40%, 60%, 100% {
/// width: 100%;
/// }
struct KeyframeListParser<'a, R: 'a> {
struct KeyframeListParser<'a> {
context: &'a ParserContext<'a>,
error_context: &'a ParserErrorContext<'a, R>,
shared_lock: &'a SharedRwLock,
declarations: &'a mut SourcePropertyDeclaration,
}
/// Parses a keyframe list from CSS input.
pub fn parse_keyframe_list<R>(
pub fn parse_keyframe_list(
context: &ParserContext,
error_context: &ParserErrorContext<R>,
input: &mut Parser,
shared_lock: &SharedRwLock,
) -> Vec<Arc<Locked<Keyframe>>>
where
R: ParseErrorReporter,
{
) -> Vec<Arc<Locked<Keyframe>>> {
debug_assert!(
context.namespaces.is_some(),
"Parsing a keyframe list from a context without namespaces?"
@ -504,7 +495,6 @@ where
input,
KeyframeListParser {
context: context,
error_context: error_context,
shared_lock: shared_lock,
declarations: &mut declarations,
},
@ -512,7 +502,7 @@ where
.collect()
}
impl<'a, 'i, R> AtRuleParser<'i> for KeyframeListParser<'a, R> {
impl<'a, 'i> AtRuleParser<'i> for KeyframeListParser<'a> {
type PreludeNoBlock = ();
type PreludeBlock = ();
type AtRule = Arc<Locked<Keyframe>>;
@ -525,7 +515,7 @@ struct KeyframeSelectorParserPrelude {
source_location: SourceLocation,
}
impl<'a, 'i, R: ParseErrorReporter> QualifiedRuleParser<'i> for KeyframeListParser<'a, R> {
impl<'a, 'i> QualifiedRuleParser<'i> for KeyframeListParser<'a> {
type Prelude = KeyframeSelectorParserPrelude;
type QualifiedRule = Arc<Locked<Keyframe>>;
type Error = StyleParseErrorKind<'i>;
@ -547,8 +537,7 @@ impl<'a, 'i, R: ParseErrorReporter> QualifiedRuleParser<'i> for KeyframeListPars
input.slice_from(start_position),
e.clone(),
);
self.context
.log_css_error(self.error_context, location, error);
self.context.log_css_error(location, error);
Err(e)
},
}
@ -585,7 +574,7 @@ impl<'a, 'i, R: ParseErrorReporter> QualifiedRuleParser<'i> for KeyframeListPars
let location = error.location;
let error =
ContextualParseError::UnsupportedKeyframePropertyDeclaration(slice, error);
context.log_css_error(self.error_context, location, error);
context.log_css_error(location, error);
},
}
// `parse_important` is not called here, `!important` is not allowed in keyframe blocks.

Просмотреть файл

@ -24,10 +24,9 @@ pub mod supports_rule;
pub mod viewport_rule;
use cssparser::{parse_one_rule, Parser, ParserInput};
use error_reporting::NullReporter;
#[cfg(feature = "gecko")]
use malloc_size_of::{MallocSizeOfOps, MallocUnconditionalShallowSizeOf};
use parser::{ParserContext, ParserErrorContext};
use parser::ParserContext;
use servo_arc::Arc;
use shared_lock::{DeepCloneParams, DeepCloneWithLock, Locked};
use shared_lock::{SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard};
@ -228,13 +227,13 @@ impl CssRule {
loader: Option<&StylesheetLoader>,
) -> Result<Self, RulesMutateError> {
let url_data = parent_stylesheet_contents.url_data.read();
let error_reporter = NullReporter;
let context = ParserContext::new(
parent_stylesheet_contents.origin,
&url_data,
None,
ParsingMode::DEFAULT,
parent_stylesheet_contents.quirks_mode,
None,
);
let mut input = ParserInput::new(css);
@ -246,9 +245,6 @@ impl CssRule {
let mut rule_parser = TopLevelRuleParser {
stylesheet_origin: parent_stylesheet_contents.origin,
context,
error_context: ParserErrorContext {
error_reporter: &error_reporter,
},
shared_lock: &shared_lock,
loader,
state,

Просмотреть файл

@ -8,10 +8,10 @@ use {Namespace, Prefix};
use counter_style::{parse_counter_style_body, parse_counter_style_name_definition};
use cssparser::{AtRuleParser, AtRuleType, Parser, QualifiedRuleParser, RuleListParser};
use cssparser::{BasicParseError, BasicParseErrorKind, CowRcStr, SourceLocation};
use error_reporting::{ContextualParseError, ParseErrorReporter};
use error_reporting::ContextualParseError;
use font_face::parse_font_face_block;
use media_queries::MediaList;
use parser::{Parse, ParserContext, ParserErrorContext};
use parser::{Parse, ParserContext};
use properties::parse_property_declaration_list;
use selector_parser::{SelectorImpl, SelectorParser};
use selectors::SelectorList;
@ -40,7 +40,7 @@ pub struct InsertRuleContext<'a> {
}
/// The parser for the top-level rules in a stylesheet.
pub struct TopLevelRuleParser<'a, R: 'a> {
pub struct TopLevelRuleParser<'a> {
/// The origin of the stylesheet we're parsing.
pub stylesheet_origin: Origin,
/// A reference to the lock we need to use to create rules.
@ -52,8 +52,6 @@ pub struct TopLevelRuleParser<'a, R: 'a> {
/// This won't contain any namespaces, and only nested parsers created with
/// `ParserContext::new_with_rule_type` will.
pub context: ParserContext<'a>,
/// The context required for reporting parse errors.
pub error_context: ParserErrorContext<'a, R>,
/// The current state of the parser.
pub state: State,
/// Whether we have tried to parse was invalid due to being in the wrong
@ -68,13 +66,12 @@ pub struct TopLevelRuleParser<'a, R: 'a> {
pub insert_rule_context: Option<InsertRuleContext<'a>>,
}
impl<'b, R> TopLevelRuleParser<'b, R> {
fn nested<'a: 'b>(&'a self) -> NestedRuleParser<'a, 'b, R> {
impl<'b> TopLevelRuleParser<'b> {
fn nested<'a: 'b>(&'a self) -> NestedRuleParser<'a, 'b> {
NestedRuleParser {
stylesheet_origin: self.stylesheet_origin,
shared_lock: self.shared_lock,
context: &self.context,
error_context: &self.error_context,
namespaces: &self.namespaces,
}
}
@ -176,7 +173,7 @@ pub enum AtRuleNonBlockPrelude {
Namespace(Option<Prefix>, Namespace, SourceLocation),
}
impl<'a, 'i, R: ParseErrorReporter> AtRuleParser<'i> for TopLevelRuleParser<'a, R> {
impl<'a, 'i> AtRuleParser<'i> for TopLevelRuleParser<'a> {
type PreludeNoBlock = AtRuleNonBlockPrelude;
type PreludeBlock = AtRuleBlockPrelude;
type AtRule = CssRule;
@ -197,11 +194,7 @@ impl<'a, 'i, R: ParseErrorReporter> AtRuleParser<'i> for TopLevelRuleParser<'a,
let url_string = input.expect_url_or_string()?.as_ref().to_owned();
let url = CssUrl::parse_from_string(url_string, &self.context);
let media = MediaList::parse(
&self.context,
input,
self.error_context.error_reporter,
);
let media = MediaList::parse(&self.context, input);
let media = Arc::new(self.shared_lock.wrap(media));
let prelude = AtRuleNonBlockPrelude::Import(url, media, location);
@ -296,7 +289,7 @@ pub struct QualifiedRuleParserPrelude {
source_location: SourceLocation,
}
impl<'a, 'i, R: ParseErrorReporter> QualifiedRuleParser<'i> for TopLevelRuleParser<'a, R> {
impl<'a, 'i> QualifiedRuleParser<'i> for TopLevelRuleParser<'a> {
type Prelude = QualifiedRuleParserPrelude;
type QualifiedRule = CssRule;
type Error = StyleParseErrorKind<'i>;
@ -327,27 +320,29 @@ impl<'a, 'i, R: ParseErrorReporter> QualifiedRuleParser<'i> for TopLevelRulePars
}
#[derive(Clone)] // shallow, relatively cheap .clone
struct NestedRuleParser<'a, 'b: 'a, R: 'b> {
struct NestedRuleParser<'a, 'b: 'a> {
stylesheet_origin: Origin,
shared_lock: &'a SharedRwLock,
context: &'a ParserContext<'b>,
error_context: &'a ParserErrorContext<'b, R>,
namespaces: &'a Namespaces,
}
impl<'a, 'b, R: ParseErrorReporter> NestedRuleParser<'a, 'b, R> {
impl<'a, 'b> NestedRuleParser<'a, 'b> {
fn parse_nested_rules(
&mut self,
input: &mut Parser,
rule_type: CssRuleType,
) -> Arc<Locked<CssRules>> {
let context = ParserContext::new_with_rule_type(self.context, rule_type, self.namespaces);
let context = ParserContext::new_with_rule_type(
self.context,
rule_type,
self.namespaces,
);
let nested_parser = NestedRuleParser {
stylesheet_origin: self.stylesheet_origin,
shared_lock: self.shared_lock,
context: &context,
error_context: &self.error_context,
namespaces: self.namespaces,
};
@ -359,8 +354,7 @@ impl<'a, 'b, R: ParseErrorReporter> NestedRuleParser<'a, 'b, R> {
Err((error, slice)) => {
let location = error.location;
let error = ContextualParseError::InvalidRule(slice, error);
self.context
.log_css_error(self.error_context, location, error);
self.context.log_css_error(location, error);
},
}
}
@ -368,7 +362,7 @@ impl<'a, 'b, R: ParseErrorReporter> NestedRuleParser<'a, 'b, R> {
}
}
impl<'a, 'b, 'i, R: ParseErrorReporter> AtRuleParser<'i> for NestedRuleParser<'a, 'b, R> {
impl<'a, 'b, 'i> AtRuleParser<'i> for NestedRuleParser<'a, 'b> {
type PreludeNoBlock = AtRuleNonBlockPrelude;
type PreludeBlock = AtRuleBlockPrelude;
type AtRule = CssRule;
@ -383,11 +377,7 @@ impl<'a, 'b, 'i, R: ParseErrorReporter> AtRuleParser<'i> for NestedRuleParser<'a
match_ignore_ascii_case! { &*name,
"media" => {
let media_queries = MediaList::parse(
self.context,
input,
self.error_context.error_reporter,
);
let media_queries = MediaList::parse(self.context, input);
let arc = Arc::new(self.shared_lock.wrap(media_queries));
Ok(AtRuleType::WithBlock(AtRuleBlockPrelude::Media(arc, location)))
},
@ -473,7 +463,7 @@ impl<'a, 'b, 'i, R: ParseErrorReporter> AtRuleParser<'i> for NestedRuleParser<'a
);
Ok(CssRule::FontFace(Arc::new(self.shared_lock.wrap(
parse_font_face_block(&context, self.error_context, input, location).into(),
parse_font_face_block(&context, input, location).into(),
))))
},
AtRuleBlockPrelude::FontFeatureValues(family_names, location) => {
@ -486,7 +476,6 @@ impl<'a, 'b, 'i, R: ParseErrorReporter> AtRuleParser<'i> for NestedRuleParser<'a
Ok(CssRule::FontFeatureValues(Arc::new(self.shared_lock.wrap(
FontFeatureValuesRule::parse(
&context,
self.error_context,
input,
family_names,
location,
@ -505,7 +494,6 @@ impl<'a, 'b, 'i, R: ParseErrorReporter> AtRuleParser<'i> for NestedRuleParser<'a
parse_counter_style_body(
name,
&context,
self.error_context,
input,
location,
)?.into(),
@ -544,7 +532,7 @@ impl<'a, 'b, 'i, R: ParseErrorReporter> AtRuleParser<'i> for NestedRuleParser<'a
);
Ok(CssRule::Viewport(Arc::new(self.shared_lock.wrap(
ViewportRule::parse(&context, self.error_context, input)?,
ViewportRule::parse(&context, input)?,
))))
},
AtRuleBlockPrelude::Keyframes(name, vendor_prefix, source_location) => {
@ -559,7 +547,6 @@ impl<'a, 'b, 'i, R: ParseErrorReporter> AtRuleParser<'i> for NestedRuleParser<'a
name,
keyframes: parse_keyframe_list(
&context,
self.error_context,
input,
self.shared_lock,
),
@ -576,7 +563,7 @@ impl<'a, 'b, 'i, R: ParseErrorReporter> AtRuleParser<'i> for NestedRuleParser<'a
);
let declarations =
parse_property_declaration_list(&context, self.error_context, input);
parse_property_declaration_list(&context, input);
Ok(CssRule::Page(Arc::new(self.shared_lock.wrap(PageRule {
block: Arc::new(self.shared_lock.wrap(declarations)),
source_location,
@ -598,7 +585,7 @@ impl<'a, 'b, 'i, R: ParseErrorReporter> AtRuleParser<'i> for NestedRuleParser<'a
}
}
impl<'a, 'b, 'i, R: ParseErrorReporter> QualifiedRuleParser<'i> for NestedRuleParser<'a, 'b, R> {
impl<'a, 'b, 'i> QualifiedRuleParser<'i> for NestedRuleParser<'a, 'b> {
type Prelude = QualifiedRuleParserPrelude;
type QualifiedRule = CssRule;
type Error = StyleParseErrorKind<'i>;
@ -627,7 +614,7 @@ impl<'a, 'b, 'i, R: ParseErrorReporter> QualifiedRuleParser<'i> for NestedRulePa
let context =
ParserContext::new_with_rule_type(self.context, CssRuleType::Style, self.namespaces);
let declarations = parse_property_declaration_list(&context, self.error_context, input);
let declarations = parse_property_declaration_list(&context, input);
Ok(CssRule::Style(Arc::new(self.shared_lock.wrap(StyleRule {
selectors: prelude.selectors,
block: Arc::new(self.shared_lock.wrap(declarations)),

Просмотреть файл

@ -13,7 +13,7 @@ use invalidation::media_queries::{MediaListKey, ToMediaListKey};
use malloc_size_of::{MallocSizeOfOps, MallocUnconditionalShallowSizeOf};
use media_queries::{Device, MediaList};
use parking_lot::RwLock;
use parser::{ParserContext, ParserErrorContext};
use parser::ParserContext;
use servo_arc::Arc;
use shared_lock::{DeepCloneParams, DeepCloneWithLock, Locked, SharedRwLock, SharedRwLockReadGuard};
use std::mem;
@ -69,13 +69,13 @@ pub struct StylesheetContents {
impl StylesheetContents {
/// Parse a given CSS string, with a given url-data, origin, and
/// quirks mode.
pub fn from_str<R: ParseErrorReporter>(
pub fn from_str(
css: &str,
url_data: UrlExtraData,
origin: Origin,
shared_lock: &SharedRwLock,
stylesheet_loader: Option<&StylesheetLoader>,
error_reporter: &R,
error_reporter: Option<&ParseErrorReporter>,
quirks_mode: QuirksMode,
line_number_offset: u32,
) -> Self {
@ -137,7 +137,7 @@ impl DeepCloneWithLock for StylesheetContents {
url_data: RwLock::new((*self.url_data.read()).clone()),
namespaces: RwLock::new((*self.namespaces.read()).clone()),
source_map_url: RwLock::new((*self.source_map_url.read()).clone()),
source_url: RwLock::new((*self.source_map_url.read()).clone()),
source_url: RwLock::new((*self.source_url.read()).clone()),
}
}
}
@ -306,18 +306,16 @@ impl StylesheetInDocument for DocumentStyleSheet {
impl Stylesheet {
/// Updates an empty stylesheet from a given string of text.
pub fn update_from_str<R>(
pub fn update_from_str(
existing: &Stylesheet,
css: &str,
url_data: UrlExtraData,
stylesheet_loader: Option<&StylesheetLoader>,
error_reporter: &R,
error_reporter: Option<&ParseErrorReporter>,
line_number_offset: u32,
) where
R: ParseErrorReporter,
{
) {
let namespaces = RwLock::new(Namespaces::default());
let (rules, source_map_url, source_url) = Stylesheet::parse_rules(
let (rules, source_map_url, source_url) = Self::parse_rules(
css,
&url_data,
existing.contents.origin,
@ -342,14 +340,14 @@ impl Stylesheet {
*existing.contents.source_url.write() = source_url;
}
fn parse_rules<R: ParseErrorReporter>(
fn parse_rules(
css: &str,
url_data: &UrlExtraData,
origin: Origin,
namespaces: &mut Namespaces,
shared_lock: &SharedRwLock,
stylesheet_loader: Option<&StylesheetLoader>,
error_reporter: &R,
error_reporter: Option<&ParseErrorReporter>,
quirks_mode: QuirksMode,
line_number_offset: u32,
) -> (Vec<CssRule>, Option<String>, Option<String>) {
@ -357,16 +355,20 @@ impl Stylesheet {
let mut input = ParserInput::new_with_line_number_offset(css, line_number_offset);
let mut input = Parser::new(&mut input);
let context = ParserContext::new(origin, url_data, None, ParsingMode::DEFAULT, quirks_mode);
let error_context = ParserErrorContext { error_reporter };
let context = ParserContext::new(
origin,
url_data,
None,
ParsingMode::DEFAULT,
quirks_mode,
error_reporter,
);
let rule_parser = TopLevelRuleParser {
stylesheet_origin: origin,
shared_lock,
loader: stylesheet_loader,
context,
error_context,
state: State::Start,
dom_error: None,
insert_rule_context: None,
@ -390,7 +392,6 @@ impl Stylesheet {
let location = error.location;
let error = ContextualParseError::InvalidRule(slice, error);
iter.parser.context.log_css_error(
&iter.parser.error_context,
location,
error,
);
@ -409,17 +410,17 @@ impl Stylesheet {
///
/// Effectively creates a new stylesheet and forwards the hard work to
/// `Stylesheet::update_from_str`.
pub fn from_str<R: ParseErrorReporter>(
pub fn from_str(
css: &str,
url_data: UrlExtraData,
origin: Origin,
media: Arc<Locked<MediaList>>,
shared_lock: SharedRwLock,
stylesheet_loader: Option<&StylesheetLoader>,
error_reporter: &R,
error_reporter: Option<&ParseErrorReporter>,
quirks_mode: QuirksMode,
line_number_offset: u32,
) -> Stylesheet {
) -> Self {
let contents = StylesheetContents::from_str(
css,
url_data,

Просмотреть файл

@ -11,11 +11,11 @@ use app_units::Au;
use context::QuirksMode;
use cssparser::{parse_important, AtRuleParser, DeclarationListParser, DeclarationParser, Parser};
use cssparser::CowRcStr;
use error_reporting::{ContextualParseError, ParseErrorReporter};
use error_reporting::ContextualParseError;
use euclid::TypedSize2D;
use font_metrics::get_metrics_provider_for_product;
use media_queries::Device;
use parser::{ParserContext, ParserErrorContext};
use parser::ParserContext;
use properties::StyleBuilder;
use rule_cache::RuleCacheConditions;
use selectors::parser::SelectorParseErrorKind;
@ -355,15 +355,13 @@ fn is_whitespace_separator_or_equals(c: &char) -> bool {
impl ViewportRule {
/// Parse a single @viewport rule.
pub fn parse<'i, 't, R>(
///
/// TODO(emilio): This could use the `Parse` trait now.
pub fn parse<'i, 't>(
context: &ParserContext,
error_context: &ParserErrorContext<R>,
input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>>
where
R: ParseErrorReporter,
{
let parser = ViewportRuleParser { context: context };
) -> Result<Self, ParseError<'i>> {
let parser = ViewportRuleParser { context };
let mut cascade = Cascade::new();
let mut parser = DeclarationListParser::new(input, parser);
@ -380,7 +378,7 @@ impl ViewportRule {
slice,
error,
);
context.log_css_error(error_context, location, error);
context.log_css_error(location, error);
},
}
}

Просмотреть файл

@ -9,7 +9,6 @@
use cssparser::{CowRcStr, serialize_identifier, ToCss};
use cssparser::{SourceLocation, ParseError, ParseErrorKind, Token, BasicParseErrorKind};
use selectors::parser::SelectorParseErrorKind;
use std::cell::Cell;
use std::ffi::CStr;
use std::ptr;
use style::error_reporting::{ParseErrorReporter, ContextualParseError};
@ -26,28 +25,31 @@ pub struct ErrorReporter {
sheet: *const DomStyleSheet,
loader: *const Loader,
uri: *mut nsIURI,
cached_error_reporting_enabled: Cell<Option<bool>>,
}
impl ErrorReporter {
/// Create a new instance of the Gecko error reporter.
/// Create a new instance of the Gecko error reporter, if error reporting is
/// enabled.
pub fn new(
sheet: *mut DomStyleSheet,
loader: *mut Loader,
extra_data: *mut RawUrlExtraData,
) -> Self {
) -> Option<Self> {
if !Self::reporting_enabled(sheet, loader) {
return None;
}
let uri = unsafe {
extra_data.as_ref()
.map(|d| d.mBaseURI.raw::<nsIURI>())
.unwrap_or(ptr::null_mut())
};
ErrorReporter {
Some(ErrorReporter {
sheet,
loader,
uri,
cached_error_reporting_enabled: Cell::new(None),
}
})
}
}
@ -393,21 +395,15 @@ impl<'a> ErrorHelpers<'a> for ContextualParseError<'a> {
}
impl ErrorReporter {
fn reporting_enabled(&self) -> bool {
if let Some(enabled) = self.cached_error_reporting_enabled.get() {
return enabled;
}
let enabled = unsafe {
bindings::Gecko_ErrorReportingEnabled(self.sheet, self.loader)
};
self.cached_error_reporting_enabled.set(Some(enabled));
enabled
fn reporting_enabled(
sheet: *const DomStyleSheet,
loader: *const Loader,
) -> bool {
unsafe { bindings::Gecko_ErrorReportingEnabled(sheet, loader) }
}
pub fn report(&self, location: SourceLocation, error: ContextualParseError) {
if !self.reporting_enabled() {
return;
}
debug_assert!(Self::reporting_enabled(self.sheet, self.loader));
let (pre, name, action) = error.to_gecko_message();
let suffix = match action {

Просмотреть файл

@ -26,7 +26,7 @@ use style::data::{ElementStyles, self};
use style::dom::{ShowSubtreeData, TDocument, TElement, TNode};
use style::driver;
use style::element_state::{DocumentState, ElementState};
use style::error_reporting::{ContextualParseError, NullReporter, ParseErrorReporter};
use style::error_reporting::{ContextualParseError, ParseErrorReporter};
use style::font_metrics::{FontMetricsProvider, get_metrics_provider_for_product};
use style::gecko::data::{GeckoStyleSheet, PerDocumentStyleData, PerDocumentStyleDataImpl};
use style::gecko::global_style_data::{GLOBAL_STYLE_DATA, GlobalStyleData, STYLE_THREAD_POOL};
@ -1155,7 +1155,7 @@ pub extern "C" fn Servo_StyleSheet_Empty(mode: SheetParsingMode) -> RawServoStyl
origin,
shared_lock,
/* loader = */ None,
&NullReporter,
None,
QuirksMode::NoQuirks,
0
)
@ -1196,10 +1196,15 @@ pub extern "C" fn Servo_StyleSheet_FromUTF8Bytes(
Arc::new(StylesheetContents::from_str(
input, url_data.clone(), mode_to_origin(mode),
&global_style_data.shared_lock, loader, &reporter,
quirks_mode.into(), line_number_offset)
).into_strong()
input,
url_data.clone(),
mode_to_origin(mode),
&global_style_data.shared_lock,
loader,
reporter.as_ref().map(|r| r as &ParseErrorReporter),
quirks_mode.into(),
line_number_offset,
)).into_strong()
}
#[no_mangle]
@ -2515,6 +2520,7 @@ pub unsafe extern "C" fn Servo_FontFaceRule_SetDescriptor(
Some(CssRuleType::FontFace),
ParsingMode::DEFAULT,
QuirksMode::NoQuirks,
None,
);
write_locked_arc(rule, |rule: &mut FontFaceRule| {
@ -2724,6 +2730,7 @@ macro_rules! counter_style_descriptors {
Some(CssRuleType::CounterStyle),
ParsingMode::DEFAULT,
QuirksMode::NoQuirks,
None,
);
write_locked_arc(rule, |rule: &mut CounterStyleRule| {
@ -3206,18 +3213,15 @@ pub unsafe extern "C" fn Servo_StyleSet_CompatModeChanged(raw_data: RawServoStyl
data.stylist.set_quirks_mode(QuirksMode::from(doc.mCompatMode));
}
fn parse_property_into<R>(
fn parse_property_into(
declarations: &mut SourcePropertyDeclaration,
property_id: PropertyId,
value: *const nsACString,
data: *mut URLExtraData,
parsing_mode: structs::ParsingMode,
quirks_mode: QuirksMode,
reporter: &R
) -> Result<(), ()>
where
R: ParseErrorReporter
{
reporter: Option<&ParseErrorReporter>,
) -> Result<(), ()> {
use style_traits::ParsingMode;
let value = unsafe { value.as_ref().unwrap().as_str_unchecked() };
let url_data = unsafe { RefPtr::from_ptr_ref(&data) };
@ -3246,8 +3250,17 @@ pub extern "C" fn Servo_ParseProperty(
RawServoDeclarationBlockStrong::null());
let mut declarations = SourcePropertyDeclaration::new();
let reporter = ErrorReporter::new(ptr::null_mut(), loader, data);
match parse_property_into(&mut declarations, id, value, data,
parsing_mode, quirks_mode.into(), &reporter) {
let result = parse_property_into(
&mut declarations,
id,
value,
data,
parsing_mode,
quirks_mode.into(),
reporter.as_ref().map(|r| r as &ParseErrorReporter),
);
match result {
Ok(()) => {
let global_style_data = &*GLOBAL_STYLE_DATA;
let mut block = PropertyDeclarationBlock::new();
@ -3278,6 +3291,7 @@ pub extern "C" fn Servo_ParseEasing(
Some(CssRuleType::Style),
ParsingMode::DEFAULT,
QuirksMode::NoQuirks,
None,
);
let easing = unsafe { (*easing).to_string() };
let mut input = ParserInput::new(&easing);
@ -3368,7 +3382,7 @@ pub extern "C" fn Servo_ParseStyleAttribute(
parse_style_attribute(
value,
url_data,
&reporter,
reporter.as_ref().map(|r| r as &ParseErrorReporter),
quirks_mode.into(),
)
)).into_strong()
@ -3553,7 +3567,7 @@ fn set_property(
data,
parsing_mode,
quirks_mode,
&reporter,
reporter.as_ref().map(|r| r as &ParseErrorReporter),
);
if result.is_err() {
@ -3757,14 +3771,12 @@ pub unsafe extern "C" fn Servo_MediaList_SetText(
Some(CssRuleType::Media),
ParsingMode::DEFAULT,
QuirksMode::NoQuirks,
// TODO(emilio): Looks like error reporting could be useful here?
None,
);
write_locked_arc(list, |list: &mut MediaList| {
*list = MediaList::parse(
&context,
&mut parser,
&NullReporter,
);
*list = MediaList::parse(&context, &mut parser);
})
}
@ -3801,6 +3813,7 @@ pub extern "C" fn Servo_MediaList_AppendMedium(
Some(CssRuleType::Media),
ParsingMode::DEFAULT,
QuirksMode::NoQuirks,
None,
);
write_locked_arc(list, |list: &mut MediaList| {
list.append_medium(&context, new_medium);
@ -3819,6 +3832,7 @@ pub extern "C" fn Servo_MediaList_DeleteMedium(
Some(CssRuleType::Media),
ParsingMode::DEFAULT,
QuirksMode::NoQuirks,
None,
);
write_locked_arc(list, |list: &mut MediaList| list.delete_medium(&context, old_medium))
}
@ -4210,6 +4224,7 @@ pub extern "C" fn Servo_DeclarationBlock_SetBackgroundImage(
Some(CssRuleType::Style),
ParsingMode::DEFAULT,
QuirksMode::NoQuirks,
None,
);
let url = SpecifiedImageUrl::parse_from_string(string.into(), &context);
let decl = PropertyDeclaration::BackgroundImage(BackgroundImage(
@ -4250,7 +4265,7 @@ pub unsafe extern "C" fn Servo_CSSSupports2(
DUMMY_URL_DATA,
structs::ParsingMode_Default,
QuirksMode::NoQuirks,
&NullReporter,
None,
).is_ok()
}
@ -4269,6 +4284,7 @@ pub extern "C" fn Servo_CSSSupports(cond: *const nsACString) -> bool {
Some(CssRuleType::Style),
ParsingMode::DEFAULT,
QuirksMode::NoQuirks,
None,
);
cond.eval(&context)
@ -5328,7 +5344,7 @@ pub unsafe extern "C" fn Servo_SelectorList_Drop(list: RawServoSelectorListOwned
fn parse_color(
value: &str,
error_reporter: Option<&ErrorReporter>,
error_reporter: Option<&ParseErrorReporter>,
) -> Result<specified::Color, ()> {
let mut input = ParserInput::new(value);
let mut parser = Parser::new(&mut input);
@ -5339,11 +5355,12 @@ fn parse_color(
Some(CssRuleType::Style),
ParsingMode::DEFAULT,
QuirksMode::NoQuirks,
error_reporter,
);
let start_position = parser.position();
parser.parse_entirely(|i| specified::Color::parse(&context, i)).map_err(|err| {
if let Some(error_reporter) = error_reporter {
if error_reporter.is_some() {
match err.kind {
ParseErrorKind::Custom(StyleParseErrorKind::ValueError(..)) => {
let location = err.location.clone();
@ -5351,7 +5368,7 @@ fn parse_color(
parser.slice_from(start_position),
err,
);
error_reporter.report(location, error);
context.log_css_error(location, error);
}
// Ignore other kinds of errors that might be reported, such as
// ParseErrorKind::Basic(BasicParseErrorKind::UnexpectedToken),
@ -5385,12 +5402,12 @@ pub extern "C" fn Servo_ComputeColor(
let value = unsafe { (*value).to_string() };
let result_color = unsafe { result_color.as_mut().unwrap() };
let reporter = unsafe { loader.as_mut() }.map(|loader| {
let reporter = unsafe { loader.as_mut() }.and_then(|loader| {
// Make an ErrorReporter that will report errors as being "from DOM".
ErrorReporter::new(ptr::null_mut(), loader, ptr::null_mut())
});
match parse_color(&value, reporter.as_ref()) {
match parse_color(&value, reporter.as_ref().map(|r| r as &ParseErrorReporter)) {
Ok(specified_color) => {
let computed_color = match raw_data {
Some(raw_data) => {
@ -5442,6 +5459,7 @@ pub unsafe extern "C" fn Servo_IntersectionObserverRootMargin_Parse(
Some(CssRuleType::Style),
ParsingMode::DEFAULT,
QuirksMode::NoQuirks,
None,
);
let margin = parser.parse_entirely(|p| {
@ -5484,7 +5502,8 @@ pub extern "C" fn Servo_ParseTransformIntoMatrix(
unsafe { dummy_url_data() },
Some(CssRuleType::Style),
ParsingMode::DEFAULT,
QuirksMode::NoQuirks
QuirksMode::NoQuirks,
None,
);
let transform = match parser.parse_entirely(|t| transform::parse(&context, t)) {
@ -5527,6 +5546,7 @@ pub extern "C" fn Servo_ParseFontShorthandForMatching(
Some(CssRuleType::FontFace),
ParsingMode::DEFAULT,
QuirksMode::NoQuirks,
None,
);
let font = match parser.parse_entirely(|f| font::parse_value(&context, f)) {
@ -5584,6 +5604,7 @@ pub unsafe extern "C" fn Servo_SourceSizeList_Parse(
Some(CssRuleType::Style),
ParsingMode::DEFAULT,
QuirksMode::NoQuirks,
None,
);
// NB: Intentionally not calling parse_entirely.

Просмотреть файл

@ -6,7 +6,6 @@ use cssparser::SourceLocation;
use nsstring::nsCString;
use servo_arc::Arc;
use style::context::QuirksMode;
use style::error_reporting::NullReporter;
use style::gecko::data::GeckoStyleSheet;
use style::gecko::global_style_data::GLOBAL_STYLE_DATA;
use style::gecko_bindings::bindings;
@ -104,10 +103,15 @@ impl AsyncStylesheetParser {
// are being logged, Gecko prevents the parallel parsing path from
// running.
let sheet = Arc::new(StylesheetContents::from_str(
input, self.extra_data.clone(), self.origin,
&global_style_data.shared_lock, Some(&self), &NullReporter,
self.quirks_mode.into(), self.line_number_offset)
);
input,
self.extra_data.clone(),
self.origin,
&global_style_data.shared_lock,
Some(&self),
None,
self.quirks_mode.into(),
self.line_number_offset,
));
unsafe {
bindings::Gecko_StyleSheet_FinishAsyncParse(self.load_data.get(), sheet.into_strong());

Просмотреть файл

@ -363,6 +363,31 @@ test(function () {
}, 'document.createElement must report an exception thrown by a custom element constructor');
test(function () {
var exceptionToThrow = {name: 'exception thrown by a custom constructor'};
class ThrowCustomBuiltinElement extends HTMLDivElement {
constructor()
{
super();
if (exceptionToThrow)
throw exceptionToThrow;
}
};
customElements.define('throw-custom-builtin-element', ThrowCustomBuiltinElement, { extends: 'div' });
assert_throws(exceptionToThrow, function () { new ThrowCustomBuiltinElement; });
var instance;
assert_reports(exceptionToThrow, function () { instance = document.createElement('div', { is: 'throw-custom-builtin-element' }); });
assert_equals(instance.localName, 'div');
assert_true(instance instanceof HTMLDivElement);
exceptionToThrow = false;
var instance = document.createElement('div', { is: 'throw-custom-builtin-element' });
assert_true(instance instanceof ThrowCustomBuiltinElement);
assert_equals(instance.localName, 'div');
}, 'document.createElement must report an exception thrown by a custom built-in element constructor');
test(() => {
class MyElement extends HTMLDivElement {}

Просмотреть файл

@ -15,6 +15,10 @@ EXTRA_COMPONENTS += [
'ClearDataService.manifest',
]
EXTRA_JS_MODULES += [
'ServiceWorkerCleanUp.jsm',
]
XPCSHELL_TESTS_MANIFESTS += ['tests/unit/xpcshell.ini']
include('/ipc/chromium/chromium-config.mozbuild')

Просмотреть файл

@ -135,6 +135,7 @@ ClearSiteData::Initialize()
}
obs->AddObserver(service, NS_HTTP_ON_EXAMINE_RESPONSE_TOPIC, false);
obs->AddObserver(service, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false);
gClearSiteData = service;
}
@ -156,6 +157,7 @@ ClearSiteData::Shutdown()
}
obs->RemoveObserver(service, NS_HTTP_ON_EXAMINE_RESPONSE_TOPIC);
obs->RemoveObserver(service, NS_XPCOM_SHUTDOWN_OBSERVER_ID);
}
ClearSiteData::ClearSiteData() = default;
@ -165,6 +167,11 @@ NS_IMETHODIMP
ClearSiteData::Observe(nsISupports* aSubject, const char* aTopic,
const char16_t* aData)
{
if (!strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) {
Shutdown();
return NS_OK;
}
MOZ_ASSERT(!strcmp(aTopic, NS_HTTP_ON_EXAMINE_RESPONSE_TOPIC));
// Pref disabled.

Просмотреть файл

@ -25,13 +25,13 @@ public:
static void
Initialize();
static void
Shutdown();
private:
ClearSiteData();
~ClearSiteData();
static void
Shutdown();
class PendingCleanupHolder;
// Starts the cleanup if the channel contains the Clear-Site-Data header and

Просмотреть файл

@ -9,7 +9,6 @@ XPCSHELL_TESTS_MANIFESTS += ['test/unit/xpcshell.ini']
EXTRA_JS_MODULES += [
'ForgetAboutSite.jsm',
'ServiceWorkerCleanUp.jsm',
]
with Files('**'):

Просмотреть файл

@ -40,6 +40,9 @@ private:
public:
nsReadingIterator()
: mStart(nullptr)
, mEnd(nullptr)
, mPosition(nullptr)
{
}
// nsReadingIterator( const nsReadingIterator<CharT>& ); // auto-generated copy-constructor OK
@ -142,6 +145,9 @@ private:
public:
nsWritingIterator()
: mStart(nullptr)
, mEnd(nullptr)
, mPosition(nullptr)
{
}
// nsWritingIterator( const nsWritingIterator<CharT>& ); // auto-generated copy-constructor OK