Javascript Environment Record, is it an Exotic Object? - javascript

Are the environment record and exotic object creation procedures the same?
i.e. creation of a basic object with different internal slots and methods, than that of an ordinary object?
Are both objects constructed with the same %Object% intrinsic method?
P.S. Is it correct to refer to an environment record as a completed execution context?

An Environment Record isn't an object at all. (Or more precisely, there's no requirement that Environment Records be implemented as objects. Thinking of them as objects will probably hinder your understanding.)
Environment Records are "specification values", entities that are defined only as a device to specify semantics. In contrast, objects are "language values", values that your JavaScript code can actually manipulate.
P.S. Is it correct to refer to an environment record as a completed execution context?
Nope. Environment Records and Execution Contexts are distinct kinds of specification values. A typical Execution Context will refer to one or two Environment Records, to resolve identifiers in the code that it evaluates.

Related

Javascript, Does ES5+ still has an activation object?

Was reading some information regarding execution context of javascript. I was reading the following article of Rupesh Mishra.
The article stated that a new execution context is created with every new function invocation. An execution context does have 2 phases creation phase and execution phase where the code is executed line by line.
There was stated that an in the creation phase the JS engine does 3 things:
Determines the value of this
Creates the scope chain
Creates the Activation or variable object
This was the explanation of the activation object:
Creates the Activation object or the variable object: Activation object is a special object in JS which contain all the variables, function arguments and inner functions declarations information. As activation object is a special object it does not have the dunder proto property.
Question:
Does ES5+ still has this activation object structure? If not, what are the current steps of the creation phase of an execution context?
Nope, ES5 (and higher) does no longer use a standard JS object to store variables. It uses lexical environments (with this value and scope chain) that contain environment records of various kinds in which the values for the variables are stored.
What are the current steps of the creation phase of an execution context?
Section 10.4 Establishing an Execution Context talks about that.
The behaviour is not too different from what ES3 did (after all old code still works), it's just described using new terms.

How does the "creation phase" know how much memory space to set up?

In JavaScript: Understanding the Weird Parts the instructor explains that memory for variables is set up during a so-called creation phase (and that undefined is assigned); then the execution phase happens. But why is this useful when we don't know what value(s) the variable will later point to?
Clearly variables can point to many different things -from e.g. a short string all the way to a deeply nested object structure -and I assume that they can vary wildly in the amount of memory they need.
If line-by-line execution -including variable assignment -happens only in the later, execution phase, how can the initial creation phase know how to set up memory? Or, is memory set aside only for the name in each variable name/value pair, with memory for the value being managed differently?
The instructor is referring to Google Chrome's V8 engine (as is evidenced by his use of it in the video).
The V8 engine uses several optimization approaches in order to facilitate memory management. At first, it will compile the JavaScript code and during compilation it will determine how many variables (hidden classes, more later) it needs to create. These will determine the amount of memory originally allocated.
V8 compiles JavaScript source code directly into machine code when it is first executed. There are no intermediate byte codes, no interpreter. Property access is handled by inline cache code that may be patched with other machine instructions as V8 executes. 1
The first set is created by navigating the JavaScript code to determine how many different object "shapes" there are. Anything without a prototype is considered to be a "Transitioning object shape"
The main way objects are encoded is by separating the hidden class (description) from the object (content). When new objects are instantiated, they are created using the same initial hidden class as previous objects from the same constructor. As properties are added, objects transition from hidden class to hidden class, typically following previous transitions in the so-called “transition tree”. 2
Conversely, if the object does have a prototype then it will have its particular shape tracked separately.
Prototypes have 2 main phases: setup and use. Prototypes in the setup phase are encoded as dictionary objects. Any direct access to the prototype, or access through a prototype chain, will transition it to use state, making sure that all such accesses from now on are fast. 2
The compiler will essentially read all possible variables as being one of these two possible shapes and then allocate the amount of memory necessary to facilitate instantiating those shapes.
Once the first set of shapes is setup, V8 will then take advantage of what they call "fast property access" in order to build on the first set of variables (hidden classes) that were setup during the build.
To reduce the time required to access JavaScript properties V8 dynamically creates hidden classes behind the scenes 3
There are two advantages to using hidden classes: property access does not require a dictionary lookup, and they enable V8 to use the classic class-based optimization, inline caching 3
As a result, not all memory use is known during compilation, only how much to allocate for the core set of hidden classes. This allocation will grow as the code is executed, from things like assignment, inline cache misses, and conversion into dictionary mode (which happens when too many properties are assigned to an object, and several other nuanced factors).
1. Dynamic machine code generation, https://github.com/v8/v8/wiki/Design%20Elements#dynamic-machine-code-generation
2. Setting up prototypes in V8, https://medium.com/#tverwaes/setting-up-prototypes-in-v8-ec9c9491dfe2
3. Fast Property Access, https://github.com/v8/v8/wiki/Design%20Elements#fast-property-access
Javascript is a bit of a problem you know at least in my opinion
in Javascript there are specifications of the language made by ecmascript
and there are implementation made by developers
you have to understand that what is been taught about Javascript what's so called "under the hood" are the specifications of Javascript
you might have heard the terms Execution Context Lexical Environment.
They are only spec on how the language should work they give idea to the Developers how to build their JS engine in a way that it will behave like the spec.
An execution context is purely a specification mechanism and need not correspond to any particular artefact of an ECMAScript implementation. It is impossible for ECMAScript code to directly access or observe an execution context. ECMAScript
Every Javascript engine is implemented differently and they supposed to behave like the spec of ECMAScript
there is a concept that everytime when an execution context is created.
it has stages creation phase and execution phase.
everytime when creation phase begin it's allocating memory for the variables for that execution context.
in reality it doesn't work like that at all
there is no really a "Creation Phase" at least in V8 engine(Google Chrome JS Engine) in the way that you think.
i can give you a hint and tell you that eveytime when you call a function that
doesn't have another function inside it.
the variables inside that function are basically replacing some "block" in memory
i will give you a basic example let's say V8 engine uses some address in memory
let's say the address is 0x61FF1C
function setNum(){ var num = 5; }
everytime when i will call the setNum function the value for example of num will get stored at address 0x61FF1C EVERYTIME when i will call the function the value of num 5it will get stored at 0x61FF1C so it's overwriting the content that were before inside 0x61FF1C.
that's just how the v8 engine works in that scenario now the example i gave is just to get the idea i know it's sounds a little vague.
there is much more to the V8 engine which i'm not going to discuss because it's huge
by the way i'm not a V8 developer so i dont know everything about that engine
i'm not even close to that level but i know some things.
anyway i think that every JS Developer should think in the spec way but also remember that many engines behave like the spec but it doesn't mean that they work exactly like the spec
When any program executes, time of execution we call running time. During running time or processing time, processor process code and communicate with memory. Procesor takes code from memory, process it, result give back to memory, take other code. All the running time, some space in memory get grater; some space gets zero, some variables get the new value, some variables have been deleting, etc. Volume of working memory in running time is changing all the time.

