diff options
Diffstat (limited to 'deps/v8/src/objects/templates.cc')
-rw-r--r-- | deps/v8/src/objects/templates.cc | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/deps/v8/src/objects/templates.cc b/deps/v8/src/objects/templates.cc new file mode 100644 index 0000000000..e5a8beff71 --- /dev/null +++ b/deps/v8/src/objects/templates.cc @@ -0,0 +1,145 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "src/objects/templates.h" + +#include "src/api/api-inl.h" +#include "src/execution/isolate.h" +#include "src/heap/factory.h" +#include "src/objects/function-kind.h" +#include "src/objects/instance-type-inl.h" +#include "src/objects/js-function-inl.h" +#include "src/objects/map-inl.h" +#include "src/objects/name-inl.h" +#include "src/objects/shared-function-info-inl.h" +#include "src/objects/string-inl.h" + +namespace v8 { +namespace internal { + +Handle<SharedFunctionInfo> FunctionTemplateInfo::GetOrCreateSharedFunctionInfo( + Isolate* isolate, Handle<FunctionTemplateInfo> info, + MaybeHandle<Name> maybe_name) { + Object current_info = info->shared_function_info(); + if (current_info.IsSharedFunctionInfo()) { + return handle(SharedFunctionInfo::cast(current_info), isolate); + } + Handle<Name> name; + Handle<String> name_string; + if (maybe_name.ToHandle(&name) && name->IsString()) { + name_string = Handle<String>::cast(name); + } else if (info->class_name().IsString()) { + name_string = handle(String::cast(info->class_name()), isolate); + } else { + name_string = isolate->factory()->empty_string(); + } + FunctionKind function_kind; + if (info->remove_prototype()) { + function_kind = kConciseMethod; + } else { + function_kind = kNormalFunction; + } + Handle<SharedFunctionInfo> result = + isolate->factory()->NewSharedFunctionInfoForApiFunction(name_string, info, + function_kind); + + result->set_length(info->length()); + result->DontAdaptArguments(); + DCHECK(result->IsApiFunction()); + + info->set_shared_function_info(*result); + return result; +} + +bool FunctionTemplateInfo::IsTemplateFor(Map map) const { + RCS_SCOPE( + LocalHeap::Current() == nullptr + ? GetIsolate()->counters()->runtime_call_stats() + : LocalIsolate::FromHeap(LocalHeap::Current())->runtime_call_stats(), + RuntimeCallCounterId::kIsTemplateFor); + + // There is a constraint on the object; check. + if (!map.IsJSObjectMap()) return false; + // Fetch the constructor function of the object. + Object cons_obj = map.GetConstructor(); + Object type; + if (cons_obj.IsJSFunction()) { + JSFunction fun = JSFunction::cast(cons_obj); + type = fun.shared().function_data(kAcquireLoad); + } else if (cons_obj.IsFunctionTemplateInfo()) { + type = FunctionTemplateInfo::cast(cons_obj); + } else { + return false; + } + // Iterate through the chain of inheriting function templates to + // see if the required one occurs. + while (type.IsFunctionTemplateInfo()) { + if (type == *this) return true; + type = FunctionTemplateInfo::cast(type).GetParentTemplate(); + } + // Didn't find the required type in the inheritance chain. + return false; +} + +bool FunctionTemplateInfo::IsLeafTemplateForApiObject(Object object) const { + i::DisallowGarbageCollection no_gc; + + if (!object.IsJSApiObject()) { + return false; + } + + bool result = false; + Map map = HeapObject::cast(object).map(); + Object constructor_obj = map.GetConstructor(); + if (constructor_obj.IsJSFunction()) { + JSFunction fun = JSFunction::cast(constructor_obj); + result = (*this == fun.shared().function_data(kAcquireLoad)); + } else if (constructor_obj.IsFunctionTemplateInfo()) { + result = (*this == constructor_obj); + } + DCHECK_IMPLIES(result, IsTemplateFor(map)); + return result; +} + +// static +FunctionTemplateRareData FunctionTemplateInfo::AllocateFunctionTemplateRareData( + Isolate* isolate, Handle<FunctionTemplateInfo> function_template_info) { + DCHECK(function_template_info->rare_data(kAcquireLoad).IsUndefined(isolate)); + Handle<FunctionTemplateRareData> rare_data = + isolate->factory()->NewFunctionTemplateRareData(); + function_template_info->set_rare_data(*rare_data, kReleaseStore); + return *rare_data; +} + +base::Optional<Name> FunctionTemplateInfo::TryGetCachedPropertyName( + Isolate* isolate, Object getter) { + DisallowGarbageCollection no_gc; + if (!getter.IsFunctionTemplateInfo()) return {}; + // Check if the accessor uses a cached property. + Object maybe_name = FunctionTemplateInfo::cast(getter).cached_property_name(); + if (maybe_name.IsTheHole(isolate)) return {}; + return Name::cast(maybe_name); +} + +int FunctionTemplateInfo::GetCFunctionsCount() const { + i::DisallowHeapAllocation no_gc; + return FixedArray::cast(GetCFunctionOverloads()).length() / + kFunctionOverloadEntrySize; +} + +Address FunctionTemplateInfo::GetCFunction(int index) const { + i::DisallowHeapAllocation no_gc; + return v8::ToCData<Address>(FixedArray::cast(GetCFunctionOverloads()) + .get(index * kFunctionOverloadEntrySize)); +} + +const CFunctionInfo* FunctionTemplateInfo::GetCSignature(int index) const { + i::DisallowHeapAllocation no_gc; + return v8::ToCData<CFunctionInfo*>( + FixedArray::cast(GetCFunctionOverloads()) + .get(index * kFunctionOverloadEntrySize + 1)); +} + +} // namespace internal +} // namespace v8 |