1 // Copyright 2017 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 #ifndef V8_OBJECTS_SHARED_FUNCTION_INFO_INL_H_
6 #define V8_OBJECTS_SHARED_FUNCTION_INFO_INL_H_
7
8 #include "src/heap/heap-inl.h"
9 #include "src/objects/scope-info.h"
10 #include "src/objects/shared-function-info.h"
11 #include "src/objects/templates.h"
12 #include "src/wasm/wasm-objects-inl.h"
13
14 // Has to be the last include (doesn't have include guards):
15 #include "src/objects/object-macros.h"
16
17 namespace v8 {
18 namespace internal {
19
20 CAST_ACCESSOR(PreParsedScopeData)
ACCESSORS(PreParsedScopeData,scope_data,PodArray<uint8_t>,kScopeDataOffset)21 ACCESSORS(PreParsedScopeData, scope_data, PodArray<uint8_t>, kScopeDataOffset)
22 ACCESSORS(PreParsedScopeData, child_data, FixedArray, kChildDataOffset)
23
24 CAST_ACCESSOR(InterpreterData)
25 ACCESSORS(InterpreterData, bytecode_array, BytecodeArray, kBytecodeArrayOffset)
26 ACCESSORS(InterpreterData, interpreter_trampoline, Code,
27 kInterpreterTrampolineOffset)
28
29 TYPE_CHECKER(SharedFunctionInfo, SHARED_FUNCTION_INFO_TYPE)
30 CAST_ACCESSOR(SharedFunctionInfo)
31 DEFINE_DEOPT_ELEMENT_ACCESSORS(SharedFunctionInfo, Object)
32
33 ACCESSORS(SharedFunctionInfo, name_or_scope_info, Object,
34 kNameOrScopeInfoOffset)
35 ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
36 ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
37 ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
38 ACCESSORS(SharedFunctionInfo, function_identifier, Object,
39 kFunctionIdentifierOffset)
40
41 BIT_FIELD_ACCESSORS(SharedFunctionInfo, raw_start_position_and_type,
42 is_named_expression,
43 SharedFunctionInfo::IsNamedExpressionBit)
44 BIT_FIELD_ACCESSORS(SharedFunctionInfo, raw_start_position_and_type,
45 is_toplevel, SharedFunctionInfo::IsTopLevelBit)
46
47 INT_ACCESSORS(SharedFunctionInfo, function_literal_id, kFunctionLiteralIdOffset)
48 #if V8_SFI_HAS_UNIQUE_ID
49 INT_ACCESSORS(SharedFunctionInfo, unique_id, kUniqueIdOffset)
50 #endif
51 INT_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
52 INT_ACCESSORS(SharedFunctionInfo, internal_formal_parameter_count,
53 kFormalParameterCountOffset)
54 INT_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
55 kExpectedNofPropertiesOffset)
56 INT_ACCESSORS(SharedFunctionInfo, raw_end_position, kEndPositionOffset)
57 INT_ACCESSORS(SharedFunctionInfo, raw_start_position_and_type,
58 kStartPositionAndTypeOffset)
59 INT_ACCESSORS(SharedFunctionInfo, function_token_position,
60 kFunctionTokenPositionOffset)
61 INT_ACCESSORS(SharedFunctionInfo, flags, kFlagsOffset)
62
63 bool SharedFunctionInfo::HasSharedName() const {
64 Object* value = name_or_scope_info();
65 if (value->IsScopeInfo()) {
66 return ScopeInfo::cast(value)->HasSharedFunctionName();
67 }
68 return value != kNoSharedNameSentinel;
69 }
70
Name()71 String* SharedFunctionInfo::Name() const {
72 if (!HasSharedName()) return GetHeap()->empty_string();
73 Object* value = name_or_scope_info();
74 if (value->IsScopeInfo()) {
75 if (ScopeInfo::cast(value)->HasFunctionName()) {
76 return String::cast(ScopeInfo::cast(value)->FunctionName());
77 }
78 return GetHeap()->empty_string();
79 }
80 return String::cast(value);
81 }
82
SetName(String * name)83 void SharedFunctionInfo::SetName(String* name) {
84 Object* maybe_scope_info = name_or_scope_info();
85 if (maybe_scope_info->IsScopeInfo()) {
86 ScopeInfo::cast(maybe_scope_info)->SetFunctionName(name);
87 } else {
88 DCHECK(maybe_scope_info->IsString() ||
89 maybe_scope_info == kNoSharedNameSentinel);
90 set_name_or_scope_info(name);
91 }
92 UpdateFunctionMapIndex();
93 }
94
abstract_code()95 AbstractCode* SharedFunctionInfo::abstract_code() {
96 if (HasBytecodeArray()) {
97 return AbstractCode::cast(GetBytecodeArray());
98 } else {
99 return AbstractCode::cast(GetCode());
100 }
101 }
102
BIT_FIELD_ACCESSORS(SharedFunctionInfo,flags,is_wrapped,SharedFunctionInfo::IsWrappedBit)103 BIT_FIELD_ACCESSORS(SharedFunctionInfo, flags, is_wrapped,
104 SharedFunctionInfo::IsWrappedBit)
105 BIT_FIELD_ACCESSORS(SharedFunctionInfo, flags, allows_lazy_compilation,
106 SharedFunctionInfo::AllowLazyCompilationBit)
107 BIT_FIELD_ACCESSORS(SharedFunctionInfo, flags, has_duplicate_parameters,
108 SharedFunctionInfo::HasDuplicateParametersBit)
109 BIT_FIELD_ACCESSORS(SharedFunctionInfo, flags, is_declaration,
110 SharedFunctionInfo::IsDeclarationBit)
111
112 BIT_FIELD_ACCESSORS(SharedFunctionInfo, flags, native,
113 SharedFunctionInfo::IsNativeBit)
114 BIT_FIELD_ACCESSORS(SharedFunctionInfo, flags, is_asm_wasm_broken,
115 SharedFunctionInfo::IsAsmWasmBrokenBit)
116 BIT_FIELD_ACCESSORS(SharedFunctionInfo, flags,
117 requires_instance_fields_initializer,
118 SharedFunctionInfo::RequiresInstanceFieldsInitializer)
119
120 bool SharedFunctionInfo::optimization_disabled() const {
121 return disable_optimization_reason() != BailoutReason::kNoReason;
122 }
123
disable_optimization_reason()124 BailoutReason SharedFunctionInfo::disable_optimization_reason() const {
125 return DisabledOptimizationReasonBits::decode(flags());
126 }
127
language_mode()128 LanguageMode SharedFunctionInfo::language_mode() {
129 STATIC_ASSERT(LanguageModeSize == 2);
130 return construct_language_mode(IsStrictBit::decode(flags()));
131 }
132
set_language_mode(LanguageMode language_mode)133 void SharedFunctionInfo::set_language_mode(LanguageMode language_mode) {
134 STATIC_ASSERT(LanguageModeSize == 2);
135 // We only allow language mode transitions that set the same language mode
136 // again or go up in the chain:
137 DCHECK(is_sloppy(this->language_mode()) || is_strict(language_mode));
138 int hints = flags();
139 hints = IsStrictBit::update(hints, is_strict(language_mode));
140 set_flags(hints);
141 UpdateFunctionMapIndex();
142 }
143
kind()144 FunctionKind SharedFunctionInfo::kind() const {
145 return FunctionKindBits::decode(flags());
146 }
147
set_kind(FunctionKind kind)148 void SharedFunctionInfo::set_kind(FunctionKind kind) {
149 int hints = flags();
150 hints = FunctionKindBits::update(hints, kind);
151 hints = IsClassConstructorBit::update(hints, IsClassConstructor(kind));
152 hints = IsDerivedConstructorBit::update(hints, IsDerivedConstructor(kind));
153 set_flags(hints);
154 UpdateFunctionMapIndex();
155 }
156
needs_home_object()157 bool SharedFunctionInfo::needs_home_object() const {
158 return NeedsHomeObjectBit::decode(flags());
159 }
160
set_needs_home_object(bool value)161 void SharedFunctionInfo::set_needs_home_object(bool value) {
162 int hints = flags();
163 hints = NeedsHomeObjectBit::update(hints, value);
164 set_flags(hints);
165 UpdateFunctionMapIndex();
166 }
167
construct_as_builtin()168 bool SharedFunctionInfo::construct_as_builtin() const {
169 return ConstructAsBuiltinBit::decode(flags());
170 }
171
CalculateConstructAsBuiltin()172 void SharedFunctionInfo::CalculateConstructAsBuiltin() {
173 bool uses_builtins_construct_stub = false;
174 if (HasBuiltinId()) {
175 int id = builtin_id();
176 if (id != Builtins::kCompileLazy && id != Builtins::kEmptyFunction) {
177 uses_builtins_construct_stub = true;
178 }
179 } else if (IsApiFunction()) {
180 uses_builtins_construct_stub = true;
181 }
182
183 int f = flags();
184 f = ConstructAsBuiltinBit::update(f, uses_builtins_construct_stub);
185 set_flags(f);
186 }
187
function_map_index()188 int SharedFunctionInfo::function_map_index() const {
189 // Note: Must be kept in sync with the FastNewClosure builtin.
190 int index =
191 Context::FIRST_FUNCTION_MAP_INDEX + FunctionMapIndexBits::decode(flags());
192 DCHECK_LE(index, Context::LAST_FUNCTION_MAP_INDEX);
193 return index;
194 }
195
set_function_map_index(int index)196 void SharedFunctionInfo::set_function_map_index(int index) {
197 STATIC_ASSERT(Context::LAST_FUNCTION_MAP_INDEX <=
198 Context::FIRST_FUNCTION_MAP_INDEX + FunctionMapIndexBits::kMax);
199 DCHECK_LE(Context::FIRST_FUNCTION_MAP_INDEX, index);
200 DCHECK_LE(index, Context::LAST_FUNCTION_MAP_INDEX);
201 index -= Context::FIRST_FUNCTION_MAP_INDEX;
202 set_flags(FunctionMapIndexBits::update(flags(), index));
203 }
204
clear_padding()205 void SharedFunctionInfo::clear_padding() {
206 memset(reinterpret_cast<void*>(this->address() + kSize), 0,
207 kAlignedSize - kSize);
208 }
209
UpdateFunctionMapIndex()210 void SharedFunctionInfo::UpdateFunctionMapIndex() {
211 int map_index = Context::FunctionMapIndex(
212 language_mode(), kind(), true, HasSharedName(), needs_home_object());
213 set_function_map_index(map_index);
214 }
215
BIT_FIELD_ACCESSORS(SharedFunctionInfo,debugger_hints,name_should_print_as_anonymous,SharedFunctionInfo::NameShouldPrintAsAnonymousBit)216 BIT_FIELD_ACCESSORS(SharedFunctionInfo, debugger_hints,
217 name_should_print_as_anonymous,
218 SharedFunctionInfo::NameShouldPrintAsAnonymousBit)
219 BIT_FIELD_ACCESSORS(SharedFunctionInfo, debugger_hints, is_anonymous_expression,
220 SharedFunctionInfo::IsAnonymousExpressionBit)
221 BIT_FIELD_ACCESSORS(SharedFunctionInfo, debugger_hints, deserialized,
222 SharedFunctionInfo::IsDeserializedBit)
223 BIT_FIELD_ACCESSORS(SharedFunctionInfo, debugger_hints, side_effect_state,
224 SharedFunctionInfo::SideEffectStateBits)
225 BIT_FIELD_ACCESSORS(SharedFunctionInfo, debugger_hints, debug_is_blackboxed,
226 SharedFunctionInfo::DebugIsBlackboxedBit)
227 BIT_FIELD_ACCESSORS(SharedFunctionInfo, debugger_hints,
228 computed_debug_is_blackboxed,
229 SharedFunctionInfo::ComputedDebugIsBlackboxedBit)
230 BIT_FIELD_ACCESSORS(SharedFunctionInfo, debugger_hints,
231 has_reported_binary_coverage,
232 SharedFunctionInfo::HasReportedBinaryCoverageBit)
233 BIT_FIELD_ACCESSORS(SharedFunctionInfo, debugger_hints, debugging_id,
234 SharedFunctionInfo::DebuggingIdBits)
235
236 void SharedFunctionInfo::DontAdaptArguments() {
237 // TODO(leszeks): Revise this DCHECK now that the code field is gone.
238 DCHECK(!HasWasmExportedFunctionData());
239 set_internal_formal_parameter_count(kDontAdaptArgumentsSentinel);
240 }
241
BIT_FIELD_ACCESSORS(SharedFunctionInfo,raw_start_position_and_type,raw_start_position,SharedFunctionInfo::StartPositionBits)242 BIT_FIELD_ACCESSORS(SharedFunctionInfo, raw_start_position_and_type,
243 raw_start_position, SharedFunctionInfo::StartPositionBits)
244
245 int SharedFunctionInfo::StartPosition() const {
246 ScopeInfo* info = scope_info();
247 if (!info->HasPositionInfo()) {
248 // TODO(cbruni): use preparsed_scope_data
249 return raw_start_position();
250 }
251 return info->StartPosition();
252 }
253
EndPosition()254 int SharedFunctionInfo::EndPosition() const {
255 ScopeInfo* info = scope_info();
256 if (!info->HasPositionInfo()) {
257 // TODO(cbruni): use preparsed_scope_data
258 return raw_end_position();
259 }
260 return info->EndPosition();
261 }
262
GetCode()263 Code* SharedFunctionInfo::GetCode() const {
264 // ======
265 // NOTE: This chain of checks MUST be kept in sync with the equivalent CSA
266 // GetSharedFunctionInfoCode method in code-stub-assembler.cc, and the
267 // architecture-specific GetSharedFunctionInfoCode methods in builtins-*.cc.
268 // ======
269
270 Isolate* isolate = GetIsolate();
271 Object* data = function_data();
272 if (data->IsSmi()) {
273 // Holding a Smi means we are a builtin.
274 DCHECK(HasBuiltinId());
275 return isolate->builtins()->builtin(builtin_id());
276 } else if (data->IsBytecodeArray()) {
277 // Having a bytecode array means we are a compiled, interpreted function.
278 DCHECK(HasBytecodeArray());
279 return isolate->builtins()->builtin(Builtins::kInterpreterEntryTrampoline);
280 } else if (data->IsFixedArray()) {
281 // Having a fixed array means we are an asm.js/wasm function.
282 DCHECK(HasAsmWasmData());
283 return isolate->builtins()->builtin(Builtins::kInstantiateAsmJs);
284 } else if (data->IsPreParsedScopeData()) {
285 // Having pre-parsed scope data means we need to compile.
286 DCHECK(HasPreParsedScopeData());
287 return isolate->builtins()->builtin(Builtins::kCompileLazy);
288 } else if (data->IsFunctionTemplateInfo()) {
289 // Having a function template info means we are an API function.
290 DCHECK(IsApiFunction());
291 return isolate->builtins()->builtin(Builtins::kHandleApiCall);
292 } else if (data->IsWasmExportedFunctionData()) {
293 // Having a WasmExportedFunctionData means the code is in there.
294 DCHECK(HasWasmExportedFunctionData());
295 return wasm_exported_function_data()->wrapper_code();
296 } else if (data->IsInterpreterData()) {
297 Code* code = InterpreterTrampoline();
298 DCHECK(code->IsCode());
299 DCHECK(code->is_interpreter_trampoline_builtin());
300 return code;
301 }
302 UNREACHABLE();
303 }
304
IsInterpreted()305 bool SharedFunctionInfo::IsInterpreted() const { return HasBytecodeArray(); }
306
scope_info()307 ScopeInfo* SharedFunctionInfo::scope_info() const {
308 Object* maybe_scope_info = name_or_scope_info();
309 if (maybe_scope_info->IsScopeInfo()) {
310 return ScopeInfo::cast(maybe_scope_info);
311 }
312 return ScopeInfo::Empty(GetIsolate());
313 }
314
set_scope_info(ScopeInfo * scope_info,WriteBarrierMode mode)315 void SharedFunctionInfo::set_scope_info(ScopeInfo* scope_info,
316 WriteBarrierMode mode) {
317 // TODO(cbruni): this code is no longer necessary once we store the positon
318 // only on the ScopeInfo.
319 if (scope_info->HasPositionInfo()) {
320 scope_info->SetPositionInfo(raw_start_position(), raw_end_position());
321 }
322 // Move the existing name onto the ScopeInfo.
323 Object* name = name_or_scope_info();
324 if (name->IsScopeInfo()) {
325 name = ScopeInfo::cast(name)->FunctionName();
326 }
327 DCHECK(name->IsString() || name == kNoSharedNameSentinel);
328 // Only set the function name for function scopes.
329 scope_info->SetFunctionName(name);
330 if (HasInferredName() && inferred_name()->length() != 0) {
331 scope_info->SetInferredFunctionName(inferred_name());
332 }
333 WRITE_FIELD(this, kNameOrScopeInfoOffset,
334 reinterpret_cast<Object*>(scope_info));
335 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kNameOrScopeInfoOffset,
336 reinterpret_cast<Object*>(scope_info), mode);
337 }
338
ACCESSORS(SharedFunctionInfo,raw_outer_scope_info_or_feedback_metadata,HeapObject,kOuterScopeInfoOrFeedbackMetadataOffset)339 ACCESSORS(SharedFunctionInfo, raw_outer_scope_info_or_feedback_metadata,
340 HeapObject, kOuterScopeInfoOrFeedbackMetadataOffset)
341
342 HeapObject* SharedFunctionInfo::outer_scope_info() const {
343 DCHECK(!is_compiled());
344 DCHECK(!HasFeedbackMetadata());
345 return raw_outer_scope_info_or_feedback_metadata();
346 }
347
HasOuterScopeInfo()348 bool SharedFunctionInfo::HasOuterScopeInfo() const {
349 ScopeInfo* outer_info = nullptr;
350 if (!is_compiled()) {
351 if (!outer_scope_info()->IsScopeInfo()) return false;
352 outer_info = ScopeInfo::cast(outer_scope_info());
353 } else {
354 if (!scope_info()->HasOuterScopeInfo()) return false;
355 outer_info = scope_info()->OuterScopeInfo();
356 }
357 return outer_info->length() > 0;
358 }
359
GetOuterScopeInfo()360 ScopeInfo* SharedFunctionInfo::GetOuterScopeInfo() const {
361 DCHECK(HasOuterScopeInfo());
362 if (!is_compiled()) return ScopeInfo::cast(outer_scope_info());
363 return scope_info()->OuterScopeInfo();
364 }
365
set_outer_scope_info(HeapObject * value,WriteBarrierMode mode)366 void SharedFunctionInfo::set_outer_scope_info(HeapObject* value,
367 WriteBarrierMode mode) {
368 DCHECK(!is_compiled());
369 DCHECK(raw_outer_scope_info_or_feedback_metadata()->IsTheHole(GetIsolate()));
370 DCHECK(value->IsScopeInfo() || value->IsTheHole(GetIsolate()));
371 return set_raw_outer_scope_info_or_feedback_metadata(value, mode);
372 }
373
HasFeedbackMetadata()374 bool SharedFunctionInfo::HasFeedbackMetadata() const {
375 return raw_outer_scope_info_or_feedback_metadata()->IsFeedbackMetadata();
376 }
377
feedback_metadata()378 FeedbackMetadata* SharedFunctionInfo::feedback_metadata() const {
379 DCHECK(HasFeedbackMetadata());
380 return FeedbackMetadata::cast(raw_outer_scope_info_or_feedback_metadata());
381 }
382
set_feedback_metadata(FeedbackMetadata * value,WriteBarrierMode mode)383 void SharedFunctionInfo::set_feedback_metadata(FeedbackMetadata* value,
384 WriteBarrierMode mode) {
385 DCHECK(!HasFeedbackMetadata());
386 DCHECK(value->IsFeedbackMetadata());
387 return set_raw_outer_scope_info_or_feedback_metadata(value, mode);
388 }
389
is_compiled()390 bool SharedFunctionInfo::is_compiled() const {
391 Object* data = function_data();
392 return data != Smi::FromEnum(Builtins::kCompileLazy) &&
393 !data->IsPreParsedScopeData();
394 }
395
GetLength()396 int SharedFunctionInfo::GetLength() const {
397 DCHECK(is_compiled());
398 DCHECK(HasLength());
399 return length();
400 }
401
HasLength()402 bool SharedFunctionInfo::HasLength() const {
403 DCHECK_IMPLIES(length() < 0, length() == kInvalidLength);
404 return length() != kInvalidLength;
405 }
406
has_simple_parameters()407 bool SharedFunctionInfo::has_simple_parameters() {
408 return scope_info()->HasSimpleParameters();
409 }
410
HasDebugInfo()411 bool SharedFunctionInfo::HasDebugInfo() const {
412 bool has_debug_info = !debug_info()->IsSmi();
413 DCHECK_EQ(debug_info()->IsStruct(), has_debug_info);
414 return has_debug_info;
415 }
416
IsApiFunction()417 bool SharedFunctionInfo::IsApiFunction() const {
418 return function_data()->IsFunctionTemplateInfo();
419 }
420
get_api_func_data()421 FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
422 DCHECK(IsApiFunction());
423 return FunctionTemplateInfo::cast(function_data());
424 }
425
HasBytecodeArray()426 bool SharedFunctionInfo::HasBytecodeArray() const {
427 return function_data()->IsBytecodeArray() ||
428 function_data()->IsInterpreterData();
429 }
430
GetBytecodeArray()431 BytecodeArray* SharedFunctionInfo::GetBytecodeArray() const {
432 DCHECK(HasBytecodeArray());
433 if (function_data()->IsBytecodeArray()) {
434 return BytecodeArray::cast(function_data());
435 } else {
436 DCHECK(function_data()->IsInterpreterData());
437 return InterpreterData::cast(function_data())->bytecode_array();
438 }
439 }
440
set_bytecode_array(class BytecodeArray * bytecode)441 void SharedFunctionInfo::set_bytecode_array(class BytecodeArray* bytecode) {
442 DCHECK(function_data() == Smi::FromEnum(Builtins::kCompileLazy));
443 set_function_data(bytecode);
444 }
445
InterpreterTrampoline()446 Code* SharedFunctionInfo::InterpreterTrampoline() const {
447 DCHECK(HasInterpreterData());
448 return interpreter_data()->interpreter_trampoline();
449 }
450
HasInterpreterData()451 bool SharedFunctionInfo::HasInterpreterData() const {
452 return function_data()->IsInterpreterData();
453 }
454
interpreter_data()455 InterpreterData* SharedFunctionInfo::interpreter_data() const {
456 DCHECK(HasInterpreterData());
457 return InterpreterData::cast(function_data());
458 }
459
set_interpreter_data(InterpreterData * interpreter_data)460 void SharedFunctionInfo::set_interpreter_data(
461 InterpreterData* interpreter_data) {
462 DCHECK(FLAG_interpreted_frames_native_stack);
463 set_function_data(interpreter_data);
464 }
465
HasAsmWasmData()466 bool SharedFunctionInfo::HasAsmWasmData() const {
467 return function_data()->IsFixedArray();
468 }
469
asm_wasm_data()470 FixedArray* SharedFunctionInfo::asm_wasm_data() const {
471 DCHECK(HasAsmWasmData());
472 return FixedArray::cast(function_data());
473 }
474
set_asm_wasm_data(FixedArray * data)475 void SharedFunctionInfo::set_asm_wasm_data(FixedArray* data) {
476 DCHECK(function_data() == Smi::FromEnum(Builtins::kCompileLazy) ||
477 HasAsmWasmData());
478 set_function_data(data);
479 }
480
HasBuiltinId()481 bool SharedFunctionInfo::HasBuiltinId() const {
482 return function_data()->IsSmi();
483 }
484
builtin_id()485 int SharedFunctionInfo::builtin_id() const {
486 DCHECK(HasBuiltinId());
487 int id = Smi::ToInt(function_data());
488 DCHECK(Builtins::IsBuiltinId(id));
489 return id;
490 }
491
set_builtin_id(int builtin_id)492 void SharedFunctionInfo::set_builtin_id(int builtin_id) {
493 DCHECK(Builtins::IsBuiltinId(builtin_id));
494 DCHECK_NE(builtin_id, Builtins::kDeserializeLazy);
495 set_function_data(Smi::FromInt(builtin_id), SKIP_WRITE_BARRIER);
496 }
497
HasPreParsedScopeData()498 bool SharedFunctionInfo::HasPreParsedScopeData() const {
499 return function_data()->IsPreParsedScopeData();
500 }
501
preparsed_scope_data()502 PreParsedScopeData* SharedFunctionInfo::preparsed_scope_data() const {
503 DCHECK(HasPreParsedScopeData());
504 return PreParsedScopeData::cast(function_data());
505 }
506
set_preparsed_scope_data(PreParsedScopeData * preparsed_scope_data)507 void SharedFunctionInfo::set_preparsed_scope_data(
508 PreParsedScopeData* preparsed_scope_data) {
509 DCHECK(function_data() == Smi::FromEnum(Builtins::kCompileLazy));
510 set_function_data(preparsed_scope_data);
511 }
512
ClearPreParsedScopeData()513 void SharedFunctionInfo::ClearPreParsedScopeData() {
514 DCHECK(function_data() == Smi::FromEnum(Builtins::kCompileLazy) ||
515 HasPreParsedScopeData());
516 set_builtin_id(Builtins::kCompileLazy);
517 }
518
HasWasmExportedFunctionData()519 bool SharedFunctionInfo::HasWasmExportedFunctionData() const {
520 return function_data()->IsWasmExportedFunctionData();
521 }
522
wasm_exported_function_data()523 WasmExportedFunctionData* SharedFunctionInfo::wasm_exported_function_data()
524 const {
525 DCHECK(HasWasmExportedFunctionData());
526 return WasmExportedFunctionData::cast(function_data());
527 }
528
HasBuiltinFunctionId()529 bool SharedFunctionInfo::HasBuiltinFunctionId() {
530 return function_identifier()->IsSmi();
531 }
532
builtin_function_id()533 BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
534 DCHECK(HasBuiltinFunctionId());
535 return static_cast<BuiltinFunctionId>(Smi::ToInt(function_identifier()));
536 }
537
set_builtin_function_id(BuiltinFunctionId id)538 void SharedFunctionInfo::set_builtin_function_id(BuiltinFunctionId id) {
539 set_function_identifier(Smi::FromInt(id));
540 }
541
HasInferredName()542 bool SharedFunctionInfo::HasInferredName() {
543 return function_identifier()->IsString();
544 }
545
inferred_name()546 String* SharedFunctionInfo::inferred_name() {
547 if (HasInferredName()) {
548 return String::cast(function_identifier());
549 }
550 DCHECK(function_identifier()->IsUndefined(GetIsolate()) ||
551 HasBuiltinFunctionId());
552 return GetHeap()->empty_string();
553 }
554
set_inferred_name(String * inferred_name)555 void SharedFunctionInfo::set_inferred_name(String* inferred_name) {
556 DCHECK(function_identifier()->IsUndefined(GetIsolate()) || HasInferredName());
557 set_function_identifier(inferred_name);
558 }
559
IsUserJavaScript()560 bool SharedFunctionInfo::IsUserJavaScript() {
561 Object* script_obj = script();
562 if (script_obj->IsUndefined(GetIsolate())) return false;
563 Script* script = Script::cast(script_obj);
564 return script->IsUserJavaScript();
565 }
566
IsSubjectToDebugging()567 bool SharedFunctionInfo::IsSubjectToDebugging() {
568 return IsUserJavaScript() && !HasAsmWasmData();
569 }
570
CanFlushCompiled()571 bool SharedFunctionInfo::CanFlushCompiled() const {
572 bool can_decompile =
573 (HasBytecodeArray() || HasAsmWasmData() || HasPreParsedScopeData());
574 return can_decompile;
575 }
576
FlushCompiled()577 void SharedFunctionInfo::FlushCompiled() {
578 DisallowHeapAllocation no_gc;
579
580 DCHECK(CanFlushCompiled());
581
582 Oddball* the_hole = GetIsolate()->heap()->the_hole_value();
583
584 if (is_compiled()) {
585 HeapObject* outer_scope_info = the_hole;
586 if (!is_toplevel()) {
587 if (scope_info()->HasOuterScopeInfo()) {
588 outer_scope_info = scope_info()->OuterScopeInfo();
589 }
590 }
591 // Raw setter to avoid validity checks, since we're performing the unusual
592 // task of decompiling.
593 set_raw_outer_scope_info_or_feedback_metadata(outer_scope_info);
594 } else {
595 DCHECK(outer_scope_info()->IsScopeInfo() || is_toplevel());
596 }
597
598 set_builtin_id(Builtins::kCompileLazy);
599 }
600
601 } // namespace internal
602 } // namespace v8
603
604 #include "src/objects/object-macros-undef.h"
605
606 #endif // V8_OBJECTS_SHARED_FUNCTION_INFO_INL_H_
607