⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 objects.cc.svn-base

📁 Google浏览器V8内核代码
💻 SVN-BASE
📖 第 1 页 / 共 5 页
字号:
// Copyright 2006-2008 the V8 project authors. All rights reserved.// Redistribution and use in source and binary forms, with or without// modification, are permitted provided that the following conditions are// met:////     * Redistributions of source code must retain the above copyright//       notice, this list of conditions and the following disclaimer.//     * Redistributions in binary form must reproduce the above//       copyright notice, this list of conditions and the following//       disclaimer in the documentation and/or other materials provided//       with the distribution.//     * Neither the name of Google Inc. nor the names of its//       contributors may be used to endorse or promote products derived//       from this software without specific prior written permission.//// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#include "v8.h"#include "api.h"#include "bootstrapper.h"#include "debug.h"#include "execution.h"#include "objects-inl.h"#include "macro-assembler.h"#include "scanner.h"#include "scopeinfo.h"#include "string-stream.h"#ifdef ENABLE_DISASSEMBLER#include "disassembler.h"#endifnamespace v8 { namespace internal {// Getters and setters are stored in a fixed array property.  These are// constants for their indices.const int kGetterIndex = 0;const int kSetterIndex = 1;bool Object::IsInstanceOf(FunctionTemplateInfo* expected) {  // There is a constraint on the object; check  if (!this->IsJSObject()) return false;  // Fetch the constructor function of the object  Object* cons_obj = JSObject::cast(this)->map()->constructor();  if (!cons_obj->IsJSFunction()) return false;  JSFunction* fun = JSFunction::cast(cons_obj);  // Iterate through the chain of inheriting function templates to  // see if the required one occurs.  for (Object* type = fun->shared()->function_data();       type->IsFunctionTemplateInfo();       type = FunctionTemplateInfo::cast(type)->parent_template()) {    if (type == expected) return true;  }  // Didn't find the required type in the inheritance chain.  return false;}static Object* CreateJSValue(JSFunction* constructor, Object* value) {  Object* result = Heap::AllocateJSObject(constructor);  if (result->IsFailure()) return result;  JSValue::cast(result)->set_value(value);  return result;}Object* Object::ToObject(Context* global_context) {  if (IsNumber()) {    return CreateJSValue(global_context->number_function(), this);  } else if (IsBoolean()) {    return CreateJSValue(global_context->boolean_function(), this);  } else if (IsString()) {    return CreateJSValue(global_context->string_function(), this);  }  ASSERT(IsJSObject());  return this;}Object* Object::ToObject() {  Context* global_context = Top::context()->global_context();  if (IsJSObject()) {    return this;  } else if (IsNumber()) {    return CreateJSValue(global_context->number_function(), this);  } else if (IsBoolean()) {    return CreateJSValue(global_context->boolean_function(), this);  } else if (IsString()) {    return CreateJSValue(global_context->string_function(), this);  }  // Throw a type error.  return Failure::InternalError();}Object* Object::ToBoolean() {  if (IsTrue()) return Heap::true_value();  if (IsFalse()) return Heap::false_value();  if (IsSmi()) {    return Heap::ToBoolean(Smi::cast(this)->value() != 0);  }  if (IsUndefined() || IsNull()) return Heap::false_value();  // Undetectable object is false  if (IsUndetectableObject()) {    return Heap::false_value();  }  if (IsString()) {    return Heap::ToBoolean(String::cast(this)->length() != 0);  }  if (IsHeapNumber()) {    return HeapNumber::cast(this)->HeapNumberToBoolean();  }  return Heap::true_value();}void Object::Lookup(String* name, LookupResult* result) {  if (IsJSObject()) return JSObject::cast(this)->Lookup(name, result);  Object* holder = NULL;  Context* global_context = Top::context()->global_context();  if (IsString()) {    holder = global_context->string_function()->instance_prototype();  } else if (IsNumber()) {    holder = global_context->number_function()->instance_prototype();  } else if (IsBoolean()) {    holder = global_context->boolean_function()->instance_prototype();  }#ifdef DEBUG  // Used to track outstanding bug #1308895.  // TODO(1308895) Remove when bug is fixed.  if (holder == NULL) {    PrintF("\nName being looked up: ");    name->Print();    PrintF("\nThis (object name is looked up in: ");    this->Print();    if (IsScript()) {      PrintF("IsScript() returns true.\n");    }  }#endif  ASSERT(holder != NULL);  // cannot handle null or undefined.  JSObject::cast(holder)->Lookup(name, result);}Object* Object::GetPropertyWithReceiver(Object* receiver,                                        String* name,                                        PropertyAttributes* attributes) {  LookupResult result;  Lookup(name, &result);  return GetProperty(receiver, &result, name, attributes);}Object* Object::GetPropertyWithCallback(Object* receiver,                                        Object* structure,                                        String* name,                                        Object* holder) {  // To accommodate both the old and the new api we switch on the  // data structure used to store the callbacks.  Eventually proxy  // callbacks should be phased out.  if (structure->IsProxy()) {    AccessorDescriptor* callback =        reinterpret_cast<AccessorDescriptor*>(Proxy::cast(structure)->proxy());    Object* value = (callback->getter)(receiver, callback->data);    RETURN_IF_SCHEDULED_EXCEPTION();    return value;  }  // api style callbacks.  if (structure->IsAccessorInfo()) {    AccessorInfo* data = AccessorInfo::cast(structure);    Object* fun_obj = data->getter();    v8::AccessorGetter call_fun = v8::ToCData<v8::AccessorGetter>(fun_obj);    HandleScope scope;    Handle<JSObject> self(JSObject::cast(receiver));    Handle<JSObject> holder_handle(JSObject::cast(holder));    Handle<String> key(name);    Handle<Object> fun_data(data->data());    LOG(ApiNamedPropertyAccess("load", *self, name));    v8::AccessorInfo info(v8::Utils::ToLocal(self),                          v8::Utils::ToLocal(fun_data),                          v8::Utils::ToLocal(holder_handle));    v8::Handle<v8::Value> result;    {      // Leaving JavaScript.      VMState state(OTHER);      result = call_fun(v8::Utils::ToLocal(key), info);    }    RETURN_IF_SCHEDULED_EXCEPTION();    if (result.IsEmpty()) return Heap::undefined_value();    return *v8::Utils::OpenHandle(*result);  }  // __defineGetter__ callback  if (structure->IsFixedArray()) {    Object* getter = FixedArray::cast(structure)->get(kGetterIndex);    if (getter->IsJSFunction()) {      HandleScope scope;      Handle<JSFunction> fun(JSFunction::cast(getter));      Handle<Object> self(receiver);      bool has_pending_exception;      Object* result =          *Execution::Call(fun, self, 0, NULL, &has_pending_exception);      // Check for pending exception and return the result.      if (has_pending_exception) return Failure::Exception();      return result;    }    // Getter is not a function.    return Heap::undefined_value();  }  UNREACHABLE();  return 0;}// Only deal with CALLBACKS and INTERCEPTORObject* JSObject::GetPropertyWithFailedAccessCheck(Object* receiver,                                                   LookupResult* result,                                                   String* name) {  if (result->IsValid()) {    switch (result->type()) {      case CALLBACKS: {        // Only allow API accessors.        Object* obj = result->GetCallbackObject();        if (obj->IsAccessorInfo()) {          AccessorInfo* info = AccessorInfo::cast(obj);          if (info->all_can_read()) {            return GetPropertyWithCallback(receiver,                                           result->GetCallbackObject(),                                           name,                                           result->holder());          }        }        break;      }      case NORMAL:      case FIELD:      case CONSTANT_FUNCTION: {        // Search ALL_CAN_READ accessors in prototype chain.        LookupResult r;        result->holder()->LookupRealNamedPropertyInPrototypes(name, &r);        if (r.IsValid()) {          return GetPropertyWithFailedAccessCheck(receiver, &r, name);        }        break;      }      case INTERCEPTOR: {        // If the object has an interceptor, try real named properties.        // No access check in GetPropertyAttributeWithInterceptor.        LookupResult r;        result->holder()->LookupRealNamedProperty(name, &r);        if (r.IsValid()) {          return GetPropertyWithFailedAccessCheck(receiver, &r, name);        }        break;      }      default: {        break;      }    }  }  Top::ReportFailedAccessCheck(this, v8::ACCESS_GET);  return Heap::undefined_value();}Object* JSObject::GetLazyProperty(Object* receiver,                                  LookupResult* result,                                  String* name,                                  PropertyAttributes* attributes) {  HandleScope scope;  Handle<Object> this_handle(this);  Handle<Object> receiver_handle(receiver);  Handle<String> name_handle(name);  bool pending_exception;  LoadLazy(Handle<JSFunction>(JSFunction::cast(result->GetValue())),           &pending_exception);  if (pending_exception) return Failure::Exception();  return this_handle->GetPropertyWithReceiver(*receiver_handle,                                              *name_handle,                                              attributes);}Object* JSObject::SetLazyProperty(LookupResult* result,                                  String* name,                                  Object* value,                                  PropertyAttributes attributes) {  HandleScope scope;  Handle<JSObject> this_handle(this);  Handle<String> name_handle(name);  Handle<Object> value_handle(value);  bool pending_exception;  LoadLazy(Handle<JSFunction>(JSFunction::cast(result->GetValue())),           &pending_exception);  if (pending_exception) return Failure::Exception();  return this_handle->SetProperty(*name_handle, *value_handle, attributes);}Object* JSObject::DeleteLazyProperty(LookupResult* result, String* name) {  HandleScope scope;  Handle<JSObject> this_handle(this);  Handle<String> name_handle(name);  bool pending_exception;  LoadLazy(Handle<JSFunction>(JSFunction::cast(result->GetValue())),           &pending_exception);  if (pending_exception) return Failure::Exception();  return this_handle->DeleteProperty(*name_handle);}Object* Object::GetProperty(Object* receiver,                            LookupResult* result,                            String* name,                            PropertyAttributes* attributes) {  // Make sure that the top context does not change when doing  // callbacks or interceptor calls.  AssertNoContextChange ncc;  // Traverse the prototype chain from the current object (this) to  // the holder and check for access rights. This avoid traversing the  // objects more than once in case of interceptors, because the  // holder will always be the interceptor holder and the search may  // only continue with a current object just after the interceptor  // holder in the prototype chain.  Object* last = result->IsValid() ? result->holder() : Heap::null_value();  for (Object* current = this; true; current = current->GetPrototype()) {    if (current->IsAccessCheckNeeded()) {      // Check if we're allowed to read from the current object. Note      // that even though we may not actually end up loading the named      // property from the current object, we still check that we have      // access to the it.      JSObject* checked = JSObject::cast(current);      if (!Top::MayNamedAccess(checked, name, v8::ACCESS_GET)) {        return checked->GetPropertyWithFailedAccessCheck(receiver,                                                         result,                                                         name);      }    }    // Stop traversing the chain once we reach the last object in the    // chain; either the holder of the result or null in case of an    // absent property.    if (current == last) break;  }  if (!result->IsProperty()) {    *attributes = ABSENT;    return Heap::undefined_value();  }  *attributes = result->GetAttributes();  if (!result->IsLoaded()) {    return JSObject::cast(this)->GetLazyProperty(receiver,                                                 result,                                                 name,                                                 attributes);  }  Object* value;  JSObject* holder = result->holder();  switch (result->type()) {    case NORMAL:      value =          holder->property_dictionary()->ValueAt(result->GetDictionaryEntry());      ASSERT(!value->IsTheHole() || result->IsReadOnly());      return value->IsTheHole() ? Heap::undefined_value() : value;    case FIELD:      value = holder->properties()->get(result->GetFieldIndex());

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -