📄 runtime.cc.svn-base
字号:
CONVERT_DOUBLE_CHECKED(f_number, args[1]); int f = FastD2I(f_number); RUNTIME_ASSERT(f >= -1 && f <= 20); char* str = DoubleToExponentialCString(value, f); Object* res = Heap::AllocateStringFromAscii(CStrVector(str)); DeleteArray(str); return res;}static Object* Runtime_NumberToPrecision(Arguments args) { NoHandleAllocation ha; ASSERT(args.length() == 2); CONVERT_DOUBLE_CHECKED(value, args[0]); if (isnan(value)) { return Heap::AllocateStringFromAscii(CStrVector("NaN")); } if (isinf(value)) { if (value < 0) { return Heap::AllocateStringFromAscii(CStrVector("-Infinity")); } return Heap::AllocateStringFromAscii(CStrVector("Infinity")); } CONVERT_DOUBLE_CHECKED(f_number, args[1]); int f = FastD2I(f_number); RUNTIME_ASSERT(f >= 1 && f <= 21); char* str = DoubleToPrecisionCString(value, f); Object* res = Heap::AllocateStringFromAscii(CStrVector(str)); DeleteArray(str); return res;}// Returns a single character string where first character equals// string->Get(index).static Handle<Object> GetCharAt(Handle<String> string, uint32_t index) { if (index < static_cast<uint32_t>(string->length())) { string->TryFlatten(); return LookupSingleCharacterStringFromCode(string->Get(index)); } return Execution::CharAt(string, index);}Object* Runtime::GetElementOrCharAt(Handle<Object> object, uint32_t index) { // Handle [] indexing on Strings if (object->IsString()) { Handle<Object> result = GetCharAt(Handle<String>::cast(object), index); if (!result->IsUndefined()) return *result; } // Handle [] indexing on String objects if (object->IsStringObjectWithCharacterAt(index)) { Handle<JSValue> js_value = Handle<JSValue>::cast(object); Handle<Object> result = GetCharAt(Handle<String>(String::cast(js_value->value())), index); if (!result->IsUndefined()) return *result; } if (object->IsString() || object->IsNumber() || object->IsBoolean()) { Handle<Object> prototype = GetPrototype(object); return prototype->GetElement(index); } return object->GetElement(index);}Object* Runtime::GetObjectProperty(Handle<Object> object, Handle<Object> key) { HandleScope scope; if (object->IsUndefined() || object->IsNull()) { Handle<Object> args[2] = { key, object }; Handle<Object> error = Factory::NewTypeError("non_object_property_load", HandleVector(args, 2)); return Top::Throw(*error); } // Check if the given key is an array index. uint32_t index; if (Array::IndexFromObject(*key, &index)) { return GetElementOrCharAt(object, index); } // Convert the key to a string - possibly by calling back into JavaScript. Handle<String> name; if (key->IsString()) { name = Handle<String>::cast(key); } else { bool has_pending_exception = false; Handle<Object> converted = Execution::ToString(key, &has_pending_exception); if (has_pending_exception) return Failure::Exception(); name = Handle<String>::cast(converted); } // Check if the name is trivially convertable to an index and get // the element if so. if (name->AsArrayIndex(&index)) { return GetElementOrCharAt(object, index); } else { PropertyAttributes attr; return object->GetProperty(*name, &attr); }}static Object* Runtime_GetProperty(Arguments args) { NoHandleAllocation ha; ASSERT(args.length() == 2); Handle<Object> object = args.at<Object>(0); Handle<Object> key = args.at<Object>(1); return Runtime::GetObjectProperty(object, key);}Object* Runtime::SetObjectProperty(Handle<Object> object, Handle<Object> key, Handle<Object> value, PropertyAttributes attr) { HandleScope scope; if (object->IsUndefined() || object->IsNull()) { Handle<Object> args[2] = { key, object }; Handle<Object> error = Factory::NewTypeError("non_object_property_store", HandleVector(args, 2)); return Top::Throw(*error); } // If the object isn't a JavaScript object, we ignore the store. if (!object->IsJSObject()) return *value; Handle<JSObject> js_object = Handle<JSObject>::cast(object); // Check if the given key is an array index. uint32_t index; if (Array::IndexFromObject(*key, &index)) { ASSERT(attr == NONE); // In Firefox/SpiderMonkey, Safari and Opera you can access the characters // of a string using [] notation. We need to support this too in // JavaScript. // In the case of a String object we just need to redirect the assignment to // the underlying string if the index is in range. Since the underlying // string does nothing with the assignment then we can ignore such // assignments. if (js_object->IsStringObjectWithCharacterAt(index)) { return *value; } Handle<Object> result = SetElement(js_object, index, value); if (result.is_null()) return Failure::Exception(); return *value; } if (key->IsString()) { Handle<Object> result; if (Handle<String>::cast(key)->AsArrayIndex(&index)) { ASSERT(attr == NONE); result = SetElement(js_object, index, value); } else { Handle<String> key_string = Handle<String>::cast(key); key_string->TryFlatten(); result = SetProperty(js_object, key_string, value, attr); } if (result.is_null()) return Failure::Exception(); return *value; } // Call-back into JavaScript to convert the key to a string. bool has_pending_exception = false; Handle<Object> converted = Execution::ToString(key, &has_pending_exception); if (has_pending_exception) return Failure::Exception(); Handle<String> name = Handle<String>::cast(converted); if (name->AsArrayIndex(&index)) { ASSERT(attr == NONE); return js_object->SetElement(index, *value); } else { return js_object->SetProperty(*name, *value, attr); }}static Object* Runtime_AddProperty(Arguments args) { NoHandleAllocation ha; ASSERT(args.length() == 4); CONVERT_CHECKED(JSObject, object, args[0]); CONVERT_CHECKED(String, name, args[1]); RUNTIME_ASSERT(!object->HasLocalProperty(name)); CONVERT_CHECKED(Smi, attr_obj, args[3]); int attr = attr_obj->value(); RUNTIME_ASSERT((attr & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); PropertyAttributes attributes = static_cast<PropertyAttributes>(attr); return object->AddProperty(name, args[2], attributes);}static Object* Runtime_SetProperty(Arguments args) { NoHandleAllocation ha; RUNTIME_ASSERT(args.length() == 3 || args.length() == 4); Handle<Object> object = args.at<Object>(0); Handle<Object> key = args.at<Object>(1); Handle<Object> value = args.at<Object>(2); // Compute attributes. PropertyAttributes attributes = NONE; if (args.length() == 4) { CONVERT_CHECKED(Smi, value_obj, args[3]); int value = value_obj->value(); // Only attribute bits should be set. ASSERT((value & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); attributes = static_cast<PropertyAttributes>(value); } return Runtime::SetObjectProperty(object, key, value, attributes);}// Set a local property, even if it is READ_ONLY. If the property does not// exist, it will be added with attributes NONE.static Object* Runtime_IgnoreAttributesAndSetProperty(Arguments args) { NoHandleAllocation ha; ASSERT(args.length() == 3); CONVERT_CHECKED(JSObject, object, args[0]); CONVERT_CHECKED(String, name, args[1]); return object->IgnoreAttributesAndSetLocalProperty(name, args[2]);}static Object* Runtime_DeleteProperty(Arguments args) { NoHandleAllocation ha; ASSERT(args.length() == 2); CONVERT_CHECKED(JSObject, object, args[0]); CONVERT_CHECKED(String, key, args[1]); return object->DeleteProperty(key);}static Object* Runtime_HasLocalProperty(Arguments args) { NoHandleAllocation ha; ASSERT(args.length() == 2); CONVERT_CHECKED(String, key, args[1]); // Only JS objects can have properties. if (args[0]->IsJSObject()) { JSObject* object = JSObject::cast(args[0]); if (object->HasLocalProperty(key)) return Heap::true_value(); } else if (args[0]->IsString()) { // Well, there is one exception: Handle [] on strings. uint32_t index; if (key->AsArrayIndex(&index)) { String* string = String::cast(args[0]); if (index < static_cast<uint32_t>(string->length())) return Heap::true_value(); } } return Heap::false_value();}static Object* Runtime_HasProperty(Arguments args) { NoHandleAllocation na; ASSERT(args.length() == 2); // Only JS objects can have properties. if (args[0]->IsJSObject()) { JSObject* object = JSObject::cast(args[0]); CONVERT_CHECKED(String, key, args[1]); if (object->HasProperty(key)) return Heap::true_value(); } return Heap::false_value();}static Object* Runtime_HasElement(Arguments args) { NoHandleAllocation na; ASSERT(args.length() == 2); // Only JS objects can have elements. if (args[0]->IsJSObject()) { JSObject* object = JSObject::cast(args[0]); CONVERT_CHECKED(Smi, index_obj, args[1]); uint32_t index = index_obj->value(); if (object->HasElement(index)) return Heap::true_value(); } return Heap::false_value();}static Object* Runtime_IsPropertyEnumerable(Arguments args) { NoHandleAllocation ha; ASSERT(args.length() == 2); CONVERT_CHECKED(JSObject, object, args[0]); CONVERT_CHECKED(String, key, args[1]); uint32_t index; if (key->AsArrayIndex(&index)) { return Heap::ToBoolean(object->HasElement(index)); } LookupResult result; object->LocalLookup(key, &result); if (!result.IsProperty()) return Heap::false_value(); return Heap::ToBoolean(!result.IsDontEnum());}static Object* Runtime_GetPropertyNames(Arguments args) { HandleScope scope; ASSERT(args.length() == 1); CONVERT_CHECKED(JSObject, raw_object, args[0]); Handle<JSObject> object(raw_object); return *GetKeysFor(object);}// Returns either a FixedArray as Runtime_GetPropertyNames,// or, if the given object has an enum cache that contains// all enumerable properties of the object and its prototypes// have none, the map of the object. This is used to speed up// the check for deletions during a for-in.static Object* Runtime_GetPropertyNamesFast(Arguments args) { ASSERT(args.length() == 1); CONVERT_CHECKED(JSObject, raw_object, args[0]); if (raw_object->IsSimpleEnum()) return raw_object->map(); HandleScope scope; Handle<JSObject> object(raw_object); Handle<FixedArray> content = GetKeysInFixedArrayFor(object); // Test again, since cache may have been built by preceding call. if (object->IsSimpleEnum()) return object->map(); return *content;}static Object* Runtime_GetArgumentsProperty(Arguments args) { NoHandleAllocation ha; ASSERT(args.length() == 1); // Compute the frame holding the arguments. JavaScriptFrameIterator it; it.AdvanceToArgumentsFrame(); JavaScriptFrame* frame = it.frame(); // Get the actual number of provided arguments. const uint32_t n = frame->GetProvidedParametersCount(); // Try to convert the key to an index. If successful and within // index return the the argument from the frame. uint32_t index; if (Array::IndexFromObject(args[0], &index) && index < n) { return frame->GetParameter(index); } // Convert the key to a string. HandleScope scope; bool exception = false; Handle<Object> converted = Execution::ToString(args.at<Object>(0), &exception); if (exception) return Failure::Exception(); Handle<String> key = Handle<String>::cast(converted); // Try to convert the string key into an array index. if (key->AsArrayIndex(&index)) { if (index < n) { return frame->GetParameter(index); } else { return Top::initial_object_prototype()->GetElement(index); } } // Handle special arguments properties. if (key->Equals(Heap::length_symbol())) return Smi::FromInt(n); if (key->Equals(Heap::callee_symbol())) return frame->function(); // Lookup in the initial Object.prototype object.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -