Remove old-style accessor support from runtime.
BUG= R=yangguo@chromium.org Review URL: https://codereview.chromium.org/258243003 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@21041 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
39c4b3c18d
commit
1a2d652658
@ -20,11 +20,12 @@ namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
|
||||
static Handle<AccessorInfo> MakeAccessor(Isolate* isolate,
|
||||
Handle<String> name,
|
||||
AccessorGetterCallback getter,
|
||||
AccessorSetterCallback setter,
|
||||
PropertyAttributes attributes) {
|
||||
Handle<AccessorInfo> Accessors::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);
|
||||
@ -49,34 +50,6 @@ static C* FindInstanceOf(Isolate* isolate, Object* obj) {
|
||||
}
|
||||
|
||||
|
||||
// Entry point that never should be called.
|
||||
Object* Accessors::IllegalSetter(Isolate* isolate,
|
||||
JSObject*,
|
||||
Object*,
|
||||
void*) {
|
||||
UNREACHABLE();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
Object* Accessors::IllegalGetAccessor(Isolate* isolate,
|
||||
Object* object,
|
||||
void*) {
|
||||
UNREACHABLE();
|
||||
return object;
|
||||
}
|
||||
|
||||
|
||||
Object* Accessors::ReadOnlySetAccessor(Isolate* isolate,
|
||||
JSObject*,
|
||||
Object* value,
|
||||
void*) {
|
||||
// According to ECMA-262, section 8.6.2.2, page 28, setting
|
||||
// read-only properties must be silently ignored.
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
static V8_INLINE bool CheckForName(Handle<String> name,
|
||||
Handle<String> property_name,
|
||||
int offset,
|
||||
|
@ -13,9 +13,6 @@ namespace internal {
|
||||
|
||||
// The list of accessor descriptors. This is a second-order macro
|
||||
// taking a macro to be applied to all accessor descriptor names.
|
||||
#define ACCESSOR_DESCRIPTOR_LIST(V) \
|
||||
|
||||
|
||||
#define ACCESSOR_INFO_LIST(V) \
|
||||
V(ArrayLength) \
|
||||
V(FunctionArguments) \
|
||||
@ -42,11 +39,6 @@ namespace internal {
|
||||
class Accessors : public AllStatic {
|
||||
public:
|
||||
// Accessor descriptors.
|
||||
#define ACCESSOR_DESCRIPTOR_DECLARATION(name) \
|
||||
static const AccessorDescriptor name;
|
||||
ACCESSOR_DESCRIPTOR_LIST(ACCESSOR_DESCRIPTOR_DECLARATION)
|
||||
#undef ACCESSOR_DESCRIPTOR_DECLARATION
|
||||
|
||||
#define ACCESSOR_INFO_DECLARATION(name) \
|
||||
static void name##Getter( \
|
||||
v8::Local<v8::String> name, \
|
||||
@ -62,10 +54,6 @@ class Accessors : public AllStatic {
|
||||
#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,
|
||||
@ -91,27 +79,16 @@ class Accessors : public AllStatic {
|
||||
Handle<String> name,
|
||||
int* object_offset);
|
||||
|
||||
private:
|
||||
static Object* FunctionGetCaller(Isolate* isolate,
|
||||
Object* object,
|
||||
void*);
|
||||
static Object* ArraySetLength(Isolate* isolate,
|
||||
JSObject* object,
|
||||
Object*,
|
||||
void*);
|
||||
static Object* ArrayGetLength(Isolate* isolate, Object* object, void*);
|
||||
static Handle<AccessorInfo> MakeAccessor(
|
||||
Isolate* isolate,
|
||||
Handle<String> name,
|
||||
AccessorGetterCallback getter,
|
||||
AccessorSetterCallback setter,
|
||||
PropertyAttributes attributes);
|
||||
|
||||
private:
|
||||
// Helper functions.
|
||||
static Handle<Object> FlattenNumber(Isolate* isolate, Handle<Object> value);
|
||||
static Object* IllegalSetter(Isolate* isolate,
|
||||
JSObject*,
|
||||
Object*,
|
||||
void*);
|
||||
static Object* IllegalGetAccessor(Isolate* isolate, Object* object, void*);
|
||||
static Object* ReadOnlySetAccessor(Isolate* isolate,
|
||||
JSObject*,
|
||||
Object* value,
|
||||
void*);
|
||||
};
|
||||
|
||||
} } // namespace v8::internal
|
||||
|
19
src/ic.cc
19
src/ic.cc
@ -1008,9 +1008,7 @@ Handle<Code> LoadIC::CompileHandler(LookupResult* lookup,
|
||||
return compiler.CompileLoadViaGetter(type, holder, name, function);
|
||||
}
|
||||
// TODO(dcarney): Handle correctly.
|
||||
if (callback->IsDeclaredAccessorInfo()) break;
|
||||
ASSERT(callback->IsForeign());
|
||||
// No IC support for old-style native accessors.
|
||||
ASSERT(callback->IsDeclaredAccessorInfo());
|
||||
break;
|
||||
}
|
||||
case INTERCEPTOR:
|
||||
@ -1433,20 +1431,7 @@ Handle<Code> StoreIC::CompileHandler(LookupResult* lookup,
|
||||
receiver, holder, name, Handle<JSFunction>::cast(setter));
|
||||
}
|
||||
// TODO(dcarney): Handle correctly.
|
||||
if (callback->IsDeclaredAccessorInfo()) break;
|
||||
ASSERT(callback->IsForeign());
|
||||
|
||||
// Use specialized code for setting the length of arrays with fast
|
||||
// properties. Slow properties might indicate redefinition of the length
|
||||
// property.
|
||||
if (receiver->IsJSArray() &&
|
||||
String::Equals(isolate()->factory()->length_string(), name) &&
|
||||
Handle<JSArray>::cast(receiver)->AllowsSetElementsLength() &&
|
||||
receiver->HasFastProperties()) {
|
||||
return compiler.CompileStoreArrayLength(receiver, lookup, name);
|
||||
}
|
||||
|
||||
// No IC support for old-style native accessors.
|
||||
ASSERT(callback->IsDeclaredAccessorInfo());
|
||||
break;
|
||||
}
|
||||
case INTERCEPTOR:
|
||||
|
@ -365,18 +365,7 @@ MaybeHandle<Object> JSObject::GetPropertyWithCallback(Handle<JSObject> object,
|
||||
Handle<Object> structure,
|
||||
Handle<Name> name) {
|
||||
Isolate* isolate = name->GetIsolate();
|
||||
// To accommodate both the old and the new api we switch on the
|
||||
// data structure used to store the callbacks. Eventually foreign
|
||||
// callbacks should be phased out.
|
||||
if (structure->IsForeign()) {
|
||||
AccessorDescriptor* callback =
|
||||
reinterpret_cast<AccessorDescriptor*>(
|
||||
Handle<Foreign>::cast(structure)->foreign_address());
|
||||
CALL_HEAP_FUNCTION(isolate,
|
||||
(callback->getter)(isolate, *receiver, callback->data),
|
||||
Object);
|
||||
}
|
||||
|
||||
ASSERT(!structure->IsForeign());
|
||||
// api style callbacks.
|
||||
if (structure->IsAccessorInfo()) {
|
||||
Handle<AccessorInfo> accessor_info = Handle<AccessorInfo>::cast(structure);
|
||||
@ -3007,23 +2996,7 @@ MaybeHandle<Object> JSObject::SetPropertyWithCallback(Handle<JSObject> object,
|
||||
// We should never get here to initialize a const with the hole
|
||||
// value since a const declaration would conflict with the setter.
|
||||
ASSERT(!value->IsTheHole());
|
||||
|
||||
// To accommodate both the old and the new api we switch on the
|
||||
// data structure used to store the callbacks. Eventually foreign
|
||||
// callbacks should be phased out.
|
||||
if (structure->IsForeign()) {
|
||||
AccessorDescriptor* callback =
|
||||
reinterpret_cast<AccessorDescriptor*>(
|
||||
Handle<Foreign>::cast(structure)->foreign_address());
|
||||
CALL_AND_RETRY_OR_DIE(isolate,
|
||||
(callback->setter)(
|
||||
isolate, *object, *value, callback->data),
|
||||
break,
|
||||
return Handle<Object>());
|
||||
RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
|
||||
return value;
|
||||
}
|
||||
|
||||
ASSERT(!structure->IsForeign());
|
||||
if (structure->IsExecutableAccessorInfo()) {
|
||||
// api style callbacks
|
||||
ExecutableAccessorInfo* data = ExecutableAccessorInfo::cast(*structure);
|
||||
@ -12546,7 +12519,6 @@ MaybeHandle<Object> JSObject::GetElementWithCallback(
|
||||
Handle<Object> holder) {
|
||||
Isolate* isolate = object->GetIsolate();
|
||||
ASSERT(!structure->IsForeign());
|
||||
|
||||
// api style callbacks.
|
||||
if (structure->IsExecutableAccessorInfo()) {
|
||||
Handle<ExecutableAccessorInfo> data =
|
||||
@ -12604,12 +12576,7 @@ MaybeHandle<Object> JSObject::SetElementWithCallback(Handle<JSObject> object,
|
||||
// We should never get here to initialize a const with the hole
|
||||
// value since a const declaration would conflict with the setter.
|
||||
ASSERT(!value->IsTheHole());
|
||||
|
||||
// To accommodate both the old and the new api we switch on the
|
||||
// data structure used to store the callbacks. Eventually foreign
|
||||
// callbacks should be phased out.
|
||||
ASSERT(!structure->IsForeign());
|
||||
|
||||
if (structure->IsExecutableAccessorInfo()) {
|
||||
// api style callbacks
|
||||
Handle<ExecutableAccessorInfo> data =
|
||||
|
@ -345,7 +345,8 @@ class LookupResult V8_FINAL BASE_EMBEDDED {
|
||||
return true;
|
||||
case CALLBACKS: {
|
||||
Object* callback = GetCallbackObject();
|
||||
return callback->IsAccessorInfo() || callback->IsForeign();
|
||||
ASSERT(!callback->IsForeign());
|
||||
return callback->IsAccessorInfo();
|
||||
}
|
||||
case HANDLER:
|
||||
case INTERCEPTOR:
|
||||
|
@ -1873,6 +1873,7 @@ RUNTIME_FUNCTION(Runtime_IsInPrototypeChain) {
|
||||
static bool CheckAccessException(Object* callback,
|
||||
v8::AccessType access_type) {
|
||||
DisallowHeapAllocation no_gc;
|
||||
ASSERT(!callback->IsForeign());
|
||||
if (callback->IsAccessorInfo()) {
|
||||
AccessorInfo* info = AccessorInfo::cast(callback);
|
||||
return
|
||||
@ -5227,7 +5228,8 @@ RUNTIME_FUNCTION(Runtime_DefineOrRedefineDataProperty) {
|
||||
// setter to update the value instead.
|
||||
// TODO(mstarzinger): So far this only works if property attributes don't
|
||||
// change, this should be fixed once we cleanup the underlying code.
|
||||
if ((callback->IsForeign() || callback->IsAccessorInfo()) &&
|
||||
ASSERT(!callback->IsForeign());
|
||||
if (callback->IsAccessorInfo() &&
|
||||
lookup.GetAttributes() == attr) {
|
||||
Handle<Object> result_object;
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
|
||||
@ -10799,7 +10801,8 @@ static Handle<Object> DebugLookupResultValue(Isolate* isolate,
|
||||
return handle(result->GetConstant(), isolate);
|
||||
case CALLBACKS: {
|
||||
Handle<Object> structure(result->GetCallbackObject(), isolate);
|
||||
if (structure->IsForeign() || structure->IsAccessorInfo()) {
|
||||
ASSERT(!structure->IsForeign());
|
||||
if (structure->IsAccessorInfo()) {
|
||||
MaybeHandle<Object> obj = JSObject::GetPropertyWithCallback(
|
||||
handle(result->holder(), isolate), receiver, structure, name);
|
||||
if (!obj.ToHandle(&value)) {
|
||||
|
@ -246,14 +246,6 @@ void ExternalReferenceTable::PopulateTable(Isolate* isolate) {
|
||||
}
|
||||
|
||||
// Accessors
|
||||
#define ACCESSOR_DESCRIPTOR_DECLARATION(name) \
|
||||
Add((Address)&Accessors::name, \
|
||||
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, \
|
||||
|
@ -27,6 +27,7 @@
|
||||
|
||||
#include "v8.h"
|
||||
#include "accessors.h"
|
||||
#include "api.h"
|
||||
|
||||
#include "cctest.h"
|
||||
|
||||
@ -104,16 +105,29 @@ TEST(StressHandles) {
|
||||
}
|
||||
|
||||
|
||||
static Object* TestAccessorGet(Isolate* isolate, Object* object, void*) {
|
||||
return *Test();
|
||||
void TestGetter(
|
||||
v8::Local<v8::String> name,
|
||||
const v8::PropertyCallbackInfo<v8::Value>& info) {
|
||||
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
|
||||
HandleScope scope(isolate);
|
||||
info.GetReturnValue().Set(v8::Utils::ToLocal(Test()));
|
||||
}
|
||||
|
||||
|
||||
const AccessorDescriptor kDescriptor = {
|
||||
TestAccessorGet,
|
||||
0,
|
||||
0
|
||||
};
|
||||
void TestSetter(
|
||||
v8::Local<v8::String> name,
|
||||
v8::Local<v8::Value> value,
|
||||
const v8::PropertyCallbackInfo<void>& info) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
|
||||
Handle<AccessorInfo> TestAccessorInfo(
|
||||
Isolate* isolate, PropertyAttributes attributes) {
|
||||
Handle<String> name = isolate->factory()->NewStringFromStaticAscii("get");
|
||||
return Accessors::MakeAccessor(isolate, name, &TestGetter, &TestSetter,
|
||||
attributes);
|
||||
}
|
||||
|
||||
|
||||
TEST(StressJS) {
|
||||
@ -132,15 +146,14 @@ TEST(StressJS) {
|
||||
// Patch the map to have an accessor for "get".
|
||||
Handle<Map> map(function->initial_map());
|
||||
Handle<DescriptorArray> instance_descriptors(map->instance_descriptors());
|
||||
Handle<Foreign> foreign = factory->NewForeign(&kDescriptor);
|
||||
Handle<String> name = factory->NewStringFromStaticAscii("get");
|
||||
ASSERT(instance_descriptors->IsEmpty());
|
||||
|
||||
PropertyAttributes attrs = static_cast<PropertyAttributes>(0);
|
||||
Handle<AccessorInfo> foreign = TestAccessorInfo(isolate, attrs);
|
||||
Map::EnsureDescriptorSlack(map, 1);
|
||||
|
||||
CallbacksDescriptor d(name,
|
||||
foreign,
|
||||
static_cast<PropertyAttributes>(0));
|
||||
CallbacksDescriptor d(Handle<Name>(Name::cast(foreign->name())),
|
||||
foreign, attrs);
|
||||
map->AppendDescriptor(&d);
|
||||
|
||||
// Add the Foo constructor the global object.
|
||||
|
Loading…
Reference in New Issue
Block a user