Don't dereference handles in DoParseLazy
This will allow for using DoParseLazy on a background thread, so we can also parse inner functions on the background thread. BUG=v8:5215 R=adamk@chromium.org,marja@chromium.org Review-Url: https://codereview.chromium.org/2201423002 Cr-Commit-Position: refs/heads/master@{#38332}
This commit is contained in:
parent
94ad974df8
commit
52cc7ddfba
@ -52,6 +52,9 @@ ParseInfo::ParseInfo(Zone* zone)
|
|||||||
unicode_cache_(nullptr),
|
unicode_cache_(nullptr),
|
||||||
stack_limit_(0),
|
stack_limit_(0),
|
||||||
hash_seed_(0),
|
hash_seed_(0),
|
||||||
|
compiler_hints_(0),
|
||||||
|
start_position_(0),
|
||||||
|
end_position_(0),
|
||||||
isolate_(nullptr),
|
isolate_(nullptr),
|
||||||
cached_data_(nullptr),
|
cached_data_(nullptr),
|
||||||
ast_value_factory_(nullptr),
|
ast_value_factory_(nullptr),
|
||||||
@ -70,6 +73,11 @@ ParseInfo::ParseInfo(Zone* zone, Handle<SharedFunctionInfo> shared)
|
|||||||
|
|
||||||
set_lazy();
|
set_lazy();
|
||||||
set_hash_seed(isolate_->heap()->HashSeed());
|
set_hash_seed(isolate_->heap()->HashSeed());
|
||||||
|
set_is_named_expression(shared->is_named_expression());
|
||||||
|
set_calls_eval(shared->scope_info()->CallsEval());
|
||||||
|
set_compiler_hints(shared->compiler_hints());
|
||||||
|
set_start_position(shared->start_position());
|
||||||
|
set_end_position(shared->end_position());
|
||||||
set_stack_limit(isolate_->stack_guard()->real_climit());
|
set_stack_limit(isolate_->stack_guard()->real_climit());
|
||||||
set_unicode_cache(isolate_->unicode_cache());
|
set_unicode_cache(isolate_->unicode_cache());
|
||||||
set_language_mode(shared->language_mode());
|
set_language_mode(shared->language_mode());
|
||||||
@ -96,6 +104,26 @@ ParseInfo::ParseInfo(Zone* zone, Handle<Script> script) : ParseInfo(zone) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ParseInfo::is_declaration() const {
|
||||||
|
return (compiler_hints_ & (1 << SharedFunctionInfo::kIsDeclaration)) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ParseInfo::is_arrow() const {
|
||||||
|
return (compiler_hints_ & (1 << SharedFunctionInfo::kIsArrow)) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ParseInfo::is_async() const {
|
||||||
|
return (compiler_hints_ & (1 << SharedFunctionInfo::kIsAsyncFunction)) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ParseInfo::is_default_constructor() const {
|
||||||
|
return (compiler_hints_ & (1 << SharedFunctionInfo::kIsDefaultConstructor)) !=
|
||||||
|
0;
|
||||||
|
}
|
||||||
|
|
||||||
|
FunctionKind ParseInfo::function_kind() const {
|
||||||
|
return SharedFunctionInfo::FunctionKindBits::decode(compiler_hints_);
|
||||||
|
}
|
||||||
|
|
||||||
FunctionEntry ParseData::GetFunctionEntry(int start) {
|
FunctionEntry ParseData::GetFunctionEntry(int start) {
|
||||||
// The current pre-data entry must be a FunctionEntry with the given
|
// The current pre-data entry must be a FunctionEntry with the given
|
||||||
@ -1080,7 +1108,13 @@ FunctionLiteral* Parser::ParseLazy(Isolate* isolate, ParseInfo* info) {
|
|||||||
stream.reset(new GenericStringUtf16CharacterStream(
|
stream.reset(new GenericStringUtf16CharacterStream(
|
||||||
source, shared_info->start_position(), shared_info->end_position()));
|
source, shared_info->start_position(), shared_info->end_position()));
|
||||||
}
|
}
|
||||||
result = DoParseLazy(isolate, info, stream.get());
|
Handle<String> name(String::cast(shared_info->name()));
|
||||||
|
result = DoParseLazy(isolate, info, ast_value_factory()->GetString(name),
|
||||||
|
stream.get());
|
||||||
|
if (result != nullptr) {
|
||||||
|
Handle<String> inferred_name(shared_info->inferred_name());
|
||||||
|
result->set_inferred_name(inferred_name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FLAG_trace_parse && result != NULL) {
|
if (FLAG_trace_parse && result != NULL) {
|
||||||
@ -1091,30 +1125,27 @@ FunctionLiteral* Parser::ParseLazy(Isolate* isolate, ParseInfo* info) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static FunctionLiteral::FunctionType ComputeFunctionType(
|
static FunctionLiteral::FunctionType ComputeFunctionType(ParseInfo* info) {
|
||||||
Handle<SharedFunctionInfo> shared_info) {
|
if (info->is_declaration()) {
|
||||||
if (shared_info->is_declaration()) {
|
|
||||||
return FunctionLiteral::kDeclaration;
|
return FunctionLiteral::kDeclaration;
|
||||||
} else if (shared_info->is_named_expression()) {
|
} else if (info->is_named_expression()) {
|
||||||
return FunctionLiteral::kNamedExpression;
|
return FunctionLiteral::kNamedExpression;
|
||||||
} else if (IsConciseMethod(shared_info->kind()) ||
|
} else if (IsConciseMethod(info->function_kind()) ||
|
||||||
IsAccessorFunction(shared_info->kind())) {
|
IsAccessorFunction(info->function_kind())) {
|
||||||
return FunctionLiteral::kAccessorOrMethod;
|
return FunctionLiteral::kAccessorOrMethod;
|
||||||
}
|
}
|
||||||
return FunctionLiteral::kAnonymousExpression;
|
return FunctionLiteral::kAnonymousExpression;
|
||||||
}
|
}
|
||||||
|
|
||||||
FunctionLiteral* Parser::DoParseLazy(Isolate* isolate, ParseInfo* info,
|
FunctionLiteral* Parser::DoParseLazy(Isolate* isolate, ParseInfo* info,
|
||||||
|
const AstRawString* raw_name,
|
||||||
Utf16CharacterStream* source) {
|
Utf16CharacterStream* source) {
|
||||||
Handle<SharedFunctionInfo> shared_info = info->shared_info();
|
|
||||||
scanner_.Initialize(source);
|
scanner_.Initialize(source);
|
||||||
DCHECK_NULL(scope_state_);
|
DCHECK_NULL(scope_state_);
|
||||||
DCHECK_NULL(target_stack_);
|
DCHECK_NULL(target_stack_);
|
||||||
|
|
||||||
Handle<String> name(String::cast(shared_info->name()));
|
|
||||||
DCHECK(ast_value_factory());
|
DCHECK(ast_value_factory());
|
||||||
fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
|
fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
|
||||||
const AstRawString* raw_name = ast_value_factory()->GetString(name);
|
|
||||||
fni_->PushEnclosingName(raw_name);
|
fni_->PushEnclosingName(raw_name);
|
||||||
|
|
||||||
ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
|
ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
|
||||||
@ -1127,16 +1158,14 @@ FunctionLiteral* Parser::DoParseLazy(Isolate* isolate, ParseInfo* info,
|
|||||||
Scope* scope = original_scope_;
|
Scope* scope = original_scope_;
|
||||||
DCHECK(scope);
|
DCHECK(scope);
|
||||||
FunctionState function_state(&function_state_, &scope_state_, scope,
|
FunctionState function_state(&function_state_, &scope_state_, scope,
|
||||||
shared_info->kind());
|
info->function_kind());
|
||||||
DCHECK(is_sloppy(scope->language_mode()) ||
|
DCHECK(is_sloppy(scope->language_mode()) ||
|
||||||
is_strict(info->language_mode()));
|
is_strict(info->language_mode()));
|
||||||
DCHECK(info->language_mode() == shared_info->language_mode());
|
FunctionLiteral::FunctionType function_type = ComputeFunctionType(info);
|
||||||
FunctionLiteral::FunctionType function_type =
|
|
||||||
ComputeFunctionType(shared_info);
|
|
||||||
bool ok = true;
|
bool ok = true;
|
||||||
|
|
||||||
if (shared_info->is_arrow()) {
|
if (info->is_arrow()) {
|
||||||
bool is_async = allow_harmony_async_await() && shared_info->is_async();
|
bool is_async = allow_harmony_async_await() && info->is_async();
|
||||||
if (is_async) {
|
if (is_async) {
|
||||||
DCHECK(!scanner()->HasAnyLineTerminatorAfterNext());
|
DCHECK(!scanner()->HasAnyLineTerminatorAfterNext());
|
||||||
if (!Check(Token::ASYNC)) {
|
if (!Check(Token::ASYNC)) {
|
||||||
@ -1156,12 +1185,12 @@ FunctionLiteral* Parser::DoParseLazy(Isolate* isolate, ParseInfo* info,
|
|||||||
// not passing the ScopeInfo to the Scope constructor.
|
// not passing the ScopeInfo to the Scope constructor.
|
||||||
// TODO(adamk): Remove these calls once the above NewScope call
|
// TODO(adamk): Remove these calls once the above NewScope call
|
||||||
// passes the ScopeInfo.
|
// passes the ScopeInfo.
|
||||||
if (shared_info->scope_info()->CallsEval()) {
|
if (info->calls_eval()) {
|
||||||
scope->RecordEvalCall();
|
scope->RecordEvalCall();
|
||||||
}
|
}
|
||||||
SetLanguageMode(scope, shared_info->language_mode());
|
SetLanguageMode(scope, info->language_mode());
|
||||||
|
|
||||||
scope->set_start_position(shared_info->start_position());
|
scope->set_start_position(info->start_position());
|
||||||
ExpressionClassifier formals_classifier(this);
|
ExpressionClassifier formals_classifier(this);
|
||||||
ParserFormalParameters formals(scope);
|
ParserFormalParameters formals(scope);
|
||||||
Checkpoint checkpoint(this);
|
Checkpoint checkpoint(this);
|
||||||
@ -1197,7 +1226,7 @@ FunctionLiteral* Parser::DoParseLazy(Isolate* isolate, ParseInfo* info,
|
|||||||
// concise body happens to be a valid expression. This is a problem
|
// concise body happens to be a valid expression. This is a problem
|
||||||
// only for arrow functions with single expression bodies, since there
|
// only for arrow functions with single expression bodies, since there
|
||||||
// is no end token such as "}" for normal functions.
|
// is no end token such as "}" for normal functions.
|
||||||
if (scanner()->location().end_pos == shared_info->end_position()) {
|
if (scanner()->location().end_pos == info->end_position()) {
|
||||||
// The pre-parser saw an arrow function here, so the full parser
|
// The pre-parser saw an arrow function here, so the full parser
|
||||||
// must produce a FunctionLiteral.
|
// must produce a FunctionLiteral.
|
||||||
DCHECK(expression->IsFunctionLiteral());
|
DCHECK(expression->IsFunctionLiteral());
|
||||||
@ -1207,17 +1236,16 @@ FunctionLiteral* Parser::DoParseLazy(Isolate* isolate, ParseInfo* info,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (shared_info->is_default_constructor()) {
|
} else if (info->is_default_constructor()) {
|
||||||
DCHECK_EQ(this->scope(), scope);
|
DCHECK_EQ(this->scope(), scope);
|
||||||
result = DefaultConstructor(
|
result = DefaultConstructor(
|
||||||
raw_name, IsSubclassConstructor(shared_info->kind()),
|
raw_name, IsSubclassConstructor(info->function_kind()),
|
||||||
shared_info->start_position(), shared_info->end_position(),
|
info->start_position(), info->end_position(), info->language_mode());
|
||||||
shared_info->language_mode());
|
|
||||||
} else {
|
} else {
|
||||||
result = ParseFunctionLiteral(raw_name, Scanner::Location::invalid(),
|
result = ParseFunctionLiteral(raw_name, Scanner::Location::invalid(),
|
||||||
kSkipFunctionNameCheck, shared_info->kind(),
|
kSkipFunctionNameCheck,
|
||||||
kNoSourcePosition, function_type,
|
info->function_kind(), kNoSourcePosition,
|
||||||
shared_info->language_mode(), &ok);
|
function_type, info->language_mode(), &ok);
|
||||||
}
|
}
|
||||||
// Make sure the results agree.
|
// Make sure the results agree.
|
||||||
DCHECK(ok == (result != nullptr));
|
DCHECK(ok == (result != nullptr));
|
||||||
@ -1225,11 +1253,6 @@ FunctionLiteral* Parser::DoParseLazy(Isolate* isolate, ParseInfo* info,
|
|||||||
|
|
||||||
// Make sure the target stack is empty.
|
// Make sure the target stack is empty.
|
||||||
DCHECK_NULL(target_stack_);
|
DCHECK_NULL(target_stack_);
|
||||||
|
|
||||||
if (result != nullptr) {
|
|
||||||
Handle<String> inferred_name(shared_info->inferred_name());
|
|
||||||
result->set_inferred_name(inferred_name);
|
|
||||||
}
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,6 +58,9 @@ class ParseInfo {
|
|||||||
FLAG_ACCESSOR(kAllowLazyParsing, allow_lazy_parsing, set_allow_lazy_parsing)
|
FLAG_ACCESSOR(kAllowLazyParsing, allow_lazy_parsing, set_allow_lazy_parsing)
|
||||||
FLAG_ACCESSOR(kAstValueFactoryOwned, ast_value_factory_owned,
|
FLAG_ACCESSOR(kAstValueFactoryOwned, ast_value_factory_owned,
|
||||||
set_ast_value_factory_owned)
|
set_ast_value_factory_owned)
|
||||||
|
FLAG_ACCESSOR(kIsNamedExpression, is_named_expression,
|
||||||
|
set_is_named_expression)
|
||||||
|
FLAG_ACCESSOR(kCallsEval, calls_eval, set_calls_eval)
|
||||||
|
|
||||||
#undef FLAG_ACCESSOR
|
#undef FLAG_ACCESSOR
|
||||||
|
|
||||||
@ -126,6 +129,26 @@ class ParseInfo {
|
|||||||
uint32_t hash_seed() { return hash_seed_; }
|
uint32_t hash_seed() { return hash_seed_; }
|
||||||
void set_hash_seed(uint32_t hash_seed) { hash_seed_ = hash_seed; }
|
void set_hash_seed(uint32_t hash_seed) { hash_seed_ = hash_seed; }
|
||||||
|
|
||||||
|
int compiler_hints() const { return compiler_hints_; }
|
||||||
|
void set_compiler_hints(int compiler_hints) {
|
||||||
|
compiler_hints_ = compiler_hints;
|
||||||
|
}
|
||||||
|
|
||||||
|
int start_position() const { return start_position_; }
|
||||||
|
void set_start_position(int start_position) {
|
||||||
|
start_position_ = start_position;
|
||||||
|
}
|
||||||
|
|
||||||
|
int end_position() const { return end_position_; }
|
||||||
|
void set_end_position(int end_position) { end_position_ = end_position; }
|
||||||
|
|
||||||
|
// Getters for individual compiler hints.
|
||||||
|
bool is_declaration() const;
|
||||||
|
bool is_arrow() const;
|
||||||
|
bool is_async() const;
|
||||||
|
bool is_default_constructor() const;
|
||||||
|
FunctionKind function_kind() const;
|
||||||
|
|
||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
// TODO(titzer): these should not be part of ParseInfo.
|
// TODO(titzer): these should not be part of ParseInfo.
|
||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
@ -171,8 +194,10 @@ class ParseInfo {
|
|||||||
kParseRestriction = 1 << 6,
|
kParseRestriction = 1 << 6,
|
||||||
kModule = 1 << 7,
|
kModule = 1 << 7,
|
||||||
kAllowLazyParsing = 1 << 8,
|
kAllowLazyParsing = 1 << 8,
|
||||||
|
kIsNamedExpression = 1 << 9,
|
||||||
|
kCallsEval = 1 << 10,
|
||||||
// ---------- Output flags --------------------------
|
// ---------- Output flags --------------------------
|
||||||
kAstValueFactoryOwned = 1 << 9
|
kAstValueFactoryOwned = 1 << 11
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------- Inputs to parsing and scope analysis -----------------------
|
//------------- Inputs to parsing and scope analysis -----------------------
|
||||||
@ -187,6 +212,9 @@ class ParseInfo {
|
|||||||
UnicodeCache* unicode_cache_;
|
UnicodeCache* unicode_cache_;
|
||||||
uintptr_t stack_limit_;
|
uintptr_t stack_limit_;
|
||||||
uint32_t hash_seed_;
|
uint32_t hash_seed_;
|
||||||
|
int compiler_hints_;
|
||||||
|
int start_position_;
|
||||||
|
int end_position_;
|
||||||
|
|
||||||
// TODO(titzer): Move handles and isolate out of ParseInfo.
|
// TODO(titzer): Move handles and isolate out of ParseInfo.
|
||||||
Isolate* isolate_;
|
Isolate* isolate_;
|
||||||
@ -750,6 +778,7 @@ class Parser : public ParserBase<ParserTraits> {
|
|||||||
|
|
||||||
FunctionLiteral* ParseLazy(Isolate* isolate, ParseInfo* info);
|
FunctionLiteral* ParseLazy(Isolate* isolate, ParseInfo* info);
|
||||||
FunctionLiteral* DoParseLazy(Isolate* isolate, ParseInfo* info,
|
FunctionLiteral* DoParseLazy(Isolate* isolate, ParseInfo* info,
|
||||||
|
const AstRawString* raw_name,
|
||||||
Utf16CharacterStream* source);
|
Utf16CharacterStream* source);
|
||||||
|
|
||||||
// Called by ParseProgram after setting up the scanner.
|
// Called by ParseProgram after setting up the scanner.
|
||||||
|
Loading…
Reference in New Issue
Block a user