From: ulan@chromium.org Date: Tue, 15 Apr 2014 13:25:17 +0000 (+0000) Subject: Reland r20652 "Handlify and convert string.length to new API-style accessor." X-Git-Tag: upstream/4.7.83~9602 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a650916d3d0c15c1c6858da852cc57f7c8ad3815;p=platform%2Fupstream%2Fv8.git Reland r20652 "Handlify and convert string.length to new API-style accessor." BUG= R=dcarney@chromium.org, yangguo@chromium.org Review URL: https://codereview.chromium.org/231973004 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20767 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/accessors.cc b/src/accessors.cc index 3030e5d..18121ab 100644 --- a/src/accessors.cc +++ b/src/accessors.cc @@ -37,11 +37,33 @@ #include "isolate.h" #include "list-inl.h" #include "property-details.h" +#include "api.h" namespace v8 { namespace internal { +static Handle MakeAccessor(Isolate* isolate, + Handle name, + AccessorGetterCallback getter, + AccessorSetterCallback setter, + PropertyAttributes attributes) { + Factory* factory = isolate->factory(); + Handle info = factory->NewExecutableAccessorInfo(); + info->set_property_attributes(attributes); + info->set_all_can_read(true); + info->set_all_can_write(true); + info->set_prohibits_overwriting(false); + info->set_name(*factory->length_string()); + info->set_property_attributes(attributes); + Handle get = v8::FromCData(isolate, getter); + Handle set = v8::FromCData(isolate, setter); + info->set_getter(*get); + info->set_setter(*set); + return info; +} + + template static C* FindInstanceOf(Isolate* isolate, Object* obj) { for (Object* cur = obj; !cur->IsNull(); cur = cur->GetPrototype(isolate)) { @@ -233,24 +255,42 @@ const AccessorDescriptor Accessors::ArrayLength = { // Accessors::StringLength // +void Accessors::StringLengthGetter( + v8::Local name, + const v8::PropertyCallbackInfo& info) { + i::Isolate* isolate = reinterpret_cast(info.GetIsolate()); + DisallowHeapAllocation no_allocation; + HandleScope scope(isolate); + Object* value = *Utils::OpenHandle(*info.This()); + Object* result; + if (value->IsJSValue()) value = JSValue::cast(value)->value(); + if (value->IsString()) { + result = Smi::FromInt(String::cast(value)->length()); + } else { + // If object is not a string we return 0 to be compatible with WebKit. + // Note: Firefox returns the length of ToString(object). + result = Smi::FromInt(0); + } + info.GetReturnValue().Set(Utils::ToLocal(Handle(result, isolate))); +} -MaybeObject* Accessors::StringGetLength(Isolate* isolate, - Object* object, - void*) { - Object* value = object; - if (object->IsJSValue()) value = JSValue::cast(object)->value(); - if (value->IsString()) return Smi::FromInt(String::cast(value)->length()); - // If object is not a string we return 0 to be compatible with WebKit. - // Note: Firefox returns the length of ToString(object). - return Smi::FromInt(0); + +void Accessors::StringLengthSetter( + v8::Local name, + v8::Local value, + const v8::PropertyCallbackInfo& info) { + UNREACHABLE(); } -const AccessorDescriptor Accessors::StringLength = { - StringGetLength, - IllegalSetter, - 0 -}; +Handle Accessors::StringLengthInfo( + Isolate* isolate, PropertyAttributes attributes) { + return MakeAccessor(isolate, + isolate->factory()->length_string(), + &StringLengthGetter, + &StringLengthSetter, + attributes); +} // diff --git a/src/accessors.h b/src/accessors.h index 83a8472..db506ce 100644 --- a/src/accessors.h +++ b/src/accessors.h @@ -43,7 +43,6 @@ namespace internal { V(FunctionArguments) \ V(FunctionCaller) \ V(ArrayLength) \ - V(StringLength) \ V(ScriptSource) \ V(ScriptName) \ V(ScriptId) \ @@ -57,6 +56,9 @@ namespace internal { V(ScriptEvalFromScriptPosition) \ V(ScriptEvalFromFunctionName) +#define ACCESSOR_INFO_LIST(V) \ + V(StringLength) \ + // Accessors contains all predefined proxy accessors. class Accessors : public AllStatic { @@ -67,11 +69,30 @@ class Accessors : public AllStatic { ACCESSOR_DESCRIPTOR_LIST(ACCESSOR_DESCRIPTOR_DECLARATION) #undef ACCESSOR_DESCRIPTOR_DECLARATION +#define ACCESSOR_INFO_DECLARATION(name) \ + static void name##Getter( \ + v8::Local name, \ + const v8::PropertyCallbackInfo& info); \ + static void name##Setter( \ + v8::Local name, \ + v8::Local value, \ + const v8::PropertyCallbackInfo& info); \ + static Handle name##Info( \ + Isolate* isolate, \ + PropertyAttributes attributes); + ACCESSOR_INFO_LIST(ACCESSOR_INFO_DECLARATION) +#undef ACCESSOR_INFO_DECLARATION + enum DescriptorId { #define ACCESSOR_DESCRIPTOR_DECLARATION(name) \ k##name, ACCESSOR_DESCRIPTOR_LIST(ACCESSOR_DESCRIPTOR_DECLARATION) #undef ACCESSOR_DESCRIPTOR_DECLARATION +#define ACCESSOR_INFO_DECLARATION(name) \ + k##name##Getter, \ + k##name##Setter, + ACCESSOR_INFO_LIST(ACCESSOR_INFO_DECLARATION) +#undef ACCESSOR_INFO_DECLARATION descriptorCount }; @@ -92,7 +113,6 @@ class Accessors : public AllStatic { Handle name, int* object_offset); - private: // Accessor functions only used through the descriptor. static MaybeObject* FunctionSetPrototype(Isolate* isolate, diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc index 7c54d92..71672d7 100644 --- a/src/bootstrapper.cc +++ b/src/bootstrapper.cc @@ -911,10 +911,10 @@ void Genesis::InitializeGlobal(Handle inner_global, Handle(native_context()->string_function()->initial_map()); Map::EnsureDescriptorSlack(string_map, 1); - Handle string_length( - factory->NewForeign(&Accessors::StringLength)); PropertyAttributes attribs = static_cast( DONT_ENUM | DONT_DELETE | READ_ONLY); + Handle string_length( + Accessors::StringLengthInfo(isolate, attribs)); { // Add length. CallbacksDescriptor d(factory->length_string(), string_length, attribs); diff --git a/src/objects.cc b/src/objects.cc index 5a1daa2..04fc161 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -419,10 +419,9 @@ MaybeHandle JSObject::GetPropertyWithCallback(Handle object, v8::ToCData(data->getter()); if (call_fun == NULL) return isolate->factory()->undefined_value(); - Handle self = Handle::cast(receiver); Handle key = Handle::cast(name); - LOG(isolate, ApiNamedPropertyAccess("load", *self, *name)); - PropertyCallbackArguments args(isolate, data->data(), *self, *object); + LOG(isolate, ApiNamedPropertyAccess("load", *object, *name)); + PropertyCallbackArguments args(isolate, data->data(), *receiver, *object); v8::Handle result = args.Call(call_fun, v8::Utils::ToLocal(key)); RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); @@ -2884,8 +2883,7 @@ MaybeHandle JSObject::SetPropertyWithCallback(Handle object, if (call_fun == NULL) return value; Handle key = Handle::cast(name); LOG(isolate, ApiNamedPropertyAccess("store", *object, *name)); - PropertyCallbackArguments args( - isolate, data->data(), *object, JSObject::cast(*holder)); + PropertyCallbackArguments args(isolate, data->data(), *object, *holder); args.Call(call_fun, v8::Utils::ToLocal(key), v8::Utils::ToLocal(value)); @@ -12137,13 +12135,12 @@ MaybeHandle JSObject::GetElementWithCallback( v8::AccessorGetterCallback call_fun = v8::ToCData(fun_obj); if (call_fun == NULL) return isolate->factory()->undefined_value(); - Handle self = Handle::cast(receiver); Handle holder_handle = Handle::cast(holder); Handle number = isolate->factory()->NewNumberFromUint(index); Handle key = isolate->factory()->NumberToString(number); - LOG(isolate, ApiNamedPropertyAccess("load", *self, *key)); + LOG(isolate, ApiNamedPropertyAccess("load", *holder_handle, *key)); PropertyCallbackArguments - args(isolate, data->data(), *self, *holder_handle); + args(isolate, data->data(), *receiver, *holder_handle); v8::Handle result = args.Call(call_fun, v8::Utils::ToLocal(key)); RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); if (result.IsEmpty()) return isolate->factory()->undefined_value(); diff --git a/src/serialize.cc b/src/serialize.cc index 4048886..ed7f045 100644 --- a/src/serialize.cc +++ b/src/serialize.cc @@ -276,10 +276,21 @@ void ExternalReferenceTable::PopulateTable(Isolate* isolate) { ACCESSOR, \ Accessors::k##name, \ "Accessors::" #name); - ACCESSOR_DESCRIPTOR_LIST(ACCESSOR_DESCRIPTOR_DECLARATION) #undef ACCESSOR_DESCRIPTOR_DECLARATION +#define ACCESSOR_INFO_DECLARATION(name) \ + Add(FUNCTION_ADDR(&Accessors::name##Getter), \ + ACCESSOR, \ + Accessors::k##name##Getter, \ + "Accessors::" #name "Getter"); \ + Add(FUNCTION_ADDR(&Accessors::name##Setter), \ + ACCESSOR, \ + Accessors::k##name##Setter, \ + "Accessors::" #name "Setter"); + ACCESSOR_INFO_LIST(ACCESSOR_INFO_DECLARATION) +#undef ACCESSOR_INFO_DECLARATION + StubCache* stub_cache = isolate->stub_cache(); // Stub cache tables