summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/runtime
diff options
context:
space:
mode:
Diffstat (limited to 'Source/JavaScriptCore/runtime')
-rw-r--r--Source/JavaScriptCore/runtime/ArgList.h4
-rw-r--r--Source/JavaScriptCore/runtime/Arguments.cpp4
-rw-r--r--Source/JavaScriptCore/runtime/ArrayPrototype.cpp20
-rw-r--r--Source/JavaScriptCore/runtime/CallData.h2
-rw-r--r--Source/JavaScriptCore/runtime/ClassInfo.h4
-rw-r--r--Source/JavaScriptCore/runtime/CommonSlowPaths.h2
-rw-r--r--Source/JavaScriptCore/runtime/Completion.cpp3
-rw-r--r--Source/JavaScriptCore/runtime/Completion.h4
-rw-r--r--Source/JavaScriptCore/runtime/ConstructData.h2
-rw-r--r--Source/JavaScriptCore/runtime/DateConstructor.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/DateInstance.h4
-rw-r--r--Source/JavaScriptCore/runtime/DatePrototype.cpp36
-rw-r--r--Source/JavaScriptCore/runtime/Error.cpp9
-rw-r--r--Source/JavaScriptCore/runtime/Error.h18
-rw-r--r--Source/JavaScriptCore/runtime/ErrorInstance.h8
-rw-r--r--Source/JavaScriptCore/runtime/ErrorPrototype.cpp4
-rw-r--r--Source/JavaScriptCore/runtime/ExceptionHelpers.cpp8
-rw-r--r--Source/JavaScriptCore/runtime/ExceptionHelpers.h8
-rw-r--r--Source/JavaScriptCore/runtime/Executable.cpp104
-rw-r--r--Source/JavaScriptCore/runtime/Executable.h16
-rw-r--r--Source/JavaScriptCore/runtime/FunctionConstructor.cpp8
-rw-r--r--Source/JavaScriptCore/runtime/FunctionConstructor.h2
-rw-r--r--Source/JavaScriptCore/runtime/FunctionPrototype.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/GetterSetter.h4
-rw-r--r--Source/JavaScriptCore/runtime/Identifier.h16
-rw-r--r--Source/JavaScriptCore/runtime/InitializeThreading.h2
-rw-r--r--Source/JavaScriptCore/runtime/InternalFunction.h6
-rw-r--r--Source/JavaScriptCore/runtime/JSActivation.cpp8
-rw-r--r--Source/JavaScriptCore/runtime/JSActivation.h2
-rw-r--r--Source/JavaScriptCore/runtime/JSArray.cpp297
-rw-r--r--Source/JavaScriptCore/runtime/JSArray.h39
-rw-r--r--Source/JavaScriptCore/runtime/JSBoundFunction.cpp4
-rw-r--r--Source/JavaScriptCore/runtime/JSBoundFunction.h2
-rw-r--r--Source/JavaScriptCore/runtime/JSByteArray.h18
-rw-r--r--Source/JavaScriptCore/runtime/JSCell.cpp9
-rw-r--r--Source/JavaScriptCore/runtime/JSCell.h22
-rw-r--r--Source/JavaScriptCore/runtime/JSFunction.cpp35
-rw-r--r--Source/JavaScriptCore/runtime/JSFunction.h16
-rw-r--r--Source/JavaScriptCore/runtime/JSGlobalData.cpp4
-rw-r--r--Source/JavaScriptCore/runtime/JSGlobalData.h34
-rw-r--r--Source/JavaScriptCore/runtime/JSGlobalObject.cpp4
-rw-r--r--Source/JavaScriptCore/runtime/JSGlobalObject.h28
-rw-r--r--Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp15
-rw-r--r--Source/JavaScriptCore/runtime/JSGlobalThis.h2
-rw-r--r--Source/JavaScriptCore/runtime/JSLock.h16
-rw-r--r--Source/JavaScriptCore/runtime/JSONObject.cpp22
-rw-r--r--Source/JavaScriptCore/runtime/JSObject.cpp153
-rw-r--r--Source/JavaScriptCore/runtime/JSObject.h140
-rw-r--r--Source/JavaScriptCore/runtime/JSStaticScopeObject.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/JSStaticScopeObject.h2
-rw-r--r--Source/JavaScriptCore/runtime/JSString.cpp5
-rw-r--r--Source/JavaScriptCore/runtime/JSString.h26
-rw-r--r--Source/JavaScriptCore/runtime/JSValue.cpp14
-rw-r--r--Source/JavaScriptCore/runtime/JSValue.h19
-rw-r--r--Source/JavaScriptCore/runtime/JSValueInlineMethods.h1
-rw-r--r--Source/JavaScriptCore/runtime/JSVariableObject.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/JSVariableObject.h10
-rw-r--r--Source/JavaScriptCore/runtime/Lookup.h6
-rw-r--r--Source/JavaScriptCore/runtime/MemoryStatistics.h2
-rw-r--r--Source/JavaScriptCore/runtime/NumberPrototype.cpp4
-rw-r--r--Source/JavaScriptCore/runtime/ObjectConstructor.cpp19
-rw-r--r--Source/JavaScriptCore/runtime/ObjectPrototype.cpp12
-rw-r--r--Source/JavaScriptCore/runtime/ObjectPrototype.h2
-rw-r--r--Source/JavaScriptCore/runtime/Operations.cpp10
-rw-r--r--Source/JavaScriptCore/runtime/Operations.h23
-rw-r--r--Source/JavaScriptCore/runtime/Options.cpp15
-rw-r--r--Source/JavaScriptCore/runtime/Options.h4
-rw-r--r--Source/JavaScriptCore/runtime/PropertyDescriptor.cpp50
-rw-r--r--Source/JavaScriptCore/runtime/PropertyDescriptor.h32
-rw-r--r--Source/JavaScriptCore/runtime/PropertyNameArray.h2
-rw-r--r--Source/JavaScriptCore/runtime/PropertySlot.h2
-rw-r--r--Source/JavaScriptCore/runtime/RegExp.cpp72
-rw-r--r--Source/JavaScriptCore/runtime/RegExp.h8
-rw-r--r--Source/JavaScriptCore/runtime/RegExpConstructor.cpp86
-rw-r--r--Source/JavaScriptCore/runtime/RegExpConstructor.h33
-rw-r--r--Source/JavaScriptCore/runtime/RegExpMatchesArray.h30
-rw-r--r--Source/JavaScriptCore/runtime/RegExpObject.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/RegExpObject.h4
-rw-r--r--Source/JavaScriptCore/runtime/RegExpPrototype.cpp6
-rw-r--r--Source/JavaScriptCore/runtime/SamplingCounter.h4
-rw-r--r--Source/JavaScriptCore/runtime/SmallStrings.h6
-rw-r--r--Source/JavaScriptCore/runtime/StringConstructor.cpp7
-rw-r--r--Source/JavaScriptCore/runtime/StringObject.h4
-rw-r--r--Source/JavaScriptCore/runtime/StringPrototype.cpp271
-rw-r--r--Source/JavaScriptCore/runtime/Structure.cpp23
-rw-r--r--Source/JavaScriptCore/runtime/Structure.h20
-rw-r--r--Source/JavaScriptCore/runtime/TimeoutChecker.h4
-rw-r--r--Source/JavaScriptCore/runtime/UString.h40
-rw-r--r--Source/JavaScriptCore/runtime/WriteBarrier.h4
89 files changed, 981 insertions, 1079 deletions
diff --git a/Source/JavaScriptCore/runtime/ArgList.h b/Source/JavaScriptCore/runtime/ArgList.h
index ac5a4f271..1512a0fa1 100644
--- a/Source/JavaScriptCore/runtime/ArgList.h
+++ b/Source/JavaScriptCore/runtime/ArgList.h
@@ -102,7 +102,7 @@ namespace JSC {
static void markLists(HeapRootVisitor&, ListSet&);
private:
- void slowAppend(JSValue);
+ JS_EXPORT_PRIVATE void slowAppend(JSValue);
EncodedJSValue& slotFor(int item) const
{
@@ -171,7 +171,7 @@ namespace JSC {
bool isEmpty() const { return !m_argCount; }
size_t size() const { return m_argCount; }
- void getSlice(int startIndex, ArgList& result) const;
+ JS_EXPORT_PRIVATE void getSlice(int startIndex, ArgList& result) const;
private:
JSValue* m_args;
diff --git a/Source/JavaScriptCore/runtime/Arguments.cpp b/Source/JavaScriptCore/runtime/Arguments.cpp
index fc136eb7e..6a675ab84 100644
--- a/Source/JavaScriptCore/runtime/Arguments.cpp
+++ b/Source/JavaScriptCore/runtime/Arguments.cpp
@@ -109,7 +109,7 @@ void Arguments::createStrictModeCallerIfNecessary(ExecState* exec)
d->overrodeCaller = true;
PropertyDescriptor descriptor;
- descriptor.setAccessorDescriptor(globalObject()->throwTypeErrorGetterSetter(exec), DontEnum | DontDelete | Getter | Setter);
+ descriptor.setAccessorDescriptor(globalObject()->throwTypeErrorGetterSetter(exec), DontEnum | DontDelete | Accessor);
methodTable()->defineOwnProperty(this, exec, exec->propertyNames().caller, descriptor, false);
}
@@ -120,7 +120,7 @@ void Arguments::createStrictModeCalleeIfNecessary(ExecState* exec)
d->overrodeCallee = true;
PropertyDescriptor descriptor;
- descriptor.setAccessorDescriptor(globalObject()->throwTypeErrorGetterSetter(exec), DontEnum | DontDelete | Getter | Setter);
+ descriptor.setAccessorDescriptor(globalObject()->throwTypeErrorGetterSetter(exec), DontEnum | DontDelete | Accessor);
methodTable()->defineOwnProperty(this, exec, exec->propertyNames().callee, descriptor, false);
}
diff --git a/Source/JavaScriptCore/runtime/ArrayPrototype.cpp b/Source/JavaScriptCore/runtime/ArrayPrototype.cpp
index dcf7a2fae..cb9b12a59 100644
--- a/Source/JavaScriptCore/runtime/ArrayPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/ArrayPrototype.cpp
@@ -197,7 +197,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState* exec)
if (element.isUndefinedOrNull())
continue;
- UString str = element.toString(exec);
+ UString str = element.toString(exec)->value(exec);
strBuffer[k] = str.impl();
totalSize += str.length();
allStrings8Bit = allStrings8Bit && str.is8Bit();
@@ -272,9 +272,9 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncToLocaleString(ExecState* exec)
CallData callData;
CallType callType = getCallData(conversionFunction, callData);
if (callType != CallTypeNone)
- str = call(exec, conversionFunction, callType, callData, element, exec->emptyList()).toString(exec);
+ str = call(exec, conversionFunction, callType, callData, element, exec->emptyList()).toString(exec)->value(exec);
else
- str = element.toString(exec);
+ str = element.toString(exec)->value(exec);
strBuffer.append(str);
}
}
@@ -297,7 +297,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncJoin(ExecState* exec)
UString separator;
if (!exec->argument(0).isUndefined())
- separator = exec->argument(0).toString(exec);
+ separator = exec->argument(0).toString(exec)->value(exec);
unsigned k = 0;
if (isJSArray(thisObj)) {
@@ -308,7 +308,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncJoin(ExecState* exec)
goto skipFirstLoop;
JSValue element = array->getIndex(k);
if (!element.isUndefinedOrNull())
- strBuffer.append(element.toString(exec));
+ strBuffer.append(element.toString(exec)->value(exec));
k++;
}
@@ -319,7 +319,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncJoin(ExecState* exec)
strBuffer.append(',');
JSValue element = array->getIndex(k);
if (!element.isUndefinedOrNull())
- strBuffer.append(element.toString(exec));
+ strBuffer.append(element.toString(exec)->value(exec));
}
} else {
for (; k < length; k++) {
@@ -328,7 +328,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncJoin(ExecState* exec)
strBuffer.append(separator);
JSValue element = array->getIndex(k);
if (!element.isUndefinedOrNull())
- strBuffer.append(element.toString(exec));
+ strBuffer.append(element.toString(exec)->value(exec));
}
}
}
@@ -343,7 +343,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncJoin(ExecState* exec)
JSValue element = thisObj->get(exec, k);
if (!element.isUndefinedOrNull())
- strBuffer.append(element.toString(exec));
+ strBuffer.append(element.toString(exec)->value(exec));
}
return JSValue::encode(strBuffer.build(exec));
@@ -429,7 +429,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncPush(ExecState* exec)
thisObj->methodTable()->putByIndex(thisObj, exec, length + n, exec->argument(n));
else {
PutPropertySlot slot;
- Identifier propertyName(exec, JSValue(static_cast<int64_t>(length) + static_cast<int64_t>(n)).toString(exec));
+ Identifier propertyName(exec, JSValue(static_cast<int64_t>(length) + static_cast<int64_t>(n)).toString(exec)->value(exec));
thisObj->methodTable()->put(thisObj, exec, propertyName, exec->argument(n), slot);
}
}
@@ -571,7 +571,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSort(ExecState* exec)
l.append(minObj);
compareResult = call(exec, function, callType, callData, jsUndefined(), l).toNumber(exec);
} else
- compareResult = (jObj.toString(exec) < minObj.toString(exec)) ? -1 : 1;
+ compareResult = (jObj.toString(exec)->value(exec) < minObj.toString(exec)->value(exec)) ? -1 : 1;
if (compareResult < 0) {
themin = j;
diff --git a/Source/JavaScriptCore/runtime/CallData.h b/Source/JavaScriptCore/runtime/CallData.h
index b138f5484..15a6a0a48 100644
--- a/Source/JavaScriptCore/runtime/CallData.h
+++ b/Source/JavaScriptCore/runtime/CallData.h
@@ -57,7 +57,7 @@ namespace JSC {
} js;
};
- JSValue call(ExecState*, JSValue functionObject, CallType, const CallData&, JSValue thisValue, const ArgList&);
+ JS_EXPORT_PRIVATE JSValue call(ExecState*, JSValue functionObject, CallType, const CallData&, JSValue thisValue, const ArgList&);
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/ClassInfo.h b/Source/JavaScriptCore/runtime/ClassInfo.h
index 9fff64e67..3d556d88c 100644
--- a/Source/JavaScriptCore/runtime/ClassInfo.h
+++ b/Source/JavaScriptCore/runtime/ClassInfo.h
@@ -88,7 +88,7 @@ namespace JSC {
HasInstanceFunctionPtr hasInstance;
typedef void (*PutWithAttributesFunctionPtr)(JSObject*, ExecState*, const Identifier& propertyName, JSValue, unsigned attributes);
- PutWithAttributesFunctionPtr putWithAttributes;
+ PutWithAttributesFunctionPtr putDirectVirtual;
typedef bool (*DefineOwnPropertyFunctionPtr)(JSObject*, ExecState*, const Identifier&, PropertyDescriptor&, bool);
DefineOwnPropertyFunctionPtr defineOwnProperty;
@@ -135,7 +135,7 @@ struct MemberCheck##member { \
&ClassName::getPropertyNames, \
&ClassName::className, \
&ClassName::hasInstance, \
- &ClassName::putWithAttributes, \
+ &ClassName::putDirectVirtual, \
&ClassName::defineOwnProperty, \
&ClassName::getOwnPropertyDescriptor, \
}, \
diff --git a/Source/JavaScriptCore/runtime/CommonSlowPaths.h b/Source/JavaScriptCore/runtime/CommonSlowPaths.h
index ab4de7da8..86c4bd5c2 100644
--- a/Source/JavaScriptCore/runtime/CommonSlowPaths.h
+++ b/Source/JavaScriptCore/runtime/CommonSlowPaths.h
@@ -76,7 +76,7 @@ inline bool opIn(ExecState* exec, JSValue propName, JSValue baseVal)
if (propName.getUInt32(i))
return baseObj->hasProperty(exec, i);
- Identifier property(exec, propName.toString(exec));
+ Identifier property(exec, propName.toString(exec)->value(exec));
if (exec->globalData().exception)
return false;
return baseObj->hasProperty(exec, property);
diff --git a/Source/JavaScriptCore/runtime/Completion.cpp b/Source/JavaScriptCore/runtime/Completion.cpp
index c3d9e6947..98a66589a 100644
--- a/Source/JavaScriptCore/runtime/Completion.cpp
+++ b/Source/JavaScriptCore/runtime/Completion.cpp
@@ -24,6 +24,7 @@
#include "Completion.h"
#include "CallFrame.h"
+#include "CodeProfiling.h"
#include "JSGlobalObject.h"
#include "JSLock.h"
#include "Interpreter.h"
@@ -55,6 +56,8 @@ JSValue evaluate(ExecState* exec, ScopeChainNode* scopeChain, const SourceCode&
JSLock lock(exec);
ASSERT(exec->globalData().identifierTable == wtfThreadData().currentIdentifierTable());
+ CodeProfiling profile(source);
+
ProgramExecutable* program = ProgramExecutable::create(exec, source);
if (!program) {
if (returnedException)
diff --git a/Source/JavaScriptCore/runtime/Completion.h b/Source/JavaScriptCore/runtime/Completion.h
index c3dbdfc58..3d3b86fe4 100644
--- a/Source/JavaScriptCore/runtime/Completion.h
+++ b/Source/JavaScriptCore/runtime/Completion.h
@@ -31,8 +31,8 @@ namespace JSC {
class ScopeChainNode;
class SourceCode;
- bool checkSyntax(ExecState*, const SourceCode&, JSValue* exception = 0);
- JSValue evaluate(ExecState*, ScopeChainNode*, const SourceCode&, JSValue thisValue = JSValue(), JSValue* exception = 0);
+ JS_EXPORT_PRIVATE bool checkSyntax(ExecState*, const SourceCode&, JSValue* exception = 0);
+ JS_EXPORT_PRIVATE JSValue evaluate(ExecState*, ScopeChainNode*, const SourceCode&, JSValue thisValue = JSValue(), JSValue* exception = 0);
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/ConstructData.h b/Source/JavaScriptCore/runtime/ConstructData.h
index cc8f46977..d7a3c73d3 100644
--- a/Source/JavaScriptCore/runtime/ConstructData.h
+++ b/Source/JavaScriptCore/runtime/ConstructData.h
@@ -56,7 +56,7 @@ namespace JSC {
} js;
};
- JSObject* construct(ExecState*, JSValue constructor, ConstructType, const ConstructData&, const ArgList&);
+ JS_EXPORT_PRIVATE JSObject* construct(ExecState*, JSValue constructor, ConstructType, const ConstructData&, const ArgList&);
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/DateConstructor.cpp b/Source/JavaScriptCore/runtime/DateConstructor.cpp
index 79c5181eb..365172294 100644
--- a/Source/JavaScriptCore/runtime/DateConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/DateConstructor.cpp
@@ -185,7 +185,7 @@ CallType DateConstructor::getCallData(JSCell*, CallData& callData)
static EncodedJSValue JSC_HOST_CALL dateParse(ExecState* exec)
{
- return JSValue::encode(jsNumber(parseDate(exec, exec->argument(0).toString(exec))));
+ return JSValue::encode(jsNumber(parseDate(exec, exec->argument(0).toString(exec)->value(exec))));
}
static EncodedJSValue JSC_HOST_CALL dateNow(ExecState*)
diff --git a/Source/JavaScriptCore/runtime/DateInstance.h b/Source/JavaScriptCore/runtime/DateInstance.h
index 3edfb0970..7c976a514 100644
--- a/Source/JavaScriptCore/runtime/DateInstance.h
+++ b/Source/JavaScriptCore/runtime/DateInstance.h
@@ -31,9 +31,9 @@ namespace JSC {
class DateInstance : public JSWrapperObject {
protected:
- DateInstance(ExecState*, Structure*);
+ JS_EXPORT_PRIVATE DateInstance(ExecState*, Structure*);
void finishCreation(JSGlobalData&);
- void finishCreation(JSGlobalData&, double);
+ JS_EXPORT_PRIVATE void finishCreation(JSGlobalData&, double);
static void destroy(JSCell*);
diff --git a/Source/JavaScriptCore/runtime/DatePrototype.cpp b/Source/JavaScriptCore/runtime/DatePrototype.cpp
index 96dea01db..922fb0a86 100644
--- a/Source/JavaScriptCore/runtime/DatePrototype.cpp
+++ b/Source/JavaScriptCore/runtime/DatePrototype.cpp
@@ -60,8 +60,10 @@
#include <sys/timeb.h>
#endif
-#if PLATFORM(MAC) || PLATFORM(IOS)
+#if PLATFORM(MAC) || PLATFORM(IOS) || PLATFORM(WX) || (PLATFORM(QT) && OS(DARWIN))
#include <CoreFoundation/CoreFoundation.h>
+#elif USE(ICU_UNICODE)
+#include <unicode/udat.h>
#endif
#if OS(WINCE) && !PLATFORM(QT)
@@ -128,7 +130,7 @@ namespace JSC {
enum LocaleDateTimeFormat { LocaleDateAndTime, LocaleDate, LocaleTime };
-#if PLATFORM(MAC) || PLATFORM(IOS)
+#if PLATFORM(MAC) || PLATFORM(IOS) || PLATFORM(WX) || (PLATFORM(QT) && OS(DARWIN))
// FIXME: Since this is superior to the strftime-based version, why limit this to PLATFORM(MAC)?
// Instead we should consider using this whenever USE(CF) is true.
@@ -154,13 +156,13 @@ static JSCell* formatLocaleDate(ExecState* exec, DateInstance*, double timeInMil
bool useCustomFormat = false;
UString customFormatString;
- UString arg0String = exec->argument(0).toString(exec);
+ UString arg0String = exec->argument(0).toString(exec)->value(exec);
if (arg0String == "custom" && !exec->argument(1).isUndefined()) {
useCustomFormat = true;
- customFormatString = exec->argument(1).toString(exec);
+ customFormatString = exec->argument(1).toString(exec)->value(exec);
} else if (format == LocaleDateAndTime && !exec->argument(1).isUndefined()) {
dateStyle = styleFromArgString(arg0String, dateStyle);
- timeStyle = styleFromArgString(exec->argument(1).toString(exec), timeStyle);
+ timeStyle = styleFromArgString(exec->argument(1).toString(exec)->value(exec), timeStyle);
} else if (format != LocaleTime && !exec->argument(0).isUndefined())
dateStyle = styleFromArgString(arg0String, dateStyle);
else if (format != LocaleDate && !exec->argument(0).isUndefined())
@@ -195,7 +197,29 @@ static JSCell* formatLocaleDate(ExecState* exec, DateInstance*, double timeInMil
return jsNontrivialString(exec, UString(buffer, length));
}
-#else // !PLATFORM(MAC) && !PLATFORM(IOS)
+#elif USE(ICU_UNICODE) && !UCONFIG_NO_FORMATTING
+
+static JSCell* formatLocaleDate(ExecState* exec, DateInstance* dateObject, double timeInMilliseconds, LocaleDateTimeFormat format)
+{
+ UDateFormatStyle timeStyle = (format != LocaleDate ? UDAT_LONG : UDAT_NONE);
+ UDateFormatStyle dateStyle = (format != LocaleTime ? UDAT_LONG : UDAT_NONE);
+
+ UErrorCode status = U_ZERO_ERROR;
+ UDateFormat* df = udat_open(timeStyle, dateStyle, 0, 0, -1, 0, 0, &status);
+ if (!df)
+ return jsEmptyString(exec);
+
+ UChar buffer[128];
+ int32_t length;
+ length = udat_format(df, timeInMilliseconds, buffer, 128, 0, &status);
+ udat_close(df);
+ if (status != U_ZERO_ERROR)
+ return jsEmptyString(exec);
+
+ return jsNontrivialString(exec, UString(buffer, length));
+}
+
+#else
static JSCell* formatLocaleDate(ExecState* exec, const GregorianDateTime& gdt, LocaleDateTimeFormat format)
{
diff --git a/Source/JavaScriptCore/runtime/Error.cpp b/Source/JavaScriptCore/runtime/Error.cpp
index 24f5da4f2..0947e3c20 100644
--- a/Source/JavaScriptCore/runtime/Error.cpp
+++ b/Source/JavaScriptCore/runtime/Error.cpp
@@ -37,7 +37,6 @@
namespace JSC {
static const char* linePropertyName = "line";
-static const char* sourceIdPropertyName = "sourceId";
static const char* sourceURLPropertyName = "sourceURL";
JSObject* createError(JSGlobalObject* globalObject, const UString& message)
@@ -119,15 +118,12 @@ JSObject* createURIError(ExecState* exec, const UString& message)
JSObject* addErrorInfo(JSGlobalData* globalData, JSObject* error, int line, const SourceCode& source)
{
- intptr_t sourceID = source.provider()->asID();
const UString& sourceURL = source.provider()->url();
if (line != -1)
- error->putWithAttributes(globalData, Identifier(globalData, linePropertyName), jsNumber(line), ReadOnly | DontDelete);
- if (sourceID != -1)
- error->putWithAttributes(globalData, Identifier(globalData, sourceIdPropertyName), jsNumber((double)sourceID), ReadOnly | DontDelete);
+ error->putDirect(*globalData, Identifier(globalData, linePropertyName), jsNumber(line), ReadOnly | DontDelete);
if (!sourceURL.isNull())
- error->putWithAttributes(globalData, Identifier(globalData, sourceURLPropertyName), jsString(globalData, sourceURL), ReadOnly | DontDelete);
+ error->putDirect(*globalData, Identifier(globalData, sourceURLPropertyName), jsString(globalData, sourceURL), ReadOnly | DontDelete);
return error;
}
@@ -140,7 +136,6 @@ JSObject* addErrorInfo(ExecState* exec, JSObject* error, int line, const SourceC
bool hasErrorInfo(ExecState* exec, JSObject* error)
{
return error->hasProperty(exec, Identifier(exec, linePropertyName))
- || error->hasProperty(exec, Identifier(exec, sourceIdPropertyName))
|| error->hasProperty(exec, Identifier(exec, sourceURLPropertyName));
}
diff --git a/Source/JavaScriptCore/runtime/Error.h b/Source/JavaScriptCore/runtime/Error.h
index b807d4ab4..88b540a35 100644
--- a/Source/JavaScriptCore/runtime/Error.h
+++ b/Source/JavaScriptCore/runtime/Error.h
@@ -46,12 +46,12 @@ namespace JSC {
JSObject* createTypeError(JSGlobalObject*, const UString&);
JSObject* createURIError(JSGlobalObject*, const UString&);
// ExecState wrappers.
- JSObject* createError(ExecState*, const UString&);
+ JS_EXPORT_PRIVATE JSObject* createError(ExecState*, const UString&);
JSObject* createEvalError(ExecState*, const UString&);
- JSObject* createRangeError(ExecState*, const UString&);
- JSObject* createReferenceError(ExecState*, const UString&);
- JSObject* createSyntaxError(ExecState*, const UString&);
- JSObject* createTypeError(ExecState*, const UString&);
+ JS_EXPORT_PRIVATE JSObject* createRangeError(ExecState*, const UString&);
+ JS_EXPORT_PRIVATE JSObject* createReferenceError(ExecState*, const UString&);
+ JS_EXPORT_PRIVATE JSObject* createSyntaxError(ExecState*, const UString&);
+ JS_EXPORT_PRIVATE JSObject* createTypeError(ExecState*, const UString&);
JSObject* createURIError(ExecState*, const UString&);
// Methods to add
@@ -61,12 +61,12 @@ namespace JSC {
JSObject* addErrorInfo(ExecState*, JSObject* error, int line, const SourceCode&);
// Methods to throw Errors.
- JSValue throwError(ExecState*, JSValue);
- JSObject* throwError(ExecState*, JSObject*);
+ JS_EXPORT_PRIVATE JSValue throwError(ExecState*, JSValue);
+ JS_EXPORT_PRIVATE JSObject* throwError(ExecState*, JSObject*);
// Convenience wrappers, create an throw an exception with a default message.
- JSObject* throwTypeError(ExecState*);
- JSObject* throwSyntaxError(ExecState*);
+ JS_EXPORT_PRIVATE JSObject* throwTypeError(ExecState*);
+ JS_EXPORT_PRIVATE JSObject* throwSyntaxError(ExecState*);
// Convenience wrappers, wrap result as an EncodedJSValue.
inline EncodedJSValue throwVMError(ExecState* exec, JSValue error) { return JSValue::encode(throwError(exec, error)); }
diff --git a/Source/JavaScriptCore/runtime/ErrorInstance.h b/Source/JavaScriptCore/runtime/ErrorInstance.h
index 888bfe856..d6fa32f99 100644
--- a/Source/JavaScriptCore/runtime/ErrorInstance.h
+++ b/Source/JavaScriptCore/runtime/ErrorInstance.h
@@ -42,14 +42,10 @@ namespace JSC {
instance->finishCreation(globalData, message);
return instance;
}
+
static ErrorInstance* create(ExecState* exec, Structure* structure, JSValue message)
{
- if (message.isUndefined()) {
- ErrorInstance* instance = new (NotNull, allocateCell<ErrorInstance>(*exec->heap())) ErrorInstance(exec->globalData(), structure);
- instance->finishCreation(exec->globalData(), UString());
- return instance;
- }
- return create(exec->globalData(), structure, message.toString(exec));
+ return create(exec->globalData(), structure, message.isUndefined() ? UString() : message.toString(exec)->value(exec));
}
bool appendSourceToMessage() { return m_appendSourceToMessage; }
diff --git a/Source/JavaScriptCore/runtime/ErrorPrototype.cpp b/Source/JavaScriptCore/runtime/ErrorPrototype.cpp
index e1a395c0e..7af294782 100644
--- a/Source/JavaScriptCore/runtime/ErrorPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/ErrorPrototype.cpp
@@ -101,7 +101,7 @@ EncodedJSValue JSC_HOST_CALL errorProtoFuncToString(ExecState* exec)
if (name.isUndefined())
nameString = "Error";
else {
- nameString = name.toString(exec);
+ nameString = name.toString(exec)->value(exec);
if (exec->hadException())
return JSValue::encode(jsUndefined());
}
@@ -118,7 +118,7 @@ EncodedJSValue JSC_HOST_CALL errorProtoFuncToString(ExecState* exec)
if (message.isUndefined())
messageString = "";
else {
- messageString = message.toString(exec);
+ messageString = message.toString(exec)->value(exec);
if (exec->hadException())
return JSValue::encode(jsUndefined());
}
diff --git a/Source/JavaScriptCore/runtime/ExceptionHelpers.cpp b/Source/JavaScriptCore/runtime/ExceptionHelpers.cpp
index 05e971f7f..ce63ae9af 100644
--- a/Source/JavaScriptCore/runtime/ExceptionHelpers.cpp
+++ b/Source/JavaScriptCore/runtime/ExceptionHelpers.cpp
@@ -113,7 +113,7 @@ JSObject* createUndefinedVariableError(ExecState* exec, const Identifier& ident)
JSObject* createInvalidParamError(ExecState* exec, const char* op, JSValue value)
{
- UString errorMessage = makeUString("'", value.toString(exec), "' is not a valid argument for '", op, "'");
+ UString errorMessage = makeUString("'", value.toString(exec)->value(exec), "' is not a valid argument for '", op, "'");
JSObject* exception = createTypeError(exec, errorMessage);
ASSERT(exception->isErrorInstance());
static_cast<ErrorInstance*>(exception)->setAppendSourceToMessage();
@@ -122,7 +122,7 @@ JSObject* createInvalidParamError(ExecState* exec, const char* op, JSValue value
JSObject* createNotAConstructorError(ExecState* exec, JSValue value)
{
- UString errorMessage = makeUString("'", value.toString(exec), "' is not a constructor");
+ UString errorMessage = makeUString("'", value.toString(exec)->value(exec), "' is not a constructor");
JSObject* exception = createTypeError(exec, errorMessage);
ASSERT(exception->isErrorInstance());
static_cast<ErrorInstance*>(exception)->setAppendSourceToMessage();
@@ -131,7 +131,7 @@ JSObject* createNotAConstructorError(ExecState* exec, JSValue value)
JSObject* createNotAFunctionError(ExecState* exec, JSValue value)
{
- UString errorMessage = makeUString("'", value.toString(exec), "' is not a function");
+ UString errorMessage = makeUString("'", value.toString(exec)->value(exec), "' is not a function");
JSObject* exception = createTypeError(exec, errorMessage);
ASSERT(exception->isErrorInstance());
static_cast<ErrorInstance*>(exception)->setAppendSourceToMessage();
@@ -140,7 +140,7 @@ JSObject* createNotAFunctionError(ExecState* exec, JSValue value)
JSObject* createNotAnObjectError(ExecState* exec, JSValue value)
{
- UString errorMessage = makeUString("'", value.toString(exec), "' is not an object");
+ UString errorMessage = makeUString("'", value.toString(exec)->value(exec), "' is not an object");
JSObject* exception = createTypeError(exec, errorMessage);
ASSERT(exception->isErrorInstance());
static_cast<ErrorInstance*>(exception)->setAppendSourceToMessage();
diff --git a/Source/JavaScriptCore/runtime/ExceptionHelpers.h b/Source/JavaScriptCore/runtime/ExceptionHelpers.h
index f71d1a308..7bffd294b 100644
--- a/Source/JavaScriptCore/runtime/ExceptionHelpers.h
+++ b/Source/JavaScriptCore/runtime/ExceptionHelpers.h
@@ -33,15 +33,15 @@
namespace JSC {
-JSObject* createInterruptedExecutionException(JSGlobalData*);
+JS_EXPORT_PRIVATE JSObject* createInterruptedExecutionException(JSGlobalData*);
bool isInterruptedExecutionException(JSObject*);
bool isInterruptedExecutionException(JSValue);
JSObject* createTerminatedExecutionException(JSGlobalData*);
bool isTerminatedExecutionException(JSObject*);
-bool isTerminatedExecutionException(JSValue);
+JS_EXPORT_PRIVATE bool isTerminatedExecutionException(JSValue);
-JSObject* createStackOverflowError(ExecState*);
+JS_EXPORT_PRIVATE JSObject* createStackOverflowError(ExecState*);
JSObject* createStackOverflowError(JSGlobalObject*);
JSObject* createOutOfMemoryError(JSGlobalObject*);
JSObject* createUndefinedVariableError(ExecState*, const Identifier&);
@@ -79,7 +79,7 @@ public:
return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
}
- static JS_EXPORTDATA const ClassInfo s_info;
+ static const ClassInfo s_info;
};
class TerminatedExecutionError : public JSNonFinalObject {
diff --git a/Source/JavaScriptCore/runtime/Executable.cpp b/Source/JavaScriptCore/runtime/Executable.cpp
index a364e84da..c67c54cd2 100644
--- a/Source/JavaScriptCore/runtime/Executable.cpp
+++ b/Source/JavaScriptCore/runtime/Executable.cpp
@@ -30,6 +30,7 @@
#include "CodeBlock.h"
#include "DFGDriver.h"
#include "JIT.h"
+#include "JITDriver.h"
#include "Parser.h"
#include "UStringBuilder.h"
#include "Vector.h"
@@ -130,22 +131,24 @@ void ProgramExecutable::destroy(JSCell* cell)
const ClassInfo FunctionExecutable::s_info = { "FunctionExecutable", &ScriptExecutable::s_info, 0, 0, CREATE_METHOD_TABLE(FunctionExecutable) };
-FunctionExecutable::FunctionExecutable(JSGlobalData& globalData, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, bool inStrictContext)
+FunctionExecutable::FunctionExecutable(JSGlobalData& globalData, const Identifier& name, const Identifier& inferredName, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, bool inStrictContext)
: ScriptExecutable(globalData.functionExecutableStructure.get(), globalData, source, inStrictContext)
, m_numCapturedVariables(0)
, m_forceUsesArguments(forceUsesArguments)
, m_parameters(parameters)
, m_name(name)
+ , m_inferredName(inferredName)
, m_symbolTable(0)
{
}
-FunctionExecutable::FunctionExecutable(ExecState* exec, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, bool inStrictContext)
+FunctionExecutable::FunctionExecutable(ExecState* exec, const Identifier& name, const Identifier& inferredName, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, bool inStrictContext)
: ScriptExecutable(exec->globalData().functionExecutableStructure.get(), exec, source, inStrictContext)
, m_numCapturedVariables(0)
, m_forceUsesArguments(forceUsesArguments)
, m_parameters(parameters)
, m_name(name)
+ , m_inferredName(inferredName)
, m_symbolTable(0)
{
}
@@ -209,27 +212,8 @@ JSObject* EvalExecutable::compileInternal(ExecState* exec, ScopeChainNode* scope
}
#if ENABLE(JIT)
- if (exec->globalData().canUseJIT()) {
- bool dfgCompiled = false;
- if (jitType == JITCode::DFGJIT)
- dfgCompiled = DFG::tryCompile(exec, m_evalCodeBlock.get(), m_jitCodeForCall);
- if (dfgCompiled)
- ASSERT(!m_evalCodeBlock->alternative() || !m_evalCodeBlock->alternative()->hasIncomingCalls());
- else {
- if (m_evalCodeBlock->alternative()) {
- // There is already an alternative piece of code compiled with a different
- // JIT, so we can silently fail.
- m_evalCodeBlock = static_pointer_cast<EvalCodeBlock>(m_evalCodeBlock->releaseAlternative());
- return 0;
- }
- m_jitCodeForCall = JIT::compile(scopeChainNode->globalData, m_evalCodeBlock.get());
- }
-#if !ENABLE(OPCODE_SAMPLING)
- if (!BytecodeGenerator::dumpsGeneratedCode())
- m_evalCodeBlock->handleBytecodeDiscardingOpportunity();
-#endif
- m_evalCodeBlock->setJITCode(m_jitCodeForCall, MacroAssemblerCodePtr());
- }
+ if (!jitCompileIfAppropriate(*globalData, m_evalCodeBlock, m_jitCodeForCall, jitType))
+ return 0;
#endif
#if ENABLE(JIT)
@@ -354,26 +338,8 @@ JSObject* ProgramExecutable::compileInternal(ExecState* exec, ScopeChainNode* sc
}
#if ENABLE(JIT)
- if (exec->globalData().canUseJIT()) {
- bool dfgCompiled = false;
- if (jitType == JITCode::DFGJIT)
- dfgCompiled = DFG::tryCompile(exec, m_programCodeBlock.get(), m_jitCodeForCall);
- if (dfgCompiled) {
- if (m_programCodeBlock->alternative())
- m_programCodeBlock->alternative()->unlinkIncomingCalls();
- } else {
- if (m_programCodeBlock->alternative()) {
- m_programCodeBlock = static_pointer_cast<ProgramCodeBlock>(m_programCodeBlock->releaseAlternative());
- return 0;
- }
- m_jitCodeForCall = JIT::compile(scopeChainNode->globalData, m_programCodeBlock.get());
- }
-#if !ENABLE(OPCODE_SAMPLING)
- if (!BytecodeGenerator::dumpsGeneratedCode())
- m_programCodeBlock->handleBytecodeDiscardingOpportunity();
-#endif
- m_programCodeBlock->setJITCode(m_jitCodeForCall, MacroAssemblerCodePtr());
- }
+ if (!jitCompileIfAppropriate(*globalData, m_programCodeBlock, m_jitCodeForCall, jitType))
+ return 0;
#endif
#if ENABLE(JIT)
@@ -540,29 +506,8 @@ JSObject* FunctionExecutable::compileForCallInternal(ExecState* exec, ScopeChain
m_symbolTable = m_codeBlockForCall->sharedSymbolTable();
#if ENABLE(JIT)
- JSGlobalData* globalData = scopeChainNode->globalData;
- if (globalData->canUseJIT()) {
- bool dfgCompiled = false;
- if (jitType == JITCode::DFGJIT)
- dfgCompiled = DFG::tryCompileFunction(exec, m_codeBlockForCall.get(), m_jitCodeForCall, m_jitCodeForCallWithArityCheck);
- if (dfgCompiled) {
- if (m_codeBlockForCall->alternative())
- m_codeBlockForCall->alternative()->unlinkIncomingCalls();
- } else {
- if (m_codeBlockForCall->alternative()) {
- m_codeBlockForCall = static_pointer_cast<FunctionCodeBlock>(m_codeBlockForCall->releaseAlternative());
- m_symbolTable = m_codeBlockForCall->sharedSymbolTable();
- return 0;
- }
- m_jitCodeForCall = JIT::compile(globalData, m_codeBlockForCall.get(), &m_jitCodeForCallWithArityCheck);
- }
-#if !ENABLE(OPCODE_SAMPLING)
- if (!BytecodeGenerator::dumpsGeneratedCode())
- m_codeBlockForCall->handleBytecodeDiscardingOpportunity();
-#endif
-
- m_codeBlockForCall->setJITCode(m_jitCodeForCall, m_jitCodeForCallWithArityCheck);
- }
+ if (!jitCompileFunctionIfAppropriate(exec->globalData(), m_codeBlockForCall, m_jitCodeForCall, m_jitCodeForCallWithArityCheck, m_symbolTable, jitType))
+ return 0;
#endif
#if ENABLE(JIT)
@@ -603,29 +548,8 @@ JSObject* FunctionExecutable::compileForConstructInternal(ExecState* exec, Scope
m_symbolTable = m_codeBlockForConstruct->sharedSymbolTable();
#if ENABLE(JIT)
- JSGlobalData* globalData = scopeChainNode->globalData;
- if (globalData->canUseJIT()) {
- bool dfgCompiled = false;
- if (jitType == JITCode::DFGJIT)
- dfgCompiled = DFG::tryCompileFunction(exec, m_codeBlockForConstruct.get(), m_jitCodeForConstruct, m_jitCodeForConstructWithArityCheck);
- if (dfgCompiled) {
- if (m_codeBlockForConstruct->alternative())
- m_codeBlockForConstruct->alternative()->unlinkIncomingCalls();
- } else {
- if (m_codeBlockForConstruct->alternative()) {
- m_codeBlockForConstruct = static_pointer_cast<FunctionCodeBlock>(m_codeBlockForConstruct->releaseAlternative());
- m_symbolTable = m_codeBlockForConstruct->sharedSymbolTable();
- return 0;
- }
- m_jitCodeForConstruct = JIT::compile(globalData, m_codeBlockForConstruct.get(), &m_jitCodeForConstructWithArityCheck);
- }
-#if !ENABLE(OPCODE_SAMPLING)
- if (!BytecodeGenerator::dumpsGeneratedCode())
- m_codeBlockForConstruct->handleBytecodeDiscardingOpportunity();
-#endif
-
- m_codeBlockForConstruct->setJITCode(m_jitCodeForConstruct, m_jitCodeForConstructWithArityCheck);
- }
+ if (!jitCompileFunctionIfAppropriate(exec->globalData(), m_codeBlockForConstruct, m_jitCodeForConstruct, m_jitCodeForConstructWithArityCheck, m_symbolTable, jitType))
+ return 0;
#endif
#if ENABLE(JIT)
@@ -738,7 +662,7 @@ FunctionExecutable* FunctionExecutable::fromGlobalCode(const Identifier& functio
FunctionBodyNode* body = static_cast<FuncExprNode*>(funcExpr)->body();
ASSERT(body);
- return FunctionExecutable::create(exec->globalData(), functionName, body->source(), body->usesArguments(), body->parameters(), body->isStrictMode(), body->lineNo(), body->lastLine());
+ return FunctionExecutable::create(exec->globalData(), functionName, functionName, body->source(), body->usesArguments(), body->parameters(), body->isStrictMode(), body->lineNo(), body->lastLine());
}
UString FunctionExecutable::paramString() const
diff --git a/Source/JavaScriptCore/runtime/Executable.h b/Source/JavaScriptCore/runtime/Executable.h
index cc44d61a7..6800b5a82 100644
--- a/Source/JavaScriptCore/runtime/Executable.h
+++ b/Source/JavaScriptCore/runtime/Executable.h
@@ -87,7 +87,7 @@ namespace JSC {
static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto) { return Structure::create(globalData, globalObject, proto, TypeInfo(CompoundType, StructureFlags), &s_info); }
- static const ClassInfo s_info;
+ static JS_EXPORTDATA const ClassInfo s_info;
protected:
static const unsigned StructureFlags = 0;
@@ -456,17 +456,17 @@ namespace JSC {
public:
typedef ScriptExecutable Base;
- static FunctionExecutable* create(ExecState* exec, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, bool isInStrictContext, int firstLine, int lastLine)
+ static FunctionExecutable* create(ExecState* exec, const Identifier& name, const Identifier& inferredName, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, bool isInStrictContext, int firstLine, int lastLine)
{
- FunctionExecutable* executable = new (NotNull, allocateCell<FunctionExecutable>(*exec->heap())) FunctionExecutable(exec, name, source, forceUsesArguments, parameters, isInStrictContext);
+ FunctionExecutable* executable = new (NotNull, allocateCell<FunctionExecutable>(*exec->heap())) FunctionExecutable(exec, name, inferredName, source, forceUsesArguments, parameters, isInStrictContext);
executable->finishCreation(exec->globalData(), name, firstLine, lastLine);
exec->globalData().heap.addFinalizer(executable, &finalize);
return executable;
}
- static FunctionExecutable* create(JSGlobalData& globalData, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, bool isInStrictContext, int firstLine, int lastLine)
+ static FunctionExecutable* create(JSGlobalData& globalData, const Identifier& name, const Identifier& inferredName, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, bool isInStrictContext, int firstLine, int lastLine)
{
- FunctionExecutable* executable = new (NotNull, allocateCell<FunctionExecutable>(globalData.heap)) FunctionExecutable(globalData, name, source, forceUsesArguments, parameters, isInStrictContext);
+ FunctionExecutable* executable = new (NotNull, allocateCell<FunctionExecutable>(globalData.heap)) FunctionExecutable(globalData, name, inferredName, source, forceUsesArguments, parameters, isInStrictContext);
executable->finishCreation(globalData, name, firstLine, lastLine);
globalData.heap.addFinalizer(executable, &finalize);
return executable;
@@ -608,6 +608,7 @@ namespace JSC {
}
const Identifier& name() { return m_name; }
+ const Identifier& inferredName() { return m_inferredName; }
JSString* nameValue() const { return m_nameValue.get(); }
size_t parameterCount() const { return m_parameters->size(); } // Excluding 'this'!
unsigned capturedVariableCount() const { return m_numCapturedVariables; }
@@ -639,8 +640,8 @@ namespace JSC {
}
private:
- FunctionExecutable(JSGlobalData&, const Identifier& name, const SourceCode&, bool forceUsesArguments, FunctionParameters*, bool);
- FunctionExecutable(ExecState*, const Identifier& name, const SourceCode&, bool forceUsesArguments, FunctionParameters*, bool);
+ FunctionExecutable(JSGlobalData&, const Identifier& name, const Identifier& inferredName, const SourceCode&, bool forceUsesArguments, FunctionParameters*, bool);
+ FunctionExecutable(ExecState*, const Identifier& name, const Identifier& inferredName, const SourceCode&, bool forceUsesArguments, FunctionParameters*, bool);
JSObject* compileForCallInternal(ExecState*, ScopeChainNode*, JITCode::JITType);
JSObject* compileForConstructInternal(ExecState*, ScopeChainNode*, JITCode::JITType);
@@ -661,6 +662,7 @@ namespace JSC {
OwnPtr<FunctionCodeBlock> m_codeBlockForCall;
OwnPtr<FunctionCodeBlock> m_codeBlockForConstruct;
Identifier m_name;
+ Identifier m_inferredName;
WriteBarrier<JSString> m_nameValue;
SharedSymbolTable* m_symbolTable;
};
diff --git a/Source/JavaScriptCore/runtime/FunctionConstructor.cpp b/Source/JavaScriptCore/runtime/FunctionConstructor.cpp
index e08e58c83..956b2161d 100644
--- a/Source/JavaScriptCore/runtime/FunctionConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/FunctionConstructor.cpp
@@ -96,17 +96,17 @@ JSObject* constructFunctionSkippingEvalEnabledCheck(ExecState* exec, JSGlobalObj
if (args.isEmpty())
program = "(function() { \n})";
else if (args.size() == 1)
- program = makeUString("(function() { ", args.at(0).toString(exec), "\n})");
+ program = makeUString("(function() { ", args.at(0).toString(exec)->value(exec), "\n})");
else {
UStringBuilder builder;
builder.append("(function(");
- builder.append(args.at(0).toString(exec));
+ builder.append(args.at(0).toString(exec)->value(exec));
for (size_t i = 1; i < args.size() - 1; i++) {
builder.append(",");
- builder.append(args.at(i).toString(exec));
+ builder.append(args.at(i).toString(exec)->value(exec));
}
builder.append(") { ");
- builder.append(args.at(args.size() - 1).toString(exec));
+ builder.append(args.at(args.size() - 1).toString(exec)->value(exec));
builder.append("\n})");
program = builder.toUString();
}
diff --git a/Source/JavaScriptCore/runtime/FunctionConstructor.h b/Source/JavaScriptCore/runtime/FunctionConstructor.h
index 7141916cf..31986b70a 100644
--- a/Source/JavaScriptCore/runtime/FunctionConstructor.h
+++ b/Source/JavaScriptCore/runtime/FunctionConstructor.h
@@ -59,7 +59,7 @@ namespace JSC {
JSObject* constructFunction(ExecState*, JSGlobalObject*, const ArgList&, const Identifier& functionName, const UString& sourceURL, const WTF::TextPosition&);
JSObject* constructFunction(ExecState*, JSGlobalObject*, const ArgList&);
- JSObject* constructFunctionSkippingEvalEnabledCheck(ExecState*, JSGlobalObject*, const ArgList&, const Identifier&, const UString&, const WTF::TextPosition&);
+ JS_EXPORT_PRIVATE JSObject* constructFunctionSkippingEvalEnabledCheck(ExecState*, JSGlobalObject*, const ArgList&, const Identifier&, const UString&, const WTF::TextPosition&);
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/FunctionPrototype.cpp b/Source/JavaScriptCore/runtime/FunctionPrototype.cpp
index 049b7b914..266ddc241 100644
--- a/Source/JavaScriptCore/runtime/FunctionPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/FunctionPrototype.cpp
@@ -207,7 +207,7 @@ EncodedJSValue JSC_HOST_CALL functionProtoFuncBind(ExecState* exec)
length = targetLength - numBoundArgs;
}
- Identifier name(exec, target.get(exec, exec->propertyNames().name).toString(exec));
+ Identifier name(exec, target.get(exec, exec->propertyNames().name).toString(exec)->value(exec));
return JSValue::encode(JSBoundFunction::create(exec, globalObject, targetObject, exec->argument(0), boundArgs, length, name));
}
diff --git a/Source/JavaScriptCore/runtime/GetterSetter.h b/Source/JavaScriptCore/runtime/GetterSetter.h
index 293bf6434..b8caf0198 100644
--- a/Source/JavaScriptCore/runtime/GetterSetter.h
+++ b/Source/JavaScriptCore/runtime/GetterSetter.h
@@ -56,9 +56,9 @@ namespace JSC {
static void visitChildren(JSCell*, SlotVisitor&);
JSObject* getter() const { return m_getter.get(); }
- void setGetter(JSGlobalData& globalData, JSObject* getter) { m_getter.set(globalData, this, getter); }
+ void setGetter(JSGlobalData& globalData, JSObject* getter) { m_getter.setMayBeNull(globalData, this, getter); }
JSObject* setter() const { return m_setter.get(); }
- void setSetter(JSGlobalData& globalData, JSObject* setter) { m_setter.set(globalData, this, setter); }
+ void setSetter(JSGlobalData& globalData, JSObject* setter) { m_setter.setMayBeNull(globalData, this, setter); }
static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
{
return Structure::create(globalData, globalObject, prototype, TypeInfo(GetterSetterType, OverridesVisitChildren), &s_info);
diff --git a/Source/JavaScriptCore/runtime/Identifier.h b/Source/JavaScriptCore/runtime/Identifier.h
index 2cc88b256..947c95b33 100644
--- a/Source/JavaScriptCore/runtime/Identifier.h
+++ b/Source/JavaScriptCore/runtime/Identifier.h
@@ -56,14 +56,14 @@ namespace JSC {
static Identifier createLCharFromUChar(JSGlobalData* globalData, const UChar* s, int length) { return Identifier(globalData, add8(globalData, s, length)); }
- static Identifier from(ExecState* exec, unsigned y);
- static Identifier from(ExecState* exec, int y);
+ JS_EXPORT_PRIVATE static Identifier from(ExecState* exec, unsigned y);
+ JS_EXPORT_PRIVATE static Identifier from(ExecState* exec, int y);
static Identifier from(ExecState* exec, double y);
static Identifier from(JSGlobalData*, unsigned y);
static Identifier from(JSGlobalData*, int y);
static Identifier from(JSGlobalData*, double y);
- static uint32_t toUInt32(const UString&, bool& ok);
+ JS_EXPORT_PRIVATE static uint32_t toUInt32(const UString&, bool& ok);
uint32_t toUInt32(bool& ok) const { return toUInt32(m_string, ok); }
unsigned toArrayIndex(bool& ok) const;
@@ -84,7 +84,7 @@ namespace JSC {
static bool equal(const StringImpl*, const UChar*, unsigned length);
static bool equal(const StringImpl* a, const StringImpl* b) { return ::equal(a, b); }
- static PassRefPtr<StringImpl> add(ExecState*, const char*); // Only to be used with string literals.
+ JS_EXPORT_PRIVATE static PassRefPtr<StringImpl> add(ExecState*, const char*); // Only to be used with string literals.
static PassRefPtr<StringImpl> add(JSGlobalData*, const char*); // Only to be used with string literals.
private:
@@ -119,11 +119,11 @@ namespace JSC {
return addSlowCase(globalData, r);
}
- static PassRefPtr<StringImpl> addSlowCase(ExecState*, StringImpl* r);
- static PassRefPtr<StringImpl> addSlowCase(JSGlobalData*, StringImpl* r);
+ JS_EXPORT_PRIVATE static PassRefPtr<StringImpl> addSlowCase(ExecState*, StringImpl* r);
+ JS_EXPORT_PRIVATE static PassRefPtr<StringImpl> addSlowCase(JSGlobalData*, StringImpl* r);
- static void checkCurrentIdentifierTable(ExecState*);
- static void checkCurrentIdentifierTable(JSGlobalData*);
+ JS_EXPORT_PRIVATE static void checkCurrentIdentifierTable(ExecState*);
+ JS_EXPORT_PRIVATE static void checkCurrentIdentifierTable(JSGlobalData*);
};
template <> ALWAYS_INLINE bool Identifier::canUseSingleCharacterString(LChar)
diff --git a/Source/JavaScriptCore/runtime/InitializeThreading.h b/Source/JavaScriptCore/runtime/InitializeThreading.h
index 1a93ccb9b..91301a0d8 100644
--- a/Source/JavaScriptCore/runtime/InitializeThreading.h
+++ b/Source/JavaScriptCore/runtime/InitializeThreading.h
@@ -33,7 +33,7 @@ namespace JSC {
// This function must be called from the main thread. It is safe to call it repeatedly.
// Darwin is an exception to this rule: it is OK to call this function from any thread, even reentrantly.
- void initializeThreading();
+ JS_EXPORT_PRIVATE void initializeThreading();
}
diff --git a/Source/JavaScriptCore/runtime/InternalFunction.h b/Source/JavaScriptCore/runtime/InternalFunction.h
index a038b7ae1..532bd0c8d 100644
--- a/Source/JavaScriptCore/runtime/InternalFunction.h
+++ b/Source/JavaScriptCore/runtime/InternalFunction.h
@@ -37,7 +37,7 @@ namespace JSC {
static JS_EXPORTDATA const ClassInfo s_info;
- const UString& name(ExecState*);
+ JS_EXPORT_PRIVATE const UString& name(ExecState*);
const UString displayName(ExecState*);
const UString calculatedDisplayName(ExecState*);
@@ -49,9 +49,9 @@ namespace JSC {
protected:
static const unsigned StructureFlags = ImplementsHasInstance | JSObject::StructureFlags;
- InternalFunction(JSGlobalObject*, Structure*);
+ JS_EXPORT_PRIVATE InternalFunction(JSGlobalObject*, Structure*);
- void finishCreation(JSGlobalData&, const Identifier& name);
+ JS_EXPORT_PRIVATE void finishCreation(JSGlobalData&, const Identifier& name);
static CallType getCallData(JSCell*, CallData&);
};
diff --git a/Source/JavaScriptCore/runtime/JSActivation.cpp b/Source/JavaScriptCore/runtime/JSActivation.cpp
index 83d1ee493..3e05738eb 100644
--- a/Source/JavaScriptCore/runtime/JSActivation.cpp
+++ b/Source/JavaScriptCore/runtime/JSActivation.cpp
@@ -45,7 +45,7 @@ JSActivation::JSActivation(CallFrame* callFrame, FunctionExecutable* functionExe
: Base(callFrame->globalData(), callFrame->globalData().activationStructure.get(), functionExecutable->symbolTable(), callFrame->registers())
, m_numCapturedArgs(max(callFrame->argumentCount(), functionExecutable->parameterCount()))
, m_numCapturedVars(functionExecutable->capturedVariableCount())
- , m_requiresDynamicChecks(functionExecutable->usesEval())
+ , m_requiresDynamicChecks(functionExecutable->usesEval() && !functionExecutable->isStrictMode())
, m_argumentsRegister(functionExecutable->generatedBytecode().argumentsRegister())
{
}
@@ -184,11 +184,11 @@ void JSActivation::put(JSCell* cell, ExecState* exec, const Identifier& property
// properties are non-standard extensions that other implementations do not
// expose in the activation object.
ASSERT(!thisObject->hasGetterSetterProperties());
- thisObject->putDirect(exec->globalData(), propertyName, value, 0, true, slot);
+ thisObject->putOwnDataProperty(exec->globalData(), propertyName, value, slot);
}
// FIXME: Make this function honor ReadOnly (const) and DontEnum
-void JSActivation::putWithAttributes(JSObject* object, ExecState* exec, const Identifier& propertyName, JSValue value, unsigned attributes)
+void JSActivation::putDirectVirtual(JSObject* object, ExecState* exec, const Identifier& propertyName, JSValue value, unsigned attributes)
{
JSActivation* thisObject = jsCast<JSActivation*>(object);
ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(thisObject));
@@ -200,7 +200,7 @@ void JSActivation::putWithAttributes(JSObject* object, ExecState* exec, const Id
// properties are non-standard extensions that other implementations do not
// expose in the activation object.
ASSERT(!thisObject->hasGetterSetterProperties());
- JSObject::putWithAttributes(thisObject, exec, propertyName, value, attributes);
+ JSObject::putDirectVirtual(thisObject, exec, propertyName, value, attributes);
}
bool JSActivation::deleteProperty(JSCell* cell, ExecState* exec, const Identifier& propertyName)
diff --git a/Source/JavaScriptCore/runtime/JSActivation.h b/Source/JavaScriptCore/runtime/JSActivation.h
index 2ce053e05..c18492344 100644
--- a/Source/JavaScriptCore/runtime/JSActivation.h
+++ b/Source/JavaScriptCore/runtime/JSActivation.h
@@ -64,7 +64,7 @@ namespace JSC {
static void put(JSCell*, ExecState*, const Identifier&, JSValue, PutPropertySlot&);
- static void putWithAttributes(JSObject*, ExecState*, const Identifier&, JSValue, unsigned attributes);
+ static void putDirectVirtual(JSObject*, ExecState*, const Identifier&, JSValue, unsigned attributes);
static bool deleteProperty(JSCell*, ExecState*, const Identifier& propertyName);
static JSObject* toThisObject(JSCell*, ExecState*);
diff --git a/Source/JavaScriptCore/runtime/JSArray.cpp b/Source/JavaScriptCore/runtime/JSArray.cpp
index b3210083d..c84fb5b10 100644
--- a/Source/JavaScriptCore/runtime/JSArray.cpp
+++ b/Source/JavaScriptCore/runtime/JSArray.cpp
@@ -24,6 +24,8 @@
#include "JSArray.h"
#include "ArrayPrototype.h"
+#include "BumpSpace.h"
+#include "BumpSpaceInlineMethods.h"
#include "CachedCall.h"
#include "Error.h"
#include "Executable.h"
@@ -130,7 +132,10 @@ inline void JSArray::checkConsistency(ConsistencyCheckType)
JSArray::JSArray(JSGlobalData& globalData, Structure* structure)
: JSNonFinalObject(globalData, structure)
+ , m_indexBias(0)
, m_storage(0)
+ , m_sparseValueMap(0)
+ , m_subclassData(0)
{
}
@@ -142,13 +147,14 @@ void JSArray::finishCreation(JSGlobalData& globalData, unsigned initialLength)
unsigned initialVectorLength = BASE_VECTOR_LEN;
unsigned initialStorageSize = storageSize(initialVectorLength);
- m_storage = static_cast<ArrayStorage*>(fastMalloc(initialStorageSize));
+ void* newStorage = 0;
+ if (!globalData.heap.tryAllocateStorage(initialStorageSize, &newStorage))
+ CRASH();
+
+ m_storage = static_cast<ArrayStorage*>(newStorage);
m_storage->m_allocBase = m_storage;
m_storage->m_length = initialLength;
- m_indexBias = 0;
m_vectorLength = initialVectorLength;
- m_storage->m_sparseValueMap = 0;
- m_storage->subclassData = 0;
m_storage->m_numValuesInVector = 0;
#if CHECK_ARRAY_CONSISTENCY
m_storage->m_inCompactInitialization = false;
@@ -159,8 +165,6 @@ void JSArray::finishCreation(JSGlobalData& globalData, unsigned initialLength)
vector[i].clear();
checkConsistency();
-
- Heap::heap(this)->reportExtraMemoryCost(initialStorageSize);
}
JSArray* JSArray::tryFinishCreationUninitialized(JSGlobalData& globalData, unsigned initialLength)
@@ -175,14 +179,16 @@ JSArray* JSArray::tryFinishCreationUninitialized(JSGlobalData& globalData, unsig
unsigned initialVectorLength = max(initialLength, BASE_VECTOR_LEN);
unsigned initialStorageSize = storageSize(initialVectorLength);
- m_storage = static_cast<ArrayStorage*>(fastMalloc(initialStorageSize));
+ void* newStorage = 0;
+ if (!globalData.heap.tryAllocateStorage(initialStorageSize, &newStorage))
+ CRASH();
+
+ m_storage = static_cast<ArrayStorage*>(newStorage);
m_storage->m_allocBase = m_storage;
m_storage->m_length = 0;
- m_indexBias = 0;
m_vectorLength = initialVectorLength;
- m_storage->m_sparseValueMap = 0;
- m_storage->subclassData = 0;
m_storage->m_numValuesInVector = initialLength;
+
#if CHECK_ARRAY_CONSISTENCY
m_storage->m_inCompactInitialization = true;
#endif
@@ -191,26 +197,15 @@ JSArray* JSArray::tryFinishCreationUninitialized(JSGlobalData& globalData, unsig
for (size_t i = initialLength; i < initialVectorLength; ++i)
vector[i].clear();
- Heap::heap(this)->reportExtraMemoryCost(initialStorageSize);
return this;
}
-JSArray::~JSArray()
-{
- ASSERT(jsCast<JSArray*>(this));
-
- // If we are unable to allocate memory for m_storage then this may be null.
- if (!m_storage)
- return;
-
- checkConsistency(DestructorConsistencyCheck);
- delete m_storage->m_sparseValueMap;
- fastFree(m_storage->m_allocBase);
-}
-
-void JSArray::destroy(JSCell* cell)
+// This function can be called multiple times on the same object.
+void JSArray::finalize(JSCell* cell)
{
- jsCast<JSArray*>(cell)->JSArray::~JSArray();
+ JSArray* thisObject = jsCast<JSArray*>(cell);
+ thisObject->checkConsistency(DestructorConsistencyCheck);
+ thisObject->deallocateSparseMap();
}
inline std::pair<SparseArrayValueMap::iterator, bool> SparseArrayValueMap::add(JSArray* array, unsigned i)
@@ -229,7 +224,7 @@ inline void SparseArrayValueMap::put(ExecState* exec, JSArray* array, unsigned i
{
SparseArrayEntry& entry = add(array, i).first->second;
- if (!(entry.attributes & (Getter | Setter))) {
+ if (!(entry.attributes & Accessor)) {
if (entry.attributes & ReadOnly) {
// FIXME: should throw if being called from strict mode.
// throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
@@ -310,13 +305,27 @@ inline void SparseArrayValueMap::visitChildren(SlotVisitor& visitor)
visitor.append(&it->second);
}
-void JSArray::enterSparseMode(JSGlobalData& globalData)
+void JSArray::allocateSparseMap(JSGlobalData& globalData)
+{
+ m_sparseValueMap = new SparseArrayValueMap;
+ globalData.heap.addFinalizer(this, finalize);
+}
+
+void JSArray::deallocateSparseMap()
+{
+ delete m_sparseValueMap;
+ m_sparseValueMap = 0;
+}
+
+void JSArray::enterDictionaryMode(JSGlobalData& globalData)
{
ArrayStorage* storage = m_storage;
- SparseArrayValueMap* map = storage->m_sparseValueMap;
+ SparseArrayValueMap* map = m_sparseValueMap;
- if (!map)
- map = storage->m_sparseValueMap = new SparseArrayValueMap;
+ if (!map) {
+ allocateSparseMap(globalData);
+ map = m_sparseValueMap;
+ }
if (map->sparseMode())
return;
@@ -332,10 +341,13 @@ void JSArray::enterSparseMode(JSGlobalData& globalData)
map->add(this, i).first->second.set(globalData, this, value);
}
- ArrayStorage* newStorage = static_cast<ArrayStorage*>(fastMalloc(storageSize(0)));
+ void* newRawStorage = 0;
+ if (!globalData.heap.tryAllocateStorage(storageSize(0), &newRawStorage))
+ CRASH();
+
+ ArrayStorage* newStorage = static_cast<ArrayStorage*>(newRawStorage);
memcpy(newStorage, m_storage, storageSize(0));
newStorage->m_allocBase = newStorage;
- fastFree(m_storage);
m_storage = newStorage;
m_indexBias = 0;
m_vectorLength = 0;
@@ -348,25 +360,21 @@ void JSArray::putDescriptor(ExecState* exec, SparseArrayEntry* entryInMap, Prope
entryInMap->set(exec->globalData(), this, descriptor.value());
else if (oldDescriptor.isAccessorDescriptor())
entryInMap->set(exec->globalData(), this, jsUndefined());
- entryInMap->attributes = descriptor.attributesOverridingCurrent(oldDescriptor) & ~(Getter | Setter);
+ entryInMap->attributes = descriptor.attributesOverridingCurrent(oldDescriptor) & ~Accessor;
return;
}
if (descriptor.isAccessorDescriptor()) {
JSObject* getter = 0;
- if (descriptor.getter() && descriptor.getter().isObject())
- getter = asObject(descriptor.getter());
- if (!getter && oldDescriptor.isAccessorDescriptor()) {
- if (oldDescriptor.getter() && oldDescriptor.getter().isObject())
- getter = asObject(oldDescriptor.getter());
- }
+ if (descriptor.getterPresent())
+ getter = descriptor.getterObject();
+ else if (oldDescriptor.isAccessorDescriptor())
+ getter = oldDescriptor.getterObject();
JSObject* setter = 0;
- if (descriptor.setter() && descriptor.setter().isObject())
- setter = asObject(descriptor.setter());
- if (!setter && oldDescriptor.isAccessorDescriptor()) {
- if (oldDescriptor.setter() && oldDescriptor.setter().isObject())
- setter = asObject(oldDescriptor.setter());
- }
+ if (descriptor.setterPresent())
+ setter = descriptor.setterObject();
+ else if (oldDescriptor.isAccessorDescriptor())
+ setter = oldDescriptor.setterObject();
GetterSetter* accessor = GetterSetter::create(exec);
if (getter)
@@ -406,10 +414,10 @@ bool JSArray::defineOwnNumericProperty(ExecState* exec, unsigned index, Property
return true;
}
- enterSparseMode(exec->globalData());
+ enterDictionaryMode(exec->globalData());
}
- SparseArrayValueMap* map = m_storage->m_sparseValueMap;
+ SparseArrayValueMap* map = m_sparseValueMap;
ASSERT(map);
// 1. Let current be the result of calling the [[GetOwnProperty]] internal method of O with property name P.
@@ -491,6 +499,7 @@ bool JSArray::defineOwnNumericProperty(ExecState* exec, unsigned index, Property
}
// 10.b. else, the [[Configurable]] field of current is true, so any change is acceptable.
} else {
+ ASSERT(current.isAccessorDescriptor() && current.getterPresent() && current.setterPresent());
// 11. Else, IsAccessorDescriptor(current) and IsAccessorDescriptor(Desc) are both true so, if the [[Configurable]] field of current is false, then
if (!current.configurable()) {
// 11.i. Reject, if the [[Set]] field of Desc is present and SameValue(Desc.[[Set]], current.[[Set]]) is false.
@@ -515,9 +524,9 @@ void JSArray::setLengthWritable(ExecState* exec, bool writable)
if (!isLengthWritable() || writable)
return;
- enterSparseMode(exec->globalData());
+ enterDictionaryMode(exec->globalData());
- SparseArrayValueMap* map = m_storage->m_sparseValueMap;
+ SparseArrayValueMap* map = m_sparseValueMap;
ASSERT(map);
map->setLengthIsReadOnly();
}
@@ -531,10 +540,10 @@ bool JSArray::defineOwnProperty(JSObject* object, ExecState* exec, const Identif
if (propertyName == exec->propertyNames().length) {
// All paths through length definition call the default [[DefineOwnProperty]], hence:
// from ES5.1 8.12.9 7.a.
- if (descriptor.configurable())
+ if (descriptor.configurablePresent() && descriptor.configurable())
return reject(exec, throwException, "Attempting to change configurable attribute of unconfigurable property.");
// from ES5.1 8.12.9 7.b.
- if (descriptor.enumerable())
+ if (descriptor.enumerablePresent() && descriptor.enumerable())
return reject(exec, throwException, "Attempting to change enumerable attribute of unconfigurable property.");
// a. If the [[Value]] field of Desc is absent, then
@@ -542,11 +551,12 @@ bool JSArray::defineOwnProperty(JSObject* object, ExecState* exec, const Identif
if (descriptor.isAccessorDescriptor())
return reject(exec, throwException, "Attempting to change access mechanism for an unconfigurable property.");
// from ES5.1 8.12.9 10.a.
- if (!array->isLengthWritable() && descriptor.writable())
+ if (!array->isLengthWritable() && descriptor.writablePresent() && descriptor.writable())
return reject(exec, throwException, "Attempting to change writable attribute of unconfigurable property.");
// This descriptor is either just making length read-only, or changing nothing!
if (!descriptor.value()) {
- array->setLengthWritable(exec, descriptor.writable());
+ if (descriptor.writablePresent())
+ array->setLengthWritable(exec, descriptor.writable());
return true;
}
@@ -561,7 +571,8 @@ bool JSArray::defineOwnProperty(JSObject* object, ExecState* exec, const Identif
// Based on SameValue check in 8.12.9, this is always okay.
if (newLen == array->length()) {
- array->setLengthWritable(exec, descriptor.writable());
+ if (descriptor.writablePresent())
+ array->setLengthWritable(exec, descriptor.writable());
return true;
}
@@ -588,13 +599,17 @@ bool JSArray::defineOwnProperty(JSObject* object, ExecState* exec, const Identif
// 2. If newWritable is false, set newLenDesc.[[Writable] to false.
// 3. Call the default [[DefineOwnProperty]] internal method (8.12.9) on A passing "length", newLenDesc, and false as arguments.
// 4. Reject.
- array->setLengthWritable(exec, descriptor.writable());
+ if (descriptor.writablePresent())
+ array->setLengthWritable(exec, descriptor.writable());
return false;
}
// m. If newWritable is false, then
- // i. Call the default [[DefineOwnProperty]] internal method (8.12.9) on A passing "length", Property Descriptor{[[Writable]]: false}, and false as arguments. This call will always return true.
- array->setLengthWritable(exec, descriptor.writable());
+ // i. Call the default [[DefineOwnProperty]] internal method (8.12.9) on A passing "length",
+ // Property Descriptor{[[Writable]]: false}, and false as arguments. This call will always
+ // return true.
+ if (descriptor.writablePresent())
+ array->setLengthWritable(exec, descriptor.writable());
// n. Return true.
return true;
}
@@ -623,7 +638,7 @@ bool JSArray::getOwnPropertySlotByIndex(JSCell* cell, ExecState* exec, unsigned
{
JSArray* thisObject = jsCast<JSArray*>(cell);
ArrayStorage* storage = thisObject->m_storage;
-
+
if (i >= storage->m_length) {
if (i > MAX_ARRAY_INDEX)
return thisObject->methodTable()->getOwnPropertySlot(thisObject, exec, Identifier::from(exec, i), slot);
@@ -636,7 +651,7 @@ bool JSArray::getOwnPropertySlotByIndex(JSCell* cell, ExecState* exec, unsigned
slot.setValue(value);
return true;
}
- } else if (SparseArrayValueMap* map = storage->m_sparseValueMap) {
+ } else if (SparseArrayValueMap* map = thisObject->m_sparseValueMap) {
SparseArrayValueMap::iterator it = map->find(i);
if (it != map->notFound()) {
it->second.get(slot);
@@ -684,7 +699,7 @@ bool JSArray::getOwnPropertyDescriptor(JSObject* object, ExecState* exec, const
descriptor.setDescriptor(value.get(), 0);
return true;
}
- } else if (SparseArrayValueMap* map = storage->m_sparseValueMap) {
+ } else if (SparseArrayValueMap* map = thisObject->m_sparseValueMap) {
SparseArrayValueMap::iterator it = map->find(i);
if (it != map->notFound()) {
it->second.get(descriptor);
@@ -765,7 +780,7 @@ NEVER_INLINE void JSArray::putByIndexBeyondVectorLength(ExecState* exec, unsigne
ASSERT(i <= MAX_ARRAY_INDEX);
ArrayStorage* storage = m_storage;
- SparseArrayValueMap* map = storage->m_sparseValueMap;
+ SparseArrayValueMap* map = m_sparseValueMap;
// First, handle cases where we don't currently have a sparse map.
if (LIKELY(!map)) {
@@ -774,7 +789,7 @@ NEVER_INLINE void JSArray::putByIndexBeyondVectorLength(ExecState* exec, unsigne
storage->m_length = i + 1;
// Check that it is sensible to still be using a vector, and then try to grow the vector.
- if (LIKELY((isDenseEnoughForVector(i, storage->m_numValuesInVector)) && increaseVectorLength(i + 1))) {
+ if (LIKELY((isDenseEnoughForVector(i, storage->m_numValuesInVector)) && increaseVectorLength(globalData, i + 1))) {
// success! - reread m_storage since it has likely been reallocated, and store to the vector.
storage = m_storage;
storage->m_vector[i].set(globalData, this, value);
@@ -782,8 +797,8 @@ NEVER_INLINE void JSArray::putByIndexBeyondVectorLength(ExecState* exec, unsigne
return;
}
// We don't want to, or can't use a vector to hold this property - allocate a sparse map & add the value.
- map = new SparseArrayValueMap;
- storage->m_sparseValueMap = map;
+ allocateSparseMap(exec->globalData());
+ map = m_sparseValueMap;
map->put(exec, this, i, value);
return;
}
@@ -803,7 +818,7 @@ NEVER_INLINE void JSArray::putByIndexBeyondVectorLength(ExecState* exec, unsigne
// We are currently using a map - check whether we still want to be doing so.
// We will continue to use a sparse map if SparseMode is set, a vector would be too sparse, or if allocation fails.
unsigned numValuesInArray = storage->m_numValuesInVector + map->size();
- if (map->sparseMode() || !isDenseEnoughForVector(length, numValuesInArray) || !increaseVectorLength(length)) {
+ if (map->sparseMode() || !isDenseEnoughForVector(length, numValuesInArray) || !increaseVectorLength(exec->globalData(), length)) {
map->put(exec, this, i, value);
return;
}
@@ -817,8 +832,7 @@ NEVER_INLINE void JSArray::putByIndexBeyondVectorLength(ExecState* exec, unsigne
SparseArrayValueMap::const_iterator end = map->end();
for (SparseArrayValueMap::const_iterator it = map->begin(); it != end; ++it)
vector[it->first].set(globalData, this, it->second.getNonSparseMode());
- delete map;
- storage->m_sparseValueMap = 0;
+ deallocateSparseMap();
// Store the new property into the vector.
WriteBarrier<Unknown>& valueSlot = vector[i];
@@ -857,7 +871,7 @@ bool JSArray::deletePropertyByIndex(JSCell* cell, ExecState* exec, unsigned i)
valueSlot.clear();
--storage->m_numValuesInVector;
}
- } else if (SparseArrayValueMap* map = storage->m_sparseValueMap) {
+ } else if (SparseArrayValueMap* map = thisObject->m_sparseValueMap) {
SparseArrayValueMap::iterator it = map->find(i);
if (it != map->notFound()) {
if (it->second.attributes & DontDelete)
@@ -892,7 +906,7 @@ void JSArray::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNam
propertyNames.add(Identifier::from(exec, i));
}
- if (SparseArrayValueMap* map = storage->m_sparseValueMap) {
+ if (SparseArrayValueMap* map = thisObject->m_sparseValueMap) {
Vector<unsigned> keys;
keys.reserveCapacity(map->size());
@@ -940,7 +954,7 @@ ALWAYS_INLINE unsigned JSArray::getNewVectorLength(unsigned desiredLength)
return min(increasedLength, MAX_STORAGE_VECTOR_LENGTH);
}
-bool JSArray::increaseVectorLength(unsigned newLength)
+bool JSArray::increaseVectorLength(JSGlobalData& globalData, unsigned newLength)
{
// This function leaves the array in an internally inconsistent state, because it does not move any values from sparse value map
// to the vector. Callers have to account for that, because they can do it more efficiently.
@@ -952,15 +966,16 @@ bool JSArray::increaseVectorLength(unsigned newLength)
unsigned vectorLength = m_vectorLength;
ASSERT(newLength > vectorLength);
unsigned newVectorLength = getNewVectorLength(newLength);
- void* baseStorage = storage->m_allocBase;
// Fast case - there is no precapacity. In these cases a realloc makes sense.
if (LIKELY(!m_indexBias)) {
- if (!tryFastRealloc(baseStorage, storageSize(newVectorLength)).getValue(baseStorage))
+ void* newStorage = storage->m_allocBase;
+ if (!globalData.heap.tryReallocateStorage(&newStorage, storageSize(vectorLength), storageSize(newVectorLength)))
return false;
- storage = m_storage = reinterpret_cast_ptr<ArrayStorage*>(baseStorage);
- m_storage->m_allocBase = baseStorage;
+ storage = m_storage = reinterpret_cast_ptr<ArrayStorage*>(static_cast<char*>(newStorage));
+ m_storage->m_allocBase = newStorage;
+ ASSERT(m_storage->m_allocBase);
WriteBarrier<Unknown>* vector = storage->m_vector;
for (unsigned i = vectorLength; i < newVectorLength; ++i)
@@ -968,7 +983,6 @@ bool JSArray::increaseVectorLength(unsigned newLength)
m_vectorLength = newVectorLength;
- Heap::heap(this)->reportExtraMemoryCost(storageSize(newVectorLength) - storageSize(vectorLength));
return true;
}
@@ -976,15 +990,11 @@ bool JSArray::increaseVectorLength(unsigned newLength)
unsigned newIndexBias = min(m_indexBias >> 1, MAX_STORAGE_VECTOR_LENGTH - newVectorLength);
// Calculate new stoarge capcity, allowing room for the pre-capacity.
unsigned newStorageCapacity = newVectorLength + newIndexBias;
- void* newAllocBase;
- if (!tryFastMalloc(storageSize(newStorageCapacity)).getValue(newAllocBase))
+ void* newAllocBase = 0;
+ if (!globalData.heap.tryAllocateStorage(storageSize(newStorageCapacity), &newAllocBase))
return false;
// The sum of m_vectorLength and m_indexBias will never exceed MAX_STORAGE_VECTOR_LENGTH.
ASSERT(m_vectorLength <= MAX_STORAGE_VECTOR_LENGTH && (MAX_STORAGE_VECTOR_LENGTH - m_vectorLength) >= m_indexBias);
- unsigned currentCapacity = m_vectorLength + m_indexBias;
- // Currently there is no way to report to the heap that the extra capacity is shrinking!
- if (newStorageCapacity > currentCapacity)
- Heap::heap(this)->reportExtraMemoryCost((newStorageCapacity - currentCapacity) * sizeof(WriteBarrier<Unknown>));
m_vectorLength = newVectorLength;
m_indexBias = newIndexBias;
@@ -996,14 +1006,13 @@ bool JSArray::increaseVectorLength(unsigned newLength)
m_storage->m_vector[i].clear();
// Free the old allocation, update m_allocBase.
- fastFree(m_storage->m_allocBase);
m_storage->m_allocBase = newAllocBase;
return true;
}
// This method makes room in the vector, but leaves the new space uncleared.
-bool JSArray::unshiftCountSlowCase(unsigned count)
+bool JSArray::unshiftCountSlowCase(JSGlobalData& globalData, unsigned count)
{
// If not, we should have handled this on the fast path.
ASSERT(count > m_indexBias);
@@ -1034,19 +1043,16 @@ bool JSArray::unshiftCountSlowCase(unsigned count)
// Step 2:
// We're either going to choose to allocate a new ArrayStorage, or we're going to reuse the existing on.
- void* newAllocBase;
+ void* newAllocBase = 0;
unsigned newStorageCapacity;
// If the current storage array is sufficiently large (but not too large!) then just keep using it.
if (currentCapacity > desiredCapacity && isDenseEnoughForVector(currentCapacity, requiredVectorLength)) {
newAllocBase = storage->m_allocBase;
newStorageCapacity = currentCapacity;
} else {
- if (!tryFastMalloc(storageSize(desiredCapacity)).getValue(newAllocBase))
+ if (!globalData.heap.tryAllocateStorage(storageSize(desiredCapacity), &newAllocBase))
return false;
newStorageCapacity = desiredCapacity;
- // Currently there is no way to report to the heap that the extra capacity is shrinking!
- if (desiredCapacity > currentCapacity)
- Heap::heap(this)->reportExtraMemoryCost((desiredCapacity - currentCapacity) * sizeof(WriteBarrier<Unknown>));
}
// Step 3:
@@ -1079,7 +1085,6 @@ bool JSArray::unshiftCountSlowCase(unsigned count)
// Are we copying into a new allocation?
if (newAllocBase != m_storage->m_allocBase) {
// Free the old allocation, update m_allocBase.
- fastFree(m_storage->m_allocBase);
m_storage->m_allocBase = newAllocBase;
// We need to clear any entries in the vector beyond length. We only need to
@@ -1101,9 +1106,9 @@ bool JSArray::setLength(ExecState* exec, unsigned newLength, bool throwException
unsigned length = storage->m_length;
// If the length is read only then we enter sparse mode, so should enter the following 'if'.
- ASSERT(isLengthWritable() || storage->m_sparseValueMap);
+ ASSERT(isLengthWritable() || m_sparseValueMap);
- if (SparseArrayValueMap* map = storage->m_sparseValueMap) {
+ if (SparseArrayValueMap* map = m_sparseValueMap) {
// Fail if the length is not writable.
if (map->lengthIsReadOnly())
return reject(exec, throwException, StrictModeReadonlyPropertyWriteError);
@@ -1138,10 +1143,8 @@ bool JSArray::setLength(ExecState* exec, unsigned newLength, bool throwException
} else {
for (unsigned i = 0; i < keys.size(); ++i)
map->remove(keys[i]);
- if (map->isEmpty()) {
- delete map;
- storage->m_sparseValueMap = 0;
- }
+ if (map->isEmpty())
+ deallocateSparseMap();
}
}
}
@@ -1190,7 +1193,7 @@ JSValue JSArray::pop(ExecState* exec)
result = jsUndefined();
} else {
result = jsUndefined();
- if (SparseArrayValueMap* map = storage->m_sparseValueMap) {
+ if (SparseArrayValueMap* map = m_sparseValueMap) {
SparseArrayValueMap::iterator it = map->find(length);
if (it != map->notFound()) {
unsigned attributes = it->second.attributes;
@@ -1206,10 +1209,8 @@ JSValue JSArray::pop(ExecState* exec)
}
map->remove(it);
- if (map->isEmpty() && !map->sparseMode()) {
- delete map;
- storage->m_sparseValueMap = 0;
- }
+ if (map->isEmpty() && !map->sparseMode())
+ deallocateSparseMap();
}
}
}
@@ -1331,7 +1332,7 @@ void JSArray::unshiftCount(ExecState* exec, unsigned count)
memmove(newBaseStorage, storage, storageSize(0));
m_storage = reinterpret_cast_ptr<ArrayStorage*>(newBaseStorage);
m_vectorLength += count;
- } else if (!unshiftCountSlowCase(count)) {
+ } else if (!unshiftCountSlowCase(exec->globalData(), count)) {
throwOutOfMemoryError(exec);
return;
}
@@ -1349,13 +1350,21 @@ void JSArray::visitChildren(JSCell* cell, SlotVisitor& visitor)
ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
JSNonFinalObject::visitChildren(thisObject, visitor);
-
- ArrayStorage* storage = thisObject->m_storage;
- unsigned usedVectorLength = std::min(storage->m_length, thisObject->m_vectorLength);
- visitor.appendValues(storage->m_vector, usedVectorLength);
+ if (thisObject->m_storage) {
+ ArrayStorage* storage = thisObject->m_storage;
+ void* baseStorage = storage->m_allocBase;
+
+ visitor.copyAndAppend(reinterpret_cast<void**>(&baseStorage), storageSize(thisObject->m_vectorLength + thisObject->m_indexBias), storage->m_vector->slot(), thisObject->m_vectorLength);
+
+ if (baseStorage != thisObject->m_storage->m_allocBase) {
+ thisObject->m_storage = reinterpret_cast<ArrayStorage*>(static_cast<char*>(baseStorage) + sizeof(JSValue) * thisObject->m_indexBias);
+ thisObject->m_storage->m_allocBase = baseStorage;
+ ASSERT(thisObject->m_storage->m_allocBase);
+ }
+ }
- if (SparseArrayValueMap* map = storage->m_sparseValueMap)
+ if (SparseArrayValueMap* map = thisObject->m_sparseValueMap)
map->visitChildren(visitor);
}
@@ -1379,8 +1388,8 @@ void JSArray::sortNumeric(ExecState* exec, JSValue compareFunction, CallType cal
ArrayStorage* storage = m_storage;
- unsigned lengthNotIncludingUndefined = compactForSorting();
- if (storage->m_sparseValueMap) {
+ unsigned lengthNotIncludingUndefined = compactForSorting(exec->globalData());
+ if (m_sparseValueMap) {
throwOutOfMemoryError(exec);
return;
}
@@ -1412,10 +1421,8 @@ void JSArray::sort(ExecState* exec)
{
ASSERT(!inSparseMode());
- ArrayStorage* storage = m_storage;
-
- unsigned lengthNotIncludingUndefined = compactForSorting();
- if (storage->m_sparseValueMap) {
+ unsigned lengthNotIncludingUndefined = compactForSorting(exec->globalData());
+ if (m_sparseValueMap) {
throwOutOfMemoryError(exec);
return;
}
@@ -1437,7 +1444,7 @@ void JSArray::sort(ExecState* exec)
Heap::heap(this)->pushTempSortVector(&values);
for (size_t i = 0; i < lengthNotIncludingUndefined; i++) {
- JSValue value = storage->m_vector[i].get();
+ JSValue value = m_storage->m_vector[i].get();
ASSERT(!value.isUndefined());
values[i].first = value;
}
@@ -1446,7 +1453,7 @@ void JSArray::sort(ExecState* exec)
// a toString call raises an exception.
for (size_t i = 0; i < lengthNotIncludingUndefined; i++)
- values[i].second = values[i].first.toString(exec);
+ values[i].second = values[i].first.toString(exec)->value(exec);
if (exec->hadException()) {
Heap::heap(this)->popTempSortVector(&values);
@@ -1467,13 +1474,13 @@ void JSArray::sort(ExecState* exec)
// If the toString function changed the length of the array or vector storage,
// increase the length to handle the orignal number of actual values.
if (m_vectorLength < lengthNotIncludingUndefined)
- increaseVectorLength(lengthNotIncludingUndefined);
- if (storage->m_length < lengthNotIncludingUndefined)
- storage->m_length = lengthNotIncludingUndefined;
+ increaseVectorLength(exec->globalData(), lengthNotIncludingUndefined);
+ if (m_storage->m_length < lengthNotIncludingUndefined)
+ m_storage->m_length = lengthNotIncludingUndefined;
JSGlobalData& globalData = exec->globalData();
for (size_t i = 0; i < lengthNotIncludingUndefined; i++)
- storage->m_vector[i].set(globalData, this, values[i].first);
+ m_storage->m_vector[i].set(globalData, this, values[i].first);
Heap::heap(this)->popTempSortVector(&values);
@@ -1563,18 +1570,16 @@ void JSArray::sort(ExecState* exec, JSValue compareFunction, CallType callType,
checkConsistency();
- ArrayStorage* storage = m_storage;
-
// FIXME: This ignores exceptions raised in the compare function or in toNumber.
// The maximum tree depth is compiled in - but the caller is clearly up to no good
// if a larger array is passed.
- ASSERT(storage->m_length <= static_cast<unsigned>(std::numeric_limits<int>::max()));
- if (storage->m_length > static_cast<unsigned>(std::numeric_limits<int>::max()))
+ ASSERT(m_storage->m_length <= static_cast<unsigned>(std::numeric_limits<int>::max()));
+ if (m_storage->m_length > static_cast<unsigned>(std::numeric_limits<int>::max()))
return;
- unsigned usedVectorLength = min(storage->m_length, m_vectorLength);
- unsigned nodeCount = usedVectorLength + (storage->m_sparseValueMap ? storage->m_sparseValueMap->size() : 0);
+ unsigned usedVectorLength = min(m_storage->m_length, m_vectorLength);
+ unsigned nodeCount = usedVectorLength + (m_sparseValueMap ? m_sparseValueMap->size() : 0);
if (!nodeCount)
return;
@@ -1602,14 +1607,14 @@ void JSArray::sort(ExecState* exec, JSValue compareFunction, CallType callType,
// Iterate over the array, ignoring missing values, counting undefined ones, and inserting all other ones into the tree.
for (; numDefined < usedVectorLength; ++numDefined) {
- JSValue v = storage->m_vector[numDefined].get();
+ JSValue v = m_storage->m_vector[numDefined].get();
if (!v || v.isUndefined())
break;
tree.abstractor().m_nodes[numDefined].value = v;
tree.insert(numDefined);
}
for (unsigned i = numDefined; i < usedVectorLength; ++i) {
- JSValue v = storage->m_vector[i].get();
+ JSValue v = m_storage->m_vector[i].get();
if (v) {
if (v.isUndefined())
++numUndefined;
@@ -1623,17 +1628,15 @@ void JSArray::sort(ExecState* exec, JSValue compareFunction, CallType callType,
unsigned newUsedVectorLength = numDefined + numUndefined;
- if (SparseArrayValueMap* map = storage->m_sparseValueMap) {
+ if (SparseArrayValueMap* map = m_sparseValueMap) {
newUsedVectorLength += map->size();
if (newUsedVectorLength > m_vectorLength) {
// Check that it is possible to allocate an array large enough to hold all the entries.
- if ((newUsedVectorLength > MAX_STORAGE_VECTOR_LENGTH) || !increaseVectorLength(newUsedVectorLength)) {
+ if ((newUsedVectorLength > MAX_STORAGE_VECTOR_LENGTH) || !increaseVectorLength(exec->globalData(), newUsedVectorLength)) {
throwOutOfMemoryError(exec);
return;
}
}
-
- storage = m_storage;
SparseArrayValueMap::const_iterator end = map->end();
for (SparseArrayValueMap::const_iterator it = map->begin(); it != end; ++it) {
@@ -1642,8 +1645,7 @@ void JSArray::sort(ExecState* exec, JSValue compareFunction, CallType callType,
++numDefined;
}
- delete map;
- storage->m_sparseValueMap = 0;
+ deallocateSparseMap();
}
ASSERT(tree.abstractor().m_nodes.size() >= numDefined);
@@ -1656,19 +1658,19 @@ void JSArray::sort(ExecState* exec, JSValue compareFunction, CallType callType,
iter.start_iter_least(tree);
JSGlobalData& globalData = exec->globalData();
for (unsigned i = 0; i < numDefined; ++i) {
- storage->m_vector[i].set(globalData, this, tree.abstractor().m_nodes[*iter].value);
+ m_storage->m_vector[i].set(globalData, this, tree.abstractor().m_nodes[*iter].value);
++iter;
}
// Put undefined values back in.
for (unsigned i = numDefined; i < newUsedVectorLength; ++i)
- storage->m_vector[i].setUndefined();
+ m_storage->m_vector[i].setUndefined();
// Ensure that unused values in the vector are zeroed out.
for (unsigned i = newUsedVectorLength; i < usedVectorLength; ++i)
- storage->m_vector[i].clear();
+ m_storage->m_vector[i].clear();
- storage->m_numValuesInVector = newUsedVectorLength;
+ m_storage->m_numValuesInVector = newUsedVectorLength;
checkConsistency(SortConsistencyCheck);
}
@@ -1709,7 +1711,7 @@ void JSArray::copyToArguments(ExecState* exec, CallFrame* callFrame, uint32_t le
callFrame->setArgument(i, get(exec, i));
}
-unsigned JSArray::compactForSorting()
+unsigned JSArray::compactForSorting(JSGlobalData& globalData)
{
ASSERT(!inSparseMode());
@@ -1740,12 +1742,12 @@ unsigned JSArray::compactForSorting()
unsigned newUsedVectorLength = numDefined + numUndefined;
- if (SparseArrayValueMap* map = storage->m_sparseValueMap) {
+ if (SparseArrayValueMap* map = m_sparseValueMap) {
newUsedVectorLength += map->size();
if (newUsedVectorLength > m_vectorLength) {
// Check that it is possible to allocate an array large enough to hold all the entries - if not,
// exception is thrown by caller.
- if ((newUsedVectorLength > MAX_STORAGE_VECTOR_LENGTH) || !increaseVectorLength(newUsedVectorLength))
+ if ((newUsedVectorLength > MAX_STORAGE_VECTOR_LENGTH) || !increaseVectorLength(globalData, newUsedVectorLength))
return 0;
storage = m_storage;
@@ -1755,8 +1757,7 @@ unsigned JSArray::compactForSorting()
for (SparseArrayValueMap::const_iterator it = map->begin(); it != end; ++it)
storage->m_vector[numDefined++].setWithoutWriteBarrier(it->second.getNonSparseMode());
- delete map;
- storage->m_sparseValueMap = 0;
+ deallocateSparseMap();
}
for (unsigned i = numDefined; i < newUsedVectorLength; ++i)
@@ -1773,12 +1774,12 @@ unsigned JSArray::compactForSorting()
void* JSArray::subclassData() const
{
- return m_storage->subclassData;
+ return m_subclassData;
}
void JSArray::setSubclassData(void* d)
{
- m_storage->subclassData = d;
+ m_subclassData = d;
}
#if CHECK_ARRAY_CONSISTENCY
@@ -1791,7 +1792,7 @@ void JSArray::checkConsistency(ConsistencyCheckType type)
ASSERT(storage);
if (type == SortConsistencyCheck)
- ASSERT(!storage->m_sparseValueMap);
+ ASSERT(!m_sparseValueMap);
unsigned numValuesInVector = 0;
for (unsigned i = 0; i < m_vectorLength; ++i) {
@@ -1808,9 +1809,9 @@ void JSArray::checkConsistency(ConsistencyCheckType type)
ASSERT(numValuesInVector == storage->m_numValuesInVector);
ASSERT(numValuesInVector <= storage->m_length);
- if (storage->m_sparseValueMap) {
- SparseArrayValueMap::iterator end = storage->m_sparseValueMap->end();
- for (SparseArrayValueMap::iterator it = storage->m_sparseValueMap->begin(); it != end; ++it) {
+ if (m_sparseValueMap) {
+ SparseArrayValueMap::iterator end = m_sparseValueMap->end();
+ for (SparseArrayValueMap::iterator it = m_sparseValueMap->begin(); it != end; ++it) {
unsigned index = it->first;
ASSERT(index < storage->m_length);
ASSERT(index >= storage->m_vectorLength);
diff --git a/Source/JavaScriptCore/runtime/JSArray.h b/Source/JavaScriptCore/runtime/JSArray.h
index 871cfc882..a3354c602 100644
--- a/Source/JavaScriptCore/runtime/JSArray.h
+++ b/Source/JavaScriptCore/runtime/JSArray.h
@@ -114,8 +114,6 @@ namespace JSC {
struct ArrayStorage {
unsigned m_length; // The "length" property on the array
unsigned m_numValuesInVector;
- SparseArrayValueMap* m_sparseValueMap;
- void* subclassData; // A JSArray subclass can use this to fill the vector lazily.
void* m_allocBase; // Pointer to base address returned by malloc(). Keeping this pointer does eliminate false positives from the leak detector.
#if CHECK_ARRAY_CONSISTENCY
bool m_inCompactInitialization;
@@ -127,16 +125,15 @@ namespace JSC {
friend class Walker;
protected:
- explicit JSArray(JSGlobalData&, Structure*);
+ JS_EXPORT_PRIVATE explicit JSArray(JSGlobalData&, Structure*);
- void finishCreation(JSGlobalData&, unsigned initialLength = 0);
- JSArray* tryFinishCreationUninitialized(JSGlobalData&, unsigned initialLength);
+ JS_EXPORT_PRIVATE void finishCreation(JSGlobalData&, unsigned initialLength = 0);
+ JS_EXPORT_PRIVATE JSArray* tryFinishCreationUninitialized(JSGlobalData&, unsigned initialLength);
public:
typedef JSNonFinalObject Base;
- ~JSArray();
- static void destroy(JSCell*);
+ static void finalize(JSCell*);
static JSArray* create(JSGlobalData& globalData, Structure* structure, unsigned initialLength = 0)
{
@@ -156,10 +153,10 @@ namespace JSC {
return array->tryFinishCreationUninitialized(globalData, initialLength);
}
- static bool defineOwnProperty(JSObject*, ExecState*, const Identifier&, PropertyDescriptor&, bool throwException);
+ JS_EXPORT_PRIVATE static bool defineOwnProperty(JSObject*, ExecState*, const Identifier&, PropertyDescriptor&, bool throwException);
static bool getOwnPropertySlot(JSCell*, ExecState*, const Identifier&, PropertySlot&);
- static bool getOwnPropertySlotByIndex(JSCell*, ExecState*, unsigned propertyName, PropertySlot&);
+ JS_EXPORT_PRIVATE static bool getOwnPropertySlotByIndex(JSCell*, ExecState*, unsigned propertyName, PropertySlot&);
static bool getOwnPropertyDescriptor(JSObject*, ExecState*, const Identifier&, PropertyDescriptor&);
static void putByIndex(JSCell*, ExecState*, unsigned propertyName, JSValue);
@@ -232,7 +229,7 @@ namespace JSC {
bool inSparseMode()
{
- SparseArrayValueMap* map = m_storage->m_sparseValueMap;
+ SparseArrayValueMap* map = m_sparseValueMap;
return map && map->sparseMode();
}
@@ -254,7 +251,7 @@ namespace JSC {
return OBJECT_OFFSETOF(JSArray, m_vectorLength);
}
- static void visitChildren(JSCell*, SlotVisitor&);
+ JS_EXPORT_PRIVATE static void visitChildren(JSCell*, SlotVisitor&);
protected:
static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesVisitChildren | OverridesGetPropertyNames | JSObject::StructureFlags;
@@ -264,29 +261,31 @@ namespace JSC {
static bool deletePropertyByIndex(JSCell*, ExecState*, unsigned propertyName);
static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
- void* subclassData() const;
- void setSubclassData(void*);
+ JS_EXPORT_PRIVATE void* subclassData() const;
+ JS_EXPORT_PRIVATE void setSubclassData(void*);
private:
bool isLengthWritable()
{
- SparseArrayValueMap* map = m_storage->m_sparseValueMap;
+ SparseArrayValueMap* map = m_sparseValueMap;
return !map || !map->lengthIsReadOnly();
}
void setLengthWritable(ExecState*, bool writable);
void putDescriptor(ExecState*, SparseArrayEntry*, PropertyDescriptor&, PropertyDescriptor& old);
bool defineOwnNumericProperty(ExecState*, unsigned, PropertyDescriptor&, bool throwException);
- void enterSparseMode(JSGlobalData&);
+ void enterDictionaryMode(JSGlobalData&);
+ void allocateSparseMap(JSGlobalData&);
+ void deallocateSparseMap();
bool getOwnPropertySlotSlowCase(ExecState*, unsigned propertyName, PropertySlot&);
void putByIndexBeyondVectorLength(ExecState*, unsigned propertyName, JSValue);
unsigned getNewVectorLength(unsigned desiredLength);
- bool increaseVectorLength(unsigned newLength);
- bool unshiftCountSlowCase(unsigned count);
+ bool increaseVectorLength(JSGlobalData&, unsigned newLength);
+ bool unshiftCountSlowCase(JSGlobalData&, unsigned count);
- unsigned compactForSorting();
+ unsigned compactForSorting(JSGlobalData&);
enum ConsistencyCheckType { NormalConsistencyCheck, DestructorConsistencyCheck, SortConsistencyCheck };
void checkConsistency(ConsistencyCheckType = NormalConsistencyCheck);
@@ -294,6 +293,10 @@ namespace JSC {
unsigned m_vectorLength; // The valid length of m_vector
unsigned m_indexBias; // The number of JSValue sized blocks before ArrayStorage.
ArrayStorage *m_storage;
+
+ // FIXME: Maybe SparseArrayValueMap should be put into its own JSCell?
+ SparseArrayValueMap* m_sparseValueMap;
+ void* m_subclassData; // A JSArray subclass can use this to fill the vector lazily.
};
JSArray* asArray(JSValue);
diff --git a/Source/JavaScriptCore/runtime/JSBoundFunction.cpp b/Source/JavaScriptCore/runtime/JSBoundFunction.cpp
index 549b6034f..88260ea27 100644
--- a/Source/JavaScriptCore/runtime/JSBoundFunction.cpp
+++ b/Source/JavaScriptCore/runtime/JSBoundFunction.cpp
@@ -111,8 +111,8 @@ void JSBoundFunction::finishCreation(ExecState* exec, NativeExecutable* executab
Base::finishCreation(exec, executable, length, name);
ASSERT(inherits(&s_info));
- initializeGetterSetterProperty(exec, exec->propertyNames().arguments, globalObject()->throwTypeErrorGetterSetter(exec), DontDelete | DontEnum | Getter | Setter);
- initializeGetterSetterProperty(exec, exec->propertyNames().caller, globalObject()->throwTypeErrorGetterSetter(exec), DontDelete | DontEnum | Getter | Setter);
+ initializeGetterSetterProperty(exec, exec->propertyNames().arguments, globalObject()->throwTypeErrorGetterSetter(exec), DontDelete | DontEnum | Accessor);
+ initializeGetterSetterProperty(exec, exec->propertyNames().caller, globalObject()->throwTypeErrorGetterSetter(exec), DontDelete | DontEnum | Accessor);
}
void JSBoundFunction::visitChildren(JSCell* cell, SlotVisitor& visitor)
diff --git a/Source/JavaScriptCore/runtime/JSBoundFunction.h b/Source/JavaScriptCore/runtime/JSBoundFunction.h
index c60d7db01..e54d45883 100644
--- a/Source/JavaScriptCore/runtime/JSBoundFunction.h
+++ b/Source/JavaScriptCore/runtime/JSBoundFunction.h
@@ -51,7 +51,7 @@ public:
return Structure::create(globalData, globalObject, prototype, TypeInfo(JSFunctionType, StructureFlags), &s_info);
}
- static JS_EXPORTDATA const ClassInfo s_info;
+ static const ClassInfo s_info;
protected:
const static unsigned StructureFlags = OverridesHasInstance | OverridesVisitChildren | Base::StructureFlags;
diff --git a/Source/JavaScriptCore/runtime/JSByteArray.h b/Source/JavaScriptCore/runtime/JSByteArray.h
index 754774d3e..d1f4ad630 100644
--- a/Source/JavaScriptCore/runtime/JSByteArray.h
+++ b/Source/JavaScriptCore/runtime/JSByteArray.h
@@ -76,7 +76,7 @@ namespace JSC {
}
private:
- JSByteArray(ExecState*, Structure*, ByteArray* storage);
+ JS_EXPORT_PRIVATE JSByteArray(ExecState*, Structure*, ByteArray* storage);
public:
static JSByteArray* create(ExecState* exec, Structure* structure, ByteArray* storage)
@@ -86,15 +86,15 @@ namespace JSC {
return array;
}
- static Structure* createStructure(JSGlobalData&, JSGlobalObject*, JSValue prototype, const JSC::ClassInfo* = &s_info);
+ JS_EXPORT_PRIVATE static Structure* createStructure(JSGlobalData&, JSGlobalObject*, JSValue prototype, const JSC::ClassInfo* = &s_info);
- static bool getOwnPropertySlot(JSC::JSCell*, JSC::ExecState*, const JSC::Identifier& propertyName, JSC::PropertySlot&);
- static bool getOwnPropertySlotByIndex(JSC::JSCell*, JSC::ExecState*, unsigned propertyName, JSC::PropertySlot&);
- static bool getOwnPropertyDescriptor(JSObject*, ExecState*, const Identifier&, PropertyDescriptor&);
- static void put(JSC::JSCell*, JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSValue, JSC::PutPropertySlot&);
- static void putByIndex(JSC::JSCell*, JSC::ExecState*, unsigned propertyName, JSC::JSValue);
+ JS_EXPORT_PRIVATE static bool getOwnPropertySlot(JSC::JSCell*, JSC::ExecState*, const JSC::Identifier& propertyName, JSC::PropertySlot&);
+ JS_EXPORT_PRIVATE static bool getOwnPropertySlotByIndex(JSC::JSCell*, JSC::ExecState*, unsigned propertyName, JSC::PropertySlot&);
+ JS_EXPORT_PRIVATE static bool getOwnPropertyDescriptor(JSObject*, ExecState*, const Identifier&, PropertyDescriptor&);
+ JS_EXPORT_PRIVATE static void put(JSC::JSCell*, JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSValue, JSC::PutPropertySlot&);
+ JS_EXPORT_PRIVATE static void putByIndex(JSC::JSCell*, JSC::ExecState*, unsigned propertyName, JSC::JSValue);
- static void getOwnPropertyNames(JSC::JSObject*, JSC::ExecState*, JSC::PropertyNameArray&, EnumerationMode);
+ JS_EXPORT_PRIVATE static void getOwnPropertyNames(JSC::JSObject*, JSC::ExecState*, JSC::PropertyNameArray&, EnumerationMode);
static JS_EXPORTDATA const ClassInfo s_info;
@@ -103,7 +103,7 @@ namespace JSC {
WTF::ByteArray* storage() const { return m_storage.get(); }
~JSByteArray();
- static void destroy(JSCell*);
+ JS_EXPORT_PRIVATE static void destroy(JSCell*);
static size_t offsetOfStorage() { return OBJECT_OFFSETOF(JSByteArray, m_storage); }
diff --git a/Source/JavaScriptCore/runtime/JSCell.cpp b/Source/JavaScriptCore/runtime/JSCell.cpp
index 065fd13ea..9dcd6364b 100644
--- a/Source/JavaScriptCore/runtime/JSCell.cpp
+++ b/Source/JavaScriptCore/runtime/JSCell.cpp
@@ -145,13 +145,6 @@ double JSCell::toNumber(ExecState* exec) const
return static_cast<const JSObject*>(this)->toNumber(exec);
}
-UString JSCell::toString(ExecState* exec) const
-{
- if (isString())
- return static_cast<const JSString*>(this)->toString(exec);
- return static_cast<const JSObject*>(this)->toString(exec);
-}
-
JSObject* JSCell::toObject(ExecState* exec, JSGlobalObject* globalObject) const
{
if (isString())
@@ -203,7 +196,7 @@ bool JSCell::hasInstance(JSObject*, ExecState*, JSValue, JSValue)
return false;
}
-void JSCell::putWithAttributes(JSObject*, ExecState*, const Identifier&, JSValue, unsigned)
+void JSCell::putDirectVirtual(JSObject*, ExecState*, const Identifier&, JSValue, unsigned)
{
ASSERT_NOT_REACHED();
}
diff --git a/Source/JavaScriptCore/runtime/JSCell.h b/Source/JavaScriptCore/runtime/JSCell.h
index 47e336a86..a36bb7d58 100644
--- a/Source/JavaScriptCore/runtime/JSCell.h
+++ b/Source/JavaScriptCore/runtime/JSCell.h
@@ -51,6 +51,7 @@ namespace JSC {
TypedArrayInt16,
TypedArrayInt32,
TypedArrayUint8,
+ TypedArrayUint8Clamped,
TypedArrayUint16,
TypedArrayUint32,
TypedArrayFloat32,
@@ -67,7 +68,7 @@ namespace JSC {
protected:
JSCell(JSGlobalData&, Structure*);
- static void destroy(JSCell*);
+ JS_EXPORT_PRIVATE static void destroy(JSCell*);
public:
// Querying the type.
@@ -82,21 +83,20 @@ namespace JSC {
void clearStructure() { m_structure.clear(); }
// Extracting the value.
- bool getString(ExecState* exec, UString&) const;
- UString getString(ExecState* exec) const; // null string if not a string
- JSObject* getObject(); // NULL if not an object
+ JS_EXPORT_PRIVATE bool getString(ExecState* exec, UString&) const;
+ JS_EXPORT_PRIVATE UString getString(ExecState* exec) const; // null string if not a string
+ JS_EXPORT_PRIVATE JSObject* getObject(); // NULL if not an object
const JSObject* getObject() const; // NULL if not an object
- static CallType getCallData(JSCell*, CallData&);
- static ConstructType getConstructData(JSCell*, ConstructData&);
+ JS_EXPORT_PRIVATE static CallType getCallData(JSCell*, CallData&);
+ JS_EXPORT_PRIVATE static ConstructType getConstructData(JSCell*, ConstructData&);
// Basic conversions.
- JSValue toPrimitive(ExecState*, PreferredPrimitiveType) const;
+ JS_EXPORT_PRIVATE JSValue toPrimitive(ExecState*, PreferredPrimitiveType) const;
bool getPrimitiveNumber(ExecState*, double& number, JSValue&) const;
bool toBoolean(ExecState*) const;
- double toNumber(ExecState*) const;
- UString toString(ExecState*) const;
- JSObject* toObject(ExecState*, JSGlobalObject*) const;
+ JS_EXPORT_PRIVATE double toNumber(ExecState*) const;
+ JS_EXPORT_PRIVATE JSObject* toObject(ExecState*, JSGlobalObject*) const;
static void visitChildren(JSCell*, SlotVisitor&);
@@ -159,7 +159,7 @@ namespace JSC {
static NO_RETURN_DUE_TO_ASSERT void getPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
static UString className(const JSObject*);
static bool hasInstance(JSObject*, ExecState*, JSValue, JSValue prototypeProperty);
- static NO_RETURN_DUE_TO_ASSERT void putWithAttributes(JSObject*, ExecState*, const Identifier& propertyName, JSValue, unsigned attributes);
+ static NO_RETURN_DUE_TO_ASSERT void putDirectVirtual(JSObject*, ExecState*, const Identifier& propertyName, JSValue, unsigned attributes);
static bool defineOwnProperty(JSObject*, ExecState*, const Identifier& propertyName, PropertyDescriptor&, bool shouldThrow);
static bool getOwnPropertyDescriptor(JSObject*, ExecState*, const Identifier&, PropertyDescriptor&);
diff --git a/Source/JavaScriptCore/runtime/JSFunction.cpp b/Source/JavaScriptCore/runtime/JSFunction.cpp
index 65470a53f..15718a176 100644
--- a/Source/JavaScriptCore/runtime/JSFunction.cpp
+++ b/Source/JavaScriptCore/runtime/JSFunction.cpp
@@ -136,7 +136,11 @@ const UString JSFunction::calculatedDisplayName(ExecState* exec)
if (!explicitName.isEmpty())
return explicitName;
- return name(exec);
+ const UString actualName = name(exec);
+ if (!actualName.isEmpty() || isHostFunction())
+ return actualName;
+
+ return jsExecutable()->inferredName().ustring();
}
const SourceCode* JSFunction::sourceCode() const
@@ -175,14 +179,14 @@ JSValue JSFunction::argumentsGetter(ExecState* exec, JSValue slotBase, const Ide
{
JSFunction* thisObj = asFunction(slotBase);
ASSERT(!thisObj->isHostFunction());
- return exec->interpreter()->retrieveArguments(exec, thisObj);
+ return exec->interpreter()->retrieveArgumentsFromVMCode(exec, thisObj);
}
JSValue JSFunction::callerGetter(ExecState* exec, JSValue slotBase, const Identifier&)
{
JSFunction* thisObj = asFunction(slotBase);
ASSERT(!thisObj->isHostFunction());
- return exec->interpreter()->retrieveCaller(exec, thisObj);
+ return exec->interpreter()->retrieveCallerFromVMCode(exec, thisObj);
}
JSValue JSFunction::lengthGetter(ExecState*, JSValue slotBase, const Identifier&)
@@ -204,8 +208,7 @@ bool JSFunction::getOwnPropertySlot(JSCell* cell, ExecState* exec, const Identif
if (!location) {
JSObject* prototype = constructEmptyObject(exec, thisObject->globalObject()->emptyObjectStructure());
prototype->putDirect(exec->globalData(), exec->propertyNames().constructor, thisObject, DontEnum);
- PutPropertySlot slot;
- thisObject->putDirect(exec->globalData(), exec->propertyNames().prototype, prototype, DontDelete | DontEnum, false, slot);
+ thisObject->putDirect(exec->globalData(), exec->propertyNames().prototype, prototype, DontDelete | DontEnum);
location = thisObject->getDirectLocation(exec->globalData(), exec->propertyNames().prototype);
}
@@ -216,7 +219,7 @@ bool JSFunction::getOwnPropertySlot(JSCell* cell, ExecState* exec, const Identif
if (thisObject->jsExecutable()->isStrictMode()) {
bool result = Base::getOwnPropertySlot(thisObject, exec, propertyName, slot);
if (!result) {
- thisObject->initializeGetterSetterProperty(exec, propertyName, thisObject->globalObject()->throwTypeErrorGetterSetter(exec), DontDelete | DontEnum | Getter | Setter);
+ thisObject->initializeGetterSetterProperty(exec, propertyName, thisObject->globalObject()->throwTypeErrorGetterSetter(exec), DontDelete | DontEnum | Accessor);
result = Base::getOwnPropertySlot(thisObject, exec, propertyName, slot);
ASSERT(result);
}
@@ -235,7 +238,7 @@ bool JSFunction::getOwnPropertySlot(JSCell* cell, ExecState* exec, const Identif
if (thisObject->jsExecutable()->isStrictMode()) {
bool result = Base::getOwnPropertySlot(thisObject, exec, propertyName, slot);
if (!result) {
- thisObject->initializeGetterSetterProperty(exec, propertyName, thisObject->globalObject()->throwTypeErrorGetterSetter(exec), DontDelete | DontEnum | Getter | Setter);
+ thisObject->initializeGetterSetterProperty(exec, propertyName, thisObject->globalObject()->throwTypeErrorGetterSetter(exec), DontDelete | DontEnum | Accessor);
result = Base::getOwnPropertySlot(thisObject, exec, propertyName, slot);
ASSERT(result);
}
@@ -264,13 +267,13 @@ bool JSFunction::getOwnPropertyDescriptor(JSObject* object, ExecState* exec, con
if (thisObject->jsExecutable()->isStrictMode()) {
bool result = Base::getOwnPropertyDescriptor(thisObject, exec, propertyName, descriptor);
if (!result) {
- thisObject->initializeGetterSetterProperty(exec, propertyName, thisObject->globalObject()->throwTypeErrorGetterSetter(exec), DontDelete | DontEnum | Getter | Setter);
+ thisObject->initializeGetterSetterProperty(exec, propertyName, thisObject->globalObject()->throwTypeErrorGetterSetter(exec), DontDelete | DontEnum | Accessor);
result = Base::getOwnPropertyDescriptor(thisObject, exec, propertyName, descriptor);
ASSERT(result);
}
return result;
}
- descriptor.setDescriptor(exec->interpreter()->retrieveArguments(exec, thisObject), ReadOnly | DontEnum | DontDelete);
+ descriptor.setDescriptor(exec->interpreter()->retrieveArgumentsFromVMCode(exec, thisObject), ReadOnly | DontEnum | DontDelete);
return true;
}
@@ -283,13 +286,13 @@ bool JSFunction::getOwnPropertyDescriptor(JSObject* object, ExecState* exec, con
if (thisObject->jsExecutable()->isStrictMode()) {
bool result = Base::getOwnPropertyDescriptor(thisObject, exec, propertyName, descriptor);
if (!result) {
- thisObject->initializeGetterSetterProperty(exec, propertyName, thisObject->globalObject()->throwTypeErrorGetterSetter(exec), DontDelete | DontEnum | Getter | Setter);
+ thisObject->initializeGetterSetterProperty(exec, propertyName, thisObject->globalObject()->throwTypeErrorGetterSetter(exec), DontDelete | DontEnum | Accessor);
result = Base::getOwnPropertyDescriptor(thisObject, exec, propertyName, descriptor);
ASSERT(result);
}
return result;
}
- descriptor.setDescriptor(exec->interpreter()->retrieveCaller(exec, thisObject), ReadOnly | DontEnum | DontDelete);
+ descriptor.setDescriptor(exec->interpreter()->retrieveCallerFromVMCode(exec, thisObject), ReadOnly | DontEnum | DontDelete);
return true;
}
@@ -358,5 +361,15 @@ ConstructType JSFunction::getConstructData(JSCell* cell, ConstructData& construc
constructData.js.scopeChain = thisObject->scope();
return ConstructTypeJS;
}
+
+
+UString getCalculatedDisplayName(CallFrame* callFrame, JSObject* object)
+{
+ if (JSFunction* function = jsDynamicCast<JSFunction*>(object))
+ return function->calculatedDisplayName(callFrame);
+ if (InternalFunction* function = jsDynamicCast<InternalFunction*>(object))
+ return function->calculatedDisplayName(callFrame);
+ return UString();
+}
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/JSFunction.h b/Source/JavaScriptCore/runtime/JSFunction.h
index 5118f8b10..a12b079d7 100644
--- a/Source/JavaScriptCore/runtime/JSFunction.h
+++ b/Source/JavaScriptCore/runtime/JSFunction.h
@@ -40,8 +40,10 @@ namespace JSC {
class JITCompiler;
}
- EncodedJSValue JSC_HOST_CALL callHostFunctionAsConstructor(ExecState*);
+ JS_EXPORT_PRIVATE EncodedJSValue JSC_HOST_CALL callHostFunctionAsConstructor(ExecState*);
+ JS_EXPORT_PRIVATE UString getCalculatedDisplayName(CallFrame*, JSObject*);
+
class JSFunction : public JSNonFinalObject {
friend class JIT;
friend class DFG::SpeculativeJIT;
@@ -51,7 +53,7 @@ namespace JSC {
public:
typedef JSNonFinalObject Base;
- static JSFunction* create(ExecState*, JSGlobalObject*, int length, const Identifier& name, NativeFunction nativeFunction, NativeFunction nativeConstructor = callHostFunctionAsConstructor);
+ JS_EXPORT_PRIVATE static JSFunction* create(ExecState*, JSGlobalObject*, int length, const Identifier& name, NativeFunction nativeFunction, NativeFunction nativeConstructor = callHostFunctionAsConstructor);
static JSFunction* create(ExecState*, JSGlobalObject*, int length, const Identifier& name, NativeExecutable* nativeExecutable);
static JSFunction* create(ExecState* exec, FunctionExecutable* executable, ScopeChainNode* scopeChain)
@@ -64,8 +66,8 @@ namespace JSC {
static void destroy(JSCell*);
- const UString& name(ExecState*);
- const UString displayName(ExecState*);
+ JS_EXPORT_PRIVATE const UString& name(ExecState*);
+ JS_EXPORT_PRIVATE const UString displayName(ExecState*);
const UString calculatedDisplayName(ExecState*);
ScopeChainNode* scope()
@@ -94,7 +96,7 @@ namespace JSC {
inline bool isHostFunction() const;
FunctionExecutable* jsExecutable() const;
- const SourceCode* sourceCode() const;
+ JS_EXPORT_PRIVATE const SourceCode* sourceCode() const;
static JS_EXPORTDATA const ClassInfo s_info;
@@ -123,7 +125,7 @@ namespace JSC {
protected:
const static unsigned StructureFlags = OverridesGetOwnPropertySlot | ImplementsHasInstance | OverridesVisitChildren | OverridesGetPropertyNames | JSObject::StructureFlags;
- JSFunction(ExecState*, JSGlobalObject*, Structure*);
+ JS_EXPORT_PRIVATE JSFunction(ExecState*, JSGlobalObject*, Structure*);
JSFunction(ExecState*, FunctionExecutable*, ScopeChainNode*);
void finishCreation(ExecState*, NativeExecutable*, int length, const Identifier& name);
@@ -140,7 +142,7 @@ namespace JSC {
static void visitChildren(JSCell*, SlotVisitor&);
private:
- bool isHostFunctionNonInline() const;
+ JS_EXPORT_PRIVATE bool isHostFunctionNonInline() const;
static JSValue argumentsGetter(ExecState*, JSValue, const Identifier&);
static JSValue callerGetter(ExecState*, JSValue, const Identifier&);
diff --git a/Source/JavaScriptCore/runtime/JSGlobalData.cpp b/Source/JavaScriptCore/runtime/JSGlobalData.cpp
index dab3f24ba..bbe520a1e 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalData.cpp
+++ b/Source/JavaScriptCore/runtime/JSGlobalData.cpp
@@ -101,7 +101,7 @@ extern const HashTable globalObjectTable;
extern const HashTable mathTable;
extern const HashTable numberConstructorTable;
extern const HashTable numberPrototypeTable;
-extern const HashTable objectConstructorTable;
+JS_EXPORTDATA extern const HashTable objectConstructorTable;
extern const HashTable objectPrototypeTable;
extern const HashTable regExpTable;
extern const HashTable regExpConstructorTable;
@@ -162,8 +162,6 @@ JSGlobalData::JSGlobalData(GlobalDataType globalDataType, ThreadStackType thread
#endif
{
interpreter = new Interpreter;
- if (globalDataType == Default)
- m_stack = wtfThreadData().stack();
// Need to be careful to keep everything consistent here
IdentifierTable* existingEntryIdentifierTable = wtfThreadData().setCurrentIdentifierTable(identifierTable);
diff --git a/Source/JavaScriptCore/runtime/JSGlobalData.h b/Source/JavaScriptCore/runtime/JSGlobalData.h
index a6ad8a747..92817f2a2 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalData.h
+++ b/Source/JavaScriptCore/runtime/JSGlobalData.h
@@ -134,18 +134,18 @@ namespace JSC {
enum GlobalDataType { Default, APIContextGroup, APIShared };
struct ClientData {
- virtual ~ClientData() = 0;
+ JS_EXPORT_PRIVATE virtual ~ClientData() = 0;
};
bool isSharedInstance() { return globalDataType == APIShared; }
bool usingAPI() { return globalDataType != Default; }
static bool sharedInstanceExists();
- static JSGlobalData& sharedInstance();
+ JS_EXPORT_PRIVATE static JSGlobalData& sharedInstance();
- static PassRefPtr<JSGlobalData> create(ThreadStackType, HeapSize = SmallHeap);
- static PassRefPtr<JSGlobalData> createLeaked(ThreadStackType, HeapSize = SmallHeap);
+ JS_EXPORT_PRIVATE static PassRefPtr<JSGlobalData> create(ThreadStackType, HeapSize = SmallHeap);
+ JS_EXPORT_PRIVATE static PassRefPtr<JSGlobalData> createLeaked(ThreadStackType, HeapSize = SmallHeap);
static PassRefPtr<JSGlobalData> createContextGroup(ThreadStackType, HeapSize = SmallHeap);
- ~JSGlobalData();
+ JS_EXPORT_PRIVATE ~JSGlobalData();
void makeUsableFromMultipleThreads() { heap.machineThreads().makeUsableFromMultipleThreads(); }
@@ -223,13 +223,6 @@ namespace JSC {
bool canUseJIT() { return m_canUseJIT; }
#endif
- const StackBounds& stack()
- {
- return (globalDataType == Default)
- ? m_stack
- : wtfThreadData().stack();
- }
-
OwnPtr<ParserArena> parserArena;
OwnPtr<Keywords> keywords;
Interpreter* interpreter;
@@ -308,21 +301,21 @@ namespace JSC {
CachedTranscendentalFunction<sin> cachedSin;
- void resetDateCache();
+ JS_EXPORT_PRIVATE void resetDateCache();
- void startSampling();
- void stopSampling();
- void dumpSampleData(ExecState* exec);
+ JS_EXPORT_PRIVATE void startSampling();
+ JS_EXPORT_PRIVATE void stopSampling();
+ JS_EXPORT_PRIVATE void dumpSampleData(ExecState* exec);
void recompileAllJSFunctions();
RegExpCache* regExpCache() { return m_regExpCache; }
#if ENABLE(REGEXP_TRACING)
void addRegExpToTrace(PassRefPtr<RegExp> regExp);
#endif
- void dumpRegExpTrace();
- void clearBuiltinStructures();
+ JS_EXPORT_PRIVATE void dumpRegExpTrace();
+ JS_EXPORT_PRIVATE void clearBuiltinStructures();
bool isCollectorBusy() { return heap.isBusy(); }
- void releaseExecutableMemory();
+ JS_EXPORT_PRIVATE void releaseExecutableMemory();
#if ENABLE(GC_VALIDATION)
bool isInitializingObject() const;
@@ -345,6 +338,7 @@ namespace JSC {
registerTypedArrayFunction(int16, Int16);
registerTypedArrayFunction(int32, Int32);
registerTypedArrayFunction(uint8, Uint8);
+ registerTypedArrayFunction(uint8Clamped, Uint8Clamped);
registerTypedArrayFunction(uint16, Uint16);
registerTypedArrayFunction(uint32, Uint32);
registerTypedArrayFunction(float32, Float32);
@@ -358,7 +352,6 @@ namespace JSC {
#if ENABLE(JIT) && ENABLE(INTERPRETER)
bool m_canUseJIT;
#endif
- StackBounds m_stack;
#if ENABLE(GC_VALIDATION)
bool m_isInitializingObject;
#endif
@@ -366,6 +359,7 @@ namespace JSC {
TypedArrayDescriptor m_int16ArrayDescriptor;
TypedArrayDescriptor m_int32ArrayDescriptor;
TypedArrayDescriptor m_uint8ArrayDescriptor;
+ TypedArrayDescriptor m_uint8ClampedArrayDescriptor;
TypedArrayDescriptor m_uint16ArrayDescriptor;
TypedArrayDescriptor m_uint32ArrayDescriptor;
TypedArrayDescriptor m_float32ArrayDescriptor;
diff --git a/Source/JavaScriptCore/runtime/JSGlobalObject.cpp b/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
index 5ad53c222..f28139d27 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
@@ -153,7 +153,7 @@ void JSGlobalObject::put(JSCell* cell, ExecState* exec, const Identifier& proper
JSVariableObject::put(thisObject, exec, propertyName, value, slot);
}
-void JSGlobalObject::putWithAttributes(JSObject* object, ExecState* exec, const Identifier& propertyName, JSValue value, unsigned attributes)
+void JSGlobalObject::putDirectVirtual(JSObject* object, ExecState* exec, const Identifier& propertyName, JSValue value, unsigned attributes)
{
JSGlobalObject* thisObject = jsCast<JSGlobalObject*>(object);
ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(thisObject));
@@ -167,7 +167,7 @@ void JSGlobalObject::putWithAttributes(JSObject* object, ExecState* exec, const
if (!valueBefore) {
JSValue valueAfter = thisObject->getDirect(exec->globalData(), propertyName);
if (valueAfter)
- JSObject::putWithAttributes(thisObject, exec, propertyName, valueAfter, attributes);
+ JSObject::putDirectVirtual(thisObject, exec, propertyName, valueAfter, attributes);
}
}
diff --git a/Source/JavaScriptCore/runtime/JSGlobalObject.h b/Source/JavaScriptCore/runtime/JSGlobalObject.h
index 1caa8b187..70368307d 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalObject.h
+++ b/Source/JavaScriptCore/runtime/JSGlobalObject.h
@@ -192,20 +192,20 @@ namespace JSC {
}
public:
- ~JSGlobalObject();
- static void destroy(JSCell*);
+ JS_EXPORT_PRIVATE ~JSGlobalObject();
+ JS_EXPORT_PRIVATE static void destroy(JSCell*);
- static void visitChildren(JSCell*, SlotVisitor&);
+ JS_EXPORT_PRIVATE static void visitChildren(JSCell*, SlotVisitor&);
- static bool getOwnPropertySlot(JSCell*, ExecState*, const Identifier&, PropertySlot&);
- static bool getOwnPropertyDescriptor(JSObject*, ExecState*, const Identifier&, PropertyDescriptor&);
+ JS_EXPORT_PRIVATE static bool getOwnPropertySlot(JSCell*, ExecState*, const Identifier&, PropertySlot&);
+ JS_EXPORT_PRIVATE static bool getOwnPropertyDescriptor(JSObject*, ExecState*, const Identifier&, PropertyDescriptor&);
bool hasOwnPropertyForWrite(ExecState*, const Identifier&);
- static void put(JSCell*, ExecState*, const Identifier&, JSValue, PutPropertySlot&);
+ JS_EXPORT_PRIVATE static void put(JSCell*, ExecState*, const Identifier&, JSValue, PutPropertySlot&);
- static void putWithAttributes(JSObject*, ExecState*, const Identifier& propertyName, JSValue, unsigned attributes);
+ JS_EXPORT_PRIVATE static void putDirectVirtual(JSObject*, ExecState*, const Identifier& propertyName, JSValue, unsigned attributes);
- static void defineGetter(JSObject*, ExecState*, const Identifier& propertyName, JSObject* getterFunc, unsigned attributes);
- static void defineSetter(JSObject*, ExecState*, const Identifier& propertyName, JSObject* setterFunc, unsigned attributes);
+ JS_EXPORT_PRIVATE static void defineGetter(JSObject*, ExecState*, const Identifier& propertyName, JSObject* getterFunc, unsigned attributes);
+ JS_EXPORT_PRIVATE static void defineSetter(JSObject*, ExecState*, const Identifier& propertyName, JSObject* setterFunc, unsigned attributes);
// We use this in the code generator as we perform symbol table
// lookups prior to initializing the properties
@@ -283,7 +283,7 @@ namespace JSC {
ScopeChainNode* globalScopeChain() { return m_globalScopeChain.get(); }
- ExecState* globalExec();
+ JS_EXPORT_PRIVATE ExecState* globalExec();
static bool shouldInterruptScript(const JSGlobalObject*) { return true; }
@@ -332,17 +332,17 @@ namespace JSC {
JSValue value;
unsigned attributes;
};
- void addStaticGlobals(GlobalPropertyInfo*, int count);
+ JS_EXPORT_PRIVATE void addStaticGlobals(GlobalPropertyInfo*, int count);
private:
// FIXME: Fold reset into init.
- void init(JSObject* thisValue);
+ JS_EXPORT_PRIVATE void init(JSObject* thisValue);
void reset(JSValue prototype);
void createThrowTypeError(ExecState*);
void setRegisters(WriteBarrier<Unknown>* registers, PassOwnArrayPtr<WriteBarrier<Unknown> > registerArray, size_t count);
- static void clearRareData(JSCell*);
+ JS_EXPORT_PRIVATE static void clearRareData(JSCell*);
};
JSGlobalObject* asGlobalObject(JSValue);
@@ -488,7 +488,7 @@ namespace JSC {
class DynamicGlobalObjectScope {
WTF_MAKE_NONCOPYABLE(DynamicGlobalObjectScope);
public:
- DynamicGlobalObjectScope(JSGlobalData&, JSGlobalObject*);
+ JS_EXPORT_PRIVATE DynamicGlobalObjectScope(JSGlobalData&, JSGlobalObject*);
~DynamicGlobalObjectScope()
{
diff --git a/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp b/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
index bf6b31ef1..b82ab62ab 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
+++ b/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
@@ -51,8 +51,7 @@ namespace JSC {
static JSValue encode(ExecState* exec, const char* doNotEscape)
{
- UString str = exec->argument(0).toString(exec);
- CString cstr = str.utf8(true);
+ CString cstr = exec->argument(0).toString(exec)->value(exec).utf8(true);
if (!cstr.data())
return throwError(exec, createURIError(exec, "String contained an illegal UTF-16 sequence."));
@@ -143,7 +142,7 @@ static JSValue decode(ExecState* exec, const CharType* characters, int length, c
static JSValue decode(ExecState* exec, const char* doNotUnescape, bool strict)
{
JSStringBuilder builder;
- UString str = exec->argument(0).toString(exec);
+ UString str = exec->argument(0).toString(exec)->value(exec);
if (str.is8Bit())
return decode(exec, str.characters8(), str.length(), doNotUnescape, strict);
@@ -513,7 +512,7 @@ EncodedJSValue JSC_HOST_CALL globalFuncEval(ExecState* exec)
if (!x.isString())
return JSValue::encode(x);
- UString s = x.toString(exec);
+ UString s = x.toString(exec)->value(exec);
if (s.is8Bit()) {
LiteralParser<LChar> preparser(exec, s.characters8(), s.length(), NonStrictJSON);
@@ -556,7 +555,7 @@ EncodedJSValue JSC_HOST_CALL globalFuncParseInt(ExecState* exec)
}
// If ToString throws, we shouldn't call ToInt32.
- UString s = value.toString(exec);
+ UString s = value.toString(exec)->value(exec);
if (exec->hadException())
return JSValue::encode(jsUndefined());
@@ -565,7 +564,7 @@ EncodedJSValue JSC_HOST_CALL globalFuncParseInt(ExecState* exec)
EncodedJSValue JSC_HOST_CALL globalFuncParseFloat(ExecState* exec)
{
- return JSValue::encode(jsNumber(parseFloat(exec->argument(0).toString(exec))));
+ return JSValue::encode(jsNumber(parseFloat(exec->argument(0).toString(exec)->value(exec))));
}
EncodedJSValue JSC_HOST_CALL globalFuncIsNaN(ExecState* exec)
@@ -623,7 +622,7 @@ EncodedJSValue JSC_HOST_CALL globalFuncEscape(ExecState* exec)
"*+-./@_";
JSStringBuilder builder;
- UString str = exec->argument(0).toString(exec);
+ UString str = exec->argument(0).toString(exec)->value(exec);
if (str.is8Bit()) {
const LChar* c = str.characters8();
for (unsigned k = 0; k < str.length(); k++, c++) {
@@ -662,7 +661,7 @@ EncodedJSValue JSC_HOST_CALL globalFuncEscape(ExecState* exec)
EncodedJSValue JSC_HOST_CALL globalFuncUnescape(ExecState* exec)
{
UStringBuilder builder;
- UString str = exec->argument(0).toString(exec);
+ UString str = exec->argument(0).toString(exec)->value(exec);
int k = 0;
int len = str.length();
diff --git a/Source/JavaScriptCore/runtime/JSGlobalThis.h b/Source/JavaScriptCore/runtime/JSGlobalThis.h
index fa5de0491..fa5c2eb34 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalThis.h
+++ b/Source/JavaScriptCore/runtime/JSGlobalThis.h
@@ -63,7 +63,7 @@ protected:
static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags;
- static void visitChildren(JSCell*, SlotVisitor&);
+ JS_EXPORT_PRIVATE static void visitChildren(JSCell*, SlotVisitor&);
WriteBarrier<JSGlobalObject> m_unwrappedObject;
};
diff --git a/Source/JavaScriptCore/runtime/JSLock.h b/Source/JavaScriptCore/runtime/JSLock.h
index 7b07b4fb3..a0eb96975 100644
--- a/Source/JavaScriptCore/runtime/JSLock.h
+++ b/Source/JavaScriptCore/runtime/JSLock.h
@@ -56,7 +56,7 @@ namespace JSC {
class JSLock {
WTF_MAKE_NONCOPYABLE(JSLock);
public:
- JSLock(ExecState*);
+ JS_EXPORT_PRIVATE JSLock(ExecState*);
JSLock(JSGlobalData*);
JSLock(JSLockBehavior lockBehavior)
@@ -80,22 +80,22 @@ namespace JSC {
unlock(m_lockBehavior);
}
- static void lock(JSLockBehavior);
- static void unlock(JSLockBehavior);
+ JS_EXPORT_PRIVATE static void lock(JSLockBehavior);
+ JS_EXPORT_PRIVATE static void unlock(JSLockBehavior);
static void lock(ExecState*);
static void unlock(ExecState*);
- static intptr_t lockCount();
- static bool currentThreadIsHoldingLock();
+ JS_EXPORT_PRIVATE static intptr_t lockCount();
+ JS_EXPORT_PRIVATE static bool currentThreadIsHoldingLock();
JSLockBehavior m_lockBehavior;
class DropAllLocks {
WTF_MAKE_NONCOPYABLE(DropAllLocks);
public:
- DropAllLocks(ExecState* exec);
- DropAllLocks(JSLockBehavior);
- ~DropAllLocks();
+ JS_EXPORT_PRIVATE DropAllLocks(ExecState* exec);
+ JS_EXPORT_PRIVATE DropAllLocks(JSLockBehavior);
+ JS_EXPORT_PRIVATE ~DropAllLocks();
private:
intptr_t m_lockCount;
diff --git a/Source/JavaScriptCore/runtime/JSONObject.cpp b/Source/JavaScriptCore/runtime/JSONObject.cpp
index 05c6c2953..83b118429 100644
--- a/Source/JavaScriptCore/runtime/JSONObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSONObject.cpp
@@ -142,7 +142,7 @@ static inline JSValue unwrapBoxedPrimitive(ExecState* exec, JSValue value)
if (object->inherits(&NumberObject::s_info))
return jsNumber(object->toNumber(exec));
if (object->inherits(&StringObject::s_info))
- return jsString(exec, object->toString(exec));
+ return object->toString(exec);
if (object->inherits(&BooleanObject::s_info))
return object->toPrimitive(exec);
return value;
@@ -223,25 +223,12 @@ Stringifier::Stringifier(ExecState* exec, const Local<Unknown>& replacer, const
if (exec->hadException())
break;
- UString propertyName;
- if (name.getString(exec, propertyName)) {
- m_arrayReplacerPropertyNames.add(Identifier(exec, propertyName));
- continue;
- }
-
- if (name.isNumber()) {
- m_arrayReplacerPropertyNames.add(Identifier::from(exec, name.asNumber()));
- continue;
- }
-
if (name.isObject()) {
if (!asObject(name)->inherits(&NumberObject::s_info) && !asObject(name)->inherits(&StringObject::s_info))
continue;
- propertyName = name.toString(exec);
- if (exec->hadException())
- break;
- m_arrayReplacerPropertyNames.add(Identifier(exec, propertyName));
}
+
+ m_arrayReplacerPropertyNames.add(Identifier(exec, name.toString(exec)->value(exec)));
}
return;
}
@@ -825,8 +812,7 @@ EncodedJSValue JSC_HOST_CALL JSONProtoFuncParse(ExecState* exec)
{
if (!exec->argumentCount())
return throwVMError(exec, createError(exec, "JSON.parse requires at least one parameter"));
- JSValue value = exec->argument(0);
- UString source = value.toString(exec);
+ UString source = exec->argument(0).toString(exec)->value(exec);
if (exec->hadException())
return JSValue::encode(jsNull());
diff --git a/Source/JavaScriptCore/runtime/JSObject.cpp b/Source/JavaScriptCore/runtime/JSObject.cpp
index a813e8416..a443fda86 100644
--- a/Source/JavaScriptCore/runtime/JSObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSObject.cpp
@@ -24,6 +24,7 @@
#include "config.h"
#include "JSObject.h"
+#include "BumpSpaceInlineMethods.h"
#include "DatePrototype.h"
#include "ErrorConstructor.h"
#include "GetterSetter.h"
@@ -83,11 +84,6 @@ static inline void getClassPropertyNames(ExecState* exec, const ClassInfo* class
}
}
-void JSObject::finalize(JSCell* cell)
-{
- delete [] jsCast<JSObject*>(cell)->m_propertyStorage.get();
-}
-
void JSObject::destroy(JSCell* cell)
{
jsCast<JSObject*>(cell)->JSObject::~JSObject();
@@ -106,7 +102,16 @@ void JSObject::visitChildren(JSCell* cell, SlotVisitor& visitor)
PropertyStorage storage = thisObject->propertyStorage();
size_t storageSize = thisObject->structure()->propertyStorageSize();
- visitor.appendValues(storage, storageSize);
+ if (thisObject->isUsingInlineStorage())
+ visitor.appendValues(storage, storageSize);
+ else {
+ // We have this extra temp here to slake GCC's thirst for the blood of those who dereference type-punned pointers.
+ void* temp = storage;
+ visitor.copyAndAppend(&temp, thisObject->structure()->propertyStorageCapacity() * sizeof(WriteBarrierBase<Unknown>), storage->slot(), storageSize);
+ storage = static_cast<PropertyStorage>(temp);
+ thisObject->m_propertyStorage.set(storage, StorageBarrier::Unchecked);
+ }
+
if (thisObject->m_inheritorID)
visitor.append(&thisObject->m_inheritorID);
@@ -162,7 +167,7 @@ void JSObject::put(JSCell* cell, ExecState* exec, const Identifier& propertyName
for (JSObject* obj = thisObject; !obj->structure()->hasGetterSetterProperties(); obj = asObject(prototype)) {
prototype = obj->prototype();
if (prototype.isNull()) {
- if (!thisObject->putDirectInternal(globalData, propertyName, value, 0, true, slot, getJSFunction(value)) && slot.isStrictMode())
+ if (!thisObject->putDirectInternal<PutModePut>(globalData, propertyName, value, 0, slot, getJSFunction(value)) && slot.isStrictMode())
throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
return;
}
@@ -205,7 +210,7 @@ void JSObject::put(JSCell* cell, ExecState* exec, const Identifier& propertyName
break;
}
- if (!thisObject->putDirectInternal(globalData, propertyName, value, 0, true, slot, getJSFunction(value)) && slot.isStrictMode())
+ if (!thisObject->putDirectInternal<PutModePut>(globalData, propertyName, value, 0, slot, getJSFunction(value)) && slot.isStrictMode())
throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
return;
}
@@ -217,16 +222,28 @@ void JSObject::putByIndex(JSCell* cell, ExecState* exec, unsigned propertyName,
thisObject->methodTable()->put(thisObject, exec, Identifier::from(exec, propertyName), value, slot);
}
-void JSObject::putWithAttributes(JSObject* object, ExecState* exec, const Identifier& propertyName, JSValue value, unsigned attributes)
+void JSObject::putDirectVirtual(JSObject* object, ExecState* exec, const Identifier& propertyName, JSValue value, unsigned attributes)
{
+ ASSERT(!value.isGetterSetter() && !(attributes & Accessor));
PutPropertySlot slot;
- object->putDirectInternal(exec->globalData(), propertyName, value, attributes, true, slot, getJSFunction(value));
+ object->putDirectInternal<PutModeDefineOwnProperty>(exec->globalData(), propertyName, value, attributes, slot, getJSFunction(value));
}
-void JSObject::putWithAttributes(JSGlobalData* globalData, const Identifier& propertyName, JSValue value, unsigned attributes)
+void JSObject::putDirectAccessor(JSGlobalData& globalData, const Identifier& propertyName, JSValue value, unsigned attributes)
{
+ ASSERT(value.isGetterSetter() && (attributes & Accessor));
+ ASSERT(propertyName != globalData.propertyNames->underscoreProto);
+
PutPropertySlot slot;
- putDirectInternal(*globalData, propertyName, value, attributes, true, slot, getJSFunction(value));
+ putDirectInternal<PutModeDefineOwnProperty>(globalData, propertyName, value, attributes, slot, getJSFunction(value));
+
+ // putDirect will change our Structure if we add a new property. For
+ // getters and setters, though, we also need to change our Structure
+ // if we override an existing non-getter or non-setter.
+ if (slot.type() != PutPropertySlot::NewProperty)
+ setStructure(globalData, Structure::attributeChangeTransition(globalData, structure(), propertyName, attributes));
+
+ structure()->setHasGetterSetterProperties(true);
}
bool JSObject::hasProperty(ExecState* exec, const Identifier& propertyName) const
@@ -361,15 +378,13 @@ void JSObject::defineGetter(JSObject* thisObject, ExecState* exec, const Identif
JSGlobalData& globalData = exec->globalData();
PutPropertySlot slot;
GetterSetter* getterSetter = GetterSetter::create(exec);
- thisObject->putDirectInternal(globalData, propertyName, getterSetter, attributes | Getter, true, slot, 0);
+ thisObject->putDirectInternal<PutModeDefineOwnProperty>(globalData, propertyName, getterSetter, attributes | Accessor, slot, 0);
// putDirect will change our Structure if we add a new property. For
// getters and setters, though, we also need to change our Structure
// if we override an existing non-getter or non-setter.
- if (slot.type() != PutPropertySlot::NewProperty) {
- if (!thisObject->structure()->isDictionary())
- thisObject->setStructure(exec->globalData(), Structure::getterSetterTransition(globalData, thisObject->structure()));
- }
+ if (slot.type() != PutPropertySlot::NewProperty)
+ thisObject->setStructure(exec->globalData(), Structure::attributeChangeTransition(globalData, thisObject->structure(), propertyName, attributes | Accessor));
thisObject->structure()->setHasGetterSetterProperties(true);
getterSetter->setGetter(globalData, getterFunction);
@@ -379,20 +394,17 @@ void JSObject::initializeGetterSetterProperty(ExecState* exec, const Identifier&
{
// Set an inital property on an object; the property must not already exist & the attribute flags must be set correctly.
ASSERT(structure()->get(exec->globalData(), propertyName) == WTF::notFound);
- ASSERT(static_cast<bool>(getterSetter->getter()) == static_cast<bool>(attributes & Getter));
- ASSERT(static_cast<bool>(getterSetter->setter()) == static_cast<bool>(attributes & Setter));
+ ASSERT(static_cast<bool>(attributes & Accessor));
JSGlobalData& globalData = exec->globalData();
PutPropertySlot slot;
- putDirectInternal(globalData, propertyName, getterSetter, attributes | Getter, true, slot, 0);
+ putDirectInternal<PutModeDefineOwnProperty>(globalData, propertyName, getterSetter, attributes, slot, 0);
// putDirect will change our Structure if we add a new property. For
// getters and setters, though, we also need to change our Structure
// if we override an existing non-getter or non-setter.
- if (slot.type() != PutPropertySlot::NewProperty) {
- if (!structure()->isDictionary())
- setStructure(exec->globalData(), Structure::getterSetterTransition(globalData, structure()));
- }
+ if (slot.type() != PutPropertySlot::NewProperty)
+ setStructure(exec->globalData(), Structure::attributeChangeTransition(globalData, structure(), propertyName, attributes));
structure()->setHasGetterSetterProperties(true);
}
@@ -413,15 +425,13 @@ void JSObject::defineSetter(JSObject* thisObject, ExecState* exec, const Identif
PutPropertySlot slot;
GetterSetter* getterSetter = GetterSetter::create(exec);
- thisObject->putDirectInternal(exec->globalData(), propertyName, getterSetter, attributes | Setter, true, slot, 0);
+ thisObject->putDirectInternal<PutModeDefineOwnProperty>(exec->globalData(), propertyName, getterSetter, attributes | Accessor, slot, 0);
// putDirect will change our Structure if we add a new property. For
// getters and setters, though, we also need to change our Structure
// if we override an existing non-getter or non-setter.
- if (slot.type() != PutPropertySlot::NewProperty) {
- if (!thisObject->structure()->isDictionary())
- thisObject->setStructure(exec->globalData(), Structure::getterSetterTransition(exec->globalData(), thisObject->structure()));
- }
+ if (slot.type() != PutPropertySlot::NewProperty)
+ thisObject->setStructure(exec->globalData(), Structure::attributeChangeTransition(exec->globalData(), thisObject->structure(), propertyName, attributes | Accessor));
thisObject->structure()->setHasGetterSetterProperties(true);
getterSetter->setSetter(exec->globalData(), setterFunction);
@@ -531,11 +541,11 @@ double JSObject::toNumber(ExecState* exec) const
return primitive.toNumber(exec);
}
-UString JSObject::toString(ExecState* exec) const
+JSString* JSObject::toString(ExecState* exec) const
{
JSValue primitive = toPrimitive(exec, PreferString);
if (exec->hadException())
- return "";
+ return jsEmptyString(exec);
return primitive.toString(exec);
}
@@ -646,20 +656,28 @@ void JSObject::allocatePropertyStorage(JSGlobalData& globalData, size_t oldSize,
// It's important that this function not rely on structure(), since
// we might be in the middle of a transition.
- PropertyStorage newPropertyStorage = 0;
- newPropertyStorage = new WriteBarrierBase<Unknown>[newSize];
PropertyStorage oldPropertyStorage = m_propertyStorage.get();
- ASSERT(newPropertyStorage);
+ PropertyStorage newPropertyStorage = 0;
- for (unsigned i = 0; i < oldSize; ++i)
- newPropertyStorage[i] = oldPropertyStorage[i];
+ if (isUsingInlineStorage()) {
+ // We have this extra temp here to slake GCC's thirst for the blood of those who dereference type-punned pointers.
+ void* temp = newPropertyStorage;
+ if (!globalData.heap.tryAllocateStorage(sizeof(WriteBarrierBase<Unknown>) * newSize, &temp))
+ CRASH();
+ newPropertyStorage = static_cast<PropertyStorage>(temp);
- if (isUsingInlineStorage())
- Heap::heap(this)->addFinalizer(this, &finalize);
- else
- delete [] oldPropertyStorage;
+ for (unsigned i = 0; i < oldSize; ++i)
+ newPropertyStorage[i] = oldPropertyStorage[i];
+ } else {
+ // We have this extra temp here to slake GCC's thirst for the blood of those who dereference type-punned pointers.
+ void* temp = oldPropertyStorage;
+ if (!globalData.heap.tryReallocateStorage(&temp, sizeof(WriteBarrierBase<Unknown>) * oldSize, sizeof(WriteBarrierBase<Unknown>) * newSize))
+ CRASH();
+ newPropertyStorage = static_cast<PropertyStorage>(temp);
+ }
+ ASSERT(newPropertyStorage);
m_propertyStorage.set(globalData, this, newPropertyStorage);
}
@@ -692,15 +710,11 @@ static bool putDescriptor(ExecState* exec, JSObject* target, const Identifier& p
if (descriptor.isGenericDescriptor() || descriptor.isDataDescriptor()) {
if (descriptor.isGenericDescriptor() && oldDescriptor.isAccessorDescriptor()) {
GetterSetter* accessor = GetterSetter::create(exec);
- if (oldDescriptor.getter()) {
- attributes |= Getter;
- accessor->setGetter(exec->globalData(), asObject(oldDescriptor.getter()));
- }
- if (oldDescriptor.setter()) {
- attributes |= Setter;
- accessor->setSetter(exec->globalData(), asObject(oldDescriptor.setter()));
- }
- target->methodTable()->putWithAttributes(target, exec, propertyName, accessor, attributes);
+ if (oldDescriptor.getterPresent())
+ accessor->setGetter(exec->globalData(), oldDescriptor.getterObject());
+ if (oldDescriptor.setterPresent())
+ accessor->setSetter(exec->globalData(), oldDescriptor.setterObject());
+ target->putDirectAccessor(exec->globalData(), propertyName, accessor, attributes | Accessor);
return true;
}
JSValue newValue = jsUndefined();
@@ -708,21 +722,32 @@ static bool putDescriptor(ExecState* exec, JSObject* target, const Identifier& p
newValue = descriptor.value();
else if (oldDescriptor.value())
newValue = oldDescriptor.value();
- target->methodTable()->putWithAttributes(target, exec, propertyName, newValue, attributes & ~(Getter | Setter));
+ target->putDirect(exec->globalData(), propertyName, newValue, attributes & ~Accessor);
return true;
}
attributes &= ~ReadOnly;
- if (descriptor.getter() && descriptor.getter().isObject())
- target->methodTable()->defineGetter(target, exec, propertyName, asObject(descriptor.getter()), attributes);
- if (exec->hadException())
- return false;
- if (descriptor.setter() && descriptor.setter().isObject())
- target->methodTable()->defineSetter(target, exec, propertyName, asObject(descriptor.setter()), attributes);
- return !exec->hadException();
+ GetterSetter* accessor = GetterSetter::create(exec);
+
+ if (descriptor.getterPresent())
+ accessor->setGetter(exec->globalData(), descriptor.getterObject());
+ else if (oldDescriptor.getterPresent())
+ accessor->setGetter(exec->globalData(), oldDescriptor.getterObject());
+ if (descriptor.setterPresent())
+ accessor->setSetter(exec->globalData(), descriptor.setterObject());
+ else if (oldDescriptor.setterPresent())
+ accessor->setSetter(exec->globalData(), oldDescriptor.setterObject());
+
+ target->putDirectAccessor(exec->globalData(), propertyName, accessor, attributes | Accessor);
+ return true;
}
bool JSObject::defineOwnProperty(JSObject* object, ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor, bool throwException)
{
+ // __proto__ is magic; we don't currently support setting it as a regular property.
+ // Silent filter out calls to set __proto__ at an early stage; pretend all is okay.
+ if (propertyName == exec->propertyNames().underscoreProto)
+ return true;
+
// If we have a new property we can just put it on normally
PropertyDescriptor current;
if (!object->methodTable()->getOwnPropertyDescriptor(object, exec, propertyName, current)) {
@@ -824,19 +849,15 @@ bool JSObject::defineOwnProperty(JSObject* object, ExecState* exec, const Identi
return false;
GetterSetter* getterSetter = asGetterSetter(accessor);
if (current.attributesEqual(descriptor)) {
- if (descriptor.setter())
- getterSetter->setSetter(exec->globalData(), asObject(descriptor.setter()));
- if (descriptor.getter())
- getterSetter->setGetter(exec->globalData(), asObject(descriptor.getter()));
+ if (descriptor.setterPresent())
+ getterSetter->setSetter(exec->globalData(), descriptor.setterObject());
+ if (descriptor.getterPresent())
+ getterSetter->setGetter(exec->globalData(), descriptor.getterObject());
return true;
}
object->methodTable()->deleteProperty(object, exec, propertyName);
unsigned attrs = current.attributesWithOverride(descriptor);
- if (descriptor.setter())
- attrs |= Setter;
- if (descriptor.getter())
- attrs |= Getter;
- object->putDirect(exec->globalData(), propertyName, getterSetter, attrs);
+ object->putDirectAccessor(exec->globalData(), propertyName, getterSetter, attrs | Accessor);
return true;
}
diff --git a/Source/JavaScriptCore/runtime/JSObject.h b/Source/JavaScriptCore/runtime/JSObject.h
index e26012dd9..433249c20 100644
--- a/Source/JavaScriptCore/runtime/JSObject.h
+++ b/Source/JavaScriptCore/runtime/JSObject.h
@@ -55,7 +55,7 @@ namespace JSC {
class Structure;
struct HashTable;
- JSObject* throwTypeError(ExecState*, const UString&);
+ JS_EXPORT_PRIVATE JSObject* throwTypeError(ExecState*, const UString&);
extern JS_EXPORTDATA const char* StrictModeReadonlyPropertyWriteError;
// ECMA 262-3 8.6.1
@@ -66,8 +66,7 @@ namespace JSC {
DontEnum = 1 << 2, // property doesn't appear in (for .. in ..)
DontDelete = 1 << 3, // property can't be deleted
Function = 1 << 4, // property is a function - only used by static hashtables
- Getter = 1 << 5, // property is a getter
- Setter = 1 << 6 // property is a setter
+ Accessor = 1 << 5, // property is a getter/setter
};
class JSObject : public JSCell {
@@ -75,18 +74,21 @@ namespace JSC {
friend class JIT;
friend class JSCell;
friend class MarkedBlock;
- friend bool setUpStaticFunctionSlot(ExecState* exec, const HashEntry* entry, JSObject* thisObj, const Identifier& propertyName, PropertySlot& slot);
+ JS_EXPORT_PRIVATE friend bool setUpStaticFunctionSlot(ExecState* exec, const HashEntry* entry, JSObject* thisObj, const Identifier& propertyName, PropertySlot& slot);
+
+ enum PutMode {
+ PutModePut,
+ PutModeDefineOwnProperty,
+ };
public:
typedef JSCell Base;
- static void destroy(JSCell*);
-
- static void visitChildren(JSCell*, SlotVisitor&);
+ JS_EXPORT_PRIVATE static void destroy(JSCell*);
- static UString className(const JSObject*);
+ JS_EXPORT_PRIVATE static void visitChildren(JSCell*, SlotVisitor&);
- static void finalize(JSCell*);
+ JS_EXPORT_PRIVATE static UString className(const JSObject*);
JSValue prototype() const;
void setPrototype(JSGlobalData&, JSValue prototype);
@@ -99,43 +101,50 @@ namespace JSC {
bool getPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
bool getPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
- bool getPropertyDescriptor(ExecState*, const Identifier& propertyName, PropertyDescriptor&);
+ JS_EXPORT_PRIVATE bool getPropertyDescriptor(ExecState*, const Identifier& propertyName, PropertyDescriptor&);
static bool getOwnPropertySlot(JSCell*, ExecState*, const Identifier& propertyName, PropertySlot&);
- static bool getOwnPropertySlotByIndex(JSCell*, ExecState*, unsigned propertyName, PropertySlot&);
- static bool getOwnPropertyDescriptor(JSObject*, ExecState*, const Identifier&, PropertyDescriptor&);
-
- static void put(JSCell*, ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
- static void putByIndex(JSCell*, ExecState*, unsigned propertyName, JSValue);
-
- static void putWithAttributes(JSObject*, ExecState*, const Identifier& propertyName, JSValue, unsigned attributes);
- void putWithAttributes(JSGlobalData*, const Identifier& propertyName, JSValue, unsigned attributes);
+ JS_EXPORT_PRIVATE static bool getOwnPropertySlotByIndex(JSCell*, ExecState*, unsigned propertyName, PropertySlot&);
+ JS_EXPORT_PRIVATE static bool getOwnPropertyDescriptor(JSObject*, ExecState*, const Identifier&, PropertyDescriptor&);
+
+ JS_EXPORT_PRIVATE static void put(JSCell*, ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
+ JS_EXPORT_PRIVATE static void putByIndex(JSCell*, ExecState*, unsigned propertyName, JSValue);
+
+ // putDirect is effectively an unchecked vesion of 'defineOwnProperty':
+ // - the prototype chain is not consulted
+ // - accessors are not called.
+ // - attributes will be respected (after the call the property will exist with the given attributes)
+ JS_EXPORT_PRIVATE static void putDirectVirtual(JSObject*, ExecState*, const Identifier& propertyName, JSValue, unsigned attributes);
+ void putDirect(JSGlobalData&, const Identifier& propertyName, JSValue, unsigned attributes = 0);
+ void putDirect(JSGlobalData&, const Identifier& propertyName, JSValue, PutPropertySlot&);
+ void putDirectWithoutTransition(JSGlobalData&, const Identifier& propertyName, JSValue, unsigned attributes = 0);
+ void putDirectAccessor(JSGlobalData&, const Identifier& propertyName, JSValue, unsigned attributes);
bool propertyIsEnumerable(ExecState*, const Identifier& propertyName) const;
- bool hasProperty(ExecState*, const Identifier& propertyName) const;
- bool hasProperty(ExecState*, unsigned propertyName) const;
+ JS_EXPORT_PRIVATE bool hasProperty(ExecState*, const Identifier& propertyName) const;
+ JS_EXPORT_PRIVATE bool hasProperty(ExecState*, unsigned propertyName) const;
bool hasOwnProperty(ExecState*, const Identifier& propertyName) const;
- static bool deleteProperty(JSCell*, ExecState*, const Identifier& propertyName);
- static bool deletePropertyByIndex(JSCell*, ExecState*, unsigned propertyName);
+ JS_EXPORT_PRIVATE static bool deleteProperty(JSCell*, ExecState*, const Identifier& propertyName);
+ JS_EXPORT_PRIVATE static bool deletePropertyByIndex(JSCell*, ExecState*, unsigned propertyName);
- static JSValue defaultValue(const JSObject*, ExecState*, PreferredPrimitiveType);
+ JS_EXPORT_PRIVATE static JSValue defaultValue(const JSObject*, ExecState*, PreferredPrimitiveType);
- static bool hasInstance(JSObject*, ExecState*, JSValue, JSValue prototypeProperty);
+ JS_EXPORT_PRIVATE static bool hasInstance(JSObject*, ExecState*, JSValue, JSValue prototypeProperty);
- static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
- static void getPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
+ JS_EXPORT_PRIVATE static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
+ JS_EXPORT_PRIVATE static void getPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
JSValue toPrimitive(ExecState*, PreferredPrimitiveType = NoPreference) const;
- bool toBoolean(ExecState*) const;
+ JS_EXPORT_PRIVATE bool toBoolean(ExecState*) const;
bool getPrimitiveNumber(ExecState*, double& number, JSValue&) const;
- double toNumber(ExecState*) const;
- UString toString(ExecState*) const;
+ JS_EXPORT_PRIVATE double toNumber(ExecState*) const;
+ JS_EXPORT_PRIVATE JSString* toString(ExecState*) const;
// NOTE: JSObject and its subclasses must be able to gracefully handle ExecState* = 0,
// because this call may come from inside the compiler.
- static JSObject* toThisObject(JSCell*, ExecState*);
+ JS_EXPORT_PRIVATE static JSObject* toThisObject(JSCell*, ExecState*);
JSObject* unwrappedObject();
bool getPropertySpecificValue(ExecState* exec, const Identifier& propertyName, JSCell*& specificFunction) const;
@@ -171,35 +180,37 @@ namespace JSC {
bool hasCustomProperties() { return structure()->didTransition(); }
bool hasGetterSetterProperties() { return structure()->hasGetterSetterProperties(); }
- bool putDirect(JSGlobalData&, const Identifier& propertyName, JSValue, unsigned attr, bool checkReadOnly, PutPropertySlot&);
- void putDirect(JSGlobalData&, const Identifier& propertyName, JSValue, unsigned attr = 0);
- bool putDirect(JSGlobalData&, const Identifier& propertyName, JSValue, PutPropertySlot&);
-
- void putDirectWithoutTransition(JSGlobalData&, const Identifier& propertyName, JSValue, unsigned attr = 0);
+ // putOwnDataProperty has 'put' like semantics, however this method:
+ // - assumes the object contains no own getter/setter properties.
+ // - provides no special handling for __proto__
+ // - does not walk the prototype chain (to check for accessors or non-writable properties).
+ // This is used by JSActivation.
+ bool putOwnDataProperty(JSGlobalData&, const Identifier& propertyName, JSValue, PutPropertySlot&);
// Fast access to known property offsets.
JSValue getDirectOffset(size_t offset) const { return propertyStorage()[offset].get(); }
void putDirectOffset(JSGlobalData& globalData, size_t offset, JSValue value) { propertyStorage()[offset].set(globalData, this, value); }
void putUndefinedAtDirectOffset(size_t offset) { propertyStorage()[offset].setUndefined(); }
- void fillGetterPropertySlot(PropertySlot&, WriteBarrierBase<Unknown>* location);
+ JS_EXPORT_PRIVATE void fillGetterPropertySlot(PropertySlot&, WriteBarrierBase<Unknown>* location);
void initializeGetterSetterProperty(ExecState*, const Identifier&, GetterSetter*, unsigned attributes);
- static void defineGetter(JSObject*, ExecState*, const Identifier& propertyName, JSObject* getterFunction, unsigned attributes = 0);
- static void defineSetter(JSObject*, ExecState*, const Identifier& propertyName, JSObject* setterFunction, unsigned attributes = 0);
- JSValue lookupGetter(ExecState*, const Identifier& propertyName);
- JSValue lookupSetter(ExecState*, const Identifier& propertyName);
- static bool defineOwnProperty(JSObject*, ExecState*, const Identifier& propertyName, PropertyDescriptor&, bool shouldThrow);
+ JS_EXPORT_PRIVATE static void defineGetter(JSObject*, ExecState*, const Identifier& propertyName, JSObject* getterFunction, unsigned attributes = 0);
+ JS_EXPORT_PRIVATE static void defineSetter(JSObject*, ExecState*, const Identifier& propertyName, JSObject* setterFunction, unsigned attributes = 0);
+ JS_EXPORT_PRIVATE JSValue lookupGetter(ExecState*, const Identifier& propertyName);
+ JS_EXPORT_PRIVATE JSValue lookupSetter(ExecState*, const Identifier& propertyName);
+ JS_EXPORT_PRIVATE static bool defineOwnProperty(JSObject*, ExecState*, const Identifier& propertyName, PropertyDescriptor&, bool shouldThrow);
bool isGlobalObject() const;
bool isVariableObject() const;
+ bool isStaticScopeObject() const;
bool isActivationObject() const;
bool isErrorInstance() const;
bool isGlobalThis() const;
void seal(JSGlobalData&);
void freeze(JSGlobalData&);
- void preventExtensions(JSGlobalData&);
+ JS_EXPORT_PRIVATE void preventExtensions(JSGlobalData&);
bool isSealed(JSGlobalData& globalData) { return structure()->isSealed(globalData); }
bool isFrozen(JSGlobalData& globalData) { return structure()->isFrozen(globalData); }
bool isExtensible() { return structure()->isExtensible(); }
@@ -207,7 +218,7 @@ namespace JSC {
bool staticFunctionsReified() { return structure()->staticFunctionsReified(); }
void reifyStaticFunctionsForDelete(ExecState* exec);
- void allocatePropertyStorage(JSGlobalData&, size_t oldSize, size_t newSize);
+ JS_EXPORT_PRIVATE void allocatePropertyStorage(JSGlobalData&, size_t oldSize, size_t newSize);
bool isUsingInlineStorage() const { return static_cast<const void*>(m_propertyStorage.get()) == static_cast<const void*>(this + 1); }
void* addressOfPropertyStorage()
@@ -281,7 +292,8 @@ namespace JSC {
return &propertyStorage()[offset];
}
- bool putDirectInternal(JSGlobalData&, const Identifier& propertyName, JSValue, unsigned attr, bool checkReadOnly, PutPropertySlot&, JSCell*);
+ template<PutMode>
+ bool putDirectInternal(JSGlobalData&, const Identifier& propertyName, JSValue, unsigned attr, PutPropertySlot&, JSCell*);
bool inlineGetOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
@@ -317,7 +329,7 @@ COMPILE_ASSERT((JSFinalObject_inlineStorageCapacity >= JSNonFinalObject_inlineSt
return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
}
- static void destroy(JSCell*);
+ JS_EXPORT_PRIVATE static void destroy(JSCell*);
protected:
explicit JSNonFinalObject(JSGlobalData& globalData, Structure* structure)
@@ -417,6 +429,11 @@ inline bool JSObject::isVariableObject() const
return structure()->typeInfo().type() >= VariableObjectType;
}
+inline bool JSObject::isStaticScopeObject() const
+{
+ return structure()->typeInfo().type() == StaticScopeObjectType;
+}
+
inline bool JSObject::isActivationObject() const
{
return structure()->typeInfo().type() == ActivationObjectType;
@@ -628,9 +645,11 @@ inline JSValue JSObject::get(ExecState* exec, unsigned propertyName) const
return jsUndefined();
}
-inline bool JSObject::putDirectInternal(JSGlobalData& globalData, const Identifier& propertyName, JSValue value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot, JSCell* specificFunction)
+template<JSObject::PutMode mode>
+inline bool JSObject::putDirectInternal(JSGlobalData& globalData, const Identifier& propertyName, JSValue value, unsigned attributes, PutPropertySlot& slot, JSCell* specificFunction)
{
ASSERT(value);
+ ASSERT(value.isGetterSetter() == !!(attributes & Accessor));
ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
if (structure()->isDictionary()) {
@@ -642,7 +661,7 @@ inline bool JSObject::putDirectInternal(JSGlobalData& globalData, const Identifi
// or the new value is different, then despecify.
if (currentSpecificFunction && (specificFunction != currentSpecificFunction))
structure()->despecifyDictionaryFunction(globalData, propertyName);
- if (checkReadOnly && currentAttributes & ReadOnly)
+ if ((mode == PutModePut) && currentAttributes & ReadOnly)
return false;
putDirectOffset(globalData, offset, value);
@@ -657,7 +676,7 @@ inline bool JSObject::putDirectInternal(JSGlobalData& globalData, const Identifi
return true;
}
- if (checkReadOnly && !isExtensible())
+ if ((mode == PutModePut) && !isExtensible())
return false;
size_t currentCapacity = structure()->propertyStorageCapacity();
@@ -693,7 +712,7 @@ inline bool JSObject::putDirectInternal(JSGlobalData& globalData, const Identifi
JSCell* currentSpecificFunction;
offset = structure()->get(globalData, propertyName, currentAttributes, currentSpecificFunction);
if (offset != WTF::notFound) {
- if (checkReadOnly && currentAttributes & ReadOnly)
+ if ((mode == PutModePut) && currentAttributes & ReadOnly)
return false;
// There are three possibilities here:
@@ -721,7 +740,7 @@ inline bool JSObject::putDirectInternal(JSGlobalData& globalData, const Identifi
return true;
}
- if (checkReadOnly && !isExtensible())
+ if ((mode == PutModePut) && !isExtensible())
return false;
Structure* structure = Structure::addPropertyTransition(globalData, this->structure(), propertyName, attributes, specificFunction, offset);
@@ -739,27 +758,31 @@ inline bool JSObject::putDirectInternal(JSGlobalData& globalData, const Identifi
return true;
}
-inline bool JSObject::putDirect(JSGlobalData& globalData, const Identifier& propertyName, JSValue value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot)
+inline bool JSObject::putOwnDataProperty(JSGlobalData& globalData, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
{
ASSERT(value);
ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
+ ASSERT(!structure()->hasGetterSetterProperties());
- return putDirectInternal(globalData, propertyName, value, attributes, checkReadOnly, slot, getJSFunction(value));
+ return putDirectInternal<PutModePut>(globalData, propertyName, value, 0, slot, getJSFunction(value));
}
inline void JSObject::putDirect(JSGlobalData& globalData, const Identifier& propertyName, JSValue value, unsigned attributes)
{
+ ASSERT(!value.isGetterSetter() && !(attributes & Accessor));
PutPropertySlot slot;
- putDirectInternal(globalData, propertyName, value, attributes, false, slot, getJSFunction(value));
+ putDirectInternal<PutModeDefineOwnProperty>(globalData, propertyName, value, attributes, slot, getJSFunction(value));
}
-inline bool JSObject::putDirect(JSGlobalData& globalData, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
+inline void JSObject::putDirect(JSGlobalData& globalData, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
{
- return putDirectInternal(globalData, propertyName, value, 0, false, slot, getJSFunction(value));
+ ASSERT(!value.isGetterSetter());
+ putDirectInternal<PutModeDefineOwnProperty>(globalData, propertyName, value, 0, slot, getJSFunction(value));
}
inline void JSObject::putDirectWithoutTransition(JSGlobalData& globalData, const Identifier& propertyName, JSValue value, unsigned attributes)
{
+ ASSERT(!value.isGetterSetter() && !(attributes & Accessor));
size_t currentCapacity = structure()->propertyStorageCapacity();
size_t offset = structure()->addPropertyWithoutTransition(globalData, propertyName, attributes, getJSFunction(value));
if (currentCapacity != structure()->propertyStorageCapacity())
@@ -841,13 +864,6 @@ inline void JSValue::put(ExecState* exec, const Identifier& propertyName, JSValu
asCell()->methodTable()->put(asCell(), exec, propertyName, value, slot);
}
-inline void JSValue::putDirect(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
-{
- ASSERT(isCell() && isObject());
- if (!asObject(asCell())->putDirect(exec->globalData(), propertyName, value, slot) && slot.isStrictMode())
- throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
-}
-
inline void JSValue::put(ExecState* exec, unsigned propertyName, JSValue value)
{
if (UNLIKELY(!isCell())) {
diff --git a/Source/JavaScriptCore/runtime/JSStaticScopeObject.cpp b/Source/JavaScriptCore/runtime/JSStaticScopeObject.cpp
index ada921d0e..f8942b5f8 100644
--- a/Source/JavaScriptCore/runtime/JSStaticScopeObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSStaticScopeObject.cpp
@@ -78,7 +78,7 @@ void JSStaticScopeObject::put(JSCell* cell, ExecState* exec, const Identifier& p
ASSERT_NOT_REACHED();
}
-void JSStaticScopeObject::putWithAttributes(JSObject* object, ExecState* exec, const Identifier& propertyName, JSValue value, unsigned attributes)
+void JSStaticScopeObject::putDirectVirtual(JSObject* object, ExecState* exec, const Identifier& propertyName, JSValue value, unsigned attributes)
{
JSStaticScopeObject* thisObject = jsCast<JSStaticScopeObject*>(object);
if (thisObject->symbolTablePutWithAttributes(exec->globalData(), propertyName, value, attributes))
diff --git a/Source/JavaScriptCore/runtime/JSStaticScopeObject.h b/Source/JavaScriptCore/runtime/JSStaticScopeObject.h
index 6a2e51a15..bbf03a347 100644
--- a/Source/JavaScriptCore/runtime/JSStaticScopeObject.h
+++ b/Source/JavaScriptCore/runtime/JSStaticScopeObject.h
@@ -47,7 +47,7 @@ namespace JSC{
static bool getOwnPropertySlot(JSCell*, ExecState*, const Identifier&, PropertySlot&);
static void put(JSCell*, ExecState*, const Identifier&, JSValue, PutPropertySlot&);
- static void putWithAttributes(JSObject*, ExecState*, const Identifier&, JSValue, unsigned attributes);
+ static void putDirectVirtual(JSObject*, ExecState*, const Identifier&, JSValue, unsigned attributes);
static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto) { return Structure::create(globalData, globalObject, proto, TypeInfo(StaticScopeObjectType, StructureFlags), &s_info); }
diff --git a/Source/JavaScriptCore/runtime/JSString.cpp b/Source/JavaScriptCore/runtime/JSString.cpp
index 93193b5e5..4e98f9d18 100644
--- a/Source/JavaScriptCore/runtime/JSString.cpp
+++ b/Source/JavaScriptCore/runtime/JSString.cpp
@@ -229,11 +229,6 @@ double JSString::toNumber(ExecState* exec) const
return jsToNumber(value(exec));
}
-UString JSString::toString(ExecState* exec) const
-{
- return value(exec);
-}
-
inline StringObject* StringObject::create(ExecState* exec, JSGlobalObject* globalObject, JSString* string)
{
StringObject* object = new (NotNull, allocateCell<StringObject>(*exec->heap())) StringObject(exec->globalData(), globalObject->stringObjectStructure());
diff --git a/Source/JavaScriptCore/runtime/JSString.h b/Source/JavaScriptCore/runtime/JSString.h
index f40455571..c0637a6e0 100644
--- a/Source/JavaScriptCore/runtime/JSString.h
+++ b/Source/JavaScriptCore/runtime/JSString.h
@@ -214,10 +214,9 @@ namespace JSC {
unsigned length() { return m_length; }
JSValue toPrimitive(ExecState*, PreferredPrimitiveType) const;
- bool toBoolean(ExecState*) const;
+ JS_EXPORT_PRIVATE bool toBoolean(ExecState*) const;
bool getPrimitiveNumber(ExecState*, double& number, JSValue&) const;
JSObject* toObject(ExecState*, JSGlobalObject*) const;
- UString toString(ExecState*) const;
double toNumber(ExecState*) const;
bool getStringPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
@@ -236,12 +235,12 @@ namespace JSC {
static size_t offsetOfLength() { return OBJECT_OFFSETOF(JSString, m_length); }
static size_t offsetOfValue() { return OBJECT_OFFSETOF(JSString, m_value); }
- static const ClassInfo s_info;
+ static JS_EXPORTDATA const ClassInfo s_info;
static void visitChildren(JSCell*, SlotVisitor&);
private:
- void resolveRope(ExecState*) const;
+ JS_EXPORT_PRIVATE void resolveRope(ExecState*) const;
void resolveRopeSlowCase8(LChar*) const;
void resolveRopeSlowCase(UChar*) const;
void outOfMemory(ExecState*) const;
@@ -453,24 +452,11 @@ namespace JSC {
return isTrue(); // false, null, and undefined all convert to false.
}
- inline UString JSValue::toString(ExecState* exec) const
+ inline JSString* JSValue::toString(ExecState* exec) const
{
if (isString())
- return static_cast<JSString*>(asCell())->value(exec);
- if (isInt32())
- return exec->globalData().numericStrings.add(asInt32());
- if (isDouble())
- return exec->globalData().numericStrings.add(asDouble());
- if (isTrue())
- return "true";
- if (isFalse())
- return "false";
- if (isNull())
- return "null";
- if (isUndefined())
- return "undefined";
- ASSERT(isCell());
- return asCell()->toString(exec);
+ return static_cast<JSString*>(asCell());
+ return toStringSlowCase(exec);
}
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/JSValue.cpp b/Source/JavaScriptCore/runtime/JSValue.cpp
index a5d3d936a..6b803c316 100644
--- a/Source/JavaScriptCore/runtime/JSValue.cpp
+++ b/Source/JavaScriptCore/runtime/JSValue.cpp
@@ -204,10 +204,9 @@ bool JSValue::isValidCallee()
return asObject(asCell())->globalObject();
}
-JSString* JSValue::toPrimitiveString(ExecState* exec) const
+JSString* JSValue::toStringSlowCase(ExecState* exec) const
{
- if (isString())
- return static_cast<JSString*>(asCell());
+ ASSERT(!isString());
if (isInt32())
return jsString(&exec->globalData(), exec->globalData().numericStrings.add(asInt32()));
if (isDouble())
@@ -222,10 +221,11 @@ JSString* JSValue::toPrimitiveString(ExecState* exec) const
return jsNontrivialString(exec, exec->propertyNames().undefined.ustring());
ASSERT(isCell());
- JSValue v = asCell()->toPrimitive(exec, NoPreference);
- if (v.isString())
- return static_cast<JSString*>(v.asCell());
- return jsString(&exec->globalData(), v.toString(exec));
+ JSValue value = asCell()->toPrimitive(exec, PreferString);
+ if (exec->hadException())
+ return jsEmptyString(exec);
+ ASSERT(!value.isObject());
+ return value.toString(exec);
}
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/JSValue.h b/Source/JavaScriptCore/runtime/JSValue.h
index a00106274..79e50fba0 100644
--- a/Source/JavaScriptCore/runtime/JSValue.h
+++ b/Source/JavaScriptCore/runtime/JSValue.h
@@ -93,7 +93,7 @@ namespace JSC {
};
// This implements ToInt32, defined in ECMA-262 9.5.
- int32_t toInt32(double);
+ JS_EXPORT_PRIVATE int32_t toInt32(double);
// This implements ToUInt32, defined in ECMA-262 9.6.
inline uint32_t toUInt32(double number)
@@ -197,13 +197,12 @@ namespace JSC {
// toNumber conversion is expected to be side effect free if an exception has
// been set in the ExecState already.
double toNumber(ExecState*) const;
- UString toString(ExecState*) const;
- JSString* toPrimitiveString(ExecState*) const;
+ JSString* toString(ExecState*) const;
JSObject* toObject(ExecState*) const;
JSObject* toObject(ExecState*, JSGlobalObject*) const;
// Integer conversions.
- double toInteger(ExecState*) const;
+ JS_EXPORT_PRIVATE double toInteger(ExecState*) const;
double toIntegerPreserveNaN(ExecState*) const;
int32_t toInt32(ExecState*) const;
uint32_t toUInt32(ExecState*) const;
@@ -218,7 +217,6 @@ namespace JSC {
JSValue get(ExecState*, unsigned propertyName) const;
JSValue get(ExecState*, unsigned propertyName, PropertySlot&) const;
void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
- void putDirect(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
void put(ExecState*, unsigned propertyName, JSValue);
JSObject* toThisObject(ExecState*) const;
@@ -232,7 +230,7 @@ namespace JSC {
bool isCell() const;
JSCell* asCell() const;
- bool isValidCallee();
+ JS_EXPORT_PRIVATE bool isValidCallee();
#ifndef NDEBUG
char* description();
@@ -245,11 +243,12 @@ namespace JSC {
JSValue(HashTableDeletedValueTag);
inline const JSValue asValue() const { return *this; }
- double toNumberSlowCase(ExecState*) const;
- JSObject* toObjectSlowCase(ExecState*, JSGlobalObject*) const;
- JSObject* toThisObjectSlowCase(ExecState*) const;
+ JS_EXPORT_PRIVATE double toNumberSlowCase(ExecState*) const;
+ JS_EXPORT_PRIVATE JSString* toStringSlowCase(ExecState*) const;
+ JS_EXPORT_PRIVATE JSObject* toObjectSlowCase(ExecState*, JSGlobalObject*) const;
+ JS_EXPORT_PRIVATE JSObject* toThisObjectSlowCase(ExecState*) const;
- JSObject* synthesizePrototype(ExecState*) const;
+ JS_EXPORT_PRIVATE JSObject* synthesizePrototype(ExecState*) const;
JSObject* synthesizeObject(ExecState*) const;
#if USE(JSVALUE32_64)
diff --git a/Source/JavaScriptCore/runtime/JSValueInlineMethods.h b/Source/JavaScriptCore/runtime/JSValueInlineMethods.h
index e13d34745..1373558f7 100644
--- a/Source/JavaScriptCore/runtime/JSValueInlineMethods.h
+++ b/Source/JavaScriptCore/runtime/JSValueInlineMethods.h
@@ -477,6 +477,7 @@ namespace JSC {
inline double JSValue::asDouble() const
{
+ ASSERT(isDouble());
return reinterpretIntptrToDouble(u.asInt64 - DoubleEncodeOffset);
}
diff --git a/Source/JavaScriptCore/runtime/JSVariableObject.cpp b/Source/JavaScriptCore/runtime/JSVariableObject.cpp
index 706e3debb..8ca695074 100644
--- a/Source/JavaScriptCore/runtime/JSVariableObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSVariableObject.cpp
@@ -73,7 +73,7 @@ bool JSVariableObject::symbolTableGet(const Identifier& propertyName, PropertyDe
return false;
}
-void JSVariableObject::putWithAttributes(JSObject*, ExecState*, const Identifier&, JSValue, unsigned)
+void JSVariableObject::putDirectVirtual(JSObject*, ExecState*, const Identifier&, JSValue, unsigned)
{
ASSERT_NOT_REACHED();
}
diff --git a/Source/JavaScriptCore/runtime/JSVariableObject.h b/Source/JavaScriptCore/runtime/JSVariableObject.h
index 78e624e02..c1d05ff74 100644
--- a/Source/JavaScriptCore/runtime/JSVariableObject.h
+++ b/Source/JavaScriptCore/runtime/JSVariableObject.h
@@ -48,12 +48,12 @@ namespace JSC {
SymbolTable& symbolTable() const { return *m_symbolTable; }
- static void destroy(JSCell*);
+ JS_EXPORT_PRIVATE static void destroy(JSCell*);
- static NO_RETURN_DUE_TO_ASSERT void putWithAttributes(JSObject*, ExecState*, const Identifier&, JSValue, unsigned attributes);
+ static NO_RETURN_DUE_TO_ASSERT void putDirectVirtual(JSObject*, ExecState*, const Identifier&, JSValue, unsigned attributes);
- static bool deleteProperty(JSCell*, ExecState*, const Identifier&);
- static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
+ JS_EXPORT_PRIVATE static bool deleteProperty(JSCell*, ExecState*, const Identifier&);
+ JS_EXPORT_PRIVATE static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
bool isDynamicScope(bool& requiresDynamicChecks) const;
@@ -88,7 +88,7 @@ namespace JSC {
void setRegisters(WriteBarrier<Unknown>* registers, PassOwnArrayPtr<WriteBarrier<Unknown> > registerArray);
bool symbolTableGet(const Identifier&, PropertySlot&);
- bool symbolTableGet(const Identifier&, PropertyDescriptor&);
+ JS_EXPORT_PRIVATE bool symbolTableGet(const Identifier&, PropertyDescriptor&);
bool symbolTableGet(const Identifier&, PropertySlot&, bool& slotIsWriteable);
bool symbolTablePut(ExecState*, const Identifier&, JSValue, bool shouldThrow);
bool symbolTablePutWithAttributes(JSGlobalData&, const Identifier&, JSValue, unsigned attributes);
diff --git a/Source/JavaScriptCore/runtime/Lookup.h b/Source/JavaScriptCore/runtime/Lookup.h
index 8ed70b41d..64d06b503 100644
--- a/Source/JavaScriptCore/runtime/Lookup.h
+++ b/Source/JavaScriptCore/runtime/Lookup.h
@@ -126,7 +126,7 @@ namespace JSC {
createTable(&exec->globalData());
}
- void deleteTable() const;
+ JS_EXPORT_PRIVATE void deleteTable() const;
// Find an entry in the table, and return the entry.
ALWAYS_INLINE const HashEntry* entry(JSGlobalData* globalData, const Identifier& identifier) const
@@ -218,10 +218,10 @@ namespace JSC {
}
// Convert the hash table keys to identifiers.
- void createTable(JSGlobalData*) const;
+ JS_EXPORT_PRIVATE void createTable(JSGlobalData*) const;
};
- bool setUpStaticFunctionSlot(ExecState*, const HashEntry*, JSObject* thisObject, const Identifier& propertyName, PropertySlot&);
+ JS_EXPORT_PRIVATE bool setUpStaticFunctionSlot(ExecState*, const HashEntry*, JSObject* thisObject, const Identifier& propertyName, PropertySlot&);
/**
* This method does it all (looking in the hashtable, checking for function
diff --git a/Source/JavaScriptCore/runtime/MemoryStatistics.h b/Source/JavaScriptCore/runtime/MemoryStatistics.h
index d4b8b6fc1..9a86df296 100644
--- a/Source/JavaScriptCore/runtime/MemoryStatistics.h
+++ b/Source/JavaScriptCore/runtime/MemoryStatistics.h
@@ -37,7 +37,7 @@ struct GlobalMemoryStatistics {
size_t JITBytes;
};
-GlobalMemoryStatistics globalMemoryStatistics();
+JS_EXPORT_PRIVATE GlobalMemoryStatistics globalMemoryStatistics();
}
diff --git a/Source/JavaScriptCore/runtime/NumberPrototype.cpp b/Source/JavaScriptCore/runtime/NumberPrototype.cpp
index 4612b56d2..fb90bcd17 100644
--- a/Source/JavaScriptCore/runtime/NumberPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/NumberPrototype.cpp
@@ -447,7 +447,7 @@ EncodedJSValue JSC_HOST_CALL numberProtoFuncToString(ExecState* exec)
radix = static_cast<int>(radixValue.toInteger(exec)); // nan -> 0
if (radix == 10)
- return JSValue::encode(jsString(exec, jsNumber(x).toString(exec)));
+ return JSValue::encode(jsNumber(x).toString(exec));
// Fast path for number to character conversion.
if (radix == 36) {
@@ -474,7 +474,7 @@ EncodedJSValue JSC_HOST_CALL numberProtoFuncToLocaleString(ExecState* exec)
if (!toThisNumber(exec->hostThisValue(), x))
return throwVMTypeError(exec);
- return JSValue::encode(jsString(exec, jsNumber(x).toString(exec)));
+ return JSValue::encode(jsNumber(x).toString(exec));
}
EncodedJSValue JSC_HOST_CALL numberProtoFuncValueOf(ExecState* exec)
diff --git a/Source/JavaScriptCore/runtime/ObjectConstructor.cpp b/Source/JavaScriptCore/runtime/ObjectConstructor.cpp
index 65d28c18c..d96c1de7f 100644
--- a/Source/JavaScriptCore/runtime/ObjectConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/ObjectConstructor.cpp
@@ -149,7 +149,7 @@ EncodedJSValue JSC_HOST_CALL objectConstructorGetOwnPropertyDescriptor(ExecState
{
if (!exec->argument(0).isObject())
return throwVMError(exec, createTypeError(exec, "Requested property descriptor of a value that is not an object."));
- UString propertyName = exec->argument(1).toString(exec);
+ UString propertyName = exec->argument(1).toString(exec)->value(exec);
if (exec->hadException())
return JSValue::encode(jsNull());
JSObject* object = asObject(exec->argument(0));
@@ -164,8 +164,10 @@ EncodedJSValue JSC_HOST_CALL objectConstructorGetOwnPropertyDescriptor(ExecState
description->putDirect(exec->globalData(), exec->propertyNames().value, descriptor.value() ? descriptor.value() : jsUndefined(), 0);
description->putDirect(exec->globalData(), exec->propertyNames().writable, jsBoolean(descriptor.writable()), 0);
} else {
- description->putDirect(exec->globalData(), exec->propertyNames().get, descriptor.getter() ? descriptor.getter() : jsUndefined(), 0);
- description->putDirect(exec->globalData(), exec->propertyNames().set, descriptor.setter() ? descriptor.setter() : jsUndefined(), 0);
+ ASSERT(descriptor.getter());
+ ASSERT(descriptor.setter());
+ description->putDirect(exec->globalData(), exec->propertyNames().get, descriptor.getter(), 0);
+ description->putDirect(exec->globalData(), exec->propertyNames().set, descriptor.setter(), 0);
}
description->putDirect(exec->globalData(), exec->propertyNames().enumerable, jsBoolean(descriptor.enumerable()), 0);
@@ -251,8 +253,7 @@ static bool toPropertyDescriptor(ExecState* exec, JSValue in, PropertyDescriptor
throwError(exec, createTypeError(exec, "Getter must be a function."));
return false;
}
- } else
- get = JSValue();
+ }
desc.setGetter(get);
}
@@ -267,9 +268,7 @@ static bool toPropertyDescriptor(ExecState* exec, JSValue in, PropertyDescriptor
throwError(exec, createTypeError(exec, "Setter must be a function."));
return false;
}
- } else
- set = JSValue();
-
+ }
desc.setSetter(set);
}
@@ -293,13 +292,13 @@ EncodedJSValue JSC_HOST_CALL objectConstructorDefineProperty(ExecState* exec)
if (!exec->argument(0).isObject())
return throwVMError(exec, createTypeError(exec, "Properties can only be defined on Objects."));
JSObject* O = asObject(exec->argument(0));
- UString propertyName = exec->argument(1).toString(exec);
+ UString propertyName = exec->argument(1).toString(exec)->value(exec);
if (exec->hadException())
return JSValue::encode(jsNull());
PropertyDescriptor descriptor;
if (!toPropertyDescriptor(exec, exec->argument(2), descriptor))
return JSValue::encode(jsNull());
- ASSERT((descriptor.attributes() & (Getter | Setter)) || (!descriptor.isAccessorDescriptor()));
+ ASSERT((descriptor.attributes() & Accessor) || (!descriptor.isAccessorDescriptor()));
ASSERT(!exec->hadException());
O->methodTable()->defineOwnProperty(O, exec, Identifier(exec, propertyName), descriptor, true);
return JSValue::encode(O);
diff --git a/Source/JavaScriptCore/runtime/ObjectPrototype.cpp b/Source/JavaScriptCore/runtime/ObjectPrototype.cpp
index 3f4dc19db..7ca7dae61 100644
--- a/Source/JavaScriptCore/runtime/ObjectPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/ObjectPrototype.cpp
@@ -118,7 +118,7 @@ EncodedJSValue JSC_HOST_CALL objectProtoFuncValueOf(ExecState* exec)
EncodedJSValue JSC_HOST_CALL objectProtoFuncHasOwnProperty(ExecState* exec)
{
JSValue thisValue = exec->hostThisValue();
- return JSValue::encode(jsBoolean(thisValue.toObject(exec)->hasOwnProperty(exec, Identifier(exec, exec->argument(0).toString(exec)))));
+ return JSValue::encode(jsBoolean(thisValue.toObject(exec)->hasOwnProperty(exec, Identifier(exec, exec->argument(0).toString(exec)->value(exec)))));
}
EncodedJSValue JSC_HOST_CALL objectProtoFuncIsPrototypeOf(ExecState* exec)
@@ -149,7 +149,7 @@ EncodedJSValue JSC_HOST_CALL objectProtoFuncDefineGetter(ExecState* exec)
CallData callData;
if (getCallData(exec->argument(1), callData) == CallTypeNone)
return throwVMError(exec, createSyntaxError(exec, "invalid getter usage"));
- thisObject->methodTable()->defineGetter(thisObject, exec, Identifier(exec, exec->argument(0).toString(exec)), asObject(exec->argument(1)), 0);
+ thisObject->methodTable()->defineGetter(thisObject, exec, Identifier(exec, exec->argument(0).toString(exec)->value(exec)), asObject(exec->argument(1)), 0);
return JSValue::encode(jsUndefined());
}
@@ -162,7 +162,7 @@ EncodedJSValue JSC_HOST_CALL objectProtoFuncDefineSetter(ExecState* exec)
CallData callData;
if (getCallData(exec->argument(1), callData) == CallTypeNone)
return throwVMError(exec, createSyntaxError(exec, "invalid setter usage"));
- thisObject->methodTable()->defineSetter(thisObject, exec, Identifier(exec, exec->argument(0).toString(exec)), asObject(exec->argument(1)), 0);
+ thisObject->methodTable()->defineSetter(thisObject, exec, Identifier(exec, exec->argument(0).toString(exec)->value(exec)), asObject(exec->argument(1)), 0);
return JSValue::encode(jsUndefined());
}
@@ -172,7 +172,7 @@ EncodedJSValue JSC_HOST_CALL objectProtoFuncLookupGetter(ExecState* exec)
if (exec->hadException())
return JSValue::encode(jsUndefined());
- return JSValue::encode(thisObject->lookupGetter(exec, Identifier(exec, exec->argument(0).toString(exec))));
+ return JSValue::encode(thisObject->lookupGetter(exec, Identifier(exec, exec->argument(0).toString(exec)->value(exec))));
}
EncodedJSValue JSC_HOST_CALL objectProtoFuncLookupSetter(ExecState* exec)
@@ -181,13 +181,13 @@ EncodedJSValue JSC_HOST_CALL objectProtoFuncLookupSetter(ExecState* exec)
if (exec->hadException())
return JSValue::encode(jsUndefined());
- return JSValue::encode(thisObject->lookupSetter(exec, Identifier(exec, exec->argument(0).toString(exec))));
+ return JSValue::encode(thisObject->lookupSetter(exec, Identifier(exec, exec->argument(0).toString(exec)->value(exec))));
}
EncodedJSValue JSC_HOST_CALL objectProtoFuncPropertyIsEnumerable(ExecState* exec)
{
JSValue thisValue = exec->hostThisValue();
- return JSValue::encode(jsBoolean(thisValue.toObject(exec)->propertyIsEnumerable(exec, Identifier(exec, exec->argument(0).toString(exec)))));
+ return JSValue::encode(jsBoolean(thisValue.toObject(exec)->propertyIsEnumerable(exec, Identifier(exec, exec->argument(0).toString(exec)->value(exec)))));
}
// 15.2.4.3 Object.prototype.toLocaleString()
diff --git a/Source/JavaScriptCore/runtime/ObjectPrototype.h b/Source/JavaScriptCore/runtime/ObjectPrototype.h
index 78b1cbd39..4c49e97a7 100644
--- a/Source/JavaScriptCore/runtime/ObjectPrototype.h
+++ b/Source/JavaScriptCore/runtime/ObjectPrototype.h
@@ -59,7 +59,7 @@ namespace JSC {
bool m_hasNoPropertiesWithUInt32Names;
};
- EncodedJSValue JSC_HOST_CALL objectProtoFuncToString(ExecState*);
+ JS_EXPORT_PRIVATE EncodedJSValue JSC_HOST_CALL objectProtoFuncToString(ExecState*);
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/Operations.cpp b/Source/JavaScriptCore/runtime/Operations.cpp
index b89746f3f..459feb466 100644
--- a/Source/JavaScriptCore/runtime/Operations.cpp
+++ b/Source/JavaScriptCore/runtime/Operations.cpp
@@ -47,13 +47,11 @@ NEVER_INLINE JSValue jsAddSlowCase(CallFrame* callFrame, JSValue v1, JSValue v2)
JSValue p1 = v1.toPrimitive(callFrame);
JSValue p2 = v2.toPrimitive(callFrame);
- if (p1.isString()) {
- return p2.isString()
- ? jsString(callFrame, asString(p1), asString(p2))
- : jsString(callFrame, asString(p1), jsString(callFrame, p2.toString(callFrame)));
- }
+ if (p1.isString())
+ return jsString(callFrame, asString(p1), p2.toString(callFrame));
+
if (p2.isString())
- return jsString(callFrame, jsString(callFrame, p1.toString(callFrame)), asString(p2));
+ return jsString(callFrame, p1.toString(callFrame), asString(p2));
return jsNumber(p1.toNumber(callFrame) + p2.toNumber(callFrame));
}
diff --git a/Source/JavaScriptCore/runtime/Operations.h b/Source/JavaScriptCore/runtime/Operations.h
index ca2174fa1..945283899 100644
--- a/Source/JavaScriptCore/runtime/Operations.h
+++ b/Source/JavaScriptCore/runtime/Operations.h
@@ -81,10 +81,7 @@ namespace JSC {
for (unsigned i = 0; i < count; ++i) {
JSValue v = strings[i].jsValue();
- if (v.isString())
- ropeBuilder.append(asString(v));
- else
- ropeBuilder.append(jsString(globalData, v.toString(exec)));
+ ropeBuilder.append(v.toString(exec));
if (ropeBuilder.length() < oldLength) // True for overflow
return throwOutOfMemoryError(exec);
@@ -97,20 +94,13 @@ namespace JSC {
{
JSGlobalData* globalData = &exec->globalData();
JSString::RopeBuilder ropeBuilder(*globalData);
-
- if (thisValue.isString())
- ropeBuilder.append(asString(thisValue));
- else
- ropeBuilder.append(jsString(globalData, thisValue.toString(exec)));
+ ropeBuilder.append(thisValue.toString(exec));
unsigned oldLength = 0;
for (unsigned i = 0; i < exec->argumentCount(); ++i) {
JSValue v = exec->argument(i);
- if (v.isString())
- ropeBuilder.append(asString(v));
- else
- ropeBuilder.append(jsString(globalData, v.toString(exec)));
+ ropeBuilder.append(v.toString(exec));
if (ropeBuilder.length() < oldLength) // True for overflow
return throwOutOfMemoryError(exec);
@@ -300,11 +290,8 @@ namespace JSC {
if (v1.isNumber() && v2.isNumber())
return jsNumber(v1.asNumber() + v2.asNumber());
- if (v1.isString()) {
- return v2.isString()
- ? jsString(callFrame, asString(v1), asString(v2))
- : jsString(callFrame, asString(v1), v2.toPrimitiveString(callFrame));
- }
+ if (v1.isString() && !v2.isObject())
+ return jsString(callFrame, asString(v1), v2.toString(callFrame));
// All other cases are pretty uncommon
return jsAddSlowCase(callFrame, v1, v2);
diff --git a/Source/JavaScriptCore/runtime/Options.cpp b/Source/JavaScriptCore/runtime/Options.cpp
index 68d10b7bd..ddfba6e7c 100644
--- a/Source/JavaScriptCore/runtime/Options.cpp
+++ b/Source/JavaScriptCore/runtime/Options.cpp
@@ -27,6 +27,7 @@
#include "Options.h"
#include <limits>
+#include <wtf/NumberOfCores.h>
#include <wtf/PageBlock.h>
#if OS(DARWIN) && ENABLE(PARALLEL_GC)
@@ -129,10 +130,10 @@ void setHeuristic(T& variable, const char* name, U value)
void initializeOptions()
{
- SET(maximumOptimizationCandidateInstructionCount, 1000);
+ SET(maximumOptimizationCandidateInstructionCount, 1100);
- SET(maximumFunctionForCallInlineCandidateInstructionCount, 150);
- SET(maximumFunctionForConstructInlineCandidateInstructionCount, 80);
+ SET(maximumFunctionForCallInlineCandidateInstructionCount, 180);
+ SET(maximumFunctionForConstructInlineCandidateInstructionCount, 100);
SET(maximumInliningDepth, 5);
@@ -174,12 +175,8 @@ void initializeOptions()
SET(opaqueRootMergeThreshold, 1000);
int cpusToUse = 1;
-#if OS(DARWIN) && ENABLE(PARALLEL_GC)
- int name[2];
- size_t valueSize = sizeof(cpusToUse);
- name[0] = CTL_HW;
- name[1] = HW_AVAILCPU;
- sysctl(name, 2, &cpusToUse, &valueSize, 0, 0);
+#if ENABLE(PARALLEL_GC)
+ cpusToUse = WTF::numberOfProcessorCores();
#endif
// We don't scale so well beyond 4.
if (cpusToUse > 4)
diff --git a/Source/JavaScriptCore/runtime/Options.h b/Source/JavaScriptCore/runtime/Options.h
index f7cc5f4e8..feebd37bb 100644
--- a/Source/JavaScriptCore/runtime/Options.h
+++ b/Source/JavaScriptCore/runtime/Options.h
@@ -73,8 +73,8 @@ extern unsigned gcMarkStackSegmentSize;
extern unsigned minimumNumberOfCellsToKeep;
extern unsigned maximumNumberOfSharedSegments;
extern unsigned sharedStackWakeupThreshold;
-extern unsigned numberOfGCMarkers;
-extern unsigned opaqueRootMergeThreshold;
+JS_EXPORTDATA extern unsigned numberOfGCMarkers;
+JS_EXPORTDATA extern unsigned opaqueRootMergeThreshold;
void initializeOptions();
diff --git a/Source/JavaScriptCore/runtime/PropertyDescriptor.cpp b/Source/JavaScriptCore/runtime/PropertyDescriptor.cpp
index c664952a5..e3458e4b9 100644
--- a/Source/JavaScriptCore/runtime/PropertyDescriptor.cpp
+++ b/Source/JavaScriptCore/runtime/PropertyDescriptor.cpp
@@ -84,24 +84,31 @@ JSValue PropertyDescriptor::setter() const
return m_setter;
}
+JSObject* PropertyDescriptor::getterObject() const
+{
+ ASSERT(isAccessorDescriptor() && getterPresent());
+ return m_getter.isObject() ? asObject(m_getter) : 0;
+}
+
+JSObject* PropertyDescriptor::setterObject() const
+{
+ ASSERT(isAccessorDescriptor() && setterPresent());
+ return m_setter.isObject() ? asObject(m_setter) : 0;
+}
+
void PropertyDescriptor::setDescriptor(JSValue value, unsigned attributes)
{
ASSERT(value);
+ ASSERT(value.isGetterSetter() == !!(attributes & Accessor));
+
m_attributes = attributes;
if (value.isGetterSetter()) {
- GetterSetter* accessor = asGetterSetter(value);
-
- m_getter = accessor->getter();
- if (m_getter)
- m_attributes |= Getter;
+ m_attributes &= ~ReadOnly; // FIXME: we should be able to ASSERT this!
- m_setter = accessor->setter();
- if (m_setter)
- m_attributes |= Setter;
-
- ASSERT(m_getter || m_setter);
+ GetterSetter* accessor = asGetterSetter(value);
+ m_getter = accessor->getter() ? accessor->getter() : jsUndefined();
+ m_setter = accessor->setter() ? accessor->setter() : jsUndefined();
m_seenAttributes = EnumerablePresent | ConfigurablePresent;
- m_attributes &= ~ReadOnly;
} else {
m_value = value;
m_seenAttributes = EnumerablePresent | ConfigurablePresent | WritablePresent;
@@ -110,14 +117,12 @@ void PropertyDescriptor::setDescriptor(JSValue value, unsigned attributes)
void PropertyDescriptor::setAccessorDescriptor(GetterSetter* accessor, unsigned attributes)
{
- ASSERT(attributes & (Getter | Setter));
- ASSERT(accessor->getter() || accessor->setter());
- ASSERT(!accessor->getter() == !(attributes & Getter));
- ASSERT(!accessor->setter() == !(attributes & Setter));
+ ASSERT(attributes & Accessor);
+ attributes &= ~ReadOnly; // FIXME: we should be able to ASSERT this!
+
m_attributes = attributes;
- m_getter = accessor->getter();
- m_setter = accessor->setter();
- m_attributes &= ~ReadOnly;
+ m_getter = accessor->getter() ? accessor->getter() : jsUndefined();
+ m_setter = accessor->setter() ? accessor->setter() : jsUndefined();
m_seenAttributes = EnumerablePresent | ConfigurablePresent;
}
@@ -151,14 +156,14 @@ void PropertyDescriptor::setConfigurable(bool configurable)
void PropertyDescriptor::setSetter(JSValue setter)
{
m_setter = setter;
- m_attributes |= Setter;
+ m_attributes |= Accessor;
m_attributes &= ~ReadOnly;
}
void PropertyDescriptor::setGetter(JSValue getter)
{
m_getter = getter;
- m_attributes |= Getter;
+ m_attributes |= Accessor;
m_attributes &= ~ReadOnly;
}
@@ -217,6 +222,7 @@ unsigned PropertyDescriptor::attributesWithOverride(const PropertyDescriptor& ot
unsigned PropertyDescriptor::attributesOverridingCurrent(const PropertyDescriptor& current) const
{
+ unsigned currentAttributes = current.m_attributes;
unsigned overrideMask = 0;
if (writablePresent())
overrideMask |= ReadOnly;
@@ -225,8 +231,8 @@ unsigned PropertyDescriptor::attributesOverridingCurrent(const PropertyDescripto
if (configurablePresent())
overrideMask |= DontDelete;
if (isAccessorDescriptor())
- overrideMask |= (Getter | Setter);
- return (m_attributes & overrideMask) | (current.m_attributes & ~overrideMask);
+ overrideMask |= Accessor;
+ return (m_attributes & overrideMask) | (currentAttributes & ~overrideMask);
}
}
diff --git a/Source/JavaScriptCore/runtime/PropertyDescriptor.h b/Source/JavaScriptCore/runtime/PropertyDescriptor.h
index 3d481b25e..98af02e66 100644
--- a/Source/JavaScriptCore/runtime/PropertyDescriptor.h
+++ b/Source/JavaScriptCore/runtime/PropertyDescriptor.h
@@ -41,25 +41,27 @@ namespace JSC {
, m_seenAttributes(0)
{
}
- bool writable() const;
- bool enumerable() const;
- bool configurable() const;
- bool isDataDescriptor() const;
+ JS_EXPORT_PRIVATE bool writable() const;
+ JS_EXPORT_PRIVATE bool enumerable() const;
+ JS_EXPORT_PRIVATE bool configurable() const;
+ JS_EXPORT_PRIVATE bool isDataDescriptor() const;
bool isGenericDescriptor() const;
- bool isAccessorDescriptor() const;
+ JS_EXPORT_PRIVATE bool isAccessorDescriptor() const;
unsigned attributes() const { return m_attributes; }
JSValue value() const { return m_value; }
- JSValue getter() const;
- JSValue setter() const;
- void setUndefined();
- void setDescriptor(JSValue value, unsigned attributes);
+ JS_EXPORT_PRIVATE JSValue getter() const;
+ JS_EXPORT_PRIVATE JSValue setter() const;
+ JSObject* getterObject() const;
+ JSObject* setterObject() const;
+ JS_EXPORT_PRIVATE void setUndefined();
+ JS_EXPORT_PRIVATE void setDescriptor(JSValue value, unsigned attributes);
void setAccessorDescriptor(GetterSetter* accessor, unsigned attributes);
- void setWritable(bool);
- void setEnumerable(bool);
- void setConfigurable(bool);
+ JS_EXPORT_PRIVATE void setWritable(bool);
+ JS_EXPORT_PRIVATE void setEnumerable(bool);
+ JS_EXPORT_PRIVATE void setConfigurable(bool);
void setValue(JSValue value) { m_value = value; }
- void setSetter(JSValue);
- void setGetter(JSValue);
+ JS_EXPORT_PRIVATE void setSetter(JSValue);
+ JS_EXPORT_PRIVATE void setGetter(JSValue);
bool isEmpty() const { return !(m_value || m_getter || m_setter || m_seenAttributes); }
bool writablePresent() const { return m_seenAttributes & WritablePresent; }
bool enumerablePresent() const { return m_seenAttributes & EnumerablePresent; }
@@ -72,7 +74,7 @@ namespace JSC {
unsigned attributesOverridingCurrent(const PropertyDescriptor& current) const;
private:
- static unsigned defaultAttributes;
+ JS_EXPORTDATA static unsigned defaultAttributes;
bool operator==(const PropertyDescriptor&){ return false; }
enum { WritablePresent = 1, EnumerablePresent = 2, ConfigurablePresent = 4};
// May be a getter/setter
diff --git a/Source/JavaScriptCore/runtime/PropertyNameArray.h b/Source/JavaScriptCore/runtime/PropertyNameArray.h
index 0da930f17..dabda945b 100644
--- a/Source/JavaScriptCore/runtime/PropertyNameArray.h
+++ b/Source/JavaScriptCore/runtime/PropertyNameArray.h
@@ -69,7 +69,7 @@ namespace JSC {
JSGlobalData* globalData() { return m_globalData; }
void add(const Identifier& identifier) { add(identifier.impl()); }
- void add(StringImpl*);
+ JS_EXPORT_PRIVATE void add(StringImpl*);
void addKnownUnique(StringImpl* identifier) { m_data->propertyNameVector().append(Identifier(m_globalData, identifier)); }
Identifier& operator[](unsigned i) { return m_data->propertyNameVector()[i]; }
diff --git a/Source/JavaScriptCore/runtime/PropertySlot.h b/Source/JavaScriptCore/runtime/PropertySlot.h
index 8557e6d24..cfedf7876 100644
--- a/Source/JavaScriptCore/runtime/PropertySlot.h
+++ b/Source/JavaScriptCore/runtime/PropertySlot.h
@@ -218,7 +218,7 @@ namespace JSC {
return m_getValue;
}
private:
- JSValue functionGetter(ExecState*) const;
+ JS_EXPORT_PRIVATE JSValue functionGetter(ExecState*) const;
GetValueFunc m_getValue;
GetIndexValueFunc m_getIndexValue;
diff --git a/Source/JavaScriptCore/runtime/RegExp.cpp b/Source/JavaScriptCore/runtime/RegExp.cpp
index 0d513d2cc..69bca5df0 100644
--- a/Source/JavaScriptCore/runtime/RegExp.cpp
+++ b/Source/JavaScriptCore/runtime/RegExp.cpp
@@ -330,68 +330,52 @@ void RegExp::compileIfNecessary(JSGlobalData& globalData, Yarr::YarrCharSize cha
compile(&globalData, charSize);
}
-
-int RegExp::match(JSGlobalData& globalData, const UString& s, int startOffset, Vector<int, 32>* ovector)
+int RegExp::match(JSGlobalData& globalData, const UString& s, unsigned startOffset, Vector<int, 32>* ovector)
{
- if (startOffset < 0)
- startOffset = 0;
-
#if ENABLE(REGEXP_TRACING)
m_rtMatchCallCount++;
#endif
- if (static_cast<unsigned>(startOffset) > s.length() || s.isNull())
- return -1;
-
- if (m_state != ParseError) {
- compileIfNecessary(globalData, s.is8Bit() ? Yarr::Char8 : Yarr::Char16);
-
- int offsetVectorSize = (m_numSubpatterns + 1) * 2;
- int* offsetVector;
- Vector<int, 32> nonReturnedOvector;
- if (ovector) {
- ovector->resize(offsetVectorSize);
- offsetVector = ovector->data();
- } else {
- nonReturnedOvector.resize(offsetVectorSize);
- offsetVector = nonReturnedOvector.data();
- }
+ ASSERT(m_state != ParseError);
+ compileIfNecessary(globalData, s.is8Bit() ? Yarr::Char8 : Yarr::Char16);
- ASSERT(offsetVector);
- // Initialize offsetVector with the return value (index 0) and the
- // first subpattern start indicies (even index values) set to -1.
- // No need to init the subpattern end indicies.
- for (unsigned j = 0, i = 0; i < m_numSubpatterns + 1; j += 2, i++)
- offsetVector[j] = -1;
+ int offsetVectorSize = (m_numSubpatterns + 1) * 2;
+ int* offsetVector;
+ Vector<int, 32> nonReturnedOvector;
+ if (ovector) {
+ ovector->resize(offsetVectorSize);
+ offsetVector = ovector->data();
+ } else {
+ nonReturnedOvector.resize(offsetVectorSize);
+ offsetVector = nonReturnedOvector.data();
+ }
+ ASSERT(offsetVector);
- int result;
+ int result;
#if ENABLE(YARR_JIT)
- if (m_state == JITCode) {
- if (s.is8Bit())
- result = Yarr::execute(m_representation->m_regExpJITCode, s.characters8(), startOffset, s.length(), offsetVector);
- else
- result = Yarr::execute(m_representation->m_regExpJITCode, s.characters16(), startOffset, s.length(), offsetVector);
+ if (m_state == JITCode) {
+ if (s.is8Bit())
+ result = Yarr::execute(m_representation->m_regExpJITCode, s.characters8(), startOffset, s.length(), offsetVector);
+ else
+ result = Yarr::execute(m_representation->m_regExpJITCode, s.characters16(), startOffset, s.length(), offsetVector);
#if ENABLE(YARR_JIT_DEBUG)
- matchCompareWithInterpreter(s, startOffset, offsetVector, result);
+ matchCompareWithInterpreter(s, startOffset, offsetVector, result);
#endif
- } else
+ } else
#endif
- result = Yarr::interpret(m_representation->m_regExpBytecode.get(), s, startOffset, s.length(), offsetVector);
- ASSERT(result >= -1);
+ result = Yarr::interpret(m_representation->m_regExpBytecode.get(), s, startOffset, s.length(), offsetVector);
+ ASSERT(result >= -1);
#if REGEXP_FUNC_TEST_DATA_GEN
- RegExpFunctionalTestCollector::get()->outputOneTest(this, s, startOffset, offsetVector, result);
+ RegExpFunctionalTestCollector::get()->outputOneTest(this, s, startOffset, offsetVector, result);
#endif
#if ENABLE(REGEXP_TRACING)
- if (result != -1)
- m_rtMatchFoundCount++;
+ if (result != -1)
+ m_rtMatchFoundCount++;
#endif
- return result;
- }
-
- return -1;
+ return result;
}
void RegExp::invalidateCode()
diff --git a/Source/JavaScriptCore/runtime/RegExp.h b/Source/JavaScriptCore/runtime/RegExp.h
index 65eb48499..d0201cbfb 100644
--- a/Source/JavaScriptCore/runtime/RegExp.h
+++ b/Source/JavaScriptCore/runtime/RegExp.h
@@ -35,13 +35,13 @@ namespace JSC {
struct RegExpRepresentation;
class JSGlobalData;
- RegExpFlags regExpFlags(const UString&);
+ JS_EXPORT_PRIVATE RegExpFlags regExpFlags(const UString&);
class RegExp : public JSCell {
public:
typedef JSCell Base;
- static RegExp* create(JSGlobalData&, const UString& pattern, RegExpFlags);
+ JS_EXPORT_PRIVATE static RegExp* create(JSGlobalData&, const UString& pattern, RegExpFlags);
static void destroy(JSCell*);
bool global() const { return m_flags & FlagGlobal; }
@@ -53,7 +53,7 @@ namespace JSC {
bool isValid() const { return !m_constructionError && m_flags != InvalidFlags; }
const char* errorMessage() const { return m_constructionError; }
- int match(JSGlobalData&, const UString&, int startOffset, Vector<int, 32>* ovector = 0);
+ JS_EXPORT_PRIVATE int match(JSGlobalData&, const UString&, unsigned startOffset, Vector<int, 32>* ovector = 0);
unsigned numSubpatterns() const { return m_numSubpatterns; }
bool hasCode()
@@ -72,7 +72,7 @@ namespace JSC {
return Structure::create(globalData, globalObject, prototype, TypeInfo(LeafType, 0), &s_info);
}
- static JS_EXPORTDATA const ClassInfo s_info;
+ static const ClassInfo s_info;
RegExpKey key() { return RegExpKey(m_flags, m_patternString); }
diff --git a/Source/JavaScriptCore/runtime/RegExpConstructor.cpp b/Source/JavaScriptCore/runtime/RegExpConstructor.cpp
index 05832ed0c..53e880e70 100644
--- a/Source/JavaScriptCore/runtime/RegExpConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/RegExpConstructor.cpp
@@ -97,9 +97,18 @@ const ClassInfo RegExpMatchesArray::s_info = {"Array", &JSArray::s_info, 0, 0, C
@end
*/
+RegExpResult& RegExpResult::operator=(const RegExpConstructorPrivate& rhs)
+{
+ this->input = rhs.input;
+ this->ovector = rhs.lastOvector();
+ this->lastNumSubPatterns = rhs.lastNumSubPatterns;
+
+ return *this;
+}
+
+
RegExpConstructor::RegExpConstructor(JSGlobalObject* globalObject, Structure* structure)
: InternalFunction(globalObject, structure)
- , d(adoptPtr(new RegExpConstructorPrivate))
{
}
@@ -122,27 +131,14 @@ void RegExpConstructor::destroy(JSCell* cell)
RegExpMatchesArray::RegExpMatchesArray(ExecState* exec)
: JSArray(exec->globalData(), exec->lexicalGlobalObject()->regExpMatchesArrayStructure())
+ , m_didFillArrayInstance(false)
{
}
-void RegExpMatchesArray::finishCreation(JSGlobalData& globalData, RegExpConstructorPrivate* data)
+void RegExpMatchesArray::finishCreation(JSGlobalData& globalData, const RegExpConstructorPrivate& data)
{
- Base::finishCreation(globalData, data->lastNumSubPatterns + 1);
- RegExpConstructorPrivate* d = new RegExpConstructorPrivate;
- d->input = data->lastInput;
- d->lastInput = data->lastInput;
- d->lastNumSubPatterns = data->lastNumSubPatterns;
- unsigned offsetVectorSize = (data->lastNumSubPatterns + 1) * 2; // only copying the result part of the vector
- d->lastOvector().resize(offsetVectorSize);
- memcpy(d->lastOvector().data(), data->lastOvector().data(), offsetVectorSize * sizeof(int));
- // d->multiline is not needed, and remains uninitialized
-
- setSubclassData(d);
-}
-
-RegExpMatchesArray::~RegExpMatchesArray()
-{
- delete static_cast<RegExpConstructorPrivate*>(subclassData());
+ Base::finishCreation(globalData, data.lastNumSubPatterns + 1);
+ m_regExpResult = data;
}
void RegExpMatchesArray::destroy(JSCell* cell)
@@ -152,65 +148,61 @@ void RegExpMatchesArray::destroy(JSCell* cell)
void RegExpMatchesArray::fillArrayInstance(ExecState* exec)
{
- RegExpConstructorPrivate* d = static_cast<RegExpConstructorPrivate*>(subclassData());
- ASSERT(d);
-
- unsigned lastNumSubpatterns = d->lastNumSubPatterns;
+ unsigned lastNumSubpatterns = m_regExpResult.lastNumSubPatterns;
for (unsigned i = 0; i <= lastNumSubpatterns; ++i) {
- int start = d->lastOvector()[2 * i];
+ int start = m_regExpResult.ovector[2 * i];
if (start >= 0)
- JSArray::putByIndex(this, exec, i, jsSubstring(exec, d->lastInput, start, d->lastOvector()[2 * i + 1] - start));
+ JSArray::putByIndex(this, exec, i, jsSubstring(exec, m_regExpResult.input, start, m_regExpResult.ovector[2 * i + 1] - start));
else
JSArray::putByIndex(this, exec, i, jsUndefined());
}
PutPropertySlot slot;
- JSArray::put(this, exec, exec->propertyNames().index, jsNumber(d->lastOvector()[0]), slot);
- JSArray::put(this, exec, exec->propertyNames().input, jsString(exec, d->input), slot);
+ JSArray::put(this, exec, exec->propertyNames().index, jsNumber(m_regExpResult.ovector[0]), slot);
+ JSArray::put(this, exec, exec->propertyNames().input, jsString(exec, m_regExpResult.input), slot);
- delete d;
- setSubclassData(0);
+ m_didFillArrayInstance = true;
}
JSObject* RegExpConstructor::arrayOfMatches(ExecState* exec) const
{
- return RegExpMatchesArray::create(exec, d.get());
+ return RegExpMatchesArray::create(exec, d);
}
JSValue RegExpConstructor::getBackref(ExecState* exec, unsigned i) const
{
- if (!d->lastOvector().isEmpty() && i <= d->lastNumSubPatterns) {
- int start = d->lastOvector()[2 * i];
+ if (!d.lastOvector().isEmpty() && i <= d.lastNumSubPatterns) {
+ int start = d.lastOvector()[2 * i];
if (start >= 0)
- return jsSubstring(exec, d->lastInput, start, d->lastOvector()[2 * i + 1] - start);
+ return jsSubstring(exec, d.lastInput, start, d.lastOvector()[2 * i + 1] - start);
}
return jsEmptyString(exec);
}
JSValue RegExpConstructor::getLastParen(ExecState* exec) const
{
- unsigned i = d->lastNumSubPatterns;
+ unsigned i = d.lastNumSubPatterns;
if (i > 0) {
- ASSERT(!d->lastOvector().isEmpty());
- int start = d->lastOvector()[2 * i];
+ ASSERT(!d.lastOvector().isEmpty());
+ int start = d.lastOvector()[2 * i];
if (start >= 0)
- return jsSubstring(exec, d->lastInput, start, d->lastOvector()[2 * i + 1] - start);
+ return jsSubstring(exec, d.lastInput, start, d.lastOvector()[2 * i + 1] - start);
}
return jsEmptyString(exec);
}
JSValue RegExpConstructor::getLeftContext(ExecState* exec) const
{
- if (!d->lastOvector().isEmpty())
- return jsSubstring(exec, d->lastInput, 0, d->lastOvector()[0]);
+ if (!d.lastOvector().isEmpty())
+ return jsSubstring(exec, d.lastInput, 0, d.lastOvector()[0]);
return jsEmptyString(exec);
}
JSValue RegExpConstructor::getRightContext(ExecState* exec) const
{
- if (!d->lastOvector().isEmpty())
- return jsSubstring(exec, d->lastInput, d->lastOvector()[1], d->lastInput.length() - d->lastOvector()[1]);
+ if (!d.lastOvector().isEmpty())
+ return jsSubstring(exec, d.lastInput, d.lastOvector()[1], d.lastInput.length() - d.lastOvector()[1]);
return jsEmptyString(exec);
}
@@ -306,7 +298,7 @@ void RegExpConstructor::put(JSCell* cell, ExecState* exec, const Identifier& pro
void setRegExpConstructorInput(ExecState* exec, JSObject* baseObject, JSValue value)
{
- asRegExpConstructor(baseObject)->setInput(value.toString(exec));
+ asRegExpConstructor(baseObject)->setInput(value.toString(exec)->value(exec));
}
void setRegExpConstructorMultiline(ExecState* exec, JSObject* baseObject, JSValue value)
@@ -331,13 +323,13 @@ JSObject* constructRegExp(ExecState* exec, JSGlobalObject* globalObject, const A
return asObject(arg0);
}
- UString pattern = arg0.isUndefined() ? UString("") : arg0.toString(exec);
+ UString pattern = arg0.isUndefined() ? UString("") : arg0.toString(exec)->value(exec);
if (exec->hadException())
return 0;
RegExpFlags flags = NoFlags;
if (!arg1.isUndefined()) {
- flags = regExpFlags(arg1.toString(exec));
+ flags = regExpFlags(arg1.toString(exec)->value(exec));
if (exec->hadException())
return 0;
if (flags == InvalidFlags)
@@ -377,24 +369,24 @@ CallType RegExpConstructor::getCallData(JSCell*, CallData& callData)
void RegExpConstructor::setInput(const UString& input)
{
- d->input = input;
+ d.input = input;
}
const UString& RegExpConstructor::input() const
{
// Can detect a distinct initial state that is invisible to JavaScript, by checking for null
// state (since jsString turns null strings to empty strings).
- return d->input;
+ return d.input;
}
void RegExpConstructor::setMultiline(bool multiline)
{
- d->multiline = multiline;
+ d.multiline = multiline;
}
bool RegExpConstructor::multiline() const
{
- return d->multiline;
+ return d.multiline;
}
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/RegExpConstructor.h b/Source/JavaScriptCore/runtime/RegExpConstructor.h
index 0a43da70a..08a96b544 100644
--- a/Source/JavaScriptCore/runtime/RegExpConstructor.h
+++ b/Source/JavaScriptCore/runtime/RegExpConstructor.h
@@ -55,6 +55,21 @@ namespace JSC {
unsigned lastOvectorIndex : 1;
};
+ struct RegExpResult {
+ WTF_MAKE_FAST_ALLOCATED;
+ public:
+ RegExpResult()
+ : lastNumSubPatterns(0)
+ {
+ }
+
+ RegExpResult& operator=(const RegExpConstructorPrivate&);
+
+ UString input;
+ unsigned lastNumSubPatterns;
+ Vector<int, 32> ovector;
+ };
+
class RegExpConstructor : public InternalFunction {
public:
typedef InternalFunction Base;
@@ -102,7 +117,7 @@ namespace JSC {
static ConstructType getConstructData(JSCell*, ConstructData&);
static CallType getCallData(JSCell*, CallData&);
- OwnPtr<RegExpConstructorPrivate> d;
+ RegExpConstructorPrivate d;
};
RegExpConstructor* asRegExpConstructor(JSValue);
@@ -122,20 +137,20 @@ namespace JSC {
*/
ALWAYS_INLINE void RegExpConstructor::performMatch(JSGlobalData& globalData, RegExp* r, const UString& s, int startOffset, int& position, int& length, int** ovector)
{
- position = r->match(globalData, s, startOffset, &d->tempOvector());
+ position = r->match(globalData, s, startOffset, &d.tempOvector());
if (ovector)
- *ovector = d->tempOvector().data();
+ *ovector = d.tempOvector().data();
if (position != -1) {
- ASSERT(!d->tempOvector().isEmpty());
+ ASSERT(!d.tempOvector().isEmpty());
- length = d->tempOvector()[1] - d->tempOvector()[0];
+ length = d.tempOvector()[1] - d.tempOvector()[0];
- d->input = s;
- d->lastInput = s;
- d->changeLastOvector();
- d->lastNumSubPatterns = r->numSubpatterns();
+ d.input = s;
+ d.lastInput = s;
+ d.changeLastOvector();
+ d.lastNumSubPatterns = r->numSubpatterns();
}
}
diff --git a/Source/JavaScriptCore/runtime/RegExpMatchesArray.h b/Source/JavaScriptCore/runtime/RegExpMatchesArray.h
index a0a8a8e98..c34920d8d 100644
--- a/Source/JavaScriptCore/runtime/RegExpMatchesArray.h
+++ b/Source/JavaScriptCore/runtime/RegExpMatchesArray.h
@@ -31,30 +31,29 @@ namespace JSC {
public:
typedef JSArray Base;
- static RegExpMatchesArray* create(ExecState* exec, RegExpConstructorPrivate* ctorPrivate)
+ static RegExpMatchesArray* create(ExecState* exec, const RegExpConstructorPrivate& ctorPrivate)
{
RegExpMatchesArray* regExp = new (NotNull, allocateCell<RegExpMatchesArray>(*exec->heap())) RegExpMatchesArray(exec);
regExp->finishCreation(exec->globalData(), ctorPrivate);
return regExp;
}
- ~RegExpMatchesArray();
static void destroy(JSCell*);
- static JS_EXPORTDATA const ClassInfo s_info;
-
+ static const ClassInfo s_info;
+
static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
{
return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
}
-
+
protected:
- void finishCreation(JSGlobalData&, RegExpConstructorPrivate* data);
+ void finishCreation(JSGlobalData&, const RegExpConstructorPrivate& data);
private:
static bool getOwnPropertySlot(JSCell* cell, ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
RegExpMatchesArray* thisObject = jsCast<RegExpMatchesArray*>(cell);
- if (thisObject->subclassData())
+ if (!thisObject->m_didFillArrayInstance)
thisObject->fillArrayInstance(exec);
return JSArray::getOwnPropertySlot(thisObject, exec, propertyName, slot);
}
@@ -62,7 +61,7 @@ namespace JSC {
static bool getOwnPropertySlotByIndex(JSCell* cell, ExecState* exec, unsigned propertyName, PropertySlot& slot)
{
RegExpMatchesArray* thisObject = jsCast<RegExpMatchesArray*>(cell);
- if (thisObject->subclassData())
+ if (!thisObject->m_didFillArrayInstance)
thisObject->fillArrayInstance(exec);
return JSArray::getOwnPropertySlotByIndex(thisObject, exec, propertyName, slot);
}
@@ -70,7 +69,7 @@ namespace JSC {
static bool getOwnPropertyDescriptor(JSObject* object, ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
{
RegExpMatchesArray* thisObject = jsCast<RegExpMatchesArray*>(object);
- if (thisObject->subclassData())
+ if (!thisObject->m_didFillArrayInstance)
thisObject->fillArrayInstance(exec);
return JSArray::getOwnPropertyDescriptor(thisObject, exec, propertyName, descriptor);
}
@@ -78,7 +77,7 @@ namespace JSC {
static void put(JSCell* cell, ExecState* exec, const Identifier& propertyName, JSValue v, PutPropertySlot& slot)
{
RegExpMatchesArray* thisObject = jsCast<RegExpMatchesArray*>(cell);
- if (thisObject->subclassData())
+ if (!thisObject->m_didFillArrayInstance)
thisObject->fillArrayInstance(exec);
JSArray::put(thisObject, exec, propertyName, v, slot);
}
@@ -86,7 +85,7 @@ namespace JSC {
static void putByIndex(JSCell* cell, ExecState* exec, unsigned propertyName, JSValue v)
{
RegExpMatchesArray* thisObject = jsCast<RegExpMatchesArray*>(cell);
- if (thisObject->subclassData())
+ if (!thisObject->m_didFillArrayInstance)
thisObject->fillArrayInstance(exec);
JSArray::putByIndex(thisObject, exec, propertyName, v);
}
@@ -94,7 +93,7 @@ namespace JSC {
static bool deleteProperty(JSCell* cell, ExecState* exec, const Identifier& propertyName)
{
RegExpMatchesArray* thisObject = jsCast<RegExpMatchesArray*>(cell);
- if (thisObject->subclassData())
+ if (!thisObject->m_didFillArrayInstance)
thisObject->fillArrayInstance(exec);
return JSArray::deleteProperty(thisObject, exec, propertyName);
}
@@ -102,7 +101,7 @@ namespace JSC {
static bool deletePropertyByIndex(JSCell* cell, ExecState* exec, unsigned propertyName)
{
RegExpMatchesArray* thisObject = jsCast<RegExpMatchesArray*>(cell);
- if (thisObject->subclassData())
+ if (!thisObject->m_didFillArrayInstance)
thisObject->fillArrayInstance(exec);
return JSArray::deletePropertyByIndex(thisObject, exec, propertyName);
}
@@ -110,12 +109,15 @@ namespace JSC {
static void getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& arr, EnumerationMode mode = ExcludeDontEnumProperties)
{
RegExpMatchesArray* thisObject = jsCast<RegExpMatchesArray*>(object);
- if (thisObject->subclassData())
+ if (!thisObject->m_didFillArrayInstance)
thisObject->fillArrayInstance(exec);
JSArray::getOwnPropertyNames(thisObject, exec, arr, mode);
}
void fillArrayInstance(ExecState*);
+
+ RegExpResult m_regExpResult;
+ bool m_didFillArrayInstance;
};
}
diff --git a/Source/JavaScriptCore/runtime/RegExpObject.cpp b/Source/JavaScriptCore/runtime/RegExpObject.cpp
index 4553f7ad0..4c192ff90 100644
--- a/Source/JavaScriptCore/runtime/RegExpObject.cpp
+++ b/Source/JavaScriptCore/runtime/RegExpObject.cpp
@@ -231,7 +231,7 @@ JSValue RegExpObject::exec(ExecState* exec)
bool RegExpObject::match(ExecState* exec)
{
RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor();
- UString input = exec->argument(0).toString(exec);
+ UString input = exec->argument(0).toString(exec)->value(exec);
JSGlobalData* globalData = &exec->globalData();
if (!regExp()->global()) {
int position;
diff --git a/Source/JavaScriptCore/runtime/RegExpObject.h b/Source/JavaScriptCore/runtime/RegExpObject.h
index 4e84d3831..081a7f111 100644
--- a/Source/JavaScriptCore/runtime/RegExpObject.h
+++ b/Source/JavaScriptCore/runtime/RegExpObject.h
@@ -75,8 +75,8 @@ namespace JSC {
}
protected:
- RegExpObject(JSGlobalObject*, Structure*, RegExp*);
- void finishCreation(JSGlobalObject*);
+ JS_EXPORT_PRIVATE RegExpObject(JSGlobalObject*, Structure*, RegExp*);
+ JS_EXPORT_PRIVATE void finishCreation(JSGlobalObject*);
static void destroy(JSCell*);
static const unsigned StructureFlags = OverridesVisitChildren | OverridesGetOwnPropertySlot | Base::StructureFlags;
diff --git a/Source/JavaScriptCore/runtime/RegExpPrototype.cpp b/Source/JavaScriptCore/runtime/RegExpPrototype.cpp
index 6c79f9428..9074e97c3 100644
--- a/Source/JavaScriptCore/runtime/RegExpPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/RegExpPrototype.cpp
@@ -110,13 +110,13 @@ EncodedJSValue JSC_HOST_CALL regExpProtoFuncCompile(ExecState* exec)
return throwVMError(exec, createTypeError(exec, "Cannot supply flags when constructing one RegExp from another."));
regExp = asRegExpObject(arg0)->regExp();
} else {
- UString pattern = !exec->argumentCount() ? UString("") : arg0.toString(exec);
+ UString pattern = !exec->argumentCount() ? UString("") : arg0.toString(exec)->value(exec);
if (exec->hadException())
return JSValue::encode(jsUndefined());
RegExpFlags flags = NoFlags;
if (!arg1.isUndefined()) {
- flags = regExpFlags(arg1.toString(exec));
+ flags = regExpFlags(arg1.toString(exec)->value(exec));
if (exec->hadException())
return JSValue::encode(jsUndefined());
if (flags == InvalidFlags)
@@ -153,7 +153,7 @@ EncodedJSValue JSC_HOST_CALL regExpProtoFuncToString(ExecState* exec)
postfix[index++] = 'i';
if (thisObject->get(exec, exec->propertyNames().multiline).toBoolean(exec))
postfix[index] = 'm';
- UString source = thisObject->get(exec, exec->propertyNames().source).toString(exec);
+ UString source = thisObject->get(exec, exec->propertyNames().source).toString(exec)->value(exec);
// If source is empty, use "/(?:)/" to avoid colliding with comment syntax
return JSValue::encode(jsMakeNontrivialString(exec, "/", source.length() ? source : UString("(?:)"), postfix));
}
diff --git a/Source/JavaScriptCore/runtime/SamplingCounter.h b/Source/JavaScriptCore/runtime/SamplingCounter.h
index 664b0280e..329a5cfd3 100644
--- a/Source/JavaScriptCore/runtime/SamplingCounter.h
+++ b/Source/JavaScriptCore/runtime/SamplingCounter.h
@@ -46,7 +46,7 @@ public:
m_counter += count;
}
- static void dump();
+ JS_EXPORT_PRIVATE static void dump();
int64_t* addressOfCounter() { return &m_counter; }
@@ -74,7 +74,7 @@ protected:
AbstractSamplingCounter** m_referer;
// Null object used to detect end of static chain.
static AbstractSamplingCounter s_abstractSamplingCounterChainEnd;
- static AbstractSamplingCounter* s_abstractSamplingCounterChain;
+ JS_EXPORTDATA static AbstractSamplingCounter* s_abstractSamplingCounterChain;
static bool s_completed;
};
diff --git a/Source/JavaScriptCore/runtime/SmallStrings.h b/Source/JavaScriptCore/runtime/SmallStrings.h
index 9c6ed9a32..cd8e63095 100644
--- a/Source/JavaScriptCore/runtime/SmallStrings.h
+++ b/Source/JavaScriptCore/runtime/SmallStrings.h
@@ -60,7 +60,7 @@ namespace JSC {
return m_singleCharacterStrings[character];
}
- StringImpl* singleCharacterStringRep(unsigned char character);
+ JS_EXPORT_PRIVATE StringImpl* singleCharacterStringRep(unsigned char character);
void finalizeSmallStrings();
void clear();
@@ -72,8 +72,8 @@ namespace JSC {
private:
static const unsigned singleCharacterStringCount = maxSingleCharacterString + 1;
- void createEmptyString(JSGlobalData*);
- void createSingleCharacterString(JSGlobalData*, unsigned char);
+ JS_EXPORT_PRIVATE void createEmptyString(JSGlobalData*);
+ JS_EXPORT_PRIVATE void createSingleCharacterString(JSGlobalData*, unsigned char);
JSString* m_emptyString;
JSString* m_singleCharacterStrings[singleCharacterStringCount];
diff --git a/Source/JavaScriptCore/runtime/StringConstructor.cpp b/Source/JavaScriptCore/runtime/StringConstructor.cpp
index d2f75a060..e03a87f03 100644
--- a/Source/JavaScriptCore/runtime/StringConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/StringConstructor.cpp
@@ -95,10 +95,7 @@ static EncodedJSValue JSC_HOST_CALL constructWithStringConstructor(ExecState* ex
if (!exec->argumentCount())
return JSValue::encode(StringObject::create(exec, globalObject->stringObjectStructure()));
- JSString* string = exec->argument(0).isString()
- ? asString(exec->argument(0))
- : jsString(exec, exec->argument(0).toString(exec));
- return JSValue::encode(StringObject::create(exec, globalObject->stringObjectStructure(), string));
+ return JSValue::encode(StringObject::create(exec, globalObject->stringObjectStructure(), exec->argument(0).toString(exec)));
}
ConstructType StringConstructor::getConstructData(JSCell*, ConstructData& constructData)
@@ -111,7 +108,7 @@ static EncodedJSValue JSC_HOST_CALL callStringConstructor(ExecState* exec)
{
if (!exec->argumentCount())
return JSValue::encode(jsEmptyString(exec));
- return JSValue::encode(jsString(exec, exec->argument(0).toString(exec)));
+ return JSValue::encode(exec->argument(0).toString(exec));
}
CallType StringConstructor::getCallData(JSCell*, CallData& callData)
diff --git a/Source/JavaScriptCore/runtime/StringObject.h b/Source/JavaScriptCore/runtime/StringObject.h
index 528668691..248c71601 100644
--- a/Source/JavaScriptCore/runtime/StringObject.h
+++ b/Source/JavaScriptCore/runtime/StringObject.h
@@ -64,9 +64,9 @@ namespace JSC {
}
protected:
- void finishCreation(JSGlobalData&, JSString*);
+ JS_EXPORT_PRIVATE void finishCreation(JSGlobalData&, JSString*);
static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesGetPropertyNames | JSWrapperObject::StructureFlags;
- StringObject(JSGlobalData&, Structure*);
+ JS_EXPORT_PRIVATE StringObject(JSGlobalData&, Structure*);
};
StringObject* asStringObject(JSValue);
diff --git a/Source/JavaScriptCore/runtime/StringPrototype.cpp b/Source/JavaScriptCore/runtime/StringPrototype.cpp
index 740916a69..63c00e27e 100644
--- a/Source/JavaScriptCore/runtime/StringPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/StringPrototype.cpp
@@ -170,9 +170,10 @@ static inline JSString* jsStringWithReuse(ExecState* exec, JSValue originalValue
return jsString(exec, string);
}
+template <typename CharType>
static NEVER_INLINE UString substituteBackreferencesSlow(const UString& replacement, const UString& source, const int* ovector, RegExp* reg, size_t i)
{
- Vector<UChar> substitutedReplacement;
+ Vector<CharType> substitutedReplacement;
int offset = 0;
do {
if (i + 1 == replacement.length())
@@ -182,7 +183,7 @@ static NEVER_INLINE UString substituteBackreferencesSlow(const UString& replacem
if (ref == '$') {
// "$$" -> "$"
++i;
- substitutedReplacement.append(replacement.characters() + offset, i - offset);
+ substitutedReplacement.append(replacement.getCharacters<CharType>() + offset, i - offset);
offset = i + 1;
continue;
}
@@ -222,15 +223,15 @@ static NEVER_INLINE UString substituteBackreferencesSlow(const UString& replacem
continue;
if (i - offset)
- substitutedReplacement.append(replacement.characters() + offset, i - offset);
+ substitutedReplacement.append(replacement.getCharacters<CharType>() + offset, i - offset);
i += 1 + advance;
offset = i + 1;
if (backrefStart >= 0)
- substitutedReplacement.append(source.characters() + backrefStart, backrefLength);
+ substitutedReplacement.append(source.getCharacters<CharType>() + backrefStart, backrefLength);
} while ((i = replacement.find('$', i + 1)) != notFound);
if (replacement.length() - offset)
- substitutedReplacement.append(replacement.characters() + offset, replacement.length() - offset);
+ substitutedReplacement.append(replacement.getCharacters<CharType>() + offset, replacement.length() - offset);
substitutedReplacement.shrinkToFit();
return UString::adopt(substitutedReplacement);
@@ -239,8 +240,11 @@ static NEVER_INLINE UString substituteBackreferencesSlow(const UString& replacem
static inline UString substituteBackreferences(const UString& replacement, const UString& source, const int* ovector, RegExp* reg)
{
size_t i = replacement.find('$', 0);
- if (UNLIKELY(i != notFound))
- return substituteBackreferencesSlow(replacement, source, ovector, reg, i);
+ if (UNLIKELY(i != notFound)) {
+ if (replacement.is8Bit() && source.is8Bit())
+ return substituteBackreferencesSlow<LChar>(replacement, source, ovector, reg, i);
+ return substituteBackreferencesSlow<UChar>(replacement, source, ovector, reg, i);
+ }
return replacement;
}
@@ -398,13 +402,54 @@ static ALWAYS_INLINE JSValue jsSpliceSubstringsWithSeparators(ExecState* exec, J
return jsString(exec, impl.release());
}
+static NEVER_INLINE EncodedJSValue removeUsingRegExpSearch(ExecState* exec, JSString* string, const UString& source, RegExp* regExp)
+{
+ int lastIndex = 0;
+ unsigned startPosition = 0;
+
+ Vector<StringRange, 16> sourceRanges;
+ JSGlobalData* globalData = &exec->globalData();
+ RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor();
+ unsigned sourceLen = source.length();
+
+ while (true) {
+ int matchIndex;
+ int matchLen = 0;
+ int* ovector;
+ regExpConstructor->performMatch(*globalData, regExp, source, startPosition, matchIndex, matchLen, &ovector);
+ if (matchIndex < 0)
+ break;
+
+ if (lastIndex < matchIndex)
+ sourceRanges.append(StringRange(lastIndex, matchIndex - lastIndex));
+
+ lastIndex = matchIndex + matchLen;
+ startPosition = lastIndex;
+
+ // special case of empty match
+ if (!matchLen) {
+ startPosition++;
+ if (startPosition > sourceLen)
+ break;
+ }
+ }
+
+ if (!lastIndex)
+ return JSValue::encode(string);
+
+ if (static_cast<unsigned>(lastIndex) < sourceLen)
+ sourceRanges.append(StringRange(lastIndex, sourceLen - lastIndex));
+
+ return JSValue::encode(jsSpliceSubstrings(exec, string, source, sourceRanges.data(), sourceRanges.size()));
+}
+
static NEVER_INLINE EncodedJSValue replaceUsingRegExpSearch(ExecState* exec, JSString* string, JSValue searchValue, JSValue replaceValue)
{
UString replacementString;
CallData callData;
CallType callType = getCallData(replaceValue, callData);
if (callType == CallTypeNone)
- replacementString = replaceValue.toString(exec);
+ replacementString = replaceValue.toString(exec)->value(exec);
const UString& source = string->value(exec);
unsigned sourceLen = source.length();
@@ -413,45 +458,10 @@ static NEVER_INLINE EncodedJSValue replaceUsingRegExpSearch(ExecState* exec, JSS
RegExp* regExp = asRegExpObject(searchValue)->regExp();
bool global = regExp->global();
- RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor();
-
- // Optimization for substring removal (replace with empty).
- if (global && callType == CallTypeNone && !replacementString.length()) {
- int lastIndex = 0;
- unsigned startPosition = 0;
-
- Vector<StringRange, 16> sourceRanges;
- JSGlobalData* globalData = &exec->globalData();
- while (true) {
- int matchIndex;
- int matchLen = 0;
- int* ovector;
- regExpConstructor->performMatch(*globalData, regExp, source, startPosition, matchIndex, matchLen, &ovector);
- if (matchIndex < 0)
- break;
-
- if (lastIndex < matchIndex)
- sourceRanges.append(StringRange(lastIndex, matchIndex - lastIndex));
-
- lastIndex = matchIndex + matchLen;
- startPosition = lastIndex;
-
- // special case of empty match
- if (!matchLen) {
- startPosition++;
- if (startPosition > sourceLen)
- break;
- }
- }
-
- if (!lastIndex)
- return JSValue::encode(string);
-
- if (static_cast<unsigned>(lastIndex) < sourceLen)
- sourceRanges.append(StringRange(lastIndex, sourceLen - lastIndex));
+ if (global && callType == CallTypeNone && !replacementString.length())
+ return removeUsingRegExpSearch(exec, string, source, regExp);
- return JSValue::encode(jsSpliceSubstrings(exec, string, source, sourceRanges.data(), sourceRanges.size()));
- }
+ RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor();
int lastIndex = 0;
unsigned startPosition = 0;
@@ -496,10 +506,7 @@ static NEVER_INLINE EncodedJSValue replaceUsingRegExpSearch(ExecState* exec, JSS
cachedCall.setThis(jsUndefined());
JSValue result = cachedCall.call();
- if (LIKELY(result.isString()))
- replacements.append(asString(result)->value(exec));
- else
- replacements.append(result.toString(cachedCall.newCallFrame(exec)));
+ replacements.append(result.toString(cachedCall.newCallFrame(exec))->value(exec));
if (exec->hadException())
break;
@@ -541,10 +548,7 @@ static NEVER_INLINE EncodedJSValue replaceUsingRegExpSearch(ExecState* exec, JSS
cachedCall.setThis(jsUndefined());
JSValue result = cachedCall.call();
- if (LIKELY(result.isString()))
- replacements.append(asString(result)->value(exec));
- else
- replacements.append(result.toString(cachedCall.newCallFrame(exec)));
+ replacements.append(result.toString(cachedCall.newCallFrame(exec))->value(exec));
if (exec->hadException())
break;
@@ -588,7 +592,7 @@ static NEVER_INLINE EncodedJSValue replaceUsingRegExpSearch(ExecState* exec, JSS
args.append(jsNumber(completeMatchStart));
args.append(string);
- replacements.append(call(exec, replaceValue, callType, callData, jsUndefined(), args).toString(exec));
+ replacements.append(call(exec, replaceValue, callType, callData, jsUndefined(), args).toString(exec)->value(exec));
if (exec->hadException())
break;
} else {
@@ -627,7 +631,7 @@ static NEVER_INLINE EncodedJSValue replaceUsingRegExpSearch(ExecState* exec, JSS
static NEVER_INLINE EncodedJSValue replaceUsingStringSearch(ExecState* exec, JSString* jsString, JSValue searchValue, JSValue replaceValue)
{
const UString& string = jsString->value(exec);
- UString searchString = searchValue.toString(exec);
+ UString searchString = searchValue.toString(exec)->value(exec);
if (exec->hadException())
return JSValue::encode(jsUndefined());
@@ -647,7 +651,7 @@ static NEVER_INLINE EncodedJSValue replaceUsingStringSearch(ExecState* exec, JSS
return JSValue::encode(jsUndefined());
}
- UString replaceString = replaceValue.toString(exec);
+ UString replaceString = replaceValue.toString(exec)->value(exec);
if (exec->hadException())
return JSValue::encode(jsUndefined());
@@ -659,12 +663,9 @@ static NEVER_INLINE EncodedJSValue replaceUsingStringSearch(ExecState* exec, JSS
EncodedJSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec)
{
JSValue thisValue = exec->hostThisValue();
- if (!thisValue.isString()) {
- if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible
- return throwVMTypeError(exec);
- thisValue = jsString(exec, thisValue.toString(exec));
- }
- JSString* string = asString(thisValue);
+ if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible
+ return throwVMTypeError(exec);
+ JSString* string = thisValue.toString(exec);
JSValue searchValue = exec->argument(0);
JSValue replaceValue = exec->argument(1);
@@ -692,7 +693,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncCharAt(ExecState* exec)
JSValue thisValue = exec->hostThisValue();
if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible
return throwVMTypeError(exec);
- UString s = thisValue.toString(exec);
+ UString s = thisValue.toString(exec)->value(exec);
unsigned len = s.length();
JSValue a0 = exec->argument(0);
if (a0.isUInt32()) {
@@ -712,7 +713,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncCharCodeAt(ExecState* exec)
JSValue thisValue = exec->hostThisValue();
if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible
return throwVMTypeError(exec);
- UString s = thisValue.toString(exec);
+ UString s = thisValue.toString(exec)->value(exec);
unsigned len = s.length();
JSValue a0 = exec->argument(0);
if (a0.isUInt32()) {
@@ -733,12 +734,9 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncCharCodeAt(ExecState* exec)
EncodedJSValue JSC_HOST_CALL stringProtoFuncConcat(ExecState* exec)
{
JSValue thisValue = exec->hostThisValue();
- if (thisValue.isString() && (exec->argumentCount() == 1)) {
- JSValue v = exec->argument(0);
- return JSValue::encode(v.isString()
- ? jsString(exec, asString(thisValue), asString(v))
- : jsString(exec, asString(thisValue), jsString(&exec->globalData(), v.toString(exec))));
- }
+ if (thisValue.isString() && (exec->argumentCount() == 1))
+ return JSValue::encode(jsString(exec, asString(thisValue), exec->argument(0).toString(exec)));
+
if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible
return throwVMTypeError(exec);
return JSValue::encode(jsStringFromArguments(exec, thisValue));
@@ -749,12 +747,12 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncIndexOf(ExecState* exec)
JSValue thisValue = exec->hostThisValue();
if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible
return throwVMTypeError(exec);
- UString s = thisValue.toString(exec);
+ UString s = thisValue.toString(exec)->value(exec);
int len = s.length();
JSValue a0 = exec->argument(0);
JSValue a1 = exec->argument(1);
- UString u2 = a0.toString(exec);
+ UString u2 = a0.toString(exec)->value(exec);
int pos;
if (a1.isUndefined())
pos = 0;
@@ -780,13 +778,13 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncLastIndexOf(ExecState* exec)
JSValue thisValue = exec->hostThisValue();
if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible
return throwVMTypeError(exec);
- UString s = thisValue.toString(exec);
+ UString s = thisValue.toString(exec)->value(exec);
int len = s.length();
JSValue a0 = exec->argument(0);
JSValue a1 = exec->argument(1);
- UString u2 = a0.toString(exec);
+ UString u2 = a0.toString(exec)->value(exec);
double dpos = a1.toIntegerPreserveNaN(exec);
if (dpos < 0)
dpos = 0;
@@ -804,7 +802,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncMatch(ExecState* exec)
JSValue thisValue = exec->hostThisValue();
if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible
return throwVMTypeError(exec);
- UString s = thisValue.toString(exec);
+ UString s = thisValue.toString(exec)->value(exec);
JSGlobalData* globalData = &exec->globalData();
JSValue a0 = exec->argument(0);
@@ -819,7 +817,9 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncMatch(ExecState* exec)
* replaced with the result of the expression new RegExp(regexp).
* Per ECMA 15.10.4.1, if a0 is undefined substitute the empty string.
*/
- reg = RegExp::create(exec->globalData(), a0.isUndefined() ? UString("") : a0.toString(exec), NoFlags);
+ reg = RegExp::create(exec->globalData(), a0.isUndefined() ? UString("") : a0.toString(exec)->value(exec), NoFlags);
+ if (!reg->isValid())
+ return throwVMError(exec, createSyntaxError(exec, reg->errorMessage()));
}
RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor();
int pos;
@@ -854,7 +854,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncSearch(ExecState* exec)
JSValue thisValue = exec->hostThisValue();
if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible
return throwVMTypeError(exec);
- UString s = thisValue.toString(exec);
+ UString s = thisValue.toString(exec)->value(exec);
JSGlobalData* globalData = &exec->globalData();
JSValue a0 = exec->argument(0);
@@ -869,7 +869,9 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncSearch(ExecState* exec)
* replaced with the result of the expression new RegExp(regexp).
* Per ECMA 15.10.4.1, if a0 is undefined substitute the empty string.
*/
- reg = RegExp::create(exec->globalData(), a0.isUndefined() ? UString("") : a0.toString(exec), NoFlags);
+ reg = RegExp::create(exec->globalData(), a0.isUndefined() ? UString("") : a0.toString(exec)->value(exec), NoFlags);
+ if (!reg->isValid())
+ return throwVMError(exec, createSyntaxError(exec, reg->errorMessage()));
}
RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor();
int pos;
@@ -883,7 +885,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncSlice(ExecState* exec)
JSValue thisValue = exec->hostThisValue();
if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible
return throwVMTypeError(exec);
- UString s = thisValue.toString(exec);
+ UString s = thisValue.toString(exec)->value(exec);
int len = s.length();
JSValue a0 = exec->argument(0);
@@ -915,7 +917,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncSplit(ExecState* exec)
// 2. Let S be the result of calling ToString, giving it the this value as its argument.
// 6. Let s be the number of characters in S.
- UString input = thisValue.toString(exec);
+ UString input = thisValue.toString(exec)->value(exec);
// 3. Let A be a new array created as if by the expression new Array()
// where Array is the standard built-in constructor with that name.
@@ -1017,7 +1019,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncSplit(ExecState* exec)
}
}
} else {
- UString separator = separatorValue.toString(exec);
+ UString separator = separatorValue.toString(exec)->value(exec);
// 9. If lim == 0, return A.
if (!limit)
@@ -1104,7 +1106,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncSubstr(ExecState* exec)
// CheckObjectCoercible
return throwVMTypeError(exec);
} else {
- uString = thisValue.toString(exec);
+ uString = thisValue.toString(exec)->value(exec);
if (exec->hadException())
return JSValue::encode(jsUndefined());
len = uString.length();
@@ -1134,24 +1136,16 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncSubstr(ExecState* exec)
EncodedJSValue JSC_HOST_CALL stringProtoFuncSubstring(ExecState* exec)
{
JSValue thisValue = exec->hostThisValue();
- int len;
- JSString* jsString = 0;
- UString uString;
- if (thisValue.isString()) {
- jsString = static_cast<JSString*>(thisValue.asCell());
- len = jsString->length();
- } else if (thisValue.isUndefinedOrNull()) {
- // CheckObjectCoercible
+ if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible
return throwVMTypeError(exec);
- } else {
- uString = thisValue.toString(exec);
- if (exec->hadException())
- return JSValue::encode(jsUndefined());
- len = uString.length();
- }
+
+ JSString* jsString = thisValue.toString(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
JSValue a0 = exec->argument(0);
JSValue a1 = exec->argument(1);
+ int len = jsString->length();
double start = a0.toNumber(exec);
double end;
@@ -1175,9 +1169,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncSubstring(ExecState* exec)
}
unsigned substringStart = static_cast<unsigned>(start);
unsigned substringLength = static_cast<unsigned>(end) - substringStart;
- if (jsString)
- return JSValue::encode(jsSubstring(exec, jsString, substringStart, substringLength));
- return JSValue::encode(jsSubstring(exec, uString, substringStart, substringLength));
+ return JSValue::encode(jsSubstring(exec, jsString, substringStart, substringLength));
}
EncodedJSValue JSC_HOST_CALL stringProtoFuncToLowerCase(ExecState* exec)
@@ -1185,16 +1177,16 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncToLowerCase(ExecState* exec)
JSValue thisValue = exec->hostThisValue();
if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible
return throwVMTypeError(exec);
- JSString* sVal = thisValue.isString() ? asString(thisValue) : jsString(exec, thisValue.toString(exec));
+ JSString* sVal = thisValue.toString(exec);
const UString& s = sVal->value(exec);
int sSize = s.length();
if (!sSize)
return JSValue::encode(sVal);
- StringImpl* ourImpl = s.impl();
+ StringImpl* ourImpl = s.impl();
RefPtr<StringImpl> lower = ourImpl->lower();
- if (ourImpl == lower.get())
+ if (ourImpl == lower)
return JSValue::encode(sVal);
return JSValue::encode(jsString(exec, UString(lower.release())));
}
@@ -1204,39 +1196,18 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncToUpperCase(ExecState* exec)
JSValue thisValue = exec->hostThisValue();
if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible
return throwVMTypeError(exec);
- JSString* sVal = thisValue.isString() ? asString(thisValue) : jsString(exec, thisValue.toString(exec));
+ JSString* sVal = thisValue.toString(exec);
const UString& s = sVal->value(exec);
int sSize = s.length();
if (!sSize)
return JSValue::encode(sVal);
- const UChar* sData = s.characters();
- Vector<UChar> buffer(sSize);
-
- UChar ored = 0;
- for (int i = 0; i < sSize; i++) {
- UChar c = sData[i];
- ored |= c;
- buffer[i] = toASCIIUpper(c);
- }
- if (!(ored & ~0x7f))
- return JSValue::encode(jsString(exec, UString::adopt(buffer)));
-
- bool error;
- int length = Unicode::toUpper(buffer.data(), sSize, sData, sSize, &error);
- if (error) {
- buffer.resize(length);
- length = Unicode::toUpper(buffer.data(), length, sData, sSize, &error);
- if (error)
- return JSValue::encode(sVal);
- }
- if (length == sSize) {
- if (memcmp(buffer.data(), sData, length * sizeof(UChar)) == 0)
- return JSValue::encode(sVal);
- } else
- buffer.resize(length);
- return JSValue::encode(jsString(exec, UString::adopt(buffer)));
+ StringImpl* sImpl = s.impl();
+ RefPtr<StringImpl> upper = sImpl->upper();
+ if (sImpl == upper)
+ return JSValue::encode(sVal);
+ return JSValue::encode(jsString(exec, UString(upper.release())));
}
EncodedJSValue JSC_HOST_CALL stringProtoFuncLocaleCompare(ExecState* exec)
@@ -1247,10 +1218,10 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncLocaleCompare(ExecState* exec)
JSValue thisValue = exec->hostThisValue();
if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible
return throwVMTypeError(exec);
- UString s = thisValue.toString(exec);
+ UString s = thisValue.toString(exec)->value(exec);
JSValue a0 = exec->argument(0);
- return JSValue::encode(jsNumber(localeCompare(s, a0.toString(exec))));
+ return JSValue::encode(jsNumber(localeCompare(s, a0.toString(exec)->value(exec))));
}
EncodedJSValue JSC_HOST_CALL stringProtoFuncBig(ExecState* exec)
@@ -1258,7 +1229,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncBig(ExecState* exec)
JSValue thisValue = exec->hostThisValue();
if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible
return throwVMTypeError(exec);
- UString s = thisValue.toString(exec);
+ UString s = thisValue.toString(exec)->value(exec);
return JSValue::encode(jsMakeNontrivialString(exec, "<big>", s, "</big>"));
}
@@ -1267,7 +1238,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncSmall(ExecState* exec)
JSValue thisValue = exec->hostThisValue();
if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible
return throwVMTypeError(exec);
- UString s = thisValue.toString(exec);
+ UString s = thisValue.toString(exec)->value(exec);
return JSValue::encode(jsMakeNontrivialString(exec, "<small>", s, "</small>"));
}
@@ -1276,7 +1247,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncBlink(ExecState* exec)
JSValue thisValue = exec->hostThisValue();
if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible
return throwVMTypeError(exec);
- UString s = thisValue.toString(exec);
+ UString s = thisValue.toString(exec)->value(exec);
return JSValue::encode(jsMakeNontrivialString(exec, "<blink>", s, "</blink>"));
}
@@ -1285,7 +1256,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncBold(ExecState* exec)
JSValue thisValue = exec->hostThisValue();
if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible
return throwVMTypeError(exec);
- UString s = thisValue.toString(exec);
+ UString s = thisValue.toString(exec)->value(exec);
return JSValue::encode(jsMakeNontrivialString(exec, "<b>", s, "</b>"));
}
@@ -1294,7 +1265,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncFixed(ExecState* exec)
JSValue thisValue = exec->hostThisValue();
if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible
return throwVMTypeError(exec);
- UString s = thisValue.toString(exec);
+ UString s = thisValue.toString(exec)->value(exec);
return JSValue::encode(jsMakeNontrivialString(exec, "<tt>", s, "</tt>"));
}
@@ -1303,7 +1274,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncItalics(ExecState* exec)
JSValue thisValue = exec->hostThisValue();
if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible
return throwVMTypeError(exec);
- UString s = thisValue.toString(exec);
+ UString s = thisValue.toString(exec)->value(exec);
return JSValue::encode(jsMakeNontrivialString(exec, "<i>", s, "</i>"));
}
@@ -1312,7 +1283,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncStrike(ExecState* exec)
JSValue thisValue = exec->hostThisValue();
if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible
return throwVMTypeError(exec);
- UString s = thisValue.toString(exec);
+ UString s = thisValue.toString(exec)->value(exec);
return JSValue::encode(jsMakeNontrivialString(exec, "<strike>", s, "</strike>"));
}
@@ -1321,7 +1292,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncSub(ExecState* exec)
JSValue thisValue = exec->hostThisValue();
if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible
return throwVMTypeError(exec);
- UString s = thisValue.toString(exec);
+ UString s = thisValue.toString(exec)->value(exec);
return JSValue::encode(jsMakeNontrivialString(exec, "<sub>", s, "</sub>"));
}
@@ -1330,7 +1301,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncSup(ExecState* exec)
JSValue thisValue = exec->hostThisValue();
if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible
return throwVMTypeError(exec);
- UString s = thisValue.toString(exec);
+ UString s = thisValue.toString(exec)->value(exec);
return JSValue::encode(jsMakeNontrivialString(exec, "<sup>", s, "</sup>"));
}
@@ -1339,9 +1310,9 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncFontcolor(ExecState* exec)
JSValue thisValue = exec->hostThisValue();
if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible
return throwVMTypeError(exec);
- UString s = thisValue.toString(exec);
+ UString s = thisValue.toString(exec)->value(exec);
JSValue a0 = exec->argument(0);
- return JSValue::encode(jsMakeNontrivialString(exec, "<font color=\"", a0.toString(exec), "\">", s, "</font>"));
+ return JSValue::encode(jsMakeNontrivialString(exec, "<font color=\"", a0.toString(exec)->value(exec), "\">", s, "</font>"));
}
EncodedJSValue JSC_HOST_CALL stringProtoFuncFontsize(ExecState* exec)
@@ -1349,7 +1320,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncFontsize(ExecState* exec)
JSValue thisValue = exec->hostThisValue();
if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible
return throwVMTypeError(exec);
- UString s = thisValue.toString(exec);
+ UString s = thisValue.toString(exec)->value(exec);
JSValue a0 = exec->argument(0);
uint32_t smallInteger;
@@ -1386,7 +1357,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncFontsize(ExecState* exec)
return JSValue::encode(jsNontrivialString(exec, impl));
}
- return JSValue::encode(jsMakeNontrivialString(exec, "<font size=\"", a0.toString(exec), "\">", s, "</font>"));
+ return JSValue::encode(jsMakeNontrivialString(exec, "<font size=\"", a0.toString(exec)->value(exec), "\">", s, "</font>"));
}
EncodedJSValue JSC_HOST_CALL stringProtoFuncAnchor(ExecState* exec)
@@ -1394,9 +1365,9 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncAnchor(ExecState* exec)
JSValue thisValue = exec->hostThisValue();
if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible
return throwVMTypeError(exec);
- UString s = thisValue.toString(exec);
+ UString s = thisValue.toString(exec)->value(exec);
JSValue a0 = exec->argument(0);
- return JSValue::encode(jsMakeNontrivialString(exec, "<a name=\"", a0.toString(exec), "\">", s, "</a>"));
+ return JSValue::encode(jsMakeNontrivialString(exec, "<a name=\"", a0.toString(exec)->value(exec), "\">", s, "</a>"));
}
EncodedJSValue JSC_HOST_CALL stringProtoFuncLink(ExecState* exec)
@@ -1404,9 +1375,9 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncLink(ExecState* exec)
JSValue thisValue = exec->hostThisValue();
if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible
return throwVMTypeError(exec);
- UString s = thisValue.toString(exec);
+ UString s = thisValue.toString(exec)->value(exec);
JSValue a0 = exec->argument(0);
- UString linkText = a0.toString(exec);
+ UString linkText = a0.toString(exec)->value(exec);
unsigned linkTextSize = linkText.length();
unsigned stringSize = s.length();
@@ -1449,7 +1420,7 @@ static inline JSValue trimString(ExecState* exec, JSValue thisValue, int trimKin
{
if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible
return throwTypeError(exec);
- UString str = thisValue.toString(exec);
+ UString str = thisValue.toString(exec)->value(exec);
unsigned left = 0;
if (trimKind & TrimLeft) {
while (left < str.length() && isTrimWhitespace(str[left]))
diff --git a/Source/JavaScriptCore/runtime/Structure.cpp b/Source/JavaScriptCore/runtime/Structure.cpp
index dda8c73e9..f387cf283 100644
--- a/Source/JavaScriptCore/runtime/Structure.cpp
+++ b/Source/JavaScriptCore/runtime/Structure.cpp
@@ -401,17 +401,26 @@ Structure* Structure::despecifyFunctionTransition(JSGlobalData& globalData, Stru
return transition;
}
-Structure* Structure::getterSetterTransition(JSGlobalData& globalData, Structure* structure)
+Structure* Structure::attributeChangeTransition(JSGlobalData& globalData, Structure* structure, const Identifier& propertyName, unsigned attributes)
{
- Structure* transition = create(globalData, structure);
+ if (!structure->isUncacheableDictionary()) {
+ Structure* transition = create(globalData, structure);
- // Don't set m_offset, as one can not transition to this.
+ // Don't set m_offset, as one can not transition to this.
- structure->materializePropertyMapIfNecessary(globalData);
- transition->m_propertyTable = structure->copyPropertyTableForPinning(globalData, transition);
- transition->pin();
+ structure->materializePropertyMapIfNecessary(globalData);
+ transition->m_propertyTable = structure->copyPropertyTableForPinning(globalData, transition);
+ transition->pin();
+
+ structure = transition;
+ }
- return transition;
+ ASSERT(structure->m_propertyTable);
+ PropertyMapEntry* entry = structure->m_propertyTable->find(propertyName.impl()).first;
+ ASSERT(entry);
+ entry->attributes = attributes;
+
+ return structure;
}
Structure* Structure::toDictionaryTransition(JSGlobalData& globalData, Structure* structure, DictionaryKind kind)
diff --git a/Source/JavaScriptCore/runtime/Structure.h b/Source/JavaScriptCore/runtime/Structure.h
index 70e968014..ced296856 100644
--- a/Source/JavaScriptCore/runtime/Structure.h
+++ b/Source/JavaScriptCore/runtime/Structure.h
@@ -84,12 +84,12 @@ namespace JSC {
public:
static void dumpStatistics();
- static Structure* addPropertyTransition(JSGlobalData&, Structure*, const Identifier& propertyName, unsigned attributes, JSCell* specificValue, size_t& offset);
- static Structure* addPropertyTransitionToExistingStructure(Structure*, const Identifier& propertyName, unsigned attributes, JSCell* specificValue, size_t& offset);
+ JS_EXPORT_PRIVATE static Structure* addPropertyTransition(JSGlobalData&, Structure*, const Identifier& propertyName, unsigned attributes, JSCell* specificValue, size_t& offset);
+ JS_EXPORT_PRIVATE static Structure* addPropertyTransitionToExistingStructure(Structure*, const Identifier& propertyName, unsigned attributes, JSCell* specificValue, size_t& offset);
static Structure* removePropertyTransition(JSGlobalData&, Structure*, const Identifier& propertyName, size_t& offset);
- static Structure* changePrototypeTransition(JSGlobalData&, Structure*, JSValue prototype);
- static Structure* despecifyFunctionTransition(JSGlobalData&, Structure*, const Identifier&);
- static Structure* getterSetterTransition(JSGlobalData&, Structure*);
+ JS_EXPORT_PRIVATE static Structure* changePrototypeTransition(JSGlobalData&, Structure*, JSValue prototype);
+ JS_EXPORT_PRIVATE static Structure* despecifyFunctionTransition(JSGlobalData&, Structure*, const Identifier&);
+ static Structure* attributeChangeTransition(JSGlobalData&, Structure*, const Identifier& propertyName, unsigned attributes);
static Structure* toCacheableDictionaryTransition(JSGlobalData&, Structure*);
static Structure* toUncacheableDictionaryTransition(JSGlobalData&, Structure*);
static Structure* sealTransition(JSGlobalData&, Structure*);
@@ -106,7 +106,7 @@ namespace JSC {
static void destroy(JSCell*);
// These should be used with caution.
- size_t addPropertyWithoutTransition(JSGlobalData&, const Identifier& propertyName, unsigned attributes, JSCell* specificValue);
+ JS_EXPORT_PRIVATE size_t addPropertyWithoutTransition(JSGlobalData&, const Identifier& propertyName, unsigned attributes, JSCell* specificValue);
size_t removePropertyWithoutTransition(JSGlobalData&, const Identifier& propertyName);
void setPrototypeWithoutTransition(JSGlobalData& globalData, JSValue prototype) { m_prototype.set(globalData, this, prototype); }
@@ -136,7 +136,7 @@ namespace JSC {
size_t get(JSGlobalData&, const Identifier& propertyName);
size_t get(JSGlobalData&, const UString& name);
- size_t get(JSGlobalData&, StringImpl* propertyName, unsigned& attributes, JSCell*& specificValue);
+ JS_EXPORT_PRIVATE size_t get(JSGlobalData&, StringImpl* propertyName, unsigned& attributes, JSCell*& specificValue);
size_t get(JSGlobalData& globalData, const Identifier& propertyName, unsigned& attributes, JSCell*& specificValue)
{
ASSERT(!propertyName.isNull());
@@ -151,7 +151,7 @@ namespace JSC {
bool isEmpty() const { return m_propertyTable ? m_propertyTable->isEmpty() : m_offset == noOffset; }
- void despecifyDictionaryFunction(JSGlobalData&, const Identifier& propertyName);
+ JS_EXPORT_PRIVATE void despecifyDictionaryFunction(JSGlobalData&, const Identifier& propertyName);
void disableSpecificFunctionTracking() { m_specificFunctionThrashCount = maxSpecificFunctionThrashCount; }
void setEnumerationCache(JSGlobalData&, JSPropertyNameIterator* enumerationCache); // Defined in JSPropertyNameIterator.h.
@@ -196,7 +196,7 @@ namespace JSC {
static JS_EXPORTDATA const ClassInfo s_info;
private:
- Structure(JSGlobalData&, JSGlobalObject*, JSValue prototype, const TypeInfo&, const ClassInfo*);
+ JS_EXPORT_PRIVATE Structure(JSGlobalData&, JSGlobalObject*, JSValue prototype, const TypeInfo&, const ClassInfo*);
Structure(JSGlobalData&);
Structure(JSGlobalData&, const Structure*);
@@ -226,7 +226,7 @@ namespace JSC {
PassOwnPtr<PropertyTable> copyPropertyTable(JSGlobalData&, Structure* owner);
PassOwnPtr<PropertyTable> copyPropertyTableForPinning(JSGlobalData&, Structure* owner);
- void materializePropertyMap(JSGlobalData&);
+ JS_EXPORT_PRIVATE void materializePropertyMap(JSGlobalData&);
void materializePropertyMapIfNecessary(JSGlobalData& globalData)
{
ASSERT(structure()->classInfo() == &s_info);
diff --git a/Source/JavaScriptCore/runtime/TimeoutChecker.h b/Source/JavaScriptCore/runtime/TimeoutChecker.h
index 5925641f8..89d6158cc 100644
--- a/Source/JavaScriptCore/runtime/TimeoutChecker.h
+++ b/Source/JavaScriptCore/runtime/TimeoutChecker.h
@@ -57,9 +57,9 @@ namespace JSC {
--m_startCount;
}
- void reset();
+ JS_EXPORT_PRIVATE void reset();
- bool didTimeOut(ExecState*);
+ JS_EXPORT_PRIVATE bool didTimeOut(ExecState*);
private:
unsigned m_timeoutInterval;
diff --git a/Source/JavaScriptCore/runtime/UString.h b/Source/JavaScriptCore/runtime/UString.h
index c05ae5081..668eb0489 100644
--- a/Source/JavaScriptCore/runtime/UString.h
+++ b/Source/JavaScriptCore/runtime/UString.h
@@ -33,18 +33,18 @@ public:
UString() { }
// Construct a string with UTF-16 data.
- UString(const UChar* characters, unsigned length);
+ JS_EXPORT_PRIVATE UString(const UChar* characters, unsigned length);
// Construct a string with UTF-16 data, from a null-terminated source.
- UString(const UChar*);
+ JS_EXPORT_PRIVATE UString(const UChar*);
// Construct a string with latin1 data.
UString(const LChar* characters, unsigned length);
- UString(const char* characters, unsigned length);
+ JS_EXPORT_PRIVATE UString(const char* characters, unsigned length);
// Construct a string with latin1 data, from a null-terminated source.
UString(const LChar* characters);
- UString(const char* characters);
+ JS_EXPORT_PRIVATE UString(const char* characters);
// Construct a string referencing an existing StringImpl.
UString(StringImpl* impl) : m_impl(impl) { }
@@ -99,9 +99,9 @@ public:
bool is8Bit() const { return m_impl->is8Bit(); }
- CString ascii() const;
+ JS_EXPORT_PRIVATE CString ascii() const;
CString latin1() const;
- CString utf8(bool strict = false) const;
+ JS_EXPORT_PRIVATE CString utf8(bool strict = false) const;
UChar operator[](unsigned index) const
{
@@ -112,11 +112,11 @@ public:
return m_impl->characters16()[index];
}
- static UString number(int);
- static UString number(unsigned);
- static UString number(long);
+ JS_EXPORT_PRIVATE static UString number(int);
+ JS_EXPORT_PRIVATE static UString number(unsigned);
+ JS_EXPORT_PRIVATE static UString number(long);
static UString number(long long);
- static UString number(double);
+ JS_EXPORT_PRIVATE static UString number(double);
// Find a single character or string, also with match function & latin1 forms.
size_t find(UChar c, unsigned start = 0) const
@@ -132,25 +132,17 @@ public:
size_t reverseFind(const UString& str, unsigned start = UINT_MAX) const
{ return m_impl ? m_impl->reverseFind(str.impl(), start) : notFound; }
- UString substringSharingImpl(unsigned pos, unsigned len = UINT_MAX) const;
+ JS_EXPORT_PRIVATE UString substringSharingImpl(unsigned pos, unsigned len = UINT_MAX) const;
private:
RefPtr<StringImpl> m_impl;
};
template<>
-inline const LChar* UString::getCharacters<LChar>() const
-{
- ASSERT(is8Bit());
- return characters8();
-}
+inline const LChar* UString::getCharacters<LChar>() const { return characters8(); }
template<>
-inline const UChar* UString::getCharacters<UChar>() const
-{
- ASSERT(!is8Bit());
- return characters16();
-}
+inline const UChar* UString::getCharacters<UChar>() const { return characters(); }
NEVER_INLINE bool equalSlowCase(const UString& s1, const UString& s2);
@@ -189,10 +181,10 @@ inline bool operator!=(const UString& s1, const UString& s2)
return !JSC::operator==(s1, s2);
}
-bool operator<(const UString& s1, const UString& s2);
-bool operator>(const UString& s1, const UString& s2);
+JS_EXPORT_PRIVATE bool operator<(const UString& s1, const UString& s2);
+JS_EXPORT_PRIVATE bool operator>(const UString& s1, const UString& s2);
-bool operator==(const UString& s1, const char* s2);
+JS_EXPORT_PRIVATE bool operator==(const UString& s1, const char* s2);
inline bool operator!=(const UString& s1, const char* s2)
{
diff --git a/Source/JavaScriptCore/runtime/WriteBarrier.h b/Source/JavaScriptCore/runtime/WriteBarrier.h
index 525fc0926..a7bd7a100 100644
--- a/Source/JavaScriptCore/runtime/WriteBarrier.h
+++ b/Source/JavaScriptCore/runtime/WriteBarrier.h
@@ -40,8 +40,8 @@ class JSGlobalObject;
template<class T> class WriteBarrierBase;
template<> class WriteBarrierBase<JSValue>;
-void slowValidateCell(JSCell*);
-void slowValidateCell(JSGlobalObject*);
+JS_EXPORT_PRIVATE void slowValidateCell(JSCell*);
+JS_EXPORT_PRIVATE void slowValidateCell(JSGlobalObject*);
#if ENABLE(GC_VALIDATION)
template<class T> inline void validateCell(T cell)