Bug 1865597 - Add error checking when initializing parallel marking and disable on...
[gecko.git] / js / src / vm / Interpreter.h
blob7250e7957dbbb809f2f664886309e99f13e554bc
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.
14 #include "jspubtd.h"
16 #include "vm/BuiltinObjectKind.h"
17 #include "vm/CheckIsObjectKind.h" // CheckIsObjectKind
18 #include "vm/Stack.h"
20 namespace js {
22 class WithScope;
23 class EnvironmentIter;
24 class PlainObject;
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,
47 int numToSkip = -1,
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
53 // the interpreter.
54 enum class CallReason {
55 Call,
56 // callContentFunction or constructContentFunction in self-hosted JS.
57 CallContent,
58 // Function.prototype.call or Function.prototype.apply.
59 FunCall,
60 Getter,
61 Setter,
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,
84 HandleValue rval);
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
91 // initialized.
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);
115 args[0].set(arg0);
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);
123 args[0].set(arg0);
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);
130 args[0].set(arg0);
131 args[1].set(arg1);
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);
139 args[0].set(arg0);
140 args[1].set(arg1);
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,
190 HandleValue thisv,
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);
209 class ExecuteState;
210 class InvokeState;
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 {
216 protected:
217 enum Kind { Execute, Invoke };
218 Kind kind_;
220 RootedScript script_;
222 explicit RunState(JSContext* cx, Kind kind, JSScript* script)
223 : kind_(kind), script_(cx, script) {}
225 public:
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);
243 private:
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_;
257 public:
258 ExecuteState(JSContext* cx, JSScript* script, HandleObject envChain,
259 AbstractFramePtr evalInFrame, MutableHandleValue result)
260 : RunState(cx, Execute, script),
261 envChain_(envChain),
262 evalInFrame_(evalInFrame),
263 result_(result) {}
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_;
278 public:
279 InvokeState(JSContext* cx, const CallArgs& args, MaybeConstruct construct)
280 : RunState(cx, Invoke, args.callee().as<JSFunction>().nonLazyScript()),
281 args_(args),
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) {
293 if (isInvoke()) {
294 asInvoke()->setReturnValue(v);
295 } else {
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);
307 // Implementation of
308 // https://www.ecma-international.org/ecma-262/6.0/#sec-instanceofoperator
309 extern bool InstanceofOperator(JSContext* cx, HandleObject obj, HandleValue v,
310 bool* bp);
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,
315 jsbytecode* pc);
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,
323 const TryNote* tn);
325 namespace detail {
327 template <class TryNoteFilter>
328 class MOZ_STACK_CLASS BaseTryNoteIter {
329 uint32_t pcOffset_;
330 TryNoteFilter isTryNoteValid_;
332 const TryNote* tn_;
333 const TryNote* tnEnd_;
335 void settle() {
336 for (; tn_ != tnEnd_; ++tn_) {
337 if (!pcInRange()) {
338 continue;
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:
349 * for (x of iter) {
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
356 * catch it here.
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
368 * code:
370 * try {
371 * loop: for (i of first) {
372 * <A>
373 * for (j of second) {
374 * <B>
375 * break loop; // <C1/2>
378 * } catch {...}
380 * Here is the mapping from various PCs to try-notes that we
381 * want to return:
383 * A B C1 C2
384 * | | | |
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;
402 do {
403 ++tn_;
404 MOZ_ASSERT(tn_ != tnEnd_);
405 if (pcInRange()) {
406 if (tn_->kind() == TryNoteKind::ForOfIterClose) {
407 iterCloseDepth++;
408 } else if (tn_->kind() == TryNoteKind::ForOf) {
409 iterCloseDepth--;
412 } while (iterCloseDepth > 0);
414 // Advance to trynote following the enclosing for-of.
415 continue;
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
435 * filter them out.
437 if (tn_ == tnEnd_ || isTryNoteValid_(tn_)) {
438 return;
443 public:
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();
453 settle();
456 void operator++() {
457 ++tn_;
458 settle();
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_;
483 public:
484 TryNoteIter(JSContext* cx, JSScript* script, jsbytecode* pc,
485 TryNoteFilter isTryNoteValid)
486 : Base(script, pc, isTryNoteValid), script_(cx, script) {}
489 class NoOpTryNoteFilter {
490 public:
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
497 // can-GC version.
498 class MOZ_STACK_CLASS TryNoteIterAllNoGC
499 : public detail::BaseTryNoteIter<NoOpTryNoteFilter> {
500 using Base = detail::BaseTryNoteIter<NoOpTryNoteFilter>;
501 JS::AutoCheckCannotGC nogc;
503 public:
504 TryNoteIterAllNoGC(JSScript* script, jsbytecode* pc)
505 : Base(script, pc, NoOpTryNoteFilter()) {}
508 bool HandleClosingGeneratorReturn(JSContext* cx, AbstractFramePtr frame,
509 bool ok);
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,
566 bool* res);
568 bool LessThanOrEqual(JSContext* cx, MutableHandleValue lhs,
569 MutableHandleValue rhs, bool* res);
571 bool GreaterThan(JSContext* cx, MutableHandleValue lhs, MutableHandleValue rhs,
572 bool* res);
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,
585 bool* res);
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,
608 HandleObject val);
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,
617 HandleObject val);
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,
660 HandleId id);
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,
697 bool strict);
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);
706 } /* namespace js */
708 #endif /* vm_Interpreter_h */