📄 handles.cc.svn-base
字号:
#undef CALL_HEAP_FUNCTION#undef CALL_GC// Compute the property keys from the interceptor.v8::Handle<v8::Array> GetKeysForNamedInterceptor(Handle<JSObject> receiver, Handle<JSObject> object) { Handle<InterceptorInfo> interceptor(object->GetNamedInterceptor()); Handle<Object> data(interceptor->data()); v8::AccessorInfo info( v8::Utils::ToLocal(receiver), v8::Utils::ToLocal(data), v8::Utils::ToLocal(object)); v8::Handle<v8::Array> result; if (!interceptor->enumerator()->IsUndefined()) { v8::NamedPropertyEnumerator enum_fun = v8::ToCData<v8::NamedPropertyEnumerator>(interceptor->enumerator()); LOG(ApiObjectAccess("interceptor-named-enum", *object)); { // Leaving JavaScript. VMState state(OTHER); result = enum_fun(info); } } return result;}// Compute the element keys from the interceptor.v8::Handle<v8::Array> GetKeysForIndexedInterceptor(Handle<JSObject> receiver, Handle<JSObject> object) { Handle<InterceptorInfo> interceptor(object->GetIndexedInterceptor()); Handle<Object> data(interceptor->data()); v8::AccessorInfo info( v8::Utils::ToLocal(receiver), v8::Utils::ToLocal(data), v8::Utils::ToLocal(object)); v8::Handle<v8::Array> result; if (!interceptor->enumerator()->IsUndefined()) { v8::IndexedPropertyEnumerator enum_fun = v8::ToCData<v8::IndexedPropertyEnumerator>(interceptor->enumerator()); LOG(ApiObjectAccess("interceptor-indexed-enum", *object)); { // Leaving JavaScript. VMState state(OTHER); result = enum_fun(info); } } return result;}Handle<FixedArray> GetKeysInFixedArrayFor(Handle<JSObject> object) { Handle<FixedArray> content = Factory::empty_fixed_array(); JSObject* arguments_boilerplate = Top::context()->global_context()->arguments_boilerplate(); JSFunction* arguments_function = JSFunction::cast(arguments_boilerplate->map()->constructor()); bool allow_enumeration = (object->map()->constructor() != arguments_function); // Only collect keys if access is permitted. if (allow_enumeration) { for (Handle<Object> p = object; *p != Heap::null_value(); p = Handle<Object>(p->GetPrototype())) { Handle<JSObject> current(JSObject::cast(*p)); // Check access rights if required. if (current->IsAccessCheckNeeded() && !Top::MayNamedAccess(*current, Heap::undefined_value(), v8::ACCESS_KEYS)) { Top::ReportFailedAccessCheck(*current, v8::ACCESS_KEYS); break; } // Compute the property keys. content = UnionOfKeys(content, GetEnumPropertyKeys(current)); // Add the property keys from the interceptor. if (current->HasNamedInterceptor()) { v8::Handle<v8::Array> result = GetKeysForNamedInterceptor(object, current); if (!result.IsEmpty()) content = AddKeysFromJSArray(content, v8::Utils::OpenHandle(*result)); } // Compute the element keys. Handle<FixedArray> element_keys = Factory::NewFixedArray(current->NumberOfEnumElements()); current->GetEnumElementKeys(*element_keys); content = UnionOfKeys(content, element_keys); // Add the element keys from the interceptor. if (current->HasIndexedInterceptor()) { v8::Handle<v8::Array> result = GetKeysForIndexedInterceptor(object, current); if (!result.IsEmpty()) content = AddKeysFromJSArray(content, v8::Utils::OpenHandle(*result)); } } } return content;}Handle<JSArray> GetKeysFor(Handle<JSObject> object) { Counters::for_in.Increment(); Handle<FixedArray> content = GetKeysInFixedArrayFor(object); // Allocate the JSArray with the result. Handle<JSArray> obj = Factory::NewJSArray(content->length()); Handle<JSArray>::cast(obj)->SetContent(*content); return Handle<JSArray>::cast(obj);}Handle<FixedArray> GetEnumPropertyKeys(Handle<JSObject> object) { int index = 0; if (object->HasFastProperties()) { if (object->map()->instance_descriptors()->HasEnumCache()) { Counters::enum_cache_hits.Increment(); DescriptorArray* desc = object->map()->instance_descriptors(); return Handle<FixedArray>(FixedArray::cast(desc->GetEnumCache())); } Counters::enum_cache_misses.Increment(); int num_enum = object->NumberOfEnumProperties(); Handle<FixedArray> storage = Factory::NewFixedArray(num_enum); Handle<FixedArray> sort_array = Factory::NewFixedArray(num_enum); for (DescriptorReader r(object->map()->instance_descriptors()); !r.eos(); r.advance()) { if (!r.IsTransition() && !r.IsDontEnum()) { (*storage)->set(index, r.GetKey()); (*sort_array)->set(index, Smi::FromInt(r.GetDetails().index())); index++; } } (*storage)->SortPairs(*sort_array); Handle<FixedArray> bridge_storage = Factory::NewFixedArray(DescriptorArray::kEnumCacheBridgeLength); DescriptorArray* desc = object->map()->instance_descriptors(); desc->SetEnumCache(*bridge_storage, *storage); ASSERT(storage->length() == index); return storage; } else { int num_enum = object->NumberOfEnumProperties(); Handle<FixedArray> storage = Factory::NewFixedArray(num_enum); Handle<FixedArray> sort_array = Factory::NewFixedArray(num_enum); object->property_dictionary()->CopyEnumKeysTo(*storage, *sort_array); return storage; }}bool CompileLazyShared(Handle<SharedFunctionInfo> shared, ClearExceptionFlag flag) { // Compile the source information to a code object. ASSERT(!shared->is_compiled()); bool result = Compiler::CompileLazy(shared); ASSERT(result != Top::has_pending_exception()); if (!result && flag == CLEAR_EXCEPTION) Top::clear_pending_exception(); return result;}bool CompileLazy(Handle<JSFunction> function, ClearExceptionFlag flag) { // Compile the source information to a code object. Handle<SharedFunctionInfo> shared(function->shared()); return CompileLazyShared(shared, flag);}OptimizedObjectForAddingMultipleProperties::OptimizedObjectForAddingMultipleProperties(Handle<JSObject> object, bool condition) { object_ = object; if (condition && object_->HasFastProperties()) { // Normalize the properties of object to avoid n^2 behavior // when extending the object multiple properties. unused_property_fields_ = object->map()->unused_property_fields(); NormalizeProperties(object_); has_been_transformed_ = true; } else { has_been_transformed_ = false; }}OptimizedObjectForAddingMultipleProperties::~OptimizedObjectForAddingMultipleProperties() { // Reoptimize the object to allow fast property access. if (has_been_transformed_) { TransformToFastProperties(object_, unused_property_fields_); }}void LoadLazy(Handle<JSFunction> fun, bool* pending_exception) { HandleScope scope; Handle<FixedArray> info(FixedArray::cast(fun->shared()->lazy_load_data())); int index = Smi::cast(info->get(0))->value(); ASSERT(index >= 0); Handle<Context> compile_context(Context::cast(info->get(1))); Handle<Context> function_context(Context::cast(info->get(2))); Handle<Context> security_context(Context::cast(info->get(3))); Handle<Object> receiver(compile_context->global()->builtins()); Vector<const char> name = Natives::GetScriptName(index); Handle<JSFunction> boilerplate; if (!Bootstrapper::NativesCacheLookup(name, &boilerplate)) { Handle<String> source_code = Bootstrapper::NativesSourceLookup(index); Handle<String> script_name = Factory::NewStringFromAscii(name); bool allow_natives_syntax = FLAG_allow_natives_syntax; FLAG_allow_natives_syntax = true; boilerplate = Compiler::Compile(source_code, script_name, 0, 0, NULL, NULL); FLAG_allow_natives_syntax = allow_natives_syntax; // If the compilation failed (possibly due to stack overflows), we // should never enter the result in the natives cache. Instead we // return from the function without marking the function as having // been lazily loaded. if (boilerplate.is_null()) { *pending_exception = true; return; } Bootstrapper::NativesCacheAdd(name, boilerplate); } // We shouldn't get here if compiling the script failed. ASSERT(!boilerplate.is_null()); // When the debugger running in its own context touches lazy loaded // functions loading can be triggered. In that case ensure that the // execution of the boilerplate is in the correct context. SaveContext save; if (!Debug::debug_context().is_null() && Top::context() == *Debug::debug_context()) { Top::set_context(*compile_context); Top::set_security_context(*security_context); } // Reset the lazy load data before running the script to make sure // not to get recursive lazy loading. fun->shared()->set_lazy_load_data(Heap::undefined_value()); // Run the script. Handle<JSFunction> script_fun( Factory::NewFunctionFromBoilerplate(boilerplate, function_context)); Execution::Call(script_fun, receiver, 0, NULL, pending_exception); // If lazy loading failed, restore the unloaded state of fun. if (*pending_exception) fun->shared()->set_lazy_load_data(*info);}void SetupLazy(Handle<JSFunction> fun, int index, Handle<Context> compile_context, Handle<Context> function_context, Handle<Context> security_context) { Handle<FixedArray> arr = Factory::NewFixedArray(4); arr->set(0, Smi::FromInt(index)); arr->set(1, *compile_context); // Compile in this context arr->set(2, *function_context); // Set function context to this arr->set(3, *security_context); // Receiver for call fun->shared()->set_lazy_load_data(*arr);}} } // namespace v8::internal
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -