V8 API Reference, 7.2.502.16 (for Deno 0.2.4)
shared-function-info-inl.h
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/objects/shared-function-info.h"
9 
10 #include "src/feedback-vector-inl.h"
11 #include "src/handles-inl.h"
12 #include "src/heap/heap-inl.h"
13 #include "src/objects/debug-objects-inl.h"
14 #include "src/objects/scope-info.h"
15 #include "src/objects/templates.h"
16 #include "src/wasm/wasm-objects-inl.h"
17 
18 // Has to be the last include (doesn't have include guards):
19 #include "src/objects/object-macros.h"
20 
21 namespace v8 {
22 namespace internal {
23 
24 CAST_ACCESSOR(PreParsedScopeData)
25 ACCESSORS2(PreParsedScopeData, scope_data, PodArray<uint8_t>, kScopeDataOffset)
26 INT_ACCESSORS(PreParsedScopeData, length, kLengthOffset)
27 
28 Object* PreParsedScopeData::child_data(int index) const {
29  DCHECK_GE(index, 0);
30  DCHECK_LT(index, this->length());
31  int offset = kChildDataStartOffset + index * kTaggedSize;
32  return RELAXED_READ_FIELD(this, offset);
33 }
34 
35 void PreParsedScopeData::set_child_data(int index, Object* value,
36  WriteBarrierMode mode) {
37  DCHECK_GE(index, 0);
38  DCHECK_LT(index, this->length());
39  int offset = kChildDataStartOffset + index * kTaggedSize;
40  RELAXED_WRITE_FIELD(this, offset, value);
41  CONDITIONAL_WRITE_BARRIER(this, offset, value, mode);
42 }
43 
44 ObjectSlot PreParsedScopeData::child_data_start() const {
45  return HeapObject::RawField(this, kChildDataStartOffset);
46 }
47 
48 void PreParsedScopeData::clear_padding() {
49  if (FIELD_SIZE(kOptionalPaddingOffset)) {
50  DCHECK_EQ(4, FIELD_SIZE(kOptionalPaddingOffset));
51  memset(reinterpret_cast<void*>(address() + kOptionalPaddingOffset), 0,
52  FIELD_SIZE(kOptionalPaddingOffset));
53  }
54 }
55 
56 CAST_ACCESSOR(UncompiledData)
57 ACCESSORS2(UncompiledData, inferred_name, String, kInferredNameOffset)
58 INT32_ACCESSORS(UncompiledData, start_position, kStartPositionOffset)
59 INT32_ACCESSORS(UncompiledData, end_position, kEndPositionOffset)
60 INT32_ACCESSORS(UncompiledData, function_literal_id, kFunctionLiteralIdOffset)
61 
62 void UncompiledData::clear_padding() {
63  if (FIELD_SIZE(kOptionalPaddingOffset)) {
64  DCHECK_EQ(4, FIELD_SIZE(kOptionalPaddingOffset));
65  memset(reinterpret_cast<void*>(address() + kOptionalPaddingOffset), 0,
66  FIELD_SIZE(kOptionalPaddingOffset));
67  }
68 }
69 
70 CAST_ACCESSOR(UncompiledDataWithoutPreParsedScope)
71 
72 CAST_ACCESSOR(UncompiledDataWithPreParsedScope)
73 ACCESSORS(UncompiledDataWithPreParsedScope, pre_parsed_scope_data,
74  PreParsedScopeData, kPreParsedScopeDataOffset)
75 
76 CAST_ACCESSOR(InterpreterData)
77 ACCESSORS2(InterpreterData, bytecode_array, BytecodeArray, kBytecodeArrayOffset)
78 ACCESSORS2(InterpreterData, interpreter_trampoline, Code,
79  kInterpreterTrampolineOffset)
80 
81 CAST_ACCESSOR(SharedFunctionInfo)
82 DEFINE_DEOPT_ELEMENT_ACCESSORS(SharedFunctionInfo, Object)
83 
84 ACCESSORS(SharedFunctionInfo, name_or_scope_info, Object,
85  kNameOrScopeInfoOffset)
86 ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
87 ACCESSORS(SharedFunctionInfo, script_or_debug_info, Object,
88  kScriptOrDebugInfoOffset)
89 
90 #if V8_SFI_HAS_UNIQUE_ID
91 INT_ACCESSORS(SharedFunctionInfo, unique_id, kUniqueIdOffset)
92 #endif
93 UINT16_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
94 UINT16_ACCESSORS(SharedFunctionInfo, internal_formal_parameter_count,
95  kFormalParameterCountOffset)
96 UINT8_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
97  kExpectedNofPropertiesOffset)
98 UINT8_ACCESSORS(SharedFunctionInfo, raw_builtin_function_id, kBuiltinFunctionId)
99 UINT16_ACCESSORS(SharedFunctionInfo, raw_function_token_offset,
100  kFunctionTokenOffsetOffset)
101 INT_ACCESSORS(SharedFunctionInfo, flags, kFlagsOffset)
102 
103 bool SharedFunctionInfo::HasSharedName() const {
104  Object* value = name_or_scope_info();
105  if (value->IsScopeInfo()) {
106  return ScopeInfo::cast(value)->HasSharedFunctionName();
107  }
108  return value != kNoSharedNameSentinel;
109 }
110 
111 String SharedFunctionInfo::Name() const {
112  if (!HasSharedName()) return GetReadOnlyRoots().empty_string();
113  Object* value = name_or_scope_info();
114  if (value->IsScopeInfo()) {
115  if (ScopeInfo::cast(value)->HasFunctionName()) {
116  return String::cast(ScopeInfo::cast(value)->FunctionName());
117  }
118  return GetReadOnlyRoots().empty_string();
119  }
120  return String::cast(value);
121 }
122 
123 void SharedFunctionInfo::SetName(String name) {
124  Object* maybe_scope_info = name_or_scope_info();
125  if (maybe_scope_info->IsScopeInfo()) {
126  ScopeInfo::cast(maybe_scope_info)->SetFunctionName(name);
127  } else {
128  DCHECK(maybe_scope_info->IsString() ||
129  maybe_scope_info == kNoSharedNameSentinel);
130  set_name_or_scope_info(name);
131  }
132  UpdateFunctionMapIndex();
133 }
134 
135 AbstractCode SharedFunctionInfo::abstract_code() {
136  if (HasBytecodeArray()) {
137  return AbstractCode::cast(GetBytecodeArray());
138  } else {
139  return AbstractCode::cast(GetCode());
140  }
141 }
142 
143 int SharedFunctionInfo::function_token_position() const {
144  int offset = raw_function_token_offset();
145  if (offset == kFunctionTokenOutOfRange) {
146  return kNoSourcePosition;
147  } else {
148  return StartPosition() - offset;
149  }
150 }
151 
152 BIT_FIELD_ACCESSORS(SharedFunctionInfo, flags, is_wrapped,
153  SharedFunctionInfo::IsWrappedBit)
154 BIT_FIELD_ACCESSORS(SharedFunctionInfo, flags, allows_lazy_compilation,
155  SharedFunctionInfo::AllowLazyCompilationBit)
156 BIT_FIELD_ACCESSORS(SharedFunctionInfo, flags, has_duplicate_parameters,
157  SharedFunctionInfo::HasDuplicateParametersBit)
158 BIT_FIELD_ACCESSORS(SharedFunctionInfo, flags, is_declaration,
159  SharedFunctionInfo::IsDeclarationBit)
160 
161 BIT_FIELD_ACCESSORS(SharedFunctionInfo, flags, native,
162  SharedFunctionInfo::IsNativeBit)
163 BIT_FIELD_ACCESSORS(SharedFunctionInfo, flags, is_asm_wasm_broken,
164  SharedFunctionInfo::IsAsmWasmBrokenBit)
165 BIT_FIELD_ACCESSORS(SharedFunctionInfo, flags,
166  requires_instance_members_initializer,
167  SharedFunctionInfo::RequiresInstanceMembersInitializer)
168 
169 BIT_FIELD_ACCESSORS(SharedFunctionInfo, flags, name_should_print_as_anonymous,
170  SharedFunctionInfo::NameShouldPrintAsAnonymousBit)
171 BIT_FIELD_ACCESSORS(SharedFunctionInfo, flags, is_anonymous_expression,
172  SharedFunctionInfo::IsAnonymousExpressionBit)
173 BIT_FIELD_ACCESSORS(SharedFunctionInfo, flags, deserialized,
174  SharedFunctionInfo::IsDeserializedBit)
175 BIT_FIELD_ACCESSORS(SharedFunctionInfo, flags, has_reported_binary_coverage,
176  SharedFunctionInfo::HasReportedBinaryCoverageBit)
177 
178 BIT_FIELD_ACCESSORS(SharedFunctionInfo, flags, is_named_expression,
179  SharedFunctionInfo::IsNamedExpressionBit)
180 BIT_FIELD_ACCESSORS(SharedFunctionInfo, flags, is_toplevel,
181  SharedFunctionInfo::IsTopLevelBit)
182 
183 bool SharedFunctionInfo::optimization_disabled() const {
184  return disable_optimization_reason() != BailoutReason::kNoReason;
185 }
186 
187 BailoutReason SharedFunctionInfo::disable_optimization_reason() const {
188  return DisabledOptimizationReasonBits::decode(flags());
189 }
190 
191 LanguageMode SharedFunctionInfo::language_mode() const {
192  STATIC_ASSERT(LanguageModeSize == 2);
193  return construct_language_mode(IsStrictBit::decode(flags()));
194 }
195 
196 void SharedFunctionInfo::set_language_mode(LanguageMode language_mode) {
197  STATIC_ASSERT(LanguageModeSize == 2);
198  // We only allow language mode transitions that set the same language mode
199  // again or go up in the chain:
200  DCHECK(is_sloppy(this->language_mode()) || is_strict(language_mode));
201  int hints = flags();
202  hints = IsStrictBit::update(hints, is_strict(language_mode));
203  set_flags(hints);
204  UpdateFunctionMapIndex();
205 }
206 
207 FunctionKind SharedFunctionInfo::kind() const {
208  return FunctionKindBits::decode(flags());
209 }
210 
211 void SharedFunctionInfo::set_kind(FunctionKind kind) {
212  int hints = flags();
213  hints = FunctionKindBits::update(hints, kind);
214  hints = IsClassConstructorBit::update(hints, IsClassConstructor(kind));
215  hints = IsDerivedConstructorBit::update(hints, IsDerivedConstructor(kind));
216  set_flags(hints);
217  UpdateFunctionMapIndex();
218 }
219 
220 bool SharedFunctionInfo::needs_home_object() const {
221  return NeedsHomeObjectBit::decode(flags());
222 }
223 
224 void SharedFunctionInfo::set_needs_home_object(bool value) {
225  int hints = flags();
226  hints = NeedsHomeObjectBit::update(hints, value);
227  set_flags(hints);
228  UpdateFunctionMapIndex();
229 }
230 
231 bool SharedFunctionInfo::construct_as_builtin() const {
232  return ConstructAsBuiltinBit::decode(flags());
233 }
234 
235 void SharedFunctionInfo::CalculateConstructAsBuiltin() {
236  bool uses_builtins_construct_stub = false;
237  if (HasBuiltinId()) {
238  int id = builtin_id();
239  if (id != Builtins::kCompileLazy && id != Builtins::kEmptyFunction) {
240  uses_builtins_construct_stub = true;
241  }
242  } else if (IsApiFunction()) {
243  uses_builtins_construct_stub = true;
244  }
245 
246  int f = flags();
247  f = ConstructAsBuiltinBit::update(f, uses_builtins_construct_stub);
248  set_flags(f);
249 }
250 
251 int SharedFunctionInfo::function_map_index() const {
252  // Note: Must be kept in sync with the FastNewClosure builtin.
253  int index =
254  Context::FIRST_FUNCTION_MAP_INDEX + FunctionMapIndexBits::decode(flags());
255  DCHECK_LE(index, Context::LAST_FUNCTION_MAP_INDEX);
256  return index;
257 }
258 
259 void SharedFunctionInfo::set_function_map_index(int index) {
260  STATIC_ASSERT(Context::LAST_FUNCTION_MAP_INDEX <=
261  Context::FIRST_FUNCTION_MAP_INDEX + FunctionMapIndexBits::kMax);
262  DCHECK_LE(Context::FIRST_FUNCTION_MAP_INDEX, index);
263  DCHECK_LE(index, Context::LAST_FUNCTION_MAP_INDEX);
264  index -= Context::FIRST_FUNCTION_MAP_INDEX;
265  set_flags(FunctionMapIndexBits::update(flags(), index));
266 }
267 
268 void SharedFunctionInfo::clear_padding() {
269  memset(reinterpret_cast<void*>(this->address() + kSize), 0,
270  kAlignedSize - kSize);
271 }
272 
273 void SharedFunctionInfo::UpdateFunctionMapIndex() {
274  int map_index = Context::FunctionMapIndex(
275  language_mode(), kind(), true, HasSharedName(), needs_home_object());
276  set_function_map_index(map_index);
277 }
278 
279 void SharedFunctionInfo::DontAdaptArguments() {
280  // TODO(leszeks): Revise this DCHECK now that the code field is gone.
281  DCHECK(!HasWasmExportedFunctionData());
282  set_internal_formal_parameter_count(kDontAdaptArgumentsSentinel);
283 }
284 
285 bool SharedFunctionInfo::IsInterpreted() const { return HasBytecodeArray(); }
286 
287 ScopeInfo SharedFunctionInfo::scope_info() const {
288  Object* maybe_scope_info = name_or_scope_info();
289  if (maybe_scope_info->IsScopeInfo()) {
290  return ScopeInfo::cast(maybe_scope_info);
291  }
292  return ScopeInfo::Empty(GetIsolate());
293 }
294 
295 void SharedFunctionInfo::set_scope_info(ScopeInfo scope_info,
296  WriteBarrierMode mode) {
297  // Move the existing name onto the ScopeInfo.
298  Object* name = name_or_scope_info();
299  if (name->IsScopeInfo()) {
300  name = ScopeInfo::cast(name)->FunctionName();
301  }
302  DCHECK(name->IsString() || name == kNoSharedNameSentinel);
303  // Only set the function name for function scopes.
304  scope_info->SetFunctionName(name);
305  if (HasInferredName() && inferred_name()->length() != 0) {
306  scope_info->SetInferredFunctionName(inferred_name());
307  }
308  WRITE_FIELD(this, kNameOrScopeInfoOffset, scope_info);
309  CONDITIONAL_WRITE_BARRIER(this, kNameOrScopeInfoOffset, scope_info, mode);
310 }
311 
312 ACCESSORS(SharedFunctionInfo, raw_outer_scope_info_or_feedback_metadata,
313  HeapObject, kOuterScopeInfoOrFeedbackMetadataOffset)
314 
315 HeapObject* SharedFunctionInfo::outer_scope_info() const {
316  DCHECK(!is_compiled());
317  DCHECK(!HasFeedbackMetadata());
318  return raw_outer_scope_info_or_feedback_metadata();
319 }
320 
321 bool SharedFunctionInfo::HasOuterScopeInfo() const {
322  ScopeInfo outer_info;
323  if (!is_compiled()) {
324  if (!outer_scope_info()->IsScopeInfo()) return false;
325  outer_info = ScopeInfo::cast(outer_scope_info());
326  } else {
327  if (!scope_info()->HasOuterScopeInfo()) return false;
328  outer_info = scope_info()->OuterScopeInfo();
329  }
330  return outer_info->length() > 0;
331 }
332 
333 ScopeInfo SharedFunctionInfo::GetOuterScopeInfo() const {
334  DCHECK(HasOuterScopeInfo());
335  if (!is_compiled()) return ScopeInfo::cast(outer_scope_info());
336  return scope_info()->OuterScopeInfo();
337 }
338 
339 void SharedFunctionInfo::set_outer_scope_info(HeapObject* value,
340  WriteBarrierMode mode) {
341  DCHECK(!is_compiled());
342  DCHECK(raw_outer_scope_info_or_feedback_metadata()->IsTheHole());
343  DCHECK(value->IsScopeInfo() || value->IsTheHole());
344  return set_raw_outer_scope_info_or_feedback_metadata(value, mode);
345 }
346 
347 bool SharedFunctionInfo::HasFeedbackMetadata() const {
348  return raw_outer_scope_info_or_feedback_metadata()->IsFeedbackMetadata();
349 }
350 
351 FeedbackMetadata* SharedFunctionInfo::feedback_metadata() const {
352  DCHECK(HasFeedbackMetadata());
353  return FeedbackMetadata::cast(raw_outer_scope_info_or_feedback_metadata());
354 }
355 
356 void SharedFunctionInfo::set_feedback_metadata(FeedbackMetadata* value,
357  WriteBarrierMode mode) {
358  DCHECK(!HasFeedbackMetadata());
359  DCHECK(value->IsFeedbackMetadata());
360  return set_raw_outer_scope_info_or_feedback_metadata(value, mode);
361 }
362 
363 bool SharedFunctionInfo::is_compiled() const {
364  Object* data = function_data();
365  return data != Smi::FromEnum(Builtins::kCompileLazy) &&
366  !data->IsUncompiledData();
367 }
368 
369 uint16_t SharedFunctionInfo::GetLength() const {
370  DCHECK(is_compiled());
371  DCHECK(HasLength());
372  return length();
373 }
374 
375 bool SharedFunctionInfo::HasLength() const {
376  return length() != kInvalidLength;
377 }
378 
379 bool SharedFunctionInfo::has_simple_parameters() {
380  return scope_info()->HasSimpleParameters();
381 }
382 
383 bool SharedFunctionInfo::IsApiFunction() const {
384  return function_data()->IsFunctionTemplateInfo();
385 }
386 
387 FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
388  DCHECK(IsApiFunction());
389  return FunctionTemplateInfo::cast(function_data());
390 }
391 
392 bool SharedFunctionInfo::HasBytecodeArray() const {
393  return function_data()->IsBytecodeArray() ||
394  function_data()->IsInterpreterData();
395 }
396 
397 BytecodeArray SharedFunctionInfo::GetBytecodeArray() const {
398  DCHECK(HasBytecodeArray());
399  if (HasDebugInfo() && GetDebugInfo()->HasInstrumentedBytecodeArray()) {
400  return GetDebugInfo()->OriginalBytecodeArray();
401  } else if (function_data()->IsBytecodeArray()) {
402  return BytecodeArray::cast(function_data());
403  } else {
404  DCHECK(function_data()->IsInterpreterData());
405  return InterpreterData::cast(function_data())->bytecode_array();
406  }
407 }
408 
409 BytecodeArray SharedFunctionInfo::GetDebugBytecodeArray() const {
410  DCHECK(HasBytecodeArray());
411  DCHECK(HasDebugInfo() && GetDebugInfo()->HasInstrumentedBytecodeArray());
412  if (function_data()->IsBytecodeArray()) {
413  return BytecodeArray::cast(function_data());
414  } else {
415  DCHECK(function_data()->IsInterpreterData());
416  return InterpreterData::cast(function_data())->bytecode_array();
417  }
418 }
419 
420 void SharedFunctionInfo::SetDebugBytecodeArray(BytecodeArray bytecode) {
421  DCHECK(HasBytecodeArray());
422  if (function_data()->IsBytecodeArray()) {
423  set_function_data(bytecode);
424  } else {
425  DCHECK(function_data()->IsInterpreterData());
426  interpreter_data()->set_bytecode_array(bytecode);
427  }
428 }
429 
430 void SharedFunctionInfo::set_bytecode_array(BytecodeArray bytecode) {
431  DCHECK(function_data() == Smi::FromEnum(Builtins::kCompileLazy) ||
432  HasUncompiledData());
433  set_function_data(bytecode);
434 }
435 
436 Code SharedFunctionInfo::InterpreterTrampoline() const {
437  DCHECK(HasInterpreterData());
438  return interpreter_data()->interpreter_trampoline();
439 }
440 
441 bool SharedFunctionInfo::HasInterpreterData() const {
442  return function_data()->IsInterpreterData();
443 }
444 
445 InterpreterData* SharedFunctionInfo::interpreter_data() const {
446  DCHECK(HasInterpreterData());
447  return InterpreterData::cast(function_data());
448 }
449 
450 void SharedFunctionInfo::set_interpreter_data(
451  InterpreterData* interpreter_data) {
452  DCHECK(FLAG_interpreted_frames_native_stack);
453  set_function_data(interpreter_data);
454 }
455 
456 bool SharedFunctionInfo::HasAsmWasmData() const {
457  return function_data()->IsAsmWasmData();
458 }
459 
460 AsmWasmData* SharedFunctionInfo::asm_wasm_data() const {
461  DCHECK(HasAsmWasmData());
462  return AsmWasmData::cast(function_data());
463 }
464 
465 void SharedFunctionInfo::set_asm_wasm_data(AsmWasmData* data) {
466  DCHECK(function_data() == Smi::FromEnum(Builtins::kCompileLazy) ||
467  HasUncompiledData() || HasAsmWasmData());
468  set_function_data(data);
469 }
470 
471 bool SharedFunctionInfo::HasBuiltinId() const {
472  return function_data()->IsSmi();
473 }
474 
475 int SharedFunctionInfo::builtin_id() const {
476  DCHECK(HasBuiltinId());
477  int id = Smi::ToInt(function_data());
478  DCHECK(Builtins::IsBuiltinId(id));
479  return id;
480 }
481 
482 void SharedFunctionInfo::set_builtin_id(int builtin_id) {
483  DCHECK(Builtins::IsBuiltinId(builtin_id));
484  set_function_data(Smi::FromInt(builtin_id), SKIP_WRITE_BARRIER);
485 }
486 
487 bool SharedFunctionInfo::HasUncompiledData() const {
488  return function_data()->IsUncompiledData();
489 }
490 
491 UncompiledData* SharedFunctionInfo::uncompiled_data() const {
492  DCHECK(HasUncompiledData());
493  return UncompiledData::cast(function_data());
494 }
495 
496 void SharedFunctionInfo::set_uncompiled_data(UncompiledData* uncompiled_data) {
497  DCHECK(function_data() == Smi::FromEnum(Builtins::kCompileLazy));
498  DCHECK(uncompiled_data->IsUncompiledData());
499  set_function_data(uncompiled_data);
500 }
501 
502 bool SharedFunctionInfo::HasUncompiledDataWithPreParsedScope() const {
503  return function_data()->IsUncompiledDataWithPreParsedScope();
504 }
505 
506 UncompiledDataWithPreParsedScope*
507 SharedFunctionInfo::uncompiled_data_with_pre_parsed_scope() const {
508  DCHECK(HasUncompiledDataWithPreParsedScope());
509  return UncompiledDataWithPreParsedScope::cast(function_data());
510 }
511 
512 void SharedFunctionInfo::set_uncompiled_data_with_pre_parsed_scope(
513  UncompiledDataWithPreParsedScope* uncompiled_data_with_pre_parsed_scope) {
514  DCHECK(function_data() == Smi::FromEnum(Builtins::kCompileLazy));
515  DCHECK(uncompiled_data_with_pre_parsed_scope
516  ->IsUncompiledDataWithPreParsedScope());
517  set_function_data(uncompiled_data_with_pre_parsed_scope);
518 }
519 
520 bool SharedFunctionInfo::HasUncompiledDataWithoutPreParsedScope() const {
521  return function_data()->IsUncompiledDataWithoutPreParsedScope();
522 }
523 
524 void SharedFunctionInfo::ClearPreParsedScopeData() {
525  DCHECK(HasUncompiledDataWithPreParsedScope());
526  UncompiledDataWithPreParsedScope* data =
527  uncompiled_data_with_pre_parsed_scope();
528 
529  // Trim off the pre-parsed scope data from the uncompiled data by swapping the
530  // map, leaving only an uncompiled data without pre-parsed scope.
531  DisallowHeapAllocation no_gc;
532  Heap* heap = Heap::FromWritableHeapObject(data);
533 
534  // Swap the map.
535  heap->NotifyObjectLayoutChange(data, UncompiledDataWithPreParsedScope::kSize,
536  no_gc);
537  STATIC_ASSERT(UncompiledDataWithoutPreParsedScope::kSize <
538  UncompiledDataWithPreParsedScope::kSize);
539  STATIC_ASSERT(UncompiledDataWithoutPreParsedScope::kSize ==
540  UncompiledData::kSize);
541  data->synchronized_set_map(
542  GetReadOnlyRoots().uncompiled_data_without_pre_parsed_scope_map());
543 
544  // Fill the remaining space with filler.
545  heap->CreateFillerObjectAt(
546  data->address() + UncompiledDataWithoutPreParsedScope::kSize,
547  UncompiledDataWithPreParsedScope::kSize -
548  UncompiledDataWithoutPreParsedScope::kSize,
549  ClearRecordedSlots::kNo);
550 
551  // Ensure that the clear was successful.
552  DCHECK(HasUncompiledDataWithoutPreParsedScope());
553 }
554 
555 bool SharedFunctionInfo::HasWasmExportedFunctionData() const {
556  return function_data()->IsWasmExportedFunctionData();
557 }
558 
559 Object* SharedFunctionInfo::script() const {
560  Object* maybe_script = script_or_debug_info();
561  if (maybe_script->IsDebugInfo()) {
562  return DebugInfo::cast(maybe_script)->script();
563  }
564  return maybe_script;
565 }
566 
567 void SharedFunctionInfo::set_script(Object* script) {
568  Object* maybe_debug_info = script_or_debug_info();
569  if (maybe_debug_info->IsDebugInfo()) {
570  DebugInfo::cast(maybe_debug_info)->set_script(script);
571  } else {
572  set_script_or_debug_info(script);
573  }
574 }
575 
576 bool SharedFunctionInfo::HasDebugInfo() const {
577  return script_or_debug_info()->IsDebugInfo();
578 }
579 
580 DebugInfo* SharedFunctionInfo::GetDebugInfo() const {
581  DCHECK(HasDebugInfo());
582  return DebugInfo::cast(script_or_debug_info());
583 }
584 
585 void SharedFunctionInfo::SetDebugInfo(DebugInfo* debug_info) {
586  DCHECK(!HasDebugInfo());
587  DCHECK_EQ(debug_info->script(), script_or_debug_info());
588  set_script_or_debug_info(debug_info);
589 }
590 
591 bool SharedFunctionInfo::HasBuiltinFunctionId() {
592  return builtin_function_id() != BuiltinFunctionId::kInvalidBuiltinFunctionId;
593 }
594 
595 BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
596  return static_cast<BuiltinFunctionId>(raw_builtin_function_id());
597 }
598 
599 void SharedFunctionInfo::set_builtin_function_id(BuiltinFunctionId id) {
600  set_raw_builtin_function_id(static_cast<uint8_t>(id));
601 }
602 
603 bool SharedFunctionInfo::HasInferredName() {
604  Object* scope_info = name_or_scope_info();
605  if (scope_info->IsScopeInfo()) {
606  return ScopeInfo::cast(scope_info)->HasInferredFunctionName();
607  }
608  return HasUncompiledData();
609 }
610 
611 String SharedFunctionInfo::inferred_name() {
612  Object* maybe_scope_info = name_or_scope_info();
613  if (maybe_scope_info->IsScopeInfo()) {
614  ScopeInfo scope_info = ScopeInfo::cast(maybe_scope_info);
615  if (scope_info->HasInferredFunctionName()) {
616  Object* name = ScopeInfo::cast(maybe_scope_info)->InferredFunctionName();
617  if (name->IsString()) return String::cast(name);
618  }
619  } else if (HasUncompiledData()) {
620  return uncompiled_data()->inferred_name();
621  }
622  return GetReadOnlyRoots().empty_string();
623 }
624 
625 bool SharedFunctionInfo::IsUserJavaScript() {
626  Object* script_obj = script();
627  if (script_obj->IsUndefined()) return false;
628  Script* script = Script::cast(script_obj);
629  return script->IsUserJavaScript();
630 }
631 
632 bool SharedFunctionInfo::IsSubjectToDebugging() {
633  return IsUserJavaScript() && !HasAsmWasmData();
634 }
635 
636 bool SharedFunctionInfo::CanDiscardCompiled() const {
637  bool can_decompile = (HasBytecodeArray() || HasAsmWasmData() ||
638  HasUncompiledDataWithPreParsedScope());
639  return can_decompile;
640 }
641 
642 // static
643 void SharedFunctionInfo::DiscardCompiled(
644  Isolate* isolate, Handle<SharedFunctionInfo> shared_info) {
645  DCHECK(shared_info->CanDiscardCompiled());
646 
647  int start_position = shared_info->StartPosition();
648  int end_position = shared_info->EndPosition();
649  int function_literal_id = shared_info->FunctionLiteralId(isolate);
650 
651  if (shared_info->is_compiled()) {
652  DisallowHeapAllocation no_gc;
653 
654  HeapObject* outer_scope_info;
655  if (shared_info->scope_info()->HasOuterScopeInfo()) {
656  outer_scope_info = shared_info->scope_info()->OuterScopeInfo();
657  } else {
658  outer_scope_info = ReadOnlyRoots(isolate).the_hole_value();
659  }
660  // Raw setter to avoid validity checks, since we're performing the unusual
661  // task of decompiling.
662  shared_info->set_raw_outer_scope_info_or_feedback_metadata(
663  outer_scope_info);
664  } else {
665  DCHECK(shared_info->outer_scope_info()->IsScopeInfo() ||
666  shared_info->outer_scope_info()->IsTheHole());
667  }
668 
669  if (shared_info->HasUncompiledDataWithPreParsedScope()) {
670  // If this is uncompiled data with a pre-parsed scope data, we can just
671  // clear out the scope data and keep the uncompiled data.
672  shared_info->ClearPreParsedScopeData();
673  } else {
674  // Create a new UncompiledData, without pre-parsed scope, and update the
675  // function data to point to it. Use the raw function data setter to avoid
676  // validity checks, since we're performing the unusual task of decompiling.
677  Handle<UncompiledData> data =
678  isolate->factory()->NewUncompiledDataWithoutPreParsedScope(
679  handle(shared_info->inferred_name(), isolate), start_position,
680  end_position, function_literal_id);
681  shared_info->set_function_data(*data);
682  }
683 }
684 
685 } // namespace internal
686 } // namespace v8
687 
688 #include "src/objects/object-macros-undef.h"
689 
690 #endif // V8_OBJECTS_SHARED_FUNCTION_INFO_INL_H_
Definition: libplatform.h:13