/* -*- 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/. *//* * JavaScript API. */#include"jsapi.h"#include"mozilla/FloatingPoint.h"#include"mozilla/PodOperations.h"#include<ctype.h>#include<stdarg.h>#include<string.h>#include<sys/stat.h>#include"jsarray.h"#include"jsatom.h"#include"jsbool.h"#include"jscntxt.h"#include"jsdate.h"#include"jsexn.h"#include"jsfriendapi.h"#include"jsfun.h"#include"jsgc.h"#include"jsiter.h"#include"jslock.h"#include"jsmath.h"#include"jsnum.h"#include"jsobj.h"#include"json.h"#include"jsprf.h"#include"jsscript.h"#include"jsstr.h"#include"jstypes.h"#include"jsutil.h"#include"jswatchpoint.h"#include"jsweakmap.h"#include"jswrapper.h"#include"asmjs/AsmJS.h"#include"builtin/AtomicsObject.h"#include"builtin/Eval.h"#include"builtin/Intl.h"#include"builtin/MapObject.h"#include"builtin/Promise.h"#include"builtin/RegExp.h"#include"builtin/SymbolObject.h"#ifdef ENABLE_SIMD# include "builtin/SIMD.h"#endif#ifdef ENABLE_BINARYDATA# include "builtin/TypedObject.h"#endif#include"frontend/BytecodeCompiler.h"#include"frontend/FullParseHandler.h" // for JS_BufferIsCompileableUnit#include"frontend/Parser.h" // for JS_BufferIsCompileableUnit#include"gc/Marking.h"#include"gc/Policy.h"#include"jit/JitCommon.h"#include"js/CharacterEncoding.h"#include"js/Conversions.h"#include"js/Date.h"#include"js/Initialization.h"#include"js/Proxy.h"#include"js/SliceBudget.h"#include"js/StructuredClone.h"#include"js/UniquePtr.h"#include"vm/DateObject.h"#include"vm/Debugger.h"#include"vm/ErrorObject.h"#include"vm/HelperThreads.h"#include"vm/Interpreter.h"#include"vm/RegExpStatics.h"#include"vm/Runtime.h"#include"vm/SavedStacks.h"#include"vm/ScopeObject.h"#include"vm/SelfHosting.h"#include"vm/Shape.h"#include"vm/StopIterationObject.h"#include"vm/StringBuffer.h"#include"vm/Symbol.h"#include"vm/TypedArrayCommon.h"#include"vm/WrapperObject.h"#include"vm/Xdr.h"#include"jsatominlines.h"#include"jsfuninlines.h"#include"jsscriptinlines.h"#include"vm/Interpreter-inl.h"#include"vm/NativeObject-inl.h"#include"vm/SavedStacks-inl.h"#include"vm/String-inl.h"usingnamespacejs;usingnamespacejs::gc;usingmozilla::Maybe;usingmozilla::PodCopy;usingmozilla::PodZero;usingJS::AutoGCRooter;usingJS::ToInt32;usingJS::ToInteger;usingJS::ToUint32;usingjs::frontend::Parser;#ifdef HAVE_VA_LIST_AS_ARRAY#define JS_ADDRESSOF_VA_LIST(ap) ((va_list*)(ap))#else#define JS_ADDRESSOF_VA_LIST(ap) (&(ap))#endifboolJS::CallArgs::requireAtLeast(JSContext*cx,constchar*fnname,unsignedrequired)const{if(length()<required){charnumArgsStr[40];JS_snprintf(numArgsStr,sizeofnumArgsStr,"%u",required-1);JS_ReportErrorNumber(cx,GetErrorMessage,nullptr,JSMSG_MORE_ARGS_NEEDED,fnname,numArgsStr,required==2?"":"s");returnfalse;}returntrue;}staticboolErrorTakesArguments(unsignedmsg){MOZ_ASSERT(msg<JSErr_Limit);unsignedargCount=js_ErrorFormatString[msg].argCount;MOZ_ASSERT(argCount<=2);returnargCount==1||argCount==2;}staticboolErrorTakesObjectArgument(unsignedmsg){MOZ_ASSERT(msg<JSErr_Limit);unsignedargCount=js_ErrorFormatString[msg].argCount;MOZ_ASSERT(argCount<=2);returnargCount==2;}JS_PUBLIC_API(bool)JS::ObjectOpResult::reportStrictErrorOrWarning(JSContext*cx,HandleObjectobj,HandleIdid,boolstrict){static_assert(unsigned(OkCode)==unsigned(JSMSG_NOT_AN_ERROR),"unsigned value of OkCode must not be an error code");MOZ_ASSERT(code_!=Uninitialized);MOZ_ASSERT(!ok());unsignedflags=strict?JSREPORT_ERROR:(JSREPORT_WARNING|JSREPORT_STRICT);if(code_==JSMSG_OBJECT_NOT_EXTENSIBLE||code_==JSMSG_SET_NON_OBJECT_RECEIVER){RootedValueval(cx,ObjectValue(*obj));returnReportValueErrorFlags(cx,flags,code_,JSDVG_IGNORE_STACK,val,nullptr,nullptr,nullptr);}if(ErrorTakesArguments(code_)){RootedValueidv(cx,IdToValue(id));RootedStringstr(cx,ValueToSource(cx,idv));if(!str)returnfalse;JSAutoByteStringpropName(cx,str);if(!propName)returnfalse;if(ErrorTakesObjectArgument(code_)){returnJS_ReportErrorFlagsAndNumber(cx,flags,GetErrorMessage,nullptr,code_,obj->getClass()->name,propName.ptr());}returnJS_ReportErrorFlagsAndNumber(cx,flags,GetErrorMessage,nullptr,code_,propName.ptr());}returnJS_ReportErrorFlagsAndNumber(cx,flags,GetErrorMessage,nullptr,code_);}JS_PUBLIC_API(bool)JS::ObjectOpResult::reportStrictErrorOrWarning(JSContext*cx,HandleObjectobj,boolstrict){MOZ_ASSERT(code_!=Uninitialized);MOZ_ASSERT(!ok());MOZ_ASSERT(!ErrorTakesArguments(code_));unsignedflags=strict?JSREPORT_ERROR:(JSREPORT_WARNING|JSREPORT_STRICT);returnJS_ReportErrorFlagsAndNumber(cx,flags,GetErrorMessage,nullptr,code_);}JS_PUBLIC_API(bool)JS::ObjectOpResult::failCantRedefineProp(){returnfail(JSMSG_CANT_REDEFINE_PROP);}JS_PUBLIC_API(bool)JS::ObjectOpResult::failReadOnly(){returnfail(JSMSG_READ_ONLY);}JS_PUBLIC_API(bool)JS::ObjectOpResult::failGetterOnly(){returnfail(JSMSG_GETTER_ONLY);}JS_PUBLIC_API(bool)JS::ObjectOpResult::failCantDelete(){returnfail(JSMSG_CANT_DELETE);}JS_PUBLIC_API(bool)JS::ObjectOpResult::failCantSetInterposed(){returnfail(JSMSG_CANT_SET_INTERPOSED);}JS_PUBLIC_API(bool)JS::ObjectOpResult::failCantDefineWindowElement(){returnfail(JSMSG_CANT_DEFINE_WINDOW_ELEMENT);}JS_PUBLIC_API(bool)JS::ObjectOpResult::failCantDeleteWindowElement(){returnfail(JSMSG_CANT_DELETE_WINDOW_ELEMENT);}JS_PUBLIC_API(bool)JS::ObjectOpResult::failCantDeleteWindowNamedProperty(){returnfail(JSMSG_CANT_DELETE_WINDOW_NAMED_PROPERTY);}JS_PUBLIC_API(bool)JS::ObjectOpResult::failCantPreventExtensions(){returnfail(JSMSG_CANT_PREVENT_EXTENSIONS);}JS_PUBLIC_API(bool)JS::ObjectOpResult::failCantSetProto(){returnfail(JSMSG_CANT_SET_PROTO);}JS_PUBLIC_API(bool)JS::ObjectOpResult::failNoNamedSetter(){returnfail(JSMSG_NO_NAMED_SETTER);}JS_PUBLIC_API(bool)JS::ObjectOpResult::failNoIndexedSetter(){returnfail(JSMSG_NO_INDEXED_SETTER);}JS_PUBLIC_API(int64_t)JS_Now(){returnPRMJ_Now();}JS_PUBLIC_API(Value)JS_GetNaNValue(JSContext*cx){returncx->runtime()->NaNValue;}JS_PUBLIC_API(Value)JS_GetNegativeInfinityValue(JSContext*cx){returncx->runtime()->negativeInfinityValue;}JS_PUBLIC_API(Value)JS_GetPositiveInfinityValue(JSContext*cx){returncx->runtime()->positiveInfinityValue;}JS_PUBLIC_API(Value)JS_GetEmptyStringValue(JSContext*cx){returnStringValue(cx->runtime()->emptyString);}JS_PUBLIC_API(JSString*)JS_GetEmptyString(JSRuntime*rt){MOZ_ASSERT(rt->hasContexts());returnrt->emptyString;}namespacejs{voidAssertHeapIsIdle(JSRuntime*rt){MOZ_ASSERT(!rt->isHeapBusy());}voidAssertHeapIsIdle(JSContext*cx){AssertHeapIsIdle(cx->runtime());}}// namespace jsstaticvoidAssertHeapIsIdleOrIterating(JSRuntime*rt){MOZ_ASSERT(!rt->isHeapCollecting());}staticvoidAssertHeapIsIdleOrIterating(JSContext*cx){AssertHeapIsIdleOrIterating(cx->runtime());}staticvoidAssertHeapIsIdleOrStringIsFlat(JSContext*cx,JSString*str){/* * We allow some functions to be called during a GC as long as the argument * is a flat string, since that will not cause allocation. */MOZ_ASSERT_IF(cx->runtime()->isHeapBusy(),str->isFlat());}JS_PUBLIC_API(bool)JS_ValueToObject(JSContext*cx,HandleValuevalue,MutableHandleObjectobjp){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);assertSameCompartment(cx,value);if(value.isNullOrUndefined()){objp.set(nullptr);returntrue;}JSObject*obj=ToObject(cx,value);if(!obj)returnfalse;objp.set(obj);returntrue;}JS_PUBLIC_API(JSFunction*)JS_ValueToFunction(JSContext*cx,HandleValuevalue){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);assertSameCompartment(cx,value);returnReportIfNotFunction(cx,value);}JS_PUBLIC_API(JSFunction*)JS_ValueToConstructor(JSContext*cx,HandleValuevalue){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);assertSameCompartment(cx,value);returnReportIfNotFunction(cx,value);}JS_PUBLIC_API(JSString*)JS_ValueToSource(JSContext*cx,HandleValuevalue){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);assertSameCompartment(cx,value);returnValueToSource(cx,value);}JS_PUBLIC_API(bool)JS_DoubleIsInt32(doubled,int32_t*ip){returnmozilla::NumberIsInt32(d,ip);}JS_PUBLIC_API(JSType)JS_TypeOfValue(JSContext*cx,HandleValuevalue){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);assertSameCompartment(cx,value);returnTypeOfValue(value);}JS_PUBLIC_API(bool)JS_StrictlyEqual(JSContext*cx,HandleValuevalue1,HandleValuevalue2,bool*equal){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);assertSameCompartment(cx,value1,value2);MOZ_ASSERT(equal);returnStrictlyEqual(cx,value1,value2,equal);}JS_PUBLIC_API(bool)JS_LooselyEqual(JSContext*cx,HandleValuevalue1,HandleValuevalue2,bool*equal){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);assertSameCompartment(cx,value1,value2);MOZ_ASSERT(equal);returnLooselyEqual(cx,value1,value2,equal);}JS_PUBLIC_API(bool)JS_SameValue(JSContext*cx,HandleValuevalue1,HandleValuevalue2,bool*same){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);assertSameCompartment(cx,value1,value2);MOZ_ASSERT(same);returnSameValue(cx,value1,value2,same);}JS_PUBLIC_API(bool)JS_IsBuiltinEvalFunction(JSFunction*fun){returnIsAnyBuiltinEval(fun);}JS_PUBLIC_API(bool)JS_IsBuiltinFunctionConstructor(JSFunction*fun){returnfun->isBuiltinFunctionConstructor();}/************************************************************************/#ifdef DEBUGJS_FRIEND_API(bool)JS::isGCEnabled(){return!TlsPerThreadData.get()->suppressGC;}#elseJS_FRIEND_API(bool)JS::isGCEnabled(){returntrue;}#endifJS_PUBLIC_API(JSRuntime*)JS_NewRuntime(uint32_tmaxbytes,uint32_tmaxNurseryBytes,JSRuntime*parentRuntime){MOZ_ASSERT(JS::detail::libraryInitState==JS::detail::InitState::Running,"must call JS_Init prior to creating any JSRuntimes");// Make sure that all parent runtimes are the topmost parent.while(parentRuntime&&parentRuntime->parentRuntime)parentRuntime=parentRuntime->parentRuntime;JSRuntime*rt=js_new<JSRuntime>(parentRuntime);if(!rt)returnnullptr;if(!rt->init(maxbytes,maxNurseryBytes)){JS_DestroyRuntime(rt);returnnullptr;}returnrt;}JS_PUBLIC_API(void)JS_DestroyRuntime(JSRuntime*rt){js_delete(rt);}staticJS_CurrentEmbedderTimeFunctioncurrentEmbedderTimeFunction;JS_PUBLIC_API(void)JS_SetCurrentEmbedderTimeFunction(JS_CurrentEmbedderTimeFunctiontimeFn){currentEmbedderTimeFunction=timeFn;}JS_PUBLIC_API(double)JS_GetCurrentEmbedderTime(){if(currentEmbedderTimeFunction)returncurrentEmbedderTimeFunction();returnPRMJ_Now()/static_cast<double>(PRMJ_USEC_PER_MSEC);}JS_PUBLIC_API(void*)JS_GetRuntimePrivate(JSRuntime*rt){returnrt->data;}JS_PUBLIC_API(void)JS_SetRuntimePrivate(JSRuntime*rt,void*data){rt->data=data;}JS_PUBLIC_API(void)JS_SetFutexCanWait(JSRuntime*rt){rt->fx.setCanWait(true);}staticvoidStartRequest(JSContext*cx){JSRuntime*rt=cx->runtime();MOZ_ASSERT(CurrentThreadCanAccessRuntime(rt));if(rt->requestDepth){rt->requestDepth++;}else{/* Indicate that a request is running. */rt->requestDepth=1;rt->triggerActivityCallback(true);}}staticvoidStopRequest(JSContext*cx){JSRuntime*rt=cx->runtime();MOZ_ASSERT(CurrentThreadCanAccessRuntime(rt));MOZ_ASSERT(rt->requestDepth!=0);if(rt->requestDepth!=1){rt->requestDepth--;}else{rt->requestDepth=0;rt->triggerActivityCallback(false);}}JS_PUBLIC_API(void)JS_BeginRequest(JSContext*cx){cx->outstandingRequests++;StartRequest(cx);}JS_PUBLIC_API(void)JS_EndRequest(JSContext*cx){MOZ_ASSERT(cx->outstandingRequests!=0);cx->outstandingRequests--;StopRequest(cx);}JS_PUBLIC_API(void)JS_SetContextCallback(JSRuntime*rt,JSContextCallbackcxCallback,void*data){rt->cxCallback=cxCallback;rt->cxCallbackData=data;}JS_PUBLIC_API(JSContext*)JS_NewContext(JSRuntime*rt,size_tstackChunkSize){returnNewContext(rt,stackChunkSize);}JS_PUBLIC_API(void)JS_DestroyContext(JSContext*cx){MOZ_ASSERT(!cx->compartment());DestroyContext(cx,DCM_FORCE_GC);}JS_PUBLIC_API(void)JS_DestroyContextNoGC(JSContext*cx){MOZ_ASSERT(!cx->compartment());DestroyContext(cx,DCM_NO_GC);}JS_PUBLIC_API(void*)JS_GetContextPrivate(JSContext*cx){returncx->data;}JS_PUBLIC_API(void)JS_SetContextPrivate(JSContext*cx,void*data){cx->data=data;}JS_PUBLIC_API(void*)JS_GetSecondContextPrivate(JSContext*cx){returncx->data2;}JS_PUBLIC_API(void)JS_SetSecondContextPrivate(JSContext*cx,void*data){cx->data2=data;}JS_PUBLIC_API(JSRuntime*)JS_GetRuntime(JSContext*cx){returncx->runtime();}JS_PUBLIC_API(JSRuntime*)JS_GetParentRuntime(JSContext*cx){JSRuntime*rt=cx->runtime();returnrt->parentRuntime?rt->parentRuntime:rt;}JS_PUBLIC_API(JSContext*)JS_ContextIterator(JSRuntime*rt,JSContext**iterp){JSContext*cx=*iterp;cx=cx?cx->getNext():rt->contextList.getFirst();*iterp=cx;returncx;}JS_PUBLIC_API(JSVersion)JS_GetVersion(JSContext*cx){returnVersionNumber(cx->findVersion());}JS_PUBLIC_API(void)JS_SetVersionForCompartment(JSCompartment*compartment,JSVersionversion){compartment->behaviors().setVersion(version);}staticconststructv2smap{JSVersionversion;constchar*string;}v2smap[]={{JSVERSION_ECMA_3,"ECMAv3"},{JSVERSION_1_6,"1.6"},{JSVERSION_1_7,"1.7"},{JSVERSION_1_8,"1.8"},{JSVERSION_ECMA_5,"ECMAv5"},{JSVERSION_DEFAULT,js_default_str},{JSVERSION_DEFAULT,"1.0"},{JSVERSION_DEFAULT,"1.1"},{JSVERSION_DEFAULT,"1.2"},{JSVERSION_DEFAULT,"1.3"},{JSVERSION_DEFAULT,"1.4"},{JSVERSION_DEFAULT,"1.5"},{JSVERSION_UNKNOWN,nullptr},/* must be last, nullptr is sentinel */};JS_PUBLIC_API(constchar*)JS_VersionToString(JSVersionversion){inti;for(i=0;v2smap[i].string;i++)if(v2smap[i].version==version)returnv2smap[i].string;return"unknown";}JS_PUBLIC_API(JSVersion)JS_StringToVersion(constchar*string){inti;for(i=0;v2smap[i].string;i++)if(strcmp(v2smap[i].string,string)==0)returnv2smap[i].version;returnJSVERSION_UNKNOWN;}JS_PUBLIC_API(JS::RuntimeOptions&)JS::RuntimeOptionsRef(JSRuntime*rt){returnrt->options();}JS_PUBLIC_API(JS::RuntimeOptions&)JS::RuntimeOptionsRef(JSContext*cx){returncx->runtime()->options();}JS_PUBLIC_API(JS::ContextOptions&)JS::ContextOptionsRef(JSContext*cx){returncx->options();}JS_PUBLIC_API(constchar*)JS_GetImplementationVersion(void){return"JavaScript-C"MOZILLA_VERSION;}JS_PUBLIC_API(void)JS_SetDestroyCompartmentCallback(JSRuntime*rt,JSDestroyCompartmentCallbackcallback){rt->destroyCompartmentCallback=callback;}JS_PUBLIC_API(void)JS_SetSizeOfIncludingThisCompartmentCallback(JSRuntime*rt,JSSizeOfIncludingThisCompartmentCallbackcallback){rt->sizeOfIncludingThisCompartmentCallback=callback;}JS_PUBLIC_API(void)JS_SetDestroyZoneCallback(JSRuntime*rt,JSZoneCallbackcallback){rt->destroyZoneCallback=callback;}JS_PUBLIC_API(void)JS_SetSweepZoneCallback(JSRuntime*rt,JSZoneCallbackcallback){rt->sweepZoneCallback=callback;}JS_PUBLIC_API(void)JS_SetCompartmentNameCallback(JSRuntime*rt,JSCompartmentNameCallbackcallback){rt->compartmentNameCallback=callback;}JS_PUBLIC_API(void)JS_SetWrapObjectCallbacks(JSRuntime*rt,constJSWrapObjectCallbacks*callbacks){rt->wrapObjectCallbacks=callbacks;}JS_PUBLIC_API(JSCompartment*)JS_EnterCompartment(JSContext*cx,JSObject*target){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);JSCompartment*oldCompartment=cx->compartment();cx->enterCompartment(target->compartment());returnoldCompartment;}JS_PUBLIC_API(void)JS_LeaveCompartment(JSContext*cx,JSCompartment*oldCompartment){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);cx->leaveCompartment(oldCompartment);}JSAutoCompartment::JSAutoCompartment(JSContext*cx,JSObject*targetMOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL):cx_(cx),oldCompartment_(cx->compartment()){AssertHeapIsIdleOrIterating(cx_);MOZ_GUARD_OBJECT_NOTIFIER_INIT;cx_->enterCompartment(target->compartment());}JSAutoCompartment::JSAutoCompartment(JSContext*cx,JSScript*targetMOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL):cx_(cx),oldCompartment_(cx->compartment()){AssertHeapIsIdleOrIterating(cx_);MOZ_GUARD_OBJECT_NOTIFIER_INIT;cx_->enterCompartment(target->compartment());}JSAutoCompartment::~JSAutoCompartment(){cx_->leaveCompartment(oldCompartment_);}JSAutoNullableCompartment::JSAutoNullableCompartment(JSContext*cx,JSObject*targetOrNullMOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL):cx_(cx),oldCompartment_(cx->compartment()){AssertHeapIsIdleOrIterating(cx_);MOZ_GUARD_OBJECT_NOTIFIER_INIT;if(targetOrNull){cx_->enterCompartment(targetOrNull->compartment());}else{cx_->enterNullCompartment();}}JSAutoNullableCompartment::~JSAutoNullableCompartment(){cx_->leaveCompartment(oldCompartment_);}JS_PUBLIC_API(void)JS_SetCompartmentPrivate(JSCompartment*compartment,void*data){compartment->data=data;}JS_PUBLIC_API(void*)JS_GetCompartmentPrivate(JSCompartment*compartment){returncompartment->data;}JS_PUBLIC_API(JSAddonId*)JS::NewAddonId(JSContext*cx,HandleStringstr){returnstatic_cast<JSAddonId*>(JS_AtomizeAndPinJSString(cx,str));}JS_PUBLIC_API(JSString*)JS::StringOfAddonId(JSAddonId*id){returnid;}JS_PUBLIC_API(JSAddonId*)JS::AddonIdOfObject(JSObject*obj){returnobj->compartment()->creationOptions().addonIdOrNull();}JS_PUBLIC_API(void)JS_SetZoneUserData(JS::Zone*zone,void*data){zone->data=data;}JS_PUBLIC_API(void*)JS_GetZoneUserData(JS::Zone*zone){returnzone->data;}JS_PUBLIC_API(bool)JS_WrapObject(JSContext*cx,MutableHandleObjectobjp){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);if(objp)JS::ExposeObjectToActiveJS(objp);returncx->compartment()->wrap(cx,objp);}JS_PUBLIC_API(bool)JS_WrapValue(JSContext*cx,MutableHandleValuevp){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);JS::ExposeValueToActiveJS(vp);returncx->compartment()->wrap(cx,vp);}/* * Identity remapping. Not for casual consumers. * * Normally, an object's contents and its identity are inextricably linked. * Identity is determined by the address of the JSObject* in the heap, and * the contents are what is located at that address. Transplanting allows these * concepts to be separated through a combination of swapping (exchanging the * contents of two same-compartment objects) and remapping cross-compartment * identities by altering wrappers. * * The |origobj| argument should be the object whose identity needs to be * remapped, usually to another compartment. The contents of |origobj| are * destroyed. * * The |target| argument serves two purposes: * * First, |target| serves as a hint for the new identity of the object. The new * identity object will always be in the same compartment as |target|, but * if that compartment already had an object representing |origobj| (either a * cross-compartment wrapper for it, or |origobj| itself if the two arguments * are same-compartment), the existing object is used. Otherwise, |target| * itself is used. To avoid ambiguity, JS_TransplantObject always returns the * new identity. * * Second, the new identity object's contents will be those of |target|. A swap() * is used to make this happen if an object other than |target| is used. * * We don't have a good way to recover from failure in this function, so * we intentionally crash instead. */JS_PUBLIC_API(JSObject*)JS_TransplantObject(JSContext*cx,HandleObjectorigobj,HandleObjecttarget){AssertHeapIsIdle(cx);MOZ_ASSERT(origobj!=target);MOZ_ASSERT(!origobj->is<CrossCompartmentWrapperObject>());MOZ_ASSERT(!target->is<CrossCompartmentWrapperObject>());RootedValueorigv(cx,ObjectValue(*origobj));RootedObjectnewIdentity(cx);// Don't allow a compacting GC to observe any intermediate state.AutoDisableCompactingGCnocgc(cx->runtime());AutoDisableProxyCheckadpc(cx->runtime());JSCompartment*destination=target->compartment();if(origobj->compartment()==destination){// If the original object is in the same compartment as the// destination, then we know that we won't find a wrapper in the// destination's cross compartment map and that the same// object will continue to work.if(!JSObject::swap(cx,origobj,target))MOZ_CRASH();newIdentity=origobj;}elseif(WrapperMap::Ptrp=destination->lookupWrapper(origv)){// There might already be a wrapper for the original object in// the new compartment. If there is, we use its identity and swap// in the contents of |target|.newIdentity=&p->value().get().toObject();// When we remove origv from the wrapper map, its wrapper, newIdentity,// must immediately cease to be a cross-compartment wrapper. Nuke it.destination->removeWrapper(p);NukeCrossCompartmentWrapper(cx,newIdentity);if(!JSObject::swap(cx,newIdentity,target))MOZ_CRASH();}else{// Otherwise, we use |target| for the new identity object.newIdentity=target;}// Now, iterate through other scopes looking for references to the// old object, and update the relevant cross-compartment wrappers.if(!RemapAllWrappersForObject(cx,origobj,newIdentity))MOZ_CRASH();// Lastly, update the original object to point to the new one.if(origobj->compartment()!=destination){RootedObjectnewIdentityWrapper(cx,newIdentity);AutoCompartmentac(cx,origobj);if(!JS_WrapObject(cx,&newIdentityWrapper))MOZ_CRASH();MOZ_ASSERT(Wrapper::wrappedObject(newIdentityWrapper)==newIdentity);if(!JSObject::swap(cx,origobj,newIdentityWrapper))MOZ_CRASH();if(!origobj->compartment()->putWrapper(cx,CrossCompartmentKey(newIdentity),origv))MOZ_CRASH();}// The new identity object might be one of several things. Return it to avoid// ambiguity.returnnewIdentity;}/* * Recompute all cross-compartment wrappers for an object, resetting state. * Gecko uses this to clear Xray wrappers when doing a navigation that reuses * the inner window and global object. */JS_PUBLIC_API(bool)JS_RefreshCrossCompartmentWrappers(JSContext*cx,HandleObjectobj){returnRemapAllWrappersForObject(cx,obj,obj);}JS_PUBLIC_API(bool)JS_InitStandardClasses(JSContext*cx,HandleObjectobj){MOZ_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));AssertHeapIsIdle(cx);CHECK_REQUEST(cx);assertSameCompartment(cx,obj);Rooted<GlobalObject*>global(cx,&obj->global());returnGlobalObject::initStandardClasses(cx,global);}#define EAGER_ATOM(name) NAME_OFFSET(name)typedefstructJSStdName{size_tatomOffset;/* offset of atom pointer in JSAtomState */JSProtoKeykey;boolisDummy()const{returnkey==JSProto_Null;}boolisSentinel()const{returnkey==JSProto_LIMIT;}}JSStdName;staticconstJSStdName*LookupStdName(constJSAtomState&names,JSAtom*name,constJSStdName*table){for(unsignedi=0;!table[i].isSentinel();i++){if(table[i].isDummy())continue;JSAtom*atom=AtomStateOffsetToName(names,table[i].atomOffset);MOZ_ASSERT(atom);if(name==atom)return&table[i];}returnnullptr;}/* * Table of standard classes, indexed by JSProtoKey. For entries where the * JSProtoKey does not correspond to a class with a meaningful constructor, we * insert a null entry into the table. */#define STD_NAME_ENTRY(name, code, init, clasp) { EAGER_ATOM(name), static_cast<JSProtoKey>(code) },#define STD_DUMMY_ENTRY(name, code, init, dummy) { 0, JSProto_Null },staticconstJSStdNamestandard_class_names[]={JS_FOR_PROTOTYPES(STD_NAME_ENTRY,STD_DUMMY_ENTRY){0,JSProto_LIMIT}};/* * Table of top-level function and constant names and the JSProtoKey of the * standard class that initializes them. */staticconstJSStdNamebuiltin_property_names[]={{EAGER_ATOM(eval),JSProto_Object},/* Global properties and functions defined by the Number class. */{EAGER_ATOM(NaN),JSProto_Number},{EAGER_ATOM(Infinity),JSProto_Number},{EAGER_ATOM(isNaN),JSProto_Number},{EAGER_ATOM(isFinite),JSProto_Number},{EAGER_ATOM(parseFloat),JSProto_Number},{EAGER_ATOM(parseInt),JSProto_Number},/* String global functions. */{EAGER_ATOM(escape),JSProto_String},{EAGER_ATOM(unescape),JSProto_String},{EAGER_ATOM(decodeURI),JSProto_String},{EAGER_ATOM(encodeURI),JSProto_String},{EAGER_ATOM(decodeURIComponent),JSProto_String},{EAGER_ATOM(encodeURIComponent),JSProto_String},#if JS_HAS_UNEVAL{EAGER_ATOM(uneval),JSProto_String},#endif{0,JSProto_LIMIT}};#undef EAGER_ATOMJS_PUBLIC_API(bool)JS_ResolveStandardClass(JSContext*cx,HandleObjectobj,HandleIdid,bool*resolved){JSRuntime*rt;constJSStdName*stdnm;AssertHeapIsIdle(cx);CHECK_REQUEST(cx);assertSameCompartment(cx,obj,id);Rooted<GlobalObject*>global(cx,&obj->as<GlobalObject>());*resolved=false;rt=cx->runtime();if(!rt->hasContexts()||!JSID_IS_ATOM(id))returntrue;/* Check whether we're resolving 'undefined', and define it if so. */JSAtom*idAtom=JSID_TO_ATOM(id);JSAtom*undefinedAtom=cx->names().undefined;if(idAtom==undefinedAtom){*resolved=true;returnDefineProperty(cx,global,id,UndefinedHandleValue,nullptr,nullptr,JSPROP_PERMANENT|JSPROP_READONLY|JSPROP_RESOLVING);}/* Try for class constructors/prototypes named by well-known atoms. */stdnm=LookupStdName(cx->names(),idAtom,standard_class_names);/* Try less frequently used top-level functions and constants. */if(!stdnm)stdnm=LookupStdName(cx->names(),idAtom,builtin_property_names);if(stdnm&&GlobalObject::skipDeselectedConstructor(cx,stdnm->key))stdnm=nullptr;// If this class is anonymous, then it doesn't exist as a global// property, so we won't resolve anything.JSProtoKeykey=stdnm?stdnm->key:JSProto_Null;if(key!=JSProto_Null){constClass*clasp=ProtoKeyToClass(key);if(!clasp||!(clasp->flags&JSCLASS_IS_ANONYMOUS)){if(!GlobalObject::ensureConstructor(cx,global,key))returnfalse;*resolved=true;returntrue;}}// There is no such property to resolve. An ordinary resolve hook would// just return true at this point. But the global object is special in one// more way: its prototype chain is lazily initialized. That is,// global->getProto() might be null right now because we haven't created// Object.prototype yet. Force it now.if(!global->getOrCreateObjectPrototype(cx))returnfalse;returntrue;}JS_PUBLIC_API(bool)JS_MayResolveStandardClass(constJSAtomState&names,jsidid,JSObject*maybeObj){MOZ_ASSERT_IF(maybeObj,maybeObj->is<GlobalObject>());// The global object's resolve hook is special: JS_ResolveStandardClass// initializes the prototype chain lazily. Only attempt to optimize here// if we know the prototype chain has been initialized.if(!maybeObj||!maybeObj->getProto())returntrue;if(!JSID_IS_ATOM(id))returnfalse;JSAtom*atom=JSID_TO_ATOM(id);// This will return true even for deselected constructors. (To do// better, we need a JSContext here; it's fine as it is.)returnatom==names.undefined||LookupStdName(names,atom,standard_class_names)||LookupStdName(names,atom,builtin_property_names);}JS_PUBLIC_API(bool)JS_EnumerateStandardClasses(JSContext*cx,HandleObjectobj){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);assertSameCompartment(cx,obj);MOZ_ASSERT(obj->is<GlobalObject>());Rooted<GlobalObject*>global(cx,&obj->as<GlobalObject>());returnGlobalObject::initStandardClasses(cx,global);}JS_PUBLIC_API(bool)JS_GetClassObject(JSContext*cx,JSProtoKeykey,MutableHandleObjectobjp){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);returnGetBuiltinConstructor(cx,key,objp);}JS_PUBLIC_API(bool)JS_GetClassPrototype(JSContext*cx,JSProtoKeykey,MutableHandleObjectobjp){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);returnGetBuiltinPrototype(cx,key,objp);}namespaceJS{JS_PUBLIC_API(void)ProtoKeyToId(JSContext*cx,JSProtoKeykey,MutableHandleIdidp){idp.set(NameToId(ClassName(key,cx)));}}/* namespace JS */JS_PUBLIC_API(JSProtoKey)JS_IdToProtoKey(JSContext*cx,HandleIdid){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);if(!JSID_IS_ATOM(id))returnJSProto_Null;JSAtom*atom=JSID_TO_ATOM(id);constJSStdName*stdnm=LookupStdName(cx->names(),atom,standard_class_names);if(!stdnm)returnJSProto_Null;if(GlobalObject::skipDeselectedConstructor(cx,stdnm->key))returnJSProto_Null;MOZ_ASSERT(MOZ_ARRAY_LENGTH(standard_class_names)==JSProto_LIMIT+1);returnstatic_cast<JSProtoKey>(stdnm-standard_class_names);}JS_PUBLIC_API(JSObject*)JS_GetObjectPrototype(JSContext*cx,HandleObjectforObj){CHECK_REQUEST(cx);assertSameCompartment(cx,forObj);returnforObj->global().getOrCreateObjectPrototype(cx);}JS_PUBLIC_API(JSObject*)JS_GetFunctionPrototype(JSContext*cx,HandleObjectforObj){CHECK_REQUEST(cx);assertSameCompartment(cx,forObj);returnforObj->global().getOrCreateFunctionPrototype(cx);}JS_PUBLIC_API(JSObject*)JS_GetArrayPrototype(JSContext*cx,HandleObjectforObj){CHECK_REQUEST(cx);assertSameCompartment(cx,forObj);Rooted<GlobalObject*>global(cx,&forObj->global());returnGlobalObject::getOrCreateArrayPrototype(cx,global);}JS_PUBLIC_API(JSObject*)JS_GetErrorPrototype(JSContext*cx){CHECK_REQUEST(cx);Rooted<GlobalObject*>global(cx,cx->global());returnGlobalObject::getOrCreateCustomErrorPrototype(cx,global,JSEXN_ERR);}JS_PUBLIC_API(JSObject*)JS_GetIteratorPrototype(JSContext*cx){CHECK_REQUEST(cx);Rooted<GlobalObject*>global(cx,cx->global());returnGlobalObject::getOrCreateIteratorPrototype(cx,global);}JS_PUBLIC_API(JSObject*)JS_GetGlobalForObject(JSContext*cx,JSObject*obj){AssertHeapIsIdle(cx);assertSameCompartment(cx,obj);return&obj->global();}externJS_PUBLIC_API(bool)JS_IsGlobalObject(JSObject*obj){returnobj->is<GlobalObject>();}externJS_PUBLIC_API(JSObject*)JS_GlobalLexicalScope(JSObject*obj){return&obj->as<GlobalObject>().lexicalScope();}externJS_PUBLIC_API(bool)JS_HasExtensibleLexicalScope(JSObject*obj){returnobj->is<GlobalObject>()||obj->compartment()->getNonSyntacticLexicalScope(obj);}externJS_PUBLIC_API(JSObject*)JS_ExtensibleLexicalScope(JSObject*obj){JSObject*lexical=nullptr;if(obj->is<GlobalObject>())lexical=JS_GlobalLexicalScope(obj);elselexical=obj->compartment()->getNonSyntacticLexicalScope(obj);MOZ_ASSERT(lexical);returnlexical;}JS_PUBLIC_API(JSObject*)JS_GetGlobalForCompartmentOrNull(JSContext*cx,JSCompartment*c){AssertHeapIsIdleOrIterating(cx);assertSameCompartment(cx,c);returnc->maybeGlobal();}JS_PUBLIC_API(JSObject*)JS::CurrentGlobalOrNull(JSContext*cx){AssertHeapIsIdleOrIterating(cx);CHECK_REQUEST(cx);if(!cx->compartment())returnnullptr;returncx->global();}JS_PUBLIC_API(Value)JS_ComputeThis(JSContext*cx,Value*vp){AssertHeapIsIdle(cx);assertSameCompartment(cx,JSValueArray(vp,2));CallReceivercall=CallReceiverFromVp(vp);if(!BoxNonStrictThis(cx,call))returnNullValue();returncall.thisv();}JS_PUBLIC_API(void*)JS_malloc(JSContext*cx,size_tnbytes){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);returnstatic_cast<void*>(cx->runtime()->pod_malloc<uint8_t>(nbytes));}JS_PUBLIC_API(void*)JS_realloc(JSContext*cx,void*p,size_toldBytes,size_tnewBytes){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);returnstatic_cast<void*>(cx->zone()->pod_realloc<uint8_t>(static_cast<uint8_t*>(p),oldBytes,newBytes));}JS_PUBLIC_API(void)JS_free(JSContext*cx,void*p){returnjs_free(p);}JS_PUBLIC_API(void)JS_freeop(JSFreeOp*fop,void*p){returnFreeOp::get(fop)->free_(p);}JS_PUBLIC_API(JSFreeOp*)JS_GetDefaultFreeOp(JSRuntime*rt){returnrt->defaultFreeOp();}JS_PUBLIC_API(void)JS_updateMallocCounter(JSContext*cx,size_tnbytes){returncx->runtime()->updateMallocCounter(cx->zone(),nbytes);}JS_PUBLIC_API(char*)JS_strdup(JSContext*cx,constchar*s){AssertHeapIsIdle(cx);returnDuplicateString(cx,s).release();}JS_PUBLIC_API(char*)JS_strdup(JSRuntime*rt,constchar*s){AssertHeapIsIdle(rt);size_tn=strlen(s)+1;char*p=rt->pod_malloc<char>(n);if(!p)returnnullptr;returnstatic_cast<char*>(js_memcpy(p,s,n));}#undef JS_AddRootJS_PUBLIC_API(bool)JS_AddExtraGCRootsTracer(JSRuntime*rt,JSTraceDataOptraceOp,void*data){returnrt->gc.addBlackRootsTracer(traceOp,data);}JS_PUBLIC_API(void)JS_RemoveExtraGCRootsTracer(JSRuntime*rt,JSTraceDataOptraceOp,void*data){returnrt->gc.removeBlackRootsTracer(traceOp,data);}JS_PUBLIC_API(void)JS_GC(JSRuntime*rt){AssertHeapIsIdle(rt);JS::PrepareForFullGC(rt);rt->gc.gc(GC_NORMAL,JS::gcreason::API);}JS_PUBLIC_API(void)JS_MaybeGC(JSContext*cx){GCRuntime&gc=cx->runtime()->gc;if(!gc.maybeGC(cx->zone()))gc.maybePeriodicFullGC();}JS_PUBLIC_API(void)JS_SetGCCallback(JSRuntime*rt,JSGCCallbackcb,void*data){AssertHeapIsIdle(rt);rt->gc.setGCCallback(cb,data);}JS_PUBLIC_API(void)JS_SetObjectsTenuredCallback(JSRuntime*rt,JSObjectsTenuredCallbackcb,void*data){AssertHeapIsIdle(rt);rt->gc.setObjectsTenuredCallback(cb,data);}JS_PUBLIC_API(bool)JS_AddFinalizeCallback(JSRuntime*rt,JSFinalizeCallbackcb,void*data){AssertHeapIsIdle(rt);returnrt->gc.addFinalizeCallback(cb,data);}JS_PUBLIC_API(void)JS_RemoveFinalizeCallback(JSRuntime*rt,JSFinalizeCallbackcb){rt->gc.removeFinalizeCallback(cb);}JS_PUBLIC_API(bool)JS_AddWeakPointerZoneGroupCallback(JSRuntime*rt,JSWeakPointerZoneGroupCallbackcb,void*data){AssertHeapIsIdle(rt);returnrt->gc.addWeakPointerZoneGroupCallback(cb,data);}JS_PUBLIC_API(void)JS_RemoveWeakPointerZoneGroupCallback(JSRuntime*rt,JSWeakPointerZoneGroupCallbackcb){rt->gc.removeWeakPointerZoneGroupCallback(cb);}JS_PUBLIC_API(bool)JS_AddWeakPointerCompartmentCallback(JSRuntime*rt,JSWeakPointerCompartmentCallbackcb,void*data){AssertHeapIsIdle(rt);returnrt->gc.addWeakPointerCompartmentCallback(cb,data);}JS_PUBLIC_API(void)JS_RemoveWeakPointerCompartmentCallback(JSRuntime*rt,JSWeakPointerCompartmentCallbackcb){rt->gc.removeWeakPointerCompartmentCallback(cb);}JS_PUBLIC_API(void)JS_UpdateWeakPointerAfterGC(JS::Heap<JSObject*>*objp){JS_UpdateWeakPointerAfterGCUnbarriered(objp->unsafeGet());}JS_PUBLIC_API(void)JS_UpdateWeakPointerAfterGCUnbarriered(JSObject**objp){if(IsAboutToBeFinalizedUnbarriered(objp))*objp=nullptr;}JS_PUBLIC_API(void)JS_SetGCParameter(JSRuntime*rt,JSGCParamKeykey,uint32_tvalue){rt->gc.waitBackgroundSweepEnd();AutoLockGClock(rt);MOZ_ALWAYS_TRUE(rt->gc.setParameter(key,value,lock));}JS_PUBLIC_API(uint32_t)JS_GetGCParameter(JSRuntime*rt,JSGCParamKeykey){AutoLockGClock(rt);returnrt->gc.getParameter(key,lock);}staticconstsize_tNumGCConfigs=14;structJSGCConfig{JSGCParamKeykey;uint32_tvalue;};JS_PUBLIC_API(void)JS_SetGCParametersBasedOnAvailableMemory(JSRuntime*rt,uint32_tavailMem){staticconstJSGCConfigminimal[NumGCConfigs]={{JSGC_MAX_MALLOC_BYTES,6*1024*1024},{JSGC_SLICE_TIME_BUDGET,30},{JSGC_HIGH_FREQUENCY_TIME_LIMIT,1500},{JSGC_HIGH_FREQUENCY_HIGH_LIMIT,40},{JSGC_HIGH_FREQUENCY_LOW_LIMIT,0},{JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MAX,300},{JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MIN,120},{JSGC_LOW_FREQUENCY_HEAP_GROWTH,120},{JSGC_HIGH_FREQUENCY_TIME_LIMIT,1500},{JSGC_HIGH_FREQUENCY_TIME_LIMIT,1500},{JSGC_HIGH_FREQUENCY_TIME_LIMIT,1500},{JSGC_ALLOCATION_THRESHOLD,1},{JSGC_DECOMMIT_THRESHOLD,1},{JSGC_MODE,JSGC_MODE_INCREMENTAL}};constJSGCConfig*config=minimal;if(availMem>512){staticconstJSGCConfignominal[NumGCConfigs]={{JSGC_MAX_MALLOC_BYTES,6*1024*1024},{JSGC_SLICE_TIME_BUDGET,30},{JSGC_HIGH_FREQUENCY_TIME_LIMIT,1000},{JSGC_HIGH_FREQUENCY_HIGH_LIMIT,500},{JSGC_HIGH_FREQUENCY_LOW_LIMIT,100},{JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MAX,300},{JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MIN,150},{JSGC_LOW_FREQUENCY_HEAP_GROWTH,150},{JSGC_HIGH_FREQUENCY_TIME_LIMIT,1500},{JSGC_HIGH_FREQUENCY_TIME_LIMIT,1500},{JSGC_HIGH_FREQUENCY_TIME_LIMIT,1500},{JSGC_ALLOCATION_THRESHOLD,30},{JSGC_DECOMMIT_THRESHOLD,32},{JSGC_MODE,JSGC_MODE_COMPARTMENT}};config=nominal;}for(size_ti=0;i<NumGCConfigs;i++)JS_SetGCParameter(rt,config[i].key,config[i].value);}JS_PUBLIC_API(JSString*)JS_NewExternalString(JSContext*cx,constchar16_t*chars,size_tlength,constJSStringFinalizer*fin){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);JSString*s=JSExternalString::new_(cx,chars,length,fin);returns;}externJS_PUBLIC_API(bool)JS_IsExternalString(JSString*str){returnstr->isExternal();}externJS_PUBLIC_API(constJSStringFinalizer*)JS_GetExternalStringFinalizer(JSString*str){returnstr->asExternal().externalFinalizer();}staticvoidSetNativeStackQuotaAndLimit(JSRuntime*rt,StackKindkind,size_tstackSize){rt->nativeStackQuota[kind]=stackSize;#if JS_STACK_GROWTH_DIRECTION > 0if(stackSize==0){rt->mainThread.nativeStackLimit[kind]=UINTPTR_MAX;}else{MOZ_ASSERT(rt->nativeStackBase<=size_t(-1)-stackSize);rt->mainThread.nativeStackLimit[kind]=rt->nativeStackBase+stackSize-1;}#elseif(stackSize==0){rt->mainThread.nativeStackLimit[kind]=0;}else{MOZ_ASSERT(rt->nativeStackBase>=stackSize);rt->mainThread.nativeStackLimit[kind]=rt->nativeStackBase-(stackSize-1);}#endif}JS_PUBLIC_API(void)JS_SetNativeStackQuota(JSRuntime*rt,size_tsystemCodeStackSize,size_ttrustedScriptStackSize,size_tuntrustedScriptStackSize){MOZ_ASSERT(rt->requestDepth==0);if(!trustedScriptStackSize)trustedScriptStackSize=systemCodeStackSize;elseMOZ_ASSERT(trustedScriptStackSize<systemCodeStackSize);if(!untrustedScriptStackSize)untrustedScriptStackSize=trustedScriptStackSize;elseMOZ_ASSERT(untrustedScriptStackSize<trustedScriptStackSize);SetNativeStackQuotaAndLimit(rt,StackForSystemCode,systemCodeStackSize);SetNativeStackQuotaAndLimit(rt,StackForTrustedScript,trustedScriptStackSize);SetNativeStackQuotaAndLimit(rt,StackForUntrustedScript,untrustedScriptStackSize);rt->initJitStackLimit();}/************************************************************************/JS_PUBLIC_API(bool)JS_ValueToId(JSContext*cx,HandleValuevalue,MutableHandleIdidp){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);assertSameCompartment(cx,value);returnValueToId<CanGC>(cx,value,idp);}JS_PUBLIC_API(bool)JS_StringToId(JSContext*cx,HandleStringstring,MutableHandleIdidp){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);assertSameCompartment(cx,string);RootedValuevalue(cx,StringValue(string));returnValueToId<CanGC>(cx,value,idp);}JS_PUBLIC_API(bool)JS_IdToValue(JSContext*cx,jsidid,MutableHandleValuevp){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);vp.set(IdToValue(id));assertSameCompartment(cx,vp);returntrue;}JS_PUBLIC_API(bool)JS::ToPrimitive(JSContext*cx,HandleObjectobj,JSTypehint,MutableHandleValuevp){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);MOZ_ASSERT(obj!=nullptr);MOZ_ASSERT(hint==JSTYPE_VOID||hint==JSTYPE_STRING||hint==JSTYPE_NUMBER);vp.setObject(*obj);returnToPrimitiveSlow(cx,hint,vp);}JS_PUBLIC_API(bool)JS::GetFirstArgumentAsTypeHint(JSContext*cx,CallArgsargs,JSType*result){if(!args.get(0).isString()){JS_ReportErrorNumber(cx,GetErrorMessage,nullptr,JSMSG_NOT_EXPECTED_TYPE,"Symbol.toPrimitive","\"string\", \"number\", or \"default\"",InformalValueTypeName(args.get(0)));returnfalse;}RootedStringstr(cx,args.get(0).toString());boolmatch;if(!EqualStrings(cx,str,cx->names().default_,&match))returnfalse;if(match){*result=JSTYPE_VOID;returntrue;}if(!EqualStrings(cx,str,cx->names().string,&match))returnfalse;if(match){*result=JSTYPE_STRING;returntrue;}if(!EqualStrings(cx,str,cx->names().number,&match))returnfalse;if(match){*result=JSTYPE_NUMBER;returntrue;}JSAutoByteStringbytes;constchar*source=ValueToSourceForError(cx,args.get(0),bytes);if(!source){ReportOutOfMemory(cx);returnfalse;}JS_ReportErrorNumber(cx,GetErrorMessage,nullptr,JSMSG_NOT_EXPECTED_TYPE,"Symbol.toPrimitive","\"string\", \"number\", or \"default\"",source);returnfalse;}JS_PUBLIC_API(bool)JS_PropertyStub(JSContext*cx,HandleObjectobj,HandleIdid,MutableHandleValuevp){returntrue;}JS_PUBLIC_API(bool)JS_StrictPropertyStub(JSContext*cx,HandleObjectobj,HandleIdid,MutableHandleValuevp,ObjectOpResult&result){returnresult.succeed();}JS_PUBLIC_API(JSObject*)JS_InitClass(JSContext*cx,HandleObjectobj,HandleObjectparent_proto,constJSClass*clasp,JSNativeconstructor,unsignednargs,constJSPropertySpec*ps,constJSFunctionSpec*fs,constJSPropertySpec*static_ps,constJSFunctionSpec*static_fs){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);assertSameCompartment(cx,obj,parent_proto);returnInitClass(cx,obj,parent_proto,Valueify(clasp),constructor,nargs,ps,fs,static_ps,static_fs);}JS_PUBLIC_API(bool)JS_LinkConstructorAndPrototype(JSContext*cx,HandleObjectctor,HandleObjectproto){returnLinkConstructorAndPrototype(cx,ctor,proto);}JS_PUBLIC_API(constJSClass*)JS_GetClass(JSObject*obj){returnobj->getJSClass();}JS_PUBLIC_API(bool)JS_InstanceOf(JSContext*cx,HandleObjectobj,constJSClass*clasp,CallArgs*args){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);#ifdef DEBUGif(args){assertSameCompartment(cx,obj);assertSameCompartment(cx,args->thisv(),args->calleev());}#endifif(!obj||obj->getJSClass()!=clasp){if(args)ReportIncompatibleMethod(cx,*args,Valueify(clasp));returnfalse;}returntrue;}JS_PUBLIC_API(bool)JS_HasInstance(JSContext*cx,HandleObjectobj,HandleValuevalue,bool*bp){AssertHeapIsIdle(cx);assertSameCompartment(cx,obj,value);returnHasInstance(cx,obj,value,bp);}JS_PUBLIC_API(void*)JS_GetPrivate(JSObject*obj){/* This function can be called by a finalizer. */returnobj->as<NativeObject>().getPrivate();}JS_PUBLIC_API(void)JS_SetPrivate(JSObject*obj,void*data){/* This function can be called by a finalizer. */obj->as<NativeObject>().setPrivate(data);}JS_PUBLIC_API(void*)JS_GetInstancePrivate(JSContext*cx,HandleObjectobj,constJSClass*clasp,CallArgs*args){if(!JS_InstanceOf(cx,obj,clasp,args))returnnullptr;returnobj->as<NativeObject>().getPrivate();}JS_PUBLIC_API(JSObject*)JS_GetConstructor(JSContext*cx,HandleObjectproto){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);assertSameCompartment(cx,proto);RootedValuecval(cx);if(!GetProperty(cx,proto,proto,cx->names().constructor,&cval))returnnullptr;if(!IsFunctionObject(cval)){JS_ReportErrorNumber(cx,GetErrorMessage,nullptr,JSMSG_NO_CONSTRUCTOR,proto->getClass()->name);returnnullptr;}return&cval.toObject();}boolJS::CompartmentBehaviors::extraWarnings(JSRuntime*rt)const{returnextraWarningsOverride_.get(rt->options().extraWarnings());}boolJS::CompartmentBehaviors::extraWarnings(JSContext*cx)const{returnextraWarnings(cx->runtime());}JS::CompartmentCreationOptions&JS::CompartmentCreationOptions::setZone(ZoneSpecifierspec){zone_.spec=spec;return*this;}JS::CompartmentCreationOptions&JS::CompartmentCreationOptions::setSameZoneAs(JSObject*obj){zone_.pointer=static_cast<void*>(obj->zone());return*this;}constJS::CompartmentCreationOptions&JS::CompartmentCreationOptionsRef(JSCompartment*compartment){returncompartment->creationOptions();}constJS::CompartmentCreationOptions&JS::CompartmentCreationOptionsRef(JSObject*obj){returnobj->compartment()->creationOptions();}constJS::CompartmentCreationOptions&JS::CompartmentCreationOptionsRef(JSContext*cx){returncx->compartment()->creationOptions();}boolJS::CompartmentCreationOptions::getSharedMemoryAndAtomicsEnabled()const{#if defined(ENABLE_SHARED_ARRAY_BUFFER)returnsharedMemoryAndAtomics_;#elsereturnfalse;#endif}JS::CompartmentCreationOptions&JS::CompartmentCreationOptions::setSharedMemoryAndAtomicsEnabled(boolflag){#if defined(ENABLE_SHARED_ARRAY_BUFFER)sharedMemoryAndAtomics_=flag;#endifreturn*this;}JS::CompartmentBehaviors&JS::CompartmentBehaviorsRef(JSCompartment*compartment){returncompartment->behaviors();}JS::CompartmentBehaviors&JS::CompartmentBehaviorsRef(JSObject*obj){returnobj->compartment()->behaviors();}JS::CompartmentBehaviors&JS::CompartmentBehaviorsRef(JSContext*cx){returncx->compartment()->behaviors();}JS_PUBLIC_API(JSObject*)JS_NewGlobalObject(JSContext*cx,constJSClass*clasp,JSPrincipals*principals,JS::OnNewGlobalHookOptionhookOption,constJS::CompartmentOptions&options){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);returnGlobalObject::new_(cx,Valueify(clasp),principals,hookOption,options);}JS_PUBLIC_API(void)JS_GlobalObjectTraceHook(JSTracer*trc,JSObject*global){MOZ_ASSERT(global->is<GlobalObject>());// Off thread parsing and compilation tasks create a dummy global which is then// merged back into the host compartment. Since it used to be a global, it will still// have this trace hook, but it does not have a meaning relative to its new compartment.// We can safely skip it.if(!global->isOwnGlobal())return;// Trace the compartment for any GC things that should only stick around if we know the// compartment is live.global->compartment()->trace(trc);if(JSTraceOptrace=global->compartment()->creationOptions().getTrace())trace(trc,global);}JS_PUBLIC_API(void)JS_FireOnNewGlobalObject(JSContext*cx,JS::HandleObjectglobal){// This hook is infallible, because we don't really want arbitrary script// to be able to throw errors during delicate global creation routines.// This infallibility will eat OOM and slow script, but if that happens// we'll likely run up into them again soon in a fallible context.Rooted<js::GlobalObject*>globalObject(cx,&global->as<GlobalObject>());Debugger::onNewGlobalObject(cx,globalObject);}JS_PUBLIC_API(JSObject*)JS_NewObject(JSContext*cx,constJSClass*jsclasp){MOZ_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));AssertHeapIsIdle(cx);CHECK_REQUEST(cx);constClass*clasp=Valueify(jsclasp);if(!clasp)clasp=&PlainObject::class_;/* default class is Object */MOZ_ASSERT(clasp!=&JSFunction::class_);MOZ_ASSERT(!(clasp->flags&JSCLASS_IS_GLOBAL));returnNewObjectWithClassProto(cx,clasp,nullptr);}JS_PUBLIC_API(JSObject*)JS_NewObjectWithGivenProto(JSContext*cx,constJSClass*jsclasp,HandleObjectproto){MOZ_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));AssertHeapIsIdle(cx);CHECK_REQUEST(cx);assertSameCompartment(cx,proto);constClass*clasp=Valueify(jsclasp);if(!clasp)clasp=&PlainObject::class_;/* default class is Object */MOZ_ASSERT(clasp!=&JSFunction::class_);MOZ_ASSERT(!(clasp->flags&JSCLASS_IS_GLOBAL));returnNewObjectWithGivenProto(cx,clasp,proto);}JS_PUBLIC_API(JSObject*)JS_NewPlainObject(JSContext*cx){MOZ_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));AssertHeapIsIdle(cx);CHECK_REQUEST(cx);returnNewBuiltinClassInstance<PlainObject>(cx);}JS_PUBLIC_API(JSObject*)JS_NewObjectForConstructor(JSContext*cx,constJSClass*clasp,constCallArgs&args){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);Valuecallee=args.calleev();assertSameCompartment(cx,callee);RootedObjectobj(cx,&callee.toObject());returnCreateThis(cx,Valueify(clasp),obj);}JS_PUBLIC_API(bool)JS_IsNative(JSObject*obj){returnobj->isNative();}JS_PUBLIC_API(JSRuntime*)JS_GetObjectRuntime(JSObject*obj){returnobj->compartment()->runtimeFromMainThread();}/*** Standard internal methods *******************************************************************/JS_PUBLIC_API(bool)JS_GetPrototype(JSContext*cx,HandleObjectobj,MutableHandleObjectresult){returnGetPrototype(cx,obj,result);}JS_PUBLIC_API(bool)JS_SetPrototype(JSContext*cx,HandleObjectobj,HandleObjectproto){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);assertSameCompartment(cx,obj,proto);returnSetPrototype(cx,obj,proto);}JS_PUBLIC_API(bool)JS_IsExtensible(JSContext*cx,HandleObjectobj,bool*extensible){returnIsExtensible(cx,obj,extensible);}JS_PUBLIC_API(bool)JS_PreventExtensions(JSContext*cx,JS::HandleObjectobj,ObjectOpResult&result){returnPreventExtensions(cx,obj,result);}JS_PUBLIC_API(bool)JS_SetImmutablePrototype(JSContext*cx,JS::HandleObjectobj,bool*succeeded){returnSetImmutablePrototype(cx,obj,succeeded);}JS_PUBLIC_API(bool)JS_GetOwnPropertyDescriptorById(JSContext*cx,HandleObjectobj,HandleIdid,MutableHandle<PropertyDescriptor>desc){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);returnGetOwnPropertyDescriptor(cx,obj,id,desc);}JS_PUBLIC_API(bool)JS_GetOwnPropertyDescriptor(JSContext*cx,HandleObjectobj,constchar*name,MutableHandle<PropertyDescriptor>desc){JSAtom*atom=Atomize(cx,name,strlen(name));if(!atom)returnfalse;RootedIdid(cx,AtomToId(atom));returnJS_GetOwnPropertyDescriptorById(cx,obj,id,desc);}JS_PUBLIC_API(bool)JS_GetOwnUCPropertyDescriptor(JSContext*cx,HandleObjectobj,constchar16_t*name,MutableHandle<PropertyDescriptor>desc){JSAtom*atom=AtomizeChars(cx,name,js_strlen(name));if(!atom)returnfalse;RootedIdid(cx,AtomToId(atom));returnJS_GetOwnPropertyDescriptorById(cx,obj,id,desc);}JS_PUBLIC_API(bool)JS_GetPropertyDescriptorById(JSContext*cx,HandleObjectobj,HandleIdid,MutableHandle<PropertyDescriptor>desc){returnGetPropertyDescriptor(cx,obj,id,desc);}JS_PUBLIC_API(bool)JS_GetPropertyDescriptor(JSContext*cx,HandleObjectobj,constchar*name,MutableHandle<PropertyDescriptor>desc){JSAtom*atom=Atomize(cx,name,strlen(name));if(!atom)returnfalse;RootedIdid(cx,AtomToId(atom));returnatom&&JS_GetPropertyDescriptorById(cx,obj,id,desc);}staticboolDefinePropertyByDescriptor(JSContext*cx,HandleObjectobj,HandleIdid,Handle<PropertyDescriptor>desc,ObjectOpResult&result){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);assertSameCompartment(cx,obj,id,desc);returnDefineProperty(cx,obj,id,desc.value(),desc.getter(),desc.setter(),desc.attributes(),result);}JS_PUBLIC_API(bool)JS_DefinePropertyById(JSContext*cx,HandleObjectobj,HandleIdid,Handle<PropertyDescriptor>desc,ObjectOpResult&result){returnDefinePropertyByDescriptor(cx,obj,id,desc,result);}JS_PUBLIC_API(bool)JS_DefinePropertyById(JSContext*cx,HandleObjectobj,HandleIdid,Handle<PropertyDescriptor>desc){ObjectOpResultresult;returnDefinePropertyByDescriptor(cx,obj,id,desc,result)&&result.checkStrict(cx,obj,id);}staticboolDefinePropertyById(JSContext*cx,HandleObjectobj,HandleIdid,HandleValuevalue,constJSNativeWrapper&get,constJSNativeWrapper&set,unsignedattrs,unsignedflags){JSGetterOpgetter=JS_CAST_NATIVE_TO(get.op,JSGetterOp);JSSetterOpsetter=JS_CAST_NATIVE_TO(set.op,JSSetterOp);// JSPROP_READONLY has no meaning when accessors are involved. Ideally we'd// throw if this happens, but we've accepted it for long enough that it's// not worth trying to make callers change their ways. Just flip it off on// its way through the API layer so that we can enforce this internally.if(attrs&(JSPROP_GETTER|JSPROP_SETTER))attrs&=~JSPROP_READONLY;// When we use DefineProperty, we need full scriptable Function objects rather// than JSNatives. However, we might be pulling this property descriptor off// of something with JSNative property descriptors. If we are, wrap them in// JS Function objects.//// But skip doing this if our accessors are the well-known stub// accessors, since those are known to be JSGetterOps. Assert// some sanity about it, though.MOZ_ASSERT_IF(getter==JS_PropertyStub,setter==JS_StrictPropertyStub||(attrs&JSPROP_PROPOP_ACCESSORS));MOZ_ASSERT_IF(setter==JS_StrictPropertyStub,getter==JS_PropertyStub||(attrs&JSPROP_PROPOP_ACCESSORS));// If !(attrs & JSPROP_PROPOP_ACCESSORS), then either getter/setter are both// possibly-null JSNatives (or possibly-null JSFunction* if JSPROP_GETTER or// JSPROP_SETTER is appropriately set), or both are the well-known property// stubs. The subsequent block must handle only the first of these cases,// so carefully exclude the latter case.if(!(attrs&JSPROP_PROPOP_ACCESSORS)&&getter!=JS_PropertyStub&&setter!=JS_StrictPropertyStub){if(getter&&!(attrs&JSPROP_GETTER)){RootedAtomatom(cx,IdToFunctionName(cx,id,"get"));if(!atom)returnfalse;JSFunction*getobj=NewNativeFunction(cx,(Native)getter,0,atom);if(!getobj)returnfalse;if(get.info)getobj->setJitInfo(get.info);getter=JS_DATA_TO_FUNC_PTR(GetterOp,getobj);attrs|=JSPROP_GETTER;}if(setter&&!(attrs&JSPROP_SETTER)){// Root just the getter, since the setter is not yet a JSObject.AutoRooterGetterSettergetRoot(cx,JSPROP_GETTER,&getter,nullptr);RootedAtomatom(cx,IdToFunctionName(cx,id,"set"));if(!atom)returnfalse;JSFunction*setobj=NewNativeFunction(cx,(Native)setter,1,atom);if(!setobj)returnfalse;if(set.info)setobj->setJitInfo(set.info);setter=JS_DATA_TO_FUNC_PTR(SetterOp,setobj);attrs|=JSPROP_SETTER;}}else{attrs&=~JSPROP_PROPOP_ACCESSORS;}AssertHeapIsIdle(cx);CHECK_REQUEST(cx);assertSameCompartment(cx,obj,id,value,(attrs&JSPROP_GETTER)?JS_FUNC_TO_DATA_PTR(JSObject*,getter):nullptr,(attrs&JSPROP_SETTER)?JS_FUNC_TO_DATA_PTR(JSObject*,setter):nullptr);// In most places throughout the engine, a property with null getter and// not JSPROP_GETTER/SETTER/SHARED has no getter, and the same for setters:// it's just a plain old data property. However the JS_Define* APIs use// null getter and setter to mean "default to the Class getProperty and// setProperty ops".if(!(attrs&(JSPROP_GETTER|JSPROP_SETTER))){if(!getter)getter=obj->getClass()->getProperty;if(!setter)setter=obj->getClass()->setProperty;}if(getter==JS_PropertyStub)getter=nullptr;if(setter==JS_StrictPropertyStub)setter=nullptr;returnDefineProperty(cx,obj,id,value,getter,setter,attrs);}/* * Wrapper functions to create wrappers with no corresponding JSJitInfo from API * function arguments. */staticJSNativeWrapperNativeOpWrapper(Nativenative){JSNativeWrapperret;ret.op=native;ret.info=nullptr;returnret;}JS_PUBLIC_API(bool)JS_DefinePropertyById(JSContext*cx,HandleObjectobj,HandleIdid,HandleValuevalue,unsignedattrs,Nativegetter,Nativesetter){returnDefinePropertyById(cx,obj,id,value,NativeOpWrapper(getter),NativeOpWrapper(setter),attrs,0);}JS_PUBLIC_API(bool)JS_DefinePropertyById(JSContext*cx,HandleObjectobj,HandleIdid,HandleObjectvalueArg,unsignedattrs,Nativegetter,Nativesetter){RootedValuevalue(cx,ObjectValue(*valueArg));returnDefinePropertyById(cx,obj,id,value,NativeOpWrapper(getter),NativeOpWrapper(setter),attrs,0);}JS_PUBLIC_API(bool)JS_DefinePropertyById(JSContext*cx,HandleObjectobj,HandleIdid,HandleStringvalueArg,unsignedattrs,Nativegetter,Nativesetter){RootedValuevalue(cx,StringValue(valueArg));returnDefinePropertyById(cx,obj,id,value,NativeOpWrapper(getter),NativeOpWrapper(setter),attrs,0);}JS_PUBLIC_API(bool)JS_DefinePropertyById(JSContext*cx,HandleObjectobj,HandleIdid,int32_tvalueArg,unsignedattrs,Nativegetter,Nativesetter){Valuevalue=Int32Value(valueArg);returnDefinePropertyById(cx,obj,id,HandleValue::fromMarkedLocation(&value),NativeOpWrapper(getter),NativeOpWrapper(setter),attrs,0);}JS_PUBLIC_API(bool)JS_DefinePropertyById(JSContext*cx,HandleObjectobj,HandleIdid,uint32_tvalueArg,unsignedattrs,Nativegetter,Nativesetter){Valuevalue=NumberValue(valueArg);returnDefinePropertyById(cx,obj,id,HandleValue::fromMarkedLocation(&value),NativeOpWrapper(getter),NativeOpWrapper(setter),attrs,0);}JS_PUBLIC_API(bool)JS_DefinePropertyById(JSContext*cx,HandleObjectobj,HandleIdid,doublevalueArg,unsignedattrs,Nativegetter,Nativesetter){Valuevalue=NumberValue(valueArg);returnDefinePropertyById(cx,obj,id,HandleValue::fromMarkedLocation(&value),NativeOpWrapper(getter),NativeOpWrapper(setter),attrs,0);}staticboolDefineProperty(JSContext*cx,HandleObjectobj,constchar*name,HandleValuevalue,constJSNativeWrapper&getter,constJSNativeWrapper&setter,unsignedattrs,unsignedflags){AutoRooterGetterSettergsRoot(cx,attrs,const_cast<JSNative*>(&getter.op),const_cast<JSNative*>(&setter.op));JSAtom*atom=Atomize(cx,name,strlen(name));if(!atom)returnfalse;RootedIdid(cx,AtomToId(atom));returnDefinePropertyById(cx,obj,id,value,getter,setter,attrs,flags);}JS_PUBLIC_API(bool)JS_DefineProperty(JSContext*cx,HandleObjectobj,constchar*name,HandleValuevalue,unsignedattrs,Nativegetter/* = nullptr */,Nativesetter/* = nullptr */){returnDefineProperty(cx,obj,name,value,NativeOpWrapper(getter),NativeOpWrapper(setter),attrs,0);}JS_PUBLIC_API(bool)JS_DefineProperty(JSContext*cx,HandleObjectobj,constchar*name,HandleObjectvalueArg,unsignedattrs,Nativegetter/* = nullptr */,Nativesetter/* = nullptr */){RootedValuevalue(cx,ObjectValue(*valueArg));returnDefineProperty(cx,obj,name,value,NativeOpWrapper(getter),NativeOpWrapper(setter),attrs,0);}JS_PUBLIC_API(bool)JS_DefineProperty(JSContext*cx,HandleObjectobj,constchar*name,HandleStringvalueArg,unsignedattrs,Nativegetter/* = nullptr */,Nativesetter/* = nullptr */){RootedValuevalue(cx,StringValue(valueArg));returnDefineProperty(cx,obj,name,value,NativeOpWrapper(getter),NativeOpWrapper(setter),attrs,0);}JS_PUBLIC_API(bool)JS_DefineProperty(JSContext*cx,HandleObjectobj,constchar*name,int32_tvalueArg,unsignedattrs,Nativegetter/* = nullptr */,Nativesetter/* = nullptr */){Valuevalue=Int32Value(valueArg);returnDefineProperty(cx,obj,name,HandleValue::fromMarkedLocation(&value),NativeOpWrapper(getter),NativeOpWrapper(setter),attrs,0);}JS_PUBLIC_API(bool)JS_DefineProperty(JSContext*cx,HandleObjectobj,constchar*name,uint32_tvalueArg,unsignedattrs,Nativegetter/* = nullptr */,Nativesetter/* = nullptr */){Valuevalue=NumberValue(valueArg);returnDefineProperty(cx,obj,name,HandleValue::fromMarkedLocation(&value),NativeOpWrapper(getter),NativeOpWrapper(setter),attrs,0);}JS_PUBLIC_API(bool)JS_DefineProperty(JSContext*cx,HandleObjectobj,constchar*name,doublevalueArg,unsignedattrs,Nativegetter/* = nullptr */,Nativesetter/* = nullptr */){Valuevalue=NumberValue(valueArg);returnDefineProperty(cx,obj,name,HandleValue::fromMarkedLocation(&value),NativeOpWrapper(getter),NativeOpWrapper(setter),attrs,0);}#define AUTO_NAMELEN(s,n) (((n) == (size_t)-1) ? js_strlen(s) : (n))JS_PUBLIC_API(bool)JS_DefineUCProperty(JSContext*cx,HandleObjectobj,constchar16_t*name,size_tnamelen,Handle<PropertyDescriptor>desc,ObjectOpResult&result){JSAtom*atom=AtomizeChars(cx,name,AUTO_NAMELEN(name,namelen));if(!atom)returnfalse;RootedIdid(cx,AtomToId(atom));returnDefinePropertyByDescriptor(cx,obj,id,desc,result);}JS_PUBLIC_API(bool)JS_DefineUCProperty(JSContext*cx,HandleObjectobj,constchar16_t*name,size_tnamelen,Handle<PropertyDescriptor>desc){JSAtom*atom=AtomizeChars(cx,name,AUTO_NAMELEN(name,namelen));if(!atom)returnfalse;RootedIdid(cx,AtomToId(atom));ObjectOpResultresult;returnDefinePropertyByDescriptor(cx,obj,id,desc,result)&&result.checkStrict(cx,obj,id);}staticboolDefineUCProperty(JSContext*cx,HandleObjectobj,constchar16_t*name,size_tnamelen,constValue&value_,Nativegetter,Nativesetter,unsignedattrs,unsignedflags){RootedValuevalue(cx,value_);AutoRooterGetterSettergsRoot(cx,attrs,&getter,&setter);JSAtom*atom=AtomizeChars(cx,name,AUTO_NAMELEN(name,namelen));if(!atom)returnfalse;RootedIdid(cx,AtomToId(atom));returnDefinePropertyById(cx,obj,id,value,NativeOpWrapper(getter),NativeOpWrapper(setter),attrs,flags);}JS_PUBLIC_API(bool)JS_DefineUCProperty(JSContext*cx,HandleObjectobj,constchar16_t*name,size_tnamelen,HandleValuevalue,unsignedattrs,Nativegetter,Nativesetter){returnDefineUCProperty(cx,obj,name,namelen,value,getter,setter,attrs,0);}JS_PUBLIC_API(bool)JS_DefineUCProperty(JSContext*cx,HandleObjectobj,constchar16_t*name,size_tnamelen,HandleObjectvalueArg,unsignedattrs,Nativegetter,Nativesetter){RootedValuevalue(cx,ObjectValue(*valueArg));returnDefineUCProperty(cx,obj,name,namelen,value,getter,setter,attrs,0);}JS_PUBLIC_API(bool)JS_DefineUCProperty(JSContext*cx,HandleObjectobj,constchar16_t*name,size_tnamelen,HandleStringvalueArg,unsignedattrs,Nativegetter,Nativesetter){RootedValuevalue(cx,StringValue(valueArg));returnDefineUCProperty(cx,obj,name,namelen,value,getter,setter,attrs,0);}JS_PUBLIC_API(bool)JS_DefineUCProperty(JSContext*cx,HandleObjectobj,constchar16_t*name,size_tnamelen,int32_tvalueArg,unsignedattrs,Nativegetter,Nativesetter){Valuevalue=Int32Value(valueArg);returnDefineUCProperty(cx,obj,name,namelen,HandleValue::fromMarkedLocation(&value),getter,setter,attrs,0);}JS_PUBLIC_API(bool)JS_DefineUCProperty(JSContext*cx,HandleObjectobj,constchar16_t*name,size_tnamelen,uint32_tvalueArg,unsignedattrs,Nativegetter,Nativesetter){Valuevalue=NumberValue(valueArg);returnDefineUCProperty(cx,obj,name,namelen,HandleValue::fromMarkedLocation(&value),getter,setter,attrs,0);}JS_PUBLIC_API(bool)JS_DefineUCProperty(JSContext*cx,HandleObjectobj,constchar16_t*name,size_tnamelen,doublevalueArg,unsignedattrs,Nativegetter,Nativesetter){Valuevalue=NumberValue(valueArg);returnDefineUCProperty(cx,obj,name,namelen,HandleValue::fromMarkedLocation(&value),getter,setter,attrs,0);}staticboolDefineElement(JSContext*cx,HandleObjectobj,uint32_tindex,HandleValuevalue,unsignedattrs,Nativegetter,Nativesetter){AutoRooterGetterSettergsRoot(cx,attrs,&getter,&setter);AssertHeapIsIdle(cx);CHECK_REQUEST(cx);RootedIdid(cx);if(!IndexToId(cx,index,&id))returnfalse;returnDefinePropertyById(cx,obj,id,value,NativeOpWrapper(getter),NativeOpWrapper(setter),attrs,0);}JS_PUBLIC_API(bool)JS_DefineElement(JSContext*cx,HandleObjectobj,uint32_tindex,HandleValuevalue,unsignedattrs,Nativegetter,Nativesetter){returnDefineElement(cx,obj,index,value,attrs,getter,setter);}JS_PUBLIC_API(bool)JS_DefineElement(JSContext*cx,HandleObjectobj,uint32_tindex,HandleObjectvalueArg,unsignedattrs,Nativegetter,Nativesetter){RootedValuevalue(cx,ObjectValue(*valueArg));returnDefineElement(cx,obj,index,value,attrs,getter,setter);}JS_PUBLIC_API(bool)JS_DefineElement(JSContext*cx,HandleObjectobj,uint32_tindex,HandleStringvalueArg,unsignedattrs,Nativegetter,Nativesetter){RootedValuevalue(cx,StringValue(valueArg));returnDefineElement(cx,obj,index,value,attrs,getter,setter);}JS_PUBLIC_API(bool)JS_DefineElement(JSContext*cx,HandleObjectobj,uint32_tindex,int32_tvalueArg,unsignedattrs,Nativegetter,Nativesetter){Valuevalue=Int32Value(valueArg);returnDefineElement(cx,obj,index,HandleValue::fromMarkedLocation(&value),attrs,getter,setter);}JS_PUBLIC_API(bool)JS_DefineElement(JSContext*cx,HandleObjectobj,uint32_tindex,uint32_tvalueArg,unsignedattrs,Nativegetter,Nativesetter){Valuevalue=NumberValue(valueArg);returnDefineElement(cx,obj,index,HandleValue::fromMarkedLocation(&value),attrs,getter,setter);}JS_PUBLIC_API(bool)JS_DefineElement(JSContext*cx,HandleObjectobj,uint32_tindex,doublevalueArg,unsignedattrs,Nativegetter,Nativesetter){Valuevalue=NumberValue(valueArg);returnDefineElement(cx,obj,index,HandleValue::fromMarkedLocation(&value),attrs,getter,setter);}JS_PUBLIC_API(bool)JS_HasPropertyById(JSContext*cx,HandleObjectobj,HandleIdid,bool*foundp){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);returnHasProperty(cx,obj,id,foundp);}JS_PUBLIC_API(bool)JS_HasProperty(JSContext*cx,HandleObjectobj,constchar*name,bool*foundp){JSAtom*atom=Atomize(cx,name,strlen(name));if(!atom)returnfalse;RootedIdid(cx,AtomToId(atom));returnJS_HasPropertyById(cx,obj,id,foundp);}JS_PUBLIC_API(bool)JS_HasUCProperty(JSContext*cx,HandleObjectobj,constchar16_t*name,size_tnamelen,bool*foundp){JSAtom*atom=AtomizeChars(cx,name,AUTO_NAMELEN(name,namelen));if(!atom)returnfalse;RootedIdid(cx,AtomToId(atom));returnJS_HasPropertyById(cx,obj,id,foundp);}JS_PUBLIC_API(bool)JS_HasElement(JSContext*cx,HandleObjectobj,uint32_tindex,bool*foundp){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);RootedIdid(cx);if(!IndexToId(cx,index,&id))returnfalse;returnJS_HasPropertyById(cx,obj,id,foundp);}JS_PUBLIC_API(bool)JS_HasOwnPropertyById(JSContext*cx,HandleObjectobj,HandleIdid,bool*foundp){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);assertSameCompartment(cx,obj,id);returnHasOwnProperty(cx,obj,id,foundp);}JS_PUBLIC_API(bool)JS_HasOwnProperty(JSContext*cx,HandleObjectobj,constchar*name,bool*foundp){JSAtom*atom=Atomize(cx,name,strlen(name));if(!atom)returnfalse;RootedIdid(cx,AtomToId(atom));returnJS_HasOwnPropertyById(cx,obj,id,foundp);}JS_PUBLIC_API(bool)JS_ForwardGetPropertyTo(JSContext*cx,HandleObjectobj,HandleIdid,HandleValuereceiver,MutableHandleValuevp){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);assertSameCompartment(cx,obj,id,receiver);returnGetProperty(cx,obj,receiver,id,vp);}JS_PUBLIC_API(bool)JS_ForwardGetElementTo(JSContext*cx,HandleObjectobj,uint32_tindex,HandleObjectreceiver,MutableHandleValuevp){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);assertSameCompartment(cx,obj);returnGetElement(cx,obj,receiver,index,vp);}JS_PUBLIC_API(bool)JS_GetPropertyById(JSContext*cx,HandleObjectobj,HandleIdid,MutableHandleValuevp){RootedValuereceiver(cx,ObjectValue(*obj));returnJS_ForwardGetPropertyTo(cx,obj,id,receiver,vp);}JS_PUBLIC_API(bool)JS_GetProperty(JSContext*cx,HandleObjectobj,constchar*name,MutableHandleValuevp){JSAtom*atom=Atomize(cx,name,strlen(name));if(!atom)returnfalse;RootedIdid(cx,AtomToId(atom));returnJS_GetPropertyById(cx,obj,id,vp);}JS_PUBLIC_API(bool)JS_GetUCProperty(JSContext*cx,HandleObjectobj,constchar16_t*name,size_tnamelen,MutableHandleValuevp){JSAtom*atom=AtomizeChars(cx,name,AUTO_NAMELEN(name,namelen));if(!atom)returnfalse;RootedIdid(cx,AtomToId(atom));returnJS_GetPropertyById(cx,obj,id,vp);}JS_PUBLIC_API(bool)JS_GetElement(JSContext*cx,HandleObjectobjArg,uint32_tindex,MutableHandleValuevp){returnJS_ForwardGetElementTo(cx,objArg,index,objArg,vp);}JS_PUBLIC_API(bool)JS_ForwardSetPropertyTo(JSContext*cx,HandleObjectobj,HandleIdid,HandleValuev,HandleValuereceiver,ObjectOpResult&result){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);assertSameCompartment(cx,obj,id,receiver);returnSetProperty(cx,obj,id,v,receiver,result);}JS_PUBLIC_API(bool)JS_SetPropertyById(JSContext*cx,HandleObjectobj,HandleIdid,HandleValuev){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);assertSameCompartment(cx,obj,id);RootedValuereceiver(cx,ObjectValue(*obj));ObjectOpResultignored;returnSetProperty(cx,obj,id,v,receiver,ignored);}JS_PUBLIC_API(bool)JS_SetProperty(JSContext*cx,HandleObjectobj,constchar*name,HandleValuev){JSAtom*atom=Atomize(cx,name,strlen(name));if(!atom)returnfalse;RootedIdid(cx,AtomToId(atom));returnJS_SetPropertyById(cx,obj,id,v);}JS_PUBLIC_API(bool)JS_SetUCProperty(JSContext*cx,HandleObjectobj,constchar16_t*name,size_tnamelen,HandleValuev){JSAtom*atom=AtomizeChars(cx,name,AUTO_NAMELEN(name,namelen));if(!atom)returnfalse;RootedIdid(cx,AtomToId(atom));returnJS_SetPropertyById(cx,obj,id,v);}staticboolSetElement(JSContext*cx,HandleObjectobj,uint32_tindex,HandleValuev){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);assertSameCompartment(cx,obj,v);RootedValuereceiver(cx,ObjectValue(*obj));ObjectOpResultignored;returnSetElement(cx,obj,index,v,receiver,ignored);}JS_PUBLIC_API(bool)JS_SetElement(JSContext*cx,HandleObjectobj,uint32_tindex,HandleValuev){returnSetElement(cx,obj,index,v);}JS_PUBLIC_API(bool)JS_SetElement(JSContext*cx,HandleObjectobj,uint32_tindex,HandleObjectv){RootedValuevalue(cx,ObjectOrNullValue(v));returnSetElement(cx,obj,index,value);}JS_PUBLIC_API(bool)JS_SetElement(JSContext*cx,HandleObjectobj,uint32_tindex,HandleStringv){RootedValuevalue(cx,StringValue(v));returnSetElement(cx,obj,index,value);}JS_PUBLIC_API(bool)JS_SetElement(JSContext*cx,HandleObjectobj,uint32_tindex,int32_tv){RootedValuevalue(cx,NumberValue(v));returnSetElement(cx,obj,index,value);}JS_PUBLIC_API(bool)JS_SetElement(JSContext*cx,HandleObjectobj,uint32_tindex,uint32_tv){RootedValuevalue(cx,NumberValue(v));returnSetElement(cx,obj,index,value);}JS_PUBLIC_API(bool)JS_SetElement(JSContext*cx,HandleObjectobj,uint32_tindex,doublev){RootedValuevalue(cx,NumberValue(v));returnSetElement(cx,obj,index,value);}JS_PUBLIC_API(bool)JS_DeletePropertyById(JSContext*cx,HandleObjectobj,HandleIdid,ObjectOpResult&result){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);assertSameCompartment(cx,obj,id);returnDeleteProperty(cx,obj,id,result);}JS_PUBLIC_API(bool)JS_DeleteProperty(JSContext*cx,HandleObjectobj,constchar*name,ObjectOpResult&result){CHECK_REQUEST(cx);assertSameCompartment(cx,obj);JSAtom*atom=Atomize(cx,name,strlen(name));if(!atom)returnfalse;RootedIdid(cx,AtomToId(atom));returnDeleteProperty(cx,obj,id,result);}JS_PUBLIC_API(bool)JS_DeleteUCProperty(JSContext*cx,HandleObjectobj,constchar16_t*name,size_tnamelen,ObjectOpResult&result){CHECK_REQUEST(cx);assertSameCompartment(cx,obj);JSAtom*atom=AtomizeChars(cx,name,AUTO_NAMELEN(name,namelen));if(!atom)returnfalse;RootedIdid(cx,AtomToId(atom));returnDeleteProperty(cx,obj,id,result);}JS_PUBLIC_API(bool)JS_DeleteElement(JSContext*cx,HandleObjectobj,uint32_tindex,ObjectOpResult&result){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);assertSameCompartment(cx,obj);returnDeleteElement(cx,obj,index,result);}JS_PUBLIC_API(bool)JS_DeletePropertyById(JSContext*cx,HandleObjectobj,HandleIdid){ObjectOpResultignored;returnJS_DeletePropertyById(cx,obj,id,ignored);}JS_PUBLIC_API(bool)JS_DeleteProperty(JSContext*cx,HandleObjectobj,constchar*name){ObjectOpResultignored;returnJS_DeleteProperty(cx,obj,name,ignored);}JS_PUBLIC_API(bool)JS_DeleteElement(JSContext*cx,HandleObjectobj,uint32_tindex){ObjectOpResultignored;returnJS_DeleteElement(cx,obj,index,ignored);}JS_PUBLIC_API(bool)JS_Enumerate(JSContext*cx,HandleObjectobj,JS::MutableHandle<IdVector>props){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);assertSameCompartment(cx,obj);MOZ_ASSERT(props.empty());AutoIdVectorids(cx);if(!GetPropertyKeys(cx,obj,JSITER_OWNONLY,&ids))returnfalse;returnprops.append(ids.begin(),ids.end());}JS_PUBLIC_API(bool)JS::IsCallable(JSObject*obj){returnobj->isCallable();}JS_PUBLIC_API(bool)JS::IsConstructor(JSObject*obj){returnobj->isConstructor();}structAutoLastFrameCheck{explicitAutoLastFrameCheck(JSContext*cxMOZ_GUARD_OBJECT_NOTIFIER_PARAM):cx(cx){MOZ_ASSERT(cx);MOZ_GUARD_OBJECT_NOTIFIER_INIT;}~AutoLastFrameCheck(){if(cx->isExceptionPending()&&!JS_IsRunning(cx)&&(!cx->options().dontReportUncaught()&&!cx->options().autoJSAPIOwnsErrorReporting())){ReportUncaughtException(cx);}}private:JSContext*cx;MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER};JS_PUBLIC_API(bool)JS_CallFunctionValue(JSContext*cx,HandleObjectobj,HandleValuefval,constHandleValueArray&args,MutableHandleValuerval){MOZ_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));AssertHeapIsIdle(cx);CHECK_REQUEST(cx);assertSameCompartment(cx,obj,fval,args);AutoLastFrameChecklfc(cx);returnInvoke(cx,ObjectOrNullValue(obj),fval,args.length(),args.begin(),rval);}JS_PUBLIC_API(bool)JS_CallFunction(JSContext*cx,HandleObjectobj,HandleFunctionfun,constHandleValueArray&args,MutableHandleValuerval){MOZ_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));AssertHeapIsIdle(cx);CHECK_REQUEST(cx);assertSameCompartment(cx,obj,fun,args);AutoLastFrameChecklfc(cx);returnInvoke(cx,ObjectOrNullValue(obj),ObjectValue(*fun),args.length(),args.begin(),rval);}JS_PUBLIC_API(bool)JS_CallFunctionName(JSContext*cx,HandleObjectobj,constchar*name,constHandleValueArray&args,MutableHandleValuerval){MOZ_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));AssertHeapIsIdle(cx);CHECK_REQUEST(cx);assertSameCompartment(cx,obj,args);AutoLastFrameChecklfc(cx);JSAtom*atom=Atomize(cx,name,strlen(name));if(!atom)returnfalse;RootedValuev(cx);RootedIdid(cx,AtomToId(atom));if(!GetProperty(cx,obj,obj,id,&v))returnfalse;returnInvoke(cx,ObjectOrNullValue(obj),v,args.length(),args.begin(),rval);}JS_PUBLIC_API(bool)JS::Call(JSContext*cx,HandleValuethisv,HandleValuefval,constJS::HandleValueArray&args,MutableHandleValuerval){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);assertSameCompartment(cx,thisv,fval,args);AutoLastFrameChecklfc(cx);returnInvoke(cx,thisv,fval,args.length(),args.begin(),rval);}JS_PUBLIC_API(bool)JS::Construct(JSContext*cx,HandleValuefval,HandleObjectnewTarget,constJS::HandleValueArray&args,MutableHandleObjectobjp){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);assertSameCompartment(cx,fval,newTarget,args);AutoLastFrameChecklfc(cx);if(!IsConstructor(fval)){ReportValueError(cx,JSMSG_NOT_CONSTRUCTOR,JSDVG_IGNORE_STACK,fval,nullptr);returnfalse;}RootedValuenewTargetVal(cx,ObjectValue(*newTarget));if(!IsConstructor(newTargetVal)){ReportValueError(cx,JSMSG_NOT_CONSTRUCTOR,JSDVG_IGNORE_STACK,newTargetVal,nullptr);returnfalse;}ConstructArgscargs(cx);if(!FillArgumentsFromArraylike(cx,cargs,args))returnfalse;returnjs::Construct(cx,fval,cargs,newTargetVal,objp);}JS_PUBLIC_API(bool)JS::Construct(JSContext*cx,HandleValuefval,constJS::HandleValueArray&args,MutableHandleObjectobjp){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);assertSameCompartment(cx,fval,args);AutoLastFrameChecklfc(cx);if(!IsConstructor(fval)){ReportValueError(cx,JSMSG_NOT_CONSTRUCTOR,JSDVG_IGNORE_STACK,fval,nullptr);returnfalse;}ConstructArgscargs(cx);if(!FillArgumentsFromArraylike(cx,cargs,args))returnfalse;returnjs::Construct(cx,fval,cargs,fval,objp);}/* * */JS_PUBLIC_API(bool)JS_AlreadyHasOwnPropertyById(JSContext*cx,HandleObjectobj,HandleIdid,bool*foundp){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);assertSameCompartment(cx,obj,id);if(!obj->isNative())returnjs::HasOwnProperty(cx,obj,id,foundp);RootedNativeObjectnativeObj(cx,&obj->as<NativeObject>());RootedShapeprop(cx);NativeLookupOwnPropertyNoResolve(cx,nativeObj,id,&prop);*foundp=!!prop;returntrue;}JS_PUBLIC_API(bool)JS_AlreadyHasOwnProperty(JSContext*cx,HandleObjectobj,constchar*name,bool*foundp){JSAtom*atom=Atomize(cx,name,strlen(name));if(!atom)returnfalse;RootedIdid(cx,AtomToId(atom));returnJS_AlreadyHasOwnPropertyById(cx,obj,id,foundp);}JS_PUBLIC_API(bool)JS_AlreadyHasOwnUCProperty(JSContext*cx,HandleObjectobj,constchar16_t*name,size_tnamelen,bool*foundp){JSAtom*atom=AtomizeChars(cx,name,AUTO_NAMELEN(name,namelen));if(!atom)returnfalse;RootedIdid(cx,AtomToId(atom));returnJS_AlreadyHasOwnPropertyById(cx,obj,id,foundp);}JS_PUBLIC_API(bool)JS_AlreadyHasOwnElement(JSContext*cx,HandleObjectobj,uint32_tindex,bool*foundp){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);RootedIdid(cx);if(!IndexToId(cx,index,&id))returnfalse;returnJS_AlreadyHasOwnPropertyById(cx,obj,id,foundp);}JS_PUBLIC_API(bool)JS_FreezeObject(JSContext*cx,HandleObjectobj){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);assertSameCompartment(cx,obj);returnFreezeObject(cx,obj);}JS_PUBLIC_API(bool)JS_DeepFreezeObject(JSContext*cx,HandleObjectobj){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);assertSameCompartment(cx,obj);/* Assume that non-extensible objects are already deep-frozen, to avoid divergence. */boolextensible;if(!IsExtensible(cx,obj,&extensible))returnfalse;if(!extensible)returntrue;if(!FreezeObject(cx,obj))returnfalse;/* Walk slots in obj and if any value is a non-null object, seal it. */if(obj->isNative()){for(uint32_ti=0,n=obj->as<NativeObject>().slotSpan();i<n;++i){constValue&v=obj->as<NativeObject>().getSlot(i);if(v.isPrimitive())continue;RootedObjectobj(cx,&v.toObject());if(!JS_DeepFreezeObject(cx,obj))returnfalse;}}returntrue;}staticboolDefineSelfHostedProperty(JSContext*cx,HandleObjectobj,HandleIdid,constchar*getterName,constchar*setterName,unsignedattrs,unsignedflags){JSAtom*getterNameAtom=Atomize(cx,getterName,strlen(getterName));if(!getterNameAtom)returnfalse;RootedPropertyNamegetterNameName(cx,getterNameAtom->asPropertyName());RootedAtomname(cx,IdToFunctionName(cx,id));if(!name)returnfalse;RootedValuegetterValue(cx);if(!GlobalObject::getSelfHostedFunction(cx,cx->global(),getterNameName,name,0,&getterValue)){returnfalse;}MOZ_ASSERT(getterValue.isObject()&&getterValue.toObject().is<JSFunction>());RootedFunctiongetterFunc(cx,&getterValue.toObject().as<JSFunction>());JSNativegetterOp=JS_DATA_TO_FUNC_PTR(JSNative,getterFunc.get());RootedFunctionsetterFunc(cx);if(setterName){JSAtom*setterNameAtom=Atomize(cx,setterName,strlen(setterName));if(!setterNameAtom)returnfalse;RootedPropertyNamesetterNameName(cx,setterNameAtom->asPropertyName());RootedValuesetterValue(cx);if(!GlobalObject::getSelfHostedFunction(cx,cx->global(),setterNameName,name,0,&setterValue)){returnfalse;}MOZ_ASSERT(setterValue.isObject()&&setterValue.toObject().is<JSFunction>());setterFunc=&setterValue.toObject().as<JSFunction>();}JSNativesetterOp=JS_DATA_TO_FUNC_PTR(JSNative,setterFunc.get());returnDefinePropertyById(cx,obj,id,JS::UndefinedHandleValue,NativeOpWrapper(getterOp),NativeOpWrapper(setterOp),attrs,flags);}JS_PUBLIC_API(JSObject*)JS_DefineObject(JSContext*cx,HandleObjectobj,constchar*name,constJSClass*jsclasp,unsignedattrs){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);assertSameCompartment(cx,obj);constClass*clasp=Valueify(jsclasp);if(!clasp)clasp=&PlainObject::class_;/* default class is Object */RootedObjectnobj(cx,NewObjectWithClassProto(cx,clasp,nullptr));if(!nobj)returnnullptr;RootedValuenobjValue(cx,ObjectValue(*nobj));if(!DefineProperty(cx,obj,name,nobjValue,NativeOpWrapper(nullptr),NativeOpWrapper(nullptr),attrs,0)){returnnullptr;}returnnobj;}staticinlineValueValueFromScalar(doublex){returnDoubleValue(x);}staticinlineValueValueFromScalar(int32_tx){returnInt32Value(x);}template<typenameT>staticboolDefineConstScalar(JSContext*cx,HandleObjectobj,constJSConstScalarSpec<T>*cds){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);JSNativeWrappernoget=NativeOpWrapper(nullptr);JSNativeWrappernoset=NativeOpWrapper(nullptr);unsignedattrs=JSPROP_READONLY|JSPROP_PERMANENT;for(;cds->name;cds++){RootedValuevalue(cx,ValueFromScalar(cds->val));if(!DefineProperty(cx,obj,cds->name,value,noget,noset,attrs,0))returnfalse;}returntrue;}JS_PUBLIC_API(bool)JS_DefineConstDoubles(JSContext*cx,HandleObjectobj,constJSConstDoubleSpec*cds){returnDefineConstScalar(cx,obj,cds);}JS_PUBLIC_API(bool)JS_DefineConstIntegers(JSContext*cx,HandleObjectobj,constJSConstIntegerSpec*cis){returnDefineConstScalar(cx,obj,cis);}staticJS::SymbolCodePropertySpecNameToSymbolCode(constchar*name){MOZ_ASSERT(JS::PropertySpecNameIsSymbol(name));uintptr_tu=reinterpret_cast<uintptr_t>(name);returnJS::SymbolCode(u-1);}boolPropertySpecNameToId(JSContext*cx,constchar*name,MutableHandleIdid,js::PinningBehaviorpin=js::DoNotPinAtom){if(JS::PropertySpecNameIsSymbol(name)){JS::SymbolCodewhich=PropertySpecNameToSymbolCode(name);id.set(SYMBOL_TO_JSID(cx->wellKnownSymbols().get(which)));}else{JSAtom*atom=Atomize(cx,name,strlen(name),pin);if(!atom)returnfalse;id.set(AtomToId(atom));}returntrue;}JS_PUBLIC_API(bool)JS::PropertySpecNameToPermanentId(JSContext*cx,constchar*name,jsid*idp){// We are calling fromMarkedLocation(idp) even though idp points to a// location that will never be marked. This is OK because the whole point// of this API is to populate *idp with a jsid that does not need to be// marked.returnPropertySpecNameToId(cx,name,MutableHandleId::fromMarkedLocation(idp),js::PinAtom);}JS_PUBLIC_API(bool)JS_DefineProperties(JSContext*cx,HandleObjectobj,constJSPropertySpec*ps){RootedIdid(cx);for(;ps->name;ps++){if(!PropertySpecNameToId(cx,ps->name,&id))returnfalse;if(ps->isSelfHosted()){if(!DefineSelfHostedProperty(cx,obj,id,ps->getter.selfHosted.funname,ps->setter.selfHosted.funname,ps->flags,0)){returnfalse;}}else{if(!DefinePropertyById(cx,obj,id,JS::UndefinedHandleValue,ps->getter.native,ps->setter.native,ps->flags,0)){returnfalse;}}}returntrue;}JS_PUBLIC_API(bool)JS::ObjectToCompletePropertyDescriptor(JSContext*cx,HandleObjectobj,HandleValuedescObj,MutableHandle<PropertyDescriptor>desc){if(!ToPropertyDescriptor(cx,descObj,true,desc))returnfalse;CompletePropertyDescriptor(desc);desc.object().set(obj);returntrue;}JS_PUBLIC_API(void)JS_SetAllNonReservedSlotsToUndefined(JSContext*cx,JSObject*objArg){RootedObjectobj(cx,objArg);AssertHeapIsIdle(cx);CHECK_REQUEST(cx);assertSameCompartment(cx,obj);if(!obj->isNative())return;constClass*clasp=obj->getClass();unsignednumReserved=JSCLASS_RESERVED_SLOTS(clasp);unsignednumSlots=obj->as<NativeObject>().slotSpan();for(unsignedi=numReserved;i<numSlots;i++)obj->as<NativeObject>().setSlot(i,UndefinedValue());}JS_PUBLIC_API(Value)JS_GetReservedSlot(JSObject*obj,uint32_tindex){returnobj->as<NativeObject>().getReservedSlot(index);}JS_PUBLIC_API(void)JS_SetReservedSlot(JSObject*obj,uint32_tindex,Valuevalue){obj->as<NativeObject>().setReservedSlot(index,value);}JS_PUBLIC_API(JSObject*)JS_NewArrayObject(JSContext*cx,constJS::HandleValueArray&contents){MOZ_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));AssertHeapIsIdle(cx);CHECK_REQUEST(cx);assertSameCompartment(cx,contents);returnNewDenseCopiedArray(cx,contents.length(),contents.begin());}JS_PUBLIC_API(JSObject*)JS_NewArrayObject(JSContext*cx,size_tlength){MOZ_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));AssertHeapIsIdle(cx);CHECK_REQUEST(cx);returnNewDenseFullyAllocatedArray(cx,length);}JS_PUBLIC_API(bool)JS_IsArrayObject(JSContext*cx,JS::HandleObjectobj,bool*isArray){assertSameCompartment(cx,obj);ESClassValuecls;if(!GetBuiltinClass(cx,obj,&cls))returnfalse;*isArray=cls==ESClass_Array;returntrue;}JS_PUBLIC_API(bool)JS_IsArrayObject(JSContext*cx,JS::HandleValuevalue,bool*isArray){if(!value.isObject()){*isArray=false;returntrue;}RootedObjectobj(cx,&value.toObject());returnJS_IsArrayObject(cx,obj,isArray);}JS_PUBLIC_API(bool)JS_GetArrayLength(JSContext*cx,HandleObjectobj,uint32_t*lengthp){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);assertSameCompartment(cx,obj);returnGetLengthProperty(cx,obj,lengthp);}JS_PUBLIC_API(bool)JS_SetArrayLength(JSContext*cx,HandleObjectobj,uint32_tlength){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);assertSameCompartment(cx,obj);returnSetLengthProperty(cx,obj,length);}JS_PUBLIC_API(void)JS_HoldPrincipals(JSPrincipals*principals){++principals->refcount;}JS_PUBLIC_API(void)JS_DropPrincipals(JSRuntime*rt,JSPrincipals*principals){intrc=--principals->refcount;if(rc==0)rt->destroyPrincipals(principals);}JS_PUBLIC_API(void)JS_SetSecurityCallbacks(JSRuntime*rt,constJSSecurityCallbacks*scb){MOZ_ASSERT(scb!=&NullSecurityCallbacks);rt->securityCallbacks=scb?scb:&NullSecurityCallbacks;}JS_PUBLIC_API(constJSSecurityCallbacks*)JS_GetSecurityCallbacks(JSRuntime*rt){return(rt->securityCallbacks!=&NullSecurityCallbacks)?rt->securityCallbacks:nullptr;}JS_PUBLIC_API(void)JS_SetTrustedPrincipals(JSRuntime*rt,JSPrincipals*prin){rt->setTrustedPrincipals(prin);}externJS_PUBLIC_API(void)JS_InitDestroyPrincipalsCallback(JSRuntime*rt,JSDestroyPrincipalsOpdestroyPrincipals){MOZ_ASSERT(destroyPrincipals);MOZ_ASSERT(!rt->destroyPrincipals);rt->destroyPrincipals=destroyPrincipals;}externJS_PUBLIC_API(void)JS_InitReadPrincipalsCallback(JSRuntime*rt,JSReadPrincipalsOpread){MOZ_ASSERT(read);MOZ_ASSERT(!rt->readPrincipals);rt->readPrincipals=read;}JS_PUBLIC_API(JSFunction*)JS_NewFunction(JSContext*cx,JSNativenative,unsignednargs,unsignedflags,constchar*name){MOZ_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));AssertHeapIsIdle(cx);CHECK_REQUEST(cx);RootedAtomatom(cx);if(name){atom=Atomize(cx,name,strlen(name));if(!atom)returnnullptr;}return(flags&JSFUN_CONSTRUCTOR)?NewNativeConstructor(cx,native,nargs,atom):NewNativeFunction(cx,native,nargs,atom);}JS_PUBLIC_API(JSFunction*)JS::GetSelfHostedFunction(JSContext*cx,constchar*selfHostedName,HandleIdid,unsignednargs){MOZ_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));AssertHeapIsIdle(cx);CHECK_REQUEST(cx);RootedAtomname(cx,IdToFunctionName(cx,id));if(!name)returnnullptr;JSAtom*shAtom=Atomize(cx,selfHostedName,strlen(selfHostedName));if(!shAtom)returnnullptr;RootedPropertyNameshName(cx,shAtom->asPropertyName());RootedValuefunVal(cx);if(!GlobalObject::getSelfHostedFunction(cx,cx->global(),shName,name,nargs,&funVal))returnnullptr;return&funVal.toObject().as<JSFunction>();}JS_PUBLIC_API(JSFunction*)JS::NewFunctionFromSpec(JSContext*cx,constJSFunctionSpec*fs,HandleIdid){// Delay cloning self-hosted functions until they are called. This is// achieved by passing DefineFunction a nullptr JSNative which produces an// interpreted JSFunction where !hasScript. Interpreted call paths then// call InitializeLazyFunctionScript if !hasScript.if(fs->selfHostedName){MOZ_ASSERT(!fs->call.op);MOZ_ASSERT(!fs->call.info);JSAtom*shAtom=Atomize(cx,fs->selfHostedName,strlen(fs->selfHostedName));if(!shAtom)returnnullptr;RootedPropertyNameshName(cx,shAtom->asPropertyName());RootedAtomname(cx,IdToFunctionName(cx,id));if(!name)returnnullptr;RootedValuefunVal(cx);if(!GlobalObject::getSelfHostedFunction(cx,cx->global(),shName,name,fs->nargs,&funVal)){returnnullptr;}JSFunction*fun=&funVal.toObject().as<JSFunction>();if(fs->flags&JSFUN_HAS_REST)fun->setHasRest();returnfun;}RootedAtomatom(cx,IdToFunctionName(cx,id));if(!atom)returnnullptr;JSFunction*fun;if(!fs->call.op)fun=NewScriptedFunction(cx,fs->nargs,JSFunction::INTERPRETED_LAZY,atom);elseif(fs->flags&JSFUN_CONSTRUCTOR)fun=NewNativeConstructor(cx,fs->call.op,fs->nargs,atom);elsefun=NewNativeFunction(cx,fs->call.op,fs->nargs,atom);if(!fun)returnnullptr;if(fs->call.info)fun->setJitInfo(fs->call.info);returnfun;}staticboolCreateNonSyntacticScopeChain(JSContext*cx,AutoObjectVector&scopeChain,MutableHandleObjectdynamicScopeObj,MutableHandle<StaticScope*>staticScopeObj){Rooted<ClonedBlockObject*>globalLexical(cx,&cx->global()->lexicalScope());if(!js::CreateScopeObjectsForScopeChain(cx,scopeChain,globalLexical,dynamicScopeObj))returnfalse;staticScopeObj.set(&globalLexical->staticBlock());if(!scopeChain.empty()){staticScopeObj.set(StaticNonSyntacticScope::create(cx,staticScopeObj));if(!staticScopeObj)returnfalse;// The XPConnect subscript loader, which may pass in its own dynamic// scopes to load scripts in, expects the dynamic scope chain to be// the holder of "var" declarations. In SpiderMonkey, such objects are// called "qualified varobjs", the "qualified" part meaning the// declaration was qualified by "var". There is only sadness.//// See JSObject::isQualifiedVarObj.if(!dynamicScopeObj->setQualifiedVarObj(cx))returnfalse;// Also get a non-syntactic lexical scope to capture 'let' and 'const'// bindings. To persist lexical bindings, we have a 1-1 mapping with// the final unwrapped dynamic scope object (the scope that stores the// 'var' bindings) and the lexical scope.//// TODOshu: disallow the subscript loader from using non-distinguished// objects as dynamic scopes.dynamicScopeObj.set(cx->compartment()->getOrCreateNonSyntacticLexicalScope(cx,staticScopeObj,dynamicScopeObj));if(!dynamicScopeObj)returnfalse;}returntrue;}staticboolIsFunctionCloneable(HandleFunctionfun){if(!fun->isInterpreted())returntrue;// If a function was compiled to be lexically nested inside some other// script, we cannot clone it without breaking the compiler's assumptions.if(JSObject*scope=fun->nonLazyScript()->enclosingStaticScope()){// If the script is directly under the global scope, we can clone it.if(IsStaticGlobalLexicalScope(scope))returntrue;// If the script already deals with non-syntactic scopes, we can clone// it.if(scope->is<StaticNonSyntacticScope>())returntrue;// 'eval' scopes are always scoped immediately under a non-extensible// lexical scope.if(scope->is<StaticBlockScope>()){StaticBlockScope&block=scope->as<StaticBlockScope>();if(block.needsClone())returnfalse;JSObject*enclosing=block.enclosingStaticScope();// If the script is an indirect eval that is immediately scoped// under the global, we can clone it.if(enclosing->is<StaticEvalScope>())return!enclosing->as<StaticEvalScope>().isNonGlobal();}// Any other enclosing static scope (e.g., function, block) cannot be// cloned.returnfalse;}returntrue;}staticJSObject*CloneFunctionObject(JSContext*cx,HandleObjectfunobj,HandleObjectdynamicScope,Handle<StaticScope*>staticScope){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);assertSameCompartment(cx,dynamicScope);MOZ_ASSERT(dynamicScope);// Note that funobj can be in a different compartment.if(!funobj->is<JSFunction>()){AutoCompartmentac(cx,funobj);RootedValuev(cx,ObjectValue(*funobj));ReportIsNotFunction(cx,v);returnnullptr;}RootedFunctionfun(cx,&funobj->as<JSFunction>());if(fun->isInterpretedLazy()){AutoCompartmentac(cx,funobj);if(!fun->getOrCreateScript(cx))returnnullptr;}if(!IsFunctionCloneable(fun)){JS_ReportErrorNumber(cx,GetErrorMessage,nullptr,JSMSG_BAD_CLONE_FUNOBJ_SCOPE);returnnullptr;}if(fun->isBoundFunction()){JS_ReportErrorNumber(cx,GetErrorMessage,nullptr,JSMSG_CANT_CLONE_OBJECT);returnnullptr;}if(IsAsmJSModule(fun)){JS_ReportErrorNumber(cx,GetErrorMessage,nullptr,JSMSG_CANT_CLONE_OBJECT);returnnullptr;}if(CanReuseScriptForClone(cx->compartment(),fun,dynamicScope)){// If the script is to be reused, either the script can already handle// non-syntactic scopes, or there is only the standard global lexical// scope.#ifdef DEBUG// Fail here if we OOM during debug asserting.// CloneFunctionReuseScript will delazify the script anyways, so we// are not creating an extra failure condition for DEBUG builds.if(!fun->getOrCreateScript(cx))returnnullptr;MOZ_ASSERT(IsStaticGlobalLexicalScope(staticScope)||fun->nonLazyScript()->hasNonSyntacticScope());#endifreturnCloneFunctionReuseScript(cx,fun,dynamicScope,fun->getAllocKind());}JSFunction*clone=CloneFunctionAndScript(cx,fun,dynamicScope,staticScope,fun->getAllocKind());#ifdef DEBUG// The cloned function should itself be cloneable.RootedFunctioncloneRoot(cx,clone);MOZ_ASSERT_IF(cloneRoot,IsFunctionCloneable(cloneRoot));#endifreturnclone;}JS_PUBLIC_API(JSObject*)JS::CloneFunctionObject(JSContext*cx,HandleObjectfunobj){Rooted<ClonedBlockObject*>globalLexical(cx,&cx->global()->lexicalScope());Rooted<StaticScope*>staticLexical(cx,&globalLexical->staticBlock());returnCloneFunctionObject(cx,funobj,globalLexical,staticLexical);}externJS_PUBLIC_API(JSObject*)JS::CloneFunctionObject(JSContext*cx,HandleObjectfunobj,AutoObjectVector&scopeChain){RootedObjectdynamicScope(cx);Rooted<StaticScope*>staticScope(cx);if(!CreateNonSyntacticScopeChain(cx,scopeChain,&dynamicScope,&staticScope))returnnullptr;returnCloneFunctionObject(cx,funobj,dynamicScope,staticScope);}JS_PUBLIC_API(JSObject*)JS_GetFunctionObject(JSFunction*fun){returnfun;}JS_PUBLIC_API(JSString*)JS_GetFunctionId(JSFunction*fun){returnfun->atom();}JS_PUBLIC_API(JSString*)JS_GetFunctionDisplayId(JSFunction*fun){returnfun->displayAtom();}JS_PUBLIC_API(uint16_t)JS_GetFunctionArity(JSFunction*fun){returnfun->nargs();}JS_PUBLIC_API(bool)JS_ObjectIsFunction(JSContext*cx,JSObject*obj){returnobj->is<JSFunction>();}JS_PUBLIC_API(bool)JS_IsNativeFunction(JSObject*funobj,JSNativecall){if(!funobj->is<JSFunction>())returnfalse;JSFunction*fun=&funobj->as<JSFunction>();returnfun->isNative()&&fun->native()==call;}externJS_PUBLIC_API(bool)JS_IsConstructor(JSFunction*fun){returnfun->isConstructor();}JS_PUBLIC_API(bool)JS_DefineFunctions(JSContext*cx,HandleObjectobj,constJSFunctionSpec*fs){MOZ_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));AssertHeapIsIdle(cx);CHECK_REQUEST(cx);assertSameCompartment(cx,obj);returnDefineFunctions(cx,obj,fs,NotIntrinsic);}JS_PUBLIC_API(JSFunction*)JS_DefineFunction(JSContext*cx,HandleObjectobj,constchar*name,JSNativecall,unsignednargs,unsignedattrs){MOZ_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));AssertHeapIsIdle(cx);CHECK_REQUEST(cx);assertSameCompartment(cx,obj);JSAtom*atom=Atomize(cx,name,strlen(name));if(!atom)returnnullptr;Rooted<jsid>id(cx,AtomToId(atom));returnDefineFunction(cx,obj,id,call,nargs,attrs);}JS_PUBLIC_API(JSFunction*)JS_DefineUCFunction(JSContext*cx,HandleObjectobj,constchar16_t*name,size_tnamelen,JSNativecall,unsignednargs,unsignedattrs){MOZ_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));AssertHeapIsIdle(cx);CHECK_REQUEST(cx);assertSameCompartment(cx,obj);JSAtom*atom=AtomizeChars(cx,name,AUTO_NAMELEN(name,namelen));if(!atom)returnnullptr;Rooted<jsid>id(cx,AtomToId(atom));returnDefineFunction(cx,obj,id,call,nargs,attrs);}externJS_PUBLIC_API(JSFunction*)JS_DefineFunctionById(JSContext*cx,HandleObjectobj,HandleIdid,JSNativecall,unsignednargs,unsignedattrs){MOZ_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));AssertHeapIsIdle(cx);CHECK_REQUEST(cx);assertSameCompartment(cx,obj);returnDefineFunction(cx,obj,id,call,nargs,attrs);}/* Use the fastest available getc. */#if defined(HAVE_GETC_UNLOCKED)# define fast_getc getc_unlocked#elif defined(HAVE__GETC_NOLOCK)# define fast_getc _getc_nolock#else# define fast_getc getc#endiftypedefVector<char,8,TempAllocPolicy>FileContents;staticboolReadCompleteFile(JSContext*cx,FILE*fp,FileContents&buffer){/* Get the complete length of the file, if possible. */structstatst;intok=fstat(fileno(fp),&st);if(ok!=0)returnfalse;if(st.st_size>0){if(!buffer.reserve(st.st_size))returnfalse;}// Read in the whole file. Note that we can't assume the data's length// is actually st.st_size, because 1) some files lie about their size// (/dev/zero and /dev/random), and 2) reading files in text mode on// Windows collapses "\r\n" pairs to single \n characters.for(;;){intc=fast_getc(fp);if(c==EOF)break;if(!buffer.append(c))returnfalse;}returntrue;}namespace{classAutoFile{FILE*fp_;public:AutoFile():fp_(nullptr){}~AutoFile(){if(fp_&&fp_!=stdin)fclose(fp_);}FILE*fp()const{returnfp_;}boolopen(JSContext*cx,constchar*filename);boolreadAll(JSContext*cx,FileContents&buffer){MOZ_ASSERT(fp_);returnReadCompleteFile(cx,fp_,buffer);}};}/* anonymous namespace *//* * Open a source file for reading. Supports "-" and nullptr to mean stdin. The * return value must be fclosed unless it is stdin. */boolAutoFile::open(JSContext*cx,constchar*filename){if(!filename||strcmp(filename,"-")==0){fp_=stdin;}else{fp_=fopen(filename,"r");if(!fp_){JS_ReportErrorNumber(cx,GetErrorMessage,nullptr,JSMSG_CANT_OPEN,filename,"No such file or directory");returnfalse;}}returntrue;}voidJS::TransitiveCompileOptions::copyPODTransitiveOptions(constTransitiveCompileOptions&rhs){mutedErrors_=rhs.mutedErrors_;version=rhs.version;versionSet=rhs.versionSet;utf8=rhs.utf8;selfHostingMode=rhs.selfHostingMode;canLazilyParse=rhs.canLazilyParse;strictOption=rhs.strictOption;extraWarningsOption=rhs.extraWarningsOption;werrorOption=rhs.werrorOption;asmJSOption=rhs.asmJSOption;throwOnAsmJSValidationFailureOption=rhs.throwOnAsmJSValidationFailureOption;forceAsync=rhs.forceAsync;installedFile=rhs.installedFile;sourceIsLazy=rhs.sourceIsLazy;introductionType=rhs.introductionType;introductionLineno=rhs.introductionLineno;introductionOffset=rhs.introductionOffset;hasIntroductionInfo=rhs.hasIntroductionInfo;};voidJS::ReadOnlyCompileOptions::copyPODOptions(constReadOnlyCompileOptions&rhs){copyPODTransitiveOptions(rhs);lineno=rhs.lineno;column=rhs.column;isRunOnce=rhs.isRunOnce;forEval=rhs.forEval;noScriptRval=rhs.noScriptRval;}JS::OwningCompileOptions::OwningCompileOptions(JSContext*cx):ReadOnlyCompileOptions(),runtime(GetRuntime(cx)),elementRoot(cx),elementAttributeNameRoot(cx),introductionScriptRoot(cx){}JS::OwningCompileOptions::~OwningCompileOptions(){// OwningCompileOptions always owns these, so these casts are okay.js_free(const_cast<char*>(filename_));js_free(const_cast<char16_t*>(sourceMapURL_));js_free(const_cast<char*>(introducerFilename_));}boolJS::OwningCompileOptions::copy(JSContext*cx,constReadOnlyCompileOptions&rhs){copyPODOptions(rhs);setElement(rhs.element());setElementAttributeName(rhs.elementAttributeName());setIntroductionScript(rhs.introductionScript());returnsetFileAndLine(cx,rhs.filename(),rhs.lineno)&&setSourceMapURL(cx,rhs.sourceMapURL())&&setIntroducerFilename(cx,rhs.introducerFilename());}boolJS::OwningCompileOptions::setFile(JSContext*cx,constchar*f){char*copy=nullptr;if(f){copy=JS_strdup(cx,f);if(!copy)returnfalse;}// OwningCompileOptions always owns filename_, so this cast is okay.js_free(const_cast<char*>(filename_));filename_=copy;returntrue;}boolJS::OwningCompileOptions::setFileAndLine(JSContext*cx,constchar*f,unsignedl){if(!setFile(cx,f))returnfalse;lineno=l;returntrue;}boolJS::OwningCompileOptions::setSourceMapURL(JSContext*cx,constchar16_t*s){UniqueTwoByteCharscopy;if(s){copy=DuplicateString(cx,s);if(!copy)returnfalse;}// OwningCompileOptions always owns sourceMapURL_, so this cast is okay.js_free(const_cast<char16_t*>(sourceMapURL_));sourceMapURL_=copy.release();returntrue;}boolJS::OwningCompileOptions::setIntroducerFilename(JSContext*cx,constchar*s){char*copy=nullptr;if(s){copy=JS_strdup(cx,s);if(!copy)returnfalse;}// OwningCompileOptions always owns introducerFilename_, so this cast is okay.js_free(const_cast<char*>(introducerFilename_));introducerFilename_=copy;returntrue;}JS::CompileOptions::CompileOptions(JSContext*cx,JSVersionversion):ReadOnlyCompileOptions(),elementRoot(cx),elementAttributeNameRoot(cx),introductionScriptRoot(cx){this->version=(version!=JSVERSION_UNKNOWN)?version:cx->findVersion();strictOption=cx->runtime()->options().strictMode();extraWarningsOption=cx->compartment()->behaviors().extraWarnings(cx);werrorOption=cx->runtime()->options().werror();if(!cx->runtime()->options().asmJS())asmJSOption=AsmJSOption::Disabled;elseif(cx->compartment()->debuggerObservesAsmJS())asmJSOption=AsmJSOption::DisabledByDebugger;elseasmJSOption=AsmJSOption::Enabled;throwOnAsmJSValidationFailureOption=cx->runtime()->options().throwOnAsmJSValidationFailure();}enumSyntacticScopeOption{HasSyntacticScope,HasNonSyntacticScope};staticboolCompile(JSContext*cx,constReadOnlyCompileOptions&options,SyntacticScopeOptionscopeOption,SourceBufferHolder&srcBuf,MutableHandleScriptscript){MOZ_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));AssertHeapIsIdle(cx);CHECK_REQUEST(cx);AutoLastFrameChecklfc(cx);Rooted<StaticScope*>staticScope(cx,&cx->global()->lexicalScope().staticBlock());if(scopeOption==HasNonSyntacticScope){staticScope=StaticNonSyntacticScope::create(cx,staticScope);if(!staticScope)returnfalse;}RootedObjectglobalLexical(cx,&cx->global()->lexicalScope());script.set(frontend::CompileScript(cx,&cx->tempLifoAlloc(),globalLexical,staticScope,nullptr,options,srcBuf));return!!script;}staticboolCompile(JSContext*cx,constReadOnlyCompileOptions&options,SyntacticScopeOptionscopeOption,constchar16_t*chars,size_tlength,MutableHandleScriptscript){SourceBufferHoldersrcBuf(chars,length,SourceBufferHolder::NoOwnership);return::Compile(cx,options,scopeOption,srcBuf,script);}staticboolCompile(JSContext*cx,constReadOnlyCompileOptions&options,SyntacticScopeOptionscopeOption,constchar*bytes,size_tlength,MutableHandleScriptscript){UniqueTwoByteCharschars;if(options.utf8)chars.reset(UTF8CharsToNewTwoByteCharsZ(cx,UTF8Chars(bytes,length),&length).get());elsechars.reset(InflateString(cx,bytes,&length));if(!chars)returnfalse;return::Compile(cx,options,scopeOption,chars.get(),length,script);}staticboolCompile(JSContext*cx,constReadOnlyCompileOptions&options,SyntacticScopeOptionscopeOption,FILE*fp,MutableHandleScriptscript){FileContentsbuffer(cx);if(!ReadCompleteFile(cx,fp,buffer))returnfalse;return::Compile(cx,options,scopeOption,buffer.begin(),buffer.length(),script);}staticboolCompile(JSContext*cx,constReadOnlyCompileOptions&optionsArg,SyntacticScopeOptionscopeOption,constchar*filename,MutableHandleScriptscript){AutoFilefile;if(!file.open(cx,filename))returnfalse;CompileOptionsoptions(cx,optionsArg);options.setFileAndLine(filename,1);return::Compile(cx,options,scopeOption,file.fp(),script);}boolJS::Compile(JSContext*cx,constReadOnlyCompileOptions&options,SourceBufferHolder&srcBuf,JS::MutableHandleScriptscript){return::Compile(cx,options,HasSyntacticScope,srcBuf,script);}boolJS::Compile(JSContext*cx,constReadOnlyCompileOptions&options,constchar*bytes,size_tlength,JS::MutableHandleScriptscript){return::Compile(cx,options,HasSyntacticScope,bytes,length,script);}boolJS::Compile(JSContext*cx,constReadOnlyCompileOptions&options,constchar16_t*chars,size_tlength,JS::MutableHandleScriptscript){return::Compile(cx,options,HasSyntacticScope,chars,length,script);}boolJS::Compile(JSContext*cx,constReadOnlyCompileOptions&options,FILE*file,JS::MutableHandleScriptscript){return::Compile(cx,options,HasSyntacticScope,file,script);}boolJS::Compile(JSContext*cx,constReadOnlyCompileOptions&options,constchar*filename,JS::MutableHandleScriptscript){return::Compile(cx,options,HasSyntacticScope,filename,script);}boolJS::CompileForNonSyntacticScope(JSContext*cx,constReadOnlyCompileOptions&options,SourceBufferHolder&srcBuf,JS::MutableHandleScriptscript){return::Compile(cx,options,HasNonSyntacticScope,srcBuf,script);}boolJS::CompileForNonSyntacticScope(JSContext*cx,constReadOnlyCompileOptions&options,constchar*bytes,size_tlength,JS::MutableHandleScriptscript){return::Compile(cx,options,HasNonSyntacticScope,bytes,length,script);}boolJS::CompileForNonSyntacticScope(JSContext*cx,constReadOnlyCompileOptions&options,constchar16_t*chars,size_tlength,JS::MutableHandleScriptscript){return::Compile(cx,options,HasNonSyntacticScope,chars,length,script);}boolJS::CompileForNonSyntacticScope(JSContext*cx,constReadOnlyCompileOptions&options,FILE*file,JS::MutableHandleScriptscript){return::Compile(cx,options,HasNonSyntacticScope,file,script);}boolJS::CompileForNonSyntacticScope(JSContext*cx,constReadOnlyCompileOptions&options,constchar*filename,JS::MutableHandleScriptscript){return::Compile(cx,options,HasNonSyntacticScope,filename,script);}JS_PUBLIC_API(bool)JS::CanCompileOffThread(JSContext*cx,constReadOnlyCompileOptions&options,size_tlength){staticconstsize_tTINY_LENGTH=5*1000;staticconstsize_tHUGE_LENGTH=100*1000;// These are heuristics which the caller may choose to ignore (e.g., for// testing purposes).if(!options.forceAsync){// Compiling off the main thread inolves creating a new Zone and other// significant overheads. Don't bother if the script is tiny.if(length<TINY_LENGTH)returnfalse;// If the parsing task would have to wait for GC to complete, it'll probably// be faster to just start it synchronously on the main thread unless the// script is huge.if(OffThreadParsingMustWaitForGC(cx->runtime())&&length<HUGE_LENGTH)returnfalse;}returncx->runtime()->canUseParallelParsing()&&CanUseExtraThreads();}JS_PUBLIC_API(bool)JS::CompileOffThread(JSContext*cx,constReadOnlyCompileOptions&options,constchar16_t*chars,size_tlength,OffThreadCompileCallbackcallback,void*callbackData){MOZ_ASSERT(CanCompileOffThread(cx,options,length));returnStartOffThreadParseScript(cx,options,chars,length,callback,callbackData);}JS_PUBLIC_API(JSScript*)JS::FinishOffThreadScript(JSContext*maybecx,JSRuntime*rt,void*token){MOZ_ASSERT(CurrentThreadCanAccessRuntime(rt));if(maybecx){RootedScriptscript(maybecx);{AutoLastFrameChecklfc(maybecx);script=HelperThreadState().finishScriptParseTask(maybecx,rt,token);}returnscript;}else{returnHelperThreadState().finishScriptParseTask(maybecx,rt,token);}}JS_PUBLIC_API(bool)JS_CompileScript(JSContext*cx,constchar*ascii,size_tlength,constJS::CompileOptions&options,MutableHandleScriptscript){returnCompile(cx,options,ascii,length,script);}JS_PUBLIC_API(bool)JS_CompileUCScript(JSContext*cx,constchar16_t*chars,size_tlength,constJS::CompileOptions&options,MutableHandleScriptscript){returnCompile(cx,options,chars,length,script);}JS_PUBLIC_API(bool)JS_BufferIsCompilableUnit(JSContext*cx,HandleObjectobj,constchar*utf8,size_tlength){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);assertSameCompartment(cx,obj);cx->clearPendingException();char16_t*chars=JS::UTF8CharsToNewTwoByteCharsZ(cx,JS::UTF8Chars(utf8,length),&length).get();if(!chars)returntrue;// Return true on any out-of-memory error or non-EOF-related syntax error, so our// caller doesn't try to collect more buffered source.boolresult=true;CompileOptionsoptions(cx);Parser<frontend::FullParseHandler>parser(cx,&cx->tempLifoAlloc(),options,chars,length,/* foldConstants = */true,nullptr,nullptr);JSErrorReporterolder=JS_SetErrorReporter(cx->runtime(),nullptr);if(!parser.checkOptions()||!parser.parse()){// We ran into an error. If it was because we ran out of source, we// return false so our caller knows to try to collect more buffered// source.if(parser.isUnexpectedEOF())result=false;cx->clearPendingException();}JS_SetErrorReporter(cx->runtime(),older);js_free(chars);returnresult;}JS_PUBLIC_API(JSObject*)JS_GetGlobalFromScript(JSScript*script){MOZ_ASSERT(!script->isCachedEval());return&script->global();}JS_PUBLIC_API(constchar*)JS_GetScriptFilename(JSScript*script){// This is called from ThreadStackHelper which can be called from another// thread or inside a signal hander, so we need to be careful in case a// copmacting GC is currently moving things around.returnscript->maybeForwardedFilename();}JS_PUBLIC_API(unsigned)JS_GetScriptBaseLineNumber(JSContext*cx,JSScript*script){returnscript->lineno();}JS_PUBLIC_API(JSScript*)JS_GetFunctionScript(JSContext*cx,HandleFunctionfun){if(fun->isNative())returnnullptr;if(fun->isInterpretedLazy()){AutoCompartmentfunCompartment(cx,fun);JSScript*script=fun->getOrCreateScript(cx);if(!script)MOZ_CRASH();returnscript;}returnfun->nonLazyScript();}/* * enclosingStaticScope is a static enclosing scope, if any (e.g. a * StaticWithScope). If the enclosing scope is the global scope, this must be * null. * * enclosingDynamicScope is a dynamic scope to use, if it's not the global. */staticboolCompileFunction(JSContext*cx,constReadOnlyCompileOptions&optionsArg,constchar*name,unsignednargs,constchar*const*argnames,SourceBufferHolder&srcBuf,HandleObjectenclosingDynamicScope,Handle<StaticScope*>enclosingStaticScope,MutableHandleFunctionfun){MOZ_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));AssertHeapIsIdle(cx);CHECK_REQUEST(cx);assertSameCompartment(cx,enclosingDynamicScope);assertSameCompartment(cx,enclosingStaticScope);RootedAtomfunAtom(cx);AutoLastFrameChecklfc(cx);if(name){funAtom=Atomize(cx,name,strlen(name));if(!funAtom)returnfalse;}Rooted<PropertyNameVector>formals(cx,PropertyNameVector(cx));for(unsignedi=0;i<nargs;i++){RootedAtomargAtom(cx,Atomize(cx,argnames[i],strlen(argnames[i])));if(!argAtom||!formals.append(argAtom->asPropertyName()))returnfalse;}fun.set(NewScriptedFunction(cx,0,JSFunction::INTERPRETED_NORMAL,funAtom,/* proto = */nullptr,gc::AllocKind::FUNCTION,TenuredObject,enclosingDynamicScope));if(!fun)returnfalse;// Make sure the static scope chain matches up when we have a// non-syntactic scope.MOZ_ASSERT_IF(!IsGlobalLexicalScope(enclosingDynamicScope),HasNonSyntacticStaticScopeChain(enclosingStaticScope));if(!frontend::CompileFunctionBody(cx,fun,optionsArg,formals,srcBuf,enclosingStaticScope))returnfalse;returntrue;}JS_PUBLIC_API(bool)JS::CompileFunction(JSContext*cx,AutoObjectVector&scopeChain,constReadOnlyCompileOptions&options,constchar*name,unsignednargs,constchar*const*argnames,SourceBufferHolder&srcBuf,MutableHandleFunctionfun){RootedObjectdynamicScopeObj(cx);Rooted<StaticScope*>staticScopeObj(cx);if(!CreateNonSyntacticScopeChain(cx,scopeChain,&dynamicScopeObj,&staticScopeObj))returnfalse;returnCompileFunction(cx,options,name,nargs,argnames,srcBuf,dynamicScopeObj,staticScopeObj,fun);}JS_PUBLIC_API(bool)JS::CompileFunction(JSContext*cx,AutoObjectVector&scopeChain,constReadOnlyCompileOptions&options,constchar*name,unsignednargs,constchar*const*argnames,constchar16_t*chars,size_tlength,MutableHandleFunctionfun){SourceBufferHoldersrcBuf(chars,length,SourceBufferHolder::NoOwnership);returnCompileFunction(cx,scopeChain,options,name,nargs,argnames,srcBuf,fun);}JS_PUBLIC_API(bool)JS::CompileFunction(JSContext*cx,AutoObjectVector&scopeChain,constReadOnlyCompileOptions&options,constchar*name,unsignednargs,constchar*const*argnames,constchar*bytes,size_tlength,MutableHandleFunctionfun){UniqueTwoByteCharschars;if(options.utf8)chars.reset(UTF8CharsToNewTwoByteCharsZ(cx,UTF8Chars(bytes,length),&length).get());elsechars.reset(InflateString(cx,bytes,&length));if(!chars)returnfalse;returnCompileFunction(cx,scopeChain,options,name,nargs,argnames,chars.get(),length,fun);}JS_PUBLIC_API(JSString*)JS_DecompileScript(JSContext*cx,HandleScriptscript,constchar*name,unsignedindent){MOZ_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));AssertHeapIsIdle(cx);CHECK_REQUEST(cx);script->ensureNonLazyCanonicalFunction(cx);RootedFunctionfun(cx,script->functionNonDelazifying());if(fun)returnJS_DecompileFunction(cx,fun,indent);boolhaveSource=script->scriptSource()->hasSourceData();if(!haveSource&&!JSScript::loadSource(cx,script->scriptSource(),&haveSource))returnnullptr;returnhaveSource?script->sourceData(cx):NewStringCopyZ<CanGC>(cx,"[no source]");}JS_PUBLIC_API(JSString*)JS_DecompileFunction(JSContext*cx,HandleFunctionfun,unsignedindent){MOZ_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));AssertHeapIsIdle(cx);CHECK_REQUEST(cx);assertSameCompartment(cx,fun);returnFunctionToString(cx,fun,!(indent&JS_DONT_PRETTY_PRINT));}MOZ_NEVER_INLINEstaticboolExecuteScript(JSContext*cx,HandleObjectscope,HandleScriptscript,Value*rval){MOZ_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));AssertHeapIsIdle(cx);CHECK_REQUEST(cx);assertSameCompartment(cx,scope,script);MOZ_ASSERT_IF(!IsGlobalLexicalScope(scope),script->hasNonSyntacticScope());AutoLastFrameChecklfc(cx);returnExecute(cx,script,*scope,rval);}staticboolExecuteScript(JSContext*cx,AutoObjectVector&scopeChain,HandleScriptscriptArg,Value*rval){RootedObjectdynamicScope(cx);Rooted<StaticScope*>staticScope(cx);if(!CreateNonSyntacticScopeChain(cx,scopeChain,&dynamicScope,&staticScope))returnfalse;RootedScriptscript(cx,scriptArg);if(!script->hasNonSyntacticScope()&&!IsGlobalLexicalScope(dynamicScope)){script=CloneGlobalScript(cx,staticScope,script);if(!script)returnfalse;js::Debugger::onNewScript(cx,script);}returnExecuteScript(cx,dynamicScope,script,rval);}MOZ_NEVER_INLINEJS_PUBLIC_API(bool)JS_ExecuteScript(JSContext*cx,HandleScriptscriptArg,MutableHandleValuerval){RootedObjectglobalLexical(cx,&cx->global()->lexicalScope());returnExecuteScript(cx,globalLexical,scriptArg,rval.address());}MOZ_NEVER_INLINEJS_PUBLIC_API(bool)JS_ExecuteScript(JSContext*cx,HandleScriptscriptArg){RootedObjectglobalLexical(cx,&cx->global()->lexicalScope());returnExecuteScript(cx,globalLexical,scriptArg,nullptr);}MOZ_NEVER_INLINEJS_PUBLIC_API(bool)JS_ExecuteScript(JSContext*cx,AutoObjectVector&scopeChain,HandleScriptscriptArg,MutableHandleValuerval){returnExecuteScript(cx,scopeChain,scriptArg,rval.address());}MOZ_NEVER_INLINEJS_PUBLIC_API(bool)JS_ExecuteScript(JSContext*cx,AutoObjectVector&scopeChain,HandleScriptscriptArg){returnExecuteScript(cx,scopeChain,scriptArg,nullptr);}JS_PUBLIC_API(bool)JS::CloneAndExecuteScript(JSContext*cx,HandleScriptscriptArg){CHECK_REQUEST(cx);RootedScriptscript(cx,scriptArg);Rooted<ClonedBlockObject*>globalLexical(cx,&cx->global()->lexicalScope());if(script->compartment()!=cx->compartment()){Rooted<StaticScope*>staticLexical(cx,&globalLexical->staticBlock());script=CloneGlobalScript(cx,staticLexical,script);if(!script)returnfalse;js::Debugger::onNewScript(cx,script);}returnExecuteScript(cx,globalLexical,script,nullptr);}staticconstunsignedLARGE_SCRIPT_LENGTH=500*1024;staticboolEvaluate(JSContext*cx,HandleObjectscope,Handle<StaticScope*>staticScope,constReadOnlyCompileOptions&optionsArg,SourceBufferHolder&srcBuf,MutableHandleValuerval){CompileOptionsoptions(cx,optionsArg);MOZ_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));AssertHeapIsIdle(cx);CHECK_REQUEST(cx);assertSameCompartment(cx,scope);AutoLastFrameChecklfc(cx);MOZ_ASSERT_IF(!IsGlobalLexicalScope(scope),HasNonSyntacticStaticScopeChain(staticScope));options.setIsRunOnce(true);SourceCompressionTasksct(cx);RootedScriptscript(cx,frontend::CompileScript(cx,&cx->tempLifoAlloc(),scope,staticScope,/* evalCaller = */nullptr,options,srcBuf,/* source = */nullptr,&sct));if(!script)returnfalse;MOZ_ASSERT(script->getVersion()==options.version);boolresult=Execute(cx,script,*scope,options.noScriptRval?nullptr:rval.address());if(!sct.complete())result=false;// After evaluation, the compiled script will not be run again.// script->ensureRanAnalysis allocated 1 analyze::Bytecode for every opcode// which for large scripts means significant memory. Perform a GC eagerly// to clear out this analysis data before anything happens to inhibit the// flushing of this memory (such as setting requestAnimationFrame).if(script->length()>LARGE_SCRIPT_LENGTH){script=nullptr;PrepareZoneForGC(cx->zone());cx->runtime()->gc.gc(GC_NORMAL,JS::gcreason::FINISH_LARGE_EVALUATE);}returnresult;}staticboolEvaluate(JSContext*cx,AutoObjectVector&scopeChain,constReadOnlyCompileOptions&optionsArg,SourceBufferHolder&srcBuf,MutableHandleValuerval){RootedObjectdynamicScope(cx);Rooted<StaticScope*>staticScope(cx);if(!CreateNonSyntacticScopeChain(cx,scopeChain,&dynamicScope,&staticScope))returnfalse;return::Evaluate(cx,dynamicScope,staticScope,optionsArg,srcBuf,rval);}staticboolEvaluate(JSContext*cx,constReadOnlyCompileOptions&optionsArg,constchar16_t*chars,size_tlength,MutableHandleValuerval){SourceBufferHoldersrcBuf(chars,length,SourceBufferHolder::NoOwnership);Rooted<ClonedBlockObject*>globalLexical(cx,&cx->global()->lexicalScope());Rooted<StaticScope*>staticLexical(cx,&globalLexical->staticBlock());return::Evaluate(cx,globalLexical,staticLexical,optionsArg,srcBuf,rval);}externJS_PUBLIC_API(bool)JS::Evaluate(JSContext*cx,constReadOnlyCompileOptions&options,constchar*bytes,size_tlength,MutableHandleValuerval){char16_t*chars;if(options.utf8)chars=UTF8CharsToNewTwoByteCharsZ(cx,JS::UTF8Chars(bytes,length),&length).get();elsechars=InflateString(cx,bytes,&length);if(!chars)returnfalse;SourceBufferHoldersrcBuf(chars,length,SourceBufferHolder::GiveOwnership);Rooted<ClonedBlockObject*>globalLexical(cx,&cx->global()->lexicalScope());Rooted<StaticScope*>staticLexical(cx,&globalLexical->staticBlock());boolok=::Evaluate(cx,globalLexical,staticLexical,options,srcBuf,rval);returnok;}staticboolEvaluate(JSContext*cx,constReadOnlyCompileOptions&optionsArg,constchar*filename,MutableHandleValuerval){FileContentsbuffer(cx);{AutoFilefile;if(!file.open(cx,filename)||!file.readAll(cx,buffer))returnfalse;}CompileOptionsoptions(cx,optionsArg);options.setFileAndLine(filename,1);returnEvaluate(cx,options,buffer.begin(),buffer.length(),rval);}JS_PUBLIC_API(bool)JS::Evaluate(JSContext*cx,constReadOnlyCompileOptions&optionsArg,SourceBufferHolder&srcBuf,MutableHandleValuerval){Rooted<ClonedBlockObject*>globalLexical(cx,&cx->global()->lexicalScope());Rooted<StaticScope*>staticLexical(cx,&globalLexical->staticBlock());return::Evaluate(cx,globalLexical,staticLexical,optionsArg,srcBuf,rval);}JS_PUBLIC_API(bool)JS::Evaluate(JSContext*cx,AutoObjectVector&scopeChain,constReadOnlyCompileOptions&optionsArg,SourceBufferHolder&srcBuf,MutableHandleValuerval){return::Evaluate(cx,scopeChain,optionsArg,srcBuf,rval);}JS_PUBLIC_API(bool)JS::Evaluate(JSContext*cx,constReadOnlyCompileOptions&optionsArg,constchar16_t*chars,size_tlength,MutableHandleValuerval){return::Evaluate(cx,optionsArg,chars,length,rval);}JS_PUBLIC_API(bool)JS::Evaluate(JSContext*cx,AutoObjectVector&scopeChain,constReadOnlyCompileOptions&optionsArg,constchar16_t*chars,size_tlength,MutableHandleValuerval){SourceBufferHoldersrcBuf(chars,length,SourceBufferHolder::NoOwnership);return::Evaluate(cx,scopeChain,optionsArg,srcBuf,rval);}JS_PUBLIC_API(bool)JS::Evaluate(JSContext*cx,constReadOnlyCompileOptions&optionsArg,constchar*filename,MutableHandleValuerval){return::Evaluate(cx,optionsArg,filename,rval);}staticJSObject*JS_NewHelper(JSContext*cx,HandleObjectctor,constJS::HandleValueArray&inputArgs){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);assertSameCompartment(cx,ctor,inputArgs);RootedValuectorVal(cx,ObjectValue(*ctor));if(!IsConstructor(ctorVal)){ReportValueError(cx,JSMSG_NOT_CONSTRUCTOR,JSDVG_IGNORE_STACK,ctorVal,nullptr);returnnullptr;}ConstructArgsargs(cx);if(!FillArgumentsFromArraylike(cx,args,inputArgs))returnnullptr;RootedObjectobj(cx);if(!js::Construct(cx,ctorVal,args,ctorVal,&obj))returnnullptr;returnobj;}JS_PUBLIC_API(JSObject*)JS_New(JSContext*cx,HandleObjectctor,constJS::HandleValueArray&inputArgs){RootedObjectobj(cx);{AutoLastFrameChecklfc(cx);obj=JS_NewHelper(cx,ctor,inputArgs);}returnobj;}JS_PUBLIC_API(bool)JS_CheckForInterrupt(JSContext*cx){returnjs::CheckForInterrupt(cx);}JS_PUBLIC_API(JSInterruptCallback)JS_SetInterruptCallback(JSRuntime*rt,JSInterruptCallbackcallback){JSInterruptCallbackold=rt->interruptCallback;rt->interruptCallback=callback;returnold;}JS_PUBLIC_API(JSInterruptCallback)JS_GetInterruptCallback(JSRuntime*rt){returnrt->interruptCallback;}/************************************************************************//* * Promises. */JS_PUBLIC_API(void)JS::SetEnqueuePromiseJobCallback(JSRuntime*rt,JSEnqueuePromiseJobCallbackcallback,void*data/* = nullptr */){rt->enqueuePromiseJobCallback=callback;rt->enqueuePromiseJobCallbackData=data;}JS_PUBLIC_API(JSObject*)JS::NewPromiseObject(JSContext*cx,HandleObjectexecutor,HandleObjectproto/* = nullptr */){MOZ_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));MOZ_ASSERT(IsCallable(executor));AssertHeapIsIdle(cx);CHECK_REQUEST(cx);returnPromiseObject::create(cx,executor,proto);}JS_PUBLIC_API(bool)JS::IsPromiseObject(JS::HandleObjectobj){JSObject*object=CheckedUnwrap(obj);returnobject&&object->is<PromiseObject>();}JS_PUBLIC_API(JSObject*)JS::GetPromiseConstructor(JSContext*cx){CHECK_REQUEST(cx);Rooted<GlobalObject*>global(cx,cx->global());returnGlobalObject::getOrCreatePromiseConstructor(cx,global);}JS_PUBLIC_API(JSObject*)JS::GetPromisePrototype(JSContext*cx){CHECK_REQUEST(cx);Rooted<GlobalObject*>global(cx,cx->global());returnGlobalObject::getOrCreatePromisePrototype(cx,global);}JS_PUBLIC_API(JS::PromiseState)JS::GetPromiseState(JS::HandleObjectobj){JSObject*promise=CheckedUnwrap(obj);returnpromise->as<PromiseObject>().state();}JS_PUBLIC_API(double)JS::GetPromiseID(JS::HandleObjectpromise){returnpromise->as<PromiseObject>().getID();}JS_PUBLIC_API(JS::Value)JS::GetPromiseResult(JS::HandleObjectpromiseObj){PromiseObject*promise=&promiseObj->as<PromiseObject>();MOZ_ASSERT(promise->state()!=JS::PromiseState::Pending);returnpromise->state()==JS::PromiseState::Fulfilled?promise->value():promise->reason();}JS_PUBLIC_API(JSObject*)JS::GetPromiseAllocationSite(JS::HandleObjectpromise){returnpromise->as<PromiseObject>().allocationSite();}JS_PUBLIC_API(JSObject*)JS::GetPromiseResolutionSite(JS::HandleObjectpromise){returnpromise->as<PromiseObject>().resolutionSite();}JS_PUBLIC_API(JSObject*)JS::CallOriginalPromiseResolve(JSContext*cx,JS::HandleValueresolutionValue){InvokeArgsargs(cx);if(!args.init(1))returnnullptr;RootedObjectpromiseCtor(cx,GetPromiseConstructor(cx));if(!promiseCtor)returnnullptr;args.setThis(ObjectValue(*promiseCtor));args[0].set(resolutionValue);if(!CallSelfHostedFunction(cx,"Promise_static_resolve",args))returnnullptr;MOZ_ASSERT(args.rval().isObject());JSObject*obj=&args.rval().toObject();MOZ_ASSERT(obj->is<PromiseObject>());returnobj;}JS_PUBLIC_API(JSObject*)JS::CallOriginalPromiseReject(JSContext*cx,JS::HandleValuerejectionValue){InvokeArgsargs(cx);if(!args.init(1))returnnullptr;RootedObjectpromiseCtor(cx,GetPromiseConstructor(cx));if(!promiseCtor)returnnullptr;args.setThis(ObjectValue(*promiseCtor));args[0].set(rejectionValue);if(!CallSelfHostedFunction(cx,"Promise_static_reject",args))returnnullptr;MOZ_ASSERT(args.rval().isObject());JSObject*obj=&args.rval().toObject();MOZ_ASSERT(obj->is<PromiseObject>());returnobj;}JS_PUBLIC_API(bool)JS::ResolvePromise(JSContext*cx,JS::HandleObjectpromise,JS::HandleValueresolutionValue){MOZ_ASSERT(promise->is<PromiseObject>());returnpromise->as<PromiseObject>().resolve(cx,resolutionValue);}JS_PUBLIC_API(bool)JS::RejectPromise(JSContext*cx,JS::HandleObjectpromise,JS::HandleValuerejectionValue){MOZ_ASSERT(promise->is<PromiseObject>());returnpromise->as<PromiseObject>().reject(cx,rejectionValue);}JS_PUBLIC_API(JSObject*)JS::CallOriginalPromiseThen(JSContext*cx,JS::HandleObjectpromise,JS::HandleObjectonResolve,JS::HandleObjectonReject){MOZ_ASSERT(promise->is<PromiseObject>());MOZ_ASSERT(onResolve==nullptr||IsCallable(onResolve));MOZ_ASSERT(onReject==nullptr||IsCallable(onReject));InvokeArgsargs(cx);if(!args.init(2))returnnullptr;args.setThis(ObjectValue(*promise));args[0].setObjectOrNull(onResolve);args[1].setObjectOrNull(onReject);if(!CallSelfHostedFunction(cx,"Promise_then",args))returnnullptr;MOZ_ASSERT(args.rval().isObject());JSObject*obj=&args.rval().toObject();MOZ_ASSERT(obj->is<PromiseObject>());returnobj;}JS_PUBLIC_API(bool)JS::AddPromiseReactions(JSContext*cx,JS::HandleObjectpromise,JS::HandleObjectonResolve,JS::HandleObjectonReject){MOZ_ASSERT(promise->is<PromiseObject>());MOZ_ASSERT(IsCallable(onResolve));MOZ_ASSERT(IsCallable(onReject));InvokeArgsargs(cx);if(!args.init(4))returnfalse;args[0].setObject(*promise);args[1].setNull();args[2].setObject(*onResolve);args[3].setObject(*onReject);returnjs::CallSelfHostedFunction(cx,"EnqueuePromiseReactions",args);}JS_PUBLIC_API(JSObject*)JS::GetWaitForAllPromise(JSContext*cx,constJS::AutoObjectVector&promises){RootedArrayObjectarr(cx,NewDenseFullyAllocatedArray(cx,promises.length()));if(!arr)returnnullptr;arr->ensureDenseInitializedLength(cx,0,promises.length());for(size_ti=0,len=promises.length();i<len;i++){#ifdef DEBUGJSObject*obj=promises[i];if(IsWrapper(obj))obj=UncheckedUnwrap(obj);MOZ_ASSERT(obj->is<PromiseObject>());#endifarr->setDenseElement(i,ObjectValue(*promises[i]));}InvokeArgsargs(cx);if(!args.init(1))returnnullptr;args[0].setObject(*arr);if(!js::CallSelfHostedFunction(cx,"GetWaitForAllPromise",args))returnnullptr;MOZ_ASSERT(args.rval().isObject());JSObject*obj=&args.rval().toObject();MOZ_ASSERT(obj->is<PromiseObject>());returnobj;}JS_PUBLIC_API(void)JS_RequestInterruptCallback(JSRuntime*rt){rt->requestInterrupt(JSRuntime::RequestInterruptUrgent);}JS_PUBLIC_API(bool)JS_IsRunning(JSContext*cx){returncx->currentlyRunning();}JS_PUBLIC_API(bool)JS_SaveFrameChain(JSContext*cx){AssertHeapIsIdleOrIterating(cx);CHECK_REQUEST(cx);returncx->saveFrameChain();}JS_PUBLIC_API(void)JS_RestoreFrameChain(JSContext*cx){AssertHeapIsIdleOrIterating(cx);CHECK_REQUEST(cx);cx->restoreFrameChain();}JS::AutoSetAsyncStackForNewCalls::AutoSetAsyncStackForNewCalls(JSContext*cx,HandleObjectstack,HandleStringasyncCause,JS::AutoSetAsyncStackForNewCalls::AsyncCallKindkind):cx(cx),oldAsyncStack(cx,cx->runtime()->asyncStackForNewActivations),oldAsyncCause(cx,cx->runtime()->asyncCauseForNewActivations),oldAsyncCallIsExplicit(cx->runtime()->asyncCallIsExplicit){CHECK_REQUEST(cx);// The option determines whether we actually use the new values at this// point. It will not affect restoring the previous values when the object// is destroyed, so if the option changes it won't cause consistency issues.if(!cx->runtime()->options().asyncStack())return;SavedFrame*asyncStack=&stack->as<SavedFrame>();MOZ_ASSERT(!asyncCause->empty());cx->runtime()->asyncStackForNewActivations=asyncStack;cx->runtime()->asyncCauseForNewActivations=asyncCause;cx->runtime()->asyncCallIsExplicit=kind==AsyncCallKind::EXPLICIT;}JS::AutoSetAsyncStackForNewCalls::~AutoSetAsyncStackForNewCalls(){cx->runtime()->asyncCauseForNewActivations=oldAsyncCause;cx->runtime()->asyncStackForNewActivations=oldAsyncStack?&oldAsyncStack->as<SavedFrame>():nullptr;cx->runtime()->asyncCallIsExplicit=oldAsyncCallIsExplicit;}/************************************************************************/JS_PUBLIC_API(JSString*)JS_NewStringCopyN(JSContext*cx,constchar*s,size_tn){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);if(!n)returncx->names().empty;returnNewStringCopyN<CanGC>(cx,s,n);}JS_PUBLIC_API(JSString*)JS_NewStringCopyZ(JSContext*cx,constchar*s){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);if(!s||!*s)returncx->runtime()->emptyString;returnNewStringCopyZ<CanGC>(cx,s);}JS_PUBLIC_API(bool)JS_StringHasBeenPinned(JSContext*cx,JSString*str){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);if(!str->isAtom())returnfalse;returnAtomIsPinned(cx,&str->asAtom());}JS_PUBLIC_API(jsid)INTERNED_STRING_TO_JSID(JSContext*cx,JSString*str){MOZ_ASSERT(str);MOZ_ASSERT(((size_t)str&JSID_TYPE_MASK)==0);MOZ_ASSERT_IF(cx,JS_StringHasBeenPinned(cx,str));returnAtomToId(&str->asAtom());}JS_PUBLIC_API(JSString*)JS_AtomizeAndPinJSString(JSContext*cx,HandleStringstr){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);JSAtom*atom=AtomizeString(cx,str,PinAtom);MOZ_ASSERT_IF(atom,JS_StringHasBeenPinned(cx,atom));returnatom;}JS_PUBLIC_API(JSString*)JS_AtomizeString(JSContext*cx,constchar*s){returnJS_AtomizeStringN(cx,s,strlen(s));}JS_PUBLIC_API(JSString*)JS_AtomizeStringN(JSContext*cx,constchar*s,size_tlength){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);returnAtomize(cx,s,length,DoNotPinAtom);}JS_PUBLIC_API(JSString*)JS_AtomizeAndPinString(JSContext*cx,constchar*s){returnJS_AtomizeAndPinStringN(cx,s,strlen(s));}JS_PUBLIC_API(JSString*)JS_AtomizeAndPinStringN(JSContext*cx,constchar*s,size_tlength){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);JSAtom*atom=Atomize(cx,s,length,PinAtom);MOZ_ASSERT_IF(atom,JS_StringHasBeenPinned(cx,atom));returnatom;}JS_PUBLIC_API(JSString*)JS_NewUCString(JSContext*cx,char16_t*chars,size_tlength){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);returnNewString<CanGC>(cx,chars,length);}JS_PUBLIC_API(JSString*)JS_NewUCStringCopyN(JSContext*cx,constchar16_t*s,size_tn){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);if(!n)returncx->names().empty;returnNewStringCopyN<CanGC>(cx,s,n);}JS_PUBLIC_API(JSString*)JS_NewUCStringCopyZ(JSContext*cx,constchar16_t*s){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);if(!s)returncx->runtime()->emptyString;returnNewStringCopyZ<CanGC>(cx,s);}JS_PUBLIC_API(JSString*)JS_AtomizeUCString(JSContext*cx,constchar16_t*s){returnJS_AtomizeUCStringN(cx,s,js_strlen(s));}JS_PUBLIC_API(JSString*)JS_AtomizeUCStringN(JSContext*cx,constchar16_t*s,size_tlength){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);returnAtomizeChars(cx,s,length,DoNotPinAtom);}JS_PUBLIC_API(JSString*)JS_AtomizeAndPinUCStringN(JSContext*cx,constchar16_t*s,size_tlength){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);JSAtom*atom=AtomizeChars(cx,s,length,PinAtom);MOZ_ASSERT_IF(atom,JS_StringHasBeenPinned(cx,atom));returnatom;}JS_PUBLIC_API(JSString*)JS_AtomizeAndPinUCString(JSContext*cx,constchar16_t*s){returnJS_AtomizeAndPinUCStringN(cx,s,js_strlen(s));}JS_PUBLIC_API(size_t)JS_GetStringLength(JSString*str){returnstr->length();}JS_PUBLIC_API(bool)JS_StringIsFlat(JSString*str){returnstr->isFlat();}JS_PUBLIC_API(bool)JS_StringHasLatin1Chars(JSString*str){returnstr->hasLatin1Chars();}JS_PUBLIC_API(constJS::Latin1Char*)JS_GetLatin1StringCharsAndLength(JSContext*cx,constJS::AutoCheckCannotGC&nogc,JSString*str,size_t*plength){MOZ_ASSERT(plength);AssertHeapIsIdleOrStringIsFlat(cx,str);CHECK_REQUEST(cx);assertSameCompartment(cx,str);JSLinearString*linear=str->ensureLinear(cx);if(!linear)returnnullptr;*plength=linear->length();returnlinear->latin1Chars(nogc);}JS_PUBLIC_API(constchar16_t*)JS_GetTwoByteStringCharsAndLength(JSContext*cx,constJS::AutoCheckCannotGC&nogc,JSString*str,size_t*plength){MOZ_ASSERT(plength);AssertHeapIsIdleOrStringIsFlat(cx,str);CHECK_REQUEST(cx);assertSameCompartment(cx,str);JSLinearString*linear=str->ensureLinear(cx);if(!linear)returnnullptr;*plength=linear->length();returnlinear->twoByteChars(nogc);}JS_PUBLIC_API(constchar16_t*)JS_GetTwoByteExternalStringChars(JSString*str){returnstr->asExternal().twoByteChars();}JS_PUBLIC_API(bool)JS_GetStringCharAt(JSContext*cx,JSString*str,size_tindex,char16_t*res){AssertHeapIsIdleOrStringIsFlat(cx,str);CHECK_REQUEST(cx);assertSameCompartment(cx,str);JSLinearString*linear=str->ensureLinear(cx);if(!linear)returnfalse;*res=linear->latin1OrTwoByteChar(index);returntrue;}JS_PUBLIC_API(char16_t)JS_GetFlatStringCharAt(JSFlatString*str,size_tindex){returnstr->latin1OrTwoByteChar(index);}JS_PUBLIC_API(bool)JS_CopyStringChars(JSContext*cx,mozilla::Range<char16_t>dest,JSString*str){AssertHeapIsIdleOrStringIsFlat(cx,str);CHECK_REQUEST(cx);assertSameCompartment(cx,str);JSLinearString*linear=str->ensureLinear(cx);if(!linear)returnfalse;MOZ_ASSERT(linear->length()<=dest.length());CopyChars(dest.start().get(),*linear);returntrue;}JS_PUBLIC_API(constLatin1Char*)JS_GetLatin1InternedStringChars(constJS::AutoCheckCannotGC&nogc,JSString*str){MOZ_ASSERT(str->isAtom());JSFlatString*flat=str->ensureFlat(nullptr);if(!flat)returnnullptr;returnflat->latin1Chars(nogc);}JS_PUBLIC_API(constchar16_t*)JS_GetTwoByteInternedStringChars(constJS::AutoCheckCannotGC&nogc,JSString*str){MOZ_ASSERT(str->isAtom());JSFlatString*flat=str->ensureFlat(nullptr);if(!flat)returnnullptr;returnflat->twoByteChars(nogc);}externJS_PUBLIC_API(JSFlatString*)JS_FlattenString(JSContext*cx,JSString*str){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);assertSameCompartment(cx,str);JSFlatString*flat=str->ensureFlat(cx);if(!flat)returnnullptr;returnflat;}externJS_PUBLIC_API(constLatin1Char*)JS_GetLatin1FlatStringChars(constJS::AutoCheckCannotGC&nogc,JSFlatString*str){returnstr->latin1Chars(nogc);}externJS_PUBLIC_API(constchar16_t*)JS_GetTwoByteFlatStringChars(constJS::AutoCheckCannotGC&nogc,JSFlatString*str){returnstr->twoByteChars(nogc);}JS_PUBLIC_API(bool)JS_CompareStrings(JSContext*cx,JSString*str1,JSString*str2,int32_t*result){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);returnCompareStrings(cx,str1,str2,result);}JS_PUBLIC_API(bool)JS_StringEqualsAscii(JSContext*cx,JSString*str,constchar*asciiBytes,bool*match){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);JSLinearString*linearStr=str->ensureLinear(cx);if(!linearStr)returnfalse;*match=StringEqualsAscii(linearStr,asciiBytes);returntrue;}JS_PUBLIC_API(bool)JS_FlatStringEqualsAscii(JSFlatString*str,constchar*asciiBytes){returnStringEqualsAscii(str,asciiBytes);}JS_PUBLIC_API(size_t)JS_PutEscapedFlatString(char*buffer,size_tsize,JSFlatString*str,charquote){returnPutEscapedString(buffer,size,str,quote);}JS_PUBLIC_API(size_t)JS_PutEscapedString(JSContext*cx,char*buffer,size_tsize,JSString*str,charquote){AssertHeapIsIdle(cx);JSLinearString*linearStr=str->ensureLinear(cx);if(!linearStr)returnsize_t(-1);returnPutEscapedString(buffer,size,linearStr,quote);}JS_PUBLIC_API(bool)JS_FileEscapedString(FILE*fp,JSString*str,charquote){JSLinearString*linearStr=str->ensureLinear(nullptr);returnlinearStr&&FileEscapedString(fp,linearStr,quote);}JS_PUBLIC_API(JSString*)JS_NewDependentString(JSContext*cx,HandleStringstr,size_tstart,size_tlength){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);returnNewDependentString(cx,str,start,length);}JS_PUBLIC_API(JSString*)JS_ConcatStrings(JSContext*cx,HandleStringleft,HandleStringright){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);returnConcatStrings<CanGC>(cx,left,right);}JS_PUBLIC_API(bool)JS_DecodeBytes(JSContext*cx,constchar*src,size_tsrclen,char16_t*dst,size_t*dstlenp){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);if(!dst){*dstlenp=srclen;returntrue;}size_tdstlen=*dstlenp;if(srclen>dstlen){CopyAndInflateChars(dst,src,dstlen);AutoSuppressGCsuppress(cx);JS_ReportErrorNumber(cx,GetErrorMessage,nullptr,JSMSG_BUFFER_TOO_SMALL);returnfalse;}CopyAndInflateChars(dst,src,srclen);*dstlenp=srclen;returntrue;}staticchar*EncodeLatin1(ExclusiveContext*cx,JSString*str){JSLinearString*linear=str->ensureLinear(cx);if(!linear)returnnullptr;JS::AutoCheckCannotGCnogc;if(linear->hasTwoByteChars())returnJS::LossyTwoByteCharsToNewLatin1CharsZ(cx,linear->twoByteRange(nogc)).c_str();size_tlen=str->length();Latin1Char*buf=cx->pod_malloc<Latin1Char>(len+1);if(!buf){ReportOutOfMemory(cx);returnnullptr;}mozilla::PodCopy(buf,linear->latin1Chars(nogc),len);buf[len]='\0';returnreinterpret_cast<char*>(buf);}JS_PUBLIC_API(char*)JS_EncodeString(JSContext*cx,JSString*str){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);returnEncodeLatin1(cx,str);}JS_PUBLIC_API(char*)JS_EncodeStringToUTF8(JSContext*cx,HandleStringstr){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);returnStringToNewUTF8CharsZ(cx,*str).release();}JS_PUBLIC_API(size_t)JS_GetStringEncodingLength(JSContext*cx,JSString*str){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);if(!str->ensureLinear(cx))returnsize_t(-1);returnstr->length();}JS_PUBLIC_API(size_t)JS_EncodeStringToBuffer(JSContext*cx,JSString*str,char*buffer,size_tlength){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);/* * FIXME bug 612141 - fix DeflateStringToBuffer interface so the result * would allow to distinguish between insufficient buffer and encoding * error. */size_twrittenLength=length;JSLinearString*linear=str->ensureLinear(cx);if(!linear)returnsize_t(-1);boolres;if(linear->hasLatin1Chars()){JS::AutoCheckCannotGCnogc;res=DeflateStringToBuffer(nullptr,linear->latin1Chars(nogc),linear->length(),buffer,&writtenLength);}else{JS::AutoCheckCannotGCnogc;res=DeflateStringToBuffer(nullptr,linear->twoByteChars(nogc),linear->length(),buffer,&writtenLength);}if(res){MOZ_ASSERT(writtenLength<=length);returnwrittenLength;}MOZ_ASSERT(writtenLength<=length);size_tnecessaryLength=str->length();if(necessaryLength==size_t(-1))returnsize_t(-1);MOZ_ASSERT(writtenLength==length);// C strings are NOT encoded.returnnecessaryLength;}JS_PUBLIC_API(JS::Symbol*)JS::NewSymbol(JSContext*cx,HandleStringdescription){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);if(description)assertSameCompartment(cx,description);returnSymbol::new_(cx,SymbolCode::UniqueSymbol,description);}JS_PUBLIC_API(JS::Symbol*)JS::GetSymbolFor(JSContext*cx,HandleStringkey){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);assertSameCompartment(cx,key);returnSymbol::for_(cx,key);}JS_PUBLIC_API(JSString*)JS::GetSymbolDescription(HandleSymbolsymbol){returnsymbol->description();}JS_PUBLIC_API(JS::SymbolCode)JS::GetSymbolCode(Handle<Symbol*>symbol){returnsymbol->code();}JS_PUBLIC_API(JS::Symbol*)JS::GetWellKnownSymbol(JSContext*cx,JS::SymbolCodewhich){returncx->wellKnownSymbols().get(uint32_t(which));}#ifdef DEBUGstaticboolPropertySpecNameIsDigits(constchar*s){if(JS::PropertySpecNameIsSymbol(s))returnfalse;if(!*s)returnfalse;for(;*s;s++){if(*s<'0'||*s>'9')returnfalse;}returntrue;}#endif // DEBUGJS_PUBLIC_API(bool)JS::PropertySpecNameEqualsId(constchar*name,HandleIdid){if(JS::PropertySpecNameIsSymbol(name)){if(!JSID_IS_SYMBOL(id))returnfalse;Symbol*sym=JSID_TO_SYMBOL(id);returnsym->isWellKnownSymbol()&&sym->code()==PropertySpecNameToSymbolCode(name);}MOZ_ASSERT(!PropertySpecNameIsDigits(name));returnJSID_IS_ATOM(id)&&JS_FlatStringEqualsAscii(JSID_TO_ATOM(id),name);}JS_PUBLIC_API(bool)JS_Stringify(JSContext*cx,MutableHandleValuevp,HandleObjectreplacer,HandleValuespace,JSONWriteCallbackcallback,void*data){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);assertSameCompartment(cx,replacer,space);StringBuffersb(cx);if(!sb.ensureTwoByteChars())returnfalse;if(!Stringify(cx,vp,replacer,space,sb,StringifyBehavior::Normal))returnfalse;if(sb.empty()&&!sb.append(cx->names().null))returnfalse;returncallback(sb.rawTwoByteBegin(),sb.length(),data);}JS_PUBLIC_API(bool)JS::ToJSONMaybeSafely(JSContext*cx,JS::HandleObjectinput,JSONWriteCallbackcallback,void*data){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);assertSameCompartment(cx,input);StringBuffersb(cx);if(!sb.ensureTwoByteChars())returnfalse;RootedValueinputValue(cx,ObjectValue(*input));if(!Stringify(cx,&inputValue,nullptr,NullHandleValue,sb,StringifyBehavior::RestrictedSafe))returnfalse;if(sb.empty()&&!sb.append(cx->names().null))returnfalse;returncallback(sb.rawTwoByteBegin(),sb.length(),data);}JS_PUBLIC_API(bool)JS_ParseJSON(JSContext*cx,constchar16_t*chars,uint32_tlen,MutableHandleValuevp){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);returnParseJSONWithReviver(cx,mozilla::Range<constchar16_t>(chars,len),NullHandleValue,vp);}JS_PUBLIC_API(bool)JS_ParseJSON(JSContext*cx,HandleStringstr,MutableHandleValuevp){returnJS_ParseJSONWithReviver(cx,str,NullHandleValue,vp);}JS_PUBLIC_API(bool)JS_ParseJSONWithReviver(JSContext*cx,constchar16_t*chars,uint32_tlen,HandleValuereviver,MutableHandleValuevp){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);returnParseJSONWithReviver(cx,mozilla::Range<constchar16_t>(chars,len),reviver,vp);}JS_PUBLIC_API(bool)JS_ParseJSONWithReviver(JSContext*cx,HandleStringstr,HandleValuereviver,MutableHandleValuevp){AssertHeapIsIdle(cx);CHECK_REQUEST(cx);assertSameCompartment(cx,str);AutoStableStringCharsstableChars(cx);if(!stableChars.init(cx,str))returnfalse;returnstableChars.isLatin1()?ParseJSONWithReviver(cx,stableChars.latin1Range(),reviver,vp):ParseJSONWithReviver(cx,stableChars.twoByteRange(),reviver,vp);}/************************************************************************/JS_PUBLIC_API(void)JS_ReportError(JSContext*cx,constchar*format,...){va_listap;AssertHeapIsIdle(cx);va_start(ap,format);ReportErrorVA(cx,JSREPORT_ERROR,format,ap);va_end(ap);}JS_PUBLIC_API(void)JS_ReportErrorNumber(JSContext*cx,JSErrorCallbackerrorCallback,void*userRef,constunsignederrorNumber,...){va_listap;va_start(ap,errorNumber);JS_ReportErrorNumberVA(cx,errorCallback,userRef,errorNumber,ap);va_end(ap);}JS_PUBLIC_API(void)JS_ReportErrorNumberVA(JSContext*cx,JSErrorCallbackerrorCallback,void*userRef,constunsignederrorNumber,va_listap){AssertHeapIsIdle(cx);ReportErrorNumberVA(cx,JSREPORT_ERROR,errorCallback,userRef,errorNumber,ArgumentsAreASCII,ap);}JS_PUBLIC_API(void)JS_ReportErrorNumberUC(JSContext*cx,JSErrorCallbackerrorCallback,void*userRef,constunsignederrorNumber,...){va_listap;AssertHeapIsIdle(cx);va_start(ap,errorNumber);ReportErrorNumberVA(cx,JSREPORT_ERROR,errorCallback,userRef,errorNumber,ArgumentsAreUnicode,ap);va_end(ap);}JS_PUBLIC_API(void)JS_ReportErrorNumberUCArray(JSContext*cx,JSErrorCallbackerrorCallback,void*userRef,constunsignederrorNumber,constchar16_t**args){AssertHeapIsIdle(cx);ReportErrorNumberUCArray(cx,JSREPORT_ERROR,errorCallback,userRef,errorNumber,args);}JS_PUBLIC_API(bool)JS_ReportWarning(JSContext*cx,constchar*format,...){va_listap;boolok;AssertHeapIsIdle(cx);va_start(ap,format);ok=ReportErrorVA(cx,JSREPORT_WARNING,format,ap);va_end(ap);returnok;}JS_PUBLIC_API(bool)JS_ReportErrorFlagsAndNumber(JSContext*cx,unsignedflags,JSErrorCallbackerrorCallback,void*userRef,constunsignederrorNumber,...){va_listap;boolok;AssertHeapIsIdle(cx);va_start(ap,errorNumber);ok=ReportErrorNumberVA(cx,flags,errorCallback,userRef,errorNumber,ArgumentsAreASCII,ap);va_end(ap);returnok;}JS_PUBLIC_API(bool)JS_ReportErrorFlagsAndNumberUC(JSContext*cx,unsignedflags,