#ifndef frontend_BytecodeCompilation_h
#define frontend_BytecodeCompilation_h
#include "mozilla/Assertions.h"
#include "mozilla/Attributes.h"
#include "mozilla/Maybe.h"
#include "mozilla/Utf8.h"
#include <stddef.h>
#include <stdint.h>
#include "frontend/EitherParser.h"
#include "frontend/ParseContext.h"
#include "frontend/SharedContext.h"
#include "js/CompileOptions.h"
#include "js/RootingAPI.h"
#include "js/SourceText.h"
#include "vm/JSContext.h"
#include "vm/JSScript.h"
#include "vm/Scope.h"
class JSFunction;
class JSObject;
namespace js {
namespace frontend {
template <typename Unit>
class SourceAwareCompiler;
template <typename Unit>
class ScriptCompiler;
template <typename Unit>
class ModuleCompiler;
template <typename Unit>
class StandaloneFunctionCompiler;
class MOZ_STACK_CLASS BytecodeCompiler {
protected:
AutoKeepAtoms keepAtoms;
JSContext* cx;
const JS::ReadOnlyCompileOptions& options;
JS::Rooted<ScriptSourceObject*> sourceObject;
ScriptSource* scriptSource = nullptr;
mozilla::Maybe<UsedNameTracker> usedNames;
Directives directives;
JS::Rooted<JSScript*> script;
protected:
BytecodeCompiler(JSContext* cx, const JS::ReadOnlyCompileOptions& options);
template <typename Unit>
friend class SourceAwareCompiler;
template <typename Unit>
friend class ScriptCompiler;
template <typename Unit>
friend class ModuleCompiler;
template <typename Unit>
friend class StandaloneFunctionCompiler;
public:
JSContext* context() const { return cx; }
ScriptSourceObject* sourceObjectPtr() const { return sourceObject.get(); }
protected:
void assertSourceCreated() const {
MOZ_ASSERT(sourceObject != nullptr);
MOZ_ASSERT(scriptSource != nullptr);
}
MOZ_MUST_USE bool createScriptSource(
const mozilla::Maybe<uint32_t>& parameterListEnd);
void createUsedNames() { usedNames.emplace(cx); }
MOZ_MUST_USE bool internalCreateScript(uint32_t toStringStart,
uint32_t toStringEnd,
uint32_t sourceBufferLength);
MOZ_MUST_USE bool emplaceEmitter(mozilla::Maybe<BytecodeEmitter>& emitter,
const EitherParser& parser,
SharedContext* sharedContext);
template <typename Unit>
MOZ_MUST_USE bool assignSource(JS::SourceText<Unit>& sourceBuffer);
bool canLazilyParse() const;
MOZ_MUST_USE bool deoptimizeArgumentsInEnclosingScripts(
JSContext* cx, JS::Handle<JSObject*> environment);
};
class MOZ_STACK_CLASS GlobalScriptInfo final : public BytecodeCompiler {
GlobalSharedContext globalsc_;
public:
GlobalScriptInfo(JSContext* cx, const JS::ReadOnlyCompileOptions& options,
ScopeKind scopeKind)
: BytecodeCompiler(cx, options),
globalsc_(cx, scopeKind, directives, options.extraWarningsOption) {
MOZ_ASSERT(scopeKind == ScopeKind::Global ||
scopeKind == ScopeKind::NonSyntactic);
}
GlobalSharedContext* sharedContext() { return &globalsc_; }
};
extern JSScript* CompileGlobalScript(
GlobalScriptInfo& info, JS::SourceText<char16_t>& srcBuf,
ScriptSourceObject** sourceObjectOut = nullptr);
extern JSScript* CompileGlobalScript(
GlobalScriptInfo& info, JS::SourceText<mozilla::Utf8Unit>& srcBuf,
ScriptSourceObject** sourceObjectOut = nullptr);
class MOZ_STACK_CLASS EvalScriptInfo final : public BytecodeCompiler {
JS::Handle<JSObject*> environment_;
EvalSharedContext evalsc_;
public:
EvalScriptInfo(JSContext* cx, const JS::ReadOnlyCompileOptions& options,
JS::Handle<JSObject*> environment,
JS::Handle<Scope*> enclosingScope)
: BytecodeCompiler(cx, options),
environment_(environment),
evalsc_(cx, environment_, enclosingScope, directives,
options.extraWarningsOption) {}
HandleObject environment() { return environment_; }
EvalSharedContext* sharedContext() { return &evalsc_; }
};
extern JSScript* CompileEvalScript(EvalScriptInfo& info,
JS::SourceText<char16_t>& srcBuf);
class MOZ_STACK_CLASS ModuleInfo final : public BytecodeCompiler {
public:
ModuleInfo(JSContext* cx, const JS::ReadOnlyCompileOptions& options)
: BytecodeCompiler(cx, options) {}
};
class MOZ_STACK_CLASS StandaloneFunctionInfo final : public BytecodeCompiler {
public:
StandaloneFunctionInfo(JSContext* cx,
const JS::ReadOnlyCompileOptions& options)
: BytecodeCompiler(cx, options) {}
};
extern MOZ_MUST_USE bool CompileLazyFunction(JSContext* cx,
JS::Handle<LazyScript*> lazy,
const char16_t* units,
size_t length);
extern MOZ_MUST_USE bool CompileLazyFunction(JSContext* cx,
JS::Handle<LazyScript*> lazy,
const mozilla::Utf8Unit* units,
size_t length);
}
}
#endif