1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: set ts=8 sts=2 et sw=2 tw=80:
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef vm_Interpreter_h
8 #define vm_Interpreter_h
11 * JS interpreter interface.
16 #include "vm/BuiltinObjectKind.h"
17 #include "vm/CheckIsObjectKind.h" // CheckIsObjectKind
23 class EnvironmentIter
;
27 * Convert null/undefined |thisv| into the global lexical's |this| object, and
28 * replace other primitives with boxed versions.
30 extern JSObject
* BoxNonStrictThis(JSContext
* cx
, HandleValue thisv
);
32 extern bool GetFunctionThis(JSContext
* cx
, AbstractFramePtr frame
,
33 MutableHandleValue res
);
35 extern void GetNonSyntacticGlobalThis(JSContext
* cx
, HandleObject envChain
,
36 MutableHandleValue res
);
39 * numToSkip is the number of stack values the expression decompiler should skip
40 * before it reaches |v|. If it's -1, the decompiler will search the stack.
42 extern bool ReportIsNotFunction(JSContext
* cx
, HandleValue v
, int numToSkip
,
43 MaybeConstruct construct
= NO_CONSTRUCT
);
45 /* See ReportIsNotFunction comment for the meaning of numToSkip. */
46 extern JSObject
* ValueToCallable(JSContext
* cx
, HandleValue v
,
48 MaybeConstruct construct
= NO_CONSTRUCT
);
50 // Reasons why a call could be performed, for passing onto the debugger's
51 // `onNativeCall` hook.
52 // `onNativeCall` hook disabled all JITs, and this needs to be handled only in
54 enum class CallReason
{
56 // callContentFunction or constructContentFunction in self-hosted JS.
58 // Function.prototype.call or Function.prototype.apply.
65 * Call or construct arguments that are stored in rooted memory.
67 * NOTE: Any necessary |GetThisValue| computation must have been performed on
68 * |args.thisv()|, likely by the interpreter when pushing |this| onto the
69 * stack. If you're not sure whether |GetThisValue| processing has been
70 * performed, use |Invoke|.
72 extern bool InternalCallOrConstruct(JSContext
* cx
, const CallArgs
& args
,
73 MaybeConstruct construct
,
74 CallReason reason
= CallReason::Call
);
77 * These helpers take care of the infinite-recursion check necessary for
78 * getter/setter calls.
80 extern bool CallGetter(JSContext
* cx
, HandleValue thisv
, HandleValue getter
,
81 MutableHandleValue rval
);
83 extern bool CallSetter(JSContext
* cx
, HandleValue thisv
, HandleValue setter
,
86 // ES7 rev 0c1bd3004329336774cbc90de727cd0cf5f11e93
87 // 7.3.12 Call(F, V, argumentsList).
88 // All parameters are required, hopefully forcing callers to be careful not to
89 // (say) blindly pass callee as |newTarget| when a different value should have
90 // been passed. Behavior is unspecified if any element of |args| isn't
93 // |rval| is written to *only* after |fval| and |thisv| have been consumed, so
94 // |rval| *may* alias either argument.
95 extern bool Call(JSContext
* cx
, HandleValue fval
, HandleValue thisv
,
96 const AnyInvokeArgs
& args
, MutableHandleValue rval
,
97 CallReason reason
= CallReason::Call
);
99 inline bool Call(JSContext
* cx
, HandleValue fval
, HandleValue thisv
,
100 MutableHandleValue rval
) {
101 FixedInvokeArgs
<0> args(cx
);
102 return Call(cx
, fval
, thisv
, args
, rval
);
105 inline bool Call(JSContext
* cx
, HandleValue fval
, JSObject
* thisObj
,
106 MutableHandleValue rval
) {
107 RootedValue
thisv(cx
, ObjectOrNullValue(thisObj
));
108 FixedInvokeArgs
<0> args(cx
);
109 return Call(cx
, fval
, thisv
, args
, rval
);
112 inline bool Call(JSContext
* cx
, HandleValue fval
, HandleValue thisv
,
113 HandleValue arg0
, MutableHandleValue rval
) {
114 FixedInvokeArgs
<1> args(cx
);
116 return Call(cx
, fval
, thisv
, args
, rval
);
119 inline bool Call(JSContext
* cx
, HandleValue fval
, JSObject
* thisObj
,
120 HandleValue arg0
, MutableHandleValue rval
) {
121 RootedValue
thisv(cx
, ObjectOrNullValue(thisObj
));
122 FixedInvokeArgs
<1> args(cx
);
124 return Call(cx
, fval
, thisv
, args
, rval
);
127 inline bool Call(JSContext
* cx
, HandleValue fval
, HandleValue thisv
,
128 HandleValue arg0
, HandleValue arg1
, MutableHandleValue rval
) {
129 FixedInvokeArgs
<2> args(cx
);
132 return Call(cx
, fval
, thisv
, args
, rval
);
135 inline bool Call(JSContext
* cx
, HandleValue fval
, JSObject
* thisObj
,
136 HandleValue arg0
, HandleValue arg1
, MutableHandleValue rval
) {
137 RootedValue
thisv(cx
, ObjectOrNullValue(thisObj
));
138 FixedInvokeArgs
<2> args(cx
);
141 return Call(cx
, fval
, thisv
, args
, rval
);
144 // Perform the above Call() operation using the given arguments. Similar to
145 // ConstructFromStack() below, this handles |!IsCallable(args.calleev())|.
147 // This internal operation is intended only for use with arguments known to be
148 // on the JS stack, or at least in carefully-rooted memory. The vast majority of
149 // potential users should instead use InvokeArgs in concert with Call().
150 extern bool CallFromStack(JSContext
* cx
, const CallArgs
& args
,
151 CallReason reason
= CallReason::Call
);
153 // ES6 7.3.13 Construct(F, argumentsList, newTarget). All parameters are
154 // required, hopefully forcing callers to be careful not to (say) blindly pass
155 // callee as |newTarget| when a different value should have been passed.
156 // Behavior is unspecified if any element of |args| isn't initialized.
158 // |rval| is written to *only* after |fval| and |newTarget| have been consumed,
159 // so |rval| *may* alias either argument.
161 // NOTE: As with the ES6 spec operation, it's the caller's responsibility to
162 // ensure |fval| and |newTarget| are both |IsConstructor|.
163 extern bool Construct(JSContext
* cx
, HandleValue fval
,
164 const AnyConstructArgs
& args
, HandleValue newTarget
,
165 MutableHandleObject objp
);
167 // Check that in the given |args|, which must be |args.isConstructing()|, that
168 // |IsConstructor(args.callee())|. If this is not the case, throw a TypeError.
169 // Otherwise, the user must ensure that, additionally,
170 // |IsConstructor(args.newTarget())|. (If |args| comes directly from the
171 // interpreter stack, as set up by JSOp::New, this comes for free.) Then perform
172 // a Construct() operation using |args|.
174 // This internal operation is intended only for use with arguments known to be
175 // on the JS stack, or at least in carefully-rooted memory. The vast majority of
176 // potential users should instead use ConstructArgs in concert with Construct().
177 extern bool ConstructFromStack(JSContext
* cx
, const CallArgs
& args
,
178 CallReason reason
= CallReason::Call
);
180 // Call Construct(fval, args, newTarget), but use the given |thisv| as |this|
181 // during construction of |fval|.
183 // |rval| is written to *only* after |fval|, |thisv|, and |newTarget| have been
184 // consumed, so |rval| *may* alias any of these arguments.
186 // This method exists only for very rare cases where a |this| was created
187 // caller-side for construction of |fval|: basically only for JITs using
188 // |CreateThis|. If that's not you, use Construct()!
189 extern bool InternalConstructWithProvidedThis(JSContext
* cx
, HandleValue fval
,
191 const AnyConstructArgs
& args
,
192 HandleValue newTarget
,
193 MutableHandleValue rval
);
196 * Executes a script with the given envChain. To support debugging, the
197 * evalInFrame parameter can point to an arbitrary frame in the context's call
198 * stack to simulate executing an eval in that frame.
200 extern bool ExecuteKernel(JSContext
* cx
, HandleScript script
,
201 HandleObject envChainArg
,
202 AbstractFramePtr evalInFrame
,
203 MutableHandleValue result
);
205 /* Execute a script with the given envChain as global code. */
206 extern bool Execute(JSContext
* cx
, HandleScript script
, HandleObject envChain
,
207 MutableHandleValue rval
);
212 // RunState is passed to RunScript and RunScript then either passes it to the
213 // interpreter or to the JITs. RunState contains all information we need to
214 // construct an interpreter or JIT frame.
215 class MOZ_RAII RunState
{
217 enum Kind
{ Execute
, Invoke
};
220 RootedScript script_
;
222 explicit RunState(JSContext
* cx
, Kind kind
, JSScript
* script
)
223 : kind_(kind
), script_(cx
, script
) {}
226 bool isExecute() const { return kind_
== Execute
; }
227 bool isInvoke() const { return kind_
== Invoke
; }
229 ExecuteState
* asExecute() const {
230 MOZ_ASSERT(isExecute());
231 return (ExecuteState
*)this;
233 InvokeState
* asInvoke() const {
234 MOZ_ASSERT(isInvoke());
235 return (InvokeState
*)this;
238 JS::HandleScript
script() const { return script_
; }
240 InterpreterFrame
* pushInterpreterFrame(JSContext
* cx
);
241 inline void setReturnValue(const Value
& v
);
244 RunState(const RunState
& other
) = delete;
245 RunState(const ExecuteState
& other
) = delete;
246 RunState(const InvokeState
& other
) = delete;
247 void operator=(const RunState
& other
) = delete;
250 // Eval or global script.
251 class MOZ_RAII ExecuteState
: public RunState
{
252 HandleObject envChain_
;
254 AbstractFramePtr evalInFrame_
;
255 MutableHandleValue result_
;
258 ExecuteState(JSContext
* cx
, JSScript
* script
, HandleObject envChain
,
259 AbstractFramePtr evalInFrame
, MutableHandleValue result
)
260 : RunState(cx
, Execute
, script
),
262 evalInFrame_(evalInFrame
),
265 JSObject
* environmentChain() const { return envChain_
; }
266 bool isDebuggerEval() const { return !!evalInFrame_
; }
268 InterpreterFrame
* pushInterpreterFrame(JSContext
* cx
);
270 void setReturnValue(const Value
& v
) { result_
.set(v
); }
273 // Data to invoke a function.
274 class MOZ_RAII InvokeState final
: public RunState
{
275 const CallArgs
& args_
;
276 MaybeConstruct construct_
;
279 InvokeState(JSContext
* cx
, const CallArgs
& args
, MaybeConstruct construct
)
280 : RunState(cx
, Invoke
, args
.callee().as
<JSFunction
>().nonLazyScript()),
282 construct_(construct
) {}
284 bool constructing() const { return construct_
; }
285 const CallArgs
& args() const { return args_
; }
287 InterpreterFrame
* pushInterpreterFrame(JSContext
* cx
);
289 void setReturnValue(const Value
& v
) { args_
.rval().set(v
); }
292 inline void RunState::setReturnValue(const Value
& v
) {
294 asInvoke()->setReturnValue(v
);
296 asExecute()->setReturnValue(v
);
300 extern bool RunScript(JSContext
* cx
, RunState
& state
);
301 extern bool Interpret(JSContext
* cx
, RunState
& state
);
303 extern JSType
TypeOfObject(JSObject
* obj
);
305 extern JSType
TypeOfValue(const Value
& v
);
308 // https://www.ecma-international.org/ecma-262/6.0/#sec-instanceofoperator
309 extern bool InstanceofOperator(JSContext
* cx
, HandleObject obj
, HandleValue v
,
312 // Unwind environment chain and iterator to match the scope corresponding to
313 // the given bytecode position.
314 extern void UnwindEnvironment(JSContext
* cx
, EnvironmentIter
& ei
,
317 // Unwind all environments.
318 extern void UnwindAllEnvironmentsInFrame(JSContext
* cx
, EnvironmentIter
& ei
);
320 // Compute the pc needed to unwind the scope to the beginning of the block
321 // pointed to by the try note.
322 extern jsbytecode
* UnwindEnvironmentToTryPc(JSScript
* script
,
327 template <class TryNoteFilter
>
328 class MOZ_STACK_CLASS BaseTryNoteIter
{
330 TryNoteFilter isTryNoteValid_
;
333 const TryNote
* tnEnd_
;
336 for (; tn_
!= tnEnd_
; ++tn_
) {
341 /* Try notes cannot be disjoint. That is, we can't have
342 * multiple notes with disjoint pc ranges jumping to the same
343 * catch block. This interacts awkwardly with for-of loops, in
344 * which calls to IteratorClose emitted due to abnormal
345 * completion (break, throw, return) are emitted inline, at the
346 * source location of the break, throw, or return
347 * statement. For example:
350 * try { return; } catch (e) { }
353 * From the try-note nesting's perspective, the IteratorClose
354 * resulting from |return| is covered by the inner try, when it
355 * should not be. If IteratorClose throws, we don't want to
358 * To make this work, we use TryNoteKind::ForOfIterClose try-notes,
359 * which cover the range of the abnormal completion. When
360 * looking up trynotes, a for-of iterclose note indicates that
361 * the enclosing for-of has just been terminated. As a result,
362 * trynotes within that for-of are no longer active. When we
363 * see a for-of-iterclose, we skip ahead in the trynotes list
364 * until we see the matching for-of.
366 * Breaking out of multiple levels of for-of at once is handled
367 * using nested TryNoteKind::ForOfIterClose try-notes. Consider this
371 * loop: for (i of first) {
373 * for (j of second) {
375 * break loop; // <C1/2>
380 * Here is the mapping from various PCs to try-notes that we
385 * | | | [---|---] ForOfIterClose (outer)
386 * | | [---|------|---] ForOfIterClose (inner)
387 * | [--X-----|------|----] ForOf (inner)
388 * [---X-----------X------|-----] ForOf (outer)
389 * [------------------------X------] TryCatch
391 * - At A, we find the outer for-of.
392 * - At B, we find the inner for-of.
393 * - At C1, we find one TryNoteKind::ForOfIterClose, skip past one
394 * TryNoteKind::ForOf, and find the outer for-of. (This occurs if an
395 * exception is thrown while closing the inner iterator.)
396 * - At C2, we find two TryNoteKind::ForOfIterClose, skip past two
397 * TryNoteKind::ForOf, and reach the outer try-catch. (This occurs if
398 * an exception is thrown while closing the outer iterator.)
400 if (tn_
->kind() == TryNoteKind::ForOfIterClose
) {
401 uint32_t iterCloseDepth
= 1;
404 MOZ_ASSERT(tn_
!= tnEnd_
);
406 if (tn_
->kind() == TryNoteKind::ForOfIterClose
) {
408 } else if (tn_
->kind() == TryNoteKind::ForOf
) {
412 } while (iterCloseDepth
> 0);
414 // Advance to trynote following the enclosing for-of.
419 * We have a note that covers the exception pc but we must check
420 * whether the interpreter has already executed the corresponding
421 * handler. This is possible when the executed bytecode implements
422 * break or return from inside a for-in loop.
424 * In this case the emitter generates additional [enditer] and [goto]
425 * opcodes to close all outstanding iterators and execute the finally
426 * blocks. If such an [enditer] throws an exception, its pc can still
427 * be inside several nested for-in loops and try-finally statements
428 * even if we have already closed the corresponding iterators and
429 * invoked the finally blocks.
431 * To address this, we make [enditer] always decrease the stack even
432 * when its implementation throws an exception. Thus already executed
433 * [enditer] and [goto] opcodes will have try notes with the stack
434 * depth exceeding the current one and this condition is what we use to
437 if (tn_
== tnEnd_
|| isTryNoteValid_(tn_
)) {
444 BaseTryNoteIter(JSScript
* script
, jsbytecode
* pc
,
445 TryNoteFilter isTryNoteValid
)
446 : pcOffset_(script
->pcToOffset(pc
)), isTryNoteValid_(isTryNoteValid
) {
447 // NOTE: The Span is a temporary so we can't use begin()/end()
448 // here or the iterator will outlive the span.
449 auto trynotes
= script
->trynotes();
450 tn_
= trynotes
.data();
451 tnEnd_
= tn_
+ trynotes
.size();
461 bool pcInRange() const {
462 // This checks both ends of the range at once
463 // because unsigned integers wrap on underflow.
464 uint32_t offset
= pcOffset_
;
465 uint32_t start
= tn_
->start
;
466 uint32_t length
= tn_
->length
;
467 return offset
- start
< length
;
469 bool done() const { return tn_
== tnEnd_
; }
470 const TryNote
* operator*() const { return tn_
; }
473 } // namespace detail
475 template <class TryNoteFilter
>
476 class MOZ_STACK_CLASS TryNoteIter
477 : public detail::BaseTryNoteIter
<TryNoteFilter
> {
478 using Base
= detail::BaseTryNoteIter
<TryNoteFilter
>;
480 // Keep the script alive as long as the iterator is live.
481 RootedScript script_
;
484 TryNoteIter(JSContext
* cx
, JSScript
* script
, jsbytecode
* pc
,
485 TryNoteFilter isTryNoteValid
)
486 : Base(script
, pc
, isTryNoteValid
), script_(cx
, script
) {}
489 class NoOpTryNoteFilter
{
491 explicit NoOpTryNoteFilter() = default;
492 bool operator()(const TryNote
*) { return true; }
495 // Iterator over all try notes. Code using this iterator is not allowed to
496 // trigger GC to make sure the script stays alive. See TryNoteIter above for the
498 class MOZ_STACK_CLASS TryNoteIterAllNoGC
499 : public detail::BaseTryNoteIter
<NoOpTryNoteFilter
> {
500 using Base
= detail::BaseTryNoteIter
<NoOpTryNoteFilter
>;
501 JS::AutoCheckCannotGC nogc
;
504 TryNoteIterAllNoGC(JSScript
* script
, jsbytecode
* pc
)
505 : Base(script
, pc
, NoOpTryNoteFilter()) {}
508 bool HandleClosingGeneratorReturn(JSContext
* cx
, AbstractFramePtr frame
,
511 /************************************************************************/
513 bool ThrowOperation(JSContext
* cx
, HandleValue v
);
515 bool GetProperty(JSContext
* cx
, HandleValue value
, Handle
<PropertyName
*> name
,
516 MutableHandleValue vp
);
518 JSObject
* Lambda(JSContext
* cx
, HandleFunction fun
, HandleObject parent
);
520 bool SetObjectElement(JSContext
* cx
, HandleObject obj
, HandleValue index
,
521 HandleValue value
, bool strict
);
523 bool SetObjectElementWithReceiver(JSContext
* cx
, HandleObject obj
,
524 HandleValue index
, HandleValue value
,
525 HandleValue receiver
, bool strict
);
527 bool AddValues(JSContext
* cx
, MutableHandleValue lhs
, MutableHandleValue rhs
,
528 MutableHandleValue res
);
530 bool SubValues(JSContext
* cx
, MutableHandleValue lhs
, MutableHandleValue rhs
,
531 MutableHandleValue res
);
533 bool MulValues(JSContext
* cx
, MutableHandleValue lhs
, MutableHandleValue rhs
,
534 MutableHandleValue res
);
536 bool DivValues(JSContext
* cx
, MutableHandleValue lhs
, MutableHandleValue rhs
,
537 MutableHandleValue res
);
539 bool ModValues(JSContext
* cx
, MutableHandleValue lhs
, MutableHandleValue rhs
,
540 MutableHandleValue res
);
542 bool PowValues(JSContext
* cx
, MutableHandleValue lhs
, MutableHandleValue rhs
,
543 MutableHandleValue res
);
545 bool BitNot(JSContext
* cx
, MutableHandleValue in
, MutableHandleValue res
);
547 bool BitXor(JSContext
* cx
, MutableHandleValue lhs
, MutableHandleValue rhs
,
548 MutableHandleValue res
);
550 bool BitOr(JSContext
* cx
, MutableHandleValue lhs
, MutableHandleValue rhs
,
551 MutableHandleValue res
);
553 bool BitAnd(JSContext
* cx
, MutableHandleValue lhs
, MutableHandleValue rhs
,
554 MutableHandleValue res
);
556 bool BitLsh(JSContext
* cx
, MutableHandleValue lhs
, MutableHandleValue rhs
,
557 MutableHandleValue res
);
559 bool BitRsh(JSContext
* cx
, MutableHandleValue lhs
, MutableHandleValue rhs
,
560 MutableHandleValue res
);
562 bool UrshValues(JSContext
* cx
, MutableHandleValue lhs
, MutableHandleValue rhs
,
563 MutableHandleValue res
);
565 bool LessThan(JSContext
* cx
, MutableHandleValue lhs
, MutableHandleValue rhs
,
568 bool LessThanOrEqual(JSContext
* cx
, MutableHandleValue lhs
,
569 MutableHandleValue rhs
, bool* res
);
571 bool GreaterThan(JSContext
* cx
, MutableHandleValue lhs
, MutableHandleValue rhs
,
574 bool GreaterThanOrEqual(JSContext
* cx
, MutableHandleValue lhs
,
575 MutableHandleValue rhs
, bool* res
);
577 bool AtomicIsLockFree(JSContext
* cx
, HandleValue in
, int* out
);
579 template <bool strict
>
580 bool DelPropOperation(JSContext
* cx
, HandleValue val
,
581 Handle
<PropertyName
*> name
, bool* res
);
583 template <bool strict
>
584 bool DelElemOperation(JSContext
* cx
, HandleValue val
, HandleValue index
,
587 JSObject
* BindVarOperation(JSContext
* cx
, JSObject
* envChain
);
589 JSObject
* ImportMetaOperation(JSContext
* cx
, HandleScript script
);
591 JSObject
* BuiltinObjectOperation(JSContext
* cx
, BuiltinObjectKind kind
);
593 bool ThrowMsgOperation(JSContext
* cx
, const unsigned throwMsgKind
);
595 bool GetAndClearException(JSContext
* cx
, MutableHandleValue res
);
597 bool GetAndClearExceptionAndStack(JSContext
* cx
, MutableHandleValue res
,
598 MutableHandle
<SavedFrame
*> stack
);
600 bool DeleteNameOperation(JSContext
* cx
, Handle
<PropertyName
*> name
,
601 HandleObject scopeObj
, MutableHandleValue res
);
603 bool ImplicitThisOperation(JSContext
* cx
, HandleObject scopeObj
,
604 Handle
<PropertyName
*> name
, MutableHandleValue res
);
606 bool InitPropGetterSetterOperation(JSContext
* cx
, jsbytecode
* pc
,
607 HandleObject obj
, Handle
<PropertyName
*> name
,
610 unsigned GetInitDataPropAttrs(JSOp op
);
612 bool EnterWithOperation(JSContext
* cx
, AbstractFramePtr frame
, HandleValue val
,
613 Handle
<WithScope
*> scope
);
615 bool InitElemGetterSetterOperation(JSContext
* cx
, jsbytecode
* pc
,
616 HandleObject obj
, HandleValue idval
,
619 bool SpreadCallOperation(JSContext
* cx
, HandleScript script
, jsbytecode
* pc
,
620 HandleValue thisv
, HandleValue callee
, HandleValue arr
,
621 HandleValue newTarget
, MutableHandleValue res
);
623 bool OptimizeSpreadCall(JSContext
* cx
, HandleValue arg
,
624 MutableHandleValue result
);
626 bool OptimizeGetIterator(JSContext
* cx
, HandleValue arg
, bool* result
);
628 ArrayObject
* ArrayFromArgumentsObject(JSContext
* cx
,
629 Handle
<ArgumentsObject
*> args
);
631 JSObject
* NewObjectOperation(JSContext
* cx
, HandleScript script
,
632 const jsbytecode
* pc
);
634 JSObject
* NewPlainObjectBaselineFallback(JSContext
* cx
,
635 Handle
<SharedShape
*> shape
,
636 gc::AllocKind allocKind
,
637 gc::AllocSite
* site
);
639 JSObject
* NewPlainObjectOptimizedFallback(JSContext
* cx
,
640 Handle
<SharedShape
*> shape
,
641 gc::AllocKind allocKind
,
642 gc::Heap initialHeap
);
644 ArrayObject
* NewArrayOperation(JSContext
* cx
, uint32_t length
,
645 NewObjectKind newKind
= GenericObject
);
647 // Called from JIT code when inline array allocation fails.
648 ArrayObject
* NewArrayObjectBaselineFallback(JSContext
* cx
, uint32_t length
,
649 gc::AllocKind allocKind
,
650 gc::AllocSite
* site
);
651 ArrayObject
* NewArrayObjectOptimizedFallback(JSContext
* cx
, uint32_t length
,
652 gc::AllocKind allocKind
,
653 NewObjectKind newKind
);
655 [[nodiscard
]] bool GetImportOperation(JSContext
* cx
, HandleObject envChain
,
656 HandleScript script
, jsbytecode
* pc
,
657 MutableHandleValue vp
);
659 void ReportRuntimeLexicalError(JSContext
* cx
, unsigned errorNumber
,
662 void ReportRuntimeLexicalError(JSContext
* cx
, unsigned errorNumber
,
663 Handle
<PropertyName
*> name
);
665 void ReportRuntimeLexicalError(JSContext
* cx
, unsigned errorNumber
,
666 HandleScript script
, jsbytecode
* pc
);
668 void ReportInNotObjectError(JSContext
* cx
, HandleValue lref
, HandleValue rref
);
670 // The parser only reports redeclarations that occurs within a single
671 // script. Due to the extensibility of the global lexical scope, we also check
672 // for redeclarations during runtime in JSOp::GlobalOrEvalDeclInstantation.
673 void ReportRuntimeRedeclaration(JSContext
* cx
, Handle
<PropertyName
*> name
,
674 const char* redeclKind
);
676 bool ThrowCheckIsObject(JSContext
* cx
, CheckIsObjectKind kind
);
678 bool ThrowUninitializedThis(JSContext
* cx
);
680 bool ThrowInitializedThis(JSContext
* cx
);
682 bool ThrowObjectCoercible(JSContext
* cx
, HandleValue value
);
684 bool DefaultClassConstructor(JSContext
* cx
, unsigned argc
, Value
* vp
);
686 bool Debug_CheckSelfHosted(JSContext
* cx
, HandleValue funVal
);
688 bool CheckClassHeritageOperation(JSContext
* cx
, HandleValue heritage
);
690 PlainObject
* ObjectWithProtoOperation(JSContext
* cx
, HandleValue proto
);
692 JSObject
* FunWithProtoOperation(JSContext
* cx
, HandleFunction fun
,
693 HandleObject parent
, HandleObject proto
);
695 bool SetPropertySuper(JSContext
* cx
, HandleValue lval
, HandleValue receiver
,
696 Handle
<PropertyName
*> name
, HandleValue rval
,
699 bool SetElementSuper(JSContext
* cx
, HandleValue lval
, HandleValue receiver
,
700 HandleValue index
, HandleValue rval
, bool strict
);
702 bool LoadAliasedDebugVar(JSContext
* cx
, JSObject
* env
, jsbytecode
* pc
,
703 MutableHandleValue result
);
705 bool CloseIterOperation(JSContext
* cx
, HandleObject iter
, CompletionKind kind
);
708 #endif /* vm_Interpreter_h */