| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067 |
- /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * vim: set ts=8 sts=4 et sw=4 tw=99:
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
- #ifndef jsfriendapi_h
- #define jsfriendapi_h
- #include "mozilla/Atomics.h"
- #include "mozilla/Casting.h"
- #include "mozilla/Maybe.h"
- #include "mozilla/MemoryReporting.h"
- #include "mozilla/UniquePtr.h"
- #include "jsapi.h" // For JSAutoByteString. See bug 1033916.
- #include "jsbytecode.h"
- #include "jspubtd.h"
- #include "js/CallArgs.h"
- #include "js/CallNonGenericMethod.h"
- #include "js/Class.h"
- #include "js/Utility.h"
- #if JS_STACK_GROWTH_DIRECTION > 0
- # define JS_CHECK_STACK_SIZE(limit, sp) (MOZ_LIKELY((uintptr_t)(sp) < (limit)))
- #else
- # define JS_CHECK_STACK_SIZE(limit, sp) (MOZ_LIKELY((uintptr_t)(sp) > (limit)))
- #endif
- class JSAtom;
- struct JSErrorFormatString;
- class JSLinearString;
- struct JSJitInfo;
- class JSErrorReport;
- namespace JS {
- template <class T>
- class Heap;
- } /* namespace JS */
- namespace js {
- class JS_FRIEND_API(BaseProxyHandler);
- class InterpreterFrame;
- } /* namespace js */
- extern JS_FRIEND_API(void)
- JS_SetGrayGCRootsTracer(JSContext* cx, JSTraceDataOp traceOp, void* data);
- extern JS_FRIEND_API(JSObject*)
- JS_FindCompilationScope(JSContext* cx, JS::HandleObject obj);
- extern JS_FRIEND_API(JSFunction*)
- JS_GetObjectFunction(JSObject* obj);
- extern JS_FRIEND_API(bool)
- JS_SplicePrototype(JSContext* cx, JS::HandleObject obj, JS::HandleObject proto);
- extern JS_FRIEND_API(JSObject*)
- JS_NewObjectWithUniqueType(JSContext* cx, const JSClass* clasp, JS::HandleObject proto);
- /**
- * Allocate an object in exactly the same way as JS_NewObjectWithGivenProto, but
- * without invoking the metadata callback on it. This allows creation of
- * internal bookkeeping objects that are guaranteed to not have metadata
- * attached to them.
- */
- extern JS_FRIEND_API(JSObject*)
- JS_NewObjectWithoutMetadata(JSContext* cx, const JSClass* clasp, JS::Handle<JSObject*> proto);
- extern JS_FRIEND_API(uint32_t)
- JS_ObjectCountDynamicSlots(JS::HandleObject obj);
- extern JS_FRIEND_API(size_t)
- JS_SetProtoCalled(JSContext* cx);
- extern JS_FRIEND_API(size_t)
- JS_GetCustomIteratorCount(JSContext* cx);
- extern JS_FRIEND_API(bool)
- JS_NondeterministicGetWeakMapKeys(JSContext* cx, JS::HandleObject obj, JS::MutableHandleObject ret);
- extern JS_FRIEND_API(bool)
- JS_NondeterministicGetWeakSetKeys(JSContext* cx, JS::HandleObject obj, JS::MutableHandleObject ret);
- // Raw JSScript* because this needs to be callable from a signal handler.
- extern JS_FRIEND_API(unsigned)
- JS_PCToLineNumber(JSScript* script, jsbytecode* pc, unsigned* columnp = nullptr);
- /**
- * Determine whether the given object is backed by a DeadObjectProxy.
- *
- * Such objects hold no other objects (they have no outgoing reference edges)
- * and will throw if you touch them (e.g. by reading/writing a property).
- */
- extern JS_FRIEND_API(bool)
- JS_IsDeadWrapper(JSObject* obj);
- /*
- * Used by the cycle collector to trace through a shape or object group and
- * all cycle-participating data it reaches, using bounded stack space.
- */
- extern JS_FRIEND_API(void)
- JS_TraceShapeCycleCollectorChildren(JS::CallbackTracer* trc, JS::GCCellPtr shape);
- extern JS_FRIEND_API(void)
- JS_TraceObjectGroupCycleCollectorChildren(JS::CallbackTracer* trc, JS::GCCellPtr group);
- enum {
- JS_TELEMETRY_GC_REASON,
- JS_TELEMETRY_GC_IS_ZONE_GC,
- JS_TELEMETRY_GC_MS,
- JS_TELEMETRY_GC_BUDGET_MS,
- JS_TELEMETRY_GC_ANIMATION_MS,
- JS_TELEMETRY_GC_MAX_PAUSE_MS,
- JS_TELEMETRY_GC_MARK_MS,
- JS_TELEMETRY_GC_SWEEP_MS,
- JS_TELEMETRY_GC_COMPACT_MS,
- JS_TELEMETRY_GC_MARK_ROOTS_MS,
- JS_TELEMETRY_GC_MARK_GRAY_MS,
- JS_TELEMETRY_GC_SLICE_MS,
- JS_TELEMETRY_GC_SLOW_PHASE,
- JS_TELEMETRY_GC_MMU_50,
- JS_TELEMETRY_GC_RESET,
- JS_TELEMETRY_GC_RESET_REASON,
- JS_TELEMETRY_GC_INCREMENTAL_DISABLED,
- JS_TELEMETRY_GC_NON_INCREMENTAL,
- JS_TELEMETRY_GC_NON_INCREMENTAL_REASON,
- JS_TELEMETRY_GC_SCC_SWEEP_TOTAL_MS,
- JS_TELEMETRY_GC_SCC_SWEEP_MAX_PAUSE_MS,
- JS_TELEMETRY_GC_MINOR_REASON,
- JS_TELEMETRY_GC_MINOR_REASON_LONG,
- JS_TELEMETRY_GC_MINOR_US,
- JS_TELEMETRY_GC_NURSERY_BYTES,
- JS_TELEMETRY_GC_PRETENURE_COUNT,
- JS_TELEMETRY_DEPRECATED_LANGUAGE_EXTENSIONS_IN_CONTENT,
- JS_TELEMETRY_DEPRECATED_LANGUAGE_EXTENSIONS_IN_ADDONS,
- JS_TELEMETRY_ADDON_EXCEPTIONS,
- JS_TELEMETRY_AOT_USAGE,
- JS_TELEMETRY_END
- };
- typedef void
- (*JSAccumulateTelemetryDataCallback)(int id, uint32_t sample, const char* key);
- extern JS_FRIEND_API(void)
- JS_SetAccumulateTelemetryCallback(JSContext* cx, JSAccumulateTelemetryDataCallback callback);
- extern JS_FRIEND_API(bool)
- JS_GetIsSecureContext(JSCompartment* compartment);
- extern JS_FRIEND_API(JSPrincipals*)
- JS_GetCompartmentPrincipals(JSCompartment* compartment);
- extern JS_FRIEND_API(void)
- JS_SetCompartmentPrincipals(JSCompartment* compartment, JSPrincipals* principals);
- extern JS_FRIEND_API(JSPrincipals*)
- JS_GetScriptPrincipals(JSScript* script);
- extern JS_FRIEND_API(bool)
- JS_ScriptHasMutedErrors(JSScript* script);
- extern JS_FRIEND_API(JSObject*)
- JS_CloneObject(JSContext* cx, JS::HandleObject obj, JS::HandleObject proto);
- /**
- * Copy the own properties of src to dst in a fast way. src and dst must both
- * be native and must be in the compartment of cx. They must have the same
- * class, the same parent, and the same prototype. Class reserved slots will
- * NOT be copied.
- *
- * dst must not have any properties on it before this function is called.
- *
- * src must have been allocated via JS_NewObjectWithoutMetadata so that we can
- * be sure it has no metadata that needs copying to dst. This also means that
- * dst needs to have the compartment global as its parent. This function will
- * preserve the existing metadata on dst, if any.
- */
- extern JS_FRIEND_API(bool)
- JS_InitializePropertiesFromCompatibleNativeObject(JSContext* cx,
- JS::HandleObject dst,
- JS::HandleObject src);
- extern JS_FRIEND_API(JSString*)
- JS_BasicObjectToString(JSContext* cx, JS::HandleObject obj);
- namespace js {
- JS_FRIEND_API(bool)
- GetBuiltinClass(JSContext* cx, JS::HandleObject obj, ESClass* cls);
- JS_FRIEND_API(const char*)
- ObjectClassName(JSContext* cx, JS::HandleObject obj);
- JS_FRIEND_API(void)
- ReportOverRecursed(JSContext* maybecx);
- JS_FRIEND_API(bool)
- AddRawValueRoot(JSContext* cx, JS::Value* vp, const char* name);
- JS_FRIEND_API(void)
- RemoveRawValueRoot(JSContext* cx, JS::Value* vp);
- JS_FRIEND_API(JSAtom*)
- GetPropertyNameFromPC(JSScript* script, jsbytecode* pc);
- #ifdef JS_DEBUG
- /*
- * Routines to print out values during debugging. These are FRIEND_API to help
- * the debugger find them and to support temporarily hacking js::Dump* calls
- * into other code. Note that there are overloads that do not require the FILE*
- * parameter, which will default to stderr.
- */
- extern JS_FRIEND_API(void)
- DumpString(JSString* str, FILE* fp);
- extern JS_FRIEND_API(void)
- DumpAtom(JSAtom* atom, FILE* fp);
- extern JS_FRIEND_API(void)
- DumpObject(JSObject* obj, FILE* fp);
- extern JS_FRIEND_API(void)
- DumpChars(const char16_t* s, size_t n, FILE* fp);
- extern JS_FRIEND_API(void)
- DumpValue(const JS::Value& val, FILE* fp);
- extern JS_FRIEND_API(void)
- DumpId(jsid id, FILE* fp);
- extern JS_FRIEND_API(void)
- DumpInterpreterFrame(JSContext* cx, FILE* fp, InterpreterFrame* start = nullptr);
- extern JS_FRIEND_API(bool)
- DumpPC(JSContext* cx, FILE* fp);
- extern JS_FRIEND_API(bool)
- DumpScript(JSContext* cx, JSScript* scriptArg, FILE* fp);
- // Versions for use directly in a debugger (default parameters are not handled
- // well in gdb; built-in handles like stderr are not handled well in lldb.)
- extern JS_FRIEND_API(void) DumpString(JSString* str);
- extern JS_FRIEND_API(void) DumpAtom(JSAtom* atom);
- extern JS_FRIEND_API(void) DumpObject(JSObject* obj);
- extern JS_FRIEND_API(void) DumpChars(const char16_t* s, size_t n);
- extern JS_FRIEND_API(void) DumpValue(const JS::Value& val);
- extern JS_FRIEND_API(void) DumpId(jsid id);
- extern JS_FRIEND_API(void) DumpInterpreterFrame(JSContext* cx, InterpreterFrame* start = nullptr);
- extern JS_FRIEND_API(bool) DumpPC(JSContext* cx);
- extern JS_FRIEND_API(bool) DumpScript(JSContext* cx, JSScript* scriptArg);
- #endif
- extern JS_FRIEND_API(void)
- DumpBacktrace(JSContext* cx, FILE* fp);
- extern JS_FRIEND_API(void)
- DumpBacktrace(JSContext* cx);
- } // namespace js
- namespace JS {
- /** Exposed for DumpJSStack */
- extern JS_FRIEND_API(char*)
- FormatStackDump(JSContext* cx, char* buf, bool showArgs, bool showLocals, bool showThisProps);
- /**
- * Set all of the uninitialized lexicals on an object to undefined. Return
- * true if any lexicals were initialized and false otherwise.
- * */
- extern JS_FRIEND_API(bool)
- ForceLexicalInitialization(JSContext *cx, HandleObject obj);
- } // namespace JS
- /**
- * Copies all own properties from |obj| to |target|. |obj| must be a "native"
- * object (that is to say, normal-ish - not an Array or a Proxy).
- *
- * This function immediately enters a compartment, and does not impose any
- * restrictions on the compartment of |cx|.
- */
- extern JS_FRIEND_API(bool)
- JS_CopyPropertiesFrom(JSContext* cx, JS::HandleObject target, JS::HandleObject obj);
- /*
- * Single-property version of the above. This function asserts that an |own|
- * property of the given name exists on |obj|.
- *
- * On entry, |cx| must be same-compartment with |obj|.
- *
- * The copyBehavior argument controls what happens with
- * non-configurable properties.
- */
- typedef enum {
- MakeNonConfigurableIntoConfigurable,
- CopyNonConfigurableAsIs
- } PropertyCopyBehavior;
- extern JS_FRIEND_API(bool)
- JS_CopyPropertyFrom(JSContext* cx, JS::HandleId id, JS::HandleObject target,
- JS::HandleObject obj,
- PropertyCopyBehavior copyBehavior = CopyNonConfigurableAsIs);
- extern JS_FRIEND_API(bool)
- JS_WrapPropertyDescriptor(JSContext* cx, JS::MutableHandle<JS::PropertyDescriptor> desc);
- struct JSFunctionSpecWithHelp {
- const char* name;
- JSNative call;
- uint16_t nargs;
- uint16_t flags;
- const JSJitInfo* jitInfo;
- const char* usage;
- const char* help;
- };
- #define JS_FN_HELP(name,call,nargs,flags,usage,help) \
- {name, call, nargs, (flags) | JSPROP_ENUMERATE | JSFUN_STUB_GSOPS, nullptr, usage, help}
- #define JS_INLINABLE_FN_HELP(name,call,nargs,flags,native,usage,help) \
- {name, call, nargs, (flags) | JSPROP_ENUMERATE | JSFUN_STUB_GSOPS, &js::jit::JitInfo_##native,\
- usage, help}
- #define JS_FS_HELP_END \
- {nullptr, nullptr, 0, 0, nullptr, nullptr}
- extern JS_FRIEND_API(bool)
- JS_DefineFunctionsWithHelp(JSContext* cx, JS::HandleObject obj, const JSFunctionSpecWithHelp* fs);
- namespace js {
- extern JS_FRIEND_DATA(const js::ClassOps) ProxyClassOps;
- extern JS_FRIEND_DATA(const js::ClassExtension) ProxyClassExtension;
- extern JS_FRIEND_DATA(const js::ObjectOps) ProxyObjectOps;
- /*
- * Helper Macros for creating JSClasses that function as proxies.
- *
- * NB: The macro invocation must be surrounded by braces, so as to
- * allow for potential JSClass extensions.
- */
- #define PROXY_MAKE_EXT(objectMoved) \
- { \
- js::proxy_WeakmapKeyDelegate, \
- objectMoved \
- }
- #define PROXY_CLASS_WITH_EXT(name, flags, extPtr) \
- { \
- name, \
- js::Class::NON_NATIVE | \
- JSCLASS_IS_PROXY | \
- JSCLASS_DELAY_METADATA_BUILDER | \
- flags, \
- &js::ProxyClassOps, \
- JS_NULL_CLASS_SPEC, \
- extPtr, \
- &js::ProxyObjectOps \
- }
- #define PROXY_CLASS_DEF(name, flags) \
- PROXY_CLASS_WITH_EXT(name, flags, &js::ProxyClassExtension)
- /*
- * Proxy stubs, similar to JS_*Stub, for embedder proxy class definitions.
- *
- * NB: Should not be called directly.
- */
- extern JS_FRIEND_API(bool)
- proxy_LookupProperty(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::MutableHandleObject objp,
- JS::MutableHandle<Shape*> propp);
- extern JS_FRIEND_API(bool)
- proxy_DefineProperty(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
- JS::Handle<JS::PropertyDescriptor> desc,
- JS::ObjectOpResult& result);
- extern JS_FRIEND_API(bool)
- proxy_HasProperty(JSContext* cx, JS::HandleObject obj, JS::HandleId id, bool* foundp);
- extern JS_FRIEND_API(bool)
- proxy_GetProperty(JSContext* cx, JS::HandleObject obj, JS::HandleValue receiver, JS::HandleId id,
- JS::MutableHandleValue vp);
- extern JS_FRIEND_API(bool)
- proxy_SetProperty(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue bp,
- JS::HandleValue receiver, JS::ObjectOpResult& result);
- extern JS_FRIEND_API(bool)
- proxy_GetOwnPropertyDescriptor(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
- JS::MutableHandle<JS::PropertyDescriptor> desc);
- extern JS_FRIEND_API(bool)
- proxy_DeleteProperty(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
- JS::ObjectOpResult& result);
- extern JS_FRIEND_API(void)
- proxy_Trace(JSTracer* trc, JSObject* obj);
- extern JS_FRIEND_API(JSObject*)
- proxy_WeakmapKeyDelegate(JSObject* obj);
- extern JS_FRIEND_API(bool)
- proxy_Convert(JSContext* cx, JS::HandleObject proxy, JSType hint, JS::MutableHandleValue vp);
- extern JS_FRIEND_API(void)
- proxy_Finalize(FreeOp* fop, JSObject* obj);
- extern JS_FRIEND_API(void)
- proxy_ObjectMoved(JSObject* obj, const JSObject* old);
- extern JS_FRIEND_API(bool)
- proxy_HasInstance(JSContext* cx, JS::HandleObject proxy, JS::MutableHandleValue v, bool* bp);
- extern JS_FRIEND_API(bool)
- proxy_Call(JSContext* cx, unsigned argc, JS::Value* vp);
- extern JS_FRIEND_API(bool)
- proxy_Construct(JSContext* cx, unsigned argc, JS::Value* vp);
- extern JS_FRIEND_API(JSObject*)
- proxy_innerObject(JSObject* obj);
- extern JS_FRIEND_API(bool)
- proxy_Watch(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleObject callable);
- extern JS_FRIEND_API(bool)
- proxy_Unwatch(JSContext* cx, JS::HandleObject obj, JS::HandleId id);
- extern JS_FRIEND_API(bool)
- proxy_GetElements(JSContext* cx, JS::HandleObject proxy, uint32_t begin, uint32_t end,
- ElementAdder* adder);
- extern JS_FRIEND_API(JSString*)
- proxy_FunToString(JSContext* cx, JS::HandleObject proxy, unsigned indent);
- /**
- * A class of objects that return source code on demand.
- *
- * When code is compiled with setSourceIsLazy(true), SpiderMonkey doesn't
- * retain the source code (and doesn't do lazy bytecode generation). If we ever
- * need the source code, say, in response to a call to Function.prototype.
- * toSource or Debugger.Source.prototype.text, then we call the 'load' member
- * function of the instance of this class that has hopefully been registered
- * with the runtime, passing the code's URL, and hope that it will be able to
- * find the source.
- */
- class SourceHook {
- public:
- virtual ~SourceHook() { }
- /**
- * Set |*src| and |*length| to refer to the source code for |filename|.
- * On success, the caller owns the buffer to which |*src| points, and
- * should use JS_free to free it.
- */
- virtual bool load(JSContext* cx, const char* filename, char16_t** src, size_t* length) = 0;
- };
- /**
- * Have |cx| use |hook| to retrieve lazily-retrieved source code. See the
- * comments for SourceHook. The context takes ownership of the hook, and
- * will delete it when the context itself is deleted, or when a new hook is
- * set.
- */
- extern JS_FRIEND_API(void)
- SetSourceHook(JSContext* cx, mozilla::UniquePtr<SourceHook> hook);
- /** Remove |cx|'s source hook, and return it. The caller now owns the hook. */
- extern JS_FRIEND_API(mozilla::UniquePtr<SourceHook>)
- ForgetSourceHook(JSContext* cx);
- extern JS_FRIEND_API(JS::Zone*)
- GetCompartmentZone(JSCompartment* comp);
- typedef bool
- (* PreserveWrapperCallback)(JSContext* cx, JSObject* obj);
- typedef enum {
- CollectNurseryBeforeDump,
- IgnoreNurseryObjects
- } DumpHeapNurseryBehaviour;
- /**
- * Dump the complete object graph of heap-allocated things.
- * fp is the file for the dump output.
- */
- extern JS_FRIEND_API(void)
- DumpHeap(JSContext* cx, FILE* fp, DumpHeapNurseryBehaviour nurseryBehaviour);
- #ifdef JS_OLD_GETTER_SETTER_METHODS
- JS_FRIEND_API(bool) obj_defineGetter(JSContext* cx, unsigned argc, JS::Value* vp);
- JS_FRIEND_API(bool) obj_defineSetter(JSContext* cx, unsigned argc, JS::Value* vp);
- #endif
- extern JS_FRIEND_API(bool)
- IsSystemCompartment(JSCompartment* comp);
- extern JS_FRIEND_API(bool)
- IsSystemZone(JS::Zone* zone);
- extern JS_FRIEND_API(bool)
- IsAtomsCompartment(JSCompartment* comp);
- extern JS_FRIEND_API(bool)
- IsAtomsZone(JS::Zone* zone);
- struct WeakMapTracer
- {
- JSContext* context;
- explicit WeakMapTracer(JSContext* cx) : context(cx) {}
- // Weak map tracer callback, called once for every binding of every
- // weak map that was live at the time of the last garbage collection.
- //
- // m will be nullptr if the weak map is not contained in a JS Object.
- //
- // The callback should not GC (and will assert in a debug build if it does so.)
- virtual void trace(JSObject* m, JS::GCCellPtr key, JS::GCCellPtr value) = 0;
- };
- extern JS_FRIEND_API(void)
- TraceWeakMaps(WeakMapTracer* trc);
- extern JS_FRIEND_API(bool)
- AreGCGrayBitsValid(JSContext* cx);
- extern JS_FRIEND_API(bool)
- ZoneGlobalsAreAllGray(JS::Zone* zone);
- typedef void
- (*GCThingCallback)(void* closure, JS::GCCellPtr thing);
- extern JS_FRIEND_API(void)
- VisitGrayWrapperTargets(JS::Zone* zone, GCThingCallback callback, void* closure);
- extern JS_FRIEND_API(JSObject*)
- GetWeakmapKeyDelegate(JSObject* key);
- /**
- * Invoke cellCallback on every gray JSObject in the given zone.
- */
- extern JS_FRIEND_API(void)
- IterateGrayObjects(JS::Zone* zone, GCThingCallback cellCallback, void* data);
- /**
- * Invoke cellCallback on every gray JSObject in the given zone while cycle
- * collection is in progress.
- */
- extern JS_FRIEND_API(void)
- IterateGrayObjectsUnderCC(JS::Zone* zone, GCThingCallback cellCallback, void* data);
- #ifdef JS_HAS_CTYPES
- extern JS_FRIEND_API(size_t)
- SizeOfDataIfCDataObject(mozilla::MallocSizeOf mallocSizeOf, JSObject* obj);
- #endif
- extern JS_FRIEND_API(JSCompartment*)
- GetAnyCompartmentInZone(JS::Zone* zone);
- /*
- * Shadow declarations of JS internal structures, for access by inline access
- * functions below. Do not use these structures in any other way. When adding
- * new fields for access by inline methods, make sure to add static asserts to
- * the original header file to ensure that offsets are consistent.
- */
- namespace shadow {
- struct ObjectGroup {
- const Class* clasp;
- JSObject* proto;
- JSCompartment* compartment;
- };
- struct BaseShape {
- const js::Class* clasp_;
- JSObject* parent;
- };
- class Shape {
- public:
- shadow::BaseShape* base;
- jsid _1;
- uint32_t slotInfo;
- static const uint32_t FIXED_SLOTS_SHIFT = 27;
- };
- /**
- * This layout is shared by all native objects. For non-native objects, the
- * group may always be accessed safely, and other members may be as well,
- * depending on the object's specific layout.
- */
- struct Object {
- shadow::ObjectGroup* group;
- shadow::Shape* shape;
- JS::Value* slots;
- void* _1;
- size_t numFixedSlots() const { return shape->slotInfo >> Shape::FIXED_SLOTS_SHIFT; }
- JS::Value* fixedSlots() const {
- return (JS::Value*)(uintptr_t(this) + sizeof(shadow::Object));
- }
- JS::Value& slotRef(size_t slot) const {
- size_t nfixed = numFixedSlots();
- if (slot < nfixed)
- return fixedSlots()[slot];
- return slots[slot - nfixed];
- }
- };
- struct Function {
- Object base;
- uint16_t nargs;
- uint16_t flags;
- /* Used only for natives */
- JSNative native;
- const JSJitInfo* jitinfo;
- void* _1;
- };
- struct String
- {
- static const uint32_t INLINE_CHARS_BIT = JS_BIT(2);
- static const uint32_t LATIN1_CHARS_BIT = JS_BIT(6);
- static const uint32_t ROPE_FLAGS = 0;
- static const uint32_t TYPE_FLAGS_MASK = JS_BIT(6) - 1;
- uint32_t flags;
- uint32_t length;
- union {
- const JS::Latin1Char* nonInlineCharsLatin1;
- const char16_t* nonInlineCharsTwoByte;
- JS::Latin1Char inlineStorageLatin1[1];
- char16_t inlineStorageTwoByte[1];
- };
- };
- } /* namespace shadow */
- // This is equal to |&JSObject::class_|. Use it in places where you don't want
- // to #include jsobj.h.
- extern JS_FRIEND_DATA(const js::Class* const) ObjectClassPtr;
- inline const js::Class*
- GetObjectClass(const JSObject* obj)
- {
- return reinterpret_cast<const shadow::Object*>(obj)->group->clasp;
- }
- inline const JSClass*
- GetObjectJSClass(JSObject* obj)
- {
- return js::Jsvalify(GetObjectClass(obj));
- }
- JS_FRIEND_API(const Class*)
- ProtoKeyToClass(JSProtoKey key);
- // Returns the key for the class inherited by a given standard class (that
- // is to say, the prototype of this standard class's prototype).
- //
- // You must be sure that this corresponds to a standard class with a cached
- // JSProtoKey before calling this function. In general |key| will match the
- // cached proto key, except in cases where multiple JSProtoKeys share a
- // JSClass.
- inline JSProtoKey
- InheritanceProtoKeyForStandardClass(JSProtoKey key)
- {
- // [Object] has nothing to inherit from.
- if (key == JSProto_Object)
- return JSProto_Null;
- // If we're ClassSpec defined return the proto key from that
- if (ProtoKeyToClass(key)->specDefined())
- return ProtoKeyToClass(key)->specInheritanceProtoKey();
- // Otherwise, we inherit [Object].
- return JSProto_Object;
- }
- JS_FRIEND_API(bool)
- IsFunctionObject(JSObject* obj);
- static MOZ_ALWAYS_INLINE JSCompartment*
- GetObjectCompartment(JSObject* obj)
- {
- return reinterpret_cast<shadow::Object*>(obj)->group->compartment;
- }
- JS_FRIEND_API(JSObject*)
- GetGlobalForObjectCrossCompartment(JSObject* obj);
- JS_FRIEND_API(JSObject*)
- GetPrototypeNoProxy(JSObject* obj);
- JS_FRIEND_API(void)
- AssertSameCompartment(JSContext* cx, JSObject* obj);
- #ifdef JS_DEBUG
- JS_FRIEND_API(void)
- AssertSameCompartment(JSObject* objA, JSObject* objB);
- #else
- inline void AssertSameCompartment(JSObject* objA, JSObject* objB) {}
- #endif
- JS_FRIEND_API(void)
- NotifyAnimationActivity(JSObject* obj);
- /**
- * Return the outermost enclosing function (script) of the scripted caller.
- * This function returns nullptr in several cases:
- * - no script is running on the context
- * - the caller is in global or eval code
- * In particular, this function will "stop" its outermost search at eval() and
- * thus it will really return the outermost enclosing function *since the
- * innermost eval*.
- */
- JS_FRIEND_API(JSFunction*)
- GetOutermostEnclosingFunctionOfScriptedCaller(JSContext* cx);
- JS_FRIEND_API(JSFunction*)
- DefineFunctionWithReserved(JSContext* cx, JSObject* obj, const char* name, JSNative call,
- unsigned nargs, unsigned attrs);
- JS_FRIEND_API(JSFunction*)
- NewFunctionWithReserved(JSContext* cx, JSNative call, unsigned nargs, unsigned flags,
- const char* name);
- JS_FRIEND_API(JSFunction*)
- NewFunctionByIdWithReserved(JSContext* cx, JSNative native, unsigned nargs, unsigned flags,
- jsid id);
- JS_FRIEND_API(const JS::Value&)
- GetFunctionNativeReserved(JSObject* fun, size_t which);
- JS_FRIEND_API(void)
- SetFunctionNativeReserved(JSObject* fun, size_t which, const JS::Value& val);
- JS_FRIEND_API(bool)
- FunctionHasNativeReserved(JSObject* fun);
- JS_FRIEND_API(bool)
- GetObjectProto(JSContext* cx, JS::HandleObject obj, JS::MutableHandleObject proto);
- extern JS_FRIEND_API(JSObject*)
- GetStaticPrototype(JSObject* obj);
- JS_FRIEND_API(bool)
- GetOriginalEval(JSContext* cx, JS::HandleObject scope,
- JS::MutableHandleObject eval);
- inline void*
- GetObjectPrivate(JSObject* obj)
- {
- MOZ_ASSERT(GetObjectClass(obj)->flags & JSCLASS_HAS_PRIVATE);
- const shadow::Object* nobj = reinterpret_cast<const shadow::Object*>(obj);
- void** addr = reinterpret_cast<void**>(&nobj->fixedSlots()[nobj->numFixedSlots()]);
- return *addr;
- }
- inline const JS::Value&
- GetReservedSlot(JSObject* obj, size_t slot)
- {
- MOZ_ASSERT(slot < JSCLASS_RESERVED_SLOTS(GetObjectClass(obj)));
- return reinterpret_cast<const shadow::Object*>(obj)->slotRef(slot);
- }
- JS_FRIEND_API(void)
- SetReservedOrProxyPrivateSlotWithBarrier(JSObject* obj, size_t slot, const JS::Value& value);
- inline void
- SetReservedSlot(JSObject* obj, size_t slot, const JS::Value& value)
- {
- MOZ_ASSERT(slot < JSCLASS_RESERVED_SLOTS(GetObjectClass(obj)));
- shadow::Object* sobj = reinterpret_cast<shadow::Object*>(obj);
- if (sobj->slotRef(slot).isMarkable() || value.isMarkable())
- SetReservedOrProxyPrivateSlotWithBarrier(obj, slot, value);
- else
- sobj->slotRef(slot) = value;
- }
- JS_FRIEND_API(uint32_t)
- GetObjectSlotSpan(JSObject* obj);
- inline const JS::Value&
- GetObjectSlot(JSObject* obj, size_t slot)
- {
- MOZ_ASSERT(slot < GetObjectSlotSpan(obj));
- return reinterpret_cast<const shadow::Object*>(obj)->slotRef(slot);
- }
- MOZ_ALWAYS_INLINE size_t
- GetAtomLength(JSAtom* atom)
- {
- return reinterpret_cast<shadow::String*>(atom)->length;
- }
- static const uint32_t MaxStringLength = (1 << 28) - 1;
- MOZ_ALWAYS_INLINE size_t
- GetStringLength(JSString* s)
- {
- return reinterpret_cast<shadow::String*>(s)->length;
- }
- MOZ_ALWAYS_INLINE size_t
- GetFlatStringLength(JSFlatString* s)
- {
- return reinterpret_cast<shadow::String*>(s)->length;
- }
- MOZ_ALWAYS_INLINE size_t
- GetLinearStringLength(JSLinearString* s)
- {
- return reinterpret_cast<shadow::String*>(s)->length;
- }
- MOZ_ALWAYS_INLINE bool
- LinearStringHasLatin1Chars(JSLinearString* s)
- {
- return reinterpret_cast<shadow::String*>(s)->flags & shadow::String::LATIN1_CHARS_BIT;
- }
- MOZ_ALWAYS_INLINE bool
- AtomHasLatin1Chars(JSAtom* atom)
- {
- return reinterpret_cast<shadow::String*>(atom)->flags & shadow::String::LATIN1_CHARS_BIT;
- }
- MOZ_ALWAYS_INLINE bool
- StringHasLatin1Chars(JSString* s)
- {
- return reinterpret_cast<shadow::String*>(s)->flags & shadow::String::LATIN1_CHARS_BIT;
- }
- MOZ_ALWAYS_INLINE const JS::Latin1Char*
- GetLatin1LinearStringChars(const JS::AutoCheckCannotGC& nogc, JSLinearString* linear)
- {
- MOZ_ASSERT(LinearStringHasLatin1Chars(linear));
- using shadow::String;
- String* s = reinterpret_cast<String*>(linear);
- if (s->flags & String::INLINE_CHARS_BIT)
- return s->inlineStorageLatin1;
- return s->nonInlineCharsLatin1;
- }
- MOZ_ALWAYS_INLINE const char16_t*
- GetTwoByteLinearStringChars(const JS::AutoCheckCannotGC& nogc, JSLinearString* linear)
- {
- MOZ_ASSERT(!LinearStringHasLatin1Chars(linear));
- using shadow::String;
- String* s = reinterpret_cast<String*>(linear);
- if (s->flags & String::INLINE_CHARS_BIT)
- return s->inlineStorageTwoByte;
- return s->nonInlineCharsTwoByte;
- }
- MOZ_ALWAYS_INLINE JSLinearString*
- AtomToLinearString(JSAtom* atom)
- {
- return reinterpret_cast<JSLinearString*>(atom);
- }
- MOZ_ALWAYS_INLINE JSFlatString*
- AtomToFlatString(JSAtom* atom)
- {
- return reinterpret_cast<JSFlatString*>(atom);
- }
- MOZ_ALWAYS_INLINE JSLinearString*
- FlatStringToLinearString(JSFlatString* s)
- {
- return reinterpret_cast<JSLinearString*>(s);
- }
- MOZ_ALWAYS_INLINE const JS::Latin1Char*
- GetLatin1AtomChars(const JS::AutoCheckCannotGC& nogc, JSAtom* atom)
- {
- return GetLatin1LinearStringChars(nogc, AtomToLinearString(atom));
- }
- MOZ_ALWAYS_INLINE const char16_t*
- GetTwoByteAtomChars(const JS::AutoCheckCannotGC& nogc, JSAtom* atom)
- {
- return GetTwoByteLinearStringChars(nogc, AtomToLinearString(atom));
- }
- JS_FRIEND_API(JSLinearString*)
- StringToLinearStringSlow(JSContext* cx, JSString* str);
- MOZ_ALWAYS_INLINE JSLinearString*
- StringToLinearString(JSContext* cx, JSString* str)
- {
- using shadow::String;
- String* s = reinterpret_cast<String*>(str);
- if (MOZ_UNLIKELY((s->flags & String::TYPE_FLAGS_MASK) == String::ROPE_FLAGS))
- return StringToLinearStringSlow(cx, str);
- return reinterpret_cast<JSLinearString*>(str);
- }
- template<typename CharType>
- MOZ_ALWAYS_INLINE void
- CopyLinearStringChars(CharType* dest, JSLinearString* s, size_t len, size_t start = 0);
- MOZ_ALWAYS_INLINE void
- CopyLinearStringChars(char16_t* dest, JSLinearString* s, size_t len, size_t start = 0)
- {
- MOZ_ASSERT(start + len <= GetLinearStringLength(s));
- JS::AutoCheckCannotGC nogc;
- if (LinearStringHasLatin1Chars(s)) {
- const JS::Latin1Char* src = GetLatin1LinearStringChars(nogc, s);
- for (size_t i = 0; i < len; i++)
- dest[i] = src[start + i];
- } else {
- const char16_t* src = GetTwoByteLinearStringChars(nogc, s);
- mozilla::PodCopy(dest, src + start, len);
- }
- }
- MOZ_ALWAYS_INLINE void
- CopyLinearStringChars(char* dest, JSLinearString* s, size_t len, size_t start = 0)
- {
- MOZ_ASSERT(start + len <= GetLinearStringLength(s));
- JS::AutoCheckCannotGC nogc;
- if (LinearStringHasLatin1Chars(s)) {
- const JS::Latin1Char* src = GetLatin1LinearStringChars(nogc, s);
- for (size_t i = 0; i < len; i++)
- dest[i] = char(src[start + i]);
- } else {
- const char16_t* src = GetTwoByteLinearStringChars(nogc, s);
- for (size_t i = 0; i < len; i++)
- dest[i] = char(src[start + i]);
- }
- }
- template<typename CharType>
- inline bool
- CopyStringChars(JSContext* cx, CharType* dest, JSString* s, size_t len, size_t start = 0)
- {
- JSLinearString* linear = StringToLinearString(cx, s);
- if (!linear)
- return false;
- CopyLinearStringChars(dest, linear, len, start);
- return true;
- }
- inline void
- CopyFlatStringChars(char16_t* dest, JSFlatString* s, size_t len)
- {
- CopyLinearStringChars(dest, FlatStringToLinearString(s), len);
- }
- /**
- * Add some or all property keys of obj to the id vector *props.
- *
- * The flags parameter controls which property keys are added. Pass a
- * combination of the following bits:
- *
- * JSITER_OWNONLY - Don't also search the prototype chain; only consider
- * obj's own properties.
- *
- * JSITER_HIDDEN - Include nonenumerable properties.
- *
- * JSITER_SYMBOLS - Include property keys that are symbols. The default
- * behavior is to filter out symbols.
- *
- * JSITER_SYMBOLSONLY - Exclude non-symbol property keys.
- *
- * This is the closest C++ API we have to `Reflect.ownKeys(obj)`, or
- * equivalently, the ES6 [[OwnPropertyKeys]] internal method. Pass
- * `JSITER_OWNONLY | JSITER_HIDDEN | JSITER_SYMBOLS` as flags to get
- * results that match the output of Reflect.ownKeys.
- */
- JS_FRIEND_API(bool)
- GetPropertyKeys(JSContext* cx, JS::HandleObject obj, unsigned flags, JS::AutoIdVector* props);
- JS_FRIEND_API(bool)
- AppendUnique(JSContext* cx, JS::AutoIdVector& base, JS::AutoIdVector& others);
- JS_FRIEND_API(bool)
- StringIsArrayIndex(JSLinearString* str, uint32_t* indexp);
- JS_FRIEND_API(void)
- SetPreserveWrapperCallback(JSContext* cx, PreserveWrapperCallback callback);
- JS_FRIEND_API(bool)
- IsObjectInContextCompartment(JSObject* obj, const JSContext* cx);
- /*
- * NB: keep these in sync with the copy in builtin/SelfHostingDefines.h.
- * The first three are omitted because they shouldn't be used in new code.
- */
- #define JSITER_ENUMERATE 0x1 /* for-in compatible hidden default iterator */
- #define JSITER_FOREACH 0x2 /* get obj[key] for each property */
- #define JSITER_KEYVALUE 0x4 /* obsolete destructuring for-in wants [key, value] */
- #define JSITER_OWNONLY 0x8 /* iterate over obj's own properties only */
- #define JSITER_HIDDEN 0x10 /* also enumerate non-enumerable properties */
- #define JSITER_SYMBOLS 0x20 /* also include symbol property keys */
- #define JSITER_SYMBOLSONLY 0x40 /* exclude string property keys */
- JS_FRIEND_API(bool)
- RunningWithTrustedPrincipals(JSContext* cx);
- inline uintptr_t
- GetNativeStackLimit(JSContext* cx, StackKind kind, int extraAllowance = 0)
- {
- uintptr_t limit = ContextFriendFields::get(cx)->nativeStackLimit[kind];
- #if JS_STACK_GROWTH_DIRECTION > 0
- limit += extraAllowance;
- #else
- limit -= extraAllowance;
- #endif
- return limit;
- }
- inline uintptr_t
- GetNativeStackLimit(JSContext* cx, int extraAllowance = 0)
- {
- StackKind kind = RunningWithTrustedPrincipals(cx) ? StackForTrustedScript
- : StackForUntrustedScript;
- return GetNativeStackLimit(cx, kind, extraAllowance);
- }
- /*
- * These macros report a stack overflow and run |onerror| if we are close to
- * using up the C stack. The JS_CHECK_CHROME_RECURSION variant gives us a
- * little extra space so that we can ensure that crucial code is able to run.
- * JS_CHECK_RECURSION_CONSERVATIVE allows less space than any other check,
- * including a safety buffer (as in, it uses the untrusted limit and subtracts
- * a little more from it).
- */
- #define JS_CHECK_RECURSION_LIMIT(cx, limit, onerror) \
- JS_BEGIN_MACRO \
- int stackDummy_; \
- if (!JS_CHECK_STACK_SIZE(limit, &stackDummy_)) { \
- js::ReportOverRecursed(cx); \
- onerror; \
- } \
- JS_END_MACRO
- #define JS_CHECK_RECURSION(cx, onerror) \
- JS_CHECK_RECURSION_LIMIT(cx, js::GetNativeStackLimit(cx), onerror)
- #define JS_CHECK_RECURSION_LIMIT_DONT_REPORT(cx, limit, onerror) \
- JS_BEGIN_MACRO \
- int stackDummy_; \
- if (!JS_CHECK_STACK_SIZE(limit, &stackDummy_)) { \
- onerror; \
- } \
- JS_END_MACRO
- #define JS_CHECK_RECURSION_DONT_REPORT(cx, onerror) \
- JS_CHECK_RECURSION_LIMIT_DONT_REPORT(cx, js::GetNativeStackLimit(cx), onerror)
- #define JS_CHECK_RECURSION_WITH_SP_DONT_REPORT(cx, sp, onerror) \
- JS_BEGIN_MACRO \
- if (!JS_CHECK_STACK_SIZE(js::GetNativeStackLimit(cx), sp)) { \
- onerror; \
- } \
- JS_END_MACRO
- #define JS_CHECK_RECURSION_WITH_SP(cx, sp, onerror) \
- JS_BEGIN_MACRO \
- if (!JS_CHECK_STACK_SIZE(js::GetNativeStackLimit(cx), sp)) { \
- js::ReportOverRecursed(cx); \
- onerror; \
- } \
- JS_END_MACRO
- #define JS_CHECK_SYSTEM_RECURSION(cx, onerror) \
- JS_CHECK_RECURSION_LIMIT(cx, js::GetNativeStackLimit(cx, js::StackForSystemCode), onerror)
- #define JS_CHECK_RECURSION_CONSERVATIVE(cx, onerror) \
- JS_CHECK_RECURSION_LIMIT(cx, \
- js::GetNativeStackLimit(cx, js::StackForUntrustedScript, -1024 * int(sizeof(size_t))), \
- onerror)
- #define JS_CHECK_RECURSION_CONSERVATIVE_DONT_REPORT(cx, onerror) \
- JS_CHECK_RECURSION_LIMIT_DONT_REPORT(cx, \
- js::GetNativeStackLimit(cx, js::StackForUntrustedScript, -1024 * int(sizeof(size_t))), \
- onerror)
- JS_FRIEND_API(void)
- StartPCCountProfiling(JSContext* cx);
- JS_FRIEND_API(void)
- StopPCCountProfiling(JSContext* cx);
- JS_FRIEND_API(void)
- PurgePCCounts(JSContext* cx);
- JS_FRIEND_API(size_t)
- GetPCCountScriptCount(JSContext* cx);
- JS_FRIEND_API(JSString*)
- GetPCCountScriptSummary(JSContext* cx, size_t script);
- JS_FRIEND_API(JSString*)
- GetPCCountScriptContents(JSContext* cx, size_t script);
- /**
- * Generate lcov trace file content for the current compartment, and allocate a
- * new buffer and return the content in it, the size of the newly allocated
- * content within the buffer would be set to the length out-param.
- *
- * In case of out-of-memory, this function returns nullptr and does not set any
- * value to the length out-param.
- */
- JS_FRIEND_API(char*)
- GetCodeCoverageSummary(JSContext* cx, size_t* length);
- typedef void
- (* ActivityCallback)(void* arg, bool active);
- /**
- * Sets a callback that is run whenever the runtime goes idle - the
- * last active request ceases - and begins activity - when it was
- * idle and a request begins.
- */
- JS_FRIEND_API(void)
- SetActivityCallback(JSContext* cx, ActivityCallback cb, void* arg);
- typedef bool
- (* DOMInstanceClassHasProtoAtDepth)(const Class* instanceClass,
- uint32_t protoID, uint32_t depth);
- struct JSDOMCallbacks {
- DOMInstanceClassHasProtoAtDepth instanceClassMatchesProto;
- };
- typedef struct JSDOMCallbacks DOMCallbacks;
- extern JS_FRIEND_API(void)
- SetDOMCallbacks(JSContext* cx, const DOMCallbacks* callbacks);
- extern JS_FRIEND_API(const DOMCallbacks*)
- GetDOMCallbacks(JSContext* cx);
- extern JS_FRIEND_API(JSObject*)
- GetTestingFunctions(JSContext* cx);
- /**
- * Helper to convert FreeOp to JSFreeOp when the definition of FreeOp is not
- * available and the compiler does not know that FreeOp inherits from
- * JSFreeOp.
- */
- inline JSFreeOp*
- CastToJSFreeOp(FreeOp* fop)
- {
- return reinterpret_cast<JSFreeOp*>(fop);
- }
- /* Implemented in jsexn.cpp. */
- /**
- * Get an error type name from a JSExnType constant.
- * Returns nullptr for invalid arguments and JSEXN_INTERNALERR
- */
- extern JS_FRIEND_API(JSFlatString*)
- GetErrorTypeName(JSContext* cx, int16_t exnType);
- #ifdef JS_DEBUG
- extern JS_FRIEND_API(unsigned)
- GetEnterCompartmentDepth(JSContext* cx);
- #endif
- class RegExpGuard;
- extern JS_FRIEND_API(bool)
- RegExpToSharedNonInline(JSContext* cx, JS::HandleObject regexp, RegExpGuard* shared);
- /* Implemented in jswrapper.cpp. */
- typedef enum NukeReferencesToWindow {
- NukeWindowReferences,
- DontNukeWindowReferences
- } NukeReferencesToWindow;
- /*
- * These filters are designed to be ephemeral stack classes, and thus don't
- * do any rooting or holding of their members.
- */
- struct CompartmentFilter {
- virtual bool match(JSCompartment* c) const = 0;
- };
- struct AllCompartments : public CompartmentFilter {
- virtual bool match(JSCompartment* c) const override { return true; }
- };
- struct ContentCompartmentsOnly : public CompartmentFilter {
- virtual bool match(JSCompartment* c) const override {
- return !IsSystemCompartment(c);
- }
- };
- struct ChromeCompartmentsOnly : public CompartmentFilter {
- virtual bool match(JSCompartment* c) const override {
- return IsSystemCompartment(c);
- }
- };
- struct SingleCompartment : public CompartmentFilter {
- JSCompartment* ours;
- explicit SingleCompartment(JSCompartment* c) : ours(c) {}
- virtual bool match(JSCompartment* c) const override { return c == ours; }
- };
- struct CompartmentsWithPrincipals : public CompartmentFilter {
- JSPrincipals* principals;
- explicit CompartmentsWithPrincipals(JSPrincipals* p) : principals(p) {}
- virtual bool match(JSCompartment* c) const override {
- return JS_GetCompartmentPrincipals(c) == principals;
- }
- };
- extern JS_FRIEND_API(bool)
- NukeCrossCompartmentWrappers(JSContext* cx,
- const CompartmentFilter& sourceFilter,
- const CompartmentFilter& targetFilter,
- NukeReferencesToWindow nukeReferencesToWindow);
- /* Specify information about DOMProxy proxies in the DOM, for use by ICs. */
- /*
- * The DOMProxyShadowsCheck function will be called to check if the property for
- * id should be gotten from the prototype, or if there is an own property that
- * shadows it.
- * * If ShadowsViaDirectExpando is returned, then the slot at
- * listBaseExpandoSlot contains an expando object which has the property in
- * question.
- * * If ShadowsViaIndirectExpando is returned, then the slot at
- * listBaseExpandoSlot contains a private pointer to an ExpandoAndGeneration
- * and the expando object in the ExpandoAndGeneration has the property in
- * question.
- * * If DoesntShadow is returned then the slot at listBaseExpandoSlot should
- * either be undefined or point to an expando object that would contain the
- * own property.
- * * If DoesntShadowUnique is returned then the slot at listBaseExpandoSlot
- * should contain a private pointer to a ExpandoAndGeneration, which contains
- * a JS::Value that should either be undefined or point to an expando object,
- * and a uint64 value. If that value changes then the IC for getting a
- * property will be invalidated.
- * * If Shadows is returned, that means the property is an own property of the
- * proxy but doesn't live on the expando object.
- */
- struct ExpandoAndGeneration {
- ExpandoAndGeneration()
- : expando(JS::UndefinedValue()),
- generation(0)
- {}
- void OwnerUnlinked()
- {
- ++generation;
- }
- static size_t offsetOfExpando()
- {
- return offsetof(ExpandoAndGeneration, expando);
- }
- static size_t offsetOfGeneration()
- {
- return offsetof(ExpandoAndGeneration, generation);
- }
- JS::Heap<JS::Value> expando;
- uint64_t generation;
- };
- typedef enum DOMProxyShadowsResult {
- ShadowCheckFailed,
- Shadows,
- DoesntShadow,
- DoesntShadowUnique,
- ShadowsViaDirectExpando,
- ShadowsViaIndirectExpando
- } DOMProxyShadowsResult;
- typedef DOMProxyShadowsResult
- (* DOMProxyShadowsCheck)(JSContext* cx, JS::HandleObject object, JS::HandleId id);
- JS_FRIEND_API(void)
- SetDOMProxyInformation(const void* domProxyHandlerFamily, uint32_t domProxyExpandoSlot,
- DOMProxyShadowsCheck domProxyShadowsCheck);
- const void* GetDOMProxyHandlerFamily();
- uint32_t GetDOMProxyExpandoSlot();
- DOMProxyShadowsCheck GetDOMProxyShadowsCheck();
- inline bool DOMProxyIsShadowing(DOMProxyShadowsResult result) {
- return result == Shadows ||
- result == ShadowsViaDirectExpando ||
- result == ShadowsViaIndirectExpando;
- }
- /* Implemented in jsdate.cpp. */
- /** Detect whether the internal date value is NaN. */
- extern JS_FRIEND_API(bool)
- DateIsValid(JSContext* cx, JS::HandleObject obj, bool* isValid);
- extern JS_FRIEND_API(bool)
- DateGetMsecSinceEpoch(JSContext* cx, JS::HandleObject obj, double* msecSinceEpoch);
- } /* namespace js */
- /* Implemented in jscntxt.cpp. */
- /**
- * Report an exception, which is currently realized as a printf-style format
- * string and its arguments.
- */
- typedef enum JSErrNum {
- #define MSG_DEF(name, count, exception, format) \
- name,
- #include "js.msg"
- #undef MSG_DEF
- JSErr_Limit
- } JSErrNum;
- namespace js {
- extern JS_FRIEND_API(const JSErrorFormatString*)
- GetErrorMessage(void* userRef, const unsigned errorNumber);
- // AutoStableStringChars is here so we can use it in ErrorReport. It
- // should get moved out of here if we can manage it. See bug 1040316.
- /**
- * This class provides safe access to a string's chars across a GC. Once
- * we allocate strings and chars in the nursery (bug 903519), this class
- * will have to make a copy of the string's chars if they are allocated
- * in the nursery, so it's best to avoid using this class unless you really
- * need it. It's usually more efficient to use the latin1Chars/twoByteChars
- * JSString methods and often the code can be rewritten so that only indexes
- * instead of char pointers are used in parts of the code that can GC.
- */
- class MOZ_STACK_CLASS AutoStableStringChars
- {
- /*
- * When copying string char, use this many bytes of inline storage. This is
- * chosen to allow the inline string types to be copied without allocating.
- * This is asserted in AutoStableStringChars::allocOwnChars.
- */
- static const size_t InlineCapacity = 24;
- /* Ensure the string is kept alive while we're using its chars. */
- JS::RootedString s_;
- union {
- const char16_t* twoByteChars_;
- const JS::Latin1Char* latin1Chars_;
- };
- mozilla::Maybe<Vector<uint8_t, InlineCapacity>> ownChars_;
- enum State { Uninitialized, Latin1, TwoByte };
- State state_;
- public:
- explicit AutoStableStringChars(JSContext* cx)
- : s_(cx), state_(Uninitialized)
- {}
- MOZ_MUST_USE
- bool init(JSContext* cx, JSString* s);
- /* Like init(), but Latin1 chars are inflated to TwoByte. */
- MOZ_MUST_USE
- bool initTwoByte(JSContext* cx, JSString* s);
- bool isLatin1() const { return state_ == Latin1; }
- bool isTwoByte() const { return state_ == TwoByte; }
- const char16_t* twoByteChars() const {
- MOZ_ASSERT(state_ == TwoByte);
- return twoByteChars_;
- }
- mozilla::Range<const JS::Latin1Char> latin1Range() const {
- MOZ_ASSERT(state_ == Latin1);
- return mozilla::Range<const JS::Latin1Char>(latin1Chars_,
- GetStringLength(s_));
- }
- mozilla::Range<const char16_t> twoByteRange() const {
- MOZ_ASSERT(state_ == TwoByte);
- return mozilla::Range<const char16_t>(twoByteChars_,
- GetStringLength(s_));
- }
- /* If we own the chars, transfer ownership to the caller. */
- bool maybeGiveOwnershipToCaller() {
- MOZ_ASSERT(state_ != Uninitialized);
- if (!ownChars_.isSome() || !ownChars_->extractRawBuffer())
- return false;
- state_ = Uninitialized;
- ownChars_.reset();
- return true;
- }
- private:
- AutoStableStringChars(const AutoStableStringChars& other) = delete;
- void operator=(const AutoStableStringChars& other) = delete;
- bool baseIsInline(JS::Handle<JSLinearString*> linearString);
- template <typename T> T* allocOwnChars(JSContext* cx, size_t count);
- bool copyLatin1Chars(JSContext* cx, JS::Handle<JSLinearString*> linearString);
- bool copyTwoByteChars(JSContext* cx, JS::Handle<JSLinearString*> linearString);
- bool copyAndInflateLatin1Chars(JSContext*, JS::Handle<JSLinearString*> linearString);
- };
- struct MOZ_STACK_CLASS JS_FRIEND_API(ErrorReport)
- {
- explicit ErrorReport(JSContext* cx);
- ~ErrorReport();
- enum SniffingBehavior {
- WithSideEffects,
- NoSideEffects
- };
- /**
- * Generate a JSErrorReport from the provided thrown value.
- *
- * If the value is a (possibly wrapped) Error object, the JSErrorReport will
- * be exactly initialized from the Error object's information, without
- * observable side effects. (The Error object's JSErrorReport is reused, if
- * it has one.)
- *
- * Otherwise various attempts are made to derive JSErrorReport information
- * from |exn| and from the current execution state. This process is
- * *definitely* inconsistent with any standard, and particulars of the
- * behavior implemented here generally shouldn't be relied upon.
- *
- * If the value of |sniffingBehavior| is |WithSideEffects|, some of these
- * attempts *may* invoke user-configurable behavior when |exn| is an object:
- * converting |exn| to a string, detecting and getting properties on |exn|,
- * accessing |exn|'s prototype chain, and others are possible. Users *must*
- * tolerate |ErrorReport::init| potentially having arbitrary effects. Any
- * exceptions thrown by these operations will be caught and silently
- * ignored, and "default" values will be substituted into the JSErrorReport.
- *
- * But if the value of |sniffingBehavior| is |NoSideEffects|, these attempts
- * *will not* invoke any observable side effects. The JSErrorReport will
- * simply contain fewer, less precise details.
- *
- * Unlike some functions involved in error handling, this function adheres
- * to the usual JSAPI return value error behavior.
- */
- bool init(JSContext* cx, JS::HandleValue exn,
- SniffingBehavior sniffingBehavior);
- JSErrorReport* report()
- {
- return reportp;
- }
- const JS::ConstUTF8CharsZ toStringResult()
- {
- return toStringResult_;
- }
- private:
- // More or less an equivalent of JS_ReportErrorNumber/js::ReportErrorNumberVA
- // but fills in an ErrorReport instead of reporting it. Uses varargs to
- // make it simpler to call js::ExpandErrorArgumentsVA.
- //
- // Returns false if we fail to actually populate the ErrorReport
- // for some reason (probably out of memory).
- bool populateUncaughtExceptionReportUTF8(JSContext* cx, ...);
- bool populateUncaughtExceptionReportUTF8VA(JSContext* cx, va_list ap);
- // Reports exceptions from add-on scopes to telementry.
- void ReportAddonExceptionToTelementry(JSContext* cx);
- // We may have a provided JSErrorReport, so need a way to represent that.
- JSErrorReport* reportp;
- // Or we may need to synthesize a JSErrorReport one of our own.
- JSErrorReport ownedReport;
- // And we have a string to maybe keep alive that has pointers into
- // it from ownedReport.
- JS::RootedString str;
- // And keep its chars alive too.
- AutoStableStringChars strChars;
- // And we need to root our exception value.
- JS::RootedObject exnObject;
- // And for our filename.
- JSAutoByteString filename;
- // We may have a result of error.toString().
- // FIXME: We should not call error.toString(), since it could have side
- // effect (see bug 633623).
- JS::ConstUTF8CharsZ toStringResult_;
- JSAutoByteString toStringResultBytesStorage;
- };
- /* Implemented in vm/StructuredClone.cpp. */
- extern JS_FRIEND_API(uint64_t)
- GetSCOffset(JSStructuredCloneWriter* writer);
- namespace Scalar {
- /**
- * Scalar types that can appear in typed arrays and typed objects. The enum
- * values must to be kept in sync with the JS_SCALARTYPEREPR_ constants, as
- * well as the TypedArrayObject::classes and TypedArrayObject::protoClasses
- * definitions.
- */
- enum Type {
- Int8 = 0,
- Uint8,
- Int16,
- Uint16,
- Int32,
- Uint32,
- Float32,
- Float64,
- /**
- * Special type that is a uint8_t, but assignments are clamped to [0, 256).
- * Treat the raw data type as a uint8_t.
- */
- Uint8Clamped,
- /**
- * Types that don't have their own TypedArray equivalent, for now.
- */
- MaxTypedArrayViewType,
- Int64,
- Float32x4,
- Int8x16,
- Int16x8,
- Int32x4
- };
- static inline size_t
- byteSize(Type atype)
- {
- switch (atype) {
- case Int8:
- case Uint8:
- case Uint8Clamped:
- return 1;
- case Int16:
- case Uint16:
- return 2;
- case Int32:
- case Uint32:
- case Float32:
- return 4;
- case Int64:
- case Float64:
- return 8;
- case Int8x16:
- case Int16x8:
- case Int32x4:
- case Float32x4:
- return 16;
- default:
- MOZ_CRASH("invalid scalar type");
- }
- }
- static inline bool
- isSignedIntType(Type atype) {
- switch (atype) {
- case Int8:
- case Int16:
- case Int32:
- case Int64:
- case Int8x16:
- case Int16x8:
- case Int32x4:
- return true;
- case Uint8:
- case Uint8Clamped:
- case Uint16:
- case Uint32:
- case Float32:
- case Float64:
- case Float32x4:
- return false;
- default:
- MOZ_CRASH("invalid scalar type");
- }
- }
- static inline bool
- isSimdType(Type atype) {
- switch (atype) {
- case Int8:
- case Uint8:
- case Uint8Clamped:
- case Int16:
- case Uint16:
- case Int32:
- case Uint32:
- case Int64:
- case Float32:
- case Float64:
- return false;
- case Int8x16:
- case Int16x8:
- case Int32x4:
- case Float32x4:
- return true;
- case MaxTypedArrayViewType:
- break;
- }
- MOZ_CRASH("invalid scalar type");
- }
- static inline size_t
- scalarByteSize(Type atype) {
- switch (atype) {
- case Int8x16:
- return 1;
- case Int16x8:
- return 2;
- case Int32x4:
- case Float32x4:
- return 4;
- case Int8:
- case Uint8:
- case Uint8Clamped:
- case Int16:
- case Uint16:
- case Int32:
- case Uint32:
- case Int64:
- case Float32:
- case Float64:
- case MaxTypedArrayViewType:
- break;
- }
- MOZ_CRASH("invalid simd type");
- }
- } /* namespace Scalar */
- } /* namespace js */
- /*
- * Create a new typed array with nelements elements.
- *
- * These functions (except the WithBuffer variants) fill in the array with zeros.
- */
- extern JS_FRIEND_API(JSObject*)
- JS_NewInt8Array(JSContext* cx, uint32_t nelements);
- extern JS_FRIEND_API(JSObject*)
- JS_NewUint8Array(JSContext* cx, uint32_t nelements);
- extern JS_FRIEND_API(JSObject*)
- JS_NewUint8ClampedArray(JSContext* cx, uint32_t nelements);
- extern JS_FRIEND_API(JSObject*)
- JS_NewInt16Array(JSContext* cx, uint32_t nelements);
- extern JS_FRIEND_API(JSObject*)
- JS_NewUint16Array(JSContext* cx, uint32_t nelements);
- extern JS_FRIEND_API(JSObject*)
- JS_NewInt32Array(JSContext* cx, uint32_t nelements);
- extern JS_FRIEND_API(JSObject*)
- JS_NewUint32Array(JSContext* cx, uint32_t nelements);
- extern JS_FRIEND_API(JSObject*)
- JS_NewFloat32Array(JSContext* cx, uint32_t nelements);
- extern JS_FRIEND_API(JSObject*)
- JS_NewFloat64Array(JSContext* cx, uint32_t nelements);
- /*
- * Create a new typed array and copy in values from the given object. The
- * object is used as if it were an array; that is, the new array (if
- * successfully created) will have length given by array.length, and its
- * elements will be those specified by array[0], array[1], and so on, after
- * conversion to the typed array element type.
- */
- extern JS_FRIEND_API(JSObject*)
- JS_NewInt8ArrayFromArray(JSContext* cx, JS::HandleObject array);
- extern JS_FRIEND_API(JSObject*)
- JS_NewUint8ArrayFromArray(JSContext* cx, JS::HandleObject array);
- extern JS_FRIEND_API(JSObject*)
- JS_NewUint8ClampedArrayFromArray(JSContext* cx, JS::HandleObject array);
- extern JS_FRIEND_API(JSObject*)
- JS_NewInt16ArrayFromArray(JSContext* cx, JS::HandleObject array);
- extern JS_FRIEND_API(JSObject*)
- JS_NewUint16ArrayFromArray(JSContext* cx, JS::HandleObject array);
- extern JS_FRIEND_API(JSObject*)
- JS_NewInt32ArrayFromArray(JSContext* cx, JS::HandleObject array);
- extern JS_FRIEND_API(JSObject*)
- JS_NewUint32ArrayFromArray(JSContext* cx, JS::HandleObject array);
- extern JS_FRIEND_API(JSObject*)
- JS_NewFloat32ArrayFromArray(JSContext* cx, JS::HandleObject array);
- extern JS_FRIEND_API(JSObject*)
- JS_NewFloat64ArrayFromArray(JSContext* cx, JS::HandleObject array);
- /*
- * Create a new typed array using the given ArrayBuffer or
- * SharedArrayBuffer for storage. The length value is optional; if -1
- * is passed, enough elements to use up the remainder of the byte
- * array is used as the default value.
- */
- extern JS_FRIEND_API(JSObject*)
- JS_NewInt8ArrayWithBuffer(JSContext* cx, JS::HandleObject arrayBuffer,
- uint32_t byteOffset, int32_t length);
- extern JS_FRIEND_API(JSObject*)
- JS_NewUint8ArrayWithBuffer(JSContext* cx, JS::HandleObject arrayBuffer,
- uint32_t byteOffset, int32_t length);
- extern JS_FRIEND_API(JSObject*)
- JS_NewUint8ClampedArrayWithBuffer(JSContext* cx, JS::HandleObject arrayBuffer,
- uint32_t byteOffset, int32_t length);
- extern JS_FRIEND_API(JSObject*)
- JS_NewInt16ArrayWithBuffer(JSContext* cx, JS::HandleObject arrayBuffer,
- uint32_t byteOffset, int32_t length);
- extern JS_FRIEND_API(JSObject*)
- JS_NewUint16ArrayWithBuffer(JSContext* cx, JS::HandleObject arrayBuffer,
- uint32_t byteOffset, int32_t length);
- extern JS_FRIEND_API(JSObject*)
- JS_NewInt32ArrayWithBuffer(JSContext* cx, JS::HandleObject arrayBuffer,
- uint32_t byteOffset, int32_t length);
- extern JS_FRIEND_API(JSObject*)
- JS_NewUint32ArrayWithBuffer(JSContext* cx, JS::HandleObject arrayBuffer,
- uint32_t byteOffset, int32_t length);
- extern JS_FRIEND_API(JSObject*)
- JS_NewFloat32ArrayWithBuffer(JSContext* cx, JS::HandleObject arrayBuffer,
- uint32_t byteOffset, int32_t length);
- extern JS_FRIEND_API(JSObject*)
- JS_NewFloat64ArrayWithBuffer(JSContext* cx, JS::HandleObject arrayBuffer,
- uint32_t byteOffset, int32_t length);
- /**
- * Create a new SharedArrayBuffer with the given byte length. This
- * may only be called if
- * JS::CompartmentCreationOptionsRef(cx).getSharedMemoryAndAtomicsEnabled() is
- * true.
- */
- extern JS_FRIEND_API(JSObject*)
- JS_NewSharedArrayBuffer(JSContext* cx, uint32_t nbytes);
- /**
- * Create a new ArrayBuffer with the given byte length.
- */
- extern JS_FRIEND_API(JSObject*)
- JS_NewArrayBuffer(JSContext* cx, uint32_t nbytes);
- /**
- * Check whether obj supports JS_GetTypedArray* APIs. Note that this may return
- * false if a security wrapper is encountered that denies the unwrapping. If
- * this test or one of the JS_Is*Array tests succeeds, then it is safe to call
- * the various accessor JSAPI calls defined below.
- */
- extern JS_FRIEND_API(bool)
- JS_IsTypedArrayObject(JSObject* obj);
- /**
- * Check whether obj supports JS_GetArrayBufferView* APIs. Note that this may
- * return false if a security wrapper is encountered that denies the
- * unwrapping. If this test or one of the more specific tests succeeds, then it
- * is safe to call the various ArrayBufferView accessor JSAPI calls defined
- * below.
- */
- extern JS_FRIEND_API(bool)
- JS_IsArrayBufferViewObject(JSObject* obj);
- /*
- * Test for specific typed array types (ArrayBufferView subtypes)
- */
- extern JS_FRIEND_API(bool)
- JS_IsInt8Array(JSObject* obj);
- extern JS_FRIEND_API(bool)
- JS_IsUint8Array(JSObject* obj);
- extern JS_FRIEND_API(bool)
- JS_IsUint8ClampedArray(JSObject* obj);
- extern JS_FRIEND_API(bool)
- JS_IsInt16Array(JSObject* obj);
- extern JS_FRIEND_API(bool)
- JS_IsUint16Array(JSObject* obj);
- extern JS_FRIEND_API(bool)
- JS_IsInt32Array(JSObject* obj);
- extern JS_FRIEND_API(bool)
- JS_IsUint32Array(JSObject* obj);
- extern JS_FRIEND_API(bool)
- JS_IsFloat32Array(JSObject* obj);
- extern JS_FRIEND_API(bool)
- JS_IsFloat64Array(JSObject* obj);
- /**
- * Return the isShared flag of a typed array, which denotes whether
- * the underlying buffer is a SharedArrayBuffer.
- *
- * |obj| must have passed a JS_IsTypedArrayObject/JS_Is*Array test, or somehow
- * be known that it would pass such a test: it is a typed array or a wrapper of
- * a typed array, and the unwrapping will succeed.
- */
- extern JS_FRIEND_API(bool)
- JS_GetTypedArraySharedness(JSObject* obj);
- /*
- * Test for specific typed array types (ArrayBufferView subtypes) and return
- * the unwrapped object if so, else nullptr. Never throws.
- */
- namespace js {
- extern JS_FRIEND_API(JSObject*)
- UnwrapInt8Array(JSObject* obj);
- extern JS_FRIEND_API(JSObject*)
- UnwrapUint8Array(JSObject* obj);
- extern JS_FRIEND_API(JSObject*)
- UnwrapUint8ClampedArray(JSObject* obj);
- extern JS_FRIEND_API(JSObject*)
- UnwrapInt16Array(JSObject* obj);
- extern JS_FRIEND_API(JSObject*)
- UnwrapUint16Array(JSObject* obj);
- extern JS_FRIEND_API(JSObject*)
- UnwrapInt32Array(JSObject* obj);
- extern JS_FRIEND_API(JSObject*)
- UnwrapUint32Array(JSObject* obj);
- extern JS_FRIEND_API(JSObject*)
- UnwrapFloat32Array(JSObject* obj);
- extern JS_FRIEND_API(JSObject*)
- UnwrapFloat64Array(JSObject* obj);
- extern JS_FRIEND_API(JSObject*)
- UnwrapArrayBuffer(JSObject* obj);
- extern JS_FRIEND_API(JSObject*)
- UnwrapArrayBufferView(JSObject* obj);
- extern JS_FRIEND_API(JSObject*)
- UnwrapSharedArrayBuffer(JSObject* obj);
- namespace detail {
- extern JS_FRIEND_DATA(const Class* const) Int8ArrayClassPtr;
- extern JS_FRIEND_DATA(const Class* const) Uint8ArrayClassPtr;
- extern JS_FRIEND_DATA(const Class* const) Uint8ClampedArrayClassPtr;
- extern JS_FRIEND_DATA(const Class* const) Int16ArrayClassPtr;
- extern JS_FRIEND_DATA(const Class* const) Uint16ArrayClassPtr;
- extern JS_FRIEND_DATA(const Class* const) Int32ArrayClassPtr;
- extern JS_FRIEND_DATA(const Class* const) Uint32ArrayClassPtr;
- extern JS_FRIEND_DATA(const Class* const) Float32ArrayClassPtr;
- extern JS_FRIEND_DATA(const Class* const) Float64ArrayClassPtr;
- const size_t TypedArrayLengthSlot = 1;
- } // namespace detail
- #define JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Type, type) \
- inline void \
- Get ## Type ## ArrayLengthAndData(JSObject* obj, uint32_t* length, bool* isSharedMemory, type** data) \
- { \
- MOZ_ASSERT(GetObjectClass(obj) == detail::Type ## ArrayClassPtr); \
- const JS::Value& lenSlot = GetReservedSlot(obj, detail::TypedArrayLengthSlot); \
- *length = mozilla::AssertedCast<uint32_t>(lenSlot.toInt32()); \
- *isSharedMemory = JS_GetTypedArraySharedness(obj); \
- *data = static_cast<type*>(GetObjectPrivate(obj)); \
- }
- JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Int8, int8_t)
- JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Uint8, uint8_t)
- JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Uint8Clamped, uint8_t)
- JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Int16, int16_t)
- JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Uint16, uint16_t)
- JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Int32, int32_t)
- JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Uint32, uint32_t)
- JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Float32, float)
- JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Float64, double)
- #undef JS_DEFINE_DATA_AND_LENGTH_ACCESSOR
- // This one isn't inlined because it's rather tricky (by dint of having to deal
- // with a dozen-plus classes and varying slot layouts.
- extern JS_FRIEND_API(void)
- GetArrayBufferViewLengthAndData(JSObject* obj, uint32_t* length, bool* isSharedMemory, uint8_t** data);
- // This one isn't inlined because there are a bunch of different ArrayBuffer
- // classes that would have to be individually handled here.
- //
- // There is an isShared out argument for API consistency (eases use from DOM).
- // It will always be set to false.
- extern JS_FRIEND_API(void)
- GetArrayBufferLengthAndData(JSObject* obj, uint32_t* length, bool* isSharedMemory, uint8_t** data);
- // Ditto for SharedArrayBuffer.
- //
- // There is an isShared out argument for API consistency (eases use from DOM).
- // It will always be set to true.
- extern JS_FRIEND_API(void)
- GetSharedArrayBufferLengthAndData(JSObject* obj, uint32_t* length, bool* isSharedMemory, uint8_t** data);
- } // namespace js
- JS_FRIEND_API(uint8_t*)
- JS_GetSharedArrayBufferData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&);
- /*
- * Unwrap Typed arrays all at once. Return nullptr without throwing if the
- * object cannot be viewed as the correct typed array, or the typed array
- * object on success, filling both outparameters.
- */
- extern JS_FRIEND_API(JSObject*)
- JS_GetObjectAsInt8Array(JSObject* obj, uint32_t* length, bool* isSharedMemory, int8_t** data);
- extern JS_FRIEND_API(JSObject*)
- JS_GetObjectAsUint8Array(JSObject* obj, uint32_t* length, bool* isSharedMemory, uint8_t** data);
- extern JS_FRIEND_API(JSObject*)
- JS_GetObjectAsUint8ClampedArray(JSObject* obj, uint32_t* length, bool* isSharedMemory, uint8_t** data);
- extern JS_FRIEND_API(JSObject*)
- JS_GetObjectAsInt16Array(JSObject* obj, uint32_t* length, bool* isSharedMemory, int16_t** data);
- extern JS_FRIEND_API(JSObject*)
- JS_GetObjectAsUint16Array(JSObject* obj, uint32_t* length, bool* isSharedMemory, uint16_t** data);
- extern JS_FRIEND_API(JSObject*)
- JS_GetObjectAsInt32Array(JSObject* obj, uint32_t* length, bool* isSharedMemory, int32_t** data);
- extern JS_FRIEND_API(JSObject*)
- JS_GetObjectAsUint32Array(JSObject* obj, uint32_t* length, bool* isSharedMemory, uint32_t** data);
- extern JS_FRIEND_API(JSObject*)
- JS_GetObjectAsFloat32Array(JSObject* obj, uint32_t* length, bool* isSharedMemory, float** data);
- extern JS_FRIEND_API(JSObject*)
- JS_GetObjectAsFloat64Array(JSObject* obj, uint32_t* length, bool* isSharedMemory, double** data);
- extern JS_FRIEND_API(JSObject*)
- JS_GetObjectAsArrayBufferView(JSObject* obj, uint32_t* length, bool* isSharedMemory, uint8_t** data);
- /*
- * Unwrap an ArrayBuffer, return nullptr if it's a different type.
- */
- extern JS_FRIEND_API(JSObject*)
- JS_GetObjectAsArrayBuffer(JSObject* obj, uint32_t* length, uint8_t** data);
- /*
- * Get the type of elements in a typed array, or MaxTypedArrayViewType if a DataView.
- *
- * |obj| must have passed a JS_IsArrayBufferView/JS_Is*Array test, or somehow
- * be known that it would pass such a test: it is an ArrayBufferView or a
- * wrapper of an ArrayBufferView, and the unwrapping will succeed.
- */
- extern JS_FRIEND_API(js::Scalar::Type)
- JS_GetArrayBufferViewType(JSObject* obj);
- extern JS_FRIEND_API(js::Scalar::Type)
- JS_GetSharedArrayBufferViewType(JSObject* obj);
- /*
- * Check whether obj supports the JS_GetArrayBuffer* APIs. Note that this may
- * return false if a security wrapper is encountered that denies the
- * unwrapping. If this test succeeds, then it is safe to call the various
- * accessor JSAPI calls defined below.
- */
- extern JS_FRIEND_API(bool)
- JS_IsArrayBufferObject(JSObject* obj);
- extern JS_FRIEND_API(bool)
- JS_IsSharedArrayBufferObject(JSObject* obj);
- /**
- * Return the available byte length of an array buffer.
- *
- * |obj| must have passed a JS_IsArrayBufferObject test, or somehow be known
- * that it would pass such a test: it is an ArrayBuffer or a wrapper of an
- * ArrayBuffer, and the unwrapping will succeed.
- */
- extern JS_FRIEND_API(uint32_t)
- JS_GetArrayBufferByteLength(JSObject* obj);
- extern JS_FRIEND_API(uint32_t)
- JS_GetSharedArrayBufferByteLength(JSObject* obj);
- /**
- * Return true if the arrayBuffer contains any data. This will return false for
- * ArrayBuffer.prototype and detached ArrayBuffers.
- *
- * |obj| must have passed a JS_IsArrayBufferObject test, or somehow be known
- * that it would pass such a test: it is an ArrayBuffer or a wrapper of an
- * ArrayBuffer, and the unwrapping will succeed.
- */
- extern JS_FRIEND_API(bool)
- JS_ArrayBufferHasData(JSObject* obj);
- /**
- * Return a pointer to the start of the data referenced by a typed array. The
- * data is still owned by the typed array, and should not be modified on
- * another thread. Furthermore, the pointer can become invalid on GC (if the
- * data is small and fits inside the array's GC header), so callers must take
- * care not to hold on across anything that could GC.
- *
- * |obj| must have passed a JS_IsArrayBufferObject test, or somehow be known
- * that it would pass such a test: it is an ArrayBuffer or a wrapper of an
- * ArrayBuffer, and the unwrapping will succeed.
- *
- * *isSharedMemory will be set to false, the argument is present to simplify
- * its use from code that also interacts with SharedArrayBuffer.
- */
- extern JS_FRIEND_API(uint8_t*)
- JS_GetArrayBufferData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&);
- /**
- * Check whether the obj is ArrayBufferObject and memory mapped. Note that this
- * may return false if a security wrapper is encountered that denies the
- * unwrapping.
- */
- extern JS_FRIEND_API(bool)
- JS_IsMappedArrayBufferObject(JSObject* obj);
- /**
- * Return the number of elements in a typed array.
- *
- * |obj| must have passed a JS_IsTypedArrayObject/JS_Is*Array test, or somehow
- * be known that it would pass such a test: it is a typed array or a wrapper of
- * a typed array, and the unwrapping will succeed.
- */
- extern JS_FRIEND_API(uint32_t)
- JS_GetTypedArrayLength(JSObject* obj);
- /**
- * Return the byte offset from the start of an array buffer to the start of a
- * typed array view.
- *
- * |obj| must have passed a JS_IsTypedArrayObject/JS_Is*Array test, or somehow
- * be known that it would pass such a test: it is a typed array or a wrapper of
- * a typed array, and the unwrapping will succeed.
- */
- extern JS_FRIEND_API(uint32_t)
- JS_GetTypedArrayByteOffset(JSObject* obj);
- /**
- * Return the byte length of a typed array.
- *
- * |obj| must have passed a JS_IsTypedArrayObject/JS_Is*Array test, or somehow
- * be known that it would pass such a test: it is a typed array or a wrapper of
- * a typed array, and the unwrapping will succeed.
- */
- extern JS_FRIEND_API(uint32_t)
- JS_GetTypedArrayByteLength(JSObject* obj);
- /**
- * Check whether obj supports JS_ArrayBufferView* APIs. Note that this may
- * return false if a security wrapper is encountered that denies the
- * unwrapping.
- */
- extern JS_FRIEND_API(bool)
- JS_IsArrayBufferViewObject(JSObject* obj);
- /**
- * More generic name for JS_GetTypedArrayByteLength to cover DataViews as well
- */
- extern JS_FRIEND_API(uint32_t)
- JS_GetArrayBufferViewByteLength(JSObject* obj);
- /*
- * Return a pointer to the start of the data referenced by a typed array. The
- * data is still owned by the typed array, and should not be modified on
- * another thread. Furthermore, the pointer can become invalid on GC (if the
- * data is small and fits inside the array's GC header), so callers must take
- * care not to hold on across anything that could GC.
- *
- * |obj| must have passed a JS_Is*Array test, or somehow be known that it would
- * pass such a test: it is a typed array or a wrapper of a typed array, and the
- * unwrapping will succeed.
- *
- * *isSharedMemory will be set to true if the typed array maps a
- * SharedArrayBuffer, otherwise to false.
- */
- extern JS_FRIEND_API(int8_t*)
- JS_GetInt8ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&);
- extern JS_FRIEND_API(uint8_t*)
- JS_GetUint8ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&);
- extern JS_FRIEND_API(uint8_t*)
- JS_GetUint8ClampedArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&);
- extern JS_FRIEND_API(int16_t*)
- JS_GetInt16ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&);
- extern JS_FRIEND_API(uint16_t*)
- JS_GetUint16ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&);
- extern JS_FRIEND_API(int32_t*)
- JS_GetInt32ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&);
- extern JS_FRIEND_API(uint32_t*)
- JS_GetUint32ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&);
- extern JS_FRIEND_API(float*)
- JS_GetFloat32ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&);
- extern JS_FRIEND_API(double*)
- JS_GetFloat64ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&);
- /**
- * Same as above, but for any kind of ArrayBufferView. Prefer the type-specific
- * versions when possible.
- */
- extern JS_FRIEND_API(void*)
- JS_GetArrayBufferViewData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&);
- /**
- * Return the ArrayBuffer or SharedArrayBuffer underlying an ArrayBufferView.
- * This may return a detached buffer. |obj| must be an object that would
- * return true for JS_IsArrayBufferViewObject().
- */
- extern JS_FRIEND_API(JSObject*)
- JS_GetArrayBufferViewBuffer(JSContext* cx, JS::HandleObject obj, bool* isSharedMemory);
- /**
- * Detach an ArrayBuffer, causing all associated views to no longer refer to
- * the ArrayBuffer's original attached memory.
- *
- * The |changeData| argument is obsolete and ignored.
- */
- extern JS_FRIEND_API(bool)
- JS_DetachArrayBuffer(JSContext* cx, JS::HandleObject obj);
- /**
- * Check whether the obj is a detached ArrayBufferObject. Note that this may
- * return false if a security wrapper is encountered that denies the
- * unwrapping.
- */
- extern JS_FRIEND_API(bool)
- JS_IsDetachedArrayBufferObject(JSObject* obj);
- /**
- * Check whether obj supports JS_GetDataView* APIs.
- */
- JS_FRIEND_API(bool)
- JS_IsDataViewObject(JSObject* obj);
- /**
- * Create a new DataView using the given ArrayBuffer for storage. The given
- * buffer must be an ArrayBuffer (or a cross-compartment wrapper of an
- * ArrayBuffer), and the offset and length must fit within the bounds of the
- * arrayBuffer. Currently, nullptr will be returned and an exception will be
- * thrown if these conditions do not hold, but do not depend on that behavior.
- */
- JS_FRIEND_API(JSObject*)
- JS_NewDataView(JSContext* cx, JS::HandleObject arrayBuffer, uint32_t byteOffset, int32_t byteLength);
- /**
- * Return the byte offset of a data view into its array buffer. |obj| must be a
- * DataView.
- *
- * |obj| must have passed a JS_IsDataViewObject test, or somehow be known that
- * it would pass such a test: it is a data view or a wrapper of a data view,
- * and the unwrapping will succeed.
- */
- JS_FRIEND_API(uint32_t)
- JS_GetDataViewByteOffset(JSObject* obj);
- /**
- * Return the byte length of a data view.
- *
- * |obj| must have passed a JS_IsDataViewObject test, or somehow be known that
- * it would pass such a test: it is a data view or a wrapper of a data view,
- * and the unwrapping will succeed. If cx is nullptr, then DEBUG builds may be
- * unable to assert when unwrapping should be disallowed.
- */
- JS_FRIEND_API(uint32_t)
- JS_GetDataViewByteLength(JSObject* obj);
- /**
- * Return a pointer to the beginning of the data referenced by a DataView.
- *
- * |obj| must have passed a JS_IsDataViewObject test, or somehow be known that
- * it would pass such a test: it is a data view or a wrapper of a data view,
- * and the unwrapping will succeed. If cx is nullptr, then DEBUG builds may be
- * unable to assert when unwrapping should be disallowed.
- */
- JS_FRIEND_API(void*)
- JS_GetDataViewData(JSObject* obj, const JS::AutoCheckCannotGC&);
- namespace js {
- /**
- * Add a watchpoint -- in the Object.prototype.watch sense -- to |obj| for the
- * property |id|, using the callable object |callable| as the function to be
- * called for notifications.
- *
- * This is an internal function exposed -- temporarily -- only so that DOM
- * proxies can be watchable. Don't use it! We'll soon kill off the
- * Object.prototype.{,un}watch functions, at which point this will go too.
- */
- extern JS_FRIEND_API(bool)
- WatchGuts(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleObject callable);
- /**
- * Remove a watchpoint -- in the Object.prototype.watch sense -- from |obj| for
- * the property |id|.
- *
- * This is an internal function exposed -- temporarily -- only so that DOM
- * proxies can be watchable. Don't use it! We'll soon kill off the
- * Object.prototype.{,un}watch functions, at which point this will go too.
- */
- extern JS_FRIEND_API(bool)
- UnwatchGuts(JSContext* cx, JS::HandleObject obj, JS::HandleId id);
- namespace jit {
- enum class InlinableNative : uint16_t;
- } // namespace jit
- } // namespace js
- /**
- * A class, expected to be passed by value, which represents the CallArgs for a
- * JSJitGetterOp.
- */
- class JSJitGetterCallArgs : protected JS::MutableHandleValue
- {
- public:
- explicit JSJitGetterCallArgs(const JS::CallArgs& args)
- : JS::MutableHandleValue(args.rval())
- {}
- explicit JSJitGetterCallArgs(JS::RootedValue* rooted)
- : JS::MutableHandleValue(rooted)
- {}
- JS::MutableHandleValue rval() {
- return *this;
- }
- };
- /**
- * A class, expected to be passed by value, which represents the CallArgs for a
- * JSJitSetterOp.
- */
- class JSJitSetterCallArgs : protected JS::MutableHandleValue
- {
- public:
- explicit JSJitSetterCallArgs(const JS::CallArgs& args)
- : JS::MutableHandleValue(args[0])
- {}
- JS::MutableHandleValue operator[](unsigned i) {
- MOZ_ASSERT(i == 0);
- return *this;
- }
- unsigned length() const { return 1; }
- // Add get() or maybe hasDefined() as needed
- };
- struct JSJitMethodCallArgsTraits;
- /**
- * A class, expected to be passed by reference, which represents the CallArgs
- * for a JSJitMethodOp.
- */
- class JSJitMethodCallArgs : protected JS::detail::CallArgsBase<JS::detail::NoUsedRval>
- {
- private:
- typedef JS::detail::CallArgsBase<JS::detail::NoUsedRval> Base;
- friend struct JSJitMethodCallArgsTraits;
- public:
- explicit JSJitMethodCallArgs(const JS::CallArgs& args) {
- argv_ = args.array();
- argc_ = args.length();
- }
- JS::MutableHandleValue rval() const {
- return Base::rval();
- }
- unsigned length() const { return Base::length(); }
- JS::MutableHandleValue operator[](unsigned i) const {
- return Base::operator[](i);
- }
- bool hasDefined(unsigned i) const {
- return Base::hasDefined(i);
- }
- JSObject& callee() const {
- // We can't use Base::callee() because that will try to poke at
- // this->usedRval_, which we don't have.
- return argv_[-2].toObject();
- }
- JS::HandleValue get(unsigned i) const {
- return Base::get(i);
- }
- };
- struct JSJitMethodCallArgsTraits
- {
- static const size_t offsetOfArgv = offsetof(JSJitMethodCallArgs, argv_);
- static const size_t offsetOfArgc = offsetof(JSJitMethodCallArgs, argc_);
- };
- typedef bool
- (* JSJitGetterOp)(JSContext* cx, JS::HandleObject thisObj,
- void* specializedThis, JSJitGetterCallArgs args);
- typedef bool
- (* JSJitSetterOp)(JSContext* cx, JS::HandleObject thisObj,
- void* specializedThis, JSJitSetterCallArgs args);
- typedef bool
- (* JSJitMethodOp)(JSContext* cx, JS::HandleObject thisObj,
- void* specializedThis, const JSJitMethodCallArgs& args);
- /**
- * This struct contains metadata passed from the DOM to the JS Engine for JIT
- * optimizations on DOM property accessors. Eventually, this should be made
- * available to general JSAPI users, but we are not currently ready to do so.
- */
- struct JSJitInfo {
- enum OpType {
- Getter,
- Setter,
- Method,
- StaticMethod,
- InlinableNative,
- // Must be last
- OpTypeCount
- };
- enum ArgType {
- // Basic types
- String = (1 << 0),
- Integer = (1 << 1), // Only 32-bit or less
- Double = (1 << 2), // Maybe we want to add Float sometime too
- Boolean = (1 << 3),
- Object = (1 << 4),
- Null = (1 << 5),
- // And derived types
- Numeric = Integer | Double,
- // Should "Primitive" use the WebIDL definition, which
- // excludes string and null, or the typical JS one that includes them?
- Primitive = Numeric | Boolean | Null | String,
- ObjectOrNull = Object | Null,
- Any = ObjectOrNull | Primitive,
- // Our sentinel value.
- ArgTypeListEnd = (1 << 31)
- };
- static_assert(Any & String, "Any must include String.");
- static_assert(Any & Integer, "Any must include Integer.");
- static_assert(Any & Double, "Any must include Double.");
- static_assert(Any & Boolean, "Any must include Boolean.");
- static_assert(Any & Object, "Any must include Object.");
- static_assert(Any & Null, "Any must include Null.");
- /**
- * An enum that describes what this getter/setter/method aliases. This
- * determines what things can be hoisted past this call, and if this
- * call is movable what it can be hoisted past.
- */
- enum AliasSet {
- /**
- * Alias nothing: a constant value, getting it can't affect any other
- * values, nothing can affect it.
- */
- AliasNone,
- /**
- * Alias things that can modify the DOM but nothing else. Doing the
- * call can't affect the behavior of any other function.
- */
- AliasDOMSets,
- /**
- * Alias the world. Calling this can change arbitrary values anywhere
- * in the system. Most things fall in this bucket.
- */
- AliasEverything,
- /** Must be last. */
- AliasSetCount
- };
- bool needsOuterizedThisObject() const
- {
- return type() != Getter && type() != Setter;
- }
- bool isTypedMethodJitInfo() const
- {
- return isTypedMethod;
- }
- OpType type() const
- {
- return OpType(type_);
- }
- AliasSet aliasSet() const
- {
- return AliasSet(aliasSet_);
- }
- JSValueType returnType() const
- {
- return JSValueType(returnType_);
- }
- union {
- JSJitGetterOp getter;
- JSJitSetterOp setter;
- JSJitMethodOp method;
- /** A DOM static method, used for Promise wrappers */
- JSNative staticMethod;
- };
- union {
- uint16_t protoID;
- js::jit::InlinableNative inlinableNative;
- };
- union {
- uint16_t depth;
- // Additional opcode for some InlinableNative functions.
- uint16_t nativeOp;
- };
- // These fields are carefully packed to take up 4 bytes. If you need more
- // bits for whatever reason, please see if you can steal bits from existing
- // fields before adding more members to this structure.
- #define JITINFO_OP_TYPE_BITS 4
- #define JITINFO_ALIAS_SET_BITS 4
- #define JITINFO_RETURN_TYPE_BITS 8
- #define JITINFO_SLOT_INDEX_BITS 10
- /** The OpType that says what sort of function we are. */
- uint32_t type_ : JITINFO_OP_TYPE_BITS;
- /**
- * The alias set for this op. This is a _minimal_ alias set; in
- * particular for a method it does not include whatever argument
- * conversions might do. That's covered by argTypes and runtime
- * analysis of the actual argument types being passed in.
- */
- uint32_t aliasSet_ : JITINFO_ALIAS_SET_BITS;
- /** The return type tag. Might be JSVAL_TYPE_UNKNOWN. */
- uint32_t returnType_ : JITINFO_RETURN_TYPE_BITS;
- static_assert(OpTypeCount <= (1 << JITINFO_OP_TYPE_BITS),
- "Not enough space for OpType");
- static_assert(AliasSetCount <= (1 << JITINFO_ALIAS_SET_BITS),
- "Not enough space for AliasSet");
- static_assert((sizeof(JSValueType) * 8) <= JITINFO_RETURN_TYPE_BITS,
- "Not enough space for JSValueType");
- #undef JITINFO_RETURN_TYPE_BITS
- #undef JITINFO_ALIAS_SET_BITS
- #undef JITINFO_OP_TYPE_BITS
- /** Is op fallible? False in setters. */
- uint32_t isInfallible : 1;
- /**
- * Is op movable? To be movable the op must
- * not AliasEverything, but even that might
- * not be enough (e.g. in cases when it can
- * throw or is explicitly not movable).
- */
- uint32_t isMovable : 1;
- /**
- * Can op be dead-code eliminated? Again, this
- * depends on whether the op can throw, in
- * addition to the alias set.
- */
- uint32_t isEliminatable : 1;
- // XXXbz should we have a JSValueType for the type of the member?
- /**
- * True if this is a getter that can always
- * get the value from a slot of the "this" object.
- */
- uint32_t isAlwaysInSlot : 1;
- /**
- * True if this is a getter that can sometimes (if the slot doesn't contain
- * UndefinedValue()) get the value from a slot of the "this" object.
- */
- uint32_t isLazilyCachedInSlot : 1;
- /** True if this is an instance of JSTypedMethodJitInfo. */
- uint32_t isTypedMethod : 1;
- /**
- * If isAlwaysInSlot or isSometimesInSlot is true,
- * the index of the slot to get the value from.
- * Otherwise 0.
- */
- uint32_t slotIndex : JITINFO_SLOT_INDEX_BITS;
- static const size_t maxSlotIndex = (1 << JITINFO_SLOT_INDEX_BITS) - 1;
- #undef JITINFO_SLOT_INDEX_BITS
- };
- static_assert(sizeof(JSJitInfo) == (sizeof(void*) + 2 * sizeof(uint32_t)),
- "There are several thousand instances of JSJitInfo stored in "
- "a binary. Please don't increase its space requirements without "
- "verifying that there is no other way forward (better packing, "
- "smaller datatypes for fields, subclassing, etc.).");
- struct JSTypedMethodJitInfo
- {
- // We use C-style inheritance here, rather than C++ style inheritance
- // because not all compilers support brace-initialization for non-aggregate
- // classes. Using C++ style inheritance and constructors instead of
- // brace-initialization would also force the creation of static
- // constructors (on some compilers) when JSJitInfo and JSTypedMethodJitInfo
- // structures are declared. Since there can be several thousand of these
- // structures present and we want to have roughly equivalent performance
- // across a range of compilers, we do things manually.
- JSJitInfo base;
- const JSJitInfo::ArgType* const argTypes; /* For a method, a list of sets of
- types that the function
- expects. This can be used,
- for example, to figure out
- when argument coercions can
- have side-effects. */
- };
- namespace js {
- static MOZ_ALWAYS_INLINE shadow::Function*
- FunctionObjectToShadowFunction(JSObject* fun)
- {
- MOZ_ASSERT(GetObjectClass(fun) == FunctionClassPtr);
- return reinterpret_cast<shadow::Function*>(fun);
- }
- /* Statically asserted in jsfun.h. */
- static const unsigned JS_FUNCTION_INTERPRETED_BITS = 0x0201;
- // Return whether the given function object is native.
- static MOZ_ALWAYS_INLINE bool
- FunctionObjectIsNative(JSObject* fun)
- {
- return !(FunctionObjectToShadowFunction(fun)->flags & JS_FUNCTION_INTERPRETED_BITS);
- }
- static MOZ_ALWAYS_INLINE JSNative
- GetFunctionObjectNative(JSObject* fun)
- {
- MOZ_ASSERT(FunctionObjectIsNative(fun));
- return FunctionObjectToShadowFunction(fun)->native;
- }
- } // namespace js
- static MOZ_ALWAYS_INLINE const JSJitInfo*
- FUNCTION_VALUE_TO_JITINFO(const JS::Value& v)
- {
- MOZ_ASSERT(js::FunctionObjectIsNative(&v.toObject()));
- return js::FunctionObjectToShadowFunction(&v.toObject())->jitinfo;
- }
- static MOZ_ALWAYS_INLINE void
- SET_JITINFO(JSFunction * func, const JSJitInfo* info)
- {
- js::shadow::Function* fun = reinterpret_cast<js::shadow::Function*>(func);
- MOZ_ASSERT(!(fun->flags & js::JS_FUNCTION_INTERPRETED_BITS));
- fun->jitinfo = info;
- }
- /*
- * Engine-internal extensions of jsid. This code is here only until we
- * eliminate Gecko's dependencies on it!
- */
- static MOZ_ALWAYS_INLINE jsid
- JSID_FROM_BITS(size_t bits)
- {
- jsid id;
- JSID_BITS(id) = bits;
- return id;
- }
- namespace js {
- namespace detail {
- bool IdMatchesAtom(jsid id, JSAtom* atom);
- } // namespace detail
- } // namespace js
- /**
- * Must not be used on atoms that are representable as integer jsids.
- * Prefer NameToId or AtomToId over this function:
- *
- * A PropertyName is an atom that does not contain an integer in the range
- * [0, UINT32_MAX]. However, jsid can only hold an integer in the range
- * [0, JSID_INT_MAX] (where JSID_INT_MAX == 2^31-1). Thus, for the range of
- * integers (JSID_INT_MAX, UINT32_MAX], to represent as a jsid 'id', it must be
- * the case JSID_IS_ATOM(id) and !JSID_TO_ATOM(id)->isPropertyName(). In most
- * cases when creating a jsid, code does not have to care about this corner
- * case because:
- *
- * - When given an arbitrary JSAtom*, AtomToId must be used, which checks for
- * integer atoms representable as integer jsids, and does this conversion.
- *
- * - When given a PropertyName*, NameToId can be used which which does not need
- * to do any dynamic checks.
- *
- * Thus, it is only the rare third case which needs this function, which
- * handles any JSAtom* that is known not to be representable with an int jsid.
- */
- static MOZ_ALWAYS_INLINE jsid
- NON_INTEGER_ATOM_TO_JSID(JSAtom* atom)
- {
- MOZ_ASSERT(((size_t)atom & 0x7) == 0);
- jsid id = JSID_FROM_BITS((size_t)atom);
- MOZ_ASSERT(js::detail::IdMatchesAtom(id, atom));
- return id;
- }
- /* All strings stored in jsids are atomized, but are not necessarily property names. */
- static MOZ_ALWAYS_INLINE bool
- JSID_IS_ATOM(jsid id)
- {
- return JSID_IS_STRING(id);
- }
- static MOZ_ALWAYS_INLINE bool
- JSID_IS_ATOM(jsid id, JSAtom* atom)
- {
- return id == JSID_FROM_BITS((size_t)atom);
- }
- static MOZ_ALWAYS_INLINE JSAtom*
- JSID_TO_ATOM(jsid id)
- {
- return (JSAtom*)JSID_TO_STRING(id);
- }
- JS_STATIC_ASSERT(sizeof(jsid) == sizeof(void*));
- namespace js {
- static MOZ_ALWAYS_INLINE JS::Value
- IdToValue(jsid id)
- {
- if (JSID_IS_STRING(id))
- return JS::StringValue(JSID_TO_STRING(id));
- if (JSID_IS_INT(id))
- return JS::Int32Value(JSID_TO_INT(id));
- if (JSID_IS_SYMBOL(id))
- return JS::SymbolValue(JSID_TO_SYMBOL(id));
- MOZ_ASSERT(JSID_IS_VOID(id));
- return JS::UndefinedValue();
- }
- /**
- * If the embedder has registered a ScriptEnvironmentPreparer,
- * PrepareScriptEnvironmentAndInvoke will call the preparer's 'invoke' method
- * with the given |closure|, with the assumption that the preparer will set up
- * any state necessary to run script in |scope|, invoke |closure| with a valid
- * JSContext*, report any exceptions thrown from the closure, and return.
- *
- * If no preparer is registered, PrepareScriptEnvironmentAndInvoke will assert
- * that |rt| has exactly one JSContext associated with it, enter the compartment
- * of |scope| on that context, and invoke |closure|.
- *
- * In both cases, PrepareScriptEnvironmentAndInvoke will report any exceptions
- * that are thrown by the closure. Consumers who want to propagate back
- * whether the closure succeeded should do so via members of the closure
- * itself.
- */
- struct ScriptEnvironmentPreparer {
- struct Closure {
- virtual bool operator()(JSContext* cx) = 0;
- };
- virtual void invoke(JS::HandleObject scope, Closure& closure) = 0;
- };
- extern JS_FRIEND_API(void)
- PrepareScriptEnvironmentAndInvoke(JSContext* cx, JS::HandleObject scope,
- ScriptEnvironmentPreparer::Closure& closure);
- JS_FRIEND_API(void)
- SetScriptEnvironmentPreparer(JSContext* cx, ScriptEnvironmentPreparer* preparer);
- enum CTypesActivityType {
- CTYPES_CALL_BEGIN,
- CTYPES_CALL_END,
- CTYPES_CALLBACK_BEGIN,
- CTYPES_CALLBACK_END
- };
- typedef void
- (* CTypesActivityCallback)(JSContext* cx, CTypesActivityType type);
- /**
- * Sets a callback that is run whenever js-ctypes is about to be used when
- * calling into C.
- */
- JS_FRIEND_API(void)
- SetCTypesActivityCallback(JSContext* cx, CTypesActivityCallback cb);
- class MOZ_RAII JS_FRIEND_API(AutoCTypesActivityCallback) {
- private:
- JSContext* cx;
- CTypesActivityCallback callback;
- CTypesActivityType endType;
- MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
- public:
- AutoCTypesActivityCallback(JSContext* cx, CTypesActivityType beginType,
- CTypesActivityType endType
- MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
- ~AutoCTypesActivityCallback() {
- DoEndCallback();
- }
- void DoEndCallback() {
- if (callback) {
- callback(cx, endType);
- callback = nullptr;
- }
- }
- };
- // Abstract base class for objects that build allocation metadata for JavaScript
- // values.
- struct AllocationMetadataBuilder {
- AllocationMetadataBuilder() { }
- // Return a metadata object for the newly constructed object |obj|, or
- // nullptr if there's no metadata to attach.
- //
- // Implementations should treat all errors as fatal; there is no way to
- // report errors from this callback. In particular, the caller provides an
- // oomUnsafe for overriding implementations to use.
- virtual JSObject* build(JSContext* cx, JS::HandleObject obj,
- AutoEnterOOMUnsafeRegion& oomUnsafe) const
- {
- return nullptr;
- }
- };
- /**
- * Specify a callback to invoke when creating each JS object in the current
- * compartment, which may return a metadata object to associate with the
- * object.
- */
- JS_FRIEND_API(void)
- SetAllocationMetadataBuilder(JSContext* cx, const AllocationMetadataBuilder *callback);
- /** Get the metadata associated with an object. */
- JS_FRIEND_API(JSObject*)
- GetAllocationMetadata(JSObject* obj);
- JS_FRIEND_API(bool)
- GetElementsWithAdder(JSContext* cx, JS::HandleObject obj, JS::HandleObject receiver,
- uint32_t begin, uint32_t end, js::ElementAdder* adder);
- JS_FRIEND_API(bool)
- ForwardToNative(JSContext* cx, JSNative native, const JS::CallArgs& args);
- /**
- * Helper function for HTMLDocument and HTMLFormElement.
- *
- * These are the only two interfaces that have [OverrideBuiltins], a named
- * getter, and no named setter. They're implemented as proxies with a custom
- * getOwnPropertyDescriptor() method. Unfortunately, overriding
- * getOwnPropertyDescriptor() automatically affects the behavior of set(),
- * which normally is just common sense but is *not* desired for these two
- * interfaces.
- *
- * The fix is for these two interfaces to override set() to ignore the
- * getOwnPropertyDescriptor() override.
- *
- * SetPropertyIgnoringNamedGetter is exposed to make it easier to override
- * set() in this way. It carries out all the steps of BaseProxyHandler::set()
- * except the initial getOwnPropertyDescriptor() call. The caller must supply
- * that descriptor as the 'ownDesc' parameter.
- *
- * Implemented in proxy/BaseProxyHandler.cpp.
- */
- JS_FRIEND_API(bool)
- SetPropertyIgnoringNamedGetter(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
- JS::HandleValue v, JS::HandleValue receiver,
- JS::Handle<JS::PropertyDescriptor> ownDesc,
- JS::ObjectOpResult& result);
- JS_FRIEND_API(void)
- ReportASCIIErrorWithId(JSContext* cx, const char* msg, JS::HandleId id);
- // This function is for one specific use case, please don't use this for anything else!
- extern JS_FRIEND_API(bool)
- ExecuteInGlobalAndReturnScope(JSContext* cx, JS::HandleObject obj, JS::HandleScript script,
- JS::MutableHandleObject scope);
- #if defined(XP_WIN) && defined(_WIN64)
- // Parameters use void* types to avoid #including windows.h. The return value of
- // this function is returned from the exception handler.
- typedef long
- (*JitExceptionHandler)(void* exceptionRecord, // PEXECTION_RECORD
- void* context); // PCONTEXT
- /**
- * Windows uses "structured exception handling" to handle faults. When a fault
- * occurs, the stack is searched for a handler (similar to C++ exception
- * handling). If the search does not find a handler, the "unhandled exception
- * filter" is called. Breakpad uses the unhandled exception filter to do crash
- * reporting. Unfortunately, on Win64, JIT code on the stack completely throws
- * off this unwinding process and prevents the unhandled exception filter from
- * being called. The reason is that Win64 requires unwind information be
- * registered for all code regions and JIT code has none. While it is possible
- * to register full unwind information for JIT code, this is a lot of work (one
- * has to be able to recover the frame pointer at any PC) so instead we register
- * a handler for all JIT code that simply calls breakpad's unhandled exception
- * filter (which will perform crash reporting and then terminate the process).
- * This would be wrong if there was an outer __try block that expected to handle
- * the fault, but this is not generally allowed.
- *
- * Gecko must call SetJitExceptionFilter before any JIT code is compiled and
- * only once per process.
- */
- extern JS_FRIEND_API(void)
- SetJitExceptionHandler(JitExceptionHandler handler);
- #endif
- /**
- * Get the nearest enclosing with environment object for a given function. If
- * the function is not scripted or is not enclosed by a with scope, returns
- * the global.
- */
- extern JS_FRIEND_API(JSObject*)
- GetNearestEnclosingWithEnvironmentObjectForFunction(JSFunction* fun);
- /**
- * Get the first SavedFrame object in this SavedFrame stack whose principals are
- * subsumed by the cx's principals. If there is no such frame, return nullptr.
- *
- * Do NOT pass a non-SavedFrame object here.
- *
- * The savedFrame and cx do not need to be in the same compartment.
- */
- extern JS_FRIEND_API(JSObject*)
- GetFirstSubsumedSavedFrame(JSContext* cx, JS::HandleObject savedFrame, JS::SavedFrameSelfHosted selfHosted);
- extern JS_FRIEND_API(bool)
- ReportIsNotFunction(JSContext* cx, JS::HandleValue v);
- extern JS_FRIEND_API(JSObject*)
- ConvertArgsToArray(JSContext* cx, const JS::CallArgs& args);
- /**
- * Window and WindowProxy
- *
- * The functions below have to do with Windows and WindowProxies. There's an
- * invariant that actual Window objects (the global objects of web pages) are
- * never directly exposed to script. Instead we often substitute a WindowProxy.
- *
- * The environment chain, on the other hand, contains the Window and never its
- * WindowProxy.
- *
- * As a result, we have calls to these "substitute-this-object-for-that-object"
- * functions sprinkled at apparently arbitrary (but actually *very* carefully
- * and nervously selected) places throughout the engine and indeed the
- * universe.
- */
- /**
- * Tell the JS engine which Class is used for WindowProxy objects. Used by the
- * functions below.
- */
- extern JS_FRIEND_API(void)
- SetWindowProxyClass(JSContext* cx, const Class* clasp);
- /**
- * Associates a WindowProxy with a Window (global object). `windowProxy` must
- * have the Class set by SetWindowProxyClass.
- */
- extern JS_FRIEND_API(void)
- SetWindowProxy(JSContext* cx, JS::HandleObject global, JS::HandleObject windowProxy);
- namespace detail {
- JS_FRIEND_API(bool)
- IsWindowSlow(JSObject* obj);
- } // namespace detail
- /**
- * Returns true iff `obj` is a global object with an associated WindowProxy,
- * see SetWindowProxy.
- */
- inline bool
- IsWindow(JSObject* obj)
- {
- if (GetObjectClass(obj)->flags & JSCLASS_IS_GLOBAL)
- return detail::IsWindowSlow(obj);
- return false;
- }
- /**
- * Returns true iff `obj` has the WindowProxy Class (see SetWindowProxyClass).
- */
- JS_FRIEND_API(bool)
- IsWindowProxy(JSObject* obj);
- /**
- * If `obj` is a Window, get its associated WindowProxy (or a CCW or dead
- * wrapper if the page was navigated away from), else return `obj`. This
- * function is infallible and never returns nullptr.
- */
- extern JS_FRIEND_API(JSObject*)
- ToWindowProxyIfWindow(JSObject* obj);
- /**
- * If `obj` is a WindowProxy, get its associated Window (the compartment's
- * global), else return `obj`. This function is infallible and never returns
- * nullptr.
- */
- extern JS_FRIEND_API(JSObject*)
- ToWindowIfWindowProxy(JSObject* obj);
- } /* namespace js */
- class NativeProfiler
- {
- public:
- virtual ~NativeProfiler() {};
- virtual void sampleNative(void* addr, uint32_t size) = 0;
- virtual void removeNative(void* addr) = 0;
- virtual void reset() = 0;
- };
- class GCHeapProfiler
- {
- public:
- virtual ~GCHeapProfiler() {};
- virtual void sampleTenured(void* addr, uint32_t size) = 0;
- virtual void sampleNursery(void* addr, uint32_t size) = 0;
- virtual void markTenuredStart() = 0;
- virtual void markTenured(void* addr) = 0;
- virtual void sweepTenured() = 0;
- virtual void sweepNursery() = 0;
- virtual void moveNurseryToTenured(void* addrOld, void* addrNew) = 0;
- virtual void reset() = 0;
- };
- class MemProfiler
- {
- static mozilla::Atomic<uint32_t, mozilla::Relaxed> sActiveProfilerCount;
- static NativeProfiler* sNativeProfiler;
- static GCHeapProfiler* GetGCHeapProfiler(void* addr);
- static GCHeapProfiler* GetGCHeapProfiler(JSRuntime* runtime);
- static NativeProfiler* GetNativeProfiler() {
- return sNativeProfiler;
- }
- GCHeapProfiler* mGCHeapProfiler;
- JSRuntime* mRuntime;
- public:
- explicit MemProfiler(JSRuntime* aRuntime) : mGCHeapProfiler(nullptr), mRuntime(aRuntime) {}
- void start(GCHeapProfiler* aGCHeapProfiler);
- void stop();
- GCHeapProfiler* getGCHeapProfiler() const {
- return mGCHeapProfiler;
- }
- static MOZ_ALWAYS_INLINE bool enabled() {
- return sActiveProfilerCount > 0;
- }
- static MemProfiler* GetMemProfiler(JSContext* context);
- static void SetNativeProfiler(NativeProfiler* aProfiler) {
- sNativeProfiler = aProfiler;
- }
- static MOZ_ALWAYS_INLINE void SampleNative(void* addr, uint32_t size) {
- JS::AutoSuppressGCAnalysis nogc;
- if (MOZ_LIKELY(!enabled()))
- return;
- NativeProfiler* profiler = GetNativeProfiler();
- if (profiler)
- profiler->sampleNative(addr, size);
- }
- static MOZ_ALWAYS_INLINE void SampleTenured(void* addr, uint32_t size) {
- JS::AutoSuppressGCAnalysis nogc;
- if (MOZ_LIKELY(!enabled()))
- return;
- GCHeapProfiler* profiler = GetGCHeapProfiler(addr);
- if (profiler)
- profiler->sampleTenured(addr, size);
- }
- static MOZ_ALWAYS_INLINE void SampleNursery(void* addr, uint32_t size) {
- JS::AutoSuppressGCAnalysis nogc;
- if (MOZ_LIKELY(!enabled()))
- return;
- GCHeapProfiler* profiler = GetGCHeapProfiler(addr);
- if (profiler)
- profiler->sampleNursery(addr, size);
- }
- static MOZ_ALWAYS_INLINE void RemoveNative(void* addr) {
- JS::AutoSuppressGCAnalysis nogc;
- if (MOZ_LIKELY(!enabled()))
- return;
- NativeProfiler* profiler = GetNativeProfiler();
- if (profiler)
- profiler->removeNative(addr);
- }
- static MOZ_ALWAYS_INLINE void MarkTenuredStart(JSRuntime* runtime) {
- JS::AutoSuppressGCAnalysis nogc;
- if (MOZ_LIKELY(!enabled()))
- return;
- GCHeapProfiler* profiler = GetGCHeapProfiler(runtime);
- if (profiler)
- profiler->markTenuredStart();
- }
- static MOZ_ALWAYS_INLINE void MarkTenured(void* addr) {
- JS::AutoSuppressGCAnalysis nogc;
- if (MOZ_LIKELY(!enabled()))
- return;
- GCHeapProfiler* profiler = GetGCHeapProfiler(addr);
- if (profiler)
- profiler->markTenured(addr);
- }
- static MOZ_ALWAYS_INLINE void SweepTenured(JSRuntime* runtime) {
- JS::AutoSuppressGCAnalysis nogc;
- if (MOZ_LIKELY(!enabled()))
- return;
- GCHeapProfiler* profiler = GetGCHeapProfiler(runtime);
- if (profiler)
- profiler->sweepTenured();
- }
- static MOZ_ALWAYS_INLINE void SweepNursery(JSRuntime* runtime) {
- JS::AutoSuppressGCAnalysis nogc;
- if (MOZ_LIKELY(!enabled()))
- return;
- GCHeapProfiler* profiler = GetGCHeapProfiler(runtime);
- if (profiler)
- profiler->sweepNursery();
- }
- static MOZ_ALWAYS_INLINE void MoveNurseryToTenured(void* addrOld, void* addrNew) {
- JS::AutoSuppressGCAnalysis nogc;
- if (MOZ_LIKELY(!enabled()))
- return;
- GCHeapProfiler* profiler = GetGCHeapProfiler(addrOld);
- if (profiler)
- profiler->moveNurseryToTenured(addrOld, addrNew);
- }
- };
- #endif /* jsfriendapi_h */
|