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