--- fd33855c148c79e8c576b3d35bd39960e03c5ad5/js/src/vm/Opcodes.h
+++ 1c86d61787a105fd9e868e164dde3486be0cd255/js/src/vm/Opcodes.h
@@ -1900,38 +1900,32 @@
* Category: Functions
* Type: Calls
* Operands:
* Stack: callee, this, args => rval
*/ \
MACRO(StrictSpreadEval, strict_spread_eval, NULL, 1, 3, 1, JOF_BYTE|JOF_INVOKE|JOF_SPREAD|JOF_CHECKSTRICT|JOF_IC) \
/*
* Push the implicit `this` value for an unqualified function call, like
- * `foo()`. `nameIndex` gives the name of the function we're calling.
+ * `foo()`.
*
* The result is always `undefined` except when the name refers to a `with`
* binding. For example, in `with (date) { getFullYear(); }`, the
* implicit `this` passed to `getFullYear` is `date`, not `undefined`.
*
- * This walks the run-time environment chain looking for the environment
- * record that contains the function. If the function call definitely
- * refers to a local binding, use `JSOp::Undefined`.
- *
- * Implements: [EvaluateCall][1] step 1.b. But not entirely correctly.
- * See [bug 1166408][2].
+ * Implements: [EvaluateCall][1] step 1.b.
*
* [1]: https://tc39.es/ecma262/#sec-evaluatecall
- * [2]: https://bugzilla.mozilla.org/show_bug.cgi?id=1166408
*
* Category: Functions
* Type: Calls
- * Operands: uint32_t nameIndex
- * Stack: => this
+ * Operands:
+ * Stack: env => this
*/ \
- MACRO(ImplicitThis, implicit_this, "", 5, 0, 1, JOF_ATOM|JOF_USES_ENV) \
+ MACRO(ImplicitThis, implicit_this, "", 1, 1, 1, JOF_BYTE) \
/*
* Push the call site object for a tagged template call.
*
* `script->getObject(objectIndex)` is the call site object.
*
* The call site object will already have the `.raw` property defined on it
* and will be frozen.
*
@@ -2857,28 +2851,39 @@
* Type: Initialization
* Operands:
* Stack: this => this
*/ \
MACRO(CheckThis, check_this, NULL, 1, 1, 1, JOF_BYTE) \
/*
* Look up a name on the global lexical environment's chain and push the
* environment which contains a binding for that name. If no such binding
- * exists, push the global lexical environment.
+ * exists, push the top-most variables object, which is the global object.
*
* Category: Variables and scopes
* Type: Looking up bindings
* Operands: uint32_t nameIndex
* Stack: => global
*/ \
- MACRO(BindGName, bind_g_name, NULL, 5, 0, 1, JOF_ATOM|JOF_GNAME|JOF_IC) \
+ MACRO(BindUnqualifiedGName, bind_unqualified_g_name, NULL, 5, 0, 1, JOF_ATOM|JOF_GNAME|JOF_IC) \
+ /*
+ * Look up an unqualified name on the environment chain and push the
+ * environment which contains a binding for that name. If no such binding
+ * exists, push the first variables object along the environment chain.
+ *
+ * Category: Variables and scopes
+ * Type: Looking up bindings
+ * Operands: uint32_t nameIndex
+ * Stack: => env
+ */ \
+ MACRO(BindUnqualifiedName, bind_unqualified_name, NULL, 5, 0, 1, JOF_ATOM|JOF_IC|JOF_USES_ENV) \
/*
* Look up a name on the environment chain and push the environment which
* contains a binding for that name. If no such binding exists, push the
- * global lexical environment.
+ * global object.
*
* Category: Variables and scopes
* Type: Looking up bindings
* Operands: uint32_t nameIndex
* Stack: => env
*/ \
MACRO(BindName, bind_name, NULL, 5, 0, 1, JOF_ATOM|JOF_IC|JOF_USES_ENV) \
/*
@@ -3030,25 +3035,28 @@
* Stack: => val
*/ \
MACRO(GetImport, get_import, NULL, 5, 0, 1, JOF_ATOM) \
/*
* Get the value of a binding from the environment `env`. If the name is
* not bound in `env`, throw a ReferenceError.
*
* `env` must be an environment currently on the environment chain, pushed
- * by `JSOp::BindName` or `JSOp::BindVar`.
+ * by `JSOp::BindName`, `JSOp::BindUnqualifiedName`, or `JSOp::BindVar`.
*
- * Note: `JSOp::BindName` and `JSOp::GetBoundName` are the two halves of the
- * `JSOp::GetName` operation: finding and reading a variable. This
- * decomposed version is needed to implement the compound assignment and
- * increment/decrement operators, which get and then set a variable. The
- * spec says the variable lookup is done only once. If we did the lookup
+ * Note: `JSOp::Bind(Unqualified)Name` and `JSOp::GetBoundName` are the two
+ * halves of the `JSOp::GetName` operation: finding and reading a variable.
+ * This decomposed version is needed to implement:
+ * 1. The call operator, which gets a variable and its this-environment.
+ * 2. The compound assignment and increment/decrement operators, which get
+ * and then set a variable.
+ * The spec says the variable lookup is done only once. If we did the lookup
* twice, there would be observable bugs, thanks to dynamic scoping. We
- * could set the wrong variable or call proxy traps incorrectly.
+ * could get the wrong this-environment resp. variable or call proxy traps
+ * incorrectly.
*
* Implements: [GetValue][1] steps 4 and 6.
*
* [1]: https://tc39.es/ecma262/#sec-getvalue
*
* Category: Variables and scopes
* Type: Getting binding values
* Operands: uint32_t nameIndex
@@ -3101,29 +3109,29 @@
*/ \
MACRO(EnvCallee, env_callee, NULL, 2, 0, 1, JOF_UINT8) \
/*
* Assign `val` to the binding in `env` with the name given by `nameIndex`.
* Throw a ReferenceError if the binding is an uninitialized lexical.
* This can call setters and/or proxy traps.
*
* `env` must be an environment currently on the environment chain,
- * pushed by `JSOp::BindName` or `JSOp::BindVar`.
+ * pushed by `JSOp::BindUnqualifiedName` or `JSOp::BindVar`.
*
* This is the fallback `Set` instruction that handles all unoptimized
* cases. Optimized instructions follow.
*
* Implements: [PutValue][1] steps 5 and 7 for unoptimized bindings.
*
- * Note: `JSOp::BindName` and `JSOp::SetName` are the two halves of simple
- * assignment: finding and setting a variable. They are two separate
- * instructions because, per spec, the "finding" part happens before
- * evaluating the right-hand side of the assignment, and the "setting" part
- * after. Optimized cases don't need a `Bind` instruction because the
- * "finding" is done statically.
+ * Note: `JSOp::BindUnqualifiedName` and `JSOp::SetName` are the two halves
+ * of simple assignment: finding and setting a variable. They are two
+ * separate instructions because, per spec, the "finding" part happens
+ * before evaluating the right-hand side of the assignment, and the
+ * "setting" part after. Optimized cases don't need a `Bind` instruction
+ * because the "finding" is done statically.
*
* [1]: https://tc39.es/ecma262/#sec-putvalue
*
* Category: Variables and scopes
* Type: Setting binding values
* Operands: uint32_t nameIndex
* Stack: env, val => val
*/ \
@@ -3140,27 +3148,27 @@
* Category: Variables and scopes
* Type: Setting binding values
* Operands: uint32_t nameIndex
* Stack: env, val => val
*/ \
MACRO(StrictSetName, strict_set_name, NULL, 5, 2, 1, JOF_ATOM|JOF_PROPSET|JOF_CHECKSTRICT|JOF_IC|JOF_USES_ENV) \
/*
* Like `JSOp::SetName`, but for assigning to globals. `env` must be an
- * environment pushed by `JSOp::BindGName`.
+ * environment pushed by `JSOp::BindUnqualifiedGName`.
*
* Category: Variables and scopes
* Type: Setting binding values
* Operands: uint32_t nameIndex
* Stack: env, val => val
*/ \
MACRO(SetGName, set_g_name, NULL, 5, 2, 1, JOF_ATOM|JOF_PROPSET|JOF_GNAME|JOF_CHECKSLOPPY|JOF_IC) \
/*
* Like `JSOp::StrictSetGName`, but for assigning to globals. `env` must be
- * an environment pushed by `JSOp::BindGName`.
+ * an environment pushed by `JSOp::BindUnqualifiedGName`.
*
* Category: Variables and scopes
* Type: Setting binding values
* Operands: uint32_t nameIndex
* Stack: env, val => val
*/ \
MACRO(StrictSetGName, strict_set_g_name, NULL, 5, 2, 1, JOF_ATOM|JOF_PROPSET|JOF_GNAME|JOF_CHECKSTRICT|JOF_IC) \
/*
@@ -3365,20 +3373,21 @@
/*
* Push a `WithEnvironmentObject` wrapping ToObject(`val`) to the
* environment chain.
*
* Implements: [Evaluation of `with` statements][1], steps 2-6.
*
* Operations that may need to consult a WithEnvironment can't be correctly
* implemented using optimized instructions like `JSOp::GetLocal`. A script
- * must use the deoptimized `JSOp::GetName`, `BindName`, `SetName`, and
- * `DelName` instead. Since those instructions don't work correctly with
- * optimized locals and arguments, all bindings in scopes enclosing a
- * `with` statement are marked as "aliased" and deoptimized too.
+ * must use the deoptimized `JSOp::GetName`, `BindUnqualifiedName`,
+ * `BindName`,`SetName`, and `DelName` instead. Since those instructions
+ * don't work correctly with optimized locals and arguments, all bindings in
+ * scopes enclosing a `with` statement are marked as "aliased" and
+ * deoptimized too.
*
* See `JSOp::PushLexicalEnv` for the fine print.
*
* [1]: https://tc39.es/ecma262/#sec-with-statement-runtime-semantics-evaluation
*
* Category: Variables and scopes
* Type: Entering and leaving environments
* Operands: uint32_t staticWithIndex
@@ -3688,43 +3697,41 @@
/*
* In certain circumstances it may be useful to "pad out" the opcode space to
* a power of two. Use this macro to do so.
*/
#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
# define FOR_EACH_TRAILING_UNUSED_OPCODE(MACRO) \
- IF_RECORD_TUPLE(/* empty */, MACRO(239)) \
IF_RECORD_TUPLE(/* empty */, MACRO(240)) \
IF_RECORD_TUPLE(/* empty */, MACRO(241)) \
IF_RECORD_TUPLE(/* empty */, MACRO(242)) \
IF_RECORD_TUPLE(/* empty */, MACRO(243)) \
IF_RECORD_TUPLE(/* empty */, MACRO(244)) \
IF_RECORD_TUPLE(/* empty */, MACRO(245)) \
- MACRO(246) \
+ IF_RECORD_TUPLE(/* empty */, MACRO(246)) \
MACRO(247) \
MACRO(248) \
MACRO(249) \
MACRO(250) \
MACRO(251) \
MACRO(252) \
MACRO(253) \
MACRO(254) \
MACRO(255)
#else
# define FOR_EACH_TRAILING_UNUSED_OPCODE(MACRO) \
- IF_RECORD_TUPLE(/* empty */, MACRO(236)) \
IF_RECORD_TUPLE(/* empty */, MACRO(237)) \
IF_RECORD_TUPLE(/* empty */, MACRO(238)) \
IF_RECORD_TUPLE(/* empty */, MACRO(239)) \
IF_RECORD_TUPLE(/* empty */, MACRO(240)) \
IF_RECORD_TUPLE(/* empty */, MACRO(241)) \
IF_RECORD_TUPLE(/* empty */, MACRO(242)) \
- MACRO(243) \
+ IF_RECORD_TUPLE(/* empty */, MACRO(243)) \
MACRO(244) \
MACRO(245) \
MACRO(246) \
MACRO(247) \
MACRO(248) \
MACRO(249) \
MACRO(250) \
MACRO(251) \
Files
/js/src/vm/BytecodeUtil.cpp
/js/src/vm/Opcodes.h
Changesets
Diffs
/js/src/vm/BytecodeUtil.cpp
/js/src/vm/Opcodes.h