Make the GC aware of JSReceiver pointers in LookupResults.
The LookupResult utility class is used in handlified code, but it can contain a raw pointer to the lookup's holder object. Create a per-thread stack of live LookupResults and iterate all the live ones on GC. R=vegorov@chromium.org,erik.corry@gmail.com BUG= TEST= Review URL: http://codereview.chromium.org/8341009 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@9676 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
96a2c24a16
commit
56c763f023
@ -3110,7 +3110,7 @@ Local<Value> v8::Object::GetRealNamedPropertyInPrototypeChain(
|
||||
ENTER_V8(isolate);
|
||||
i::Handle<i::JSObject> self_obj = Utils::OpenHandle(this);
|
||||
i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
|
||||
i::LookupResult lookup;
|
||||
i::LookupResult lookup(isolate);
|
||||
self_obj->LookupRealNamedPropertyInPrototypes(*key_obj, &lookup);
|
||||
return GetPropertyByLookup(isolate, self_obj, key_obj, &lookup);
|
||||
}
|
||||
@ -3123,7 +3123,7 @@ Local<Value> v8::Object::GetRealNamedProperty(Handle<String> key) {
|
||||
ENTER_V8(isolate);
|
||||
i::Handle<i::JSObject> self_obj = Utils::OpenHandle(this);
|
||||
i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
|
||||
i::LookupResult lookup;
|
||||
i::LookupResult lookup(isolate);
|
||||
self_obj->LookupRealNamedProperty(*key_obj, &lookup);
|
||||
return GetPropertyByLookup(isolate, self_obj, key_obj, &lookup);
|
||||
}
|
||||
|
@ -2320,7 +2320,7 @@ void LCodeGen::EmitLoadFieldOrConstantFunction(Register result,
|
||||
Register object,
|
||||
Handle<Map> type,
|
||||
Handle<String> name) {
|
||||
LookupResult lookup;
|
||||
LookupResult lookup(isolate());
|
||||
type->LookupInDescriptors(NULL, *name, &lookup);
|
||||
ASSERT(lookup.IsProperty() &&
|
||||
(lookup.type() == FIELD || lookup.type() == CONSTANT_FUNCTION));
|
||||
|
@ -2504,7 +2504,7 @@ MaybeObject* CallStubCompiler::CompileCallInterceptor(JSObject* object,
|
||||
// Get the number of arguments.
|
||||
const int argc = arguments().immediate();
|
||||
|
||||
LookupResult lookup;
|
||||
LookupResult lookup(isolate());
|
||||
LookupPostInterceptor(holder, name, &lookup);
|
||||
|
||||
// Get the receiver from the stack.
|
||||
@ -2908,7 +2908,7 @@ MaybeObject* LoadStubCompiler::CompileLoadInterceptor(JSObject* object,
|
||||
// -----------------------------------
|
||||
Label miss;
|
||||
|
||||
LookupResult lookup;
|
||||
LookupResult lookup(isolate());
|
||||
LookupPostInterceptor(holder, name, &lookup);
|
||||
GenerateLoadInterceptor(object,
|
||||
holder,
|
||||
@ -3066,7 +3066,7 @@ MaybeObject* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver,
|
||||
__ cmp(r0, Operand(Handle<String>(name)));
|
||||
__ b(ne, &miss);
|
||||
|
||||
LookupResult lookup;
|
||||
LookupResult lookup(isolate());
|
||||
LookupPostInterceptor(holder, name, &lookup);
|
||||
GenerateLoadInterceptor(receiver,
|
||||
holder,
|
||||
|
@ -720,7 +720,7 @@ bool Call::ComputeTarget(Handle<Map> type, Handle<String> name) {
|
||||
holder_ = Handle<JSObject>::null();
|
||||
}
|
||||
while (true) {
|
||||
LookupResult lookup;
|
||||
LookupResult lookup(type->GetIsolate());
|
||||
type->LookupInDescriptors(NULL, *name, &lookup);
|
||||
// If the function wasn't found directly in the map, we start
|
||||
// looking upwards through the prototype chain.
|
||||
|
@ -1065,7 +1065,7 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
|
||||
DONT_ENUM);
|
||||
|
||||
#ifdef DEBUG
|
||||
LookupResult lookup;
|
||||
LookupResult lookup(isolate);
|
||||
result->LocalLookup(heap->callee_symbol(), &lookup);
|
||||
ASSERT(lookup.IsProperty() && (lookup.type() == FIELD));
|
||||
ASSERT(lookup.GetFieldIndex() == Heap::kArgumentsCalleeIndex);
|
||||
@ -1162,7 +1162,7 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
|
||||
DONT_ENUM);
|
||||
|
||||
#ifdef DEBUG
|
||||
LookupResult lookup;
|
||||
LookupResult lookup(isolate);
|
||||
result->LocalLookup(heap->length_symbol(), &lookup);
|
||||
ASSERT(lookup.IsProperty() && (lookup.type() == FIELD));
|
||||
ASSERT(lookup.GetFieldIndex() == Heap::kArgumentsLengthIndex);
|
||||
@ -2088,7 +2088,7 @@ void Genesis::TransferNamedProperties(Handle<JSObject> from,
|
||||
break;
|
||||
}
|
||||
case CALLBACKS: {
|
||||
LookupResult result;
|
||||
LookupResult result(isolate());
|
||||
to->LocalLookup(descs->GetKey(i), &result);
|
||||
// If the property is already there we skip it
|
||||
if (result.IsProperty()) continue;
|
||||
@ -2126,7 +2126,7 @@ void Genesis::TransferNamedProperties(Handle<JSObject> from,
|
||||
if (properties->IsKey(raw_key)) {
|
||||
ASSERT(raw_key->IsString());
|
||||
// If the property is already there we skip it.
|
||||
LookupResult result;
|
||||
LookupResult result(isolate());
|
||||
to->LocalLookup(String::cast(raw_key), &result);
|
||||
if (result.IsProperty()) continue;
|
||||
// Set the property.
|
||||
|
@ -1390,7 +1390,7 @@ HLoadNamedFieldPolymorphic::HLoadNamedFieldPolymorphic(HValue* context,
|
||||
i < types->length() && types_.length() < kMaxLoadPolymorphism;
|
||||
++i) {
|
||||
Handle<Map> map = types->at(i);
|
||||
LookupResult lookup;
|
||||
LookupResult lookup(map->GetIsolate());
|
||||
map->LookupInDescriptors(NULL, *name, &lookup);
|
||||
if (lookup.IsProperty()) {
|
||||
switch (lookup.type()) {
|
||||
|
@ -3156,7 +3156,7 @@ void HGraphBuilder::VisitVariableProxy(VariableProxy* expr) {
|
||||
return ast_context()->ReturnInstruction(instr, expr->id());
|
||||
}
|
||||
|
||||
LookupResult lookup;
|
||||
LookupResult lookup(isolate());
|
||||
GlobalPropertyAccess type =
|
||||
LookupGlobalProperty(variable, &lookup, false);
|
||||
|
||||
@ -3471,7 +3471,7 @@ HInstruction* HGraphBuilder::BuildStoreNamed(HValue* object,
|
||||
Handle<String> name = Handle<String>::cast(key->handle());
|
||||
ASSERT(!name.is_null());
|
||||
|
||||
LookupResult lookup;
|
||||
LookupResult lookup(isolate());
|
||||
SmallMapList* types = expr->GetReceiverTypes();
|
||||
bool is_monomorphic = expr->IsMonomorphic() &&
|
||||
ComputeStoredField(types->first(), name, &lookup);
|
||||
@ -3495,7 +3495,7 @@ void HGraphBuilder::HandlePolymorphicStoreNamedField(Assignment* expr,
|
||||
HBasicBlock* join = NULL;
|
||||
for (int i = 0; i < types->length() && count < kMaxStorePolymorphism; ++i) {
|
||||
Handle<Map> map = types->at(i);
|
||||
LookupResult lookup;
|
||||
LookupResult lookup(isolate());
|
||||
if (ComputeStoredField(map, name, &lookup)) {
|
||||
if (count == 0) {
|
||||
AddInstruction(new(zone()) HCheckNonSmi(object)); // Only needed once.
|
||||
@ -3578,7 +3578,7 @@ void HGraphBuilder::HandlePropertyAssignment(Assignment* expr) {
|
||||
ASSERT(!name.is_null());
|
||||
|
||||
SmallMapList* types = expr->GetReceiverTypes();
|
||||
LookupResult lookup;
|
||||
LookupResult lookup(isolate());
|
||||
|
||||
if (expr->IsMonomorphic()) {
|
||||
instr = BuildStoreNamed(object, value, expr);
|
||||
@ -3623,7 +3623,7 @@ void HGraphBuilder::HandleGlobalVariableAssignment(Variable* var,
|
||||
HValue* value,
|
||||
int position,
|
||||
int ast_id) {
|
||||
LookupResult lookup;
|
||||
LookupResult lookup(isolate());
|
||||
GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, true);
|
||||
if (type == kUseCell) {
|
||||
Handle<GlobalObject> global(info()->global_object());
|
||||
@ -3938,7 +3938,7 @@ HInstruction* HGraphBuilder::BuildLoadNamed(HValue* obj,
|
||||
Property* expr,
|
||||
Handle<Map> map,
|
||||
Handle<String> name) {
|
||||
LookupResult lookup;
|
||||
LookupResult lookup(isolate());
|
||||
map->LookupInDescriptors(NULL, *name, &lookup);
|
||||
if (lookup.IsProperty() && lookup.type() == FIELD) {
|
||||
return BuildLoadNamedField(obj,
|
||||
@ -5012,7 +5012,7 @@ void HGraphBuilder::VisitCall(Call* expr) {
|
||||
// If there is a global property cell for the name at compile time and
|
||||
// access check is not enabled we assume that the function will not change
|
||||
// and generate optimized code for calling the function.
|
||||
LookupResult lookup;
|
||||
LookupResult lookup(isolate());
|
||||
GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, false);
|
||||
if (type == kUseCell &&
|
||||
!info()->global_object()->IsAccessCheckNeeded()) {
|
||||
@ -5869,7 +5869,7 @@ void HGraphBuilder::VisitCompareOperation(CompareOperation* expr) {
|
||||
!info()->global_object()->IsAccessCheckNeeded()) {
|
||||
Handle<String> name = proxy->name();
|
||||
Handle<GlobalObject> global(info()->global_object());
|
||||
LookupResult lookup;
|
||||
LookupResult lookup(isolate());
|
||||
global->Lookup(*name, &lookup);
|
||||
if (lookup.IsProperty() &&
|
||||
lookup.type() == NORMAL &&
|
||||
|
@ -2185,7 +2185,7 @@ void LCodeGen::EmitLoadFieldOrConstantFunction(Register result,
|
||||
Register object,
|
||||
Handle<Map> type,
|
||||
Handle<String> name) {
|
||||
LookupResult lookup;
|
||||
LookupResult lookup(isolate());
|
||||
type->LookupInDescriptors(NULL, *name, &lookup);
|
||||
ASSERT(lookup.IsProperty() &&
|
||||
(lookup.type() == FIELD || lookup.type() == CONSTANT_FUNCTION));
|
||||
|
@ -2372,7 +2372,7 @@ MaybeObject* CallStubCompiler::CompileCallInterceptor(JSObject* object,
|
||||
// Get the number of arguments.
|
||||
const int argc = arguments().immediate();
|
||||
|
||||
LookupResult lookup;
|
||||
LookupResult lookup(isolate());
|
||||
LookupPostInterceptor(holder, name, &lookup);
|
||||
|
||||
// Get the receiver from the stack.
|
||||
@ -2914,7 +2914,7 @@ MaybeObject* LoadStubCompiler::CompileLoadInterceptor(JSObject* receiver,
|
||||
// -----------------------------------
|
||||
Label miss;
|
||||
|
||||
LookupResult lookup;
|
||||
LookupResult lookup(isolate());
|
||||
LookupPostInterceptor(holder, name, &lookup);
|
||||
|
||||
// TODO(368): Compile in the whole chain: all the interceptors in
|
||||
@ -3102,7 +3102,7 @@ MaybeObject* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver,
|
||||
__ cmp(eax, Immediate(Handle<String>(name)));
|
||||
__ j(not_equal, &miss);
|
||||
|
||||
LookupResult lookup;
|
||||
LookupResult lookup(isolate());
|
||||
LookupPostInterceptor(holder, name, &lookup);
|
||||
GenerateLoadInterceptor(receiver,
|
||||
holder,
|
||||
|
10
src/ic.cc
10
src/ic.cc
@ -483,7 +483,7 @@ MaybeObject* CallICBase::LoadFunction(State state,
|
||||
}
|
||||
|
||||
// Lookup the property in the object.
|
||||
LookupResult lookup;
|
||||
LookupResult lookup(isolate());
|
||||
LookupForRead(*object, *name, &lookup);
|
||||
|
||||
if (!lookup.IsProperty()) {
|
||||
@ -935,7 +935,7 @@ MaybeObject* LoadIC::Load(State state,
|
||||
if (name->AsArrayIndex(&index)) return object->GetElement(index);
|
||||
|
||||
// Named lookup in the object.
|
||||
LookupResult lookup;
|
||||
LookupResult lookup(isolate());
|
||||
LookupForRead(*object, *name, &lookup);
|
||||
|
||||
// If we did not find a property, check if we need to throw an exception.
|
||||
@ -1203,7 +1203,7 @@ MaybeObject* KeyedLoadIC::Load(State state,
|
||||
}
|
||||
|
||||
// Named lookup.
|
||||
LookupResult lookup;
|
||||
LookupResult lookup(isolate());
|
||||
LookupForRead(*object, *name, &lookup);
|
||||
|
||||
// If we did not find a property, check if we need to throw an exception.
|
||||
@ -1435,7 +1435,7 @@ MaybeObject* StoreIC::Store(State state,
|
||||
|
||||
// Lookup the property locally in the receiver.
|
||||
if (FLAG_use_ic && !receiver->IsJSGlobalProxy()) {
|
||||
LookupResult lookup;
|
||||
LookupResult lookup(isolate());
|
||||
|
||||
if (LookupForWrite(*receiver, *name, &lookup)) {
|
||||
// Generate a stub for this store.
|
||||
@ -1849,7 +1849,7 @@ MaybeObject* KeyedStoreIC::Store(State state,
|
||||
}
|
||||
|
||||
// Lookup the property locally in the receiver.
|
||||
LookupResult lookup;
|
||||
LookupResult lookup(isolate());
|
||||
receiver->LocalLookup(*name, &lookup);
|
||||
|
||||
// Update inline cache and stub cache.
|
||||
|
@ -98,6 +98,7 @@ void ThreadLocalTop::InitializeInternal() {
|
||||
failed_access_check_callback_ = NULL;
|
||||
save_context_ = NULL;
|
||||
catcher_ = NULL;
|
||||
top_lookup_result_ = NULL;
|
||||
|
||||
// These members are re-initialized later after deserialization
|
||||
// is complete.
|
||||
@ -480,6 +481,9 @@ void Isolate::Iterate(ObjectVisitor* v, ThreadLocalTop* thread) {
|
||||
for (StackFrameIterator it(this, thread); !it.done(); it.Advance()) {
|
||||
it.frame()->Iterate(v);
|
||||
}
|
||||
|
||||
// Iterate pointers in live lookup results.
|
||||
thread->top_lookup_result_->Iterate(v);
|
||||
}
|
||||
|
||||
|
||||
|
@ -255,6 +255,9 @@ class ThreadLocalTop BASE_EMBEDDED {
|
||||
// Call back function to report unsafe JS accesses.
|
||||
v8::FailedAccessCheckCallback failed_access_check_callback_;
|
||||
|
||||
// Head of the list of live LookupResults.
|
||||
LookupResult* top_lookup_result_;
|
||||
|
||||
// Whether out of memory exceptions should be ignored.
|
||||
bool ignore_out_of_memory_;
|
||||
|
||||
@ -995,6 +998,13 @@ class Isolate {
|
||||
void SetData(void* data) { embedder_data_ = data; }
|
||||
void* GetData() { return embedder_data_; }
|
||||
|
||||
LookupResult* top_lookup_result() {
|
||||
return thread_local_top_.top_lookup_result_;
|
||||
}
|
||||
void SetTopLookupResult(LookupResult* top) {
|
||||
thread_local_top_.top_lookup_result_ = top;
|
||||
}
|
||||
|
||||
private:
|
||||
Isolate();
|
||||
|
||||
|
@ -2515,7 +2515,7 @@ MaybeObject* CallStubCompiler::CompileCallInterceptor(JSObject* object,
|
||||
// Get the number of arguments.
|
||||
const int argc = arguments().immediate();
|
||||
|
||||
LookupResult lookup;
|
||||
LookupResult lookup(isolate());
|
||||
LookupPostInterceptor(holder, name, &lookup);
|
||||
|
||||
// Get the receiver from the stack.
|
||||
@ -2919,7 +2919,7 @@ MaybeObject* LoadStubCompiler::CompileLoadInterceptor(JSObject* object,
|
||||
// -----------------------------------
|
||||
Label miss;
|
||||
|
||||
LookupResult lookup;
|
||||
LookupResult lookup(isolate());
|
||||
LookupPostInterceptor(holder, name, &lookup);
|
||||
GenerateLoadInterceptor(object,
|
||||
holder,
|
||||
@ -3073,7 +3073,7 @@ MaybeObject* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver,
|
||||
// Check the key is the cached one.
|
||||
__ Branch(&miss, ne, a0, Operand(Handle<String>(name)));
|
||||
|
||||
LookupResult lookup;
|
||||
LookupResult lookup(isolate());
|
||||
LookupPostInterceptor(holder, name, &lookup);
|
||||
GenerateLoadInterceptor(receiver,
|
||||
holder,
|
||||
|
@ -154,7 +154,7 @@ void Object::Lookup(String* name, LookupResult* result) {
|
||||
MaybeObject* Object::GetPropertyWithReceiver(Object* receiver,
|
||||
String* name,
|
||||
PropertyAttributes* attributes) {
|
||||
LookupResult result;
|
||||
LookupResult result(name->GetIsolate());
|
||||
Lookup(name, &result);
|
||||
MaybeObject* value = GetProperty(receiver, &result, name, attributes);
|
||||
ASSERT(*attributes <= ABSENT);
|
||||
@ -310,7 +310,7 @@ MaybeObject* JSObject::GetPropertyWithFailedAccessCheck(
|
||||
case FIELD:
|
||||
case CONSTANT_FUNCTION: {
|
||||
// Search ALL_CAN_READ accessors in prototype chain.
|
||||
LookupResult r;
|
||||
LookupResult r(GetIsolate());
|
||||
result->holder()->LookupRealNamedPropertyInPrototypes(name, &r);
|
||||
if (r.IsProperty()) {
|
||||
return GetPropertyWithFailedAccessCheck(receiver,
|
||||
@ -323,7 +323,7 @@ MaybeObject* JSObject::GetPropertyWithFailedAccessCheck(
|
||||
case INTERCEPTOR: {
|
||||
// If the object has an interceptor, try real named properties.
|
||||
// No access check in GetPropertyAttributeWithInterceptor.
|
||||
LookupResult r;
|
||||
LookupResult r(GetIsolate());
|
||||
result->holder()->LookupRealNamedProperty(name, &r);
|
||||
if (r.IsProperty()) {
|
||||
return GetPropertyWithFailedAccessCheck(receiver,
|
||||
@ -370,7 +370,7 @@ PropertyAttributes JSObject::GetPropertyAttributeWithFailedAccessCheck(
|
||||
case CONSTANT_FUNCTION: {
|
||||
if (!continue_search) break;
|
||||
// Search ALL_CAN_READ accessors in prototype chain.
|
||||
LookupResult r;
|
||||
LookupResult r(GetIsolate());
|
||||
result->holder()->LookupRealNamedPropertyInPrototypes(name, &r);
|
||||
if (r.IsProperty()) {
|
||||
return GetPropertyAttributeWithFailedAccessCheck(receiver,
|
||||
@ -384,7 +384,7 @@ PropertyAttributes JSObject::GetPropertyAttributeWithFailedAccessCheck(
|
||||
case INTERCEPTOR: {
|
||||
// If the object has an interceptor, try real named properties.
|
||||
// No access check in GetPropertyAttributeWithInterceptor.
|
||||
LookupResult r;
|
||||
LookupResult r(GetIsolate());
|
||||
if (continue_search) {
|
||||
result->holder()->LookupRealNamedProperty(name, &r);
|
||||
} else {
|
||||
@ -404,7 +404,7 @@ PropertyAttributes JSObject::GetPropertyAttributeWithFailedAccessCheck(
|
||||
}
|
||||
}
|
||||
|
||||
GetHeap()->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS);
|
||||
GetIsolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS);
|
||||
return ABSENT;
|
||||
}
|
||||
|
||||
@ -1658,7 +1658,7 @@ MaybeObject* JSObject::SetPropertyPostInterceptor(
|
||||
PropertyAttributes attributes,
|
||||
StrictModeFlag strict_mode) {
|
||||
// Check local property, ignore interceptor.
|
||||
LookupResult result;
|
||||
LookupResult result(GetIsolate());
|
||||
LocalLookupRealNamedProperty(name, &result);
|
||||
if (result.IsFound()) {
|
||||
// An existing property, a map transition or a null descriptor was
|
||||
@ -1840,7 +1840,7 @@ MaybeObject* JSReceiver::SetProperty(String* name,
|
||||
Object* value,
|
||||
PropertyAttributes attributes,
|
||||
StrictModeFlag strict_mode) {
|
||||
LookupResult result;
|
||||
LookupResult result(GetIsolate());
|
||||
LocalLookup(name, &result);
|
||||
return SetProperty(&result, name, value, attributes, strict_mode);
|
||||
}
|
||||
@ -2006,9 +2006,9 @@ MaybeObject* JSObject::SetPropertyWithCallbackSetterInPrototypes(
|
||||
PropertyAttributes attributes,
|
||||
bool* found,
|
||||
StrictModeFlag strict_mode) {
|
||||
LookupResult result;
|
||||
LookupCallbackSetterInPrototypes(name, &result);
|
||||
Heap* heap = GetHeap();
|
||||
LookupResult result(heap->isolate());
|
||||
LookupCallbackSetterInPrototypes(name, &result);
|
||||
if (result.IsFound()) {
|
||||
*found = true;
|
||||
if (result.type() == CALLBACKS) {
|
||||
@ -2020,7 +2020,7 @@ MaybeObject* JSObject::SetPropertyWithCallbackSetterInPrototypes(
|
||||
} else if (result.type() == HANDLER) {
|
||||
// We could not find a local property so let's check whether there is an
|
||||
// accessor that wants to handle the property.
|
||||
LookupResult accessor_result;
|
||||
LookupResult accessor_result(heap->isolate());
|
||||
LookupCallbackSetterInPrototypes(name, &accessor_result);
|
||||
if (accessor_result.IsFound()) {
|
||||
if (accessor_result.type() == CALLBACKS) {
|
||||
@ -2423,7 +2423,7 @@ MaybeObject* JSObject::SetPropertyWithFailedAccessCheck(
|
||||
case INTERCEPTOR: {
|
||||
// Try lookup real named properties. Note that only property can be
|
||||
// set is callbacks marked as ALL_CAN_WRITE on the prototype chain.
|
||||
LookupResult r;
|
||||
LookupResult r(GetIsolate());
|
||||
LookupRealNamedProperty(name, &r);
|
||||
if (r.IsProperty()) {
|
||||
return SetPropertyWithFailedAccessCheck(&r,
|
||||
@ -2441,10 +2441,10 @@ MaybeObject* JSObject::SetPropertyWithFailedAccessCheck(
|
||||
}
|
||||
}
|
||||
|
||||
Heap* heap = GetHeap();
|
||||
HandleScope scope(heap->isolate());
|
||||
Isolate* isolate = GetIsolate();
|
||||
HandleScope scope(isolate);
|
||||
Handle<Object> value_handle(value);
|
||||
heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_SET);
|
||||
isolate->ReportFailedAccessCheck(this, v8::ACCESS_SET);
|
||||
return *value_handle;
|
||||
}
|
||||
|
||||
@ -2865,12 +2865,12 @@ MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes(
|
||||
// Make sure that the top context does not change when doing callbacks or
|
||||
// interceptor calls.
|
||||
AssertNoContextChange ncc;
|
||||
LookupResult result;
|
||||
Isolate* isolate = GetIsolate();
|
||||
LookupResult result(isolate);
|
||||
LocalLookup(name, &result);
|
||||
// Check access rights if needed.
|
||||
if (IsAccessCheckNeeded()) {
|
||||
Heap* heap = GetHeap();
|
||||
if (!heap->isolate()->MayNamedAccess(this, name, v8::ACCESS_SET)) {
|
||||
if (!isolate->MayNamedAccess(this, name, v8::ACCESS_SET)) {
|
||||
return SetPropertyWithFailedAccessCheck(&result,
|
||||
name,
|
||||
value,
|
||||
@ -2941,7 +2941,7 @@ PropertyAttributes JSObject::GetPropertyAttributePostInterceptor(
|
||||
String* name,
|
||||
bool continue_search) {
|
||||
// Check local property, ignore interceptor.
|
||||
LookupResult result;
|
||||
LookupResult result(GetIsolate());
|
||||
LocalLookupRealNamedProperty(name, &result);
|
||||
if (result.IsProperty()) return result.GetAttributes();
|
||||
|
||||
@ -3017,7 +3017,7 @@ PropertyAttributes JSReceiver::GetPropertyAttributeWithReceiver(
|
||||
? NONE : ABSENT;
|
||||
}
|
||||
// Named property.
|
||||
LookupResult result;
|
||||
LookupResult result(GetIsolate());
|
||||
Lookup(key, &result);
|
||||
return GetPropertyAttribute(receiver, &result, key, true);
|
||||
}
|
||||
@ -3066,7 +3066,7 @@ PropertyAttributes JSReceiver::GetLocalPropertyAttribute(String* name) {
|
||||
return ABSENT;
|
||||
}
|
||||
// Named property.
|
||||
LookupResult result;
|
||||
LookupResult result(GetIsolate());
|
||||
LocalLookup(name, &result);
|
||||
return GetPropertyAttribute(this, &result, name, false);
|
||||
}
|
||||
@ -3573,7 +3573,7 @@ MaybeObject* JSObject::SetHiddenPropertiesDictionary(
|
||||
MaybeObject* JSObject::DeletePropertyPostInterceptor(String* name,
|
||||
DeleteMode mode) {
|
||||
// Check local property, ignore interceptor.
|
||||
LookupResult result;
|
||||
LookupResult result(GetIsolate());
|
||||
LocalLookupRealNamedProperty(name, &result);
|
||||
if (!result.IsProperty()) return GetHeap()->true_value();
|
||||
|
||||
@ -3722,7 +3722,7 @@ MaybeObject* JSObject::DeleteProperty(String* name, DeleteMode mode) {
|
||||
if (name->AsArrayIndex(&index)) {
|
||||
return DeleteElement(index, mode);
|
||||
} else {
|
||||
LookupResult result;
|
||||
LookupResult result(isolate);
|
||||
LocalLookup(name, &result);
|
||||
if (!result.IsProperty()) return isolate->heap()->true_value();
|
||||
// Ignore attributes if forcing a deletion.
|
||||
@ -4152,7 +4152,7 @@ MaybeObject* JSObject::DefineGetterSetter(String* name,
|
||||
}
|
||||
} else {
|
||||
// Lookup the name.
|
||||
LookupResult result;
|
||||
LookupResult result(heap->isolate());
|
||||
LocalLookup(name, &result);
|
||||
if (result.IsProperty()) {
|
||||
if (result.IsReadOnly()) return heap->undefined_value();
|
||||
@ -4182,8 +4182,8 @@ MaybeObject* JSObject::DefineGetterSetter(String* name,
|
||||
|
||||
|
||||
bool JSObject::CanSetCallback(String* name) {
|
||||
ASSERT(!IsAccessCheckNeeded()
|
||||
|| Isolate::Current()->MayNamedAccess(this, name, v8::ACCESS_SET));
|
||||
ASSERT(!IsAccessCheckNeeded() ||
|
||||
GetIsolate()->MayNamedAccess(this, name, v8::ACCESS_SET));
|
||||
|
||||
// Check if there is an API defined callback object which prohibits
|
||||
// callback overwriting in this object or it's prototype chain.
|
||||
@ -4191,7 +4191,7 @@ bool JSObject::CanSetCallback(String* name) {
|
||||
// certain accessors such as window.location should not be allowed
|
||||
// to be overwritten because allowing overwriting could potentially
|
||||
// cause security problems.
|
||||
LookupResult callback_result;
|
||||
LookupResult callback_result(GetIsolate());
|
||||
LookupCallback(name, &callback_result);
|
||||
if (callback_result.IsProperty()) {
|
||||
Object* obj = callback_result.GetCallbackObject();
|
||||
@ -4388,7 +4388,7 @@ MaybeObject* JSObject::DefineAccessor(AccessorInfo* info) {
|
||||
}
|
||||
} else {
|
||||
// Lookup the name.
|
||||
LookupResult result;
|
||||
LookupResult result(isolate);
|
||||
LocalLookup(name, &result);
|
||||
// ES5 forbids turning a property into an accessor if it's not
|
||||
// configurable (that is IsDontDelete in ES3 and v8), see 8.6.1 (Table 5).
|
||||
@ -4446,7 +4446,7 @@ Object* JSObject::LookupAccessor(String* name, bool is_getter) {
|
||||
for (Object* obj = this;
|
||||
obj != heap->null_value();
|
||||
obj = JSObject::cast(obj)->GetPrototype()) {
|
||||
LookupResult result;
|
||||
LookupResult result(heap->isolate());
|
||||
JSObject::cast(obj)->LocalLookup(name, &result);
|
||||
if (result.IsProperty()) {
|
||||
if (result.IsReadOnly()) return heap->undefined_value();
|
||||
@ -7088,7 +7088,7 @@ bool SharedFunctionInfo::CanGenerateInlineConstructor(Object* prototype) {
|
||||
obj = obj->GetPrototype()) {
|
||||
JSObject* js_object = JSObject::cast(obj);
|
||||
for (int i = 0; i < this_property_assignments_count(); i++) {
|
||||
LookupResult result;
|
||||
LookupResult result(heap->isolate());
|
||||
String* name = GetThisPropertyAssignmentName(i);
|
||||
js_object->LocalLookupRealNamedProperty(name, &result);
|
||||
if (result.IsProperty() && result.type() == CALLBACKS) {
|
||||
@ -9634,7 +9634,7 @@ MaybeObject* JSObject::GetPropertyPostInterceptor(
|
||||
String* name,
|
||||
PropertyAttributes* attributes) {
|
||||
// Check local property in holder, ignore interceptor.
|
||||
LookupResult result;
|
||||
LookupResult result(GetIsolate());
|
||||
LocalLookupRealNamedProperty(name, &result);
|
||||
if (result.IsProperty()) {
|
||||
return GetProperty(receiver, &result, name, attributes);
|
||||
@ -9652,7 +9652,7 @@ MaybeObject* JSObject::GetLocalPropertyPostInterceptor(
|
||||
String* name,
|
||||
PropertyAttributes* attributes) {
|
||||
// Check local property in holder, ignore interceptor.
|
||||
LookupResult result;
|
||||
LookupResult result(GetIsolate());
|
||||
LocalLookupRealNamedProperty(name, &result);
|
||||
if (result.IsProperty()) {
|
||||
return GetProperty(receiver, &result, name, attributes);
|
||||
@ -9703,15 +9703,15 @@ MaybeObject* JSObject::GetPropertyWithInterceptor(
|
||||
|
||||
bool JSObject::HasRealNamedProperty(String* key) {
|
||||
// Check access rights if needed.
|
||||
Isolate* isolate = GetIsolate();
|
||||
if (IsAccessCheckNeeded()) {
|
||||
Heap* heap = GetHeap();
|
||||
if (!heap->isolate()->MayNamedAccess(this, key, v8::ACCESS_HAS)) {
|
||||
heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS);
|
||||
if (!isolate->MayNamedAccess(this, key, v8::ACCESS_HAS)) {
|
||||
isolate->ReportFailedAccessCheck(this, v8::ACCESS_HAS);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
LookupResult result;
|
||||
LookupResult result(isolate);
|
||||
LocalLookupRealNamedProperty(key, &result);
|
||||
return result.IsProperty() && (result.type() != INTERCEPTOR);
|
||||
}
|
||||
@ -9780,15 +9780,15 @@ bool JSObject::HasRealElementProperty(uint32_t index) {
|
||||
|
||||
bool JSObject::HasRealNamedCallbackProperty(String* key) {
|
||||
// Check access rights if needed.
|
||||
Isolate* isolate = GetIsolate();
|
||||
if (IsAccessCheckNeeded()) {
|
||||
Heap* heap = GetHeap();
|
||||
if (!heap->isolate()->MayNamedAccess(this, key, v8::ACCESS_HAS)) {
|
||||
heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS);
|
||||
if (!isolate->MayNamedAccess(this, key, v8::ACCESS_HAS)) {
|
||||
isolate->ReportFailedAccessCheck(this, v8::ACCESS_HAS);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
LookupResult result;
|
||||
LookupResult result(isolate);
|
||||
LocalLookupRealNamedProperty(key, &result);
|
||||
return result.IsProperty() && (result.type() == CALLBACKS);
|
||||
}
|
||||
|
@ -2166,15 +2166,16 @@ void V8HeapExplorer::ExtractInternalReferences(JSObject* js_obj,
|
||||
|
||||
|
||||
String* V8HeapExplorer::GetConstructorName(JSObject* object) {
|
||||
if (object->IsJSFunction()) return HEAP->closure_symbol();
|
||||
Heap* heap = object->GetHeap();
|
||||
if (object->IsJSFunction()) return heap->closure_symbol();
|
||||
String* constructor_name = object->constructor_name();
|
||||
if (constructor_name == HEAP->Object_symbol()) {
|
||||
if (constructor_name == heap->Object_symbol()) {
|
||||
// Look up an immediate "constructor" property, if it is a function,
|
||||
// return its name. This is for instances of binding objects, which
|
||||
// have prototype constructor type "Object".
|
||||
Object* constructor_prop = NULL;
|
||||
LookupResult result;
|
||||
object->LocalLookupRealNamedProperty(HEAP->constructor_symbol(), &result);
|
||||
LookupResult result(heap->isolate());
|
||||
object->LocalLookupRealNamedProperty(heap->constructor_symbol(), &result);
|
||||
if (result.IsProperty()) {
|
||||
constructor_prop = result.GetLazyValue();
|
||||
}
|
||||
|
@ -31,6 +31,15 @@ namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
|
||||
void LookupResult::Iterate(ObjectVisitor* visitor) {
|
||||
LookupResult* current = this; // Could be NULL.
|
||||
while (current != NULL) {
|
||||
visitor->VisitPointer(BitCast<Object**>(¤t->holder_));
|
||||
current = current->next_;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef OBJECT_PRINT
|
||||
void LookupResult::Print(FILE* out) {
|
||||
if (!IsFound()) {
|
||||
|
@ -164,10 +164,20 @@ class CallbacksDescriptor: public Descriptor {
|
||||
|
||||
class LookupResult BASE_EMBEDDED {
|
||||
public:
|
||||
LookupResult()
|
||||
: lookup_type_(NOT_FOUND),
|
||||
explicit LookupResult(Isolate* isolate)
|
||||
: isolate_(isolate),
|
||||
next_(isolate->top_lookup_result()),
|
||||
lookup_type_(NOT_FOUND),
|
||||
holder_(NULL),
|
||||
cacheable_(true),
|
||||
details_(NONE, NORMAL) {}
|
||||
details_(NONE, NORMAL) {
|
||||
isolate->SetTopLookupResult(this);
|
||||
}
|
||||
|
||||
~LookupResult() {
|
||||
ASSERT(isolate_->top_lookup_result() == this);
|
||||
isolate_->SetTopLookupResult(next_);
|
||||
}
|
||||
|
||||
void DescriptorResult(JSObject* holder, PropertyDetails details, int number) {
|
||||
lookup_type_ = DESCRIPTOR_TYPE;
|
||||
@ -215,6 +225,7 @@ class LookupResult BASE_EMBEDDED {
|
||||
|
||||
void NotFound() {
|
||||
lookup_type_ = NOT_FOUND;
|
||||
holder_ = NULL;
|
||||
}
|
||||
|
||||
JSObject* holder() {
|
||||
@ -346,7 +357,12 @@ class LookupResult BASE_EMBEDDED {
|
||||
return holder()->GetNormalizedProperty(this);
|
||||
}
|
||||
|
||||
void Iterate(ObjectVisitor* visitor);
|
||||
|
||||
private:
|
||||
Isolate* isolate_;
|
||||
LookupResult* next_;
|
||||
|
||||
// Where did we find the result;
|
||||
enum {
|
||||
NOT_FOUND,
|
||||
|
@ -961,7 +961,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOwnProperty) {
|
||||
HandleScope scope(isolate);
|
||||
Handle<FixedArray> elms = isolate->factory()->NewFixedArray(DESCRIPTOR_SIZE);
|
||||
Handle<JSArray> desc = isolate->factory()->NewJSArrayWithElements(elms);
|
||||
LookupResult result;
|
||||
LookupResult result(isolate);
|
||||
CONVERT_ARG_CHECKED(JSObject, obj, 0);
|
||||
CONVERT_ARG_CHECKED(String, name, 1);
|
||||
|
||||
@ -1240,7 +1240,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareGlobals) {
|
||||
if (value->IsUndefined() || is_const_property) {
|
||||
// Lookup the property in the global object, and don't set the
|
||||
// value of the variable if the property is already there.
|
||||
LookupResult lookup;
|
||||
LookupResult lookup(isolate);
|
||||
global->Lookup(*name, &lookup);
|
||||
if (lookup.IsProperty()) {
|
||||
// We found an existing property. Unless it was an interceptor
|
||||
@ -1267,7 +1267,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareGlobals) {
|
||||
value = function;
|
||||
}
|
||||
|
||||
LookupResult lookup;
|
||||
LookupResult lookup(isolate);
|
||||
global->LocalLookup(*name, &lookup);
|
||||
|
||||
// Compute the property attributes. According to ECMA-262, section
|
||||
@ -1399,7 +1399,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareContextSlot) {
|
||||
// not real JSObjects.
|
||||
if (initial_value->IsTheHole() &&
|
||||
!object->IsJSContextExtensionObject()) {
|
||||
LookupResult lookup;
|
||||
LookupResult lookup(isolate);
|
||||
object->Lookup(*name, &lookup);
|
||||
if (lookup.IsProperty() && (lookup.type() == CALLBACKS)) {
|
||||
return ThrowRedeclarationError(isolate, "const", name);
|
||||
@ -1443,7 +1443,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) {
|
||||
// Note that objects can have hidden prototypes, so we need to traverse
|
||||
// the whole chain of hidden prototypes to do a 'local' lookup.
|
||||
Object* object = global;
|
||||
LookupResult lookup;
|
||||
LookupResult lookup(isolate);
|
||||
while (object->IsJSObject() &&
|
||||
JSObject::cast(object)->map()->is_hidden_prototype()) {
|
||||
JSObject* raw_holder = JSObject::cast(object);
|
||||
@ -1497,7 +1497,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeConstGlobal) {
|
||||
// add it as a local property even in case of callbacks in the
|
||||
// prototype chain (this rules out using SetProperty).
|
||||
// We use SetLocalPropertyIgnoreAttributes instead
|
||||
LookupResult lookup;
|
||||
LookupResult lookup(isolate);
|
||||
global->LocalLookup(*name, &lookup);
|
||||
if (!lookup.IsProperty()) {
|
||||
return global->SetLocalPropertyIgnoreAttributes(*name,
|
||||
@ -1614,7 +1614,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeConstContextSlot) {
|
||||
// This is the property that was introduced by the const declaration.
|
||||
// Set it if it hasn't been set before. NOTE: We cannot use
|
||||
// GetProperty() to get the current value as it 'unholes' the value.
|
||||
LookupResult lookup;
|
||||
LookupResult lookup(isolate);
|
||||
object->LocalLookupRealNamedProperty(*name, &lookup);
|
||||
ASSERT(lookup.IsProperty()); // the property was declared
|
||||
ASSERT(lookup.IsReadOnly()); // and it was declared as read-only
|
||||
@ -4135,7 +4135,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_KeyedGetProperty) {
|
||||
return value->IsTheHole() ? isolate->heap()->undefined_value() : value;
|
||||
}
|
||||
// Lookup cache miss. Perform lookup and update the cache if appropriate.
|
||||
LookupResult result;
|
||||
LookupResult result(isolate);
|
||||
receiver->LocalLookup(key, &result);
|
||||
if (result.IsProperty() && result.type() == FIELD) {
|
||||
int offset = result.GetFieldIndex();
|
||||
@ -4190,7 +4190,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DefineOrRedefineAccessorProperty) {
|
||||
int unchecked = flag_attr->value();
|
||||
RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
|
||||
RUNTIME_ASSERT(!obj->IsNull());
|
||||
LookupResult result;
|
||||
LookupResult result(isolate);
|
||||
obj->LocalLookupRealNamedProperty(name, &result);
|
||||
|
||||
PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked);
|
||||
@ -4274,7 +4274,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DefineOrRedefineDataProperty) {
|
||||
return *obj_value;
|
||||
}
|
||||
|
||||
LookupResult result;
|
||||
LookupResult result(isolate);
|
||||
js_object->LocalLookupRealNamedProperty(*name, &result);
|
||||
|
||||
// To be compatible with safari we do not change the value on API objects
|
||||
@ -10361,7 +10361,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetPropertyDetails) {
|
||||
// Try local lookup on each of the objects.
|
||||
Handle<JSObject> jsproto = obj;
|
||||
for (int i = 0; i < length; i++) {
|
||||
LookupResult result;
|
||||
LookupResult result(isolate);
|
||||
jsproto->LocalLookup(*name, &result);
|
||||
if (result.IsProperty()) {
|
||||
// LookupResult is not GC safe as it holds raw object pointers.
|
||||
@ -10418,7 +10418,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetProperty) {
|
||||
CONVERT_ARG_CHECKED(JSObject, obj, 0);
|
||||
CONVERT_ARG_CHECKED(String, name, 1);
|
||||
|
||||
LookupResult result;
|
||||
LookupResult result(isolate);
|
||||
obj->Lookup(*name, &result);
|
||||
if (result.IsProperty()) {
|
||||
return DebugLookupResultValue(isolate->heap(), *obj, *name, &result, NULL);
|
||||
|
@ -2129,7 +2129,7 @@ void LCodeGen::EmitLoadFieldOrConstantFunction(Register result,
|
||||
Register object,
|
||||
Handle<Map> type,
|
||||
Handle<String> name) {
|
||||
LookupResult lookup;
|
||||
LookupResult lookup(isolate());
|
||||
type->LookupInDescriptors(NULL, *name, &lookup);
|
||||
ASSERT(lookup.IsProperty() &&
|
||||
(lookup.type() == FIELD || lookup.type() == CONSTANT_FUNCTION));
|
||||
|
@ -2221,7 +2221,7 @@ MaybeObject* CallStubCompiler::CompileCallInterceptor(JSObject* object,
|
||||
// Get the number of arguments.
|
||||
const int argc = arguments().immediate();
|
||||
|
||||
LookupResult lookup;
|
||||
LookupResult lookup(isolate());
|
||||
LookupPostInterceptor(holder, name, &lookup);
|
||||
|
||||
// Get the receiver from the stack.
|
||||
@ -2765,7 +2765,7 @@ MaybeObject* LoadStubCompiler::CompileLoadInterceptor(JSObject* receiver,
|
||||
// -----------------------------------
|
||||
Label miss;
|
||||
|
||||
LookupResult lookup;
|
||||
LookupResult lookup(isolate());
|
||||
LookupPostInterceptor(holder, name, &lookup);
|
||||
|
||||
// TODO(368): Compile in the whole chain: all the interceptors in
|
||||
@ -2949,7 +2949,7 @@ MaybeObject* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver,
|
||||
__ Cmp(rax, Handle<String>(name));
|
||||
__ j(not_equal, &miss);
|
||||
|
||||
LookupResult lookup;
|
||||
LookupResult lookup(isolate());
|
||||
LookupPostInterceptor(holder, name, &lookup);
|
||||
GenerateLoadInterceptor(receiver,
|
||||
holder,
|
||||
|
Loading…
Reference in New Issue
Block a user