Skip to content

Commit

Permalink
Backout supporting code FunctionToStringWithRuntimeSource
Browse files Browse the repository at this point in the history
Summary:
This diff backout code (D19676080) that made function source more
boradly available to support FunctionToStringWithRuntimeSource,
which adds a lot of complexities to lazy compilation pipeline;
obscure the context lifetime, etc.

Reviewed By: avp

Differential Revision: D29094628

fbshipit-source-id: 3f0d4c168a71798fcdc4b4abc48d6ab952c32188
  • Loading branch information
Huxpro authored and facebook-github-bot committed Jul 7, 2021
1 parent fb8c5a5 commit 4d04ed5
Show file tree
Hide file tree
Showing 9 changed files with 49 additions and 133 deletions.
39 changes: 0 additions & 39 deletions include/hermes/BCGen/HBC/Bytecode.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@
#define HERMES_BCGEN_HBC_BYTECODE_H

#include "llvh/ADT/ArrayRef.h"
#include "llvh/Support/SMLoc.h"

#include "hermes/AST/Context.h"
#include "hermes/BCGen/HBC/BytecodeFileFormat.h"
#include "hermes/BCGen/HBC/BytecodeInstructionGenerator.h"
#include "hermes/BCGen/HBC/BytecodeStream.h"
Expand Down Expand Up @@ -241,17 +239,6 @@ class BytecodeModule {
/// runtime.
BytecodeOptions options_{};

#ifndef HERMESVM_LEAN
/// Stores references to source code strings for functions. These are only
/// available when compiling from source at run-time, and when lazily compiled
/// functions or Function.toString() returning source are enabled.
llvh::DenseMap<uint32_t, llvh::SMRange> functionSourceRangeMap_;

/// If there are any entries in functionSourceRangeMap_ we need to keep
/// Context alive so the source buffers don't dissapear from under us.
std::shared_ptr<Context> context_;
#endif

public:
/// Used during serialization.
explicit BytecodeModule(
Expand Down Expand Up @@ -412,32 +399,6 @@ class BytecodeModule {
BytecodeOptions getBytecodeOptions() const {
return options_;
}

#ifndef HERMESVM_LEAN
/// Called during BytecodeModule generation.
void setFunctionSourceRange(uint32_t functionID, llvh::SMRange range) {
functionSourceRangeMap_.try_emplace(functionID, range);
}

/// If we retain source code for any functions we also need to preserve
/// \c Context. Called during BytecodeModule generation.
void setContext(std::shared_ptr<Context> context) {
context_ = context;
}

/// Returns source code for a given function if available. Use \c isValid() on
/// the result to confirm source is actually available.
llvh::SMRange getFunctionSourceRange(uint32_t functionID) {
auto it = functionSourceRangeMap_.find(functionID);
return it == functionSourceRangeMap_.end() ? llvh::SMRange() : it->second;
}

/// This will only be available if we're retaining source code for at least
/// one function in this module.
std::shared_ptr<Context> getContext() const {
return context_;
}
#endif
};

} // namespace hbc
Expand Down
10 changes: 0 additions & 10 deletions include/hermes/BCGen/HBC/BytecodeDataProvider.h
Original file line number Diff line number Diff line change
Expand Up @@ -306,16 +306,6 @@ class BCProviderBase {
/// Serialize this BCProvider.
virtual void serialize(vm::Serializer &s) const = 0;
#endif

#ifndef HERMESVM_LEAN
/// Return a reference to the source code for a function. In general this will
/// NOT be available, however it may be when compiling from source at
/// run-time, and lazy compilation or Function.toString() returning soruce is
/// enabled.
virtual llvh::SMRange getFunctionSourceRange(uint32_t functionID) const {
return {};
}
#endif
};

/// BCProviderFromBuffer will be used when we are loading bytecode from
Expand Down
23 changes: 2 additions & 21 deletions include/hermes/BCGen/HBC/BytecodeProviderFromSrc.h
Original file line number Diff line number Diff line change
Expand Up @@ -203,26 +203,16 @@ class BCProviderFromSrc final : public BCProviderBase {
/// Serialize this BCProviderFromSrc.
void serialize(vm::Serializer &s) const override;
#endif

#ifndef HERMESVM_LEAN
llvh::SMRange getFunctionSourceRange(uint32_t functionID) const override {
return module_->getFunctionSourceRange(functionID);
}
#endif
};

/// BCProviderLazy is used during lazy compilation. When a function is created
/// to be lazily compiled later, we create a BCProviderLazy object with
/// a pointer to such BytecodeFunction.
class BCProviderLazy final : public BCProviderBase {
hbc::BytecodeModule *bytecodeModule_;

/// Pointer to the BytecodeFunction.
hbc::BytecodeFunction *bytecodeFunction_;

explicit BCProviderLazy(
hbc::BytecodeModule *bytecodeModule,
hbc::BytecodeFunction *bytecodeFunction);
explicit BCProviderLazy(hbc::BytecodeFunction *bytecodeFunction);

/// No debug information will be available without compiling it.
void createDebugInfo() override {
Expand All @@ -231,10 +221,9 @@ class BCProviderLazy final : public BCProviderBase {

public:
static std::unique_ptr<BCProviderBase> createBCProviderLazy(
hbc::BytecodeModule *bytecodeModule,
hbc::BytecodeFunction *bytecodeFunction) {
return std::unique_ptr<BCProviderBase>(
new BCProviderLazy(bytecodeModule, bytecodeFunction));
new BCProviderLazy(bytecodeFunction));
}

RuntimeFunctionHeader getFunctionHeader(uint32_t) const override {
Expand Down Expand Up @@ -271,18 +260,10 @@ class BCProviderLazy final : public BCProviderBase {
return bytecodeFunction_;
}

hbc::BytecodeModule *getBytecodeModule() {
return bytecodeModule_;
}

#ifdef HERMESVM_SERIALIZE
/// Serialize this BCProviderLazy.
void serialize(vm::Serializer &s) const override;
#endif

llvh::SMRange getFunctionSourceRange(uint32_t functionID) const override {
return bytecodeModule_->getFunctionSourceRange(functionID);
}
};
#endif // HERMESVM_LEAN
} // namespace hbc
Expand Down
13 changes: 8 additions & 5 deletions include/hermes/IRGen/IRGen.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,10 @@ using DeclarationFileListTy = std::vector<ESTree::ProgramNode *>;

namespace hbc {

class BytecodeFunction;

struct LazyCompilationData {
/// The context used by IRGen.
std::shared_ptr<Context> context;

/// The variables in scope at the point where the function is defined.
std::shared_ptr<SerializedScope> parentScope;

Expand All @@ -39,6 +40,9 @@ struct LazyCompilationData {
/// The source buffer ID in which we can find the function source.
uint32_t bufferId;

/// The source span of the function.
SMRange span;

/// The type of function, e.g. statement or expression.
ESTree::NodeKind nodeKind;

Expand Down Expand Up @@ -85,9 +89,8 @@ void generateIRForCJSModule(
/// a SyntaxError will be emitted instead.
/// \return the newly generated function IR and lexical scope root
std::pair<Function *, Function *> generateLazyFunctionIR(
hbc::BytecodeFunction *bcFunction,
Module *M,
llvh::SMRange sourceRange);
hbc::LazyCompilationData *lazyData,
Module *M);

} // namespace hermes

Expand Down
16 changes: 2 additions & 14 deletions lib/BCGen/HBC/BytecodeGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,6 @@ std::unique_ptr<BytecodeModule> BytecodeModuleGenerator::generate() {
const uint32_t strippedFunctionNameId =
options_.stripFunctionNames ? getStringID(kStrippedFunctionName) : 0;
auto functions = functionIDMap_.getElements();
std::shared_ptr<Context> contextIfNeeded;
for (unsigned i = 0, e = functions.size(); i < e; ++i) {
auto *F = functions[i];
auto &BFG = *functionGenerators_[F];
Expand All @@ -291,23 +290,14 @@ std::unique_ptr<BytecodeModule> BytecodeModuleGenerator::generate() {
F->getFunctionScope()->getVariables().size(),
functionNameId);

#ifndef HERMESVM_LEAN
if (F->isLazy()) {
auto context = F->getParent()->shareContext();
assert(
(!contextIfNeeded || contextIfNeeded.get() == context.get()) &&
"Different instances of Context seen");
contextIfNeeded = context;
BM->setFunctionSourceRange(i, F->getSourceRange());
}
#endif

if (F->isLazy()) {
#ifdef HERMESVM_LEAN
llvm_unreachable("Lazy support compiled out");
#else
auto lazyData = std::make_unique<LazyCompilationData>();
lazyData->context = F->getParent()->shareContext();
lazyData->parentScope = F->getLazyScope();
lazyData->span = F->getLazySource().functionRange;
lazyData->nodeKind = F->getLazySource().nodeKind;
lazyData->paramYield = F->getLazySource().paramYield;
lazyData->paramAwait = F->getLazySource().paramAwait;
Expand All @@ -331,8 +321,6 @@ std::unique_ptr<BytecodeModule> BytecodeModuleGenerator::generate() {
BM->setFunction(i, std::move(func));
}

BM->setContext(contextIfNeeded);

BM->setDebugInfo(debugInfoGen.serializeWithMove());
return BM;
}
Expand Down
6 changes: 2 additions & 4 deletions lib/BCGen/HBC/BytecodeProviderFromSrc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -239,10 +239,8 @@ BCProviderFromSrc::createBCProviderFromSrc(
return {std::move(bytecode), std::string{}};
}

BCProviderLazy::BCProviderLazy(
hbc::BytecodeModule *bytecodeModule,
hbc::BytecodeFunction *bytecodeFunction)
: bytecodeModule_(bytecodeModule), bytecodeFunction_(bytecodeFunction) {
BCProviderLazy::BCProviderLazy(hbc::BytecodeFunction *bytecodeFunction)
: bytecodeFunction_(bytecodeFunction) {
// Lazy module should always contain one function to begin with.
functionCount_ = 1;
}
Expand Down
14 changes: 7 additions & 7 deletions lib/IRGen/IRGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
*/

#include "hermes/IRGen/IRGen.h"
#include "hermes/BCGen/HBC/Bytecode.h"

#include "ESTreeIRGen.h"

Expand Down Expand Up @@ -46,11 +45,9 @@ void generateIRForCJSModule(
}

std::pair<Function *, Function *> generateLazyFunctionIR(
hbc::BytecodeFunction *bcFunction,
Module *M,
llvh::SMRange sourceRange) {
hbc::LazyCompilationData *lazyData,
Module *M) {
auto &context = M->getContext();
auto lazyData = bcFunction->getLazyCompilationData();
SimpleDiagHandlerRAII diagHandler{context.getSourceErrorManager()};

AllocationScope alloc(context.getAllocator());
Expand All @@ -67,7 +64,7 @@ std::pair<Function *, Function *> generateLazyFunctionIR(
(ESTree::NodeKind)lazyData->nodeKind,
lazyData->paramYield,
lazyData->paramAwait,
sourceRange.Start);
lazyData->span.Start);

// In case of error, generate a function that just throws a SyntaxError.
if (!parsed ||
Expand All @@ -78,7 +75,10 @@ std::pair<Function *, Function *> generateLazyFunctionIR(
<< diagHandler.getErrorString());

auto *error = ESTreeIRGen::genSyntaxErrorFunction(
M, lazyData->originalName, sourceRange, diagHandler.getErrorString());
M,
lazyData->originalName,
lazyData->span,
diagHandler.getErrorString());

return {error, error};
}
Expand Down
50 changes: 22 additions & 28 deletions lib/VM/CodeBlock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -222,11 +222,12 @@ OptValue<hbc::DebugSourceLocation> CodeBlock::getSourceLocation(
assert(offset == 0 && "Function is lazy, but debug offset >0 specified");

auto *provider = (hbc::BCProviderLazy *)getRuntimeModule()->getBytecode();
auto bcModule = provider->getBytecodeModule();
auto sourceLoc = bcModule->getFunctionSourceRange(functionID_).Start;
auto *func = provider->getBytecodeFunction();
auto *lazyData = func->getLazyCompilationData();
auto sourceLoc = lazyData->span.Start;

SourceErrorManager::SourceCoords coords;
if (!bcModule->getContext()->getSourceErrorManager().findBufferLineAndLoc(
if (!lazyData->context->getSourceErrorManager().findBufferLineAndLoc(
sourceLoc, coords)) {
return llvh::None;
}
Expand Down Expand Up @@ -269,32 +270,26 @@ SourceErrorManager::SourceCoords CodeBlock::getLazyFunctionLoc(
assert(isLazy() && "Function must be lazy");
SourceErrorManager::SourceCoords coords;
#ifndef HERMESVM_LEAN
auto provider = (hbc::BCProviderLazy *)runtimeModule_->getBytecode();
auto sourceRange =
provider->getBytecodeModule()->getFunctionSourceRange(functionID_);
assert(sourceRange.isValid() && "Source not available for function");
provider->getBytecodeModule()
->getContext()
->getSourceErrorManager()
.findBufferLineAndLoc(
start ? sourceRange.Start : sourceRange.End, coords);
auto *provider = (hbc::BCProviderLazy *)getRuntimeModule()->getBytecode();
auto *func = provider->getBytecodeFunction();
auto *lazyData = func->getLazyCompilationData();
lazyData->context->getSourceErrorManager().findBufferLineAndLoc(
start ? lazyData->span.Start : lazyData->span.End, coords);
#endif
return coords;
}

#ifndef HERMESVM_LEAN
namespace {
std::unique_ptr<hbc::BytecodeModule> compileLazyFunction(
std::shared_ptr<Context> context,
hbc::BytecodeFunction *func,
llvh::SMRange sourceRange) {
assert(func);
hbc::LazyCompilationData *lazyData) {
assert(lazyData);
LLVM_DEBUG(
llvh::dbgs() << "Compiling lazy function "
<< func->getLazyCompilationData()->originalName << "\n");
llvh::dbgs() << "Compiling lazy function " << lazyData->originalName
<< "\n");

Module M{context};
auto pair = hermes::generateLazyFunctionIR(func, &M, sourceRange);
Module M{lazyData->context};
auto pair = hermes::generateLazyFunctionIR(lazyData, &M);
Function *entryPoint = pair.first;
Function *lexicalRoot = pair.second;

Expand All @@ -315,15 +310,14 @@ std::unique_ptr<hbc::BytecodeModule> compileLazyFunction(
void CodeBlock::lazyCompileImpl(Runtime *runtime) {
assert(isLazy() && "Laziness has not been checked");
PerfSection perf("Lazy function compilation");
auto provider = (hbc::BCProviderLazy *)runtimeModule_->getBytecode();
auto func = provider->getBytecodeFunction();
auto sourceRange =
provider->getBytecodeModule()->getFunctionSourceRange(functionID_);
auto bcMod = compileLazyFunction(
provider->getBytecodeModule()->getContext(), func, sourceRange);
auto *provider = (hbc::BCProviderLazy *)runtimeModule_->getBytecode();
auto *func = provider->getBytecodeFunction();
auto *lazyData = func->getLazyCompilationData();
auto bcModule = compileLazyFunction(lazyData);

runtimeModule_->initializeLazyMayAllocate(
hbc::BCProviderFromSrc::createBCProviderFromSrc(std::move(bcMod)));
// Reset all meta data of the CodeBlock to point to the newly
hbc::BCProviderFromSrc::createBCProviderFromSrc(std::move(bcModule)));
// Reset all meta lazyData of the CodeBlock to point to the newly
// generated bytecode module.
functionID_ = runtimeModule_->getBytecode()->getGlobalFunctionIndex();
functionHeader_ =
Expand Down
11 changes: 6 additions & 5 deletions lib/VM/RuntimeModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,12 +171,13 @@ RuntimeModule *RuntimeModule::createLazyModule(
// Set the bcProvider's BytecodeModule to point to the parent's.
assert(parent->isInitialized() && "Parent module must have been initialized");

auto bcModule =
((hbc::BCProviderFromSrc *)parent->getBytecode())->getBytecodeModule();
auto bcFunction = &bcModule->getFunction(functionID);
auto *bcFunction = &((hbc::BCProviderFromSrc *)parent->getBytecode())
->getBytecodeModule()
->getFunction(functionID);

RM->bcProvider_ =
hbc::BCProviderLazy::createBCProviderLazy(bcModule, bcFunction);
RM->bcProvider_ = hbc::BCProviderLazy::createBCProviderLazy(bcFunction);

RM->bcProvider_ = hbc::BCProviderLazy::createBCProviderLazy(bcFunction);

// We don't know which function index this block will eventually represent,
// so just add it as 0 to ensure ownership. We'll move it later in
Expand Down

0 comments on commit 4d04ed5

Please sign in to comment.