1// Copyright 2016 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "src/parsing/parse-info.h"
6
7#include "src/api.h"
8#include "src/ast/ast-value-factory.h"
9#include "src/ast/ast.h"
10#include "src/heap/heap-inl.h"
11#include "src/objects-inl.h"
12#include "src/objects/scope-info.h"
13#include "src/zone/zone.h"
14
15namespace v8 {
16namespace internal {
17
18ParseInfo::ParseInfo(AccountingAllocator* zone_allocator)
19    : zone_(std::make_shared<Zone>(zone_allocator, ZONE_NAME)),
20      flags_(0),
21      source_stream_(nullptr),
22      source_stream_encoding_(ScriptCompiler::StreamedSource::ONE_BYTE),
23      character_stream_(nullptr),
24      extension_(nullptr),
25      compile_options_(ScriptCompiler::kNoCompileOptions),
26      script_scope_(nullptr),
27      asm_function_scope_(nullptr),
28      unicode_cache_(nullptr),
29      stack_limit_(0),
30      hash_seed_(0),
31      compiler_hints_(0),
32      start_position_(0),
33      end_position_(0),
34      parameters_end_pos_(kNoSourcePosition),
35      function_literal_id_(FunctionLiteral::kIdTypeInvalid),
36      max_function_literal_id_(FunctionLiteral::kIdTypeInvalid),
37      isolate_(nullptr),
38      cached_data_(nullptr),
39      ast_value_factory_(nullptr),
40      function_name_(nullptr),
41      literal_(nullptr),
42      deferred_handles_(nullptr) {}
43
44ParseInfo::ParseInfo(Handle<SharedFunctionInfo> shared)
45    : ParseInfo(shared->GetIsolate()->allocator()) {
46  isolate_ = shared->GetIsolate();
47
48  set_toplevel(shared->is_toplevel());
49  set_allow_lazy_parsing(FLAG_lazy_inner_functions);
50  set_hash_seed(isolate_->heap()->HashSeed());
51  set_is_named_expression(shared->is_named_expression());
52  set_calls_eval(shared->scope_info()->CallsEval());
53  set_compiler_hints(shared->compiler_hints());
54  set_start_position(shared->start_position());
55  set_end_position(shared->end_position());
56  function_literal_id_ = shared->function_literal_id();
57  set_stack_limit(isolate_->stack_guard()->real_climit());
58  set_unicode_cache(isolate_->unicode_cache());
59  set_language_mode(shared->language_mode());
60  set_shared_info(shared);
61  set_module(shared->kind() == FunctionKind::kModule);
62
63  Handle<Script> script(Script::cast(shared->script()));
64  set_script(script);
65  set_native(script->type() == Script::TYPE_NATIVE);
66  set_eval(script->compilation_type() == Script::COMPILATION_TYPE_EVAL);
67
68  Handle<HeapObject> scope_info(shared->outer_scope_info());
69  if (!scope_info->IsTheHole(isolate()) &&
70      Handle<ScopeInfo>::cast(scope_info)->length() > 0) {
71    set_outer_scope_info(Handle<ScopeInfo>::cast(scope_info));
72  }
73}
74
75ParseInfo::ParseInfo(Handle<SharedFunctionInfo> shared,
76                     std::shared_ptr<Zone> zone)
77    : ParseInfo(shared) {
78  zone_.swap(zone);
79}
80
81ParseInfo::ParseInfo(Handle<Script> script)
82    : ParseInfo(script->GetIsolate()->allocator()) {
83  isolate_ = script->GetIsolate();
84
85  set_allow_lazy_parsing();
86  set_toplevel();
87  set_hash_seed(isolate_->heap()->HashSeed());
88  set_stack_limit(isolate_->stack_guard()->real_climit());
89  set_unicode_cache(isolate_->unicode_cache());
90  set_script(script);
91
92  set_native(script->type() == Script::TYPE_NATIVE);
93  set_eval(script->compilation_type() == Script::COMPILATION_TYPE_EVAL);
94}
95
96ParseInfo::~ParseInfo() {
97  if (ast_value_factory_owned()) {
98    delete ast_value_factory_;
99    set_ast_value_factory_owned(false);
100  }
101  ast_value_factory_ = nullptr;
102}
103
104// static
105ParseInfo* ParseInfo::AllocateWithoutScript(Handle<SharedFunctionInfo> shared) {
106  Isolate* isolate = shared->GetIsolate();
107  ParseInfo* p = new ParseInfo(isolate->allocator());
108  p->isolate_ = isolate;
109
110  p->set_toplevel(shared->is_toplevel());
111  p->set_allow_lazy_parsing(FLAG_lazy_inner_functions);
112  p->set_hash_seed(isolate->heap()->HashSeed());
113  p->set_is_named_expression(shared->is_named_expression());
114  p->set_calls_eval(shared->scope_info()->CallsEval());
115  p->set_compiler_hints(shared->compiler_hints());
116  p->set_start_position(shared->start_position());
117  p->set_end_position(shared->end_position());
118  p->function_literal_id_ = shared->function_literal_id();
119  p->set_stack_limit(isolate->stack_guard()->real_climit());
120  p->set_unicode_cache(isolate->unicode_cache());
121  p->set_language_mode(shared->language_mode());
122  p->set_shared_info(shared);
123  p->set_module(shared->kind() == FunctionKind::kModule);
124
125  // BUG(5946): This function exists as a workaround until we can
126  // get rid of %SetCode in our native functions. The ParseInfo
127  // is explicitly set up for the case that:
128  // a) you have a native built-in,
129  // b) it's being run for the 2nd-Nth time in an isolate,
130  // c) we've already compiled bytecode and therefore don't need
131  //    to parse.
132  // We tolerate a ParseInfo without a Script in this case.
133  p->set_native(true);
134  p->set_eval(false);
135
136  Handle<HeapObject> scope_info(shared->outer_scope_info());
137  if (!scope_info->IsTheHole(isolate) &&
138      Handle<ScopeInfo>::cast(scope_info)->length() > 0) {
139    p->set_outer_scope_info(Handle<ScopeInfo>::cast(scope_info));
140  }
141  return p;
142}
143
144DeclarationScope* ParseInfo::scope() const { return literal()->scope(); }
145
146bool ParseInfo::is_declaration() const {
147  return (compiler_hints_ & (1 << SharedFunctionInfo::kIsDeclaration)) != 0;
148}
149
150FunctionKind ParseInfo::function_kind() const {
151  return SharedFunctionInfo::FunctionKindBits::decode(compiler_hints_);
152}
153
154void ParseInfo::set_deferred_handles(
155    std::shared_ptr<DeferredHandles> deferred_handles) {
156  DCHECK(deferred_handles_.get() == nullptr);
157  deferred_handles_.swap(deferred_handles);
158}
159
160void ParseInfo::set_deferred_handles(DeferredHandles* deferred_handles) {
161  DCHECK(deferred_handles_.get() == nullptr);
162  deferred_handles_.reset(deferred_handles);
163}
164
165#ifdef DEBUG
166bool ParseInfo::script_is_native() const {
167  return script_->type() == Script::TYPE_NATIVE;
168}
169#endif  // DEBUG
170
171}  // namespace internal
172}  // namespace v8
173