Skip to content

Commit

Permalink
propagate emit-async-break-check at runtime
Browse files Browse the repository at this point in the history
Summary:
Propagate the value of `emit-async-break-check` to the VM runtime using
a new runtime flag. This ensures that the async break check will work in
code generated by eval() or new Function().

Additionally, save the flag in hermes::facebook::HermesRuntimeImpl so it
can be applied by default to all source compiled using the JSI
interface.

Reviewed By: avp

Differential Revision: D26031515

fbshipit-source-id: 41fb96c7997f2c78c4e4d24e36cbc70b4403b8a0
  • Loading branch information
tmikov authored and facebook-github-bot committed Jan 23, 2021
1 parent 0879677 commit a62f4ab
Show file tree
Hide file tree
Showing 9 changed files with 54 additions and 8 deletions.
8 changes: 7 additions & 1 deletion API/hermes/hermes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,8 @@ class HermesRuntimeImpl final : public HermesRuntime,
}

compileFlags_.enableGenerator = runtimeConfig.getEnableGenerator();
compileFlags_.emitAsyncBreakCheck = defaultEmitAsyncBreakCheck_ =
runtimeConfig.getAsyncBreakCheckInEval();

#ifndef HERMESJSI_ON_STACK
// Register the memory for the runtime if it isn't stored on the stack.
Expand Down Expand Up @@ -1069,6 +1071,8 @@ class HermesRuntimeImpl final : public HermesRuntime,

/// Compilation flags used by prepareJavaScript().
::hermes::hbc::CompileFlags compileFlags_{};
/// The default setting of "emit async break check" in this runtime.
bool defaultEmitAsyncBreakCheck_{false};
};

namespace {
Expand Down Expand Up @@ -1296,7 +1300,9 @@ void HermesRuntime::watchTimeLimit(uint32_t timeoutInMs) {
}

void HermesRuntime::unwatchTimeLimit() {
impl(this)->compileFlags_.emitAsyncBreakCheck = false;
// Restore the default state.
impl(this)->compileFlags_.emitAsyncBreakCheck =
impl(this)->defaultEmitAsyncBreakCheck_;
::hermes::vm::TimeLimitMonitor::getInstance().unwatchRuntime(
&(impl(this)->runtime_));
}
Expand Down
1 change: 1 addition & 0 deletions include/hermes/CompilerDriver/CompilerDriver.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,5 +99,6 @@ extern llvh::cl::opt<bool> EmitAsyncBreakCheck;
extern llvh::cl::opt<bool> AllowFunctionToString;
extern llvh::cl::list<std::string> InputFilenames;
extern llvh::cl::opt<bool> OptimizedEval;
extern llvh::cl::opt<bool> EmitAsyncBreakCheck;
} // namespace cl
#endif
8 changes: 5 additions & 3 deletions include/hermes/VM/Runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -673,12 +673,14 @@ class Runtime : public HandleRootOwner,
RegExpMatch regExpLastMatch{};

/// Whether to allow eval and Function ctor.
const bool enableEval;
const bool enableEval : 1;
/// Whether to verify the IR being generated by eval and the Function ctor.
const bool verifyEvalIR;
const bool verifyEvalIR : 1;
/// Whether to optimize the code in the string passed to eval and the Function
/// ctor.
const bool optimizedEval;
const bool optimizedEval : 1;
/// Whether to emit async break check instructions in eval().
const bool asyncBreakCheckInEval : 1;

#ifdef HERMESVM_PROFILER_OPCODE
/// Track the frequency of each opcode in the interpreter.
Expand Down
2 changes: 2 additions & 0 deletions lib/VM/JSLib/eval.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ CallResult<HermesValue> evalInEnvironment(
compileFlags.strict = false;
compileFlags.includeLibHermes = false;
compileFlags.optimize = runtime->optimizedEval;
compileFlags.verifyIR = runtime->verifyEvalIR;
compileFlags.emitAsyncBreakCheck = runtime->asyncBreakCheckInEval;
compileFlags.lazy =
utf8code.size() >= compileFlags.preemptiveFileCompilationThreshold;
compileFlags.allowFunctionToStringWithRuntimeSource =
Expand Down
1 change: 1 addition & 0 deletions lib/VM/Runtime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ Runtime::Runtime(
: enableEval(runtimeConfig.getEnableEval()),
verifyEvalIR(runtimeConfig.getVerifyEvalIR()),
optimizedEval(runtimeConfig.getOptimizedEval()),
asyncBreakCheckInEval(runtimeConfig.getAsyncBreakCheckInEval()),
heap_(
getMetadataTable(),
this,
Expand Down
3 changes: 3 additions & 0 deletions public/hermes/Public/RuntimeConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ class Deserializer;
/* Whether to optimize the code inside eval and Function ctor */ \
F(constexpr, bool, OptimizedEval, false) \
\
/* Whether to emit async break check instructions in eval code */ \
F(constexpr, bool, AsyncBreakCheckInEval, false) \
\
/* Support for ES6 Promise. */ \
F(constexpr, bool, ES6Promise, true) \
\
Expand Down
29 changes: 29 additions & 0 deletions test/hermes/execution-time-limit-eval.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

// RUN: (! %hermes -w -O0 -emit-async-break-check -time-limit=300 %s 2>&1 ) | %FileCheck --match-full-lines %s

eval(`
function entryPoint() {
helper();
}
function helper() {
var i = 0;
while (true) {
++i;
}
}
entryPoint();
`);

//CHECK:Uncaught TimeoutError: Javascript execution has timed out.
//CHECK-NEXT: at helper {{.*}}
//CHECK-NEXT: at entryPoint {{.*}}
//CHECK-NEXT: at eval {{.*}}
//CHECK-NEXT: at global {{.*}}
9 changes: 5 additions & 4 deletions test/hermes/execution-time-limit.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
* LICENSE file in the root directory of this source tree.
*/

// RUN: (! %hermes -O0 -emit-async-break-check -time-limit=1000 %s 2>&1 ) | %FileCheck --match-full-lines %s
// RUN: (! %hermes -O0 -emit-async-break-check -time-limit=300 %s 2>&1 ) | %FileCheck --match-full-lines %s
// RUN: (! %hermes -O0 -emit-async-break-check -time-limit=300 -lazy %s 2>&1 ) | %FileCheck --match-full-lines %s

function entryPoint() {
helper();
Expand All @@ -21,6 +22,6 @@ function helper() {
entryPoint();

//CHECK: Uncaught TimeoutError: Javascript execution has timed out.
//CHECK: at helper ({{.*/execution-time-limit.js}}:17:5)
//CHECK-NEXT: at entryPoint ({{.*/execution-time-limit.js}}:11:9)
//CHECK-NEXT: at global ({{.*/execution-time-limit.js}}:21:11)
//CHECK: at helper ({{.*/execution-time-limit.js}}:18:5)
//CHECK-NEXT: at entryPoint ({{.*/execution-time-limit.js}}:12:9)
//CHECK-NEXT: at global ({{.*/execution-time-limit.js}}:22:11)
1 change: 1 addition & 0 deletions tools/hermes/hermes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ static int executeHBCBytecodeFromCL(
.withEnableEval(cl::EnableEval)
.withVerifyEvalIR(cl::VerifyIR)
.withOptimizedEval(cl::OptimizedEval)
.withAsyncBreakCheckInEval(cl::EmitAsyncBreakCheck)
.withVMExperimentFlags(cl::VMExperimentFlags)
.withES6Promise(cl::ES6Promise)
.withES6Proxy(cl::ES6Proxy)
Expand Down

0 comments on commit a62f4ab

Please sign in to comment.