11cb0ef41Sopenharmony_ci// Copyright 2017 the V8 project authors. All rights reserved. 21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be 31cb0ef41Sopenharmony_ci// found in the LICENSE file. 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ci#include "src/objects/template-objects.h" 61cb0ef41Sopenharmony_ci 71cb0ef41Sopenharmony_ci#include "src/base/functional.h" 81cb0ef41Sopenharmony_ci#include "src/execution/isolate.h" 91cb0ef41Sopenharmony_ci#include "src/heap/factory.h" 101cb0ef41Sopenharmony_ci#include "src/objects/objects-inl.h" 111cb0ef41Sopenharmony_ci#include "src/objects/property-descriptor.h" 121cb0ef41Sopenharmony_ci#include "src/objects/template-objects-inl.h" 131cb0ef41Sopenharmony_ci 141cb0ef41Sopenharmony_cinamespace v8 { 151cb0ef41Sopenharmony_cinamespace internal { 161cb0ef41Sopenharmony_ci 171cb0ef41Sopenharmony_ci// static 181cb0ef41Sopenharmony_ciHandle<JSArray> TemplateObjectDescription::GetTemplateObject( 191cb0ef41Sopenharmony_ci Isolate* isolate, Handle<NativeContext> native_context, 201cb0ef41Sopenharmony_ci Handle<TemplateObjectDescription> description, 211cb0ef41Sopenharmony_ci Handle<SharedFunctionInfo> shared_info, int slot_id) { 221cb0ef41Sopenharmony_ci uint32_t hash = shared_info->Hash(); 231cb0ef41Sopenharmony_ci 241cb0ef41Sopenharmony_ci // Check the template weakmap to see if the template object already exists. 251cb0ef41Sopenharmony_ci Handle<EphemeronHashTable> template_weakmap; 261cb0ef41Sopenharmony_ci 271cb0ef41Sopenharmony_ci if (native_context->template_weakmap().IsUndefined(isolate)) { 281cb0ef41Sopenharmony_ci template_weakmap = EphemeronHashTable::New(isolate, 1); 291cb0ef41Sopenharmony_ci } else { 301cb0ef41Sopenharmony_ci DisallowGarbageCollection no_gc; 311cb0ef41Sopenharmony_ci ReadOnlyRoots roots(isolate); 321cb0ef41Sopenharmony_ci template_weakmap = handle( 331cb0ef41Sopenharmony_ci EphemeronHashTable::cast(native_context->template_weakmap()), isolate); 341cb0ef41Sopenharmony_ci Object maybe_cached_template = template_weakmap->Lookup(shared_info, hash); 351cb0ef41Sopenharmony_ci while (!maybe_cached_template.IsTheHole(roots)) { 361cb0ef41Sopenharmony_ci CachedTemplateObject cached_template = 371cb0ef41Sopenharmony_ci CachedTemplateObject::cast(maybe_cached_template); 381cb0ef41Sopenharmony_ci if (cached_template.slot_id() == slot_id) { 391cb0ef41Sopenharmony_ci return handle(cached_template.template_object(), isolate); 401cb0ef41Sopenharmony_ci } 411cb0ef41Sopenharmony_ci maybe_cached_template = cached_template.next(); 421cb0ef41Sopenharmony_ci } 431cb0ef41Sopenharmony_ci } 441cb0ef41Sopenharmony_ci 451cb0ef41Sopenharmony_ci // Create the raw object from the {raw_strings}. 461cb0ef41Sopenharmony_ci Handle<FixedArray> raw_strings(description->raw_strings(), isolate); 471cb0ef41Sopenharmony_ci Handle<JSArray> raw_object = isolate->factory()->NewJSArrayWithElements( 481cb0ef41Sopenharmony_ci raw_strings, PACKED_ELEMENTS, raw_strings->length(), 491cb0ef41Sopenharmony_ci AllocationType::kOld); 501cb0ef41Sopenharmony_ci 511cb0ef41Sopenharmony_ci // Create the template object from the {cooked_strings}. 521cb0ef41Sopenharmony_ci Handle<FixedArray> cooked_strings(description->cooked_strings(), isolate); 531cb0ef41Sopenharmony_ci Handle<JSArray> template_object = isolate->factory()->NewJSArrayWithElements( 541cb0ef41Sopenharmony_ci cooked_strings, PACKED_ELEMENTS, cooked_strings->length(), 551cb0ef41Sopenharmony_ci AllocationType::kOld); 561cb0ef41Sopenharmony_ci 571cb0ef41Sopenharmony_ci // Freeze the {raw_object}. 581cb0ef41Sopenharmony_ci JSObject::SetIntegrityLevel(raw_object, FROZEN, kThrowOnError).ToChecked(); 591cb0ef41Sopenharmony_ci 601cb0ef41Sopenharmony_ci // Install a "raw" data property for {raw_object} on {template_object}. 611cb0ef41Sopenharmony_ci PropertyDescriptor raw_desc; 621cb0ef41Sopenharmony_ci raw_desc.set_value(raw_object); 631cb0ef41Sopenharmony_ci raw_desc.set_configurable(false); 641cb0ef41Sopenharmony_ci raw_desc.set_enumerable(false); 651cb0ef41Sopenharmony_ci raw_desc.set_writable(false); 661cb0ef41Sopenharmony_ci JSArray::DefineOwnProperty(isolate, template_object, 671cb0ef41Sopenharmony_ci isolate->factory()->raw_string(), &raw_desc, 681cb0ef41Sopenharmony_ci Just(kThrowOnError)) 691cb0ef41Sopenharmony_ci .ToChecked(); 701cb0ef41Sopenharmony_ci 711cb0ef41Sopenharmony_ci // Freeze the {template_object} as well. 721cb0ef41Sopenharmony_ci JSObject::SetIntegrityLevel(template_object, FROZEN, kThrowOnError) 731cb0ef41Sopenharmony_ci .ToChecked(); 741cb0ef41Sopenharmony_ci 751cb0ef41Sopenharmony_ci // Insert the template object into the template weakmap. 761cb0ef41Sopenharmony_ci Handle<HeapObject> previous_cached_templates = handle( 771cb0ef41Sopenharmony_ci HeapObject::cast(template_weakmap->Lookup(shared_info, hash)), isolate); 781cb0ef41Sopenharmony_ci Handle<CachedTemplateObject> cached_template = CachedTemplateObject::New( 791cb0ef41Sopenharmony_ci isolate, slot_id, template_object, previous_cached_templates); 801cb0ef41Sopenharmony_ci template_weakmap = EphemeronHashTable::Put( 811cb0ef41Sopenharmony_ci isolate, template_weakmap, shared_info, cached_template, hash); 821cb0ef41Sopenharmony_ci native_context->set_template_weakmap(*template_weakmap); 831cb0ef41Sopenharmony_ci 841cb0ef41Sopenharmony_ci return template_object; 851cb0ef41Sopenharmony_ci} 861cb0ef41Sopenharmony_ci 871cb0ef41Sopenharmony_ciHandle<CachedTemplateObject> CachedTemplateObject::New( 881cb0ef41Sopenharmony_ci Isolate* isolate, int slot_id, Handle<JSArray> template_object, 891cb0ef41Sopenharmony_ci Handle<HeapObject> next) { 901cb0ef41Sopenharmony_ci DCHECK(next->IsCachedTemplateObject() || next->IsTheHole()); 911cb0ef41Sopenharmony_ci Handle<CachedTemplateObject> result_handle = 921cb0ef41Sopenharmony_ci Handle<CachedTemplateObject>::cast(isolate->factory()->NewStruct( 931cb0ef41Sopenharmony_ci CACHED_TEMPLATE_OBJECT_TYPE, AllocationType::kOld)); 941cb0ef41Sopenharmony_ci { 951cb0ef41Sopenharmony_ci DisallowGarbageCollection no_gc; 961cb0ef41Sopenharmony_ci auto result = *result_handle; 971cb0ef41Sopenharmony_ci result.set_slot_id(slot_id); 981cb0ef41Sopenharmony_ci result.set_template_object(*template_object); 991cb0ef41Sopenharmony_ci result.set_next(*next); 1001cb0ef41Sopenharmony_ci } 1011cb0ef41Sopenharmony_ci return result_handle; 1021cb0ef41Sopenharmony_ci} 1031cb0ef41Sopenharmony_ci 1041cb0ef41Sopenharmony_ci} // namespace internal 1051cb0ef41Sopenharmony_ci} // namespace v8 106