Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Local Eval #1515

Open
wants to merge 1 commit into
base: static_h
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 11 additions & 10 deletions include/hermes/BCGen/HBC/StackFrameLayout.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ namespace hbc {
/// ...
/// 2 callee local0 : HermesValue
/// 1 scratch : HermesValue
/// 0 debugEnvironment : Environment*
/// 0 environment : Environment*
/// ----------------------------------------------
/// -1 previousFrame : NativeValue(HermesValue*) -- calleeFramePtr
/// -2 savedIP : NativeValue(void*)
Expand All @@ -45,7 +45,7 @@ namespace hbc {
/// ...
/// caller local 0 : HermesValue
/// scratch : HermesValue
/// debugEnvironment : Environment*
/// environment : Environment*
/// ----------------------------------------------
/// -- callerFramePtr
/// \endverbatim
Expand All @@ -67,7 +67,7 @@ namespace hbc {
/// - The caller populates calleeClosureOrCB, newTarget and argCount.
/// - The caller saves the current CodeBlock, IP and frame offset in the
/// corresponding fields.
/// - "debugEnvironment" is initialized to "undefined". (It will be populated
/// - "environment" is initialized to "undefined". (It will be populated
/// later by the callee.)
/// - Execution is transferred to callee.
/// - The callee updates the global "frame" register to point to the top of the
Expand All @@ -89,12 +89,13 @@ struct StackFrameLayout {
Scratch = 1,
/// The environment associated with the callee's stack frame, that is, the
/// Environment created by the last CreateEnvironment instruction to execute
/// in the callee's stack frame. It is null if debugging support is not
/// present, or if no CreateEnvironment instruction has executed, which is
/// possible if we are early in the code block, or with optimized code. This
/// is stored in the call frame so that the debugger can gain access to the
/// Environment at arbitrary frames. Note this is managed by the GC.
DebugEnvironment = 0,
/// in the callee's stack frame. It is null if no CreateEnvironment
/// instruction has executed, which is possible if we are early in the code
/// block, or with optimized code. This is stored in the call frame so
/// that the debugger can gain access to the Environment at arbitrary frames,
/// and to enable local eval support
/// Note this is managed by the GC.
Environment = 0,
/// Saved value of the caller's "frame" register, which points to the first
/// register of the caller's stack frame.
PreviousFrame = -1,
Expand Down Expand Up @@ -131,7 +132,7 @@ struct StackFrameLayout {

/// The number of additional registers the callee needs to allocate in the
/// beginning of its frame.
CalleeExtraRegistersAtStart = Scratch - DebugEnvironment + 1,
CalleeExtraRegistersAtStart = Scratch - Environment + 1,
};

/// Calculate the number of register slots needed for an outgoing call: it
Expand Down
3 changes: 1 addition & 2 deletions include/hermes/VM/RootSections.def
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ ROOT_SECTION(CharStrings)
ROOT_SECTION(StringCycleCheckVisited)
ROOT_SECTION(Builtins)
ROOT_SECTION(Jobs)
// We don't need DebugEnvironment anymore, but keep it for MobileLab.
ROOT_SECTION(DebugEnvironment)
ROOT_SECTION(Environment)
ROOT_SECTION(IdentifierTable)
ROOT_SECTION(GCScopes)
ROOT_SECTION(WeakRefs)
Expand Down
12 changes: 6 additions & 6 deletions include/hermes/VM/StackFrame-inline.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,18 +39,18 @@ StackFramePtrT<isConst>::getCalleeCodeBlock(Runtime &runtime) const {
}

template <bool isConst>
inline Handle<Environment> StackFramePtrT<isConst>::getDebugEnvironmentHandle()
inline Handle<Environment> StackFramePtrT<isConst>::getEnvironmentHandle()
const {
return getDebugEnvironmentRef().isUndefined()
return getEnvironmentRef().isUndefined()
? HandleRootOwner::makeNullHandle<Environment>()
: Handle<Environment>::vmcast_or_null(&getDebugEnvironmentRef());
: Handle<Environment>::vmcast_or_null(&getEnvironmentRef());
}

template <bool isConst>
inline Environment *StackFramePtrT<isConst>::getDebugEnvironment() const {
return getDebugEnvironmentRef().isUndefined()
inline Environment *StackFramePtrT<isConst>::getEnvironment() const {
return getEnvironmentRef().isUndefined()
? nullptr
: vmcast_or_null<Environment>(getDebugEnvironmentRef());
: vmcast_or_null<Environment>(getEnvironmentRef());
}

} // namespace vm
Expand Down
34 changes: 18 additions & 16 deletions include/hermes/VM/StackFrame.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ class StackFramePtrT {
// Declare convenience accessors to the underlying HermesValue slots.
_HERMESVM_DEFINE_STACKFRAME_REF(FirstLocal)
_HERMESVM_DEFINE_STACKFRAME_REF(Scratch)
_HERMESVM_DEFINE_STACKFRAME_REF(DebugEnvironment)
_HERMESVM_DEFINE_STACKFRAME_REF(Environment)
_HERMESVM_DEFINE_STACKFRAME_REF(PreviousFrame)
_HERMESVM_DEFINE_STACKFRAME_REF(SavedIP)
_HERMESVM_DEFINE_STACKFRAME_REF(SavedCodeBlock)
Expand Down Expand Up @@ -144,25 +144,27 @@ class StackFramePtrT {
return getSHLocalsRef().template getNativePointer<const SHLocals>();
}

/// \return a handle holding the callee debug environment.
/// \return a handle holding the callee environment.
/// The environment associated with the callee's stack frame, that is, the
/// Environment created by the last CreateEnvironment instruction to execute
/// in the callee's stack frame. It is null if debugging support is not
/// present, or if no CreateEnvironment instruction has executed, which is
/// possible if we are early in the code block, or with optimized code. This
/// is stored in the call frame so that the debugger can gain access to the
/// Environment at arbitrary frames. Note this is managed by the GC.
inline Handle<Environment> getDebugEnvironmentHandle() const;

/// \return the callee debug environment.
/// in the callee's stack frame. It is null if no CreateEnvironment
/// instruction has executed, which is possible if we are early in the code
/// block, or with optimized code. This is stored in the call frame so
/// that the debugger can gain access to the Environment at arbitrary frames,
/// and to enable local eval support
/// Note this is managed by the GC.
inline Handle<Environment> getEnvironmentHandle() const;

/// \return the callee environment.
/// The environment associated with the callee's stack frame, that is, the
/// Environment created by the last CreateEnvironment instruction to execute
/// in the callee's stack frame. It is null if debugging support is not
/// present, or if no CreateEnvironment instruction has executed, which is
/// possible if we are early in the code block, or with optimized code. This
/// is stored in the call frame so that the debugger can gain access to the
/// Environment at arbitrary frames. Note this is managed by the GC.
inline Environment *getDebugEnvironment() const;
/// in the callee's stack frame. It is null if no CreateEnvironment
/// instruction has executed, which is possible if we are early in the code
/// block, or with optimized code. This is stored in the call frame so
/// that the debugger can gain access to the Environment at arbitrary frames,
/// and to enable local eval support
/// Note this is managed by the GC.
inline Environment *getEnvironment() const;

/// \return the number of JavaScript arguments passed to the callee excluding
/// \c "this".
Expand Down
4 changes: 2 additions & 2 deletions lib/VM/Debugger/Debugger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -970,7 +970,7 @@ HermesValue Debugger::getVariableInFrame(
// Descend the environment chain to the desired depth, or stop at null.
// We may get a null environment if it has not been created.
MutableHandle<Environment> env(
runtime_, frameInfo->frame->getDebugEnvironment());
runtime_, frameInfo->frame->getEnvironment());
for (uint32_t i = 0; env && i < scopeDepth; i++)
env = env->getParentEnvironment(runtime_);

Expand Down Expand Up @@ -1052,7 +1052,7 @@ HermesValue Debugger::evalInFrame(
bool singleFunction = false;

// Environment may be undefined if it has not been created yet.
Handle<Environment> env = frameInfo->frame->getDebugEnvironmentHandle();
Handle<Environment> env = frameInfo->frame->getEnvironmentHandle();
if (!env) {
// TODO: this comes about when we break in a function before its environment
// has been created. What we would like to do here is synthesize an
Expand Down
4 changes: 3 additions & 1 deletion lib/VM/Interpreter-slowpaths.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,14 @@ ExecutionStatus Interpreter::caseDirectEval(
}

GCScopeMarkerRAII gcMarker{runtime};
auto cb = FRAME.getCalleeCodeBlock(runtime);

auto cr = vm::directEval(
runtime,
Handle<StringPrimitive>::vmcast(evalText),
strictCaller,
nullptr,
cb,
FRAME.getEnvironmentHandle(),
false);
if (cr == ExecutionStatus::EXCEPTION)
return ExecutionStatus::EXCEPTION;
Expand Down
12 changes: 3 additions & 9 deletions lib/VM/Interpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2036,9 +2036,7 @@ CallResult<HermesValue> Interpreter::interpretFunction(
ip->iCreateEnvironment.op3));

O1REG(CreateEnvironment) = envHV;
#ifdef HERMES_ENABLE_DEBUGGER
FRAME.getDebugEnvironmentRef() = envHV;
#endif
FRAME.getEnvironmentRef() = envHV;
ip = NEXTINST(CreateEnvironment);
DISPATCH;
}
Expand All @@ -2052,9 +2050,7 @@ CallResult<HermesValue> Interpreter::interpretFunction(
ip->iCreateFunctionEnvironment.op2));

O1REG(CreateFunctionEnvironment) = HermesValue::encodeObjectValue(env);
#ifdef HERMES_ENABLE_DEBUGGER
FRAME.getDebugEnvironmentRef() = O1REG(CreateFunctionEnvironment);
#endif
FRAME.getEnvironmentRef() = O1REG(CreateFunctionEnvironment);
tmpHandle = HermesValue::encodeUndefinedValue();
ip = NEXTINST(CreateFunctionEnvironment);
DISPATCH;
Expand All @@ -2069,9 +2065,7 @@ CallResult<HermesValue> Interpreter::interpretFunction(
ip->iCreateTopLevelEnvironment.op2));

O1REG(CreateTopLevelEnvironment) = envHV;
#ifdef HERMES_ENABLE_DEBUGGER
FRAME.getDebugEnvironmentRef() = envHV;
#endif
FRAME.getEnvironmentRef() = envHV;
ip = NEXTINST(CreateTopLevelEnvironment);
DISPATCH;
}
Expand Down
9 changes: 9 additions & 0 deletions lib/VM/JSLib/JSLibInternal.h
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,15 @@ CallResult<HermesValue> directEval(
const CodeBlock *codeBlock,
bool singleFunction = false);

/// A direct passthrough to call eval() on \p str.
CallResult<HermesValue> directEval(
Runtime &runtime,
Handle<StringPrimitive> str,
bool strictCaller,
const CodeBlock *codeBlock,
Handle<Environment> environment,
bool singleFunction = false);

/// ES10 23.1.1.2 AddEntriesFromIterable
/// Calls a callback with each pair of [key, value] from an iterable.
/// \param target the object to which to add the entries
Expand Down
12 changes: 11 additions & 1 deletion lib/VM/JSLib/eval.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,16 @@ CallResult<HermesValue> directEval(
bool strictCaller,
const CodeBlock *codeBlock,
bool singleFunction) {
return directEval(runtime, str, strictCaller, codeBlock, Runtime::makeNullHandle<Environment>(), singleFunction);
}

CallResult<HermesValue> directEval(
Runtime &runtime,
Handle<StringPrimitive> str,
bool strictCaller,
const CodeBlock *codeBlock,
Handle<Environment> environment,
bool singleFunction) {
// Convert the code into UTF8.
std::string code;
auto view = StringPrimitive::createStringView(runtime, str);
Expand All @@ -143,7 +153,7 @@ CallResult<HermesValue> directEval(
runtime,
code,
strictCaller,
Runtime::makeNullHandle<Environment>(),
environment,
codeBlock,
runtime.getGlobal(),
singleFunction);
Expand Down
2 changes: 1 addition & 1 deletion lib/VM/StackFrame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ void dumpStackFrame(
<< "\n"
<< " SavedIP : " << format_ptr(frame.getSavedIP()) << "\n"
<< " SavedCodeBlock : " << format_ptr(frame.getSavedCodeBlock()) << "\n"
<< " DebugEnvironment: " << frame.getDebugEnvironmentRef() << "\n"
<< " Environment : " << frame.getEnvironmentRef() << "\n"
<< " ArgCount : " << frame.getArgCount() << "\n"
<< " NewTarget : " << frame.getNewTargetRef() << "\n"
<< " CalleeClosure : " << frame.getCalleeClosureOrCBRef() << "\n"
Expand Down
2 changes: 1 addition & 1 deletion lib/VM/StaticH.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -498,7 +498,7 @@ extern "C" SHLegacyValue _sh_ljs_create_environment(
GCScopeMarkerRAII marker{runtime};
return Environment::create(runtime, parentHandle, size);
// #ifdef HERMES_ENABLE_DEBUGGER
// framePtr.getDebugEnvironmentRef() = *res;
// framePtr.getEnvironmentRef() = *res;
// #endif
}

Expand Down