diff options
Diffstat (limited to 'js/src/vm')
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, ®S.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; |