#include "isolate.h"
#include "list-inl.h"
#include "property-details.h"
+#include "api.h"
namespace v8 {
namespace internal {
+static Handle<AccessorInfo> MakeAccessor(Isolate* isolate,
+ Handle<String> name,
+ AccessorGetterCallback getter,
+ AccessorSetterCallback setter,
+ PropertyAttributes attributes) {
+ Factory* factory = isolate->factory();
+ Handle<ExecutableAccessorInfo> 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<Object> get = v8::FromCData(isolate, getter);
+ Handle<Object> set = v8::FromCData(isolate, setter);
+ info->set_getter(*get);
+ info->set_setter(*set);
+ return info;
+}
+
+
template <class C>
static C* FindInstanceOf(Isolate* isolate, Object* obj) {
for (Object* cur = obj; !cur->IsNull(); cur = cur->GetPrototype(isolate)) {
// Accessors::StringLength
//
+void Accessors::StringLengthGetter(
+ v8::Local<v8::String> name,
+ const v8::PropertyCallbackInfo<v8::Value>& info) {
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(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<Object>(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<v8::String> name,
+ v8::Local<v8::Value> value,
+ const v8::PropertyCallbackInfo<void>& info) {
+ UNREACHABLE();
}
-const AccessorDescriptor Accessors::StringLength = {
- StringGetLength,
- IllegalSetter,
- 0
-};
+Handle<AccessorInfo> Accessors::StringLengthInfo(
+ Isolate* isolate, PropertyAttributes attributes) {
+ return MakeAccessor(isolate,
+ isolate->factory()->length_string(),
+ &StringLengthGetter,
+ &StringLengthSetter,
+ attributes);
+}
//
V(FunctionArguments) \
V(FunctionCaller) \
V(ArrayLength) \
- V(StringLength) \
V(ScriptSource) \
V(ScriptName) \
V(ScriptId) \
V(ScriptEvalFromScriptPosition) \
V(ScriptEvalFromFunctionName)
+#define ACCESSOR_INFO_LIST(V) \
+ V(StringLength) \
+
// Accessors contains all predefined proxy accessors.
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<v8::String> name, \
+ const v8::PropertyCallbackInfo<v8::Value>& info); \
+ static void name##Setter( \
+ v8::Local<v8::String> name, \
+ v8::Local<v8::Value> value, \
+ const v8::PropertyCallbackInfo<void>& info); \
+ static Handle<AccessorInfo> 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
};
Handle<String> name,
int* object_offset);
-
private:
// Accessor functions only used through the descriptor.
static MaybeObject* FunctionSetPrototype(Isolate* isolate,
Handle<Map>(native_context()->string_function()->initial_map());
Map::EnsureDescriptorSlack(string_map, 1);
- Handle<Foreign> string_length(
- factory->NewForeign(&Accessors::StringLength));
PropertyAttributes attribs = static_cast<PropertyAttributes>(
DONT_ENUM | DONT_DELETE | READ_ONLY);
+ Handle<AccessorInfo> string_length(
+ Accessors::StringLengthInfo(isolate, attribs));
{ // Add length.
CallbacksDescriptor d(factory->length_string(), string_length, attribs);
v8::ToCData<v8::AccessorGetterCallback>(data->getter());
if (call_fun == NULL) return isolate->factory()->undefined_value();
- Handle<JSObject> self = Handle<JSObject>::cast(receiver);
Handle<String> key = Handle<String>::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<v8::Value> result =
args.Call(call_fun, v8::Utils::ToLocal(key));
RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
if (call_fun == NULL) return value;
Handle<String> key = Handle<String>::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));
v8::AccessorGetterCallback call_fun =
v8::ToCData<v8::AccessorGetterCallback>(fun_obj);
if (call_fun == NULL) return isolate->factory()->undefined_value();
- Handle<JSObject> self = Handle<JSObject>::cast(receiver);
Handle<JSObject> holder_handle = Handle<JSObject>::cast(holder);
Handle<Object> number = isolate->factory()->NewNumberFromUint(index);
Handle<String> 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<v8::Value> result = args.Call(call_fun, v8::Utils::ToLocal(key));
RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
if (result.IsEmpty()) return isolate->factory()->undefined_value();
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