diff options
Diffstat (limited to 'Source/JavaScriptCore/runtime/StringObject.h')
-rw-r--r-- | Source/JavaScriptCore/runtime/StringObject.h | 138 |
1 files changed, 82 insertions, 56 deletions
diff --git a/Source/JavaScriptCore/runtime/StringObject.h b/Source/JavaScriptCore/runtime/StringObject.h index df6361474..60cb61fea 100644 --- a/Source/JavaScriptCore/runtime/StringObject.h +++ b/Source/JavaScriptCore/runtime/StringObject.h @@ -1,6 +1,6 @@ /* * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2007-2008, 2016 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,69 +18,95 @@ * */ -#ifndef StringObject_h -#define StringObject_h +#pragma once #include "JSWrapperObject.h" #include "JSString.h" namespace JSC { - class StringObject : public JSWrapperObject { - public: - typedef JSWrapperObject Base; - - static StringObject* create(VM& vm, Structure* structure) - { - JSString* string = jsEmptyString(&vm); - StringObject* object = new (NotNull, allocateCell<StringObject>(vm.heap)) StringObject(vm, structure); - object->finishCreation(vm, string); - return object; - } - static StringObject* create(VM& vm, Structure* structure, JSString* string) - { - StringObject* object = new (NotNull, allocateCell<StringObject>(vm.heap)) StringObject(vm, structure); - object->finishCreation(vm, string); - return object; - } - static StringObject* create(VM&, JSGlobalObject*, JSString*); - - static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&); - static bool getOwnPropertySlotByIndex(JSObject*, ExecState*, unsigned propertyName, PropertySlot&); - - static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&); - static void putByIndex(JSCell*, ExecState*, unsigned propertyName, JSValue, bool shouldThrow); - - static bool deleteProperty(JSCell*, ExecState*, PropertyName); - static bool deletePropertyByIndex(JSCell*, ExecState*, unsigned propertyName); - static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode); - static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool shouldThrow); - - DECLARE_EXPORT_INFO; - - JSString* internalValue() const { return asString(JSWrapperObject::internalValue());} - - static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) - { - return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info()); - } - - protected: - JS_EXPORT_PRIVATE void finishCreation(VM&, JSString*); - static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | OverridesGetPropertyNames | JSWrapperObject::StructureFlags; - JS_EXPORT_PRIVATE StringObject(VM&, Structure*); - }; - - StringObject* asStringObject(JSValue); - - inline StringObject* asStringObject(JSValue value) +class StringObject : public JSWrapperObject { +public: + typedef JSWrapperObject Base; + static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | OverridesGetPropertyNames; + + static StringObject* create(VM& vm, Structure* structure) + { + JSString* string = jsEmptyString(&vm); + StringObject* object = new (NotNull, allocateCell<StringObject>(vm.heap)) StringObject(vm, structure); + object->finishCreation(vm, string); + return object; + } + static StringObject* create(VM& vm, Structure* structure, JSString* string) { - ASSERT(asObject(value)->inherits(StringObject::info())); - return static_cast<StringObject*>(asObject(value)); + StringObject* object = new (NotNull, allocateCell<StringObject>(vm.heap)) StringObject(vm, structure); + object->finishCreation(vm, string); + return object; } + static StringObject* create(VM&, JSGlobalObject*, JSString*); - JS_EXPORT_PRIVATE StringObject* constructString(VM&, JSGlobalObject*, JSValue); + JS_EXPORT_PRIVATE static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&); + JS_EXPORT_PRIVATE static bool getOwnPropertySlotByIndex(JSObject*, ExecState*, unsigned propertyName, PropertySlot&); -} // namespace JSC + JS_EXPORT_PRIVATE static bool put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&); + JS_EXPORT_PRIVATE static bool putByIndex(JSCell*, ExecState*, unsigned propertyName, JSValue, bool shouldThrow); + + JS_EXPORT_PRIVATE static bool deleteProperty(JSCell*, ExecState*, PropertyName); + JS_EXPORT_PRIVATE static bool deletePropertyByIndex(JSCell*, ExecState*, unsigned propertyName); + JS_EXPORT_PRIVATE static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode); + JS_EXPORT_PRIVATE static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool shouldThrow); + + DECLARE_EXPORT_INFO; + + JSString* internalValue() const { return asString(JSWrapperObject::internalValue());} -#endif // StringObject_h + static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) + { + return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info()); + } + +protected: + JS_EXPORT_PRIVATE void finishCreation(VM&, JSString*); + JS_EXPORT_PRIVATE StringObject(VM&, Structure*); +}; + +StringObject* asStringObject(JSValue); + +inline StringObject* asStringObject(JSValue value) +{ + ASSERT(asObject(value)->inherits(*value.getObject()->vm(), StringObject::info())); + return static_cast<StringObject*>(asObject(value)); +} + +JS_EXPORT_PRIVATE StringObject* constructString(VM&, JSGlobalObject*, JSValue); + +// Helper for producing a JSString for 'string', where 'string' was been produced by +// calling ToString on 'originalValue'. In cases where 'originalValue' already was a +// string primitive we can just use this, otherwise we need to allocate a new JSString. +// FIXME: Basically any use of this is bad. toString() returns a JSString* so we don't need to +// pass around the originalValue; we could just pass around the JSString*. Then you don't need +// this function. You just use the JSString* that toString() returned. +static inline JSString* jsStringWithReuse(ExecState* exec, JSValue originalValue, const String& string) +{ + if (originalValue.isString()) { + ASSERT(asString(originalValue)->value(exec) == string); + return asString(originalValue); + } + return jsString(exec, string); +} + +// Helper that tries to use the JSString substring sharing mechanism if 'originalValue' is a JSString. +// FIXME: Basically any use of this is bad. toString() returns a JSString* so we don't need to +// pass around the originalValue; we could just pass around the JSString*. And since we've +// resolved it, we know that we can just allocate the substring cell directly. +// https://bugs.webkit.org/show_bug.cgi?id=158140 +static inline JSString* jsSubstring(ExecState* exec, JSValue originalValue, const String& string, unsigned offset, unsigned length) +{ + if (originalValue.isString()) { + ASSERT(asString(originalValue)->value(exec) == string); + return jsSubstring(exec, asString(originalValue), offset, length); + } + return jsSubstring(exec, string, offset, length); +} + +} // namespace JSC |