Is the global symbol registry directly accessible?

We know what the global symbol registry (GSR) is.
It is global and I can access its data with Symbol.for and Symbol.keyFor.
window is global and I can access it with its name.
Is there a similar mechanism for the GSR or is it a private global registry?
The window object is very different from the GSR (and less "global" of course).
No, the GSR is not represented as an object that is accessible to JS code, with properties for key-value pairs or so (or as a Map maybe). It cannot be enumerated, if that is what you are looking for. The only ways to access it are Symbol.for and Symbol.keyFor, which suffices to expose the bijective property of the relation.
This was probably (read: my speculation) done to simplify the implementation. The GSR needs to handle symbol references weakly, they should get garbage-collected when all realms that used them are terminated. Also, the multiple realms that access it might run in different threads, which adds complexity. Exposing the mapping directly to code might introduce race conditions (similar to the reason why WeakMaps are not enumerable).

Equality operator and properties in prototype chain from different frames

When comparing functions from the prototype of a type across frames (same origin), I get the strangest behavior:
>>> window.frames[0].HTMLDocument.prototype.open === HTMLDocument.prototype.open
false
It's exactly the same behavior when using the less-strict ==.
Any idea why this happens?
Different frames mean different global objects. You will have two distinct objects that do the same. Similarly, window.Object !== frames[0].Object. This is also why you shouldn't use instanceof Array when possibly dealing with multiple environments.
Notice that this has nothing to do with the equality operator you were using, they work the same on objects and compare them by reference.
Each browsing context has a separate JavaScript environment.
According to the W3C's HTML5 spec on Web APIs:
Whenever a new Window object is created, it must also create a script settings object...
When the script settings object is created, for each language supported by the user agent, create an appropriate execution environment as defined by the relevant specification.
This requires that every browsing context (i.e., every page in a tab, frame, etc.) have a separate realization of the JavaScript environment. This means that every single page must have a different object for each page (thereby failing a == check) for environmental objects, constructors, and other functions.

Is it possible to retrieve an anonymous JavaScript object?

For example, I have this code:
{a: 42}
After this line was executed, I think the object is stored somehow in the memory, I'm wondering how can I get it, in some tricky way?
No.
You can't do this.
Any decent js interpreter will destroy it with the garbage collector.
No: once you lose all references to an object, you cannot recover it and the GC will collect it.
No.
Anonymous objects are intended to work this way. If you need to retrieve an object later on, you should simply name it. (I assume you are asking this question out of curiosity and not out of neccessity).
As soon as an object has no existing references to it, the garbage collector should destroy the object, as is confirmed by this page:
ECMAScript uses automatic garbage
collection. The specification does not
define the details, leaving that to
the implementers to sort out, and some
implementations are known to give a
very low priority to their garbage
collection operations. But the general
idea is that if an object becomes
un-referable (by having no remaining
references to it left accessible to
executing code) it becomes available
for garbage collection and will at
some future point be destroyed and any
resources it is consuming freed and
returned to the system for re-use.
This would normally be the case upon
exiting an execution context. The
scope chain structure, the
Activation/Variable object and any
objects created within the execution
context, including function objects,
would no longer be accessible and so
would become available for garbage
collection.

Categories