summaryrefslogtreecommitdiffstats
path: root/js/src/vm
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/vm')
-rw-r--r--js/src/vm/ArgumentsObject.cpp72
-rw-r--r--js/src/vm/ArgumentsObject.h3
-rw-r--r--js/src/vm/ArrayBufferObject.cpp4
-rw-r--r--js/src/vm/AsyncFunction.cpp2
-rw-r--r--js/src/vm/CommonPropertyNames.h38
-rw-r--r--js/src/vm/Debugger.cpp58
-rw-r--r--js/src/vm/Debugger.h3
-rw-r--r--js/src/vm/EnvironmentObject.cpp35
-rw-r--r--js/src/vm/EnvironmentObject.h3
-rw-r--r--js/src/vm/ErrorObject.cpp8
-rw-r--r--js/src/vm/ErrorReporting.cpp124
-rw-r--r--js/src/vm/ErrorReporting.h91
-rw-r--r--js/src/vm/GeneratorObject.cpp14
-rw-r--r--js/src/vm/GlobalObject.cpp46
-rw-r--r--js/src/vm/GlobalObject.h241
-rw-r--r--js/src/vm/HelperThreads.cpp2
-rw-r--r--js/src/vm/Interpreter-inl.h2
-rw-r--r--js/src/vm/Interpreter.cpp50
-rw-r--r--js/src/vm/Keywords.h66
-rw-r--r--js/src/vm/NativeObject-inl.h2
-rw-r--r--js/src/vm/NativeObject.cpp29
-rw-r--r--js/src/vm/NativeObject.h45
-rw-r--r--js/src/vm/ObjectGroup.cpp31
-rw-r--r--js/src/vm/Opcodes.h13
-rw-r--r--js/src/vm/ProxyObject.h2
-rw-r--r--js/src/vm/RegExpObject.cpp34
-rw-r--r--js/src/vm/RegExpObject.h11
-rw-r--r--js/src/vm/Scope.cpp8
-rw-r--r--js/src/vm/Scope.h11
-rw-r--r--js/src/vm/SelfHosting.cpp6
-rw-r--r--js/src/vm/Shape.cpp166
-rw-r--r--js/src/vm/Shape.h3
-rw-r--r--js/src/vm/SharedArrayObject.cpp3
-rw-r--r--js/src/vm/Stack-inl.h6
-rw-r--r--js/src/vm/Stack.h11
-rw-r--r--js/src/vm/StringObject-inl.h18
-rw-r--r--js/src/vm/StringObject.h2
-rw-r--r--js/src/vm/TypeInference.cpp20
-rw-r--r--js/src/vm/TypedArrayObject.cpp11
39 files changed, 824 insertions, 470 deletions
diff --git a/js/src/vm/ArgumentsObject.cpp b/js/src/vm/ArgumentsObject.cpp
index 717aa1050..66e0f40a2 100644
--- a/js/src/vm/ArgumentsObject.cpp
+++ b/js/src/vm/ArgumentsObject.cpp
@@ -214,7 +214,7 @@ ArgumentsObject::createTemplateObject(JSContext* cx, bool mapped)
? &MappedArgumentsObject::class_
: &UnmappedArgumentsObject::class_;
- RootedObject proto(cx, cx->global()->getOrCreateObjectPrototype(cx));
+ RootedObject proto(cx, GlobalObject::getOrCreateObjectPrototype(cx, cx->global()));
if (!proto)
return nullptr;
@@ -475,7 +475,7 @@ MappedArgSetter(JSContext* cx, HandleObject obj, HandleId id, MutableHandleValue
attrs &= (JSPROP_ENUMERATE | JSPROP_PERMANENT); /* only valid attributes */
RootedFunction callee(cx, &argsobj->callee());
- RootedScript script(cx, callee->getOrCreateScript(cx));
+ RootedScript script(cx, JSFunction::getOrCreateScript(cx, callee));
if (!script)
return false;
@@ -590,6 +590,64 @@ MappedArgumentsObject::obj_enumerate(JSContext* cx, HandleObject obj)
return true;
}
+// ES 2017 draft 9.4.4.2
+/* static */ bool
+MappedArgumentsObject::obj_defineProperty(JSContext* cx, HandleObject obj, HandleId id,
+ Handle<PropertyDescriptor> desc, ObjectOpResult& result)
+{
+ // Step 1.
+ Rooted<MappedArgumentsObject*> argsobj(cx, &obj->as<MappedArgumentsObject>());
+
+ // Steps 2-3.
+ bool isMapped = false;
+ if (JSID_IS_INT(id)) {
+ unsigned arg = unsigned(JSID_TO_INT(id));
+ isMapped = arg < argsobj->initialLength() && !argsobj->isElementDeleted(arg);
+ }
+
+ // Step 4.
+ Rooted<PropertyDescriptor> newArgDesc(cx, desc);
+ if (!desc.isAccessorDescriptor() && isMapped) {
+ // In this case the live mapping is supposed to keep working,
+ // we have to pass along the Getter/Setter otherwise they are overwritten.
+ newArgDesc.setGetter(MappedArgGetter);
+ newArgDesc.setSetter(MappedArgSetter);
+ }
+
+ // Steps 5-6. NativeDefineProperty will lookup [[Value]] for us.
+ if (!NativeDefineProperty(cx, obj.as<NativeObject>(), id, newArgDesc, result))
+ return false;
+ // Step 7.
+ if (!result.ok())
+ return true;
+
+ // Step 8.
+ if (isMapped) {
+ unsigned arg = unsigned(JSID_TO_INT(id));
+ if (desc.isAccessorDescriptor()) {
+ if (!argsobj->markElementDeleted(cx, arg))
+ return false;
+ } else {
+ if (desc.hasValue()) {
+ RootedFunction callee(cx, &argsobj->callee());
+ RootedScript script(cx, JSFunction::getOrCreateScript(cx, callee));
+ if (!script)
+ return false;
+ argsobj->setElement(cx, arg, desc.value());
+ if (arg < script->functionNonDelazifying()->nargs())
+ TypeScript::SetArgument(cx, script, arg, desc.value());
+ }
+ if (desc.hasWritable() && !desc.writable()) {
+ if (!argsobj->markElementDeleted(cx, arg))
+ return false;
+ }
+ }
+ }
+
+ // Step 9.
+ return result.succeed();
+}
+
static bool
UnmappedArgGetter(JSContext* cx, HandleObject obj, HandleId id, MutableHandleValue vp)
{
@@ -804,6 +862,11 @@ const ClassOps MappedArgumentsObject::classOps_ = {
ArgumentsObject::trace
};
+const ObjectOps MappedArgumentsObject::objectOps_ = {
+ nullptr, /* lookupProperty */
+ MappedArgumentsObject::obj_defineProperty
+};
+
const Class MappedArgumentsObject::class_ = {
"Arguments",
JSCLASS_DELAY_METADATA_BUILDER |
@@ -811,7 +874,10 @@ const Class MappedArgumentsObject::class_ = {
JSCLASS_HAS_CACHED_PROTO(JSProto_Object) |
JSCLASS_SKIP_NURSERY_FINALIZE |
JSCLASS_BACKGROUND_FINALIZE,
- &MappedArgumentsObject::classOps_
+ &MappedArgumentsObject::classOps_,
+ nullptr,
+ nullptr,
+ &MappedArgumentsObject::objectOps_
};
/*
diff --git a/js/src/vm/ArgumentsObject.h b/js/src/vm/ArgumentsObject.h
index 247c7cd94..988e41951 100644
--- a/js/src/vm/ArgumentsObject.h
+++ b/js/src/vm/ArgumentsObject.h
@@ -389,6 +389,7 @@ class ArgumentsObject : public NativeObject
class MappedArgumentsObject : public ArgumentsObject
{
static const ClassOps classOps_;
+ static const ObjectOps objectOps_;
public:
static const Class class_;
@@ -410,6 +411,8 @@ class MappedArgumentsObject : public ArgumentsObject
private:
static bool obj_enumerate(JSContext* cx, HandleObject obj);
static bool obj_resolve(JSContext* cx, HandleObject obj, HandleId id, bool* resolvedp);
+ static bool obj_defineProperty(JSContext* cx, HandleObject obj, HandleId id,
+ Handle<JS::PropertyDescriptor> desc, ObjectOpResult& result);
};
class UnmappedArgumentsObject : public ArgumentsObject
diff --git a/js/src/vm/ArrayBufferObject.cpp b/js/src/vm/ArrayBufferObject.cpp
index 1053fa99d..392724b21 100644
--- a/js/src/vm/ArrayBufferObject.cpp
+++ b/js/src/vm/ArrayBufferObject.cpp
@@ -140,7 +140,7 @@ static const Class ArrayBufferObjectProtoClass = {
static JSObject*
CreateArrayBufferPrototype(JSContext* cx, JSProtoKey key)
{
- return cx->global()->createBlankPrototype(cx, &ArrayBufferObjectProtoClass);
+ return GlobalObject::createBlankPrototype(cx, cx->global(), &ArrayBufferObjectProtoClass);
}
static const ClassOps ArrayBufferObjectClassOps = {
@@ -344,7 +344,7 @@ ArrayBufferObject::detach(JSContext* cx, Handle<ArrayBufferObject*> buffer,
// Make sure the global object's group has been instantiated, so the
// flag change will be observed.
AutoEnterOOMUnsafeRegion oomUnsafe;
- if (!cx->global()->getGroup(cx))
+ if (!JSObject::getGroup(cx, cx->global()))
oomUnsafe.crash("ArrayBufferObject::detach");
MarkObjectGroupFlags(cx, cx->global(), OBJECT_FLAG_TYPED_OBJECT_HAS_DETACHED_BUFFER);
cx->compartment()->detachedTypedObjects = 1;
diff --git a/js/src/vm/AsyncFunction.cpp b/js/src/vm/AsyncFunction.cpp
index f50c87114..e14b77424 100644
--- a/js/src/vm/AsyncFunction.cpp
+++ b/js/src/vm/AsyncFunction.cpp
@@ -118,7 +118,7 @@ js::WrapAsyncFunctionWithProto(JSContext* cx, HandleFunction unwrapped, HandleOb
RootedAtom funName(cx, unwrapped->explicitName());
uint16_t length;
- if (!unwrapped->getLength(cx, &length))
+ if (!JSFunction::getLength(cx, unwrapped, &length))
return nullptr;
// Steps 3 (partially).
diff --git a/js/src/vm/CommonPropertyNames.h b/js/src/vm/CommonPropertyNames.h
index 8a36df083..fd1c9f5e6 100644
--- a/js/src/vm/CommonPropertyNames.h
+++ b/js/src/vm/CommonPropertyNames.h
@@ -38,6 +38,7 @@
macro(Bool32x4, Bool32x4, "Bool32x4") \
macro(Bool64x2, Bool64x2, "Bool64x2") \
macro(boundWithSpace, boundWithSpace, "bound ") \
+ macro(break, break_, "break") \
macro(breakdown, breakdown, "breakdown") \
macro(buffer, buffer, "buffer") \
macro(builder, builder, "builder") \
@@ -52,8 +53,10 @@
macro(callee, callee, "callee") \
macro(caller, caller, "caller") \
macro(callFunction, callFunction, "callFunction") \
+ macro(case, case_, "case") \
macro(caseFirst, caseFirst, "caseFirst") \
- macro(class_, class_, "class") \
+ macro(catch, catch_, "catch") \
+ macro(class, class_, "class") \
macro(close, close, "close") \
macro(Collator, Collator, "Collator") \
macro(CollatorCompareGet, CollatorCompareGet, "Intl_Collator_compare_get") \
@@ -62,10 +65,14 @@
macro(comma, comma, ",") \
macro(compare, compare, "compare") \
macro(configurable, configurable, "configurable") \
+ macro(const, const_, "const") \
macro(construct, construct, "construct") \
macro(constructContentFunction, constructContentFunction, "constructContentFunction") \
macro(constructor, constructor, "constructor") \
+ macro(continue, continue_, "continue") \
macro(ConvertAndCopyTo, ConvertAndCopyTo, "ConvertAndCopyTo") \
+ macro(CopyDataProperties, CopyDataProperties, "CopyDataProperties") \
+ macro(CopyDataPropertiesUnfiltered, CopyDataPropertiesUnfiltered, "CopyDataPropertiesUnfiltered") \
macro(copyWithin, copyWithin, "copyWithin") \
macro(count, count, "count") \
macro(CreateResolvingFunctions, CreateResolvingFunctions, "CreateResolvingFunctions") \
@@ -76,28 +83,32 @@
macro(DateTimeFormatFormatToParts, DateTimeFormatFormatToParts, "Intl_DateTimeFormat_formatToParts") \
macro(day, day, "day") \
macro(dayPeriod, dayPeriod, "dayPeriod") \
+ macro(debugger, debugger, "debugger") \
macro(decodeURI, decodeURI, "decodeURI") \
macro(decodeURIComponent, decodeURIComponent, "decodeURIComponent") \
macro(DefaultBaseClassConstructor, DefaultBaseClassConstructor, "DefaultBaseClassConstructor") \
macro(DefaultDerivedClassConstructor, DefaultDerivedClassConstructor, "DefaultDerivedClassConstructor") \
- macro(default_, default_, "default") \
+ macro(default, default_, "default") \
macro(defineGetter, defineGetter, "__defineGetter__") \
macro(defineProperty, defineProperty, "defineProperty") \
macro(defineSetter, defineSetter, "__defineSetter__") \
macro(delete, delete_, "delete") \
macro(deleteProperty, deleteProperty, "deleteProperty") \
macro(displayURL, displayURL, "displayURL") \
+ macro(do, do_, "do") \
macro(done, done, "done") \
macro(dotGenerator, dotGenerator, ".generator") \
macro(dotThis, dotThis, ".this") \
macro(each, each, "each") \
macro(elementType, elementType, "elementType") \
+ macro(else, else_, "else") \
macro(empty, empty, "") \
macro(emptyRegExp, emptyRegExp, "(?:)") \
macro(encodeURI, encodeURI, "encodeURI") \
macro(encodeURIComponent, encodeURIComponent, "encodeURIComponent") \
macro(endTimestamp, endTimestamp, "endTimestamp") \
macro(entries, entries, "entries") \
+ macro(enum, enum_, "enum") \
macro(enumerable, enumerable, "enumerable") \
macro(enumerate, enumerate, "enumerate") \
macro(era, era, "era") \
@@ -105,11 +116,14 @@
macro(escape, escape, "escape") \
macro(eval, eval, "eval") \
macro(exec, exec, "exec") \
+ macro(export, export_, "export") \
+ macro(extends, extends, "extends") \
macro(false, false_, "false") \
macro(fieldOffsets, fieldOffsets, "fieldOffsets") \
macro(fieldTypes, fieldTypes, "fieldTypes") \
macro(fileName, fileName, "fileName") \
macro(fill, fill, "fill") \
+ macro(finally, finally_, "finally") \
macro(find, find, "find") \
macro(findIndex, findIndex, "findIndex") \
macro(firstDayOfWeek, firstDayOfWeek, "firstDayOfWeek") \
@@ -121,6 +135,7 @@
macro(Float32x4, Float32x4, "Float32x4") \
macro(float64, float64, "float64") \
macro(Float64x2, Float64x2, "Float64x2") \
+ macro(for, for_, "for") \
macro(forceInterpreter, forceInterpreter, "forceInterpreter") \
macro(forEach, forEach, "forEach") \
macro(format, format, "format") \
@@ -146,8 +161,12 @@
macro(hasOwn, hasOwn, "hasOwn") \
macro(hasOwnProperty, hasOwnProperty, "hasOwnProperty") \
macro(hour, hour, "hour") \
+ macro(if, if_, "if") \
macro(ignoreCase, ignoreCase, "ignoreCase") \
macro(ignorePunctuation, ignorePunctuation, "ignorePunctuation") \
+ macro(implements, implements, "implements") \
+ macro(import, import, "import") \
+ macro(in, in, "in") \
macro(includes, includes, "includes") \
macro(incumbentGlobal, incumbentGlobal, "incumbentGlobal") \
macro(index, index, "index") \
@@ -158,12 +177,14 @@
macro(innermost, innermost, "innermost") \
macro(inNursery, inNursery, "inNursery") \
macro(input, input, "input") \
+ macro(instanceof, instanceof, "instanceof") \
macro(int8, int8, "int8") \
macro(int16, int16, "int16") \
macro(int32, int32, "int32") \
macro(Int8x16, Int8x16, "Int8x16") \
macro(Int16x8, Int16x8, "Int16x8") \
macro(Int32x4, Int32x4, "Int32x4") \
+ macro(interface, interface, "interface") \
macro(InterpretGeneratorResume, InterpretGeneratorResume, "InterpretGeneratorResume") \
macro(isEntryPoint, isEntryPoint, "isEntryPoint") \
macro(isExtensible, isExtensible, "isExtensible") \
@@ -217,6 +238,7 @@
macro(noFilename, noFilename, "noFilename") \
macro(nonincrementalReason, nonincrementalReason, "nonincrementalReason") \
macro(noStack, noStack, "noStack") \
+ macro(notes, notes, "notes") \
macro(NumberFormat, NumberFormat, "NumberFormat") \
macro(NumberFormatFormatGet, NumberFormatFormatGet, "Intl_NumberFormat_format_get") \
macro(numeric, numeric, "numeric") \
@@ -238,13 +260,18 @@
macro(other, other, "other") \
macro(outOfMemory, outOfMemory, "out of memory") \
macro(ownKeys, ownKeys, "ownKeys") \
+ macro(Object_valueOf, Object_valueOf, "Object_valueOf") \
+ macro(package, package, "package") \
macro(parseFloat, parseFloat, "parseFloat") \
macro(parseInt, parseInt, "parseInt") \
macro(pattern, pattern, "pattern") \
macro(pending, pending, "pending") \
+ macro(public, public_, "public") \
macro(preventExtensions, preventExtensions, "preventExtensions") \
+ macro(private, private_, "private") \
macro(promise, promise, "promise") \
macro(propertyIsEnumerable, propertyIsEnumerable, "propertyIsEnumerable") \
+ macro(protected, protected_, "protected") \
macro(proto, proto, "__proto__") \
macro(prototype, prototype, "prototype") \
macro(proxy, proxy, "proxy") \
@@ -293,10 +320,12 @@
macro(StructType, StructType, "StructType") \
macro(style, style, "style") \
macro(super, super, "super") \
+ macro(switch, switch_, "switch") \
macro(Symbol_iterator_fun, Symbol_iterator_fun, "[Symbol.iterator]") \
macro(target, target, "target") \
macro(test, test, "test") \
macro(then, then, "then") \
+ macro(this, this_, "this") \
macro(throw, throw_, "throw") \
macro(timestamp, timestamp, "timestamp") \
macro(timeZone, timeZone, "timeZone") \
@@ -309,7 +338,9 @@
macro(toString, toString, "toString") \
macro(toUTCString, toUTCString, "toUTCString") \
macro(true, true_, "true") \
+ macro(try, try_, "try") \
macro(type, type, "type") \
+ macro(typeof, typeof_, "typeof") \
macro(uint8, uint8, "uint8") \
macro(uint8Clamped, uint8Clamped, "uint8Clamped") \
macro(uint16, uint16, "uint16") \
@@ -329,6 +360,7 @@
macro(useAsm, useAsm, "use asm") \
macro(useGrouping, useGrouping, "useGrouping") \
macro(useStrict, useStrict, "use strict") \
+ macro(void, void_, "void") \
macro(value, value, "value") \
macro(valueOf, valueOf, "valueOf") \
macro(values, values, "values") \
@@ -343,6 +375,8 @@
macro(weekday, weekday, "weekday") \
macro(weekendEnd, weekendEnd, "weekendEnd") \
macro(weekendStart, weekendStart, "weekendStart") \
+ macro(while, while_, "while") \
+ macro(with, with, "with") \
macro(writable, writable, "writable") \
macro(year, year, "year") \
macro(yield, yield, "yield") \
diff --git a/js/src/vm/Debugger.cpp b/js/src/vm/Debugger.cpp
index d16781326..d68d1b75e 100644
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -224,7 +224,7 @@ EnsureFunctionHasScript(JSContext* cx, HandleFunction fun)
{
if (fun->isInterpretedLazy()) {
AutoCompartment ac(cx, fun);
- return !!fun->getOrCreateScript(cx);
+ return !!JSFunction::getOrCreateScript(cx, fun);
}
return true;
}
@@ -2234,7 +2234,7 @@ Debugger::appendAllocationSite(JSContext* cx, HandleObject obj, HandleSavedFrame
RootedAtom ctorName(cx);
{
AutoCompartment ac(cx, obj);
- if (!obj->constructorDisplayAtom(cx, &ctorName))
+ if (!JSObject::constructorDisplayAtom(cx, obj, &ctorName))
return false;
}
@@ -7227,8 +7227,8 @@ static const JSFunctionSpec DebuggerSource_methods[] = {
/* static */ NativeObject*
DebuggerFrame::initClass(JSContext* cx, HandleObject dbgCtor, HandleObject obj)
{
- Rooted<GlobalObject*> global(cx, &obj->as<GlobalObject>());
- RootedObject objProto(cx, global->getOrCreateObjectPrototype(cx));
+ Handle<GlobalObject*> global = obj.as<GlobalObject>();
+ RootedObject objProto(cx, GlobalObject::getOrCreateObjectPrototype(cx, global));
return InitClass(cx, dbgCtor, objProto, &class_, construct, 0, properties_,
methods_, nullptr, nullptr);
@@ -8666,6 +8666,14 @@ DebuggerObject::errorMessageNameGetter(JSContext *cx, unsigned argc, Value* vp)
}
/* static */ bool
+DebuggerObject::errorNotesGetter(JSContext *cx, unsigned argc, Value* vp)
+{
+ THIS_DEBUGOBJECT(cx, argc, vp, "get errorNotes", args, object)
+
+ return DebuggerObject::getErrorNotes(cx, object, args.rval());
+}
+
+/* static */ bool
DebuggerObject::errorLineNumberGetter(JSContext *cx, unsigned argc, Value* vp)
{
THIS_DEBUGOBJECT(cx, argc, vp, "get errorLineNumber", args, object)
@@ -9324,6 +9332,7 @@ const JSPropertySpec DebuggerObject::properties_[] = {
JS_PSG("global", DebuggerObject::globalGetter, 0),
JS_PSG("allocationSite", DebuggerObject::allocationSiteGetter, 0),
JS_PSG("errorMessageName", DebuggerObject::errorMessageNameGetter, 0),
+ JS_PSG("errorNotes", DebuggerObject::errorNotesGetter, 0),
JS_PSG("errorLineNumber", DebuggerObject::errorLineNumberGetter, 0),
JS_PSG("errorColumnNumber", DebuggerObject::errorColumnNumberGetter, 0),
JS_PSG("isProxy", DebuggerObject::isProxyGetter, 0),
@@ -9376,8 +9385,8 @@ const JSFunctionSpec DebuggerObject::methods_[] = {
/* static */ NativeObject*
DebuggerObject::initClass(JSContext* cx, HandleObject obj, HandleObject debugCtor)
{
- Rooted<GlobalObject*> global(cx, &obj->as<GlobalObject>());
- RootedObject objProto(cx, global->getOrCreateObjectPrototype(cx));
+ Handle<GlobalObject*> global = obj.as<GlobalObject>();
+ RootedObject objProto(cx, GlobalObject::getOrCreateObjectPrototype(cx, global));
RootedNativeObject objectProto(cx, InitClass(cx, debugCtor, objProto, &class_,
construct, 0, properties_,
@@ -9611,7 +9620,7 @@ DebuggerObject::getBoundArguments(JSContext* cx, HandleDebuggerObject object,
if (!result.resize(length))
return false;
for (size_t i = 0; i < length; i++) {
- result[i].set(referent->getBoundFunctionArgument(cx, i));
+ result[i].set(referent->getBoundFunctionArgument(i));
if (!dbg->wrapDebuggeeValue(cx, result[i]))
return false;
}
@@ -9695,6 +9704,30 @@ DebuggerObject::getErrorMessageName(JSContext* cx, HandleDebuggerObject object,
}
/* static */ bool
+DebuggerObject::getErrorNotes(JSContext* cx, HandleDebuggerObject object,
+ MutableHandleValue result)
+{
+ RootedObject referent(cx, object->referent());
+ JSErrorReport* report;
+ if (!getErrorReport(cx, referent, report))
+ return false;
+
+ if (!report) {
+ result.setUndefined();
+ return true;
+ }
+
+ RootedObject errorNotesArray(cx, CreateErrorNotesArray(cx, report));
+ if (!errorNotesArray)
+ return false;
+
+ if (!cx->compartment()->wrap(cx, &errorNotesArray))
+ return false;
+ result.setObject(*errorNotesArray);
+ return true;
+}
+
+/* static */ bool
DebuggerObject::getErrorLineNumber(JSContext* cx, HandleDebuggerObject object,
MutableHandleValue result)
{
@@ -10577,8 +10610,8 @@ const JSFunctionSpec DebuggerEnvironment::methods_[] = {
/* static */ NativeObject*
DebuggerEnvironment::initClass(JSContext* cx, HandleObject dbgCtor, HandleObject obj)
{
- Rooted<GlobalObject*> global(cx, &obj->as<GlobalObject>());
- RootedObject objProto(cx, global->getOrCreateObjectPrototype(cx));
+ Handle<GlobalObject*> global = obj.as<GlobalObject>();
+ RootedObject objProto(cx, GlobalObject::getOrCreateObjectPrototype(cx, global));
return InitClass(cx, dbgCtor, objProto, &DebuggerEnvironment::class_, construct, 0,
properties_, methods_, nullptr, nullptr);
@@ -10774,7 +10807,8 @@ DebuggerEnvironment::getVariable(JSContext* cx, HandleDebuggerEnvironment enviro
//
// See wrapDebuggeeValue for how the sentinel values are wrapped.
if (referent->is<DebugEnvironmentProxy>()) {
- if (!referent->as<DebugEnvironmentProxy>().getMaybeSentinelValue(cx, id, result))
+ Rooted<DebugEnvironmentProxy*> env(cx, &referent->as<DebugEnvironmentProxy>());
+ if (!DebugEnvironmentProxy::getMaybeSentinelValue(cx, env, id, result))
return false;
} else {
if (!GetProperty(cx, referent, referent, id, result))
@@ -10942,9 +10976,9 @@ JS_DefineDebuggerObject(JSContext* cx, HandleObject obj)
memoryProto(cx);
RootedObject debuggeeWouldRunProto(cx);
RootedValue debuggeeWouldRunCtor(cx);
- Rooted<GlobalObject*> global(cx, &obj->as<GlobalObject>());
+ Handle<GlobalObject*> global = obj.as<GlobalObject>();
- objProto = global->getOrCreateObjectPrototype(cx);
+ objProto = GlobalObject::getOrCreateObjectPrototype(cx, global);
if (!objProto)
return false;
debugProto = InitClass(cx, obj,
diff --git a/js/src/vm/Debugger.h b/js/src/vm/Debugger.h
index 3239ade6d..cdcf2d67f 100644
--- a/js/src/vm/Debugger.h
+++ b/js/src/vm/Debugger.h
@@ -1246,6 +1246,8 @@ class DebuggerObject : public NativeObject
MutableHandleObject result);
static MOZ_MUST_USE bool getErrorMessageName(JSContext* cx, HandleDebuggerObject object,
MutableHandleString result);
+ static MOZ_MUST_USE bool getErrorNotes(JSContext* cx, HandleDebuggerObject object,
+ MutableHandleValue result);
static MOZ_MUST_USE bool getErrorLineNumber(JSContext* cx, HandleDebuggerObject object,
MutableHandleValue result);
static MOZ_MUST_USE bool getErrorColumnNumber(JSContext* cx, HandleDebuggerObject object,
@@ -1371,6 +1373,7 @@ class DebuggerObject : public NativeObject
static MOZ_MUST_USE bool globalGetter(JSContext* cx, unsigned argc, Value* vp);
static MOZ_MUST_USE bool allocationSiteGetter(JSContext* cx, unsigned argc, Value* vp);
static MOZ_MUST_USE bool errorMessageNameGetter(JSContext* cx, unsigned argc, Value* vp);
+ static MOZ_MUST_USE bool errorNotesGetter(JSContext* cx, unsigned argc, Value* vp);
static MOZ_MUST_USE bool errorLineNumberGetter(JSContext* cx, unsigned argc, Value* vp);
static MOZ_MUST_USE bool errorColumnNumberGetter(JSContext* cx, unsigned argc, Value* vp);
static MOZ_MUST_USE bool isProxyGetter(JSContext* cx, unsigned argc, Value* vp);
diff --git a/js/src/vm/EnvironmentObject.cpp b/js/src/vm/EnvironmentObject.cpp
index 34c39eabf..a5aac2ab4 100644
--- a/js/src/vm/EnvironmentObject.cpp
+++ b/js/src/vm/EnvironmentObject.cpp
@@ -816,7 +816,7 @@ NonSyntacticVariablesObject::create(JSContext* cx)
return nullptr;
MOZ_ASSERT(obj->isUnqualifiedVarObj());
- if (!obj->setQualifiedVarObj(cx))
+ if (!JSObject::setQualifiedVarObj(cx, obj))
return nullptr;
obj->initEnclosingEnvironment(&cx->global()->lexicalEnvironment());
@@ -957,7 +957,7 @@ LexicalEnvironmentObject::createHollowForDebug(JSContext* cx, Handle<LexicalScop
return nullptr;
}
- if (!env->setFlags(cx, BaseShape::NOT_EXTENSIBLE, JSObject::GENERATE_SHAPE))
+ if (!JSObject::setFlags(cx, env, BaseShape::NOT_EXTENSIBLE, JSObject::GENERATE_SHAPE))
return nullptr;
env->initScopeUnchecked(scope);
@@ -1425,7 +1425,8 @@ class DebugEnvironmentProxyHandler : public BaseProxyHandler
/* Handle unaliased formals, vars, lets, and consts at function scope. */
if (env->is<CallObject>()) {
CallObject& callobj = env->as<CallObject>();
- RootedScript script(cx, callobj.callee().getOrCreateScript(cx));
+ RootedFunction fun(cx, &callobj.callee());
+ RootedScript script(cx, JSFunction::getOrCreateScript(cx, fun));
if (!script->ensureHasTypes(cx) || !script->ensureHasAnalyzedArgsUsage(cx))
return false;
@@ -2233,11 +2234,11 @@ DebugEnvironmentProxy::isForDeclarative() const
e.is<LexicalEnvironmentObject>();
}
-bool
-DebugEnvironmentProxy::getMaybeSentinelValue(JSContext* cx, HandleId id, MutableHandleValue vp)
+/* static */ bool
+DebugEnvironmentProxy::getMaybeSentinelValue(JSContext* cx, Handle<DebugEnvironmentProxy*> env,
+ HandleId id, MutableHandleValue vp)
{
- Rooted<DebugEnvironmentProxy*> self(cx, this);
- return DebugEnvironmentProxyHandler::singleton.getMaybeSentinelValue(cx, self, id, vp);
+ return DebugEnvironmentProxyHandler::singleton.getMaybeSentinelValue(cx, env, id, vp);
}
bool
@@ -2960,7 +2961,7 @@ js::GetDebugEnvironmentForFunction(JSContext* cx, HandleFunction fun)
MOZ_ASSERT(CanUseDebugEnvironmentMaps(cx));
if (!DebugEnvironments::updateLiveEnvironments(cx))
return nullptr;
- JSScript* script = fun->getOrCreateScript(cx);
+ JSScript* script = JSFunction::getOrCreateScript(cx, fun);
if (!script)
return nullptr;
EnvironmentIter ei(cx, fun->environment(), script->enclosingScope());
@@ -3468,11 +3469,13 @@ RemoveReferencedNames(JSContext* cx, HandleScript script, PropertyNameSet& remai
if (script->hasObjects()) {
ObjectArray* objects = script->objects();
+ RootedFunction fun(cx);
+ RootedScript innerScript(cx);
for (size_t i = 0; i < objects->length; i++) {
JSObject* obj = objects->vector[i];
if (obj->is<JSFunction>() && obj->as<JSFunction>().isInterpreted()) {
- JSFunction* fun = &obj->as<JSFunction>();
- RootedScript innerScript(cx, fun->getOrCreateScript(cx));
+ fun = &obj->as<JSFunction>();
+ innerScript = JSFunction::getOrCreateScript(cx, fun);
if (!innerScript)
return false;
@@ -3535,11 +3538,13 @@ AnalyzeEntrainedVariablesInScript(JSContext* cx, HandleScript script, HandleScri
if (innerScript->hasObjects()) {
ObjectArray* objects = innerScript->objects();
+ RootedFunction fun(cx);
+ RootedScript innerInnerScript(cx);
for (size_t i = 0; i < objects->length; i++) {
JSObject* obj = objects->vector[i];
if (obj->is<JSFunction>() && obj->as<JSFunction>().isInterpreted()) {
- JSFunction* fun = &obj->as<JSFunction>();
- RootedScript innerInnerScript(cx, fun->getOrCreateScript(cx));
+ fun = &obj->as<JSFunction>();
+ innerInnerScript = JSFunction::getOrCreateScript(cx, fun);
if (!innerInnerScript ||
!AnalyzeEntrainedVariablesInScript(cx, script, innerInnerScript))
{
@@ -3570,11 +3575,13 @@ js::AnalyzeEntrainedVariables(JSContext* cx, HandleScript script)
return true;
ObjectArray* objects = script->objects();
+ RootedFunction fun(cx);
+ RootedScript innerScript(cx);
for (size_t i = 0; i < objects->length; i++) {
JSObject* obj = objects->vector[i];
if (obj->is<JSFunction>() && obj->as<JSFunction>().isInterpreted()) {
- JSFunction* fun = &obj->as<JSFunction>();
- RootedScript innerScript(cx, fun->getOrCreateScript(cx));
+ fun = &obj->as<JSFunction>();
+ innerScript = JSFunction::getOrCreateScript(cx, fun);
if (!innerScript)
return false;
diff --git a/js/src/vm/EnvironmentObject.h b/js/src/vm/EnvironmentObject.h
index 032286116..c527cd1b0 100644
--- a/js/src/vm/EnvironmentObject.h
+++ b/js/src/vm/EnvironmentObject.h
@@ -872,7 +872,8 @@ class DebugEnvironmentProxy : public ProxyObject
// Get a property by 'id', but returns sentinel values instead of throwing
// on exceptional cases.
- bool getMaybeSentinelValue(JSContext* cx, HandleId id, MutableHandleValue vp);
+ static bool getMaybeSentinelValue(JSContext* cx, Handle<DebugEnvironmentProxy*> env,
+ HandleId id, MutableHandleValue vp);
// Returns true iff this is a function environment with its own this-binding
// (all functions except arrow functions and generator expression lambdas).
diff --git a/js/src/vm/ErrorObject.cpp b/js/src/vm/ErrorObject.cpp
index d8d29830b..271132801 100644
--- a/js/src/vm/ErrorObject.cpp
+++ b/js/src/vm/ErrorObject.cpp
@@ -29,11 +29,11 @@ js::ErrorObject::assignInitialShape(ExclusiveContext* cx, Handle<ErrorObject*> o
{
MOZ_ASSERT(obj->empty());
- if (!obj->addDataProperty(cx, cx->names().fileName, FILENAME_SLOT, 0))
+ if (!NativeObject::addDataProperty(cx, obj, cx->names().fileName, FILENAME_SLOT, 0))
return nullptr;
- if (!obj->addDataProperty(cx, cx->names().lineNumber, LINENUMBER_SLOT, 0))
+ if (!NativeObject::addDataProperty(cx, obj, cx->names().lineNumber, LINENUMBER_SLOT, 0))
return nullptr;
- return obj->addDataProperty(cx, cx->names().columnNumber, COLUMNNUMBER_SLOT, 0);
+ return NativeObject::addDataProperty(cx, obj, cx->names().columnNumber, COLUMNNUMBER_SLOT, 0);
}
/* static */ bool
@@ -57,7 +57,7 @@ js::ErrorObject::init(JSContext* cx, Handle<ErrorObject*> obj, JSExnType type,
// |new Error()|.
RootedShape messageShape(cx);
if (message) {
- messageShape = obj->addDataProperty(cx, cx->names().message, MESSAGE_SLOT, 0);
+ messageShape = NativeObject::addDataProperty(cx, obj, cx->names().message, MESSAGE_SLOT, 0);
if (!messageShape)
return false;
MOZ_ASSERT(messageShape->slot() == MESSAGE_SLOT);
diff --git a/js/src/vm/ErrorReporting.cpp b/js/src/vm/ErrorReporting.cpp
new file mode 100644
index 000000000..5877f3a4b
--- /dev/null
+++ b/js/src/vm/ErrorReporting.cpp
@@ -0,0 +1,124 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set ts=8 sts=4 et sw=4 tw=99:
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "vm/ErrorReporting.h"
+
+#include "mozilla/Move.h"
+
+#include <stdarg.h>
+
+#include "jscntxt.h"
+#include "jsexn.h"
+
+using mozilla::Move;
+
+using JS::UniqueTwoByteChars;
+
+void
+CallWarningReporter(JSContext* cx, JSErrorReport* reportp)
+{
+ MOZ_ASSERT(reportp);
+ MOZ_ASSERT(JSREPORT_IS_WARNING(reportp->flags));
+
+ if (JS::WarningReporter warningReporter = cx->runtime()->warningReporter)
+ warningReporter(cx, reportp);
+}
+
+void
+CompileError::throwError(JSContext* cx)
+{
+ if (JSREPORT_IS_WARNING(flags)) {
+ CallWarningReporter(cx, this);
+ return;
+ }
+
+ // If there's a runtime exception type associated with this error
+ // number, set that as the pending exception. For errors occuring at
+ // compile time, this is very likely to be a JSEXN_SYNTAXERR.
+ //
+ // If an exception is thrown but not caught, the JSREPORT_EXCEPTION
+ // flag will be set in report.flags. Proper behavior for an error
+ // reporter is to ignore a report with this flag for all but top-level
+ // compilation errors. The exception will remain pending, and so long
+ // as the non-top-level "load", "eval", or "compile" native function
+ // returns false, the top-level reporter will eventually receive the
+ // uncaught exception report.
+ ErrorToException(cx, this, nullptr, nullptr);
+}
+
+bool
+ReportCompileWarning(JSContext* cx, ErrorMetadata&& metadata, UniquePtr<JSErrorNotes> notes,
+ unsigned flags, unsigned errorNumber, va_list args)
+{
+ // On the main thread, report the error immediately. When compiling off
+ // thread, save the error so that the thread finishing the parse can report
+ // it later.
+ CompileError tempErr;
+ CompileError* err = &tempErr;
+ if (!cx->isJSContext() && !cx->addPendingCompileError(&err)) {
+ return false;
+ }
+
+ err->notes = Move(notes);
+ err->flags = flags;
+ err->errorNumber = errorNumber;
+
+ err->filename = metadata.filename;
+ err->lineno = metadata.lineNumber;
+ err->column = metadata.columnNumber;
+ err->isMuted = metadata.isMuted;
+
+ if (UniqueTwoByteChars lineOfContext = Move(metadata.lineOfContext))
+ err->initOwnedLinebuf(lineOfContext.release(), metadata.lineLength, metadata.tokenOffset);
+
+ if (!ExpandErrorArgumentsVA(cx, GetErrorMessage, nullptr, errorNumber,
+ nullptr, ArgumentsAreLatin1, err, args))
+ {
+ return false;
+ }
+
+ if (cx->isJSContext()) {
+ err->throwError(cx->asJSContext());
+ }
+
+ return true;
+}
+
+void
+ReportCompileError(JSContext* cx, ErrorMetadata&& metadata, UniquePtr<JSErrorNotes> notes,
+ unsigned flags, unsigned errorNumber, va_list args)
+{
+ // On the main thread, report the error immediately. When compiling off
+ // thread, save the error so that the thread finishing the parse can report
+ // it later.
+ CompileError tempErr;
+ CompileError* err = &tempErr;
+ if (!cx->isJSContext() && !cx->addPendingCompileError(&err)) {
+ return;
+ }
+
+ err->notes = Move(notes);
+ err->flags = flags;
+ err->errorNumber = errorNumber;
+
+ err->filename = metadata.filename;
+ err->lineno = metadata.lineNumber;
+ err->column = metadata.columnNumber;
+ err->isMuted = metadata.isMuted;
+
+ if (UniqueTwoByteChars lineOfContext = Move(metadata.lineOfContext))
+ err->initOwnedLinebuf(lineOfContext.release(), metadata.lineLength, metadata.tokenOffset);
+
+ if (!ExpandErrorArgumentsVA(cx, GetErrorMessage, nullptr, errorNumber,
+ nullptr, ArgumentsAreLatin1, err, args))
+ {
+ return;
+ }
+
+ if (cx->isJSContext()) {
+ err->throwError(cx->asJSContext());
+ }
+}
diff --git a/js/src/vm/ErrorReporting.h b/js/src/vm/ErrorReporting.h
new file mode 100644
index 000000000..02bbe2c63
--- /dev/null
+++ b/js/src/vm/ErrorReporting.h
@@ -0,0 +1,91 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set ts=8 sts=4 et sw=4 tw=99:
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef vm_ErrorReporting_h
+#define vm_ErrorReporting_h
+
+#include "mozilla/Move.h"
+
+#include <stdarg.h>
+
+#include "jsapi.h" // for JSErrorNotes, JSErrorReport
+
+#include "js/UniquePtr.h" // for UniquePtr
+#include "js/Utility.h" // for UniqueTwoByteChars
+
+struct JSContext;
+
+namespace js {
+
+/**
+ * Metadata for a compilation error (or warning) at a particular offset, or at
+ * no offset (i.e. with respect to a script overall).
+ */
+struct ErrorMetadata
+{
+ // The file/URL where the error occurred.
+ const char* filename;
+
+ // The line and column numbers where the error occurred. If the error
+ // is with respect to the entire script and not with respect to a
+ // particular location, these will both be zero.
+ uint32_t lineNumber;
+ uint32_t columnNumber;
+
+ // If the error occurs at a particular location, context surrounding the
+ // location of the error: the line that contained the error, or a small
+ // portion of it if the line is long.
+ //
+ // This information is provided on a best-effort basis: code populating
+ // ErrorMetadata instances isn't obligated to supply this.
+ JS::UniqueTwoByteChars lineOfContext;
+
+ // If |lineOfContext| is non-null, its length.
+ size_t lineLength;
+
+ // If |lineOfContext| is non-null, the offset within it of the token that
+ // triggered the error.
+ size_t tokenOffset;
+
+ // Whether the error is "muted" because it derives from a cross-origin
+ // load. See the comment in TransitiveCompileOptions in jsapi.h for
+ // details.
+ bool isMuted;
+};
+
+class CompileError : public JSErrorReport
+{
+ public:
+ void throwError(JSContext* cx);
+};
+
+/** Send a JSErrorReport to the warningReporter callback. */
+extern void
+CallWarningReporter(JSContext* cx, JSErrorReport* report);
+
+/**
+ * Report a compile error during script processing prior to execution of the
+ * script.
+ */
+extern void
+ReportCompileError(ErrorMetadata&& metadata, UniquePtr<JSErrorNotes> notes,
+ unsigned flags, unsigned errorNumber, va_list args);
+
+/**
+ * Report a compile warning during script processing prior to execution of the
+ * script. Returns true if the warning was successfully reported, false if an
+ * error occurred.
+ *
+ * This function DOES NOT respect an existing werror option. If the caller
+ * wishes such option to be respected, it must do so itself.
+ */
+extern MOZ_MUST_USE bool
+ReportCompileWarning(JSContext* cx, ErrorMetadata&& metadata, UniquePtr<JSErrorNotes> notes,
+ unsigned flags, unsigned errorNumber, va_list args);
+
+} // namespace js
+
+#endif /* vm_ErrorReporting_h */
diff --git a/js/src/vm/GeneratorObject.cpp b/js/src/vm/GeneratorObject.cpp
index 690c0bf48..ba28501e6 100644
--- a/js/src/vm/GeneratorObject.cpp
+++ b/js/src/vm/GeneratorObject.cpp
@@ -256,7 +256,7 @@ static const JSFunctionSpec legacy_generator_methods[] = {
static JSObject*
NewSingletonObjectWithObjectPrototype(JSContext* cx, Handle<GlobalObject*> global)
{
- RootedObject proto(cx, global->getOrCreateObjectPrototype(cx));
+ RootedObject proto(cx, GlobalObject::getOrCreateObjectPrototype(cx, global));
if (!proto)
return nullptr;
return NewObjectWithGivenProto<PlainObject>(cx, proto, SingletonObject);
@@ -265,7 +265,7 @@ NewSingletonObjectWithObjectPrototype(JSContext* cx, Handle<GlobalObject*> globa
JSObject*
js::NewSingletonObjectWithFunctionPrototype(JSContext* cx, Handle<GlobalObject*> global)
{
- RootedObject proto(cx, global->getOrCreateFunctionPrototype(cx));
+ RootedObject proto(cx, GlobalObject::getOrCreateFunctionPrototype(cx, global));
if (!proto)
return nullptr;
return NewObjectWithGivenProto<PlainObject>(cx, proto, SingletonObject);
@@ -278,7 +278,7 @@ GlobalObject::initLegacyGeneratorProto(JSContext* cx, Handle<GlobalObject*> glob
return true;
RootedObject proto(cx, NewSingletonObjectWithObjectPrototype(cx, global));
- if (!proto || !proto->setDelegate(cx))
+ if (!proto || !JSObject::setDelegate(cx, proto))
return false;
if (!DefinePropertiesAndFunctions(cx, proto, nullptr, legacy_generator_methods))
return false;
@@ -297,9 +297,9 @@ GlobalObject::initStarGenerators(JSContext* cx, Handle<GlobalObject*> global)
if (!iteratorProto)
return false;
- RootedObject genObjectProto(cx, global->createBlankPrototypeInheriting(cx,
- &PlainObject::class_,
- iteratorProto));
+ RootedObject genObjectProto(cx, GlobalObject::createBlankPrototypeInheriting(cx, global,
+ &PlainObject::class_,
+ iteratorProto));
if (!genObjectProto)
return false;
if (!DefinePropertiesAndFunctions(cx, genObjectProto, nullptr, star_generator_methods) ||
@@ -309,7 +309,7 @@ GlobalObject::initStarGenerators(JSContext* cx, Handle<GlobalObject*> global)
}
RootedObject genFunctionProto(cx, NewSingletonObjectWithFunctionPrototype(cx, global));
- if (!genFunctionProto || !genFunctionProto->setDelegate(cx))
+ if (!genFunctionProto || !JSObject::setDelegate(cx, genFunctionProto))
return false;
if (!LinkConstructorAndPrototype(cx, genFunctionProto, genObjectProto) ||
!DefineToStringTag(cx, genFunctionProto, cx->names().GeneratorFunction))
diff --git a/js/src/vm/GlobalObject.cpp b/js/src/vm/GlobalObject.cpp
index c90b6b85f..85707e1c6 100644
--- a/js/src/vm/GlobalObject.cpp
+++ b/js/src/vm/GlobalObject.cpp
@@ -329,15 +329,15 @@ GlobalObject::createInternal(JSContext* cx, const Class* clasp)
cx->compartment()->initGlobal(*global);
- if (!global->setQualifiedVarObj(cx))
+ if (!JSObject::setQualifiedVarObj(cx, global))
return nullptr;
- if (!global->setDelegate(cx))
+ if (!JSObject::setDelegate(cx, global))
return nullptr;
return global;
}
-GlobalObject*
+/* static */ GlobalObject*
GlobalObject::new_(JSContext* cx, const Class* clasp, JSPrincipals* principals,
JS::OnNewGlobalHookOption hookOption,
const JS::CompartmentOptions& options)
@@ -398,7 +398,7 @@ GlobalObject::emptyGlobalScope() const
GlobalObject::getOrCreateEval(JSContext* cx, Handle<GlobalObject*> global,
MutableHandleObject eval)
{
- if (!global->getOrCreateObjectPrototype(cx))
+ if (!getOrCreateObjectPrototype(cx, global))
return false;
eval.set(&global->getSlot(EVAL).toObject());
return true;
@@ -573,7 +573,7 @@ GlobalObject::warnOnceAbout(JSContext* cx, HandleObject obj, WarnOnceFlag flag,
return true;
}
-JSFunction*
+/* static */ JSFunction*
GlobalObject::createConstructor(JSContext* cx, Native ctor, JSAtom* nameArg, unsigned length,
gc::AllocKind kind, const JSJitInfo* jitInfo)
{
@@ -595,28 +595,27 @@ CreateBlankProto(JSContext* cx, const Class* clasp, HandleObject proto, HandleOb
RootedNativeObject blankProto(cx, NewNativeObjectWithGivenProto(cx, clasp, proto,
SingletonObject));
- if (!blankProto || !blankProto->setDelegate(cx))
+ if (!blankProto || !JSObject::setDelegate(cx, blankProto))
return nullptr;
return blankProto;
}
-NativeObject*
-GlobalObject::createBlankPrototype(JSContext* cx, const Class* clasp)
+/* static */ NativeObject*
+GlobalObject::createBlankPrototype(JSContext* cx, Handle<GlobalObject*> global, const Class* clasp)
{
- Rooted<GlobalObject*> self(cx, this);
- RootedObject objectProto(cx, getOrCreateObjectPrototype(cx));
+ RootedObject objectProto(cx, getOrCreateObjectPrototype(cx, global));
if (!objectProto)
return nullptr;
- return CreateBlankProto(cx, clasp, objectProto, self);
+ return CreateBlankProto(cx, clasp, objectProto, global);
}
-NativeObject*
-GlobalObject::createBlankPrototypeInheriting(JSContext* cx, const Class* clasp, HandleObject proto)
+/* static */ NativeObject*
+GlobalObject::createBlankPrototypeInheriting(JSContext* cx, Handle<GlobalObject*> global,
+ const Class* clasp, HandleObject proto)
{
- Rooted<GlobalObject*> self(cx, this);
- return CreateBlankProto(cx, clasp, proto, self);
+ return CreateBlankProto(cx, clasp, proto, global);
}
bool
@@ -729,21 +728,20 @@ GlobalObject::hasRegExpStatics() const
return !getSlot(REGEXP_STATICS).isUndefined();
}
-RegExpStatics*
-GlobalObject::getRegExpStatics(ExclusiveContext* cx) const
+/* static */ RegExpStatics*
+GlobalObject::getRegExpStatics(ExclusiveContext* cx, Handle<GlobalObject*> global)
{
MOZ_ASSERT(cx);
- Rooted<GlobalObject*> self(cx, const_cast<GlobalObject*>(this));
RegExpStaticsObject* resObj = nullptr;
- const Value& val = this->getSlot(REGEXP_STATICS);
+ const Value& val = global->getSlot(REGEXP_STATICS);
if (!val.isObject()) {
MOZ_ASSERT(val.isUndefined());
- resObj = RegExpStatics::create(cx, self);
+ resObj = RegExpStatics::create(cx, global);
if (!resObj)
return nullptr;
- self->initSlot(REGEXP_STATICS, ObjectValue(*resObj));
+ global->initSlot(REGEXP_STATICS, ObjectValue(*resObj));
} else {
resObj = &val.toObject().as<RegExpStaticsObject>();
}
@@ -866,7 +864,7 @@ GlobalObject::addIntrinsicValue(JSContext* cx, Handle<GlobalObject*> global,
/* static */ bool
GlobalObject::ensureModulePrototypesCreated(JSContext *cx, Handle<GlobalObject*> global)
{
- return global->getOrCreateObject(cx, MODULE_PROTO, initModuleProto) &&
- global->getOrCreateObject(cx, IMPORT_ENTRY_PROTO, initImportEntryProto) &&
- global->getOrCreateObject(cx, EXPORT_ENTRY_PROTO, initExportEntryProto);
+ return getOrCreateObject(cx, global, MODULE_PROTO, initModuleProto) &&
+ getOrCreateObject(cx, global, IMPORT_ENTRY_PROTO, initImportEntryProto) &&
+ getOrCreateObject(cx, global, EXPORT_ENTRY_PROTO, initExportEntryProto);
}
diff --git a/js/src/vm/GlobalObject.h b/js/src/vm/GlobalObject.h
index 3534ef2f6..5aacfc5dc 100644
--- a/js/src/vm/GlobalObject.h
+++ b/js/src/vm/GlobalObject.h
@@ -290,8 +290,8 @@ class GlobalObject : public NativeObject
* Create a constructor function with the specified name and length using
* ctor, a method which creates objects with the given class.
*/
- JSFunction*
- createConstructor(JSContext* cx, JSNative ctor, JSAtom* name, unsigned length,
+ static JSFunction*
+ createConstructor(JSContext* cx, JSNative ctor, JSAtom* name, unsigned length,
gc::AllocKind kind = gc::AllocKind::FUNCTION,
const JSJitInfo* jitInfo = nullptr);
@@ -303,48 +303,44 @@ class GlobalObject : public NativeObject
* complete the minimal initialization to make the returned object safe to
* touch.
*/
- NativeObject* createBlankPrototype(JSContext* cx, const js::Class* clasp);
+ static NativeObject*
+ createBlankPrototype(JSContext* cx, Handle<GlobalObject*> global, const js::Class* clasp);
/*
* Identical to createBlankPrototype, but uses proto as the [[Prototype]]
* of the returned blank prototype.
*/
- NativeObject* createBlankPrototypeInheriting(JSContext* cx, const js::Class* clasp,
- HandleObject proto);
+ static NativeObject*
+ createBlankPrototypeInheriting(JSContext* cx, Handle<GlobalObject*> global,
+ const js::Class* clasp, HandleObject proto);
template <typename T>
- T* createBlankPrototype(JSContext* cx) {
- NativeObject* res = createBlankPrototype(cx, &T::class_);
+ static T*
+ createBlankPrototype(JSContext* cx, Handle<GlobalObject*> global) {
+ NativeObject* res = createBlankPrototype(cx, global, &T::class_);
return res ? &res->template as<T>() : nullptr;
}
- NativeObject* getOrCreateObjectPrototype(JSContext* cx) {
- if (functionObjectClassesInitialized())
- return &getPrototype(JSProto_Object).toObject().as<NativeObject>();
- RootedGlobalObject self(cx, this);
- if (!ensureConstructor(cx, self, JSProto_Object))
+ static NativeObject*
+ getOrCreateObjectPrototype(JSContext* cx, Handle<GlobalObject*> global) {
+ if (global->functionObjectClassesInitialized())
+ return &global->getPrototype(JSProto_Object).toObject().as<NativeObject>();
+ if (!ensureConstructor(cx, global, JSProto_Object))
return nullptr;
- return &self->getPrototype(JSProto_Object).toObject().as<NativeObject>();
- }
-
- static NativeObject* getOrCreateObjectPrototype(JSContext* cx, Handle<GlobalObject*> global) {
- return global->getOrCreateObjectPrototype(cx);
+ return &global->getPrototype(JSProto_Object).toObject().as<NativeObject>();
}
- NativeObject* getOrCreateFunctionPrototype(JSContext* cx) {
- if (functionObjectClassesInitialized())
- return &getPrototype(JSProto_Function).toObject().as<NativeObject>();
- RootedGlobalObject self(cx, this);
- if (!ensureConstructor(cx, self, JSProto_Object))
+ static NativeObject*
+ getOrCreateFunctionPrototype(JSContext* cx, Handle<GlobalObject*> global) {
+ if (global->functionObjectClassesInitialized())
+ return &global->getPrototype(JSProto_Function).toObject().as<NativeObject>();
+ if (!ensureConstructor(cx, global, JSProto_Object))
return nullptr;
- return &self->getPrototype(JSProto_Function).toObject().as<NativeObject>();
- }
-
- static NativeObject* getOrCreateFunctionPrototype(JSContext* cx, Handle<GlobalObject*> global) {
- return global->getOrCreateFunctionPrototype(cx);
+ return &global->getPrototype(JSProto_Function).toObject().as<NativeObject>();
}
- static NativeObject* getOrCreateArrayPrototype(JSContext* cx, Handle<GlobalObject*> global) {
+ static NativeObject*
+ getOrCreateArrayPrototype(JSContext* cx, Handle<GlobalObject*> global) {
if (!ensureConstructor(cx, global, JSProto_Array))
return nullptr;
return &global->getPrototype(JSProto_Array).toObject().as<NativeObject>();
@@ -356,37 +352,43 @@ class GlobalObject : public NativeObject
return nullptr;
}
- static NativeObject* getOrCreateBooleanPrototype(JSContext* cx, Handle<GlobalObject*> global) {
+ static NativeObject*
+ getOrCreateBooleanPrototype(JSContext* cx, Handle<GlobalObject*> global) {
if (!ensureConstructor(cx, global, JSProto_Boolean))
return nullptr;
return &global->getPrototype(JSProto_Boolean).toObject().as<NativeObject>();
}
- static NativeObject* getOrCreateNumberPrototype(JSContext* cx, Handle<GlobalObject*> global) {
+ static NativeObject*
+ getOrCreateNumberPrototype(JSContext* cx, Handle<GlobalObject*> global) {
if (!ensureConstructor(cx, global, JSProto_Number))
return nullptr;
return &global->getPrototype(JSProto_Number).toObject().as<NativeObject>();
}
- static NativeObject* getOrCreateStringPrototype(JSContext* cx, Handle<GlobalObject*> global) {
+ static NativeObject*
+ getOrCreateStringPrototype(JSContext* cx, Handle<GlobalObject*> global) {
if (!ensureConstructor(cx, global, JSProto_String))
return nullptr;
return &global->getPrototype(JSProto_String).toObject().as<NativeObject>();
}
- static NativeObject* getOrCreateSymbolPrototype(JSContext* cx, Handle<GlobalObject*> global) {
+ static NativeObject*
+ getOrCreateSymbolPrototype(JSContext* cx, Handle<GlobalObject*> global) {
if (!ensureConstructor(cx, global, JSProto_Symbol))
return nullptr;
return &global->getPrototype(JSProto_Symbol).toObject().as<NativeObject>();
}
- static NativeObject* getOrCreatePromisePrototype(JSContext* cx, Handle<GlobalObject*> global) {
+ static NativeObject*
+ getOrCreatePromisePrototype(JSContext* cx, Handle<GlobalObject*> global) {
if (!ensureConstructor(cx, global, JSProto_Promise))
return nullptr;
return &global->getPrototype(JSProto_Promise).toObject().as<NativeObject>();
}
- static NativeObject* getOrCreateRegExpPrototype(JSContext* cx, Handle<GlobalObject*> global) {
+ static NativeObject*
+ getOrCreateRegExpPrototype(JSContext* cx, Handle<GlobalObject*> global) {
if (!ensureConstructor(cx, global, JSProto_RegExp))
return nullptr;
return &global->getPrototype(JSProto_RegExp).toObject().as<NativeObject>();
@@ -398,28 +400,30 @@ class GlobalObject : public NativeObject
return nullptr;
}
- static NativeObject* getOrCreateSavedFramePrototype(JSContext* cx,
- Handle<GlobalObject*> global) {
+ static NativeObject*
+ getOrCreateSavedFramePrototype(JSContext* cx, Handle<GlobalObject*> global) {
if (!ensureConstructor(cx, global, JSProto_SavedFrame))
return nullptr;
return &global->getPrototype(JSProto_SavedFrame).toObject().as<NativeObject>();
}
- static JSObject* getOrCreateArrayBufferPrototype(JSContext* cx, Handle<GlobalObject*> global) {
+ static JSObject*
+ getOrCreateArrayBufferPrototype(JSContext* cx, Handle<GlobalObject*> global) {
if (!ensureConstructor(cx, global, JSProto_ArrayBuffer))
return nullptr;
return &global->getPrototype(JSProto_ArrayBuffer).toObject();
}
- JSObject* getOrCreateSharedArrayBufferPrototype(JSContext* cx, Handle<GlobalObject*> global) {
+ static JSObject*
+ getOrCreateSharedArrayBufferPrototype(JSContext* cx, Handle<GlobalObject*> global) {
if (!ensureConstructor(cx, global, JSProto_SharedArrayBuffer))
return nullptr;
return &global->getPrototype(JSProto_SharedArrayBuffer).toObject();
}
- static JSObject* getOrCreateCustomErrorPrototype(JSContext* cx,
- Handle<GlobalObject*> global,
- JSExnType exnType)
+ static JSObject*
+ getOrCreateCustomErrorPrototype(JSContext* cx, Handle<GlobalObject*> global,
+ JSExnType exnType)
{
JSProtoKey key = GetExceptionProtoKey(exnType);
if (!ensureConstructor(cx, global, key))
@@ -439,35 +443,41 @@ class GlobalObject : public NativeObject
return getOrCreateCustomErrorPrototype(cx, global, JSEXN_ERR);
}
- static NativeObject* getOrCreateSetPrototype(JSContext* cx, Handle<GlobalObject*> global) {
+ static NativeObject*
+ getOrCreateSetPrototype(JSContext* cx, Handle<GlobalObject*> global) {
if (!ensureConstructor(cx, global, JSProto_Set))
return nullptr;
return &global->getPrototype(JSProto_Set).toObject().as<NativeObject>();
}
- static NativeObject* getOrCreateWeakSetPrototype(JSContext* cx, Handle<GlobalObject*> global) {
+ static NativeObject*
+ getOrCreateWeakSetPrototype(JSContext* cx, Handle<GlobalObject*> global) {
if (!ensureConstructor(cx, global, JSProto_WeakSet))
return nullptr;
return &global->getPrototype(JSProto_WeakSet).toObject().as<NativeObject>();
}
- JSObject* getOrCreateIntlObject(JSContext* cx) {
- return getOrCreateObject(cx, APPLICATION_SLOTS + JSProto_Intl, initIntlObject);
+ static JSObject*
+ getOrCreateIntlObject(JSContext* cx, Handle<GlobalObject*> global) {
+ return getOrCreateObject(cx, global, APPLICATION_SLOTS + JSProto_Intl, initIntlObject);
}
- JSObject* getOrCreateTypedObjectModule(JSContext* cx) {
- return getOrCreateObject(cx, APPLICATION_SLOTS + JSProto_TypedObject, initTypedObjectModule);
+ static JSObject*
+ getOrCreateTypedObjectModule(JSContext* cx, Handle<GlobalObject*> global) {
+ return getOrCreateObject(cx, global, APPLICATION_SLOTS + JSProto_TypedObject,
+ initTypedObjectModule);
}
- JSObject* getOrCreateSimdGlobalObject(JSContext* cx) {
- return getOrCreateObject(cx, APPLICATION_SLOTS + JSProto_SIMD, initSimdObject);
+ static JSObject*
+ getOrCreateSimdGlobalObject(JSContext* cx, Handle<GlobalObject*> global) {
+ return getOrCreateObject(cx, global, APPLICATION_SLOTS + JSProto_SIMD, initSimdObject);
}
// Get the type descriptor for one of the SIMD types.
// simdType is one of the JS_SIMDTYPEREPR_* constants.
// Implemented in builtin/SIMD.cpp.
- static SimdTypeDescr* getOrCreateSimdTypeDescr(JSContext* cx, Handle<GlobalObject*> global,
- SimdType simdType);
+ static SimdTypeDescr*
+ getOrCreateSimdTypeDescr(JSContext* cx, Handle<GlobalObject*> global, SimdType simdType);
TypedObjectModuleObject& getTypedObjectModule() const;
@@ -475,16 +485,19 @@ class GlobalObject : public NativeObject
return &getPrototype(JSProto_Iterator).toObject();
}
- JSObject* getOrCreateCollatorPrototype(JSContext* cx) {
- return getOrCreateObject(cx, COLLATOR_PROTO, initIntlObject);
+ static JSObject*
+ getOrCreateCollatorPrototype(JSContext* cx, Handle<GlobalObject*> global) {
+ return getOrCreateObject(cx, global, COLLATOR_PROTO, initIntlObject);
}
- JSObject* getOrCreateNumberFormatPrototype(JSContext* cx) {
- return getOrCreateObject(cx, NUMBER_FORMAT_PROTO, initIntlObject);
+ static JSObject*
+ getOrCreateNumberFormatPrototype(JSContext* cx, Handle<GlobalObject*> global) {
+ return getOrCreateObject(cx, global, NUMBER_FORMAT_PROTO, initIntlObject);
}
- JSObject* getOrCreateDateTimeFormatPrototype(JSContext* cx) {
- return getOrCreateObject(cx, DATE_TIME_FORMAT_PROTO, initIntlObject);
+ static JSObject*
+ getOrCreateDateTimeFormatPrototype(JSContext* cx, Handle<GlobalObject*> global) {
+ return getOrCreateObject(cx, global, DATE_TIME_FORMAT_PROTO, initIntlObject);
}
static bool ensureModulePrototypesCreated(JSContext *cx, Handle<GlobalObject*> global);
@@ -539,88 +552,86 @@ class GlobalObject : public NativeObject
private:
typedef bool (*ObjectInitOp)(JSContext* cx, Handle<GlobalObject*> global);
- JSObject* getOrCreateObject(JSContext* cx, unsigned slot, ObjectInitOp init) {
- Value v = getSlotRef(slot);
+ static JSObject*
+ getOrCreateObject(JSContext* cx, Handle<GlobalObject*> global, unsigned slot,
+ ObjectInitOp init)
+ {
+ Value v = global->getSlotRef(slot);
if (v.isObject())
return &v.toObject();
- RootedGlobalObject self(cx, this);
- if (!init(cx, self))
+ if (!init(cx, global))
return nullptr;
- return &self->getSlot(slot).toObject();
+ return &global->getSlot(slot).toObject();
}
public:
- static NativeObject* getOrCreateIteratorPrototype(JSContext* cx, Handle<GlobalObject*> global)
- {
- return MaybeNativeObject(global->getOrCreateObject(cx, ITERATOR_PROTO, initIteratorProto));
+ static NativeObject*
+ getOrCreateIteratorPrototype(JSContext* cx, Handle<GlobalObject*> global) {
+ return MaybeNativeObject(getOrCreateObject(cx, global, ITERATOR_PROTO, initIteratorProto));
}
- static NativeObject* getOrCreateArrayIteratorPrototype(JSContext* cx, Handle<GlobalObject*> global)
- {
- return MaybeNativeObject(global->getOrCreateObject(cx, ARRAY_ITERATOR_PROTO, initArrayIteratorProto));
+ static NativeObject*
+ getOrCreateArrayIteratorPrototype(JSContext* cx, Handle<GlobalObject*> global) {
+ return MaybeNativeObject(getOrCreateObject(cx, global, ARRAY_ITERATOR_PROTO,
+ initArrayIteratorProto));
}
- static NativeObject* getOrCreateStringIteratorPrototype(JSContext* cx,
- Handle<GlobalObject*> global)
- {
- return MaybeNativeObject(global->getOrCreateObject(cx, STRING_ITERATOR_PROTO, initStringIteratorProto));
+ static NativeObject*
+ getOrCreateStringIteratorPrototype(JSContext* cx, Handle<GlobalObject*> global) {
+ return MaybeNativeObject(getOrCreateObject(cx, global, STRING_ITERATOR_PROTO,
+ initStringIteratorProto));
}
- static NativeObject* getOrCreateLegacyGeneratorObjectPrototype(JSContext* cx,
- Handle<GlobalObject*> global)
- {
- return MaybeNativeObject(global->getOrCreateObject(cx, LEGACY_GENERATOR_OBJECT_PROTO,
- initLegacyGeneratorProto));
+ static NativeObject*
+ getOrCreateLegacyGeneratorObjectPrototype(JSContext* cx, Handle<GlobalObject*> global) {
+ return MaybeNativeObject(getOrCreateObject(cx, global, LEGACY_GENERATOR_OBJECT_PROTO,
+ initLegacyGeneratorProto));
}
- static NativeObject* getOrCreateStarGeneratorObjectPrototype(JSContext* cx,
- Handle<GlobalObject*> global)
+ static NativeObject*
+ getOrCreateStarGeneratorObjectPrototype(JSContext* cx, Handle<GlobalObject*> global)
{
- return MaybeNativeObject(global->getOrCreateObject(cx, STAR_GENERATOR_OBJECT_PROTO, initStarGenerators));
+ return MaybeNativeObject(getOrCreateObject(cx, global, STAR_GENERATOR_OBJECT_PROTO,
+ initStarGenerators));
}
- static NativeObject* getOrCreateStarGeneratorFunctionPrototype(JSContext* cx,
- Handle<GlobalObject*> global)
- {
- return MaybeNativeObject(global->getOrCreateObject(cx, STAR_GENERATOR_FUNCTION_PROTO, initStarGenerators));
+ static NativeObject*
+ getOrCreateStarGeneratorFunctionPrototype(JSContext* cx, Handle<GlobalObject*> global) {
+ return MaybeNativeObject(getOrCreateObject(cx, global, STAR_GENERATOR_FUNCTION_PROTO,
+ initStarGenerators));
}
- static JSObject* getOrCreateStarGeneratorFunction(JSContext* cx,
- Handle<GlobalObject*> global)
- {
- return global->getOrCreateObject(cx, STAR_GENERATOR_FUNCTION, initStarGenerators);
+ static JSObject*
+ getOrCreateStarGeneratorFunction(JSContext* cx, Handle<GlobalObject*> global) {
+ return getOrCreateObject(cx, global, STAR_GENERATOR_FUNCTION, initStarGenerators);
}
- static NativeObject* getOrCreateAsyncFunctionPrototype(JSContext* cx,
- Handle<GlobalObject*> global)
- {
- return MaybeNativeObject(global->getOrCreateObject(cx, ASYNC_FUNCTION_PROTO,
- initAsyncFunction));
+ static NativeObject*
+ getOrCreateAsyncFunctionPrototype(JSContext* cx, Handle<GlobalObject*> global) {
+ return MaybeNativeObject(getOrCreateObject(cx, global, ASYNC_FUNCTION_PROTO,
+ initAsyncFunction));
}
- static JSObject* getOrCreateAsyncFunction(JSContext* cx,
- Handle<GlobalObject*> global)
- {
- return global->getOrCreateObject(cx, ASYNC_FUNCTION, initAsyncFunction);
+ static JSObject*
+ getOrCreateAsyncFunction(JSContext* cx, Handle<GlobalObject*> global) {
+ return getOrCreateObject(cx, global, ASYNC_FUNCTION, initAsyncFunction);
}
- static JSObject* getOrCreateMapIteratorPrototype(JSContext* cx,
- Handle<GlobalObject*> global)
- {
- return global->getOrCreateObject(cx, MAP_ITERATOR_PROTO, initMapIteratorProto);
+ static JSObject*
+ getOrCreateMapIteratorPrototype(JSContext* cx, Handle<GlobalObject*> global) {
+ return getOrCreateObject(cx, global, MAP_ITERATOR_PROTO, initMapIteratorProto);
}
- static JSObject* getOrCreateSetIteratorPrototype(JSContext* cx,
- Handle<GlobalObject*> global)
- {
- return global->getOrCreateObject(cx, SET_ITERATOR_PROTO, initSetIteratorProto);
+ static JSObject*
+ getOrCreateSetIteratorPrototype(JSContext* cx, Handle<GlobalObject*> global) {
+ return getOrCreateObject(cx, global, SET_ITERATOR_PROTO, initSetIteratorProto);
}
- JSObject* getOrCreateDataViewPrototype(JSContext* cx) {
- RootedGlobalObject self(cx, this);
- if (!ensureConstructor(cx, self, JSProto_DataView))
+ static JSObject*
+ getOrCreateDataViewPrototype(JSContext* cx, Handle<GlobalObject*> global) {
+ if (!ensureConstructor(cx, global, JSProto_DataView))
return nullptr;
- return &self->getPrototype(JSProto_DataView).toObject();
+ return &global->getPrototype(JSProto_DataView).toObject();
}
static JSFunction*
@@ -678,8 +689,9 @@ class GlobalObject : public NativeObject
return true;
}
- static bool getIntrinsicValue(JSContext* cx, Handle<GlobalObject*> global,
- HandlePropertyName name, MutableHandleValue value)
+ static bool
+ getIntrinsicValue(JSContext* cx, Handle<GlobalObject*> global,
+ HandlePropertyName name, MutableHandleValue value)
{
bool exists = false;
if (!GlobalObject::maybeGetIntrinsicValue(cx, global, name, value, &exists))
@@ -709,7 +721,8 @@ class GlobalObject : public NativeObject
unsigned nargs, MutableHandleValue funVal);
bool hasRegExpStatics() const;
- RegExpStatics* getRegExpStatics(ExclusiveContext* cx) const;
+ static RegExpStatics* getRegExpStatics(ExclusiveContext* cx,
+ Handle<GlobalObject*> global);
RegExpStatics* getAlreadyCreatedRegExpStatics() const;
JSObject* getThrowTypeError() const {
@@ -996,7 +1009,7 @@ GenericCreateConstructor(JSContext* cx, JSProtoKey key)
// Note - We duplicate the trick from ClassName() so that we don't need to
// include jsatominlines.h here.
PropertyName* name = (&cx->names().Null)[key];
- return cx->global()->createConstructor(cx, ctor, name, length, kind, jitInfo);
+ return GlobalObject::createConstructor(cx, ctor, name, length, kind, jitInfo);
}
inline JSObject*
@@ -1009,7 +1022,7 @@ GenericCreatePrototype(JSContext* cx, JSProtoKey key)
if (!GlobalObject::ensureConstructor(cx, cx->global(), protoKey))
return nullptr;
RootedObject parentProto(cx, &cx->global()->getPrototype(protoKey).toObject());
- return cx->global()->createBlankPrototypeInheriting(cx, clasp, parentProto);
+ return GlobalObject::createBlankPrototypeInheriting(cx, cx->global(), clasp, parentProto);
}
inline JSProtoKey
diff --git a/js/src/vm/HelperThreads.cpp b/js/src/vm/HelperThreads.cpp
index bd29d0c79..44915521f 100644
--- a/js/src/vm/HelperThreads.cpp
+++ b/js/src/vm/HelperThreads.cpp
@@ -1291,7 +1291,7 @@ GlobalHelperThreadState::finishModuleParseTask(JSContext* cx, void* token)
MOZ_ASSERT(script->module());
RootedModuleObject module(cx, script->module());
- module->fixEnvironmentsAfterCompartmentMerge(cx);
+ module->fixEnvironmentsAfterCompartmentMerge();
if (!ModuleObject::Freeze(cx, module))
return nullptr;
diff --git a/js/src/vm/Interpreter-inl.h b/js/src/vm/Interpreter-inl.h
index a2c8e220a..acfa8f74b 100644
--- a/js/src/vm/Interpreter-inl.h
+++ b/js/src/vm/Interpreter-inl.h
@@ -830,7 +830,7 @@ class FastCallGuard
if (useIon_ && fun_) {
if (!script_) {
- script_ = fun_->getOrCreateScript(cx);
+ script_ = JSFunction::getOrCreateScript(cx, fun_);
if (!script_)
return false;
}
diff --git a/js/src/vm/Interpreter.cpp b/js/src/vm/Interpreter.cpp
index 0f83c3435..030f0f3b6 100644
--- a/js/src/vm/Interpreter.cpp
+++ b/js/src/vm/Interpreter.cpp
@@ -261,11 +261,16 @@ SetPropertyOperation(JSContext* cx, JSOp op, HandleValue lval, HandleId id, Hand
}
static JSFunction*
-MakeDefaultConstructor(JSContext* cx, JSOp op, JSAtom* atom, HandleObject proto)
+MakeDefaultConstructor(JSContext* cx, HandleScript script, jsbytecode* pc, HandleObject proto)
{
+ JSOp op = JSOp(*pc);
+ JSAtom* atom = script->getAtom(pc);
bool derived = op == JSOP_DERIVEDCONSTRUCTOR;
MOZ_ASSERT(derived == !!proto);
+ jssrcnote* classNote = GetSrcNote(cx, script, pc);
+ MOZ_ASSERT(classNote && SN_TYPE(classNote) == SRC_CLASS_SPAN);
+
PropertyName* lookup = derived ? cx->names().DefaultDerivedClassConstructor
: cx->names().DefaultBaseClassConstructor;
@@ -285,6 +290,17 @@ MakeDefaultConstructor(JSContext* cx, JSOp op, JSAtom* atom, HandleObject proto)
MOZ_ASSERT(ctor->infallibleIsDefaultClassConstructor(cx));
+ // Create the script now, as the source span needs to be overridden for
+ // toString. Calling toString on a class constructor must not return the
+ // source for just the constructor function.
+ JSScript *ctorScript = JSFunction::getOrCreateScript(cx, ctor);
+ if (!ctorScript)
+ return nullptr;
+ uint32_t classStartOffset = GetSrcNoteOffset(classNote, 0);
+ uint32_t classEndOffset = GetSrcNoteOffset(classNote, 1);
+ ctorScript->setDefaultClassConstructorSpan(script->sourceObject(), classStartOffset,
+ classEndOffset);
+
return ctor;
}
@@ -373,7 +389,7 @@ js::RunScript(JSContext* cx, RunState& state)
SPSEntryMarker marker(cx->runtime(), state.script());
- state.script()->ensureNonLazyCanonicalFunction(cx);
+ state.script()->ensureNonLazyCanonicalFunction();
if (jit::IsIonEnabled(cx)) {
jit::MethodStatus status = jit::CanEnter(cx, state);
@@ -446,7 +462,7 @@ js::InternalCallOrConstruct(JSContext* cx, const CallArgs& args, MaybeConstruct
}
/* Invoke native functions. */
- JSFunction* fun = &args.callee().as<JSFunction>();
+ RootedFunction fun(cx, &args.callee().as<JSFunction>());
if (construct != CONSTRUCT && fun->isClassConstructor()) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_CANT_CALL_CLASS_CONSTRUCTOR);
return false;
@@ -454,10 +470,16 @@ js::InternalCallOrConstruct(JSContext* cx, const CallArgs& args, MaybeConstruct
if (fun->isNative()) {
MOZ_ASSERT_IF(construct, !fun->isConstructor());
- return CallJSNative(cx, fun->native(), args);
+ JSNative native = fun->native();
+ if (!construct && args.ignoresReturnValue()) {
+ const JSJitInfo* jitInfo = fun->jitInfo();
+ if (jitInfo && jitInfo->type() == JSJitInfo::IgnoresReturnValueNative)
+ native = jitInfo->ignoresReturnValueMethod;
+ }
+ return CallJSNative(cx, native, args);
}
- if (!fun->getOrCreateScript(cx))
+ if (!JSFunction::getOrCreateScript(cx, fun))
return false;
/* Run function until JSOP_RETRVAL, JSOP_RETURN or error. */
@@ -1543,7 +1565,7 @@ SetObjectElementOperation(JSContext* cx, HandleObject obj, HandleId id, HandleVa
}
}
- if (obj->isNative() && !JSID_IS_INT(id) && !obj->setHadElementsAccess(cx))
+ if (obj->isNative() && !JSID_IS_INT(id) && !JSObject::setHadElementsAccess(cx, obj))
return false;
ObjectOpResult result;
@@ -2959,6 +2981,7 @@ CASE(JSOP_FUNAPPLY)
CASE(JSOP_NEW)
CASE(JSOP_CALL)
+CASE(JSOP_CALL_IGNORES_RV)
CASE(JSOP_CALLITER)
CASE(JSOP_SUPERCALL)
CASE(JSOP_FUNCALL)
@@ -2967,10 +2990,11 @@ CASE(JSOP_FUNCALL)
cx->runtime()->spsProfiler.updatePC(script, REGS.pc);
MaybeConstruct construct = MaybeConstruct(*REGS.pc == JSOP_NEW || *REGS.pc == JSOP_SUPERCALL);
+ bool ignoresReturnValue = *REGS.pc == JSOP_CALL_IGNORES_RV;
unsigned argStackSlots = GET_ARGC(REGS.pc) + construct;
MOZ_ASSERT(REGS.stackDepth() >= 2u + GET_ARGC(REGS.pc));
- CallArgs args = CallArgsFromSp(argStackSlots, REGS.sp, construct);
+ CallArgs args = CallArgsFromSp(argStackSlots, REGS.sp, construct, ignoresReturnValue);
JSFunction* maybeFun;
bool isFunction = IsFunctionObject(args.calleev(), &maybeFun);
@@ -3000,7 +3024,7 @@ CASE(JSOP_FUNCALL)
{
MOZ_ASSERT(maybeFun);
ReservedRooted<JSFunction*> fun(&rootFunction0, maybeFun);
- ReservedRooted<JSScript*> funScript(&rootScript0, fun->getOrCreateScript(cx));
+ ReservedRooted<JSScript*> funScript(&rootScript0, JSFunction::getOrCreateScript(cx, fun));
if (!funScript)
goto error;
@@ -4174,8 +4198,8 @@ CASE(JSOP_DERIVEDCONSTRUCTOR)
MOZ_ASSERT(REGS.sp[-1].isObject());
ReservedRooted<JSObject*> proto(&rootObject0, &REGS.sp[-1].toObject());
- JSFunction* constructor = MakeDefaultConstructor(cx, JSOp(*REGS.pc), script->getAtom(REGS.pc),
- proto);
+ JSFunction* constructor = MakeDefaultConstructor(cx, script, REGS.pc, proto);
+
if (!constructor)
goto error;
@@ -4185,8 +4209,7 @@ END_CASE(JSOP_DERIVEDCONSTRUCTOR)
CASE(JSOP_CLASSCONSTRUCTOR)
{
- JSFunction* constructor = MakeDefaultConstructor(cx, JSOp(*REGS.pc), script->getAtom(REGS.pc),
- nullptr);
+ JSFunction* constructor = MakeDefaultConstructor(cx, script, REGS.pc, nullptr);
if (!constructor)
goto error;
PUSH_OBJECT(*constructor);
@@ -4725,7 +4748,8 @@ js::RunOnceScriptPrologue(JSContext* cx, HandleScript script)
// Force instantiation of the script's function's group to ensure the flag
// is preserved in type information.
- if (!script->functionNonDelazifying()->getGroup(cx))
+ RootedFunction fun(cx, script->functionNonDelazifying());
+ if (!JSObject::getGroup(cx, fun))
return false;
MarkObjectGroupFlags(cx, script->functionNonDelazifying(), OBJECT_FLAG_RUNONCE_INVALIDATED);
diff --git a/js/src/vm/Keywords.h b/js/src/vm/Keywords.h
deleted file mode 100644
index ef37c4419..000000000
--- a/js/src/vm/Keywords.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * vim: set ts=8 sts=4 et sw=4 tw=99:
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/* A higher-order macro for enumerating keyword tokens. */
-
-#ifndef vm_Keywords_h
-#define vm_Keywords_h
-
-#define FOR_EACH_JAVASCRIPT_KEYWORD(macro) \
- macro(false, false_, TOK_FALSE) \
- macro(true, true_, TOK_TRUE) \
- macro(null, null, TOK_NULL) \
- /* Keywords. */ \
- macro(break, break_, TOK_BREAK) \
- macro(case, case_, TOK_CASE) \
- macro(catch, catch_, TOK_CATCH) \
- macro(const, const_, TOK_CONST) \
- macro(continue, continue_, TOK_CONTINUE) \
- macro(debugger, debugger, TOK_DEBUGGER) \
- macro(default, default_, TOK_DEFAULT) \
- macro(delete, delete_, TOK_DELETE) \
- macro(do, do_, TOK_DO) \
- macro(else, else_, TOK_ELSE) \
- macro(finally, finally_, TOK_FINALLY) \
- macro(for, for_, TOK_FOR) \
- macro(function, function, TOK_FUNCTION) \
- macro(if, if_, TOK_IF) \
- macro(in, in, TOK_IN) \
- macro(instanceof, instanceof, TOK_INSTANCEOF) \
- macro(new, new_, TOK_NEW) \
- macro(return, return_, TOK_RETURN) \
- macro(switch, switch_, TOK_SWITCH) \
- macro(this, this_, TOK_THIS) \
- macro(throw, throw_, TOK_THROW) \
- macro(try, try_, TOK_TRY) \
- macro(typeof, typeof, TOK_TYPEOF) \
- macro(var, var, TOK_VAR) \
- macro(void, void_, TOK_VOID) \
- macro(while, while_, TOK_WHILE) \
- macro(with, with, TOK_WITH) \
- macro(import, import, TOK_IMPORT) \
- macro(export, export, TOK_EXPORT) \
- macro(class, class_, TOK_CLASS) \
- macro(extends, extends, TOK_EXTENDS) \
- macro(super, super, TOK_SUPER) \
- /* Reserved keywords. */ \
- macro(enum, enum_, TOK_RESERVED) \
- /* Future reserved keywords, but only in strict mode. */ \
- macro(implements, implements, TOK_STRICT_RESERVED) \
- macro(interface, interface, TOK_STRICT_RESERVED) \
- macro(package, package, TOK_STRICT_RESERVED) \
- macro(private, private_, TOK_STRICT_RESERVED) \
- macro(protected, protected_, TOK_STRICT_RESERVED) \
- macro(public, public_, TOK_STRICT_RESERVED) \
- macro(await, await, TOK_AWAIT) \
- /* \
- * Yield is a token inside function*. Outside of a function*, it is a \
- * future reserved keyword in strict mode, but a keyword in JS1.7 even \
- * when strict. Punt logic to parser. \
- */ \
- macro(yield, yield, TOK_YIELD)
-
-#endif /* vm_Keywords_h */
diff --git a/js/src/vm/NativeObject-inl.h b/js/src/vm/NativeObject-inl.h
index 052a3385c..e55e3db04 100644
--- a/js/src/vm/NativeObject-inl.h
+++ b/js/src/vm/NativeObject-inl.h
@@ -236,7 +236,7 @@ NativeObject::ensureDenseElements(ExclusiveContext* cx, uint32_t index, uint32_t
}
inline DenseElementResult
-NativeObject::setOrExtendDenseElements(JSContext* cx, uint32_t start, const Value* vp,
+NativeObject::setOrExtendDenseElements(ExclusiveContext* cx, uint32_t start, const Value* vp,
uint32_t count,
ShouldUpdateTypes updateTypes)
{
diff --git a/js/src/vm/NativeObject.cpp b/js/src/vm/NativeObject.cpp
index a3f28653a..da0f59fe2 100644
--- a/js/src/vm/NativeObject.cpp
+++ b/js/src/vm/NativeObject.cpp
@@ -672,10 +672,10 @@ NativeObject::maybeDensifySparseElements(js::ExclusiveContext* cx, HandleNativeO
*/
if (shape != obj->lastProperty()) {
shape = shape->previous();
- if (!obj->removeProperty(cx, id))
+ if (!NativeObject::removeProperty(cx, obj, id))
return DenseElementResult::Failure;
} else {
- if (!obj->removeProperty(cx, id))
+ if (!NativeObject::removeProperty(cx, obj, id))
return DenseElementResult::Failure;
shape = obj->lastProperty();
}
@@ -691,7 +691,7 @@ NativeObject::maybeDensifySparseElements(js::ExclusiveContext* cx, HandleNativeO
* flag so that we will not start using sparse indexes again if we need
* to grow the object.
*/
- if (!obj->clearFlag(cx, BaseShape::INDEXED))
+ if (!NativeObject::clearFlag(cx, obj, BaseShape::INDEXED))
return DenseElementResult::Failure;
return DenseElementResult::Success;
@@ -996,23 +996,22 @@ NativeObject::freeSlot(ExclusiveContext* cx, uint32_t slot)
setSlot(slot, UndefinedValue());
}
-Shape*
-NativeObject::addDataProperty(ExclusiveContext* cx, jsid idArg, uint32_t slot, unsigned attrs)
+/* static */ Shape*
+NativeObject::addDataProperty(ExclusiveContext* cx, HandleNativeObject obj,
+ jsid idArg, uint32_t slot, unsigned attrs)
{
MOZ_ASSERT(!(attrs & (JSPROP_GETTER | JSPROP_SETTER)));
- RootedNativeObject self(cx, this);
RootedId id(cx, idArg);
- return addProperty(cx, self, id, nullptr, nullptr, slot, attrs, 0);
+ return addProperty(cx, obj, id, nullptr, nullptr, slot, attrs, 0);
}
-Shape*
-NativeObject::addDataProperty(ExclusiveContext* cx, HandlePropertyName name,
- uint32_t slot, unsigned attrs)
+/* static */ Shape*
+NativeObject::addDataProperty(ExclusiveContext* cx, HandleNativeObject obj,
+ HandlePropertyName name, uint32_t slot, unsigned attrs)
{
MOZ_ASSERT(!(attrs & (JSPROP_GETTER | JSPROP_SETTER)));
- RootedNativeObject self(cx, this);
RootedId id(cx, NameToId(name));
- return addProperty(cx, self, id, nullptr, nullptr, slot, attrs, 0);
+ return addProperty(cx, obj, id, nullptr, nullptr, slot, attrs, 0);
}
template <AllowGC allowGC>
@@ -1046,7 +1045,7 @@ CallAddPropertyHook(ExclusiveContext* cx, HandleNativeObject obj, HandleShape sh
RootedId id(cx, shape->propid());
if (!CallJSAddPropertyOp(cx->asJSContext(), addProperty, obj, id, value)) {
- obj->removeProperty(cx, shape->propid());
+ NativeObject::removeProperty(cx, obj, shape->propid());
return false;
}
}
@@ -1118,7 +1117,7 @@ PurgeProtoChain(ExclusiveContext* cx, JSObject* objArg, HandleId id)
shape = obj->as<NativeObject>().lookup(cx, id);
if (shape)
- return obj->as<NativeObject>().shadowingShapeChange(cx, *shape);
+ return NativeObject::shadowingShapeChange(cx, obj.as<NativeObject>(), *shape);
obj = obj->staticPrototype();
}
@@ -2529,7 +2528,7 @@ js::NativeDeleteProperty(JSContext* cx, HandleNativeObject obj, HandleId id,
obj->setDenseElementHole(cx, JSID_TO_INT(id));
} else {
- if (!obj->removeProperty(cx, id))
+ if (!NativeObject::removeProperty(cx, obj, id))
return false;
}
diff --git a/js/src/vm/NativeObject.h b/js/src/vm/NativeObject.h
index d9d8b8aec..9cc6d5436 100644
--- a/js/src/vm/NativeObject.h
+++ b/js/src/vm/NativeObject.h
@@ -491,8 +491,8 @@ class NativeObject : public ShapedObject
void checkShapeConsistency() { }
#endif
- Shape*
- replaceWithNewEquivalentShape(ExclusiveContext* cx,
+ static Shape*
+ replaceWithNewEquivalentShape(ExclusiveContext* cx, HandleNativeObject obj,
Shape* existingShape, Shape* newShape = nullptr,
bool accessorShape = false);
@@ -510,7 +510,7 @@ class NativeObject : public ShapedObject
*/
bool setSlotSpan(ExclusiveContext* cx, uint32_t span);
- bool toDictionaryMode(ExclusiveContext* cx);
+ static MOZ_MUST_USE bool toDictionaryMode(ExclusiveContext* cx, HandleNativeObject obj);
private:
friend class TenuringTracer;
@@ -609,12 +609,15 @@ class NativeObject : public ShapedObject
}
public:
- bool generateOwnShape(ExclusiveContext* cx, Shape* newShape = nullptr) {
- return replaceWithNewEquivalentShape(cx, lastProperty(), newShape);
+ static MOZ_MUST_USE bool generateOwnShape(ExclusiveContext* cx, HandleNativeObject obj,
+ Shape* newShape = nullptr)
+ {
+ return replaceWithNewEquivalentShape(cx, obj, obj->lastProperty(), newShape);
}
- bool shadowingShapeChange(ExclusiveContext* cx, const Shape& shape);
- bool clearFlag(ExclusiveContext* cx, BaseShape::Flag flag);
+ static MOZ_MUST_USE bool shadowingShapeChange(ExclusiveContext* cx, HandleNativeObject obj,
+ const Shape& shape);
+ static bool clearFlag(ExclusiveContext* cx, HandleNativeObject obj, BaseShape::Flag flag);
// The maximum number of slots in an object.
// |MAX_SLOTS_COUNT * sizeof(JS::Value)| shouldn't overflow
@@ -741,10 +744,10 @@ class NativeObject : public ShapedObject
bool allowDictionary = true);
/* Add a data property whose id is not yet in this scope. */
- Shape* addDataProperty(ExclusiveContext* cx,
- jsid id_, uint32_t slot, unsigned attrs);
- Shape* addDataProperty(ExclusiveContext* cx, HandlePropertyName name,
- uint32_t slot, unsigned attrs);
+ static Shape* addDataProperty(ExclusiveContext* cx, HandleNativeObject obj,
+ jsid id_, uint32_t slot, unsigned attrs);
+ static Shape* addDataProperty(ExclusiveContext* cx, HandleNativeObject obj,
+ HandlePropertyName name, uint32_t slot, unsigned attrs);
/* Add or overwrite a property for id in this scope. */
static Shape*
@@ -764,7 +767,7 @@ class NativeObject : public ShapedObject
unsigned attrs, JSGetterOp getter, JSSetterOp setter);
/* Remove the property named by id from this object. */
- bool removeProperty(ExclusiveContext* cx, jsid id);
+ static bool removeProperty(ExclusiveContext* cx, HandleNativeObject obj, jsid id);
/* Clear the scope, making it empty. */
static void clear(ExclusiveContext* cx, HandleNativeObject obj);
@@ -783,7 +786,8 @@ class NativeObject : public ShapedObject
unsigned flags, ShapeTable::Entry* entry, bool allowDictionary,
const AutoKeepShapeTables& keep);
- bool fillInAfterSwap(JSContext* cx, const Vector<Value>& values, void* priv);
+ static MOZ_MUST_USE bool fillInAfterSwap(JSContext* cx, HandleNativeObject obj,
+ const Vector<Value>& values, void* priv);
public:
// Return true if this object has been converted from shared-immutable
@@ -1146,7 +1150,7 @@ class NativeObject : public ShapedObject
}
inline DenseElementResult
- setOrExtendDenseElements(JSContext* cx, uint32_t start, const Value* vp, uint32_t count,
+ setOrExtendDenseElements(ExclusiveContext* cx, uint32_t start, const Value* vp, uint32_t count,
ShouldUpdateTypes updateTypes = ShouldUpdateTypes::Update);
bool shouldConvertDoubleElements() {
@@ -1470,19 +1474,6 @@ NativeGetExistingProperty(JSContext* cx, HandleObject receiver, HandleNativeObje
/* * */
-/*
- * If obj has an already-resolved data property for id, return true and
- * store the property value in *vp.
- */
-extern bool
-HasDataProperty(JSContext* cx, NativeObject* obj, jsid id, Value* vp);
-
-inline bool
-HasDataProperty(JSContext* cx, NativeObject* obj, PropertyName* name, Value* vp)
-{
- return HasDataProperty(cx, obj, NameToId(name), vp);
-}
-
extern bool
GetPropertyForNameLookup(JSContext* cx, HandleObject obj, HandleId id, MutableHandleValue vp);
diff --git a/js/src/vm/ObjectGroup.cpp b/js/src/vm/ObjectGroup.cpp
index 676792379..ec0a7aec1 100644
--- a/js/src/vm/ObjectGroup.cpp
+++ b/js/src/vm/ObjectGroup.cpp
@@ -249,7 +249,7 @@ ObjectGroup::useSingletonForAllocationSite(JSScript* script, jsbytecode* pc, con
/////////////////////////////////////////////////////////////////////
bool
-JSObject::shouldSplicePrototype(JSContext* cx)
+JSObject::shouldSplicePrototype()
{
/*
* During bootstrapping, if inference is enabled we need to make sure not
@@ -262,33 +262,36 @@ JSObject::shouldSplicePrototype(JSContext* cx)
return isSingleton();
}
-bool
-JSObject::splicePrototype(JSContext* cx, const Class* clasp, Handle<TaggedProto> proto)
+/* static */ bool
+JSObject::splicePrototype(JSContext* cx, HandleObject obj, const Class* clasp,
+ Handle<TaggedProto> proto)
{
- MOZ_ASSERT(cx->compartment() == compartment());
-
- RootedObject self(cx, this);
+ MOZ_ASSERT(cx->compartment() == obj->compartment());
/*
* For singleton groups representing only a single JSObject, the proto
* can be rearranged as needed without destroying type information for
* the old or new types.
*/
- MOZ_ASSERT(self->isSingleton());
+ MOZ_ASSERT(obj->isSingleton());
// Windows may not appear on prototype chains.
MOZ_ASSERT_IF(proto.isObject(), !IsWindow(proto.toObject()));
- if (proto.isObject() && !proto.toObject()->setDelegate(cx))
- return false;
+ if (proto.isObject()) {
+ RootedObject protoObj(cx, proto.toObject());
+ if (!JSObject::setDelegate(cx, protoObj))
+ return false;
+ }
// Force type instantiation when splicing lazy group.
- RootedObjectGroup group(cx, self->getGroup(cx));
+ RootedObjectGroup group(cx, JSObject::getGroup(cx, obj));
if (!group)
return false;
RootedObjectGroup protoGroup(cx, nullptr);
if (proto.isObject()) {
- protoGroup = proto.toObject()->getGroup(cx);
+ RootedObject protoObj(cx, proto.toObject());
+ protoGroup = JSObject::getGroup(cx, protoObj);
if (!protoGroup)
return false;
}
@@ -307,7 +310,7 @@ JSObject::makeLazyGroup(JSContext* cx, HandleObject obj)
/* De-lazification of functions can GC, so we need to do it up here. */
if (obj->is<JSFunction>() && obj->as<JSFunction>().isInterpretedLazy()) {
RootedFunction fun(cx, &obj->as<JSFunction>());
- if (!fun->getOrCreateScript(cx))
+ if (!JSFunction::getOrCreateScript(cx, fun))
return nullptr;
}
@@ -346,7 +349,7 @@ JSObject::makeLazyGroup(JSContext* cx, HandleObject obj)
JSObject::setNewGroupUnknown(JSContext* cx, const js::Class* clasp, JS::HandleObject obj)
{
ObjectGroup::setDefaultNewGroupUnknown(cx, clasp, obj);
- return obj->setFlags(cx, BaseShape::NEW_GROUP_UNKNOWN);
+ return JSObject::setFlags(cx, obj, BaseShape::NEW_GROUP_UNKNOWN);
}
/////////////////////////////////////////////////////////////////////
@@ -508,7 +511,7 @@ ObjectGroup::defaultNewGroup(ExclusiveContext* cx, const Class* clasp,
if (proto.isObject() && !proto.toObject()->isDelegate()) {
RootedObject protoObj(cx, proto.toObject());
- if (!protoObj->setDelegate(cx))
+ if (!JSObject::setDelegate(cx, protoObj))
return nullptr;
// Objects which are prototypes of one another should be singletons, so
diff --git a/js/src/vm/Opcodes.h b/js/src/vm/Opcodes.h
index 095ef57ae..3c4d61a67 100644
--- a/js/src/vm/Opcodes.h
+++ b/js/src/vm/Opcodes.h
@@ -2282,14 +2282,23 @@
* Operands:
* Stack: =>
*/ \
- macro(JSOP_JUMPTARGET, 230, "jumptarget", NULL, 1, 0, 0, JOF_BYTE)
+ macro(JSOP_JUMPTARGET, 230, "jumptarget", NULL, 1, 0, 0, JOF_BYTE)\
+ /*
+ * Like JSOP_CALL, but tells the function that the return value is ignored.
+ * stack.
+ * Category: Statements
+ * Type: Function
+ * Operands: uint16_t argc
+ * Stack: callee, this, args[0], ..., args[argc-1] => rval
+ * nuses: (argc+2)
+ */ \
+ macro(JSOP_CALL_IGNORES_RV, 231, "call-ignores-rv", NULL, 3, -1, 1, JOF_UINT16|JOF_INVOKE|JOF_TYPESET)
/*
* In certain circumstances it may be useful to "pad out" the opcode space to
* a power of two. Use this macro to do so.
*/
#define FOR_EACH_TRAILING_UNUSED_OPCODE(macro) \
- macro(231) \
macro(232) \
macro(233) \
macro(234) \
diff --git a/js/src/vm/ProxyObject.h b/js/src/vm/ProxyObject.h
index a0a929b20..d86d72cc9 100644
--- a/js/src/vm/ProxyObject.h
+++ b/js/src/vm/ProxyObject.h
@@ -104,7 +104,7 @@ class ProxyObject : public ShapedObject
public:
static unsigned grayLinkExtraSlot(JSObject* obj);
- void renew(JSContext* cx, const BaseProxyHandler* handler, const Value& priv);
+ void renew(const BaseProxyHandler* handler, const Value& priv);
static void trace(JSTracer* trc, JSObject* obj);
diff --git a/js/src/vm/RegExpObject.cpp b/js/src/vm/RegExpObject.cpp
index e0b44e1eb..ef97ed816 100644
--- a/js/src/vm/RegExpObject.cpp
+++ b/js/src/vm/RegExpObject.cpp
@@ -129,10 +129,10 @@ RegExpSharedReadBarrier(JSContext* cx, RegExpShared* shared)
shared->unmarkGray();
}
-bool
-RegExpObject::getShared(JSContext* cx, RegExpGuard* g)
+/* static */ bool
+RegExpObject::getShared(JSContext* cx, Handle<RegExpObject*> regexp, RegExpGuard* g)
{
- if (RegExpShared* shared = maybeShared()) {
+ if (RegExpShared* shared = regexp->maybeShared()) {
// Fetching a RegExpShared from an object requires a read
// barrier, as the shared pointer might be weak.
RegExpSharedReadBarrier(cx, shared);
@@ -141,7 +141,7 @@ RegExpObject::getShared(JSContext* cx, RegExpGuard* g)
return true;
}
- return createShared(cx, g);
+ return createShared(cx, regexp, g);
}
/* static */ bool
@@ -199,7 +199,7 @@ RegExpObject::trace(JSTracer* trc, JSObject* obj)
static JSObject*
CreateRegExpPrototype(JSContext* cx, JSProtoKey key)
{
- return cx->global()->createBlankPrototype(cx, &RegExpObject::protoClass_);
+ return GlobalObject::createBlankPrototype(cx, cx->global(), &RegExpObject::protoClass_);
}
static const ClassOps RegExpObjectClassOps = {
@@ -279,16 +279,14 @@ RegExpObject::create(ExclusiveContext* cx, HandleAtom source, RegExpFlag flags,
return regexp;
}
-bool
-RegExpObject::createShared(JSContext* cx, RegExpGuard* g)
+/* static */ bool
+RegExpObject::createShared(JSContext* cx, Handle<RegExpObject*> regexp, RegExpGuard* g)
{
- Rooted<RegExpObject*> self(cx, this);
-
- MOZ_ASSERT(!maybeShared());
- if (!cx->compartment()->regExps.get(cx, getSource(), getFlags(), g))
+ MOZ_ASSERT(!regexp->maybeShared());
+ if (!cx->compartment()->regExps.get(cx, regexp->getSource(), regexp->getFlags(), g))
return false;
- self->setShared(**g);
+ regexp->setShared(**g);
return true;
}
@@ -300,7 +298,8 @@ RegExpObject::assignInitialShape(ExclusiveContext* cx, Handle<RegExpObject*> sel
JS_STATIC_ASSERT(LAST_INDEX_SLOT == 0);
/* The lastIndex property alone is writable but non-configurable. */
- return self->addDataProperty(cx, cx->names().lastIndex, LAST_INDEX_SLOT, JSPROP_PERMANENT);
+ return NativeObject::addDataProperty(cx, self, cx->names().lastIndex, LAST_INDEX_SLOT,
+ JSPROP_PERMANENT);
}
void
@@ -891,11 +890,12 @@ RegExpShared::dumpBytecode(JSContext* cx, bool match_only, HandleLinearString in
return true;
}
-bool
-RegExpObject::dumpBytecode(JSContext* cx, bool match_only, HandleLinearString input)
+/* static */ bool
+RegExpObject::dumpBytecode(JSContext* cx, Handle<RegExpObject*> regexp,
+ bool match_only, HandleLinearString input)
{
RegExpGuard g(cx);
- if (!getShared(cx, &g))
+ if (!getShared(cx, regexp, &g))
return false;
return g.re()->dumpBytecode(cx, match_only, input);
@@ -1430,7 +1430,7 @@ js::CloneRegExpObject(JSContext* cx, JSObject* obj_)
Rooted<JSAtom*> source(cx, regex->getSource());
RegExpGuard g(cx);
- if (!regex->getShared(cx, &g))
+ if (!RegExpObject::getShared(cx, regex, &g))
return nullptr;
clone->initAndZeroLastIndex(source, g->getFlags(), cx);
diff --git a/js/src/vm/RegExpObject.h b/js/src/vm/RegExpObject.h
index dc428a973..f1ea101ed 100644
--- a/js/src/vm/RegExpObject.h
+++ b/js/src/vm/RegExpObject.h
@@ -483,7 +483,8 @@ class RegExpObject : public NativeObject
static bool isOriginalFlagGetter(JSNative native, RegExpFlag* mask);
- bool getShared(JSContext* cx, RegExpGuard* g);
+ static MOZ_MUST_USE bool getShared(JSContext* cx, Handle<RegExpObject*> regexp,
+ RegExpGuard* g);
void setShared(RegExpShared& shared) {
MOZ_ASSERT(!maybeShared());
@@ -500,7 +501,8 @@ class RegExpObject : public NativeObject
void initAndZeroLastIndex(HandleAtom source, RegExpFlag flags, ExclusiveContext* cx);
#ifdef DEBUG
- bool dumpBytecode(JSContext* cx, bool match_only, HandleLinearString input);
+ static MOZ_MUST_USE bool dumpBytecode(JSContext* cx, Handle<RegExpObject*> regexp,
+ bool match_only, HandleLinearString input);
#endif
private:
@@ -508,7 +510,8 @@ class RegExpObject : public NativeObject
* Precondition: the syntax for |source| has already been validated.
* Side effect: sets the private field.
*/
- bool createShared(JSContext* cx, RegExpGuard* g);
+ static MOZ_MUST_USE bool createShared(JSContext* cx, Handle<RegExpObject*> regexp,
+ RegExpGuard* g);
RegExpShared* maybeShared() const {
return static_cast<RegExpShared*>(NativeObject::getPrivate(PRIVATE_SLOT));
}
@@ -531,7 +534,7 @@ inline bool
RegExpToShared(JSContext* cx, HandleObject obj, RegExpGuard* g)
{
if (obj->is<RegExpObject>())
- return obj->as<RegExpObject>().getShared(cx, g);
+ return RegExpObject::getShared(cx, obj.as<RegExpObject>(), g);
return Proxy::regexp_toShared(cx, obj, g);
}
diff --git a/js/src/vm/Scope.cpp b/js/src/vm/Scope.cpp
index a71c03695..0f80d7b69 100644
--- a/js/src/vm/Scope.cpp
+++ b/js/src/vm/Scope.cpp
@@ -669,6 +669,14 @@ FunctionScope::script() const
return canonicalFunction()->nonLazyScript();
}
+/* static */ bool
+FunctionScope::isSpecialName(ExclusiveContext* cx, JSAtom* name)
+{
+ return name == cx->names().arguments ||
+ name == cx->names().dotThis ||
+ name == cx->names().dotGenerator;
+}
+
/* static */ Shape*
FunctionScope::getEmptyEnvironmentShape(ExclusiveContext* cx, bool hasParameterExprs)
{
diff --git a/js/src/vm/Scope.h b/js/src/vm/Scope.h
index 1d04fd9f6..4a4ae8090 100644
--- a/js/src/vm/Scope.h
+++ b/js/src/vm/Scope.h
@@ -446,10 +446,11 @@ Scope::is<LexicalScope>() const
}
//
-// Scope corresponding to a function. Holds formal parameter names and, if the
-// function parameters contain no expressions that might possibly be
-// evaluated, the function's var bindings. For example, in these functions,
-// the FunctionScope will store a/b/c bindings but not d/e/f bindings:
+// Scope corresponding to a function. Holds formal parameter names, special
+// internal names (see FunctionScope::isSpecialName), and, if the function
+// parameters contain no expressions that might possibly be evaluated, the
+// function's var bindings. For example, in these functions, the FunctionScope
+// will store a/b/c bindings but not d/e/f bindings:
//
// function f1(a, b) {
// var cÍž
@@ -562,6 +563,8 @@ class FunctionScope : public Scope
return data().nonPositionalFormalStart;
}
+ static bool isSpecialName(ExclusiveContext* cx, JSAtom* name);
+
static Shape* getEmptyEnvironmentShape(ExclusiveContext* cx, bool hasParameterExprs);
};
diff --git a/js/src/vm/SelfHosting.cpp b/js/src/vm/SelfHosting.cpp
index ccd4cc8d7..792a00490 100644
--- a/js/src/vm/SelfHosting.cpp
+++ b/js/src/vm/SelfHosting.cpp
@@ -477,7 +477,7 @@ intrinsic_FinishBoundFunctionInit(JSContext* cx, unsigned argc, Value* vp)
// Try to avoid invoking the resolve hook.
if (targetObj->is<JSFunction>() && !targetObj->as<JSFunction>().hasResolvedLength()) {
RootedValue targetLength(cx);
- if (!targetObj->as<JSFunction>().getUnresolvedLength(cx, &targetLength))
+ if (!JSFunction::getUnresolvedLength(cx, targetObj.as<JSFunction>(), &targetLength))
return false;
length = Max(0.0, targetLength.toNumber() - argCount);
@@ -2154,7 +2154,7 @@ static const JSFunctionSpec intrinsic_functions[] = {
JS_INLINABLE_FN("std_Array_slice", array_slice, 2,0, ArraySlice),
JS_FN("std_Array_sort", array_sort, 1,0),
JS_FN("std_Array_reverse", array_reverse, 0,0),
- JS_INLINABLE_FN("std_Array_splice", array_splice, 2,0, ArraySplice),
+ JS_FNINFO("std_Array_splice", array_splice, &array_splice_info, 2,0),
JS_FN("std_Date_now", date_now, 0,0),
JS_FN("std_Date_valueOf", date_valueOf, 0,0),
@@ -3008,7 +3008,7 @@ JSRuntime::cloneSelfHostedFunctionScript(JSContext* cx, HandlePropertyName name,
MOZ_ASSERT(targetFun->isInterpretedLazy());
MOZ_ASSERT(targetFun->isSelfHostedBuiltin());
- RootedScript sourceScript(cx, sourceFun->getOrCreateScript(cx));
+ RootedScript sourceScript(cx, JSFunction::getOrCreateScript(cx, sourceFun));
if (!sourceScript)
return false;
diff --git a/js/src/vm/Shape.cpp b/js/src/vm/Shape.cpp
index 306a2c540..8fe2145e5 100644
--- a/js/src/vm/Shape.cpp
+++ b/js/src/vm/Shape.cpp
@@ -460,15 +460,13 @@ NativeObject::getChildProperty(ExclusiveContext* cx,
return shape;
}
-bool
-js::NativeObject::toDictionaryMode(ExclusiveContext* cx)
+/* static */ bool
+js::NativeObject::toDictionaryMode(ExclusiveContext* cx, HandleNativeObject obj)
{
- MOZ_ASSERT(!inDictionaryMode());
- MOZ_ASSERT(cx->isInsideCurrentCompartment(this));
-
- uint32_t span = slotSpan();
+ MOZ_ASSERT(!obj->inDictionaryMode());
+ MOZ_ASSERT(cx->isInsideCurrentCompartment(obj));
- Rooted<NativeObject*> self(cx, this);
+ uint32_t span = obj->slotSpan();
// Clone the shapes into a new dictionary list. Don't update the last
// property of this object until done, otherwise a GC triggered while
@@ -476,7 +474,7 @@ js::NativeObject::toDictionaryMode(ExclusiveContext* cx)
RootedShape root(cx);
RootedShape dictionaryShape(cx);
- RootedShape shape(cx, lastProperty());
+ RootedShape shape(cx, obj->lastProperty());
while (shape) {
MOZ_ASSERT(!shape->inDictionary());
@@ -488,7 +486,7 @@ js::NativeObject::toDictionaryMode(ExclusiveContext* cx)
GCPtrShape* listp = dictionaryShape ? &dictionaryShape->parent : nullptr;
StackShape child(shape);
- dprop->initDictionaryShape(child, self->numFixedSlots(), listp);
+ dprop->initDictionaryShape(child, obj->numFixedSlots(), listp);
if (!dictionaryShape)
root = dprop;
@@ -503,18 +501,18 @@ js::NativeObject::toDictionaryMode(ExclusiveContext* cx)
return false;
}
- if (IsInsideNursery(self) &&
- !cx->asJSContext()->gc.nursery.queueDictionaryModeObjectToSweep(self))
+ if (IsInsideNursery(obj) &&
+ !cx->asJSContext()->gc.nursery.queueDictionaryModeObjectToSweep(obj))
{
ReportOutOfMemory(cx);
return false;
}
MOZ_ASSERT(root->listp == nullptr);
- root->listp = &self->shape_;
- self->shape_ = root;
+ root->listp = &obj->shape_;
+ obj->shape_ = root;
- MOZ_ASSERT(self->inDictionaryMode());
+ MOZ_ASSERT(obj->inDictionaryMode());
root->base()->setSlotSpan(span);
return true;
@@ -534,7 +532,7 @@ NativeObject::addProperty(ExclusiveContext* cx, HandleNativeObject obj, HandleId
return nullptr;
if (!extensible) {
if (cx->isJSContext())
- obj->reportNotExtensible(cx->asJSContext());
+ JSObject::reportNotExtensible(cx->asJSContext(), obj);
return nullptr;
}
@@ -592,7 +590,7 @@ NativeObject::addPropertyInternal(ExclusiveContext* cx,
if (allowDictionary &&
(!stableSlot || ShouldConvertToDictionary(obj)))
{
- if (!obj->toDictionaryMode(cx))
+ if (!toDictionaryMode(cx, obj))
return nullptr;
table = obj->lastProperty()->maybeTable(keep);
entry = &table->search<MaybeAdding::Adding>(id, keep);
@@ -727,7 +725,7 @@ CheckCanChangeAttrs(ExclusiveContext* cx, JSObject* obj, Shape* shape, unsigned*
(*attrsp & (JSPROP_GETTER | JSPROP_SETTER | JSPROP_SHARED)))
{
if (cx->isJSContext())
- obj->reportNotConfigurable(cx->asJSContext(), shape->propid());
+ JSObject::reportNotConfigurable(cx->asJSContext(), shape->propid());
return false;
}
@@ -785,7 +783,7 @@ NativeObject::putProperty(ExclusiveContext* cx, HandleNativeObject obj, HandleId
if (!extensible) {
if (cx->isJSContext())
- obj->reportNotExtensible(cx->asJSContext());
+ JSObject::reportNotExtensible(cx->asJSContext(), obj);
return nullptr;
}
@@ -834,7 +832,7 @@ NativeObject::putProperty(ExclusiveContext* cx, HandleNativeObject obj, HandleId
* addPropertyInternal because a failure under add would lose data.
*/
if (shape != obj->lastProperty() && !obj->inDictionaryMode()) {
- if (!obj->toDictionaryMode(cx))
+ if (!toDictionaryMode(cx, obj))
return nullptr;
ShapeTable* table = obj->lastProperty()->maybeTable(keep);
MOZ_ASSERT(table);
@@ -853,10 +851,11 @@ NativeObject::putProperty(ExclusiveContext* cx, HandleNativeObject obj, HandleId
*/
bool updateLast = (shape == obj->lastProperty());
bool accessorShape = getter || setter || (attrs & (JSPROP_GETTER | JSPROP_SETTER));
- shape = obj->replaceWithNewEquivalentShape(cx, shape, nullptr, accessorShape);
+ shape = NativeObject::replaceWithNewEquivalentShape(cx, obj, shape, nullptr,
+ accessorShape);
if (!shape)
return nullptr;
- if (!updateLast && !obj->generateOwnShape(cx))
+ if (!updateLast && !NativeObject::generateOwnShape(cx, obj))
return nullptr;
/*
@@ -968,16 +967,15 @@ NativeObject::changeProperty(ExclusiveContext* cx, HandleNativeObject obj, Handl
return newShape;
}
-bool
-NativeObject::removeProperty(ExclusiveContext* cx, jsid id_)
+/* static */ bool
+NativeObject::removeProperty(ExclusiveContext* cx, HandleNativeObject obj, jsid id_)
{
RootedId id(cx, id_);
- RootedNativeObject self(cx, this);
AutoKeepShapeTables keep(cx);
ShapeTable::Entry* entry;
RootedShape shape(cx);
- if (!Shape::search(cx, lastProperty(), id, keep, shape.address(), &entry))
+ if (!Shape::search(cx, obj->lastProperty(), id, keep, shape.address(), &entry))
return false;
if (!shape)
@@ -987,10 +985,10 @@ NativeObject::removeProperty(ExclusiveContext* cx, jsid id_)
* If shape is not the last property added, or the last property cannot
* be removed, switch to dictionary mode.
*/
- if (!self->inDictionaryMode() && (shape != self->lastProperty() || !self->canRemoveLastProperty())) {
- if (!self->toDictionaryMode(cx))
+ if (!obj->inDictionaryMode() && (shape != obj->lastProperty() || !obj->canRemoveLastProperty())) {
+ if (!toDictionaryMode(cx, obj))
return false;
- ShapeTable* table = self->lastProperty()->maybeTable(keep);
+ ShapeTable* table = obj->lastProperty()->maybeTable(keep);
MOZ_ASSERT(table);
entry = &table->search<MaybeAdding::NotAdding>(shape->propid(), keep);
shape = entry->shape();
@@ -1004,21 +1002,21 @@ NativeObject::removeProperty(ExclusiveContext* cx, jsid id_)
* the object or table, so the remaining removal is infallible.
*/
RootedShape spare(cx);
- if (self->inDictionaryMode()) {
+ if (obj->inDictionaryMode()) {
/* For simplicity, always allocate an accessor shape for now. */
spare = Allocate<AccessorShape>(cx);
if (!spare)
return false;
new (spare) Shape(shape->base()->unowned(), 0);
- if (shape == self->lastProperty()) {
+ if (shape == obj->lastProperty()) {
/*
* Get an up to date unowned base shape for the new last property
* when removing the dictionary's last property. Information in
* base shapes for non-last properties may be out of sync with the
* object's state.
*/
- RootedShape previous(cx, self->lastProperty()->parent);
- StackBaseShape base(self->lastProperty()->base());
+ RootedShape previous(cx, obj->lastProperty()->parent);
+ StackBaseShape base(obj->lastProperty()->base());
BaseShape* nbase = BaseShape::getUnowned(cx, base);
if (!nbase)
return false;
@@ -1028,7 +1026,7 @@ NativeObject::removeProperty(ExclusiveContext* cx, jsid id_)
/* If shape has a slot, free its slot number. */
if (shape->hasSlot()) {
- self->freeSlot(cx, shape->slot());
+ obj->freeSlot(cx, shape->slot());
if (cx->isJSContext())
++cx->asJSContext()->runtime()->propertyRemovals;
}
@@ -1038,8 +1036,8 @@ NativeObject::removeProperty(ExclusiveContext* cx, jsid id_)
* doubly linked list, hashed by lastProperty()->table. So we can edit the
* list and hash in place.
*/
- if (self->inDictionaryMode()) {
- ShapeTable* table = self->lastProperty()->maybeTable(keep);
+ if (obj->inDictionaryMode()) {
+ ShapeTable* table = obj->lastProperty()->maybeTable(keep);
MOZ_ASSERT(table);
if (entry->hadCollision()) {
@@ -1056,23 +1054,23 @@ NativeObject::removeProperty(ExclusiveContext* cx, jsid id_)
* checks not to alter significantly the complexity of the
* delete in debug builds, see bug 534493.
*/
- Shape* aprop = self->lastProperty();
+ Shape* aprop = obj->lastProperty();
for (int n = 50; --n >= 0 && aprop->parent; aprop = aprop->parent)
- MOZ_ASSERT_IF(aprop != shape, self->contains(cx, aprop));
+ MOZ_ASSERT_IF(aprop != shape, obj->contains(cx, aprop));
#endif
}
{
/* Remove shape from its non-circular doubly linked list. */
- Shape* oldLastProp = self->lastProperty();
- shape->removeFromDictionary(self);
+ Shape* oldLastProp = obj->lastProperty();
+ shape->removeFromDictionary(obj);
/* Hand off table from the old to new last property. */
- oldLastProp->handoffTableTo(self->lastProperty());
+ oldLastProp->handoffTableTo(obj->lastProperty());
}
/* Generate a new shape for the object, infallibly. */
- JS_ALWAYS_TRUE(self->generateOwnShape(cx, spare));
+ JS_ALWAYS_TRUE(NativeObject::generateOwnShape(cx, obj, spare));
/* Consider shrinking table if its load factor is <= .25. */
uint32_t size = table->capacity();
@@ -1085,11 +1083,11 @@ NativeObject::removeProperty(ExclusiveContext* cx, jsid id_)
* lazily make via a later hashify the exact table for the new property
* lineage.
*/
- MOZ_ASSERT(shape == self->lastProperty());
- self->removeLastProperty(cx);
+ MOZ_ASSERT(shape == obj->lastProperty());
+ obj->removeLastProperty(cx);
}
- self->checkShapeConsistency();
+ obj->checkShapeConsistency();
return true;
}
@@ -1133,35 +1131,30 @@ NativeObject::rollbackProperties(ExclusiveContext* cx, HandleNativeObject obj, u
if (slot < slotSpan)
break;
}
- if (!obj->removeProperty(cx, obj->lastProperty()->propid()))
+ if (!NativeObject::removeProperty(cx, obj, obj->lastProperty()->propid()))
return false;
}
return true;
}
-Shape*
-NativeObject::replaceWithNewEquivalentShape(ExclusiveContext* cx, Shape* oldShape, Shape* newShape,
- bool accessorShape)
+/* static */ Shape*
+NativeObject::replaceWithNewEquivalentShape(ExclusiveContext* cx, HandleNativeObject obj,
+ Shape* oldShape, Shape* newShape, bool accessorShape)
{
MOZ_ASSERT(cx->isInsideCurrentZone(oldShape));
- MOZ_ASSERT_IF(oldShape != lastProperty(),
- inDictionaryMode() && lookup(cx, oldShape->propidRef()) == oldShape);
-
- NativeObject* self = this;
+ MOZ_ASSERT_IF(oldShape != obj->lastProperty(),
+ obj->inDictionaryMode() && obj->lookup(cx, oldShape->propidRef()) == oldShape);
- if (!inDictionaryMode()) {
- RootedNativeObject selfRoot(cx, self);
+ if (!obj->inDictionaryMode()) {
RootedShape newRoot(cx, newShape);
- if (!toDictionaryMode(cx))
+ if (!toDictionaryMode(cx, obj))
return nullptr;
- oldShape = selfRoot->lastProperty();
- self = selfRoot;
+ oldShape = obj->lastProperty();
newShape = newRoot;
}
if (!newShape) {
- RootedNativeObject selfRoot(cx, self);
RootedShape oldRoot(cx, oldShape);
newShape = (oldShape->isAccessorShape() || accessorShape)
? Allocate<AccessorShape>(cx)
@@ -1169,12 +1162,11 @@ NativeObject::replaceWithNewEquivalentShape(ExclusiveContext* cx, Shape* oldShap
if (!newShape)
return nullptr;
new (newShape) Shape(oldRoot->base()->unowned(), 0);
- self = selfRoot;
oldShape = oldRoot;
}
AutoCheckCannotGC nogc;
- ShapeTable* table = self->lastProperty()->ensureTableForDictionary(cx, nogc);
+ ShapeTable* table = obj->lastProperty()->ensureTableForDictionary(cx, nogc);
if (!table)
return nullptr;
@@ -1187,12 +1179,12 @@ NativeObject::replaceWithNewEquivalentShape(ExclusiveContext* cx, Shape* oldShap
* enumeration order (see bug 601399).
*/
StackShape nshape(oldShape);
- newShape->initDictionaryShape(nshape, self->numFixedSlots(), oldShape->listp);
+ newShape->initDictionaryShape(nshape, obj->numFixedSlots(), oldShape->listp);
MOZ_ASSERT(newShape->parent == oldShape);
- oldShape->removeFromDictionary(self);
+ oldShape->removeFromDictionary(obj);
- if (newShape == self->lastProperty())
+ if (newShape == obj->lastProperty())
oldShape->handoffTableTo(newShape);
if (entry)
@@ -1200,63 +1192,63 @@ NativeObject::replaceWithNewEquivalentShape(ExclusiveContext* cx, Shape* oldShap
return newShape;
}
-bool
-NativeObject::shadowingShapeChange(ExclusiveContext* cx, const Shape& shape)
+/* static */ bool
+NativeObject::shadowingShapeChange(ExclusiveContext* cx, HandleNativeObject obj, const Shape& shape)
{
- return generateOwnShape(cx);
+ return generateOwnShape(cx, obj);
}
-bool
-JSObject::setFlags(ExclusiveContext* cx, BaseShape::Flag flags, GenerateShape generateShape)
+/* static */ bool
+JSObject::setFlags(ExclusiveContext* cx, HandleObject obj, BaseShape::Flag flags,
+ GenerateShape generateShape)
{
- if (hasAllFlags(flags))
+ if (obj->hasAllFlags(flags))
return true;
- RootedObject self(cx, this);
-
- Shape* existingShape = self->ensureShape(cx);
+ Shape* existingShape = obj->ensureShape(cx);
if (!existingShape)
return false;
- if (isNative() && as<NativeObject>().inDictionaryMode()) {
- if (generateShape == GENERATE_SHAPE && !as<NativeObject>().generateOwnShape(cx))
- return false;
- StackBaseShape base(self->as<NativeObject>().lastProperty());
+ if (obj->isNative() && obj->as<NativeObject>().inDictionaryMode()) {
+ if (generateShape == GENERATE_SHAPE) {
+ if (!NativeObject::generateOwnShape(cx, obj.as<NativeObject>()))
+ return false;
+ }
+ StackBaseShape base(obj->as<NativeObject>().lastProperty());
base.flags |= flags;
UnownedBaseShape* nbase = BaseShape::getUnowned(cx, base);
if (!nbase)
return false;
- self->as<NativeObject>().lastProperty()->base()->adoptUnowned(nbase);
+ obj->as<NativeObject>().lastProperty()->base()->adoptUnowned(nbase);
return true;
}
- Shape* newShape = Shape::setObjectFlags(cx, flags, self->taggedProto(), existingShape);
+ Shape* newShape = Shape::setObjectFlags(cx, flags, obj->taggedProto(), existingShape);
if (!newShape)
return false;
- // The success of the |JSObject::ensureShape| call above means that |self|
+ // The success of the |JSObject::ensureShape| call above means that |obj|
// can be assumed to have a shape.
- self->as<ShapedObject>().setShape(newShape);
+ obj->as<ShapedObject>().setShape(newShape);
return true;
}
-bool
-NativeObject::clearFlag(ExclusiveContext* cx, BaseShape::Flag flag)
+/* static */ bool
+NativeObject::clearFlag(ExclusiveContext* cx, HandleNativeObject obj, BaseShape::Flag flag)
{
- MOZ_ASSERT(inDictionaryMode());
+ MOZ_ASSERT(obj->inDictionaryMode());
- RootedNativeObject self(cx, &as<NativeObject>());
- MOZ_ASSERT(self->lastProperty()->getObjectFlags() & flag);
+ MOZ_ASSERT(obj->lastProperty()->getObjectFlags() & flag);
- StackBaseShape base(self->lastProperty());
+ StackBaseShape base(obj->lastProperty());
base.flags &= ~flag;
UnownedBaseShape* nbase = BaseShape::getUnowned(cx, base);
if (!nbase)
return false;
- self->lastProperty()->base()->adoptUnowned(nbase);
+ obj->lastProperty()->base()->adoptUnowned(nbase);
return true;
}
diff --git a/js/src/vm/Shape.h b/js/src/vm/Shape.h
index 978798aaa..fd6d843e0 100644
--- a/js/src/vm/Shape.h
+++ b/js/src/vm/Shape.h
@@ -905,9 +905,6 @@ class Shape : public gc::TenuredCell
setter() == rawSetter;
}
- bool set(JSContext* cx, HandleNativeObject obj, HandleObject receiver, MutableHandleValue vp,
- ObjectOpResult& result);
-
BaseShape* base() const { return base_.get(); }
bool hasSlot() const {
diff --git a/js/src/vm/SharedArrayObject.cpp b/js/src/vm/SharedArrayObject.cpp
index c69306aac..0dff41201 100644
--- a/js/src/vm/SharedArrayObject.cpp
+++ b/js/src/vm/SharedArrayObject.cpp
@@ -366,7 +366,8 @@ static const Class SharedArrayBufferObjectProtoClass = {
static JSObject*
CreateSharedArrayBufferPrototype(JSContext* cx, JSProtoKey key)
{
- return cx->global()->createBlankPrototype(cx, &SharedArrayBufferObjectProtoClass);
+ return GlobalObject::createBlankPrototype(cx, cx->global(),
+ &SharedArrayBufferObjectProtoClass);
}
static const ClassOps SharedArrayBufferObjectClassOps = {
diff --git a/js/src/vm/Stack-inl.h b/js/src/vm/Stack-inl.h
index a51c0aa14..11a19d175 100644
--- a/js/src/vm/Stack-inl.h
+++ b/js/src/vm/Stack-inl.h
@@ -306,7 +306,7 @@ InterpreterStack::pushInlineFrame(JSContext* cx, InterpreterRegs& regs, const Ca
MOZ_ASSERT(regs.sp == args.end());
MOZ_ASSERT(callee->nonLazyScript() == script);
- script->ensureNonLazyCanonicalFunction(cx);
+ script->ensureNonLazyCanonicalFunction();
InterpreterFrame* prev = regs.fp();
jsbytecode* prevpc = regs.pc;
@@ -336,13 +336,13 @@ InterpreterStack::resumeGeneratorCallFrame(JSContext* cx, InterpreterRegs& regs,
HandleObject envChain)
{
MOZ_ASSERT(callee->isGenerator());
- RootedScript script(cx, callee->getOrCreateScript(cx));
+ RootedScript script(cx, JSFunction::getOrCreateScript(cx, callee));
InterpreterFrame* prev = regs.fp();
jsbytecode* prevpc = regs.pc;
Value* prevsp = regs.sp;
MOZ_ASSERT(prev);
- script->ensureNonLazyCanonicalFunction(cx);
+ script->ensureNonLazyCanonicalFunction();
LifoAlloc::Mark mark = allocator_.mark();
diff --git a/js/src/vm/Stack.h b/js/src/vm/Stack.h
index dc9306c99..23e621344 100644
--- a/js/src/vm/Stack.h
+++ b/js/src/vm/Stack.h
@@ -1006,6 +1006,17 @@ class InvokeArgs : public detail::GenericArgsBase<NO_CONSTRUCT>
explicit InvokeArgs(JSContext* cx) : Base(cx) {}
};
+/** Function call args of statically-unknown count. */
+class InvokeArgsMaybeIgnoresReturnValue : public detail::GenericArgsBase<NO_CONSTRUCT>
+{
+ using Base = detail::GenericArgsBase<NO_CONSTRUCT>;
+
+ public:
+ explicit InvokeArgsMaybeIgnoresReturnValue(JSContext* cx, bool ignoresReturnValue) : Base(cx) {
+ this->ignoresReturnValue_ = ignoresReturnValue;
+ }
+};
+
/** Function call args of statically-known count. */
template <size_t N>
class FixedInvokeArgs : public detail::FixedArgsBase<NO_CONSTRUCT, N>
diff --git a/js/src/vm/StringObject-inl.h b/js/src/vm/StringObject-inl.h
index 5fc1656f6..38191fc7a 100644
--- a/js/src/vm/StringObject-inl.h
+++ b/js/src/vm/StringObject-inl.h
@@ -15,31 +15,29 @@
namespace js {
-inline bool
-StringObject::init(JSContext* cx, HandleString str)
+/* static */ inline bool
+StringObject::init(JSContext* cx, Handle<StringObject*> obj, HandleString str)
{
- MOZ_ASSERT(numFixedSlots() == 2);
+ MOZ_ASSERT(obj->numFixedSlots() == 2);
- Rooted<StringObject*> self(cx, this);
-
- if (!EmptyShape::ensureInitialCustomShape<StringObject>(cx, self))
+ if (!EmptyShape::ensureInitialCustomShape<StringObject>(cx, obj))
return false;
- MOZ_ASSERT(self->lookup(cx, NameToId(cx->names().length))->slot() == LENGTH_SLOT);
+ MOZ_ASSERT(obj->lookup(cx, NameToId(cx->names().length))->slot() == LENGTH_SLOT);
- self->setStringThis(str);
+ obj->setStringThis(str);
return true;
}
-inline StringObject*
+/* static */ inline StringObject*
StringObject::create(JSContext* cx, HandleString str, HandleObject proto, NewObjectKind newKind)
{
JSObject* obj = NewObjectWithClassProto(cx, &class_, proto, newKind);
if (!obj)
return nullptr;
Rooted<StringObject*> strobj(cx, &obj->as<StringObject>());
- if (!strobj->init(cx, str))
+ if (!StringObject::init(cx, strobj, str))
return nullptr;
return strobj;
}
diff --git a/js/src/vm/StringObject.h b/js/src/vm/StringObject.h
index 119e3d9fa..561e0478a 100644
--- a/js/src/vm/StringObject.h
+++ b/js/src/vm/StringObject.h
@@ -56,7 +56,7 @@ class StringObject : public NativeObject
}
private:
- inline bool init(JSContext* cx, HandleString str);
+ static inline bool init(JSContext* cx, Handle<StringObject*> obj, HandleString str);
void setStringThis(JSString* str) {
MOZ_ASSERT(getReservedSlot(PRIMITIVE_VALUE_SLOT).isUndefined());
diff --git a/js/src/vm/TypeInference.cpp b/js/src/vm/TypeInference.cpp
index ba809fc4e..7c2c0194e 100644
--- a/js/src/vm/TypeInference.cpp
+++ b/js/src/vm/TypeInference.cpp
@@ -1319,7 +1319,8 @@ js::EnsureTrackPropertyTypes(JSContext* cx, JSObject* obj, jsid id)
AutoEnterAnalysis enter(cx);
if (obj->hasLazyGroup()) {
AutoEnterOOMUnsafeRegion oomUnsafe;
- if (!obj->getGroup(cx)) {
+ RootedObject objRoot(cx, obj);
+ if (!JSObject::getGroup(cx, objRoot)) {
oomUnsafe.crash("Could not allocate ObjectGroup in EnsureTrackPropertyTypes");
return;
}
@@ -1338,9 +1339,12 @@ HeapTypeSetKey::instantiate(JSContext* cx)
{
if (maybeTypes())
return true;
- if (object()->isSingleton() && !object()->singleton()->getGroup(cx)) {
- cx->clearPendingException();
- return false;
+ if (object()->isSingleton()) {
+ RootedObject obj(cx, object()->singleton());
+ if (!JSObject::getGroup(cx, obj)) {
+ cx->clearPendingException();
+ return false;
+ }
}
JSObject* obj = object()->isSingleton() ? object()->singleton() : nullptr;
maybeTypes_ = object()->maybeGroup()->getProperty(cx, obj, id());
@@ -2941,7 +2945,8 @@ ObjectGroup::clearNewScript(ExclusiveContext* cx, ObjectGroup* replacement /* =
// Mark the constructing function as having its 'new' script cleared, so we
// will not try to construct another one later.
- if (!newScript->function()->setNewScriptCleared(cx))
+ RootedFunction fun(cx, newScript->function());
+ if (!JSObject::setNewScriptCleared(cx, fun))
cx->recoverFromOutOfMemory();
}
@@ -3088,7 +3093,7 @@ js::AddClearDefiniteGetterSetterForPrototypeChain(JSContext* cx, ObjectGroup* gr
*/
RootedObject proto(cx, group->proto().toObjectOrNull());
while (proto) {
- ObjectGroup* protoGroup = proto->getGroup(cx);
+ ObjectGroup* protoGroup = JSObject::getGroup(cx, proto);
if (!protoGroup) {
cx->recoverFromOutOfMemory();
return false;
@@ -3712,7 +3717,8 @@ TypeNewScript::maybeAnalyze(JSContext* cx, ObjectGroup* group, bool* regenerate,
Vector<Initializer> initializerVector(cx);
RootedPlainObject templateRoot(cx, templateObject());
- if (!jit::AnalyzeNewScriptDefiniteProperties(cx, function(), group, templateRoot, &initializerVector))
+ RootedFunction fun(cx, function());
+ if (!jit::AnalyzeNewScriptDefiniteProperties(cx, fun, group, templateRoot, &initializerVector))
return false;
if (!group->newScript())
diff --git a/js/src/vm/TypedArrayObject.cpp b/js/src/vm/TypedArrayObject.cpp
index ae97be0de..8b0302917 100644
--- a/js/src/vm/TypedArrayObject.cpp
+++ b/js/src/vm/TypedArrayObject.cpp
@@ -361,7 +361,7 @@ class TypedArrayObjectTemplate : public TypedArrayObject
return nullptr;
const Class* clasp = TypedArrayObject::protoClassForType(ArrayTypeID());
- return global->createBlankPrototypeInheriting(cx, clasp, typedArrayProto);
+ return GlobalObject::createBlankPrototypeInheriting(cx, global, clasp, typedArrayProto);
}
static JSObject*
@@ -1892,7 +1892,7 @@ DataViewObject::constructWrapped(JSContext* cx, HandleObject bufobj, const CallA
Rooted<GlobalObject*> global(cx, cx->compartment()->maybeGlobal());
if (!proto) {
- proto = global->getOrCreateDataViewPrototype(cx);
+ proto = GlobalObject::getOrCreateDataViewPrototype(cx, global);
if (!proto)
return false;
}
@@ -2892,12 +2892,13 @@ DataViewObject::initClass(JSContext* cx)
if (global->isStandardClassResolved(JSProto_DataView))
return true;
- RootedNativeObject proto(cx, global->createBlankPrototype(cx, &DataViewObject::protoClass));
+ RootedNativeObject proto(cx, GlobalObject::createBlankPrototype(cx, global,
+ &DataViewObject::protoClass));
if (!proto)
return false;
- RootedFunction ctor(cx, global->createConstructor(cx, DataViewObject::class_constructor,
- cx->names().DataView, 3));
+ RootedFunction ctor(cx, GlobalObject::createConstructor(cx, DataViewObject::class_constructor,
+ cx->names().DataView, 3));
if (!ctor)
return false;