diff options
| author | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:40:17 -0500 |
|---|---|---|
| committer | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:40:17 -0500 |
| commit | 33058f2b292b3a581333bdfb21b8f671898c5060 (patch) | |
| tree | 51c3e392513ec574331b2d3f85c394445ea803c6 /files/ja/mozilla/projects/spidermonkey/internals | |
| parent | 8b66d724f7caf0157093fb09cfec8fbd0c6ad50a (diff) | |
| download | translated-content-33058f2b292b3a581333bdfb21b8f671898c5060.tar.gz translated-content-33058f2b292b3a581333bdfb21b8f671898c5060.tar.bz2 translated-content-33058f2b292b3a581333bdfb21b8f671898c5060.zip | |
initial commit
Diffstat (limited to 'files/ja/mozilla/projects/spidermonkey/internals')
4 files changed, 7332 insertions, 0 deletions
diff --git a/files/ja/mozilla/projects/spidermonkey/internals/bytecode/index.html b/files/ja/mozilla/projects/spidermonkey/internals/bytecode/index.html new file mode 100644 index 0000000000..f4e65a7748 --- /dev/null +++ b/files/ja/mozilla/projects/spidermonkey/internals/bytecode/index.html @@ -0,0 +1,6855 @@ +--- +title: バイトコードの説明 +slug: Mozilla/Projects/SpiderMonkey/Internals/Bytecode +tags: + - SpiderMonkey +translation_of: Mozilla/Projects/SpiderMonkey/Internals/Bytecode +--- +<div>{{SpiderMonkeySidebar("Internals")}}</div> + +<h2 id="バイトコード一覧">バイトコード一覧</h2> + +<p>この文書は <a href="http://dxr.mozilla.org/mozilla-central/source/js/src/vm/make_opcode_doc.py">make_opcode_doc.py</a> によって <a href="http://dxr.mozilla.org/mozilla-central/source/js/src/vm/Opcodes.h">Opcodes.h</a> から自動的に生成されます。</p> + +<h3 id="ステートメント">ステートメント</h3> + +<h4 id="Jumps">Jumps</h4> + +<dl> + <dt id="JSOP_AND">JSOP_AND [-1, +1] (JUMP, DETECTING, IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>69 (0x45)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>int32_t offset</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>cond</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>cond</code></td> + </tr> + </tbody> + </table> + + <p>スタックの先頭の値をブール値に変換し、結果が <code>false</code> の場合、現在のバイトコードから 32-bit のオフセットにジャンプします。</p> + </dd> + <dt id="JSOP_GOTO">JSOP_GOTO [-0, +0] (JUMP)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>6 (0x06)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>int32_t offset</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code> </code></td> + </tr> + </tbody> + </table> + + <p>現在のバイトコードから 32-bit のオフセットにジャンプします。</p> + </dd> + <dt id="JSOP_IFEQ">JSOP_IFEQ [-1, +0] (JUMP, DETECTING, IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>7 (0x07)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>int32_t offset</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>cond</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code> </code></td> + </tr> + </tbody> + </table> + + <p>Pops the top of stack value, converts it into a boolean, if the result is <code>false</code>, jumps to a 32-bit offset from the current bytecode.</p> + + <p>The idea is that a sequence like <code>JSOP_ZERO</code>; <code>JSOP_ZERO</code>; <code>JSOP_EQ</code>; <code>JSOP_IFEQ</code>; <code>JSOP_RETURN</code>; reads like a nice linear sequence that will execute the return.</p> + </dd> + <dt id="JSOP_IFNE">JSOP_IFNE [-1, +0] (JUMP, IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>8 (0x08)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>int32_t offset</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>cond</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code> </code></td> + </tr> + </tbody> + </table> + + <p>Pops the top of stack value, converts it into a boolean, if the result is <code>true</code>, jumps to a 32-bit offset from the current bytecode.</p> + </dd> + <dt id="JSOP_LABEL">JSOP_LABEL [-0, +0] (CODE_OFFSET)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>106 (0x6a)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>int32_t offset</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code> </code></td> + </tr> + </tbody> + </table> + + <p>This opcode precedes every labeled statement. It's a no-op.</p> + + <p><code>offset</code> is the offset to the next instruction after this statement, the one <code>break LABEL;</code> would jump to. IonMonkey uses this.</p> + </dd> + <dt id="JSOP_LOOPENTRY">JSOP_LOOPENTRY [-0, +0] (LOOPENTRY, IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>227 (0xe3)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint32_t icIndex, uint8_t BITFIELD</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>6</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code> </code></td> + </tr> + </tbody> + </table> + + <p>This opcode is the target of the entry jump for some loop. The uint8 argument is a bitfield. The lower 7 bits of the argument indicate the loop depth. This value starts at 1 and is just a hint: deeply nested loops all have the same value. The upper bit is set if Ion should be able to OSR at this point, which is true unless there is non-loop state on the stack. See <code>JSOP_JUMPTARGET</code> for the icIndex argument.</p> + </dd> + <dt id="JSOP_LOOPHEAD">JSOP_LOOPHEAD [-0, +0] (ICINDEX)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>109 (0x6d)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint32_t icIndex</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code> </code></td> + </tr> + </tbody> + </table> + + <p>Another no-op.</p> + + <p>This opcode is the target of the backwards jump for some loop. See <code>JSOP_JUMPTARGET</code> for the icIndex operand.</p> + </dd> + <dt id="JSOP_OR">JSOP_OR [-1, +1] (JUMP, DETECTING, IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>68 (0x44)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>int32_t offset</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>cond</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>cond</code></td> + </tr> + </tbody> + </table> + + <p>Converts the top of stack value into a boolean, if the result is <code>true</code>, jumps to a 32-bit offset from the current bytecode.</p> + </dd> +</dl> + +<h4 id="Switch_Statement">Switch Statement</h4> + +<dl> + <dt id="JSOP_CASE">JSOP_CASE [-2, +1] (JUMP)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>121 (0x79)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>int32_t offset</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>val, cond</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>val(if !cond)</code></td> + </tr> + </tbody> + </table> + + <p>Pops the top two values on the stack as <code>val</code> and <code>cond</code>. If <code>cond</code> is <code>true</code>, jumps to a 32-bit offset from the current bytecode, re-pushes <code>val</code> onto the stack if <code>false</code>.</p> + </dd> + <dt id="JSOP_CONDSWITCH">JSOP_CONDSWITCH [-0, +0]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>120 (0x78)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code> </code></td> + </tr> + </tbody> + </table> + + <p>This no-op appears after the bytecode for EXPR in <code>switch (EXPR) {...}</code> if the switch cannot be optimized using <code>JSOP_TABLESWITCH</code>.</p> + + <p>For a non-optimized switch statement like this:</p> + + <pre class="notranslate"> switch (EXPR) { + case V0: + C0; + ... + default: + D; + } +</pre> + + <p>the bytecode looks like this:</p> + + <pre class="notranslate"> (EXPR) + condswitch + (V0) + case ->C0 + ... + default ->D + (C0) + ... + (D) +</pre> + + <p>Note that code for all case-labels is emitted first, then code for the body of each case clause.</p> + </dd> + <dt id="JSOP_DEFAULT">JSOP_DEFAULT [-1, +0] (JUMP)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>122 (0x7a)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>int32_t offset</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>lval</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code> </code></td> + </tr> + </tbody> + </table> + + <p>This appears after all cases in a <code>JSOP_CONDSWITCH</code>, whether there is a <code>default:</code> label in the switch statement or not. Pop the switch operand from the stack and jump to a 32-bit offset from the current bytecode. offset from the current bytecode.</p> + </dd> + <dt id="JSOP_TABLESWITCH">JSOP_TABLESWITCH [-1, +0] (TABLESWITCH, DETECTING)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>70 (0x46)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>int32_t len, int32_t low, int32_t high,uint24_t firstResumeIndex</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>len</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>i</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code> </code></td> + </tr> + </tbody> + </table> + + <p>Pops the top of stack value as <code>i</code>, if <code>low <= i <= high</code>, jumps to a 32-bit offset: offset is stored in the script's resumeOffsets</p> + + <pre class="notranslate"> list at index 'firstResumeIndex + (i - low)' +</pre> + + <p>jumps to a 32-bit offset: <code>len</code> from the current bytecode otherwise</p> + </dd> +</dl> + +<h4 id="For-In_Statement">For-In Statement</h4> + +<dl> + <dt id="JSOP_ENDITER">JSOP_ENDITER [-1, +0]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>78 (0x4e)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>iter</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code> </code></td> + </tr> + </tbody> + </table> + + <p>Exits a for-in loop by popping the iterator object from the stack and closing it.</p> + </dd> + <dt id="JSOP_ISGENCLOSING">JSOP_ISGENCLOSING [-1, +2]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>187 (0xbb)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>val</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>val, res</code></td> + </tr> + </tbody> + </table> + + <p>Pushes a boolean indicating whether the top of the stack is MagicValue(<code>JS_GENERATOR_CLOSING</code>).</p> + </dd> + <dt id="JSOP_ISNOITER">JSOP_ISNOITER [-1, +2]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>77 (0x4d)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>val</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>val, res</code></td> + </tr> + </tbody> + </table> + + <p>Pushes a boolean indicating whether the value on top of the stack is MagicValue(<code>JS_NO_ITER_VALUE</code>).</p> + </dd> + <dt id="JSOP_ITER">JSOP_ITER [-1, +1] (IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>75 (0x4b)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>val</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>iter</code></td> + </tr> + </tbody> + </table> + + <p>Sets up a for-in loop. It pops the top of stack value as <code>val</code> and pushes <code>iter</code> which is an iterator for <code>val</code>.</p> + </dd> + <dt id="JSOP_MOREITER">JSOP_MOREITER [-1, +2]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>76 (0x4c)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>iter</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>iter, val</code></td> + </tr> + </tbody> + </table> + + <p>Pushes the next iterated value onto the stack. If no value is available, MagicValue(<code>JS_NO_ITER_VALUE</code>) is pushed.</p> + </dd> +</dl> + +<h4 id="With_Statement">With Statement</h4> + +<dl> + <dt id="JSOP_ENTERWITH">JSOP_ENTERWITH [-1, +0] (SCOPE)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>3 (0x03)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint32_t staticWithIndex</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>val</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code> </code></td> + </tr> + </tbody> + </table> + + <p>Pops the top of stack value, converts it to an object, and adds a <code>WithEnvironmentObject</code> wrapping that object to the environment chain.</p> + + <p>There is a matching <code>JSOP_LEAVEWITH</code> instruction later. All name lookups between the two that may need to consult the With object are deoptimized.</p> + </dd> + <dt id="JSOP_LEAVEWITH">JSOP_LEAVEWITH [-0, +0]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>4 (0x04)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code> </code></td> + </tr> + </tbody> + </table> + + <p>Pops the environment chain object pushed by <code>JSOP_ENTERWITH</code>.</p> + </dd> +</dl> + +<h4 id="Exception_Handling">Exception Handling</h4> + +<dl> + <dt id="JSOP_EXCEPTION">JSOP_EXCEPTION [-0, +1]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>118 (0x76)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>exception</code></td> + </tr> + </tbody> + </table> + + <p>Pushes the current pending exception onto the stack and clears the pending exception. This is only emitted at the beginning of code for a catch-block, so it is known that an exception is pending. It is used to implement catch-blocks and <code>yield*</code>.</p> + </dd> + <dt id="JSOP_FINALLY">JSOP_FINALLY [-0, +2]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>135 (0x87)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>false, resumeIndex</code></td> + </tr> + </tbody> + </table> + + <p>This opcode has a def count of 2, but these values are already on the stack (they're pushed by <code>JSOP_GOSUB</code>).</p> + </dd> + <dt id="JSOP_GOSUB">JSOP_GOSUB [-2, +0] (JUMP)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>116 (0x74)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>int32_t offset</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>false, resumeIndex</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code> </code></td> + </tr> + </tbody> + </table> + + <p>This opcode is used for entering a <code>finally</code> block. Jumps to a 32-bit offset from the current pc.</p> + + <p>Note: this op doesn't actually push/pop any values, but it has a use count of 2 (for the <code>false</code> + resumeIndex values pushed by preceding bytecode ops) because the <code>finally</code> entry point does not expect these values on the stack. See also <code>JSOP_FINALLY</code> (it has a def count of 2).</p> + + <p>When the execution resumes from <code>finally</code> block, those stack values are popped.</p> + </dd> + <dt id="JSOP_RETSUB">JSOP_RETSUB [-2, +0]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>117 (0x75)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>lval, rval</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code> </code></td> + </tr> + </tbody> + </table> + + <p>This opcode is used for returning from a <code>finally</code> block.</p> + + <p>Pops the top two values on the stack as <code>rval</code> and <code>lval</code>. Then: - If <code>lval</code> is true, throws <code>rval</code>. - If <code>lval</code> is false, jumps to the resumeIndex stored in <code>lval</code>.</p> + </dd> + <dt id="JSOP_THROW">JSOP_THROW [-1, +0]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>112 (0x70)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>v</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code> </code></td> + </tr> + </tbody> + </table> + + <p>Pops the top of stack value as <code>v</code>, sets pending exception as <code>v</code>, then raises error.</p> + </dd> + <dt id="JSOP_THROWMSG">JSOP_THROWMSG [-0, +0] (UINT16)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>74 (0x4a)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint16_t msgNumber</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>3</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code> </code></td> + </tr> + </tbody> + </table> + + <p>Sometimes we know when emitting that an operation will always throw.</p> + + <p>Throws the indicated <code>JSMSG</code>.</p> + </dd> + <dt id="JSOP_TRY">JSOP_TRY [-0, +0]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>134 (0x86)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code> </code></td> + </tr> + </tbody> + </table> + + <p>This no-op appears at the top of the bytecode for a <code>TryStatement</code>.</p> + + <p>Location information for catch/finally blocks is stored in a side table, <code>script->trynotes()</code>.</p> + </dd> +</dl> + +<h4 id="Function">Function</h4> + +<dl> + <dt id="JSOP_CALL">JSOP_CALL [-(argc+2), +1] (ARGC, INVOKE, TYPESET, IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>58 (0x3a)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint16_t argc</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>3</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>callee, this, args[0], ..., args[argc-1]</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>rval</code></td> + </tr> + </tbody> + </table> + + <p>Invokes <code>callee</code> with <code>this</code> and <code>args</code>, pushes return value onto the stack.</p> + </dd> + <dt id="JSOP_CALLITER">JSOP_CALLITER [-2, +1] (ARGC, INVOKE, TYPESET, IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>145 (0x91)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint16_t argc (must be 0)</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>3</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>callee, this</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>rval</code></td> + </tr> + </tbody> + </table> + + <p>Like <code>JSOP_CALL</code>, but used as part of for-of and destructuring bytecode to provide better error messages.</p> + </dd> + <dt id="JSOP_CALL_IGNORES_RV">JSOP_CALL_IGNORES_RV [-(argc+2), +1] (ARGC, INVOKE, TYPESET, IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>231 (0xe7)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint16_t argc</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>3</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>callee, this, args[0], ..., args[argc-1]</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>rval</code></td> + </tr> + </tbody> + </table> + + <p>Like <code>JSOP_CALL</code>, but tells the function that the return value is ignored. stack.</p> + </dd> + <dt id="JSOP_CHECKISCALLABLE">JSOP_CHECKISCALLABLE [-1, +1] (UINT8)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>219 (0xdb)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint8_t kind</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>2</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>obj</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>obj</code></td> + </tr> + </tbody> + </table> + + <p>Checks that the top value on the stack is callable, and throws a TypeError if not. The operand <code>kind</code> is used only to generate an appropriate error message.</p> + </dd> + <dt id="JSOP_EVAL">JSOP_EVAL [-(argc+2), +1] (ARGC, INVOKE, TYPESET, CHECKSLOPPY, IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>123 (0x7b)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint16_t argc</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>3</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>callee, this, args[0], ..., args[argc-1]</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>rval</code></td> + </tr> + </tbody> + </table> + + <p>Invokes <code>eval</code> with <code>args</code> and pushes return value onto the stack.</p> + + <p>If <code>eval</code> in global scope is not original one, invokes the function with <code>this</code> and <code>args</code>, and pushes return value onto the stack.</p> + </dd> + <dt id="JSOP_FUNAPPLY">JSOP_FUNAPPLY [-(argc+2), +1] (ARGC, INVOKE, TYPESET, IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>79 (0x4f)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint16_t argc</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>3</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>callee, this, args[0], ..., args[argc-1]</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>rval</code></td> + </tr> + </tbody> + </table> + + <p>Invokes <code>callee</code> with <code>this</code> and <code>args</code>, pushes return value onto the stack.</p> + + <p>This is for <code>f.apply</code>.</p> + </dd> + <dt id="JSOP_FUNCALL">JSOP_FUNCALL [-(argc+2), +1] (ARGC, INVOKE, TYPESET, IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>108 (0x6c)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint16_t argc</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>3</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>callee, this, args[0], ..., args[argc-1]</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>rval</code></td> + </tr> + </tbody> + </table> + + <p>Invokes <code>callee</code> with <code>this</code> and <code>args</code>, pushes return value onto the stack.</p> + + <p>If <code>callee</code> is determined to be the canonical <code>Function.prototype.call</code> function, then this operation is optimized to directly call <code>callee</code> with <code>args[0]</code> as <code>this</code>, and the remaining arguments as formal args to <code>callee</code>.</p> + + <p>Like <code>JSOP_FUNAPPLY</code> but for <code>f.call</code> instead of <code>f.apply</code>.</p> + </dd> + <dt id="JSOP_FUNWITHPROTO">JSOP_FUNWITHPROTO [-1, +1] (OBJECT)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>52 (0x34)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint32_t funcIndex</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>proto</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>obj</code></td> + </tr> + </tbody> + </table> + + <p>Pushes a clone of a function with a given [[Prototype]] onto the stack.</p> + </dd> + <dt id="JSOP_GETRVAL">JSOP_GETRVAL [-0, +1]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>2 (0x02)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>rval</code></td> + </tr> + </tbody> + </table> + + <p>Pushes stack frame's <code>rval</code> onto the stack.</p> + </dd> + <dt id="JSOP_LAMBDA">JSOP_LAMBDA [-0, +1] (OBJECT)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>130 (0x82)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint32_t funcIndex</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>obj</code></td> + </tr> + </tbody> + </table> + + <p>Pushes a closure for a named or anonymous function expression onto the stack.</p> + </dd> + <dt id="JSOP_LAMBDA_ARROW">JSOP_LAMBDA_ARROW [-1, +1] (OBJECT)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>131 (0x83)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint32_t funcIndex</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>new.target</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>obj</code></td> + </tr> + </tbody> + </table> + + <p>Pops the top of stack value as <code>new.target</code>, pushes an arrow function with lexical <code>new.target</code> onto the stack.</p> + </dd> + <dt id="JSOP_NEW">JSOP_NEW [-(argc+3), +1] (ARGC, INVOKE, TYPESET, IC, IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>82 (0x52)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint16_t argc</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>3</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>callee, this, args[0], ..., args[argc-1], newTarget</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>rval</code></td> + </tr> + </tbody> + </table> + + <p>Invokes <code>callee</code> as a constructor with <code>this</code> and <code>args</code>, pushes return value onto the stack.</p> + </dd> + <dt id="JSOP_OPTIMIZE_SPREADCALL">JSOP_OPTIMIZE_SPREADCALL [-1, +2]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>178 (0xb2)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>arr</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>arr, optimized</code></td> + </tr> + </tbody> + </table> + + <p>Pops the top stack value, pushes the value and a boolean value that indicates whether the spread operation for the value can be optimized in spread call.</p> + </dd> + <dt id="JSOP_RETRVAL">JSOP_RETRVAL [-0, +0]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>153 (0x99)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code> </code></td> + </tr> + </tbody> + </table> + + <p>Stops interpretation and returns value set by <code>JSOP_SETRVAL</code>. When not set, returns <code>undefined</code>.</p> + + <p>Also emitted at end of script so interpreter don't need to check if opcode is still in script range.</p> + </dd> + <dt id="JSOP_RETURN">JSOP_RETURN [-1, +0]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>5 (0x05)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>rval</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code> </code></td> + </tr> + </tbody> + </table> + + <p>Pops the top of stack value as <code>rval</code>, stops interpretation of current script and returns <code>rval</code>.</p> + </dd> + <dt id="JSOP_SETFUNNAME">JSOP_SETFUNNAME [-2, +1] (UINT8)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>182 (0xb6)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint8_t prefixKind</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>2</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>fun, name</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>fun</code></td> + </tr> + </tbody> + </table> + + <p>Pops the top two values on the stack as <code>name</code> and <code>fun</code>, defines the name of <code>fun</code> to <code>name</code> with prefix if any, and pushes <code>fun</code> back onto the stack.</p> + </dd> + <dt id="JSOP_SETRVAL">JSOP_SETRVAL [-1, +0]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>152 (0x98)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>rval</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code> </code></td> + </tr> + </tbody> + </table> + + <p>Pops the top of stack value as <code>rval</code>, sets the return value in stack frame as <code>rval</code>.</p> + </dd> + <dt id="JSOP_SPREADCALL">JSOP_SPREADCALL [-3, +1] (INVOKE, TYPESET, IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>41 (0x29)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>callee, this, args</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>rval</code></td> + </tr> + </tbody> + </table> + + <p>spreadcall variant of <code>JSOP_CALL</code>.</p> + + <p>Invokes <code>callee</code> with <code>this</code> and <code>args</code>, pushes the return value onto the stack.</p> + + <p><code>args</code> is an Array object which contains actual arguments.</p> + </dd> + <dt id="JSOP_SPREADEVAL">JSOP_SPREADEVAL [-3, +1] (INVOKE, TYPESET, CHECKSLOPPY, IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>43 (0x2b)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>callee, this, args</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>rval</code></td> + </tr> + </tbody> + </table> + + <p>spreadcall variant of <code>JSOP_EVAL</code></p> + + <p>Invokes <code>eval</code> with <code>args</code> and pushes the return value onto the stack.</p> + + <p>If <code>eval</code> in global scope is not original one, invokes the function with <code>this</code> and <code>args</code>, and pushes return value onto the stack.</p> + </dd> + <dt id="JSOP_SPREADNEW">JSOP_SPREADNEW [-4, +1] (INVOKE, TYPESET, IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>42 (0x2a)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>callee, this, args, newTarget</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>rval</code></td> + </tr> + </tbody> + </table> + + <p>spreadcall variant of <code>JSOP_NEW</code></p> + + <p>Invokes <code>callee</code> as a constructor with <code>this</code> and <code>args</code>, pushes the return value onto the stack.</p> + </dd> + <dt id="JSOP_SPREADSUPERCALL">JSOP_SPREADSUPERCALL [-4, +1] (INVOKE, TYPESET, IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>166 (0xa6)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>callee, this, args, newTarget</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>rval</code></td> + </tr> + </tbody> + </table> + + <p>spreadcall variant of <code>JSOP_SUPERCALL</code>.</p> + + <p>Behaves exactly like <code>JSOP_SPREADNEW</code>.</p> + </dd> + <dt id="JSOP_STRICTEVAL">JSOP_STRICTEVAL [-(argc+2), +1] (ARGC, INVOKE, TYPESET, CHECKSTRICT, IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>124 (0x7c)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint16_t argc</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>3</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>callee, this, args[0], ..., args[argc-1]</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>rval</code></td> + </tr> + </tbody> + </table> + + <p>Invokes <code>eval</code> with <code>args</code> and pushes return value onto the stack.</p> + + <p>If <code>eval</code> in global scope is not original one, invokes the function with <code>this</code> and <code>args</code>, and pushes return value onto the stack.</p> + </dd> + <dt id="JSOP_STRICTSPREADEVAL">JSOP_STRICTSPREADEVAL [-3, +1] (INVOKE, TYPESET, CHECKSTRICT, IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>50 (0x32)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>callee, this, args</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>rval</code></td> + </tr> + </tbody> + </table> + + <p>spreadcall variant of <code>JSOP_EVAL</code></p> + + <p>Invokes <code>eval</code> with <code>args</code> and pushes the return value onto the stack.</p> + + <p>If <code>eval</code> in global scope is not original one, invokes the function with <code>this</code> and <code>args</code>, and pushes return value onto the stack.</p> + </dd> + <dt id="JSOP_SUPERCALL">JSOP_SUPERCALL [-(argc+3), +1] (ARGC, INVOKE, TYPESET, IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>165 (0xa5)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint16_t argc</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>3</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>callee, this, args[0], ..., args[argc-1], newTarget</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>rval</code></td> + </tr> + </tbody> + </table> + + <p>Behaves exactly like <code>JSOP_NEW</code>, but allows JITs to distinguish the two cases.</p> + </dd> + <dt id="JSOP_TRYSKIPAWAIT">JSOP_TRYSKIPAWAIT [-1, +2]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>223 (0xdf)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>value</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>value_or_resolved, canskip</code></td> + </tr> + </tbody> + </table> + + <p>Pops the top of stack value as <code>value</code>, checks if the await for <code>value</code> can be skipped. If the await operation can be skipped and the resolution value for <code>value</code> can be acquired, pushes the resolution value and <code>true</code> onto the stack. Otherwise, pushes <code>value</code> and <code>false</code> on the stack.</p> + </dd> +</dl> + +<h4 id="Generator">Generator</h4> + +<dl> + <dt id="JSOP_ASYNCAWAIT">JSOP_ASYNCAWAIT [-2, +1]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>151 (0x97)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>value, gen</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>promise</code></td> + </tr> + </tbody> + </table> + + <p>Pops the top two values <code>value</code> and <code>gen</code> from the stack, then starts "awaiting" for <code>value</code> to be resolved, which will then resume the execution of <code>gen</code>. Pushes the async function promise on the stack, so that it'll be returned to the caller on the very first "await".</p> + </dd> + <dt id="JSOP_ASYNCRESOLVE">JSOP_ASYNCRESOLVE [-2, +1] (UINT8)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>192 (0xc0)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint8_t fulfillOrReject</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>2</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>valueOrReason, gen</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>promise</code></td> + </tr> + </tbody> + </table> + + <p>Pops the top two values <code>valueOrReason</code> and <code>gen</code> from the stack, then pushes the promise resolved with <code>valueOrReason</code>. `gen` must be the internal generator object created in async functions. The pushed promise is the async function's result promise, which is stored in `gen`.</p> + </dd> + <dt id="JSOP_AWAIT">JSOP_AWAIT [-2, +1] (RESUMEINDEX)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>209 (0xd1)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint24_t resumeIndex</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>4</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>promise, gen</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>resolved</code></td> + </tr> + </tbody> + </table> + + <p>Pops the generator and the return value <code>promise</code>, stops interpretation and returns <code>promise</code>. Pushes resolved value onto the stack.</p> + </dd> + <dt id="JSOP_CHECKISOBJ">JSOP_CHECKISOBJ [-1, +1] (UINT8)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>14 (0x0e)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint8_t kind</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>2</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>result</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>result</code></td> + </tr> + </tbody> + </table> + + <p>Checks that the top value on the stack is an object, and throws a TypeError if not. The operand <code>kind</code> is used only to generate an appropriate error message.</p> + </dd> + <dt id="JSOP_FINALYIELDRVAL">JSOP_FINALYIELDRVAL [-1, +0]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>204 (0xcc)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>gen</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code> </code></td> + </tr> + </tbody> + </table> + + <p>Pops the generator and suspends and closes it. Yields the value in the frame's return value slot.</p> + </dd> + <dt id="JSOP_GENERATOR">JSOP_GENERATOR [-0, +1]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>212 (0xd4)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>generator</code></td> + </tr> + </tbody> + </table> + + <p>Initializes generator frame, creates a generator and pushes it on the stack.</p> + </dd> + <dt id="JSOP_INITIALYIELD">JSOP_INITIALYIELD [-1, +1] (RESUMEINDEX)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>202 (0xca)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint24_t resumeIndex</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>4</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>generator</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>generator</code></td> + </tr> + </tbody> + </table> + + <p>Pops the generator from the top of the stack, suspends it and stops interpretation.</p> + </dd> + <dt id="JSOP_RESUME">JSOP_RESUME [-2, +1] (UINT8, INVOKE)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>205 (0xcd)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>resume kind (AbstractGeneratorObject::ResumeKind)</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>2</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>gen, val</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>rval</code></td> + </tr> + </tbody> + </table> + + <p>Pops the generator and argument from the stack, pushes a new generator frame and resumes execution of it. Pushes the return value after the generator yields.</p> + </dd> + <dt id="JSOP_TOASYNCITER">JSOP_TOASYNCITER [-2, +1]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>210 (0xd2)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>iter, next</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>asynciter</code></td> + </tr> + </tbody> + </table> + + <p>Pops the iterator and its next method from the top of the stack, and create async iterator from it and push the async iterator back onto the stack.</p> + </dd> + <dt id="JSOP_YIELD">JSOP_YIELD [-2, +1] (RESUMEINDEX)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>203 (0xcb)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint24_t resumeIndex</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>4</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>rval1, gen</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>rval2</code></td> + </tr> + </tbody> + </table> + + <p>Pops the generator and the return value <code>rval1</code>, stops interpretation and returns <code>rval1</code>. Pushes sent value from <code>send()</code> onto the stack.</p> + </dd> +</dl> + +<h4 id="Debugger">Debugger</h4> + +<dl> + <dt id="JSOP_DEBUGGER">JSOP_DEBUGGER [-0, +0]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>115 (0x73)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code> </code></td> + </tr> + </tbody> + </table> + + <p>Invokes debugger.</p> + </dd> + <dt id="JSOP_DEBUGLEAVELEXICALENV">JSOP_DEBUGLEAVELEXICALENV [-0, +0]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>201 (0xc9)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code> </code></td> + </tr> + </tbody> + </table> + + <p>The opcode to assist the debugger.</p> + </dd> +</dl> + +<h3 id="Variables_and_Scopes">Variables and Scopes</h3> + +<h4 id="Variables">Variables</h4> + +<dl> + <dt id="JSOP_BINDNAME">JSOP_BINDNAME [-0, +1] (ATOM, NAME, IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>110 (0x6e)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint32_t nameIndex</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>env</code></td> + </tr> + </tbody> + </table> + + <p>Looks up name on the environment chain and pushes the environment which contains the name onto the stack. If not found, pushes global lexical environment onto the stack.</p> + </dd> + <dt id="JSOP_DEFCONST">JSOP_DEFCONST [-0, +0] (ATOM)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>128 (0x80)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint32_t nameIndex</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code> </code></td> + </tr> + </tbody> + </table> + + <p>Defines the new constant binding on global lexical environment.</p> + + <p>Throws if a binding with the same name already exists on the environment, or if a var binding with the same name exists on the global.</p> + </dd> + <dt id="JSOP_DEFFUN">JSOP_DEFFUN [-1, +0]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>127 (0x7f)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>fun</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code> </code></td> + </tr> + </tbody> + </table> + + <p>Defines the given function on the current scope.</p> + + <p>This is used for global scripts and also in some cases for function scripts where use of dynamic scoping inhibits optimization.</p> + </dd> + <dt id="JSOP_DEFLET">JSOP_DEFLET [-0, +0] (ATOM)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>162 (0xa2)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint32_t nameIndex</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code> </code></td> + </tr> + </tbody> + </table> + + <p>Defines the new mutable binding on global lexical environment.</p> + + <p>Throws if a binding with the same name already exists on the environment, or if a var binding with the same name exists on the global.</p> + </dd> + <dt id="JSOP_DEFVAR">JSOP_DEFVAR [-0, +0] (ATOM)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>129 (0x81)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint32_t nameIndex</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code> </code></td> + </tr> + </tbody> + </table> + + <p>Defines the new binding on the frame's current variables-object (the environment on the environment chain designated to receive new variables).</p> + + <p>Throws if the current variables-object is the global object and a binding with the same name exists on the global lexical environment.</p> + + <p>This is used for global scripts and also in some cases for function scripts where use of dynamic scoping inhibits optimization.</p> + </dd> + <dt id="JSOP_DELNAME">JSOP_DELNAME [-0, +1] (ATOM, NAME, CHECKSLOPPY)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>36 (0x24)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint32_t nameIndex</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>succeeded</code></td> + </tr> + </tbody> + </table> + + <p>Looks up name on the environment chain and deletes it, pushes <code>true</code> onto the stack if succeeded (if the property was present and deleted or if the property wasn't present in the first place), <code>false</code> if not.</p> + + <p>Strict mode code should never contain this opcode.</p> + </dd> + <dt id="JSOP_GETIMPORT">JSOP_GETIMPORT [-0, +1] (ATOM, NAME, TYPESET, IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>176 (0xb0)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint32_t nameIndex</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>val</code></td> + </tr> + </tbody> + </table> + + <p>Gets the value of a module import by name and pushes it onto the stack.</p> + </dd> + <dt id="JSOP_GETNAME">JSOP_GETNAME [-0, +1] (ATOM, NAME, TYPESET, IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>59 (0x3b)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint32_t nameIndex</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>val</code></td> + </tr> + </tbody> + </table> + + <p>Looks up name on the environment chain and pushes its value onto the stack.</p> + </dd> + <dt id="JSOP_SETNAME">JSOP_SETNAME [-2, +1] (ATOM, NAME, PROPSET, DETECTING, CHECKSLOPPY, IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>111 (0x6f)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint32_t nameIndex</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>env, val</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>val</code></td> + </tr> + </tbody> + </table> + + <p>Pops an environment and value from the stack, assigns value to the given name, and pushes the value back on the stack</p> + </dd> + <dt id="JSOP_STRICTSETNAME">JSOP_STRICTSETNAME [-2, +1] (ATOM, NAME, PROPSET, DETECTING, CHECKSTRICT, IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>49 (0x31)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint32_t nameIndex</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>env, val</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>val</code></td> + </tr> + </tbody> + </table> + + <p>Pops a environment and value from the stack, assigns value to the given name, and pushes the value back on the stack. If the set failed, then throw a TypeError, per usual strict mode semantics.</p> + </dd> +</dl> + +<h4 id="Free_Variables">Free Variables</h4> + +<dl> + <dt id="JSOP_BINDGNAME">JSOP_BINDGNAME [-0, +1] (ATOM, NAME, GNAME, IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>214 (0xd6)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint32_t nameIndex</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>global</code></td> + </tr> + </tbody> + </table> + + <p>Pushes the global environment onto the stack if the script doesn't have a non-syntactic global scope. Otherwise will act like <code>JSOP_BINDNAME</code>.</p> + + <p><code>nameIndex</code> is only used when acting like <code>JSOP_BINDNAME</code>.</p> + </dd> + <dt id="JSOP_BINDVAR">JSOP_BINDVAR [-0, +1]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>213 (0xd5)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>env</code></td> + </tr> + </tbody> + </table> + + <p>Pushes the nearest <code>var</code> environment.</p> + </dd> + <dt id="JSOP_GETGNAME">JSOP_GETGNAME [-0, +1] (ATOM, NAME, TYPESET, GNAME, IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>154 (0x9a)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint32_t nameIndex</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>val</code></td> + </tr> + </tbody> + </table> + + <p>Looks up name on global environment and pushes its value onto the stack, unless the script has a non-syntactic global scope, in which case it acts just like <code>JSOP_NAME</code>.</p> + + <p>Free variable references that must either be found on the global or a ReferenceError.</p> + </dd> + <dt id="JSOP_INITGLEXICAL">JSOP_INITGLEXICAL [-1, +1] (ATOM, NAME, PROPINIT, GNAME, IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>161 (0xa1)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint32_t nameIndex</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>val</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>val</code></td> + </tr> + </tbody> + </table> + + <p>Initializes an uninitialized global lexical binding with the top of stack value.</p> + </dd> + <dt id="JSOP_SETGNAME">JSOP_SETGNAME [-2, +1] (ATOM, NAME, PROPSET, DETECTING, GNAME, CHECKSLOPPY, IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>155 (0x9b)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint32_t nameIndex</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>env, val</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>val</code></td> + </tr> + </tbody> + </table> + + <p>Pops the top two values on the stack as <code>val</code> and <code>env</code>, sets property of <code>env</code> as <code>val</code> and pushes <code>val</code> back on the stack.</p> + + <p><code>env</code> should be the global lexical environment unless the script has a non-syntactic global scope, in which case acts like <code>JSOP_SETNAME</code>.</p> + </dd> + <dt id="JSOP_STRICTSETGNAME">JSOP_STRICTSETGNAME [-2, +1] (ATOM, NAME, PROPSET, DETECTING, GNAME, CHECKSTRICT, IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>156 (0x9c)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint32_t nameIndex</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>env, val</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>val</code></td> + </tr> + </tbody> + </table> + + <p>Pops the top two values on the stack as <code>val</code> and <code>env</code>, sets property of <code>env</code> as <code>val</code> and pushes <code>val</code> back on the stack. Throws a TypeError if the set fails, per strict mode semantics.</p> + + <p><code>env</code> should be the global lexical environment unless the script has a non-syntactic global scope, in which case acts like <code>JSOP_STRICTSETNAME</code>.</p> + </dd> +</dl> + +<h4 id="Local_Variables">Local Variables</h4> + +<dl> + <dt id="JSOP_CHECKLEXICAL">JSOP_CHECKLEXICAL [-0, +0] (LOCAL, NAME)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>138 (0x8a)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint24_t localno</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>4</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code> </code></td> + </tr> + </tbody> + </table> + + <p>Checks if the value of the local variable is the <code>JS_UNINITIALIZED_LEXICAL</code> magic, throwing an error if so.</p> + </dd> + <dt id="JSOP_GETLOCAL">JSOP_GETLOCAL [-0, +1] (LOCAL, NAME)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>86 (0x56)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint24_t localno</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>4</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>val</code></td> + </tr> + </tbody> + </table> + + <p>Pushes the value of local variable onto the stack.</p> + </dd> + <dt id="JSOP_INITLEXICAL">JSOP_INITLEXICAL [-1, +1] (LOCAL, NAME, DETECTING)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>139 (0x8b)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint24_t localno</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>4</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>v</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>v</code></td> + </tr> + </tbody> + </table> + + <p>Initializes an uninitialized local lexical binding with the top of stack value.</p> + </dd> + <dt id="JSOP_SETLOCAL">JSOP_SETLOCAL [-1, +1] (LOCAL, NAME, DETECTING)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>87 (0x57)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint24_t localno</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>4</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>v</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>v</code></td> + </tr> + </tbody> + </table> + + <p>Stores the top stack value to the given local.</p> + </dd> + <dt id="JSOP_THROWSETCALLEE">JSOP_THROWSETCALLEE [-1, +1]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>179 (0xb3)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>v</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>v</code></td> + </tr> + </tbody> + </table> + + <p>Throws a runtime TypeError for invalid assignment to the callee in a named lambda, which is always a <code>const</code> binding. This is a different bytecode than <code>JSOP_SETCONST</code> because the named lambda callee, if not closed over, does not have a frame slot to look up the name with for the error message.</p> + </dd> + <dt id="JSOP_THROWSETCONST">JSOP_THROWSETCONST [-1, +1] (LOCAL, NAME, DETECTING)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>169 (0xa9)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint24_t localno</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>4</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>v</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>v</code></td> + </tr> + </tbody> + </table> + + <p>Throws a runtime TypeError for invalid assignment to <code>const</code>. The localno is used for better error messages.</p> + </dd> +</dl> + +<h4 id="Aliased_Variables">Aliased Variables</h4> + +<dl> + <dt id="JSOP_CHECKALIASEDLEXICAL">JSOP_CHECKALIASEDLEXICAL [-0, +0] (ENVCOORD, NAME)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>140 (0x8c)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint8_t hops, uint24_t slot</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code> </code></td> + </tr> + </tbody> + </table> + + <p>Checks if the value of the aliased variable is the <code>JS_UNINITIALIZED_LEXICAL</code> magic, throwing an error if so.</p> + </dd> + <dt id="JSOP_GETALIASEDVAR">JSOP_GETALIASEDVAR [-0, +1] (ENVCOORD, NAME, TYPESET, IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>136 (0x88)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint8_t hops, uint24_t slot</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>aliasedVar</code></td> + </tr> + </tbody> + </table> + + <p>Pushes aliased variable onto the stack.</p> + + <p>An "aliased variable" is a var, let, or formal arg that is aliased. Sources of aliasing include: nested functions accessing the vars of an enclosing function, function statements that are conditionally executed, <code>eval</code>, <code>with</code>, and <code>arguments</code>. All of these cases require creating a CallObject to own the aliased variable.</p> + + <p>An ALIASEDVAR opcode contains the following immediates:</p> + + <pre class="notranslate">uint8 hops: the number of environment objects to skip to find the + EnvironmentObject containing the variable being accessed +uint24 slot: the slot containing the variable in the EnvironmentObject + (this 'slot' does not include RESERVED_SLOTS). +</pre> + </dd> + <dt id="JSOP_INITALIASEDLEXICAL">JSOP_INITALIASEDLEXICAL [-1, +1] (ENVCOORD, NAME, PROPINIT, DETECTING)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>141 (0x8d)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint8_t hops, uint24_t slot</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>v</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>v</code></td> + </tr> + </tbody> + </table> + + <p>Initializes an uninitialized aliased lexical binding with the top of stack value.</p> + </dd> + <dt id="JSOP_SETALIASEDVAR">JSOP_SETALIASEDVAR [-1, +1] (ENVCOORD, NAME, PROPSET, DETECTING)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>137 (0x89)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint8_t hops, uint24_t slot</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>v</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>v</code></td> + </tr> + </tbody> + </table> + + <p>Sets aliased variable as the top of stack value.</p> + </dd> + <dt id="JSOP_THROWSETALIASEDCONST">JSOP_THROWSETALIASEDCONST [-1, +1] (ENVCOORD, NAME, DETECTING)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>170 (0xaa)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint8_t hops, uint24_t slot</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>v</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>v</code></td> + </tr> + </tbody> + </table> + + <p>Throws a runtime TypeError for invalid assignment to <code>const</code>. The environment coordinate is used for better error messages.</p> + </dd> +</dl> + +<h4 id="Intrinsics">Intrinsics</h4> + +<dl> + <dt id="JSOP_GETINTRINSIC">JSOP_GETINTRINSIC [-0, +1] (ATOM, NAME, TYPESET, IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>143 (0x8f)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint32_t nameIndex</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>intrinsic[name]</code></td> + </tr> + </tbody> + </table> + + <p>Pushes the value of the intrinsic onto the stack.</p> + + <p>Intrinsic names are emitted instead of <code>JSOP_*NAME</code> ops when the <code>CompileOptions</code> flag <code>selfHostingMode</code> is set.</p> + + <p>They are used in self-hosted code to access other self-hosted values and intrinsic functions the runtime doesn't give client JS code access to.</p> + </dd> + <dt id="JSOP_SETINTRINSIC">JSOP_SETINTRINSIC [-1, +1] (ATOM, NAME, DETECTING)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>144 (0x90)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint32_t nameIndex</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>val</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>val</code></td> + </tr> + </tbody> + </table> + + <p>Stores the top stack value in the specified intrinsic.</p> + </dd> +</dl> + +<h4 id="Block-local_Scope">Block-local Scope</h4> + +<dl> + <dt id="JSOP_FRESHENLEXICALENV">JSOP_FRESHENLEXICALENV [-0, +0]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>197 (0xc5)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code> </code></td> + </tr> + </tbody> + </table> + + <p>Replaces the current block on the env chain with a fresh block that copies all the bindings in the block. This operation implements the behavior of inducing a fresh lexical environment for every iteration of a for(let ...; ...; ...) loop, if any declarations induced by such a loop are captured within the loop.</p> + </dd> + <dt id="JSOP_POPLEXICALENV">JSOP_POPLEXICALENV [-0, +0]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>200 (0xc8)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code> </code></td> + </tr> + </tbody> + </table> + + <p>Pops lexical environment from the env chain.</p> + </dd> + <dt id="JSOP_PUSHLEXICALENV">JSOP_PUSHLEXICALENV [-0, +0] (SCOPE)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>199 (0xc7)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint32_t scopeIndex</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code> </code></td> + </tr> + </tbody> + </table> + + <p>Pushes lexical environment onto the env chain.</p> + </dd> + <dt id="JSOP_RECREATELEXICALENV">JSOP_RECREATELEXICALENV [-0, +0]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>198 (0xc6)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code> </code></td> + </tr> + </tbody> + </table> + + <p>Recreates the current block on the env chain with a fresh block with uninitialized bindings. This operation implements the behavior of inducing a fresh lexical environment for every iteration of a for-in/of loop whose loop-head has a (captured) lexical declaration.</p> + </dd> +</dl> + +<h4 id="This">This</h4> + +<dl> + <dt id="JSOP_CHECKRETURN">JSOP_CHECKRETURN [-1, +0]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>190 (0xbe)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>this</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code> </code></td> + </tr> + </tbody> + </table> + + <p>Check if a derived class constructor has a valid return value and <code>this</code> value before it returns. If the return value is not an object, stores the <code>this</code> value to the return value slot.</p> + </dd> + <dt id="JSOP_CHECKTHIS">JSOP_CHECKTHIS [-1, +1]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>189 (0xbd)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>this</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>this</code></td> + </tr> + </tbody> + </table> + + <p>Throw if the value on top of the stack is the TDZ MagicValue. Used in derived class constructors.</p> + </dd> + <dt id="JSOP_CHECKTHISREINIT">JSOP_CHECKTHISREINIT [-1, +1]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>191 (0xbf)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>this</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>this</code></td> + </tr> + </tbody> + </table> + + <p>Throw an exception if the value on top of the stack is not the TDZ MagicValue. Used in derived class constructors.</p> + </dd> + <dt id="JSOP_FUNCTIONTHIS">JSOP_FUNCTIONTHIS [-0, +1]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>185 (0xb9)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>this</code></td> + </tr> + </tbody> + </table> + + <p>Determines the <code>this</code> value for current function frame and pushes it onto the stack. Emitted in the prologue of functions with a this-binding.</p> + </dd> + <dt id="JSOP_GIMPLICITTHIS">JSOP_GIMPLICITTHIS [-0, +1] (ATOM)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>157 (0x9d)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint32_t nameIndex</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>this</code></td> + </tr> + </tbody> + </table> + + <p>Pushes the implicit <code>this</code> value for calls to the associated name onto the stack; only used when the implicit this might be derived from a non-syntactic scope (instead of the global itself).</p> + + <p>Note that code evaluated via the Debugger API uses DebugEnvironmentProxy objects on its scope chain, which are non-syntactic environments that refer to syntactic environments. As a result, the binding we want may be held by a syntactic environments such as CallObject or VarEnvrionmentObject.</p> + </dd> + <dt id="JSOP_GLOBALTHIS">JSOP_GLOBALTHIS [-0, +1]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>186 (0xba)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>this</code></td> + </tr> + </tbody> + </table> + + <p>Pushes <code>this</code> value for current stack frame onto the stack. Emitted when <code>this</code> refers to the global <code>this</code>.</p> + </dd> + <dt id="JSOP_IMPLICITTHIS">JSOP_IMPLICITTHIS [-0, +1] (ATOM)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>226 (0xe2)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint32_t nameIndex</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>this</code></td> + </tr> + </tbody> + </table> + + <p>Pushes the implicit <code>this</code> value for calls to the associated name onto the stack.</p> + </dd> +</dl> + +<h4 id="Super">Super</h4> + +<dl> + <dt id="JSOP_SUPERBASE">JSOP_SUPERBASE [-1, +1]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>103 (0x67)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>callee</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>homeObjectProto</code></td> + </tr> + </tbody> + </table> + + <p>Pushes the prototype of the home object for |callee| onto the stack.</p> + </dd> + <dt id="JSOP_SUPERFUN">JSOP_SUPERFUN [-1, +1]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>164 (0xa4)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>callee</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>superFun</code></td> + </tr> + </tbody> + </table> + + <p>Push the function to invoke with |super()|. This is the prototype of the function passed in as |callee|.</p> + </dd> +</dl> + +<h4 id="Arguments">Arguments</h4> + +<dl> + <dt id="JSOP_ARGUMENTS">JSOP_ARGUMENTS [-0, +1]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>9 (0x09)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>arguments</code></td> + </tr> + </tbody> + </table> + + <p>Pushes the <code>arguments</code> object for the current function activation.</p> + + <p>If <code><code>JSS</code>cript</code> is not marked <code>needsArgsObj</code>, then a <code>JS_OPTIMIZED_ARGUMENTS</code> magic value is pushed. Otherwise, a proper arguments object is constructed and pushed.</p> + + <p>This opcode requires that the function does not have rest parameter.</p> + </dd> + <dt id="JSOP_CALLEE">JSOP_CALLEE [-0, +1]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>132 (0x84)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>callee</code></td> + </tr> + </tbody> + </table> + + <p>Pushes current callee onto the stack.</p> + + <p>Used for named function expression self-naming, if lightweight.</p> + </dd> + <dt id="JSOP_ENVCALLEE">JSOP_ENVCALLEE [-0, +1] (UINT8)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>206 (0xce)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint8_t numHops</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>2</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>callee</code></td> + </tr> + </tbody> + </table> + + <p>Load the callee stored in a CallObject on the environment chain. The numHops operand is the number of environment objects to skip on the environment chain.</p> + </dd> + <dt id="JSOP_GETARG">JSOP_GETARG [-0, +1] (QARG, NAME)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>84 (0x54)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint16_t argno</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>3</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>arguments[argno]</code></td> + </tr> + </tbody> + </table> + + <p>Fast get op for function arguments and local variables.</p> + + <p>Pushes <code>arguments[argno]</code> onto the stack.</p> + </dd> + <dt id="JSOP_NEWTARGET">JSOP_NEWTARGET [-0, +1]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>148 (0x94)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>new.target</code></td> + </tr> + </tbody> + </table> + + <p>Push "new.target"</p> + </dd> + <dt id="JSOP_REST">JSOP_REST [-0, +1] (TYPESET, IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>224 (0xe0)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>rest</code></td> + </tr> + </tbody> + </table> + + <p>Creates rest parameter array for current function call, and pushes it onto the stack.</p> + </dd> + <dt id="JSOP_SETARG">JSOP_SETARG [-1, +1] (QARG, NAME)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>85 (0x55)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint16_t argno</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>3</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>v</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>v</code></td> + </tr> + </tbody> + </table> + + <p>Fast set op for function arguments and local variables.</p> + + <p>Sets <code>arguments[argno]</code> as the top of stack value.</p> + </dd> +</dl> + +<h4 id="Var_Scope">Var Scope</h4> + +<dl> + <dt id="JSOP_POPVARENV">JSOP_POPVARENV [-0, +0]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>181 (0xb5)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code> </code></td> + </tr> + </tbody> + </table> + + <p>Pops a var environment from the env chain.</p> + </dd> + <dt id="JSOP_PUSHVARENV">JSOP_PUSHVARENV [-0, +0] (SCOPE)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>180 (0xb4)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint32_t scopeIndex</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code> </code></td> + </tr> + </tbody> + </table> + + <p>Pushes a var environment onto the env chain.</p> + </dd> +</dl> + +<h4 id="Modules">Modules</h4> + +<dl> + <dt id="JSOP_DYNAMIC_IMPORT">JSOP_DYNAMIC_IMPORT [-1, +1]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>233 (0xe9)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>arg</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>rval</code></td> + </tr> + </tbody> + </table> + + <p>Dynamic import of the module specified by the string value on the top of the stack.</p> + </dd> + <dt id="JSOP_IMPORTMETA">JSOP_IMPORTMETA [-0, +1]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>232 (0xe8)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>import.meta</code></td> + </tr> + </tbody> + </table> + + <p>Push "import.meta"</p> + </dd> +</dl> + +<h3 id="Operators">Operators</h3> + +<h4 id="Comparison_Operators">Comparison Operators</h4> + +<dl> + <dt id="JSOP_EQ">JSOP_EQ [-2, +1] (DETECTING, IC)<br> + JSOP_GE [-2, +1] (IC)<br> + JSOP_GT [-2, +1] (IC)<br> + JSOP_LE [-2, +1] (IC)<br> + JSOP_LT [-2, +1] (IC)<br> + JSOP_NE [-2, +1] (DETECTING, IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>JSOP_EQ: 18 (0x12)<br> + JSOP_GE: 23 (0x17)<br> + JSOP_GT: 22 (0x16)<br> + JSOP_LE: 21 (0x15)<br> + JSOP_LT: 20 (0x14)<br> + JSOP_NE: 19 (0x13)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>lval, rval</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>(lval OP rval)</code></td> + </tr> + </tbody> + </table> + + <p>Pops the top two values from the stack and pushes the result of comparing them.</p> + </dd> + <dt id="JSOP_STRICTEQ">JSOP_STRICTEQ [-2, +1] (DETECTING, IC)<br> + JSOP_STRICTNE [-2, +1] (DETECTING, IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>JSOP_STRICTEQ: 72 (0x48)<br> + JSOP_STRICTNE: 73 (0x49)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>lval, rval</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>(lval OP rval)</code></td> + </tr> + </tbody> + </table> + + <p>Pops the top two values from the stack, then pushes the result of applying the operator to the two values.</p> + </dd> +</dl> + +<h4 id="Arithmetic_Operators">Arithmetic Operators</h4> + +<dl> + <dt id="JSOP_ADD">JSOP_ADD [-2, +1] (IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>27 (0x1b)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>lval, rval</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>(lval + rval)</code></td> + </tr> + </tbody> + </table> + + <p>Pops the top two values <code>lval</code> and <code>rval</code> from the stack, then pushes the result of <code>lval + rval</code>.</p> + </dd> + <dt id="JSOP_DEC">JSOP_DEC [-1, +1] (IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>235 (0xeb)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>val</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>(val - 1)</code></td> + </tr> + </tbody> + </table> + + <p>Pops the numeric value <code>val</code> from the stack, then pushes <code>val - 1</code>.</p> + </dd> + <dt id="JSOP_INC">JSOP_INC [-1, +1] (IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>234 (0xea)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>val</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>(val + 1)</code></td> + </tr> + </tbody> + </table> + + <p>Pops the numeric value <code>val</code> from the stack, then pushes <code>val + 1</code>.</p> + </dd> + <dt id="JSOP_DIV">JSOP_DIV [-2, +1] (IC)<br> + JSOP_MOD [-2, +1] (IC)<br> + JSOP_MUL [-2, +1] (IC)<br> + JSOP_SUB [-2, +1] (IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>JSOP_DIV: 30 (0x1e)<br> + JSOP_MOD: 31 (0x1f)<br> + JSOP_MUL: 29 (0x1d)<br> + JSOP_SUB: 28 (0x1c)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>lval, rval</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>(lval OP rval)</code></td> + </tr> + </tbody> + </table> + + <p>Pops the top two values <code>lval</code> and <code>rval</code> from the stack, then pushes the result of applying the arithmetic operation to them.</p> + </dd> + <dt id="JSOP_NEG">JSOP_NEG [-1, +1] (IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>34 (0x22)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>val</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>(-val)</code></td> + </tr> + </tbody> + </table> + + <p>Pops the value <code>val</code> from the stack, then pushes <code>-val</code>.</p> + </dd> + <dt id="JSOP_POS">JSOP_POS [-1, +1]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>35 (0x23)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>val</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>(+val)</code></td> + </tr> + </tbody> + </table> + + <p>Pops the value <code>val</code> from the stack, then pushes <code>+val</code>. (<code>+val</code> is the value converted to a number.)</p> + </dd> + <dt id="JSOP_POW">JSOP_POW [-2, +1] (IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>150 (0x96)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>lval, rval</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>(lval ** rval)</code></td> + </tr> + </tbody> + </table> + + <p>Pops the top two values <code>lval</code> and <code>rval</code> from the stack, then pushes the result of <code>Math.pow(lval, rval)</code>.</p> + </dd> + <dt id="JSOP_TONUMERIC">JSOP_TONUMERIC [-1, +1]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>236 (0xec)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>val</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>ToNumeric(val)</code></td> + </tr> + </tbody> + </table> + + <p>Pop <code>val</code> from the stack, then push the result of <code>ToNumeric(val)</code>.</p> + </dd> +</dl> + +<h4 id="Bitwise_Logical_Operators">Bitwise Logical Operators</h4> + +<dl> + <dt id="JSOP_BITAND">JSOP_BITAND [-2, +1] (IC)<br> + JSOP_BITOR [-2, +1] (IC)<br> + JSOP_BITXOR [-2, +1] (IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>JSOP_BITAND: 17 (0x11)<br> + JSOP_BITOR: 15 (0x0f)<br> + JSOP_BITXOR: 16 (0x10)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>lval, rval</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>(lval OP rval)</code></td> + </tr> + </tbody> + </table> + + <p>Pops the top two values <code>lval</code> and <code>rval</code> from the stack, then pushes the result of the operation applied to the two operands, converting both to 32-bit signed integers if necessary.</p> + </dd> + <dt id="JSOP_BITNOT">JSOP_BITNOT [-1, +1] (IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>33 (0x21)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>val</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>(~val)</code></td> + </tr> + </tbody> + </table> + + <p>Pops the value <code>val</code> from the stack, then pushes <code>~val</code>.</p> + </dd> +</dl> + +<h4 id="Bitwise_Shift_Operators">Bitwise Shift Operators</h4> + +<dl> + <dt id="JSOP_LSH">JSOP_LSH [-2, +1] (IC)<br> + JSOP_RSH [-2, +1] (IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>JSOP_LSH: 24 (0x18)<br> + JSOP_RSH: 25 (0x19)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>lval, rval</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>(lval OP rval)</code></td> + </tr> + </tbody> + </table> + + <p>Pops the top two values <code>lval</code> and <code>rval</code> from the stack, then pushes the result of the operation applied to the operands.</p> + </dd> + <dt id="JSOP_URSH">JSOP_URSH [-2, +1] (IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>26 (0x1a)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>lval, rval</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>(lval >>> rval)</code></td> + </tr> + </tbody> + </table> + + <p>Pops the top two values <code>lval</code> and <code>rval</code> from the stack, then pushes <code>lval >>> rval</code>.</p> + </dd> +</dl> + +<h4 id="Logical_Operators">Logical Operators</h4> + +<dl> + <dt id="JSOP_NOT">JSOP_NOT [-1, +1] (DETECTING, IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>32 (0x20)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>val</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>(!val)</code></td> + </tr> + </tbody> + </table> + + <p>Pops the value <code>val</code> from the stack, then pushes <code>!val</code>.</p> + </dd> +</dl> + +<h4 id="Special_Operators">Special Operators</h4> + +<dl> + <dt id="JSOP_DELELEM">JSOP_DELELEM [-2, +1] (ELEM, CHECKSLOPPY)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>38 (0x26)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>obj, propval</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>succeeded</code></td> + </tr> + </tbody> + </table> + + <p>Pops the top two values on the stack as <code>propval</code> and <code>obj</code>, deletes <code>propval</code> property from <code>obj</code>, pushes <code>true</code> onto the stack if succeeded, <code>false</code> if not.</p> + </dd> + <dt id="JSOP_DELPROP">JSOP_DELPROP [-1, +1] (ATOM, PROP, CHECKSLOPPY)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>37 (0x25)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint32_t nameIndex</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>obj</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>succeeded</code></td> + </tr> + </tbody> + </table> + + <p>Pops the top of stack value, deletes property from it, pushes <code>true</code> onto the stack if succeeded, <code>false</code> if not.</p> + </dd> + <dt id="JSOP_IN">JSOP_IN [-2, +1] (IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>113 (0x71)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>id, obj</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>(id in obj)</code></td> + </tr> + </tbody> + </table> + + <p>Pops the top two values <code>id</code> and <code>obj</code> from the stack, then pushes <code>id in obj</code>. This will throw a <code>TypeError</code> if <code>obj</code> is not an object.</p> + + <p>Note that <code>obj</code> is the top value.</p> + </dd> + <dt id="JSOP_INSTANCEOF">JSOP_INSTANCEOF [-2, +1] (IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>114 (0x72)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>obj, ctor</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>(obj instanceof ctor)</code></td> + </tr> + </tbody> + </table> + + <p>Pops the top two values <code>obj</code> and <code>ctor</code> from the stack, then pushes <code>obj instanceof ctor</code>. This will throw a <code>TypeError</code> if <code>obj</code> is not an object.</p> + </dd> + <dt id="JSOP_STRICTDELPROP">JSOP_STRICTDELPROP [-1, +1] (ATOM, PROP, CHECKSTRICT)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>46 (0x2e)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint32_t nameIndex</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>obj</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>succeeded</code></td> + </tr> + </tbody> + </table> + + <p>Pops the top of stack value and attempts to delete the given property from it. Pushes <code>true</code> onto success, else throws a TypeError per strict mode property-deletion requirements.</p> + </dd> + <dt id="JSOP_TYPEOF">JSOP_TYPEOF [-1, +1] (DETECTING, IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>39 (0x27)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>val</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>(typeof val)</code></td> + </tr> + </tbody> + </table> + + <p>Pops the value <code>val</code> from the stack, then pushes <code>typeof val</code>.</p> + </dd> + <dt id="JSOP_TYPEOFEXPR">JSOP_TYPEOFEXPR [-1, +1] (DETECTING, IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>196 (0xc4)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>val</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>(typeof val)</code></td> + </tr> + </tbody> + </table> + + <p>Pops the top stack value as <code>val</code> and pushes <code>typeof val</code>. Note that this opcode isn't used when, in the original source code, <code>val</code> is a name -- see <code><code>JSOP_TYPEOF</code></code> for that. (This is because <code>typeof undefinedName === "undefined"</code>.)</p> + </dd> + <dt id="JSOP_VOID">JSOP_VOID [-1, +1]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>40 (0x28)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>val</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>undefined</code></td> + </tr> + </tbody> + </table> + + <p>Pops the top value on the stack and pushes <code>undefined</code>.</p> + </dd> +</dl> + +<h4 id="Stack_Operations">Stack Operations</h4> + +<dl> + <dt id="JSOP_DUP">JSOP_DUP [-1, +2]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>12 (0x0c)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>v</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>v, v</code></td> + </tr> + </tbody> + </table> + + <p>Pushes a copy of the top value on the stack.</p> + </dd> + <dt id="JSOP_DUP2">JSOP_DUP2 [-2, +4]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>13 (0x0d)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>v1, v2</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>v1, v2, v1, v2</code></td> + </tr> + </tbody> + </table> + + <p>Duplicates the top two values on the stack.</p> + </dd> + <dt id="JSOP_DUPAT">JSOP_DUPAT [-0, +1] (UINT24)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>44 (0x2c)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint24_t n</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>4</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>v[n], v[n-1], ..., v[1], v[0]</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>v[n], v[n-1], ..., v[1], v[0], v[n]</code></td> + </tr> + </tbody> + </table> + + <p>Duplicates the Nth value from the top onto the stack.</p> + </dd> + <dt id="JSOP_PICK">JSOP_PICK [-0, +0] (UINT8)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>133 (0x85)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint8_t n</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>2</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>v[n], v[n-1], ..., v[1], v[0]</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>v[n-1], ..., v[1], v[0], v[n]</code></td> + </tr> + </tbody> + </table> + + <p>Picks the nth element from the stack and moves it to the top of the stack.</p> + </dd> + <dt id="JSOP_POP">JSOP_POP [-1, +0]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>81 (0x51)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>v</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code> </code></td> + </tr> + </tbody> + </table> + + <p>Pops the top value off the stack.</p> + </dd> + <dt id="JSOP_POPN">JSOP_POPN [-n, +0] (UINT16)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>11 (0x0b)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint16_t n</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>3</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>v[n-1], ..., v[1], v[0]</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code> </code></td> + </tr> + </tbody> + </table> + + <p>Pops the top <code>n</code> values from the stack.</p> + </dd> + <dt id="JSOP_SWAP">JSOP_SWAP [-2, +2]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>10 (0x0a)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>v1, v2</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>v2, v1</code></td> + </tr> + </tbody> + </table> + + <p>Swaps the top two values on the stack. This is useful for things like post-increment/decrement.</p> + </dd> + <dt id="JSOP_UNPICK">JSOP_UNPICK [-0, +0] (UINT8)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>183 (0xb7)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint8_t n</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>2</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>v[n], v[n-1], ..., v[1], v[0]</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>v[0], v[n], v[n-1], ..., v[1]</code></td> + </tr> + </tbody> + </table> + + <p>Moves the top of the stack value under the nth element of the stack. Note: n must NOT be 0.</p> + </dd> +</dl> + +<h4 id="Debugger_2">Debugger</h4> + +<dl> + <dt id="JSOP_DEBUGAFTERYIELD">JSOP_DEBUGAFTERYIELD [-0, +0]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>208 (0xd0)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code> </code></td> + </tr> + </tbody> + </table> + + <p>Bytecode emitted after <code>yield</code> expressions to help the Debugger fix up the frame in the JITs. No-op in the interpreter.</p> + </dd> +</dl> + +<h3 id="Literals">Literals</h3> + +<h4 id="Constants">Constants</h4> + +<dl> + <dt id="JSOP_BIGINT">JSOP_BIGINT [-0, +1] (BIGINT)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>237 (0xed)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint32_t constIndex</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>val</code></td> + </tr> + </tbody> + </table> + + <p>Pushes a BigInt constant onto the stack.</p> + </dd> + <dt id="JSOP_BUILTINPROTO">JSOP_BUILTINPROTO [-0, +1] (UINT8)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>221 (0xdd)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint8_t kind</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>2</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>%BuiltinPrototype%</code></td> + </tr> + </tbody> + </table> + + <p>Pushes the current global's builtin prototype for a given proto key.</p> + </dd> + <dt id="JSOP_DOUBLE">JSOP_DOUBLE [-0, +1] (DOUBLE)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>60 (0x3c)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>DoubleValue literal</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>9</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>val</code></td> + </tr> + </tbody> + </table> + + <p>Pushes numeric constant onto the stack.</p> + </dd> + <dt id="JSOP_FALSE">JSOP_FALSE [-0, +1]<br> + JSOP_TRUE [-0, +1]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>JSOP_FALSE: 66 (0x42)<br> + JSOP_TRUE: 67 (0x43)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>true/false</code></td> + </tr> + </tbody> + </table> + + <p>Pushes boolean value onto the stack.</p> + </dd> + <dt id="JSOP_INT32">JSOP_INT32 [-0, +1] (INT32)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>216 (0xd8)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>int32_t val</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>val</code></td> + </tr> + </tbody> + </table> + + <p>Pushes 32-bit int immediate integer operand onto the stack.</p> + </dd> + <dt id="JSOP_INT8">JSOP_INT8 [-0, +1] (INT8)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>215 (0xd7)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>int8_t val</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>2</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>val</code></td> + </tr> + </tbody> + </table> + + <p>Pushes 8-bit int immediate integer operand onto the stack.</p> + </dd> + <dt id="JSOP_IS_CONSTRUCTING">JSOP_IS_CONSTRUCTING [-0, +1]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>65 (0x41)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>JS_IS_CONSTRUCTING</code></td> + </tr> + </tbody> + </table> + + <p>Pushes <code><code>JS_IS_CONSTRUCTING</code></code></p> + </dd> + <dt id="JSOP_NULL">JSOP_NULL [-0, +1]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>64 (0x40)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>null</code></td> + </tr> + </tbody> + </table> + + <p>Pushes <code>null</code> onto the stack.</p> + </dd> + <dt id="JSOP_ONE">JSOP_ONE [-0, +1]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>63 (0x3f)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>1</code></td> + </tr> + </tbody> + </table> + + <p>Pushes <code>1</code> onto the stack.</p> + </dd> + <dt id="JSOP_STRING">JSOP_STRING [-0, +1] (ATOM)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>61 (0x3d)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint32_t atomIndex</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>atom</code></td> + </tr> + </tbody> + </table> + + <p>Pushes string constant onto the stack.</p> + </dd> + <dt id="JSOP_SYMBOL">JSOP_SYMBOL [-0, +1] (UINT8)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>45 (0x2d)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint8_t symbol (the JS::SymbolCode of the symbol to use)</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>2</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>symbol</code></td> + </tr> + </tbody> + </table> + + <p>Push a well-known symbol onto the operand stack.</p> + </dd> + <dt id="JSOP_UINT16">JSOP_UINT16 [-0, +1] (UINT16)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>88 (0x58)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint16_t val</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>3</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>val</code></td> + </tr> + </tbody> + </table> + + <p>Pushes unsigned 16-bit int immediate integer operand onto the stack.</p> + </dd> + <dt id="JSOP_UINT24">JSOP_UINT24 [-0, +1] (UINT24)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>188 (0xbc)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint24_t val</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>4</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>val</code></td> + </tr> + </tbody> + </table> + + <p>Pushes unsigned 24-bit int immediate integer operand onto the stack.</p> + </dd> + <dt id="JSOP_UNDEFINED">JSOP_UNDEFINED [-0, +1]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>1 (0x01)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>undefined</code></td> + </tr> + </tbody> + </table> + + <p>Pushes <code>undefined</code> onto the stack.</p> + </dd> + <dt id="JSOP_UNINITIALIZED">JSOP_UNINITIALIZED [-0, +1]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>142 (0x8e)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>uninitialized</code></td> + </tr> + </tbody> + </table> + + <p>Pushes a <code>JS_UNINITIALIZED_LEXICAL</code> value onto the stack, representing an uninitialized lexical binding.</p> + + <p>This opcode is used with the <code>JSOP_INITLEXICAL</code> opcode.</p> + </dd> + <dt id="JSOP_ZERO">JSOP_ZERO [-0, +1]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>62 (0x3e)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>0</code></td> + </tr> + </tbody> + </table> + + <p>Pushes <code>0</code> onto the stack.</p> + </dd> +</dl> + +<h4 id="Object">Object</h4> + +<dl> + <dt id="JSOP_CALLELEM">JSOP_CALLELEM [-2, +1] (ELEM, TYPESET, IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>193 (0xc1)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>obj, propval</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>obj[propval]</code></td> + </tr> + </tbody> + </table> + + <p>Pops the top two values on the stack as <code>propval</code> and <code>obj</code>, pushes <code>propval</code> property of <code>obj</code> onto the stack. Requires the value under <code>obj</code> to be the receiver of the following call.</p> + + <p>Like <code>JSOP_GETELEM</code> but for call context.</p> + </dd> + <dt id="JSOP_CALLPROP">JSOP_CALLPROP [-1, +1] (ATOM, PROP, TYPESET, IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>184 (0xb8)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint32_t nameIndex</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>obj</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>obj[name]</code></td> + </tr> + </tbody> + </table> + + <p>Pops the top of stack value, pushes property of it onto the stack. Requires the value under <code>obj</code> to be the receiver of the following call.</p> + + <p>Like <code>JSOP_GETPROP</code> but for call context.</p> + </dd> + <dt id="JSOP_CALLSITEOBJ">JSOP_CALLSITEOBJ [-0, +1] (OBJECT)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>101 (0x65)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint32_t objectIndex</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>obj</code></td> + </tr> + </tbody> + </table> + + <p>Pushes the call site object specified by objectIndex onto the stack. Defines the raw property specified by objectIndex + 1 on the call site object and freezes both the call site object as well as its raw property.</p> + </dd> + <dt id="JSOP_CHECKCLASSHERITAGE">JSOP_CHECKCLASSHERITAGE [-1, +1]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>51 (0x33)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>heritage</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>heritage</code></td> + </tr> + </tbody> + </table> + + <p>Ensures the result of a class's heritage expression is either null or a constructor.</p> + </dd> + <dt id="JSOP_CHECKOBJCOERCIBLE">JSOP_CHECKOBJCOERCIBLE [-1, +1]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>163 (0xa3)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>val</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>val</code></td> + </tr> + </tbody> + </table> + + <p>Throw if the value on the stack is not coerscible to an object (is |null| or |undefined|).</p> + </dd> + <dt id="JSOP_GETBOUNDNAME">JSOP_GETBOUNDNAME [-1, +1] (ATOM, NAME, TYPESET, IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>195 (0xc3)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint32_t nameIndex</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>env</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>v</code></td> + </tr> + </tbody> + </table> + + <p>Pops an environment, gets the value of a bound name on it. If the name is not bound to the environment, throw a ReferenceError. Used in conjunction with BINDNAME.</p> + </dd> + <dt id="JSOP_GETELEM">JSOP_GETELEM [-2, +1] (ELEM, TYPESET, IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>55 (0x37)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>obj, propval</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>obj[propval]</code></td> + </tr> + </tbody> + </table> + + <p>Pops the top two values on the stack as <code>propval</code> and <code>obj</code>, pushes <code>propval</code> property of <code>obj</code> onto the stack.</p> + </dd> + <dt id="JSOP_GETELEM_SUPER">JSOP_GETELEM_SUPER [-3, +1] (ELEM, TYPESET, IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>125 (0x7d)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>receiver, propval, obj</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>obj[propval]</code></td> + </tr> + </tbody> + </table> + + <p>LIKE <code>JSOP_GETELEM</code> but takes receiver on stack, and the propval is evaluated before the obj.</p> + </dd> + <dt id="JSOP_GETPROP">JSOP_GETPROP [-1, +1] (ATOM, PROP, TYPESET, IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>53 (0x35)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint32_t nameIndex</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>obj</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>obj[name]</code></td> + </tr> + </tbody> + </table> + + <p>Pops the top of stack value, pushes property of it onto the stack.</p> + </dd> + <dt id="JSOP_GETPROP_SUPER">JSOP_GETPROP_SUPER [-2, +1] (ATOM, PROP, TYPESET, IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>104 (0x68)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint32_t nameIndex</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>receiver, obj</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>obj[name]</code></td> + </tr> + </tbody> + </table> + + <p>Pops the top two values, and pushes the property of one, using the other as the receiver.</p> + </dd> + <dt id="JSOP_INITELEM">JSOP_INITELEM [-3, +1] (ELEM, PROPINIT, DETECTING, IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>94 (0x5e)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>obj, id, val</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>obj</code></td> + </tr> + </tbody> + </table> + + <p>Initialize a numeric property in an object literal, like <code>{1: x}</code>.</p> + + <p>Pops the top three values on the stack as <code>val</code>, <code>id</code> and <code>obj</code>, defines <code>id</code> property of <code>obj</code> as <code>val</code>, pushes <code>obj</code> onto the stack.</p> + </dd> + <dt id="JSOP_INITELEM_GETTER">JSOP_INITELEM_GETTER [-3, +1] (ELEM, PROPINIT, DETECTING)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>99 (0x63)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>obj, id, val</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>obj</code></td> + </tr> + </tbody> + </table> + + <p>Initialize a numeric getter in an object literal like <code>{get 2() {}}</code>.</p> + + <p>Pops the top three values on the stack as <code>val</code>, <code>id</code> and <code>obj</code>, defines <code>id</code> getter of <code>obj</code> as <code>val</code>, pushes <code>obj</code> onto the stack.</p> + </dd> + <dt id="JSOP_INITELEM_SETTER">JSOP_INITELEM_SETTER [-3, +1] (ELEM, PROPINIT, DETECTING)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>100 (0x64)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>obj, id, val</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>obj</code></td> + </tr> + </tbody> + </table> + + <p>Initialize a numeric setter in an object literal like <code>{set 2(v) {}}</code>.</p> + + <p>Pops the top three values on the stack as <code>val</code>, <code>id</code> and <code>obj</code>, defines <code>id</code> setter of <code>obj</code> as <code>val</code>, pushes <code>obj</code> onto the stack.</p> + </dd> + <dt id="JSOP_INITHIDDENELEM">JSOP_INITHIDDENELEM [-3, +1] (ELEM, PROPINIT, DETECTING, IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>175 (0xaf)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>obj, id, val</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>obj</code></td> + </tr> + </tbody> + </table> + + <p>Initialize a non-enumerable numeric property in an object literal, like <code>{1: x}</code>.</p> + + <p>Pops the top three values on the stack as <code>val</code>, <code>id</code> and <code>obj</code>, defines <code>id</code> property of <code>obj</code> as <code>val</code>, pushes <code>obj</code> onto the stack.</p> + </dd> + <dt id="JSOP_INITHIDDENELEM_GETTER">JSOP_INITHIDDENELEM_GETTER [-3, +1] (ELEM, PROPINIT, DETECTING)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>173 (0xad)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>obj, id, val</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>obj</code></td> + </tr> + </tbody> + </table> + + <p>Initialize a non-enumerable numeric getter in an object literal like <code>{get 2() {}}</code>.</p> + + <p>Pops the top three values on the stack as <code>val</code>, <code>id</code> and <code>obj</code>, defines <code>id</code> getter of <code>obj</code> as <code>val</code>, pushes <code>obj</code> onto the stack.</p> + </dd> + <dt id="JSOP_INITHIDDENELEM_SETTER">JSOP_INITHIDDENELEM_SETTER [-3, +1] (ELEM, PROPINIT, DETECTING)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>174 (0xae)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>obj, id, val</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>obj</code></td> + </tr> + </tbody> + </table> + + <p>Initialize a non-enumerable numeric setter in an object literal like <code>{set 2(v) {}}</code>.</p> + + <p>Pops the top three values on the stack as <code>val</code>, <code>id</code> and <code>obj</code>, defines <code>id</code> setter of <code>obj</code> as <code>val</code>, pushes <code>obj</code> onto the stack.</p> + </dd> + <dt id="JSOP_INITHIDDENPROP">JSOP_INITHIDDENPROP [-2, +1] (ATOM, PROP, PROPINIT, DETECTING, IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>147 (0x93)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint32_t nameIndex</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>obj, val</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>obj</code></td> + </tr> + </tbody> + </table> + + <p>Initialize a non-enumerable data-property on an object.</p> + + <p>Pops the top two values on the stack as <code>val</code> and <code>obj</code>, defines <code>nameIndex</code> property of <code>obj</code> as <code>val</code>, pushes <code>obj</code> onto the stack.</p> + </dd> + <dt id="JSOP_INITHIDDENPROP_GETTER">JSOP_INITHIDDENPROP_GETTER [-2, +1] (ATOM, PROP, PROPINIT, DETECTING)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>171 (0xab)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint32_t nameIndex</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>obj, val</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>obj</code></td> + </tr> + </tbody> + </table> + + <p>Initialize a non-enumerable getter in an object literal.</p> + + <p>Pops the top two values on the stack as <code>val</code> and <code>obj</code>, defines getter of <code>obj</code> as <code>val</code>, pushes <code>obj</code> onto the stack.</p> + </dd> + <dt id="JSOP_INITHIDDENPROP_SETTER">JSOP_INITHIDDENPROP_SETTER [-2, +1] (ATOM, PROP, PROPINIT, DETECTING)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>172 (0xac)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint32_t nameIndex</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>obj, val</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>obj</code></td> + </tr> + </tbody> + </table> + + <p>Initialize a non-enumerable setter in an object literal.</p> + + <p>Pops the top two values on the stack as <code>val</code> and <code>obj</code>, defines setter of <code>obj</code> as <code>val</code>, pushes <code>obj</code> onto the stack.</p> + </dd> + <dt id="JSOP_INITHOMEOBJECT">JSOP_INITHOMEOBJECT [-2, +1]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>92 (0x5c)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>fun, homeObject</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>fun</code></td> + </tr> + </tbody> + </table> + + <p>Initialize the home object for functions with super bindings.</p> + + <p>This opcode takes the function and the object to be the home object, does the set, and leaves the function on the stack.</p> + </dd> + <dt id="JSOP_INITLOCKEDPROP">JSOP_INITLOCKEDPROP [-2, +1] (ATOM, PROP, PROPINIT, DETECTING, IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>146 (0x92)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint32_t nameIndex</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>obj, val</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>obj</code></td> + </tr> + </tbody> + </table> + + <p>Initialize a non-configurable, non-writable, non-enumerable data-property on an object.</p> + + <p>Pops the top two values on the stack as <code>val</code> and <code>obj</code>, defines <code>nameIndex</code> property of <code>obj</code> as <code>val</code>, pushes <code>obj</code> onto the stack.</p> + </dd> + <dt id="JSOP_INITPROP">JSOP_INITPROP [-2, +1] (ATOM, PROP, PROPINIT, DETECTING, IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>93 (0x5d)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint32_t nameIndex</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>obj, val</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>obj</code></td> + </tr> + </tbody> + </table> + + <p>Initialize a named property in an object literal, like <code>{a: x}</code>.</p> + + <p>Pops the top two values on the stack as <code>val</code> and <code>obj</code>, defines <code>nameIndex</code> property of <code>obj</code> as <code>val</code>, pushes <code>obj</code> onto the stack.</p> + </dd> + <dt id="JSOP_INITPROP_GETTER">JSOP_INITPROP_GETTER [-2, +1] (ATOM, PROP, PROPINIT, DETECTING)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>97 (0x61)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint32_t nameIndex</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>obj, val</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>obj</code></td> + </tr> + </tbody> + </table> + + <p>Initialize a getter in an object literal.</p> + + <p>Pops the top two values on the stack as <code>val</code> and <code>obj</code>, defines getter of <code>obj</code> as <code>val</code>, pushes <code>obj</code> onto the stack.</p> + </dd> + <dt id="JSOP_INITPROP_SETTER">JSOP_INITPROP_SETTER [-2, +1] (ATOM, PROP, PROPINIT, DETECTING)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>98 (0x62)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint32_t nameIndex</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>obj, val</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>obj</code></td> + </tr> + </tbody> + </table> + + <p>Initialize a setter in an object literal.</p> + + <p>Pops the top two values on the stack as <code>val</code> and <code>obj</code>, defines setter of <code>obj</code> as <code>val</code>, pushes <code>obj</code> onto the stack.</p> + </dd> + <dt id="JSOP_MUTATEPROTO">JSOP_MUTATEPROTO [-2, +1]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>194 (0xc2)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>obj, newProto</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>succeeded</code></td> + </tr> + </tbody> + </table> + + <p><code>__proto__: v</code> inside an object initializer.</p> + + <p>Pops the top two values on the stack as <code>newProto</code> and <code>obj</code>, sets prototype of <code>obj</code> as <code>newProto</code>, pushes <code>true</code> onto the stack if succeeded, <code>false</code> if not.</p> + </dd> + <dt id="JSOP_NEWINIT">JSOP_NEWINIT [-0, +1] (UINT32, IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>89 (0x59)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>(uint32_t extra)</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>obj</code></td> + </tr> + </tbody> + </table> + + <p>Pushes newly created object onto the stack.</p> + + <p>This opcode has four extra bytes so it can be exchanged with <code>JSOP_NEWOBJECT</code> during emit.</p> + </dd> + <dt id="JSOP_NEWOBJECT">JSOP_NEWOBJECT [-0, +1] (OBJECT, IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>91 (0x5b)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint32_t baseobjIndex</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>obj</code></td> + </tr> + </tbody> + </table> + + <p>Pushes newly created object onto the stack.</p> + + <p>This opcode takes an object with the final shape, which can be set at the start and slots then filled in directly.</p> + </dd> + <dt id="JSOP_OBJECT">JSOP_OBJECT [-0, +1] (OBJECT)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>80 (0x50)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint32_t objectIndex</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>obj</code></td> + </tr> + </tbody> + </table> + + <p>Pushes deep-cloned object literal or singleton onto the stack.</p> + </dd> + <dt id="JSOP_OBJWITHPROTO">JSOP_OBJWITHPROTO [-1, +1]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>83 (0x53)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>proto</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>obj</code></td> + </tr> + </tbody> + </table> + + <p>Pushes newly created object onto the stack with provided [[Prototype]].</p> + </dd> + <dt id="JSOP_SETELEM">JSOP_SETELEM [-3, +1] (ELEM, PROPSET, DETECTING, CHECKSLOPPY, IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>56 (0x38)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>obj, propval, val</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>val</code></td> + </tr> + </tbody> + </table> + + <p>Pops the top three values on the stack as <code>val</code>, <code>propval</code> and <code>obj</code>, sets <code>propval</code> property of <code>obj</code> as <code>val</code>, pushes <code>val</code> onto the stack.</p> + </dd> + <dt id="JSOP_SETELEM_SUPER">JSOP_SETELEM_SUPER [-4, +1] (ELEM, PROPSET, DETECTING, CHECKSLOPPY)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>158 (0x9e)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>receiver, propval, obj, val</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>val</code></td> + </tr> + </tbody> + </table> + + <p>LIKE <code>JSOP_SETELEM</code>, but takes receiver on the stack, and the propval is evaluated before the base.</p> + </dd> + <dt id="JSOP_SETPROP">JSOP_SETPROP [-2, +1] (ATOM, PROP, PROPSET, DETECTING, CHECKSLOPPY, IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>54 (0x36)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint32_t nameIndex</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>obj, val</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>val</code></td> + </tr> + </tbody> + </table> + + <p>Pops the top two values on the stack as <code>val</code> and <code>obj</code> and performs <code>obj.prop = val</code>, pushing <code>val</code> back onto the stack.</p> + </dd> + <dt id="JSOP_SETPROP_SUPER">JSOP_SETPROP_SUPER [-3, +1] (ATOM, PROP, PROPSET, DETECTING, CHECKSLOPPY)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>107 (0x6b)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint32_t nameIndex</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>receiver, obj, val</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>val</code></td> + </tr> + </tbody> + </table> + + <p>Pops the top three values on the stack as <code>val</code>, <code>obj</code> and <code>receiver</code>, and performs <code>obj.prop = val</code>, pushing <code>val</code> back onto the stack.</p> + </dd> + <dt id="JSOP_STRICTDELELEM">JSOP_STRICTDELELEM [-2, +1] (ELEM, CHECKSTRICT)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>47 (0x2f)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>obj, propval</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>succeeded</code></td> + </tr> + </tbody> + </table> + + <p>Pops the top two values on the stack as <code>propval</code> and <code>obj</code>, and attempts to delete <code>propval</code> property from <code>obj</code>. Pushes <code>true</code> onto the stack on success, else throws a TypeError per strict mode property deletion requirements.</p> + </dd> + <dt id="JSOP_STRICTSETELEM">JSOP_STRICTSETELEM [-3, +1] (ELEM, PROPSET, DETECTING, CHECKSTRICT, IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>57 (0x39)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>obj, propval, val</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>val</code></td> + </tr> + </tbody> + </table> + + <p>Pops the top three values on the stack as <code>val</code>, <code>propval</code> and <code>obj</code>, sets <code>propval</code> property of <code>obj</code> as <code>val</code>, pushes <code>val</code> onto the stack. Throws a TypeError if the set fails, per strict mode semantics.</p> + </dd> + <dt id="JSOP_STRICTSETELEM_SUPER">JSOP_STRICTSETELEM_SUPER [-4, +1] (ELEM, PROPSET, DETECTING, CHECKSTRICT)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>159 (0x9f)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>receiver, propval, obj, val</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>val</code></td> + </tr> + </tbody> + </table> + + <p>LIKE <code>JSOP_STRICTSETELEM</code>, but takes receiver on the stack, and the propval is evaluated before the base.</p> + </dd> + <dt id="JSOP_STRICTSETPROP">JSOP_STRICTSETPROP [-2, +1] (ATOM, PROP, PROPSET, DETECTING, CHECKSTRICT, IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>48 (0x30)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint32_t nameIndex</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>obj, val</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>val</code></td> + </tr> + </tbody> + </table> + + <p>Pops the top two values on the stack as <code>val</code> and <code>obj</code>, and performs <code>obj.prop = val</code>, pushing <code>val</code> back onto the stack. Throws a TypeError if the set-operation failed (per strict mode semantics).</p> + </dd> + <dt id="JSOP_STRICTSETPROP_SUPER">JSOP_STRICTSETPROP_SUPER [-3, +1] (ATOM, PROP, PROPSET, DETECTING, CHECKSTRICT)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>105 (0x69)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint32_t nameIndex</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>receiver, obj, val</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>val</code></td> + </tr> + </tbody> + </table> + + <p>Pops the top three values on the stack as <code>val</code> and <code>obj</code>, and <code>receiver</code>, and performs <code>obj.prop = val</code>, pushing <code>val</code> back onto the stack. Throws a TypeError if the set-operation failed (per strict mode semantics).</p> + </dd> + <dt id="JSOP_TOID">JSOP_TOID [-1, +1]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>225 (0xe1)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>propertyNameValue</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>propertyKey</code></td> + </tr> + </tbody> + </table> + + <p>Replace the top-of-stack value propertyNameValue with ToPropertyKey(propertyNameValue).</p> + </dd> +</dl> + +<h4 id="Array">Array</h4> + +<dl> + <dt id="JSOP_HOLE">JSOP_HOLE [-0, +1]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>218 (0xda)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>hole</code></td> + </tr> + </tbody> + </table> + + <p>Pushes a <code>JS_ELEMENTS_HOLE</code> value onto the stack, representing an omitted property in an array literal (e.g. property 0 in the array <code>[, 1]</code>).</p> + + <p>This opcode is used with the <code>JSOP_NEWARRAY</code> opcode.</p> + </dd> + <dt id="JSOP_INITELEM_ARRAY">JSOP_INITELEM_ARRAY [-2, +1] (UINT32, ELEM, PROPINIT, DETECTING, IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>96 (0x60)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint32_t index</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>obj, val</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>obj</code></td> + </tr> + </tbody> + </table> + + <p>Initialize an array element.</p> + + <p>Pops the top two values on the stack as <code>val</code> and <code>obj</code>, sets <code>index</code> property of <code>obj</code> as <code>val</code>, pushes <code>obj</code> onto the stack.</p> + </dd> + <dt id="JSOP_INITELEM_INC">JSOP_INITELEM_INC [-3, +2] (ELEM, PROPINIT, IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>95 (0x5f)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>obj, index, val</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>obj, (index + 1)</code></td> + </tr> + </tbody> + </table> + + <p>Pops the top three values on the stack as <code>val</code>, <code>index</code> and <code>obj</code>, sets <code>index</code> property of <code>obj</code> as <code>val</code>, pushes <code>obj</code> and <code>index + 1</code> onto the stack.</p> + + <p>This opcode is used in Array literals with spread and spreadcall arguments.</p> + </dd> + <dt id="JSOP_LENGTH">JSOP_LENGTH [-1, +1] (ATOM, PROP, TYPESET, IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>217 (0xd9)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint32_t nameIndex</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>obj</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>obj['length']</code></td> + </tr> + </tbody> + </table> + + <p>Pops the top of stack value, pushes the <code>length</code> property of it onto the stack.</p> + </dd> + <dt id="JSOP_NEWARRAY">JSOP_NEWARRAY [-0, +1] (UINT32, IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>90 (0x5a)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint32_t length</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>obj</code></td> + </tr> + </tbody> + </table> + + <p>Pushes newly created array onto the stack.</p> + + <p>This opcode takes the final length, which is preallocated.</p> + </dd> + <dt id="JSOP_NEWARRAY_COPYONWRITE">JSOP_NEWARRAY_COPYONWRITE [-0, +1] (OBJECT)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>102 (0x66)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint32_t objectIndex</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>obj</code></td> + </tr> + </tbody> + </table> + + <p>Pushes a newly created array onto the stack, whose elements are the same as that of a template object's copy on write elements.</p> + </dd> +</dl> + +<h4 id="RegExp">RegExp</h4> + +<dl> + <dt id="JSOP_REGEXP">JSOP_REGEXP [-0, +1] (REGEXP)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>160 (0xa0)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint32_t regexpIndex</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>regexp</code></td> + </tr> + </tbody> + </table> + + <p>Pushes a regular expression literal onto the stack. It requires special "clone on exec" handling.</p> + </dd> +</dl> + +<h4 id="Class">Class</h4> + +<dl> + <dt id="JSOP_CLASSCONSTRUCTOR">JSOP_CLASSCONSTRUCTOR [-0, +1] (ATOM)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>167 (0xa7)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>atom className</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>constructor</code></td> + </tr> + </tbody> + </table> + + <p>Push a default constructor for a base class literal.</p> + </dd> + <dt id="JSOP_DERIVEDCONSTRUCTOR">JSOP_DERIVEDCONSTRUCTOR [-1, +1] (ATOM)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>168 (0xa8)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>atom className</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>proto</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>constructor</code></td> + </tr> + </tbody> + </table> + + <p>Push a default constructor for a derived class literal.</p> + </dd> +</dl> + +<h3 id="Other">Other</h3> + +<dl> + <dt id="JSOP_DEBUGCHECKSELFHOSTED">JSOP_DEBUGCHECKSELFHOSTED [-1, +1]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>177 (0xb1)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>checkVal</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>checkVal</code></td> + </tr> + </tbody> + </table> + + <p>Examines the top stack value, asserting that it's either a self-hosted function or a self-hosted intrinsic. This opcode does nothing in a non-debug build.</p> + </dd> + <dt id="JSOP_FORCEINTERPRETER">JSOP_FORCEINTERPRETER [-0, +0]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>207 (0xcf)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code> </code></td> + </tr> + </tbody> + </table> + + <p>No-op bytecode only emitted in some self-hosted functions. Not handled by the JITs so the script always runs in the interpreter.</p> + </dd> + <dt id="JSOP_HASOWN">JSOP_HASOWN [-2, +1] (IC)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>211 (0xd3)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>id, obj</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>(obj.hasOwnProperty(id))</code></td> + </tr> + </tbody> + </table> + + <p>Pops the top two values <code>id</code> and <code>obj</code> from the stack, then pushes obj.hasOwnProperty(id)</p> + + <p>Note that <code>obj</code> is the top value.</p> + </dd> + <dt id="JSOP_ITERNEXT">JSOP_ITERNEXT [-1, +1]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>222 (0xde)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>val</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>val</code></td> + </tr> + </tbody> + </table> + + <p>NOP opcode to hint to IonBuilder that the value on top of the stack is the (likely string) key in a for-in loop.</p> + </dd> + <dt id="JSOP_JUMPTARGET">JSOP_JUMPTARGET [-0, +0] (ICINDEX)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>230 (0xe6)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint32_t icIndex</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code> </code></td> + </tr> + </tbody> + </table> + + <p>This opcode is a no-op and it indicates the location of a jump instruction target. Some other opcodes act as jump targets as well, see BytecodeIsJumpTarget. The IC index is used by the Baseline interpreter.</p> + </dd> + <dt id="JSOP_LINENO">JSOP_LINENO [-0, +0] (UINT32)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>119 (0x77)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint32_t lineno</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>5</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code> </code></td> + </tr> + </tbody> + </table> + + <p>Embedded lineno to speedup <code>pc->line</code> mapping.</p> + </dd> + <dt id="JSOP_NOP">JSOP_NOP [-0, +0]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>0 (0x00)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code> </code></td> + </tr> + </tbody> + </table> + + <p>No operation is performed.</p> + </dd> + <dt id="JSOP_NOP_DESTRUCTURING">JSOP_NOP_DESTRUCTURING [-0, +0]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>229 (0xe5)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code> </code></td> + </tr> + </tbody> + </table> + + <p>No-op used by the decompiler to produce nicer error messages about destructuring code.</p> + </dd> + <dt id="JSOP_RESUMEINDEX">JSOP_RESUMEINDEX [-0, +1] (RESUMEINDEX)</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>126 (0x7e)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code>uint24_t resumeIndex</code></td> + </tr> + <tr> + <th>Length</th> + <td><code>4</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>resumeIndex</code></td> + </tr> + </tbody> + </table> + + <p>Pushes a resumeIndex (stored as 24-bit operand) on the stack.</p> + + <p>Resume indexes are used for ops like <code>JSOP_YIELD</code> and <code>JSOP_GOSUB</code>. <code>JSS</code>cript and BaselineScript have lists of resume entries (one for each resumeIndex); this lets the JIT resume at these ops from JIT code.</p> + </dd> + <dt id="JSOP_TOSTRING">JSOP_TOSTRING [-1, +1]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>228 (0xe4)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code>val</code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code>ToString(val)</code></td> + </tr> + </tbody> + </table> + + <p>Converts the value on the top of the stack to a String.</p> + </dd> + <dt id="JSOP_TRY_DESTRUCTURING">JSOP_TRY_DESTRUCTURING [-0, +0]</dt> + <dd> + <table class="standard-table"> + <tbody> + <tr> + <th>Value</th> + <td><code>220 (0xdc)</code></td> + </tr> + <tr> + <th>Operands</th> + <td><code> </code></td> + </tr> + <tr> + <th>Length</th> + <td><code>1</code></td> + </tr> + <tr> + <th>Stack Uses</th> + <td><code> </code></td> + </tr> + <tr> + <th>Stack Defs</th> + <td><code> </code></td> + </tr> + </tbody> + </table> + + <p>No-op used by the exception unwinder to determine the correct environment to unwind to when performing IteratorClose due to destructuring.</p> + </dd> +</dl> diff --git a/files/ja/mozilla/projects/spidermonkey/internals/garbage_collection/index.html b/files/ja/mozilla/projects/spidermonkey/internals/garbage_collection/index.html new file mode 100644 index 0000000000..e12b08f89b --- /dev/null +++ b/files/ja/mozilla/projects/spidermonkey/internals/garbage_collection/index.html @@ -0,0 +1,131 @@ +--- +title: Garbage collection +slug: Mozilla/Projects/SpiderMonkey/Internals/Garbage_collection +translation_of: Mozilla/Projects/SpiderMonkey/Internals/Garbage_collection +--- +<div class="note"> + <strong>この文書について: これはSpiderMonkeyのGC内部についての雑多な草案です。内容が古いまたは不正確な場合があります。</strong></div> +<div class="warning"> + <p><strong>警告:</strong>SpiderMonkey ガベージコレクションTipsは悲しいことに古い内容であり、完全に無視されるべきものとなってしまいました、</p> +</div> +<h2 id="デザインの概要">デザインの概要</h2> +<p>SpiderMonkeyは、オプションでインクリメンタルマーキングモード(<span style="line-height: 1.5;">incremental marking mode)を有効にされたマーク & スイープ方式のガベージコレクション(GC)を持っています。マークフェイズでは、インクリメンタルマーキングに必要なマークスタックを用います。ファイナライザを伴わないオブジェクトのスイープは、バックグラウンドスレッドにて実行されます。</span></p> +<p>世代別GCおよびコンパクションGC(compacting GC)の実装に向けた作業が進行中です。</p> +<p> </p> +<h2 id="主要なデータ構造">主要なデータ構造</h2> +<h3 id="Cell">Cell</h3> +<p><strong>Cell</strong> は、外部からも使用される、GCによって割当と回収が行われるメモリーの単位です。つまり、GC以外から見れば、GCの仕事はCellの割当と自動的な回収ということになります。</p> +<p>例えばJSObjectのように、CellはGCによって割り当てられる全てのクラスの基底クラスとなります。</p> +<h3 id="Allocation_Kind">Allocation Kind</h3> +<p>Cellは、Allocation Kindにより分類されます。Allocation Kindはオブジェクトのサイズおよびファイナライズの振る舞いを定義します。Allocation Kindは<strong>AllocKind列挙型</strong>によって定義されます。</p> +<p>Arenas always hold objects of the same allocation kind. Thus, an arena holds objects all of the same size and finalization behavior.</p> +<h3 id="Compartment">Compartment</h3> +<p>JSヒープはCompartmentに分割されます。Compartmentの要点は以下になります:</p> +<ul> + <li>あらゆるCell(JSヒープオブジェクト)は、Compartmentのどれか一つに属します(ヒープはCompartmentに分類されることを意味します)。</li> + <li>オブジェクトは、別のCompartment内のオブジェクトに対する直接のポインタを保持することはできません。代わりに、他のオブジェクト用のラッパーを保持することになります。ラッパーは、Compartment間のセキュリティチェックに用いられます。同じCompartment内のオブジェクトは同じアクセス権限を持っているため、セキュリティチェックの必要はありませんが、cross-compartment wrapper(Compartment間ラッパー)のトラバース時にチェックが行われるかもしれません。</li> + <li>エンジンは同時にひとつのCompartmentのGCが可能です。同様に、エンジンは他をGCしている場合を除いて、Compartmentの集合に対してGCが可能です。cross-compartment wrapperは、ひとつないし複数のCompartmentのGCのrootとして用いられます。</li> +</ul> +<p>Compartmentは、SpiderMonkeyにおける、GCを含む特にメモリに関連した事項の構造的かつ分野横断的なコンセプトになっています。詳細は<a href="“/ja/SpiderMonkey/SpiderMonkey_compartments" title="https://developer.mozilla.org/ja/SpiderMonkey/SpiderMonkey_compartments">Compartments</a>を参照してください。</p> +<p><strong>JSCompartment</strong>はGCに関連した重要なフィールドを保持しています:</p> +<dl> + <dt style="margin-left: 40px;"> + ArenaLists型 arenas</dt> + <dd style="margin-left: 40px;"> + この構造体は、それぞれのAllocation KindのArenaの2つのリストを記録しています。未使用のArenaのリストと、割当済みのArenaのリストです。</dd> + <dt style="margin-left: 40px;"> + bool型 needsBarrier</dt> + <dd style="margin-left: 40px;"> + このCompartmentにおけるGCが、インクリメンタルバリアの実行を必要とする場合にtrueとなります。すなわり、このCompartmentが現在インクリメンタルGCを実行しているかどうかを表します。</dd> + <dt style="margin-left: 40px;"> + CompartmentGCState型 gcState</dt> + <dd style="margin-left: 40px;"> + このCompartmentが現在GCを実行しているかどうかを表します。もし実行していなければ、GCの実行がスケジュールされているかを表します。</dd> + <dt style="margin-left: 40px;"> + size_t型 gcBytes, gcTriggerBytes, gcMallocBytes, gcMaxMallocBytes</dt> + <dd style="margin-left: 40px;"> + GCのスケジュールに使用される情報を表します</dd> + <dt style="margin-left: 40px;"> + WrapperMap型 crossCompartmentWrappers</dt> + <dd style="margin-left: 40px;"> + このCompartment内のオブジェクトのラッパーの集合です。Mapのキーはオブジェクト、値はラッパーです。同じオブジェクトに対するラッパーが複数回要求される場合、エンジンが同一のラッパーを毎回返せるようにするためにマッピングが必要とされます。ラッパーオブジェクトの集合は同様に、単一および複数のcompartmentの(non-globalな)GCにおいても必要となります</dd> +</dl> +<h3 id="Zone">Zone</h3> +<p>TODO(原文ママ)</p> +<h3 id="Chunk">Chunk</h3> +<p>Chunkはメモリの割当における最大の内部単位となります。</p> +<p>Chunkは1MBのサイズを持ち、内部にArena、パディング、Mark Bitmap(ChunkBitmap)、解放されたArenaのビットマップ、およびChunkヘッダ(ChunkInfo)を保持しています。</p> +<p>ChunkInfoは、ChunkInfo::freeArenasHeadから開始しており、ArenaHeader::nextを介してリンクしている未割当のArenaのリストを保持します。また、ChunkInfoは未割当のArenaの数の基本的な情報を保持しています。</p> +<p>TODO ChunkInfo next/prev(原文ママ)</p> +<h3 id="Arena">Arena</h3> +<p>Arenaはメモリ割当の内部単位です。</p> +<p>Arenaは1ページ(ほぼ全てのプラットフォームで4096バイト)の大きさであり、ArenaHeaderと、僅かなパディングとなるバイト領域と、整列された要素の配列を含みます。Arena内のすべての要素は、同じAllocation Kindとサイズを持ちます。</p> +<p>すべてのArenaは、ArenaHeader::firstFreeSpanOffetsから始まる自由なメモリ区間のリストを保持します。自由なメモリ区間の最後のCell(最後であるのが望ましい)は、次の自由なメモリ区間を表すFreeSpanを保持します。</p> +<h3 id="Free_Span">Free Span</h3> +<p><strong>構造体<code>FreeSpan</code></strong>は、Arena内の自由なCell <strong>[first, last]</strong>の連続を表します。FreeSpanは、自由なメモリ区間から割当を行うための関数を保持しています。</p> +<h3 id="Mark_Bitmap">Mark Bitmap</h3> +<p>マークビットマップは<strong>ChunkBitmap</strong>によって表されます。</p> +<p>マークビットマップはGC Cellごとのビットを持ちます。故に、複数のCellによって構成されているオブジェクトは、ビットマップ中の複数のビットを使います。</p> +<h2 id="Exact_Stack_Rooting_API">Exact Stack Rooting API</h2> +<div class="note"> + <p><strong>注</strong>:GC rootの実装とおよびSpiderMonkey内での使用についての情報となります。SpiderMonkeyを埋め込んで使う場合の、Rooting APIの使用方法については、<a href="“/ja/docs/SpiderMonkey/GC_Rooting_Guide" title='“/ja/docs/SpiderMonkey/GC_Rooting_Guide"'> GC Rooting Guide</a>を参照してください。</p> +</div> +<p>GC rootの実装とおよびSpiderMonkey内での使用についての情報となります。 <a href="/en-US/docs/SpiderMonkey/Internals/GC/Exact_Stack_Rooting" title="/en-US/docs/SpiderMonkey/Internals/GC/Exact_Stack_Rooting">Exact Stack Rooting</a>.</p> +<h2 id="マーキング">マーキング</h2> +<p>TODO(原文ママ)</p> +<h2 id="インクリメンタルマーキング">インクリメンタルマーキング</h2> +<p>インクリメンタルマーキングは、マーキングの最中に(JavaScriptプログラムによる)状態の変更が発生しても、他のマーキング作業の実行が可能であることを意味します。つまり、マーキングによる長時間のプログラムの実行の停止の代わりに、小さな停止の集まりがGCの実行となるのです。停止時間は10msもしくはそれ以下に抑えられます。</p> +<p>長時間の停止が必要となる可能性も常に存在します。インクリメンタルGCの間のメモリ割当の頻度が高い場合、エンジンはインクリメンタルGCの完了の前にout of memoryを実行するかもしれません。そのような場合、エンジンは幾つかのメモリーの返還とプログラムの実行の継続のために、非インクリメンタルな完全なGCを直ちに再実行しなくてはなりません。</p> +<h3 id="Incremental_write_barrier(インクリメンタル書き込みバリア)">Incremental write barrier(インクリメンタル書き込みバリア)</h3> +<h4 id="write_barrierを必要とする問題">write barrierを必要とする問題</h4> +<p>インクリメンタルGCは正確性の担保のためにwrite barrierを必要とします。</p> +<p>TODO(原文ママ)、基本的な問題を表す図を用意する<img alt="Very poor diagram showing IGC hazard that requires a write barrier" src="https://mdn.mozillademos.org/files/5187/IGC-hazard.png" style="width: 640px; height: 400px;"></p> +<p>基本的な問題は以下の通りです(色の説明については、辞書を参照)。オブジェクトAはblackかつポインタ領域を所持しています。オブジェクトBはwhiteとします。ここで、インクリメンタルなスライスが止まり、プログラムの実行による状態の変更が再開しました。プログラムがBをAに保存したことにより、AはBへのポインタを持つことになります。そして、Bへのすべての既存のポインタが削除されました。そのとき、</p> +<ul> + <li>Bは生存している。なぜならAはblackであり、Bへのポインタを含んでいるから。</li> + <li>Bはマーク作業が実行されない。なぜならBはAを介してのみ到達可能であり、Aがblackである故にAはすでにマーク作業が完了しているから。</li> + <li>以上により、Bは生存しているが、GCの回収対象となってしまう。</li> +</ul> +<p>write barrierは、ポインタの保存の発生前に実行され、生存しているオブジェクトが回収されないようにするために情報を記録する機構の一つです。</p> +<h4 id="SpiderMonkeyのincremental_write_barrier">SpiderMonkeyのincremental write barrier</h4> +<p>SpiderMonkeyは、(相対的に)シンプルな、s<strong>snapshot-at-the-beginning allocate-black barrier</strong>と呼ばれる一般的なincremental write barrierを用いています。</p> +<p>このバリアの動作を理解するために、事象を単純にするために、新規にオブジェクトが割り当てられることの無いインクリメンタルGCを仮定します。生存しているオブジェクトを回収しないようにするためにはどうすればよいでしょうか? 一つの方法としては、インクリメンタルGCの最初の時点で生存していたすべてのオブジェクトをマークするという手法があります(これは、オブジェクトへの全ての参照が現在のインクリメンタルGC中に消えた場合は、次のインクリメンタルGC時にそのオブジェクトが回収されるということです)。この手法は、インクリメンタルGCの開始時に生存しているオブジェクトのスナップショットを保存し、それら全てをマークするのと<em>コンセプト上は</em>同義であるために、<strong>snapshot-at-the-beginning</strong>と呼ばれています。実際にはスナップショットを撮る訳ではありません。そのような場合は完全な非インクリメンタルなマーク作業が必要となります。</p> +<p style="">snapshot-at-the-beginningバリアの実装は単純です。GCポインタを保持する場所がプログラムによって上書きされたタイミングで、バリアは開始します。バリアは単純にポインタによって指し示されているオブジェクトをblackにします。鍵となるのは、オブジェクトへの全てのポインタが上書きされた場合にのみ、オブジェクトはマークされず”死んだもの”となりうるという点です。そのため、オブジェクトへのポインタが上書きされたタイミングでオブジェクトをblackにすれば、オブジェクトが”死ぬ”ということは発生し得ないのです。</p> +<p style="">FIXME(原文ママ):指し示されたオブジェクトをblackにするだけは十分ではないと思います。マークされていない別のオブジェクトがあったら何がおこりますか? マークスタックについても言及すべきです。「指し示されているオブジェクトをblackにする」というのは、「再帰的に指し示されたオブジェクトをblackにする」という意味で書かれていますか?</p> +<p>これで、メモリの割当の正確性についても話します。新規に割り当てられたオブジェクトはGCの開始時には存在していませんでした。snapshot-at-the-beginningバリアはこれについては巧くカバーしません。ですが、もし新規に割り当てられたオブジェクトが生存している場合は、それが回収されないようにする必要があります。これは簡単で、インクリメンタルGC中に新規にオブジェクトが割り当てられたら、それをマークすれば良いのです。これを名付けて<strong>allocate-black</strong>と言います。</p> +<h4 id="SpiderMonkeyの_incremental_read_barrier(インクリメンタル読み取りバリア)">SpiderMonkeyの incremental read barrier(インクリメンタル読み取りバリア)</h4> +<p>インクリメンタルGCの教科書的な実装では、write barrierしかありません。SpiderMonkeyでは、weak pointer(用語集参照)のためにread barrierも用意しています。</p> +<p>TODO(原文ママ):解説の完成</p> +<h4 id="実装の詳細">実装の詳細</h4> +<p>write barrierは実行時のコストを伴うので、SpiderMonkeyはインクリメンタルGCの実行中以外ではスキップするようにしています。各compartmentの<code>needsBarrier()</code>フラグによって、バリアが必要かどうかを示しています。</p> +<p><code>T*</code>型のフィールドのように、全ての<code>T</code>型はwrite barrierを必要としており、<code>T::writeBarrierPre(old)</code>という関数が存在しています。たとえば、<code>JSObject*</code>がwrite barrierを必要とする場合、関数<code>ObjectImpl::writeBarrierPre(ObjectImpl *old)</code>が存在します(<code>JSObject</code>は<code>ObjectImpl</code>を継承しています。)。 <code><strong>zone->needsBarrier()</strong></code>がtrueである場合、<code>writeBarrierPre()</code>は<code>old</code>をマークする、ということです。</p> +<p>HeapPtr<t>クラスはwrite barrierの起動を簡単にするために提供されています。HeapPtr<t>は<strong><code>T*</code></strong>をカプセル化し、割当時にwrite barrierを起動します。これにより、GCポインタ型のオブジェクトの領域は、通常、HeapPtr<T><t>として定義されています。<strong>HeapValue</strong>クラスはValueに対して同じことを行います。<strong>HeapSlot</strong>(および関連する<strong>HeapSlotArray</strong>)も同様に、オブジェクトスロットに対するものです。<strong>HeapId</strong>は、同じくjsidに対する物です。TODO(原文ママ):なぜHeapValueとHeapSlotの2つが存在するのか</t></t></t></p> +<p>オブジェクトのプライベート領域は、特別に取り扱う必要があります。プライベート領域自体は、エンジンに対しては隠されていますが、マークされる必要があるものを指し示すかもしれません(例:JSObjectのポインタの配列)。この例では、プライベート領域が上書きされた場合、JSObjectのポインタは”死ぬ”ことになります。そのため、write barrierはそれらをマークしなければなりません。<strong>ObjectImpl::privateWriteBarrierPre</strong>はプライベート領域が上書きされる前にJSObjectクラスのトレースフックによって起動され、これに対処します。</p> +<p>他の詳細事項として、write barrierは新規に確保されたオブジェクトのフィールドの初期化時には、上書きされるポインタが存在しないことから、スキップすることができます。</p> +<h2 id="Sweeping(スイーピング)">Sweeping(スイーピング)</h2> +<p>TODO(原文ママ)</p> +<h2 id="世代別GC">世代別GC</h2> +<p>TODO(原文ママ)</p> +<h2 id="GC統計API">GC統計API</h2> +<p>実行時に<a href="“/ja/docs/SpiderMonkey/Internals/GC/Statistics_API" title='“/ja/docs/SpiderMonkey/Internals/GC/StatisticsAPI"'>GC統計API</a>.を通じて、GCが保持する明確な統計情報にアクセスする事ができます。</p> +<h2 id="ソースファイル">ソースファイル</h2> +<p><strong>jsgc{.h,inlines.h,.cpp}</strong> GCを起動するためのエントリーポイントを含む内部API関数群を定義します。</p> +<p><strong>jsgcstats.{h,cpp}</strong> 保守的なスタックスキャンに基づく情報収集のための構造体ConservativeGCStatsを定義します。TODO(原文ママ):削除されたときに消す</p> +<p><strong>gc/Barrier[-inl].h</strong> インクリメンタルおよび世代別用のwrite barrierを実装しています。</p> +<p><strong>gc/Heap.h</strong> GCのヒープ構造の根幹を成す、<code>Chunk</code>, <code>ChunkInfo</code>, <code>ChunkBitmap</code>, <code>Arena</code>, <code>ArenaHeader</code>, <code>Cell</code>, <code>FreeSpan</code>といった一連の構造体を定義します。</p> +<p><strong>gc/Marking.{h,cpp}</strong> 多様なGC対象用のマーク作業関数の全てを定義します。</p> +<p><strong>gc/Memory.{h,cpp}</strong> ページの配置と解放(mapping and unmapping)のための僅かな関数に加えて、プラットフォーム固有の実装を保持しています。配置・解放(map/unmap)用の関数はチャンクの確保と解放(allocate and release )用のために、 jsgc.cppによって使用されています。使用されておらずディスクに格納する代わりメモリ破棄が可能なページをOS伝えるなどに用いる、確保または解放(commit or decommit)のための関数もあります。</p> +<p><strong>gc/Root.h</strong> GCルートとして用いられる変数クラスを定義します。</p> +<p><strong>gc/Statistics.{h,cpp}</strong> SpiderMonkey GCのパフォーマンスカウンタとして保存される Statics構造体を定義しています。</p> +<h2 id="用語の解説">用語の解説</h2> +<p>TODO(原文ママ): SpiderMonkeyの実装と色の名前が一致しているかを確認</p> +<p><strong>black(黒)</strong>一般的な計算機科学の文脈において、マークフェイズ中、マーク済かつ子供がgray(マークキューに積まれている)なオブジェクトをblackとします。SpiderMonkeyでは、マークビットが設定されたオブジェクトをblackと見なします。</p> +<p><strong>gray(灰色)</strong>:一般的な計算機科学の文脈において、マークフェイズ中、マークキューに積まれているオブジェクトをgrayとします。SpiderMonkeyでは、マークスタック内のオブジェクトの子孫かつblackで無いものはgrayとなります。つまり、状態が明白でないオブジェクトがgrayであるということです。</p> +<p><strong>Handle(ハンドル)</strong> 私たちのGCでは、Handleはルートによって登録されたどこかを指し示すポインタです。</p> +<p><strong>root</strong> TODO(原文ママ): 上からコピーする</p> +<p><strong>weak pointer(弱参照ポインタ)</strong> 一般的な計算機科学の文脈において、weak pointerはGC目的で指し示された値が生存し続ける必要がなくなるポインタです。具体的には、既にポインタの指し示す対象が既にGCされている場合は、weak pointerのget()メソッドが返す値はnullポインタとなります。Gecko/SpiderMonkeyでは、weak pointerはマークされていないがGC対象となりうるオブジェクトへのポインタとなります。そのため、get()メソッドは存在せず、指し示す値がGCされたかどうかの保証も存在しません。プログラマは、指し示されたオブジェクトの生存時間が、weak pointerの生存時間よりも長いことを保証する必要があります。TODO(原文ママ) これが正しいか確認。</p> +<p><strong>white(白)</strong> 一般的な計算機科学の文脈において、マークフェイズ中、まだ辿れていないオブジェクトはwhiteとなります。マークされなかった場合、マークフェイズの後にオブジェクトはwhiteとなります。SpiderMonkeyでは、grayでもblackでもない(blackでもマークスタック内のオブジェクトの子でもない)オブジェクトがwhiteとなります。</p> +<h2 id="クリーンアップの可能性">クリーンアップの可能性</h2> +<p><strong>MarkPagesInUse</strong> はすべてのプラットフォームで何の操作も実施しません。</p> +<p>統計ファイルのマージ。</p> +<p><code>ArenaLists::refillFreeLists</code>は悪いネーミングです。それは、たとえ<code>Arena</code>の解放リストが完全ではなくても、<code>Cell</code>の確保を試みるように見えます。</p> diff --git a/files/ja/mozilla/projects/spidermonkey/internals/index.html b/files/ja/mozilla/projects/spidermonkey/internals/index.html new file mode 100644 index 0000000000..49e8157aa7 --- /dev/null +++ b/files/ja/mozilla/projects/spidermonkey/internals/index.html @@ -0,0 +1,290 @@ +--- +title: Internals +slug: Mozilla/Projects/SpiderMonkey/Internals +tags: + - JavaScript + - SpiderMonkey + - 要更新 + - 要翻訳 +translation_of: Mozilla/Projects/SpiderMonkey/Internals +--- +<div>{{SpiderMonkeySidebar("Internals")}}</div> + +<h2 id="Design_walk-through" name="Design_walk-through">設計</h2> + +<p>SpiderMonkey は型付けされていないバイトコードと JavaScript で扱いうる値を表す<code><a href="https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/JSAPI_Reference/JS::Value" title="https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/JSAPI_Reference/JS::Value"> JS::Value </a></code>型に対する演算を高速に行えるインタプリタです。Just-In-Time (JIT) コンパイラやガベージコレクションの機構を備え、JavaScript の値が持つ基本的な振る舞いと <a href="http://www.ecma-international.org/ecma-262/5.1/#sec-15">ECMA 262-5.1 §15</a> とその他の拡張で定義された標準ライブラリを実装し、いくつかのパブリックな API が提供されています。</p> + +<h3 id="インタプリタ">インタプリタ</h3> + +<p>多くの移植可能なインタプリタと同様、SpiderMonkey のインタプリタは主に単一の長大な関数として実装されています。バイトコードを 1 つずつ実行され、現在の命令に対応するコードへの分岐は <code>switch </code>文を利用して行われます(コンパイラによっては、より高速な手法が利用されます)。JS で記述された関数同士の呼び出し時にはJavaScript のスタックフレームが伸長し、C のスタックは消費されません。一方 JS で記述された関数から、C で定義された関数を呼び出し、また JS で記述された関数を呼ぶような場合は、コールスタックは通常通りに消費されるため、インタプリタは再突入可能となっています。</p> + +<p>SpiderMonkey バイトコードの処理には、引数の型による多くの特例が存在します。通常はインタプリタのループ内で処理されますが、邪魔な抽象化を無視する場合もあります。密な配列やプロパティキャッシュのような最適化は、<code>jsinterp.cpp</code> に定義されている <code>jsarray.*</code> や <code>jsobj.*</code> によって隠蔽され、透過的に行われるわけでは「ありません」。</p> + +<p>インタプリタに関する状態は、インタプリタのエントリポイントに引数として渡されます。暗黙的な状態は <code><a href="/en-US/docs/SpiderMonkey/JSAPI_Reference/JSRuntime" title="SpiderMonkey/JSAPI_Reference/JSRuntime">JSContext</a></code> 型の値にまとめられており、API であろうがなかろうが、SpiderMonkey のすべての関数は第 1 引数に、JSContext 型のポインタをとります。</p> + +<h3 id="コンパイラ">コンパイラ</h3> + +<p>コンパイラは JavaScript のソースコードを処理し、<em>script</em> を生成します。script にはバイトコードとそのソースコード、ソースに対するアノテーション、文字列、数値、識別子のリテラルが含まれます。またソースコード中で定義されている関数も含む、オブジェクトも script には含まれます。それぞれの関数は入れ子になった script を保持します。</p> + +<p>The compiler consists of: a random-logic rather than table-driven lexical scanner, a recursive-descent parser that produces an AST, and a tree-walking code generator. Semantic and lexical feedback are used to disambiguate hard cases such as missing semicolons, assignable expressions ("lvalues" in C parlance), and whether <code>/</code> is the division symbol or the start of a regular expression. The compiler attempts no error recovery; it bails out on the first error. The emitter does some constant folding and a few codegen optimizations; about the fanciest thing it does is to attach source notes to the script for the decompiler's benefit.</p> + +<p>The decompiler implements <code>Function.toSource()</code>, which reconstructs a function's source code. It translates postfix bytecode into infix source by consulting a separate byte-sized code, called <em>source notes</em>, to disambiguate bytecodes that result from more than one grammatical production.</p> + +<h3 id="Garbage_collector">Garbage collector</h3> + +<p>The GC is a mark-and-sweep, non-conservative (exact) collector. It is used to hold JS objects and string descriptors (<a href="http://dxr.mozilla.org/mozilla-central/source/js/src/vm/String.h">JSString</a>), but not string bytes. It runs automatically only when maxbytes (as passed to <code><a href="/en-US/docs/SpiderMonkey/JSAPI_Reference/JS_NewRuntime" title="SpiderMonkey/JSAPI_Reference/JS_NewRuntime">JS_NewRuntime</a></code>) bytes of GC things have been allocated and another thing-allocation request is made. JS API users should call <code><a href="/en-US/docs/SpiderMonkey/JSAPI_Reference/JS_GC" title="SpiderMonkey/JSAPI_Reference/JS_GC">JS_GC</a></code> or <code><a href="/en-US/docs/SpiderMonkey/JSAPI_Reference/JS_MaybeGC" title="SpiderMonkey/JSAPI_Reference/JS_MaybeGC">JS_MaybeGC</a></code> between script executions or from the <a href="https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/JSAPI_reference/JS_SetOperationCallback" title="https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/JSAPI_reference/JS_SetOperationCallback">operation callback</a>, as often as necessary.</p> + +<p>Because the GC is exact, C/C++ applications must ensure that all live objects, strings, and numbers are GC-reachable.</p> + +<h3 id="JavaScript_values">JavaScript values</h3> + +<p>The type <code><a href="https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/JSAPI_Reference/JS::Value" title="https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/JSAPI_Reference/JS::Value">JS::Value</a></code> represents a JavaScript value.</p> + +<p>The representation is 64 bits and uses NaN-boxing on all platforms, although the exact NaN-boxing format depends on the platform. NaN-boxing is a technique based on the fact that in IEEE-754 there are 2**47 different bit patterns that all represent NaN. Hence, we can encode any floating-point value as a C++ <code>double </code>(noting that JavaScript NaN must be represented as one canonical NaN format). Other values are encoded as a value and a type tag:</p> + +<ul> + <li>On x86, ARM, and similar 32-bit platforms, we use what we call "nunboxing", in which non-<code>double </code>values are a 32-bit type tag and a 32-bit payload, which is normally either a pointer or a signed 32-bit integer. There are a few special values: <code>NullValue()</code>, <code>UndefinedValue()</code>, <code>TrueValue()</code> and <code>FalseValue().</code></li> + <li>On x64 and similar 64-bit platforms, pointers are longer than 32 bits, so we can't use the nunboxing format. Instead, we use "punboxing", which has 17 bits of tag and 47 bits of payload.</li> +</ul> + +<p>Only JIT code really depends on the layout--everything else in the engine interacts with values through functions like <code>val.isDouble()</code>. Most parts of the JIT also avoid depending directly on the layout: the files <code>PunboxAssembler.h</code> and <code>NunboxAssembler.h</code> are used to generate native code that depends on the value layout.</p> + +<p>Objects consist of a possibly shared structural description, called the map or scope; and unshared property values in a vector, called the slots. Each property has an <a href="/en-US/docs/SpiderMonkey/JSAPI_Reference/jsid" title="SpiderMonkey/JSAPI_Reference/jsid">id</a>, either a nonnegative integer or an atom (unique string), with the same tagged-pointer encoding as a <code>jsval</code>.</p> + +<p>The atom manager consists of a hash table associating strings uniquely with scanner/parser information such as keyword type, index in script or function literal pool, etc. Atoms play three roles: as literals referred to by unaligned 16-bit immediate bytecode operands, as unique string descriptors for efficient property name hashing, and as members of the root GC set for exact GC.</p> + +<h3 id="Standard_library">Standard library</h3> + +<p>The methods for arrays, booleans, dates, functions, numbers, and strings are implemented using the JS API. Most are <code><a href="/en-US/docs/SpiderMonkey/JSAPI_Reference/JSFastNative" title="SpiderMonkey/JSAPI_Reference/JSFastNative">JSFastNative</a></code>s. Most string methods are customized to accept a primitive string as the <code>this</code> argument. (Otherwise, SpiderMonkey converts primitive values to objects before invoking their methods, per <span class="pl-s1"><span class="pl-s">ECMA 262-3 §</span></span>11.2.1.)</p> + +<h3 id="Error_handling">Error handling</h3> + +<p>SpiderMonkey has two interdependent error-handling systems: JavaScript exceptions (which are <em>not</em> implemented with, or even compatible with, any kind of native C/C++ exception handling) and error reporting. In general, both functions inside SpiderMonkey and JSAPI callback functions signal errors by calling <code><a href="/en-US/docs/SpiderMonkey/JSAPI_Reference/JS_ReportError" title="SpiderMonkey/JSAPI_Reference/JS_ReportError">JS_ReportError</a></code> or one of its variants, or <code><a href="/en-US/docs/SpiderMonkey/JSAPI_Reference/JS_SetPendingException" title="SpiderMonkey/JSAPI_Reference/JS_SetPendingException">JS_SetPendingException</a></code>, and returning <code><a href="/en-US/docs/SpiderMonkey/JSAPI_Reference/JSBool" title="SpiderMonkey/JSAPI_Reference/JSBool">JS_FALSE</a></code> or <code>NULL</code>.</p> + +<h3 id="Public_APIs">Public APIs</h3> + +<p>The public C/C++ interface, called the JSAPI, is in most places a thin (but source-compatible across versions) layer over the implementation. See the <a href="/en-US/docs/SpiderMonkey/JSAPI_User_Guide" title="JSAPI_User_Guide">JSAPI User Guide</a>. There is an additional public API for JavaScript debuggers, <a href="/en-US/docs/JSDBGAPI_Reference" title="JSDBGAPI_Reference">JSDBGAPI</a>, but {{Source("js/jsd/jsdebug.h")}} might be a better API for debuggers. Another API, <a href="/en-US/docs/JSXDRAPI" title="JSXDRAPI">JSXDRAPI</a>, provides serialization for JavaScript scripts. (XUL Fastload uses this.)</p> + +<h3 id="Just-In-Time_compiler">Just-In-Time compiler</h3> + +<p>SpiderMonkey contains a <a href="https://blog.mozilla.org/javascript/2013/04/05/the-baseline-compiler-has-landed/">baseline compiler</a> as first tier. A second tier JIT, code-named <em>IonMonkey</em> was enabled in <a href="https://blog.mozilla.org/javascript/2012/09/12/ionmonkey-in-firefox-18/" title="https://blog.mozilla.org/javascript/2012/09/12/ionmonkey-in-firefox-18/">Firefox 18</a>. <a href="https://wiki.mozilla.org/IonMonkey">IonMonkey</a> is an optimizing compiler.</p> + +<h3 id="Self-hosting_of_built-in_functions_in_JS">Self-hosting of built-in functions in JS</h3> + +<p>Starting with Firefox 17, SpiderMonkey has the ability to implement built-in functions in self-hosted JS code. This code is compiled in a special compilation mode that gives it access to functionality that's not normally exposed to JS code, but that's required for safe and specification-conformant implementation of built-in functions.</p> + +<p>All self-hosted code lives in <code>.js</code> files under <code>builtin/</code>. For details on implementing self-hosted built-ins, see <a href="/en-US/docs/SpiderMonkey/Internals/self-hosting" title="SpiderMonkey/self-hosting">self-hosting</a>.</p> + +<h2 id="File_walkthrough" name="File_walkthrough">File walkthrough</h2> + +<h4 id="jsapi.cpp.2C_jsapi.h" name="jsapi.cpp.2C_jsapi.h">jsapi.cpp, jsapi.h</h4> + +<p>The public API to be used by almost all client code.</p> + +<h4 id="jspubtd.h.2C_jsprvtd.h" name="jspubtd.h.2C_jsprvtd.h">jspubtd.h, jsprvtd.h</h4> + +<p>These files exist to group struct and scalar typedefs so they can be used everywhere without dragging in struct definitions from N different files. The <code>jspubtd.h</code> file contains public typedefs, and is included automatically when needed. The <code>jsprvtd.h</code> file contains private typedefs and is included by various .h files that need type names, but not type sizes or declarations.</p> + +<h4 id="jsdbgapi.cpp.2C_jsdbgapi.h" name="jsdbgapi.cpp.2C_jsdbgapi.h">jsdbgapi.cpp, jsdbgapi.h</h4> + +<p>The debugging API. Provided so far:</p> + +<p><strong>Traps</strong>, with which breakpoints, single-stepping, step over, step out, and so on can be implemented. The debugger will have to consult jsopcode.def on its own to figure out where to plant trap instructions to implement functions like step out, but a future jsdbgapi.h will provide convenience interfaces to do these things. At most one trap per bytecode can be set. When a script (<code><a href="/en-US/docs/JSScript" title="JSScript">JSScript</a></code>) is destroyed, all traps set in its bytecode are cleared.</p> + +<p><strong>Watchpoints</strong>, for intercepting set operations on properties and running a debugger-supplied function that receives the old value and a pointer to the new one, which it can use to modify the new value being set.</p> + +<p><strong>Line number</strong> to PC and back mapping functions. The line-to-PC direction "rounds" toward the next bytecode generated from a line greater than or equal to the input line, and may return the PC of a for-loop update part, if given the line number of the loop body's closing brace. Any line after the last one in a script or function maps to a PC one byte beyond the last bytecode in the script. An example, from perfect.js:</p> + +<pre class="brush:js;first-line:14">function perfect(n) { + print("The perfect numbers up to " + n + " are:"); + // We build sumOfDivisors[i] to hold a string expression for + // the sum of the divisors of i, excluding i itself. + var sumOfDivisors = new ExprArray(n + 1, 1); + for (var divisor = 2; divisor <= n; divisor++) { + for (var j = divisor + divisor; j <= n; j += divisor) { + sumOfDivisors[j] += " + " + divisor; + } + // At this point everything up to 'divisor' has its sumOfDivisors + // expression calculated, so we can determine whether it's perfect + // already by evaluating. + if (eval(sumOfDivisors[divisor]) == divisor) { + print("" + divisor + " = " + sumOfDivisors[divisor]); + } + } + delete sumOfDivisors; + print("That's all."); +}</pre> + +<p>The line number to PC and back mappings can be tested using the js program with the following script:</p> + +<pre class="brush:js">load("perfect.js"); +print(perfect); +dis(perfect); +print(); +for (var ln = 0; ln <= 40; ln++) { + var pc = line2pc(perfect, ln); + var ln2 = pc2line(perfect, pc); + print("\tline " + ln + " => pc " + pc + " => line " + ln2); +} +</pre> + +<p>The result of the for loop over lines 0 to 40 inclusive is:</p> + +<pre>line 0 => pc 0 => line 16 +line 1 => pc 0 => line 16 +line 2 => pc 0 => line 16 +line 3 => pc 0 => line 16 +line 4 => pc 0 => line 16 +line 5 => pc 0 => line 16 +line 6 => pc 0 => line 16 +line 7 => pc 0 => line 16 +line 8 => pc 0 => line 16 +line 9 => pc 0 => line 16 +line 10 => pc 0 => line 16 +line 11 => pc 0 => line 16 +line 12 => pc 0 => line 16 +line 13 => pc 0 => line 16 +line 14 => pc 0 => line 16 +line 15 => pc 0 => line 16 +line 16 => pc 0 => line 16 +line 17 => pc 19 => line 20 +line 18 => pc 19 => line 20 +line 19 => pc 19 => line 20 +line 20 => pc 19 => line 20 +line 21 => pc 36 => line 21 +line 22 => pc 53 => line 22 +line 23 => pc 74 => line 23 +line 24 => pc 92 => line 22 +line 25 => pc 106 => line 28 +line 26 => pc 106 => line 28 +line 27 => pc 106 => line 28 +line 28 => pc 106 => line 28 +line 29 => pc 127 => line 29 +line 30 => pc 154 => line 21 +line 31 => pc 154 => line 21 +line 32 => pc 161 => line 32 +line 33 => pc 172 => line 33 +line 34 => pc 172 => line 33 +line 35 => pc 172 => line 33 +line 36 => pc 172 => line 33 +line 37 => pc 172 => line 33 +line 38 => pc 172 => line 33 +line 39 => pc 172 => line 33 +line 40 => pc 172 => line 33 +</pre> + +<h4 id="jsconfig.h" name="jsconfig.h">jsconfig.h</h4> + +<p>Various configuration macros defined as 0 or 1 depending on how <code><a href="/en-US/docs/JS_VERSION" title="JS_VERSION">JS_VERSION</a></code> is defined (as 10 for JavaScript 1.0, 11 for JavaScript 1.1, etc.). Not all macros are tested around related code yet. In particular, JS 1.0 support is missing from SpiderMonkey.</p> + +<h4 id="js.cpp.2C_jsshell.msg" name="js.cpp.2C_jsshell.msg">js.cpp, jsshell.msg</h4> + +<p>The "JS shell", a simple interpreter program that uses the JS API and more than a few internal interfaces (some of these internal interfaces could be replaced by <code>jsapi.h</code> calls). The js program built from this source provides a test vehicle for evaluating scripts and calling functions, trying out new debugger primitives, etc.</p> + +<p>A look at the places where <code>jsshell.msg</code> is used in <code>js.cpp</code> shows how error messages can be handled in JSAPI applications. These messages can be localized at compile time by replacing the <code>.msg</code> file; or, with a little modification to the source, at run time.</p> + +<p><a href="/en-US/docs/SpiderMonkey/Introduction_to_the_JavaScript_shell" title="https://developer.mozilla.org/en/introduction_to_the_javascript_shell">More information on the JavaScript shell</a>.</p> + +<h4 id="js.msg" name="js.msg">js.msg</h4> + +<p>SpiderMonkey error messages.</p> + +<h4 id="jsarray..2A.2C_jsbool..2A.2C_jdsdate..2A.2C_jsfun..2A.2C_jsmath..2A.2C_jsnum..2A.2C_jsstr..2A" name="jsarray..2A.2C_jsbool..2A.2C_jdsdate..2A.2C_jsfun..2A.2C_jsmath..2A.2C_jsnum..2A.2C_jsstr..2A">jsarray.*, jsbool.*, jsdate.*, jsfun.*, jsmath.*, jsnum.*, jsstr.*</h4> + +<p>These file pairs implement the standard classes and (where they exist) their underlying primitive types. They have similar structure, generally starting with class definitions and continuing with internal constructors, finalizers, and helper functions.</p> + +<h4 id="jsobj..2A.2C_jsscope..2A" name="jsobj..2A.2C_jsscope..2A">jsobj.*, jsscope.*</h4> + +<p>These two pairs declare and implement the JS object system. All of the following happen here:</p> + +<ul> + <li>creating objects by class and prototype, and finalizing objects;</li> + <li>defining, looking up, getting, setting, and deleting properties;</li> + <li>creating and destroying properties and binding names to them.</li> +</ul> + +<p>The details of a native object's map (scope) are mostly hidden in <code>jsscope.{{mediawiki.external('ch')}}</code>.</p> + +<h4 id="jsatom.cpp.2C_jsatom.h" name="jsatom.cpp.2C_jsatom.h">jsatom.cpp, jsatom.h</h4> + +<p>The atom manager. Contains well-known string constants, their atoms, the global atom hash table and related state, the js_Atomize() function that turns a counted string of bytes into an atom, and literal pool (<code>JSAtomMap</code>) methods.</p> + +<h4 id="jsarena.cpp.2C_jsarena.h" name="jsarena.cpp.2C_jsarena.h">jsarena.cpp, jsarena.h</h4> + +<p>Last-In-First-Out allocation macros that amortize malloc costs and allow for en-masse freeing. See the paper mentioned in <code>jsarena.h</code>'s major comment.</p> + +<h4 id="jsgc.cpp.2C_jsgc.h" name="jsgc.cpp.2C_jsgc.h">jsgc.cpp, jsgc.h</h4> + +<p>The garbage collector and tracing routines.</p> + +<h4 id="jsinterp..2A.2C_jscntxt..2A.2C_jsinvoke.cpp" name="jsinterp..2A.2C_jscntxt..2A.2C_jsinvoke.cpp">jsinterp.*, jscntxt.*, jsinvoke.cpp</h4> + +<p>The bytecode interpreter, and related functions such as Call and AllocStack, live in <em>jsinterp.cpp</em>. The JSContext constructor and destructor are factored out into <em>jscntxt.cpp</em> for minimal linking when the compiler part of JS is split from the interpreter part into a separate program.</p> + +<p><code>jsinvoke.cpp</code> is a build hack used on some platforms to build <code>js_Interpret</code> under different compiler options from the rest of <code>jsinterp.cpp</code>.</p> + +<h4 id="jstracer.*_nanojit*">jstracer.*, nanojit/*</h4> + +<p><a href="/en-US/docs/SpiderMonkey/Internals/Tracing_JIT" title="SpiderMonkey/Internals/Tracing JIT">The tracing JIT</a>. The interface between the JIT and the rest of SpiderMonkey is conceptually small—the interpreter calls into the trace recorder—but as with everything else, there are tendrils everywhere.</p> + +<h4 id="jsemit..2A.2C_jsopcode.tbl.2C_jsopcode..2A.2C_jsparse..2A.2C_jsscan..2A.2C_jsscript..2A" name="jsemit..2A.2C_jsopcode.tbl.2C_jsopcode..2A.2C_jsparse..2A.2C_jsscan..2A.2C_jsscript..2A">jsemit.*, jsopcode.tbl, jsopcode.*, jsparse.*, jsscan.*, jsscript.*</h4> + +<p>Compiler and decompiler modules. The <em>jsopcode.tbl</em> file is a C preprocessor source that defines almost everything there is to know about JS bytecodes. See its major comment for how to use it. For now, a debugger will use it and its dependents such as <em>jsopcode.h</em> directly, but over time we intend to extend <em>jsdbgapi.h</em> to hide uninteresting details and provide conveniences. The code generator is split across paragraphs of code in <em>jsparse.cpp</em>, and the utility methods called on <code>JSCodeGenerator</code> appear in <em>jsemit.cpp</em>. Source notes generated by <em>jsparse.cpp</em> and <em>jsemit.cpp</em> are used in <em>jsscript.cpp</em> to map line number to program counter and back.</p> + +<h4 id="jstypes.h" name="jstypes.h">jstypes.h</h4> + +<p>Fundamental representation types and utility macros. This file alone among all .h files in SpiderMonkey must be included first by .cpp files. It is not nested in .h files, as other prerequisite .h files generally are, since it is also a direct dependency of most .cpp files and would be over-included if nested in addition to being directly included.</p> + +<h4 id="jsbit.h.2C_jslog2.cpp" name="jsbit.h.2C_jslog2.cpp">jsbit.h, jslog2.cpp</h4> + +<p>Bit-twiddling routines. Most of the work here is selectively enabling compiler-specific intrinsics such as GCC's <code>__builtin_ctz</code>, which is useful in calculating base-2 logarithms of integers.</p> + +<h4 id="jsutil.cpp.2C_jsutil.h" name="jsutil.cpp.2C_jsutil.h">jsutil.cpp, jsutil.h</h4> + +<p>The <code>JS_ASSERT</code> macro is used throughout the source as a proof device to make invariants and preconditions clear to the reader, and to hold the line during maintenance and evolution against regressions or violations of assumptions that it would be too expensive to test unconditionally at run-time. Certain assertions are followed by run-time tests that cope with assertion failure, but only where I'm too smart or paranoid to believe the assertion will never fail...</p> + +<h4 id="jsclist.h" name="jsclist.h">jsclist.h</h4> + +<p>Doubly-linked circular list struct and macros.</p> + +<h4 id="jscpucfg.cpp" name="jscpucfg.cpp">jscpucfg.cpp</h4> + +<p>This standalone program generates <em>jscpucfg.h</em>, a header file containing bytes per word and other constants that depend on CPU architecture and C compiler type model. It tries to discover most of these constants by running its own experiments on the build host, so if you are cross-compiling, beware.</p> + +<h4 id="jsdtoa.cpp.2C_jsdtoa.h.2C_dtoa.c" name="jsdtoa.cpp.2C_jsdtoa.h.2C_dtoa.c">jsdtoa.cpp, jsdtoa.h, dtoa.c</h4> + +<p>dtoa.c contains David Gay's portable double-precision floating point to string conversion code, with Permission To Use notice included. jsdtoa.cpp <code>#include</code>s this file.</p> + +<h4 id="jshash.cpp.2C_jshash.h.2C_jsdhash.cpp.2C_jsdhash.h" name="jshash.cpp.2C_jshash.h.2C_jsdhash.cpp.2C_jsdhash.h">jshash.cpp, jshash.h, jsdhash.cpp, jsdhash.h</h4> + +<p>Portable, extensible hash tables. These use multiplicative hash for strength reduction over division hash, yet with very good key distribution over power of two table sizes. jshash resolves collisions via chaining, so each entry burns a malloc and can fragment the heap. jsdhash uses open addressing.</p> + +<h4 id="jslong.cpp.2C_jslong.h" name="jslong.cpp.2C_jslong.h">jslong.cpp, jslong.h</h4> + +<p>64-bit integer emulation, and compatible macros that use intrinsic C types, like <code>long long</code>, on platforms where they exist (most everywhere, these days).</p> + +<h4 id="jsprf..2A" name="jsprf..2A">jsprf.*</h4> + +<p>Portable, buffer-overrun-resistant sprintf and friends. For no good reason save lack of time, the %e, %f, and %g formats cause your system's native sprintf, rather than <code>JS_dtoa()</code>, to be used. This bug doesn't affect SpiderMonkey, because it uses its own <code>JS_dtoa()</code> call in <code>jsnum.cpp</code> to convert from double to string, but it's a bug that we'll fix later, and one you should be aware of if you intend to use a <code>JS_*printf()</code> function with your own floating type arguments - various vendor sprintf's mishandle NaN, +/-Inf, and some even print normal floating values inaccurately.</p> + +<h4 id="prmjtime.c.2C_prmjtime.h" name="prmjtime.c.2C_prmjtime.h">prmjtime.c, prmjtime.h</h4> + +<p>Time functions. These interfaces are named in a way that makes local vs. universal time confusion likely. Caveat emptor, and we're working on it. To make matters worse, Java (and therefore JavaScript) uses "local" time numbers (offsets from the epoch) in its Date class.</p> + +<h4 id="jsfile.cpp.2C_jsfile.h.2C_jsfile.msg" name="jsfile.cpp.2C_jsfile.h.2C_jsfile.msg">jsfile.cpp, jsfile.h, jsfile.msg</h4> + +<p>Obsolete. Do not use these files.</p> + +<h4 id="Makefile.in.2C_build.mk" name="Makefile.in.2C_build.mk">Makefile.in, build.mk</h4> + +<p>Mozilla makefiles. If you're building Gecko or Firefox, the larger build system will use these files. They are also used for current standalone builds.</p> + +<h4 id="Makefile.ref.2C_rules.mk.2C_config.mk.2C_config.2F.2A" name="Makefile.ref.2C_rules.mk.2C_config.mk.2C_config.2F.2A">Makefile.ref, rules.mk, config.mk, config/*</h4> + +<p>Obsolete SpiderMonkey standalone makefiles from 1.8 and earlier. See <a href="/en-US/docs/SpiderMonkey/Build_Documentation#Building_SpiderMonkey_1.8_or_earlier" title="SpiderMonkey/Build Documentation#Building SpiderMonkey 1.8 or earlier">SpiderMonkey Build Documentation</a>.</p> + +<h3 id="See_also">See also</h3> + +<ul> + <li><a href="/jsd" title="jsd">jsd</a></li> +</ul> diff --git a/files/ja/mozilla/projects/spidermonkey/internals/thread_safety/index.html b/files/ja/mozilla/projects/spidermonkey/internals/thread_safety/index.html new file mode 100644 index 0000000000..90bfb3fb10 --- /dev/null +++ b/files/ja/mozilla/projects/spidermonkey/internals/thread_safety/index.html @@ -0,0 +1,56 @@ +--- +title: Thread Safety +slug: Mozilla/Projects/SpiderMonkey/Internals/Thread_Safety +tags: + - JavaScript + - SpiderMonkey +--- +<p>This page describes implementation details of the <a href="/ja/SpiderMonkey" title="ja/SpiderMonkey">SpiderMonkey</a> JavaScript engine. It is mainly of interest to people working on SpiderMonkey itself, but this information is also helpful for anyone embedding SpiderMonkey in a multithreaded environment. See also <code><a href="/ja/JS_THREADSAFE" title="ja/JS_THREADSAFE">JS_THREADSAFE</a></code>.</p> +<p>{{ 英語版章題("General background") }}</p> +<h4 id="General_background" name="General_background">General background</h4> +<p>SpiderMonkeyは、最上位の構造体として<code><a href="/ja/JS_NewRuntime" title="ja/JS_NewRuntime">JSRuntime</a></code>を利用します。これらの構造体は、メモリの管理とグローバルなデータ構造を扱います。 通常の場合プログラムは、多くのスレッドを利用する場合でも、1つだけ<code>JSRuntime</code>を使います。<code>JSRuntime</code>は、JSオブジェクトが動作する 世界といってもよいでしょう。オブジェクトは、他の<code>JSRuntime</code>に移って動作することはできません。 <span class="comment">SpiderMonkey has a top-level struct, <code><a href="/ja/JS_NewRuntime" title="ja/JS_NewRuntime"></code>, that handles, among other things, memory management and "global" data structures. A program typically has only one <code>JSRuntime</code>, even if it has many threads. The <code>JSRuntime</code> is the universe in which JS objects live; they can't travel to other <code>JSRuntime</code>s.</a></span></p> +<p>全てのJSコードとほとんどのJSAPIの呼び出しは、<code><a href="/ja/JS_NewContext" title="ja/JS_NewContext">JSContext</a></code>の中で動作します。<code>JSContext</code>は、 <code>JSRuntime</code>の子供のようなもので、例えば、例外の処理などは、<code>JSContext</code>ごとに実行されます。 各<code>JSContext</code>は、同時に複数スレッドからアクセスしてはなりません。 <span class="comment">All JS code and most JSAPI calls run within a <code><a href="/ja/JS_NewContext" title="ja/JS_NewContext">JSContext</a></code>. The <code>JSContext</code> is a child of the <code>JSRuntime</code>; exception handling, for example, is per-<code>JSContext</code>. Each <code>JSContext</code> must be used by only one thread at a time.</span></p> +<p>オブジェクトは、同じ<code>JSRuntime</code>内の<code>JSContext</code>間で共有できます。コンテキストとオブジェクトの間には、固定的な関係はありません。 <span class="comment">Objects may be shared among <code>JSContext</code>s within a <code>JSRuntime</code>. There's no fixed association between an object and a context.</span></p> +<p>SpiderMonkeyにおけるスレッドセーフ機能は、<code>-DJS_THREADSAFE</code>をつけてコンパイルすることで有効になります。<code><a href="/ja/JS_THREADSAFE" title="ja/JS_THREADSAFE">JS_THREADSAFE</a></code>を有効にしたビルドでは、次のような操作について特別な処理が行われます。 <span class="comment">Thread-safety in SpiderMonkey is turned on by compiling with <code>-DJS_THREADSAFE</code>. In a <code><a href="/ja/JS_THREADSAFE" title="ja/JS_THREADSAFE">JS_THREADSAFE</a></code> build, these operations are handled specially:</span></p> +<ul> <li><code>JSRuntime</code>のデータ構造にアクセスする場合</li> <li>ガーベジコレクションを行う場合</li> <li>オブジェクトのプロパティにアクセスする場合</li> +</ul> +<p><span class="comment">* access to <code>JSRuntime</code> data structures * garbage collection * access to properties of objects</span></p> +<p><code>JSRuntime</code>のデータ構造へのアクセスは、mutexによってシリアライズされます。 GCとプロパティに関する処理については、もう少し詳しく説明します。 <span class="comment">Accesses to <code>JSRuntime</code> data structures are serialized with a few mutexes. The treatment of GC and properties requires more explanation.</span></p> +<p>{{ 英語版章題("Making GC thread-safe") }}</p> +<h4 id="Making_GC_thread-safe" name="Making_GC_thread-safe">Making GC thread-safe</h4> +<p><code>JS_THREADSAFE</code>を用いるときは、APIを若干変更します。プログラム中でJSAPIを呼び出すときは、次に示す"request"で くくらなくてはなりません。 <span class="comment">With <code>JS_THREADSAFE</code>, the API changes slightly. The program must group JSAPI calls into "requests":</span></p> +<pre class="eval"> <a href="/ja/JS_SetContextThread" title="ja/JS_SetContextThread">JS_SetContextThread</a>(cx); + <a href="/ja/JS_BeginRequest" title="ja/JS_BeginRequest">JS_BeginRequest</a>(cx); + /* ... do stuff ... */ + <a href="/ja/JS_EndRequest" title="ja/JS_EndRequest">JS_EndRequest</a>(cx); + <a href="/ja/JS_ClearContextThread" title="ja/JS_ClearContextThread">JS_ClearContextThread</a>(cx); +</pre> +<p>複数のスレッドがrequest内で同じ<code>JSRuntime</code>を同時にアクセスできるため、この操作がボトルネックになることはありません。詳細は<a href="/ja/JS_BeginRequest" title="ja/JS_BeginRequest">JS_BeginRequest</a>を参照してください。 <span class="comment">It isn't a bottleneck; multiple threads are allowed to be in requests on the same <code>JSRuntime</code> at once. See <a href="/ja/JS_BeginRequest" title="ja/JS_BeginRequest">JS_BeginRequest</a>.</span></p> +<p>requestの最も顕著な効果は、いつでも複数のスレッドがrequestのくくりを実行することができるか、1つのスレッドだけがGCを実行していて他のスレッドが停止させられている 用にすることです。JS_GC()を呼び出しても、他のスレッドが停止させられるまでは、処理がブロックされます。つまり、他のスレッドがJSAPIを呼び出していないか (呼び出していないときには、特に注意する必要がないので)、JSAPIを実行中であってもGCが終了するのを待っているブロックしている状態になるまで、 GCの実行は停止させられます。 <span class="comment">The most obvious effect of a request is: at any given moment there can either be multiple threads in active requests, or one thread doing GC and all requests suspended. A call to JS_GC() will block until the latter becomes possible. In other words, GC waits until each other thread is either outside JSAPI (in which case we don't care what it's doing) or else in JSAPI, but blocked, waiting for GC to finish.</span></p> +<p>requestのくくりの中にいないときには、スレッドは、GCに影響を与えるような処理を行ってはいけません。 当たり前のことですが、requestのくくりの中では、GCが抑止されてしまうので、ブロックしたり、時間のかかる処理を行ってはいけません。 <span class="comment">Threads must not do anything that would affect GC while outside a request. And obviously you shouldn't block or otherwise dilly-dally while in a request; it prohibits GC. 最適化のために、スレッドには、スレッドごとの大きさごとに分けられた、割り当て可能なGC用のメモリの集合に関するフリーリストを持っています。 このリストにより、ほとんどの場合ロックせずにメモリを割り当てることができます。スレッドがロックを必要とするのは、スレッドの対応するフリーリストが 空だった場合だけです。このようなことが怒った場合に、ロックして広域のGC割り当てを行い、<code>JSRuntime</code>から、フリーリストに領域を補充します。 <!--As an optimization, each thread has its own size-classified freelists containing chunks of GC-managed memory ready to be allocated. This allows allocation to avoid locking most of the time (a significant speed win). A thread needs to lock on allocation only when the relevant per-thread freelist is empty. When this happens, the thread also refills that freelist from the <code>JSRuntime</code>-wide GC allocator while it's in the lock.</span></p> +<p>{{ 英語版章題("Making property accesses thread-safe") }}</p> +<h4 id="Making_property_accesses_thread-safe" name="Making_property_accesses_thread-safe">Making property accesses thread-safe</h4> +<p>JSAPIのユーザにとっては、プロパティへのアクセスは全てシリアライズされているように見えます。これから記述する方法は、SpiderMonkeyの内部に関するもので ユーザにとっては見えない、最適化についてです。 <span class="comment">To the JSAPI user, all property accesses appear to be serialized. The scheme described below is an optimization, internal to SpiderMonkey and invisible to the user.</span></p> +<p>SpiderMonkeyの実装では、mutableなオブジェクトは必要に応じて暗黙のうちにロックされます。ロックの手順は、うまく最適化されていて、単なるmutexではありません。 <span class="comment">SpiderMonkey implicitly locks mutable objects as needed. The locking protocol is cleverly optimized. It's not a simple mutex.</span></p> +<p>それぞれの、mutableなオブジェクトは、<code>JSContext</code>が"占有"している(つまり、コンテキストがロックをしなくてもプロパティにアクセスできる) か、<code>JSRuntime</code>内の<code>JSContext</code>で、"共有"しているかのいずれかです。(繰り返しになりますが、JSAPIのユーザにとっては、全てのオブジェクトは 共有されており、この"所有関係"は、ユーザには見えないように最適化されています。) <span class="comment">Each mutable object is either "owned" by a <code>JSContext</code>, meaning that context may access its properties without locking; or "shared" across all <code>JSContext</code>s in the <code>JSRuntime</code>. (Again, to the end user, all objects are shared--this "ownership" is a transparent optimization.)</span></p> +<p>初期状態では、オブジェクトの所有者は、オブジェクトを作った<code>JSContext</code.です。他の<code>JSContext</code>がオブジェクトにアクセスしようとするまでは、 ロックは全く必要ではありません。他のコンテキストがアクセスしようとした時点で、<code>JSRuntime</code>の広域ロックを取得します。ただ、この時点においても プロパティへの通常のアクセスは、1つのオブジェクト(つまり、プロパティを持っているオブジェクトのこと)のmutable部分に触る必要があるだけです。 従って、デッドロックは問題になりません。* また、スレッドがロックする必要がある場合でも、オブジェクトを所有しているコンテキストが requestのくくりを実行していないのであれば、コストのかかる他のスレッドとのランデブ**を避けることができます。 <span class="comment">Initially an object is owned by the <code>JSContext</code> in which it was created. Locking is never needed until some other <code>JSContext</code> tries to access the object. At that point, we acquire a <code>JSRuntime</code>-wide lock. But even then, each ordinary property access only needs to touch mutable parts of one object (the one that has the property), so deadlock isn't an issue.* And even though the calling thread must lock, it can still avoid a costly rendezvous** with another thread, if the context that owns the object is not currently in a request.</span></p> +<p>I found it helpful to read the code for <code><a href="http://lxr.mozilla.org/seamonkey/ident?i=OBJ_GET_SLOT" class="external">OBJ_GET_SLOT</a></code>, defined in <a href="http://hg.mozilla.org/mozilla-central/?file/tip/js/src/jsobj.h" class="external">jsobj.h</a>, and track down the various things it calls.</p> +<pre class="eval"> /* Thread-safe functions and wrapper macros for accessing slots in obj. */ + #define OBJ_GET_SLOT(cx,obj,slot) \ + (OBJ_CHECK_SLOT(obj, slot), \ + (OBJ_IS_NATIVE(obj) && OBJ_SCOPE(obj)->ownercx == cx) \ + ? LOCKED_OBJ_GET_SLOT(obj, slot) \ + : js_GetSlotThreadSafe(cx, obj, slot)) +</pre> +<p>Here <code>OBJ_CHECK_SLOT()</code> is just an assertion. <code>LOCKED_OBJ_GET_SLOT()</code> is the fast path; it amounts to an array access. <code>OBJ_SCOPE(obj)->ownercx</code> is the object's owning context, or <code>NULL</code> if the object is "shared". (An <code>OBJ_SCOPE</code> is just a handy place to stick this field; it is often shared across multiple objects, so all this locking is somewhat higher than object-level.)</p> +<p>This may appear unsafe, at least in SMP environments where writing a word isn't guaranteed to make the new value immediately visible to other CPUs. Requests save the day again: entering or leaving a request always briefly acquires a lock, which forces a read-write barrier. This barrier is necessary and sufficient to make several of these optimizations safe.</p> +<p>In short, any <code>JSContext</code> may touch any object, yet not only is locking usually optimized away, the threads don't even have to execute atomic instructions or barrier instructions in the most common path.</p> +<hr> +<p>* deadlock isn't an issue: That is, SpiderMonkey doesn't need any special code to detect and avoid potential deadlock when getting or setting an ordinary property, because it can't happen--you're only locking one object at a time. Assigning to <code>__proto__</code> is an example of a special case: SpiderMonkey checks for prototype chain cycles, which means locking the whole chain. So in that case, and maybe others, SpiderMonkey does extra work to avoid deadlock.</p> +<p>** can still avoid a costly rendezvous: That is, it can avoid "asking" that thread to surrender the object and then waiting for the thread to respond. It just takes the object. See <a href="http://lxr.mozilla.org/seamonkey/ident?i=ClaimScope" class="external">ClaimScope</a> in jslock.c.</p> +<p>{{ 英語版章題("Patent") }}</p> +<h4 id="Patent" name="Patent">Patent</h4> +<p>The SpiderMonkey request model is patented: <a href="http://www.wipo.int/pctdb/en/wo.jsp?wo=2003042845" class=" external" rel="freelink">http://www.wipo.int/pctdb/en/wo.jsp?wo=2003042845</a></p> +<p>The Mozilla Public License in the SpiderMonkey source code grants a worldwide royalty-free license to this invention.</p> + +<p>{{ languages( { "en": "en/SpiderMonkey_Internals/Thread_Safety" } ) }} </p> |
