f1 doesn't have its own x, so it refers to the global x, which is 1 and you never change it. f2 does have a local x in scope which it refers to, which is 100, but there is no code in f2 that ever refers to it! The only console.log you have is in f1, referring to the global x, and you are calling it twice (once from the top-level code and once from inside f2, but where it's called from doesn't matter)
You are saying the second time f1 is called from f2's execution context but that doesn't matter, when you call a function a new execution context is created and f2' s won't have f1's variables in scope (in its lexical environment to use the correct term here) unless you would nest the whole definition of f1 into f2. The scopes are fixed* at compile time, they won't change at runtime based on the call stack.
*: In terms of their variables' location in the source code. Since every invocation of a function creates a new scope where those local variables can have new values, technically it is of course set at runtime, but it would still be the same var/let/etc in the source code that is referred to every time.
See also: https://javascript.info/closure (this has a great explanation, as already mentioned by Andrejs Kuzmins in the comments)