summaryrefslogtreecommitdiffstats
path: root/JavaScriptCore/runtime
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2009-08-18 15:36:45 +0100
committerBen Murdoch <benm@google.com>2009-08-18 19:20:06 +0100
commitd227fc870c7a697500a3c900c31baf05fb9a8524 (patch)
treea3fa109aa5bf52fef562ac49d97a2f723889cc71 /JavaScriptCore/runtime
parentf2c627513266faa73f7669058d98c60769fb3524 (diff)
downloadexternal_webkit-d227fc870c7a697500a3c900c31baf05fb9a8524.zip
external_webkit-d227fc870c7a697500a3c900c31baf05fb9a8524.tar.gz
external_webkit-d227fc870c7a697500a3c900c31baf05fb9a8524.tar.bz2
Merge WebKit r47420
Diffstat (limited to 'JavaScriptCore/runtime')
-rw-r--r--JavaScriptCore/runtime/Arguments.h12
-rw-r--r--JavaScriptCore/runtime/ArrayConstructor.cpp14
-rw-r--r--JavaScriptCore/runtime/ArrayConstructor.h2
-rw-r--r--JavaScriptCore/runtime/ArrayPrototype.cpp12
-rw-r--r--JavaScriptCore/runtime/BooleanObject.h5
-rw-r--r--JavaScriptCore/runtime/BooleanPrototype.cpp4
-rw-r--r--JavaScriptCore/runtime/CallData.h4
-rw-r--r--JavaScriptCore/runtime/Collector.cpp52
-rw-r--r--JavaScriptCore/runtime/CommonIdentifiers.h1
-rw-r--r--JavaScriptCore/runtime/Completion.cpp21
-rw-r--r--JavaScriptCore/runtime/ConstructData.h4
-rw-r--r--JavaScriptCore/runtime/DateConstructor.cpp2
-rw-r--r--JavaScriptCore/runtime/DatePrototype.cpp64
-rw-r--r--JavaScriptCore/runtime/Error.cpp6
-rw-r--r--JavaScriptCore/runtime/Error.h1
-rw-r--r--JavaScriptCore/runtime/ExceptionHelpers.cpp10
-rw-r--r--JavaScriptCore/runtime/Executable.cpp216
-rw-r--r--JavaScriptCore/runtime/Executable.h268
-rw-r--r--JavaScriptCore/runtime/FunctionConstructor.cpp32
-rw-r--r--JavaScriptCore/runtime/FunctionConstructor.h4
-rw-r--r--JavaScriptCore/runtime/FunctionPrototype.cpp15
-rw-r--r--JavaScriptCore/runtime/FunctionPrototype.h2
-rw-r--r--JavaScriptCore/runtime/InternalFunction.h2
-rw-r--r--JavaScriptCore/runtime/JSAPIValueWrapper.h1
-rw-r--r--JavaScriptCore/runtime/JSActivation.cpp14
-rw-r--r--JavaScriptCore/runtime/JSActivation.h10
-rw-r--r--JavaScriptCore/runtime/JSArray.cpp20
-rw-r--r--JavaScriptCore/runtime/JSArray.h73
-rw-r--r--JavaScriptCore/runtime/JSByteArray.cpp2
-rw-r--r--JavaScriptCore/runtime/JSCell.h26
-rw-r--r--JavaScriptCore/runtime/JSFunction.cpp42
-rw-r--r--JavaScriptCore/runtime/JSFunction.h57
-rw-r--r--JavaScriptCore/runtime/JSGlobalData.cpp9
-rw-r--r--JavaScriptCore/runtime/JSGlobalData.h5
-rw-r--r--JavaScriptCore/runtime/JSGlobalObject.cpp10
-rw-r--r--JavaScriptCore/runtime/JSGlobalObject.h5
-rw-r--r--JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp14
-rw-r--r--JavaScriptCore/runtime/JSNumberCell.h2
-rw-r--r--JavaScriptCore/runtime/JSONObject.cpp9
-rw-r--r--JavaScriptCore/runtime/JSONObject.h2
-rw-r--r--JavaScriptCore/runtime/JSObject.cpp31
-rw-r--r--JavaScriptCore/runtime/JSObject.h37
-rw-r--r--JavaScriptCore/runtime/JSString.h2
-rw-r--r--JavaScriptCore/runtime/JSType.h1
-rw-r--r--JavaScriptCore/runtime/JSValue.h2
-rw-r--r--JavaScriptCore/runtime/MarkStack.h21
-rw-r--r--JavaScriptCore/runtime/MarkStackWin.cpp6
-rw-r--r--JavaScriptCore/runtime/MathObject.h2
-rw-r--r--JavaScriptCore/runtime/NumberConstructor.h2
-rw-r--r--JavaScriptCore/runtime/NumberObject.h5
-rw-r--r--JavaScriptCore/runtime/ObjectConstructor.cpp1
-rw-r--r--JavaScriptCore/runtime/PropertySlot.cpp3
-rw-r--r--JavaScriptCore/runtime/RegExpConstructor.cpp3
-rw-r--r--JavaScriptCore/runtime/RegExpConstructor.h2
-rw-r--r--JavaScriptCore/runtime/RegExpObject.h2
-rw-r--r--JavaScriptCore/runtime/RegExpPrototype.cpp13
-rw-r--r--JavaScriptCore/runtime/ScopeChain.cpp2
-rw-r--r--JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h2
-rw-r--r--JavaScriptCore/runtime/StringPrototype.cpp19
-rw-r--r--JavaScriptCore/runtime/TypeInfo.h3
-rw-r--r--JavaScriptCore/runtime/UString.cpp92
-rw-r--r--JavaScriptCore/runtime/UString.h4
62 files changed, 969 insertions, 340 deletions
diff --git a/JavaScriptCore/runtime/Arguments.h b/JavaScriptCore/runtime/Arguments.h
index 79fe720..390f7e2 100644
--- a/JavaScriptCore/runtime/Arguments.h
+++ b/JavaScriptCore/runtime/Arguments.h
@@ -28,6 +28,8 @@
#include "JSFunction.h"
#include "JSGlobalObject.h"
#include "Interpreter.h"
+#include "ObjectConstructor.h"
+#include "PrototypeFunction.h"
namespace JSC {
@@ -114,7 +116,7 @@ namespace JSC {
{
function = callFrame->callee();
- CodeBlock* codeBlock = &function->body()->generatedBytecode();
+ CodeBlock* codeBlock = &function->executable()->generatedBytecode();
int numParameters = codeBlock->m_numParameters;
argc = callFrame->argumentCount();
@@ -137,7 +139,7 @@ namespace JSC {
int numArguments;
getArgumentsData(callFrame, callee, firstParameterIndex, argv, numArguments);
- d->numParameters = callee->body()->parameterCount();
+ d->numParameters = callee->executable()->parameterCount();
d->firstParameterIndex = firstParameterIndex;
d->numArguments = numArguments;
@@ -168,7 +170,7 @@ namespace JSC {
: JSObject(callFrame->lexicalGlobalObject()->argumentsStructure())
, d(new ArgumentsData)
{
- ASSERT(!callFrame->callee()->body()->parameterCount());
+ ASSERT(!callFrame->callee()->executable()->parameterCount());
unsigned numArguments = callFrame->argumentCount() - 1;
@@ -214,8 +216,8 @@ namespace JSC {
{
ASSERT(!d()->registerArray);
- size_t numParametersMinusThis = d()->functionBody->generatedBytecode().m_numParameters - 1;
- size_t numVars = d()->functionBody->generatedBytecode().m_numVars;
+ size_t numParametersMinusThis = d()->functionExecutable->generatedBytecode().m_numParameters - 1;
+ size_t numVars = d()->functionExecutable->generatedBytecode().m_numVars;
size_t numLocals = numVars + numParametersMinusThis;
if (!numLocals)
diff --git a/JavaScriptCore/runtime/ArrayConstructor.cpp b/JavaScriptCore/runtime/ArrayConstructor.cpp
index e96bdfc..c60cb0e 100644
--- a/JavaScriptCore/runtime/ArrayConstructor.cpp
+++ b/JavaScriptCore/runtime/ArrayConstructor.cpp
@@ -25,15 +25,19 @@
#include "ArrayConstructor.h"
#include "ArrayPrototype.h"
+#include "Error.h"
#include "JSArray.h"
#include "JSFunction.h"
#include "Lookup.h"
+#include "PrototypeFunction.h"
namespace JSC {
ASSERT_CLASS_FITS_IN_CELL(ArrayConstructor);
+
+static JSValue JSC_HOST_CALL arrayConstructorIsArray(ExecState*, JSObject*, JSValue, const ArgList&);
-ArrayConstructor::ArrayConstructor(ExecState* exec, PassRefPtr<Structure> structure, ArrayPrototype* arrayPrototype)
+ArrayConstructor::ArrayConstructor(ExecState* exec, PassRefPtr<Structure> structure, ArrayPrototype* arrayPrototype, Structure* prototypeFunctionStructure)
: InternalFunction(&exec->globalData(), structure, Identifier(exec, arrayPrototype->classInfo()->className))
{
// ECMA 15.4.3.1 Array.prototype
@@ -41,6 +45,9 @@ ArrayConstructor::ArrayConstructor(ExecState* exec, PassRefPtr<Structure> struct
// no. of arguments for constructor
putDirectWithoutTransition(exec->propertyNames().length, jsNumber(exec, 1), ReadOnly | DontEnum | DontDelete);
+
+ // ES5
+ putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 1, exec->propertyNames().isArray, arrayConstructorIsArray), DontEnum);
}
static JSObject* constructArrayWithSizeQuirk(ExecState* exec, const ArgList& args)
@@ -82,4 +89,9 @@ CallType ArrayConstructor::getCallData(CallData& callData)
return CallTypeHost;
}
+JSValue JSC_HOST_CALL arrayConstructorIsArray(ExecState*, JSObject*, JSValue, const ArgList& args)
+{
+ return jsBoolean(args.at(0).inherits(&JSArray::info));
+}
+
} // namespace JSC
diff --git a/JavaScriptCore/runtime/ArrayConstructor.h b/JavaScriptCore/runtime/ArrayConstructor.h
index 8300d8c..2b79510 100644
--- a/JavaScriptCore/runtime/ArrayConstructor.h
+++ b/JavaScriptCore/runtime/ArrayConstructor.h
@@ -29,7 +29,7 @@ namespace JSC {
class ArrayConstructor : public InternalFunction {
public:
- ArrayConstructor(ExecState*, PassRefPtr<Structure>, ArrayPrototype*);
+ ArrayConstructor(ExecState*, PassRefPtr<Structure>, ArrayPrototype*, Structure*);
virtual ConstructType getConstructData(ConstructData&);
virtual CallType getCallData(CallData&);
diff --git a/JavaScriptCore/runtime/ArrayPrototype.cpp b/JavaScriptCore/runtime/ArrayPrototype.cpp
index 807e59a..95d3ffc 100644
--- a/JavaScriptCore/runtime/ArrayPrototype.cpp
+++ b/JavaScriptCore/runtime/ArrayPrototype.cpp
@@ -75,10 +75,10 @@ static inline bool isNumericCompareFunction(CallType callType, const CallData& c
#if ENABLE(JIT)
// If the JIT is enabled then we need to preserve the invariant that every
// function with a CodeBlock also has JIT code.
- callData.js.functionBody->jitCode(callData.js.scopeChain);
- CodeBlock& codeBlock = callData.js.functionBody->generatedBytecode();
+ callData.js.functionExecutable->jitCode(callData.js.scopeChain);
+ CodeBlock& codeBlock = callData.js.functionExecutable->generatedBytecode();
#else
- CodeBlock& codeBlock = callData.js.functionBody->bytecode(callData.js.scopeChain);
+ CodeBlock& codeBlock = callData.js.functionExecutable->bytecode(callData.js.scopeChain);
#endif
return codeBlock.isNumericCompareFunction();
@@ -144,7 +144,7 @@ static void putProperty(ExecState* exec, JSObject* obj, const Identifier& proper
JSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- if (!thisValue.isObject(&JSArray::info))
+ if (!thisValue.inherits(&JSArray::info))
return throwError(exec, TypeError);
JSObject* thisObj = asArray(thisValue);
@@ -190,7 +190,7 @@ JSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState* exec, JSObject*, JSValue
JSValue JSC_HOST_CALL arrayProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- if (!thisValue.isObject(&JSArray::info))
+ if (!thisValue.inherits(&JSArray::info))
return throwError(exec, TypeError);
JSObject* thisObj = asArray(thisValue);
@@ -298,7 +298,7 @@ JSValue JSC_HOST_CALL arrayProtoFuncConcat(ExecState* exec, JSObject*, JSValue t
ArgList::const_iterator it = args.begin();
ArgList::const_iterator end = args.end();
while (1) {
- if (curArg.isObject(&JSArray::info)) {
+ if (curArg.inherits(&JSArray::info)) {
unsigned length = curArg.get(exec, exec->propertyNames().length).toUInt32(exec);
JSObject* curObject = curArg.toObject(exec);
for (unsigned k = 0; k < length; ++k) {
diff --git a/JavaScriptCore/runtime/BooleanObject.h b/JavaScriptCore/runtime/BooleanObject.h
index cfd55fe..1361e46 100644
--- a/JavaScriptCore/runtime/BooleanObject.h
+++ b/JavaScriptCore/runtime/BooleanObject.h
@@ -31,6 +31,11 @@ namespace JSC {
virtual const ClassInfo* classInfo() const { return &info; }
static const ClassInfo info;
+
+ static PassRefPtr<Structure> createStructure(JSValue prototype)
+ {
+ return Structure::create(prototype, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot | HasDefaultMark));
+ }
};
BooleanObject* asBooleanObject(JSValue);
diff --git a/JavaScriptCore/runtime/BooleanPrototype.cpp b/JavaScriptCore/runtime/BooleanPrototype.cpp
index 703a568..cf4fbd7 100644
--- a/JavaScriptCore/runtime/BooleanPrototype.cpp
+++ b/JavaScriptCore/runtime/BooleanPrototype.cpp
@@ -59,7 +59,7 @@ JSValue JSC_HOST_CALL booleanProtoFuncToString(ExecState* exec, JSObject*, JSVal
if (thisValue == jsBoolean(true))
return jsNontrivialString(exec, "true");
- if (!thisValue.isObject(&BooleanObject::info))
+ if (!thisValue.inherits(&BooleanObject::info))
return throwError(exec, TypeError);
if (asBooleanObject(thisValue)->internalValue() == jsBoolean(false))
@@ -74,7 +74,7 @@ JSValue JSC_HOST_CALL booleanProtoFuncValueOf(ExecState* exec, JSObject*, JSValu
if (thisValue.isBoolean())
return thisValue;
- if (!thisValue.isObject(&BooleanObject::info))
+ if (!thisValue.inherits(&BooleanObject::info))
return throwError(exec, TypeError);
return asBooleanObject(thisValue)->internalValue();
diff --git a/JavaScriptCore/runtime/CallData.h b/JavaScriptCore/runtime/CallData.h
index d5b0172..24c19f9 100644
--- a/JavaScriptCore/runtime/CallData.h
+++ b/JavaScriptCore/runtime/CallData.h
@@ -35,7 +35,7 @@ namespace JSC {
class ArgList;
class ExecState;
- class FunctionBodyNode;
+ class FunctionExecutable;
class JSObject;
class JSValue;
class ScopeChainNode;
@@ -53,7 +53,7 @@ namespace JSC {
NativeFunction function;
} native;
struct {
- FunctionBodyNode* functionBody;
+ FunctionExecutable* functionExecutable;
ScopeChainNode* scopeChain;
} js;
};
diff --git a/JavaScriptCore/runtime/Collector.cpp b/JavaScriptCore/runtime/Collector.cpp
index c188016..f48e243 100644
--- a/JavaScriptCore/runtime/Collector.cpp
+++ b/JavaScriptCore/runtime/Collector.cpp
@@ -23,8 +23,10 @@
#include "ArgList.h"
#include "CallFrame.h"
+#include "CodeBlock.h"
#include "CollectorHeapIterator.h"
#include "Interpreter.h"
+#include "JSArray.h"
#include "JSGlobalObject.h"
#include "JSLock.h"
#include "JSONObject.h"
@@ -59,10 +61,16 @@
#include <windows.h>
+#elif PLATFORM(HAIKU)
+
+#include <OS.h>
+
#elif PLATFORM(UNIX)
#include <stdlib.h>
+#if !PLATFORM(HAIKU)
#include <sys/mman.h>
+#endif
#include <unistd.h>
#if PLATFORM(SOLARIS)
@@ -75,6 +83,13 @@
#include <pthread_np.h>
#endif
+#if PLATFORM(QNX)
+#include <fcntl.h>
+#include <sys/procfs.h>
+#include <stdio.h>
+#include <errno.h>
+#endif
+
#endif
#define DEBUG_COLLECTOR 0
@@ -486,6 +501,33 @@ static void* getStackBase(void* previousFrame)
}
#endif
+#if PLATFORM(QNX)
+static inline void *currentThreadStackBaseQNX()
+{
+ static void* stackBase = 0;
+ static size_t stackSize = 0;
+ static pthread_t stackThread;
+ pthread_t thread = pthread_self();
+ if (stackBase == 0 || thread != stackThread) {
+ struct _debug_thread_info threadInfo;
+ memset(&threadInfo, 0, sizeof(threadInfo));
+ threadInfo.tid = pthread_self();
+ int fd = open("/proc/self", O_RDONLY);
+ if (fd == -1) {
+ LOG_ERROR("Unable to open /proc/self (errno: %d)", errno);
+ return 0;
+ }
+ devctl(fd, DCMD_PROC_TIDSTATUS, &threadInfo, sizeof(threadInfo), 0);
+ close(fd);
+ stackBase = reinterpret_cast<void*>(threadInfo.stkbase);
+ stackSize = threadInfo.stksize;
+ ASSERT(stackBase);
+ stackThread = thread;
+ }
+ return static_cast<char*>(stackBase) + stackSize;
+}
+#endif
+
static inline void* currentThreadStackBase()
{
#if PLATFORM(DARWIN)
@@ -511,6 +553,8 @@ static inline void* currentThreadStackBase()
: "=r" (pTib)
);
return static_cast<void*>(pTib->StackBase);
+#elif PLATFORM(QNX)
+ return currentThreadStackBaseQNX();
#elif PLATFORM(SOLARIS)
stack_t s;
thr_stksegment(&s);
@@ -529,6 +573,10 @@ static inline void* currentThreadStackBase()
stackBase = (void*)info.iBase;
}
return (void*)stackBase;
+#elif PLATFORM(HAIKU)
+ thread_info threadInfo;
+ get_thread_info(find_thread(NULL), &threadInfo);
+ return threadInfo.stack_end;
#elif PLATFORM(UNIX)
static void* stackBase = 0;
static size_t stackSize = 0;
@@ -1091,8 +1139,8 @@ bool Heap::collect()
markStack.append(m_globalData->exception);
m_globalData->interpreter->registerFile().markCallFrames(markStack, this);
m_globalData->smallStrings.mark();
- if (m_globalData->scopeNodeBeingReparsed)
- m_globalData->scopeNodeBeingReparsed->markAggregate(markStack);
+ if (m_globalData->functionCodeBlockBeingReparsed)
+ m_globalData->functionCodeBlockBeingReparsed->markAggregate(markStack);
if (m_globalData->firstStringifierToMark)
JSONObject::markStringifiers(markStack, m_globalData->firstStringifierToMark);
diff --git a/JavaScriptCore/runtime/CommonIdentifiers.h b/JavaScriptCore/runtime/CommonIdentifiers.h
index 148d3dd..678e109 100644
--- a/JavaScriptCore/runtime/CommonIdentifiers.h
+++ b/JavaScriptCore/runtime/CommonIdentifiers.h
@@ -47,6 +47,7 @@
macro(ignoreCase) \
macro(index) \
macro(input) \
+ macro(isArray) \
macro(isPrototypeOf) \
macro(length) \
macro(message) \
diff --git a/JavaScriptCore/runtime/Completion.cpp b/JavaScriptCore/runtime/Completion.cpp
index b8b1581..6ae5aa2 100644
--- a/JavaScriptCore/runtime/Completion.cpp
+++ b/JavaScriptCore/runtime/Completion.cpp
@@ -41,30 +41,27 @@ Completion checkSyntax(ExecState* exec, const SourceCode& source)
{
JSLock lock(exec);
- int errLine;
- UString errMsg;
+ ProgramExecutable program(source);
+ JSObject* error = program.parse(exec);
+ if (error)
+ return Completion(Throw, error);
- RefPtr<ProgramNode> progNode = exec->globalData().parser->parse<ProgramNode>(exec, exec->dynamicGlobalObject()->debugger(), source, &errLine, &errMsg);
- if (!progNode)
- return Completion(Throw, Error::create(exec, SyntaxError, errMsg, errLine, source.provider()->asID(), source.provider()->url()));
return Completion(Normal);
}
Completion evaluate(ExecState* exec, ScopeChain& scopeChain, const SourceCode& source, JSValue thisValue)
{
JSLock lock(exec);
-
- int errLine;
- UString errMsg;
- RefPtr<ProgramNode> programNode = exec->globalData().parser->parse<ProgramNode>(exec, exec->dynamicGlobalObject()->debugger(), source, &errLine, &errMsg);
- if (!programNode)
- return Completion(Throw, Error::create(exec, SyntaxError, errMsg, errLine, source.provider()->asID(), source.provider()->url()));
+ ProgramExecutable program(source);
+ JSObject* error = program.parse(exec);
+ if (error)
+ return Completion(Throw, error);
JSObject* thisObj = (!thisValue || thisValue.isUndefinedOrNull()) ? exec->dynamicGlobalObject() : thisValue.toObject(exec);
JSValue exception;
- JSValue result = exec->interpreter()->execute(programNode.get(), exec, scopeChain.node(), thisObj, &exception);
+ JSValue result = exec->interpreter()->execute(&program, exec, scopeChain.node(), thisObj, &exception);
if (exception) {
if (exception.isObject() && asObject(exception)->isWatchdogException())
diff --git a/JavaScriptCore/runtime/ConstructData.h b/JavaScriptCore/runtime/ConstructData.h
index 9d580d5..6b954a6 100644
--- a/JavaScriptCore/runtime/ConstructData.h
+++ b/JavaScriptCore/runtime/ConstructData.h
@@ -33,7 +33,7 @@ namespace JSC {
class ArgList;
class ExecState;
- class FunctionBodyNode;
+ class FunctionExecutable;
class JSObject;
class JSValue;
class ScopeChainNode;
@@ -51,7 +51,7 @@ namespace JSC {
NativeConstructor function;
} native;
struct {
- FunctionBodyNode* functionBody;
+ FunctionExecutable* functionExecutable;
ScopeChainNode* scopeChain;
} js;
};
diff --git a/JavaScriptCore/runtime/DateConstructor.cpp b/JavaScriptCore/runtime/DateConstructor.cpp
index 2f52cff..1879c3f 100644
--- a/JavaScriptCore/runtime/DateConstructor.cpp
+++ b/JavaScriptCore/runtime/DateConstructor.cpp
@@ -79,7 +79,7 @@ JSObject* constructDate(ExecState* exec, const ArgList& args)
if (numArgs == 0) // new Date() ECMA 15.9.3.3
value = getCurrentUTCTime();
else if (numArgs == 1) {
- if (args.at(0).isObject(&DateInstance::info))
+ if (args.at(0).inherits(&DateInstance::info))
value = asDateInstance(args.at(0))->internalNumber();
else {
JSValue primitive = args.at(0).toPrimitive(exec);
diff --git a/JavaScriptCore/runtime/DatePrototype.cpp b/JavaScriptCore/runtime/DatePrototype.cpp
index e2482f4..54d3cf3 100644
--- a/JavaScriptCore/runtime/DatePrototype.cpp
+++ b/JavaScriptCore/runtime/DatePrototype.cpp
@@ -411,7 +411,7 @@ bool DatePrototype::getOwnPropertySlot(ExecState* exec, const Identifier& proper
JSValue JSC_HOST_CALL dateProtoFuncToString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- if (!thisValue.isObject(&DateInstance::info))
+ if (!thisValue.inherits(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = false;
@@ -428,7 +428,7 @@ JSValue JSC_HOST_CALL dateProtoFuncToString(ExecState* exec, JSObject*, JSValue
JSValue JSC_HOST_CALL dateProtoFuncToUTCString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- if (!thisValue.isObject(&DateInstance::info))
+ if (!thisValue.inherits(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = true;
@@ -445,7 +445,7 @@ JSValue JSC_HOST_CALL dateProtoFuncToUTCString(ExecState* exec, JSObject*, JSVal
JSValue JSC_HOST_CALL dateProtoFuncToISOString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- if (!thisValue.isObject(&DateInstance::info))
+ if (!thisValue.inherits(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = true;
@@ -467,7 +467,7 @@ JSValue JSC_HOST_CALL dateProtoFuncToISOString(ExecState* exec, JSObject*, JSVal
JSValue JSC_HOST_CALL dateProtoFuncToDateString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- if (!thisValue.isObject(&DateInstance::info))
+ if (!thisValue.inherits(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = false;
@@ -484,7 +484,7 @@ JSValue JSC_HOST_CALL dateProtoFuncToDateString(ExecState* exec, JSObject*, JSVa
JSValue JSC_HOST_CALL dateProtoFuncToTimeString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- if (!thisValue.isObject(&DateInstance::info))
+ if (!thisValue.inherits(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = false;
@@ -501,7 +501,7 @@ JSValue JSC_HOST_CALL dateProtoFuncToTimeString(ExecState* exec, JSObject*, JSVa
JSValue JSC_HOST_CALL dateProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
- if (!thisValue.isObject(&DateInstance::info))
+ if (!thisValue.inherits(&DateInstance::info))
return throwError(exec, TypeError);
DateInstance* thisDateObj = asDateInstance(thisValue);
@@ -514,7 +514,7 @@ JSValue JSC_HOST_CALL dateProtoFuncToLocaleString(ExecState* exec, JSObject*, JS
JSValue JSC_HOST_CALL dateProtoFuncToLocaleDateString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
- if (!thisValue.isObject(&DateInstance::info))
+ if (!thisValue.inherits(&DateInstance::info))
return throwError(exec, TypeError);
DateInstance* thisDateObj = asDateInstance(thisValue);
@@ -527,7 +527,7 @@ JSValue JSC_HOST_CALL dateProtoFuncToLocaleDateString(ExecState* exec, JSObject*
JSValue JSC_HOST_CALL dateProtoFuncToLocaleTimeString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
- if (!thisValue.isObject(&DateInstance::info))
+ if (!thisValue.inherits(&DateInstance::info))
return throwError(exec, TypeError);
DateInstance* thisDateObj = asDateInstance(thisValue);
@@ -540,7 +540,7 @@ JSValue JSC_HOST_CALL dateProtoFuncToLocaleTimeString(ExecState* exec, JSObject*
JSValue JSC_HOST_CALL dateProtoFuncGetTime(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- if (!thisValue.isObject(&DateInstance::info))
+ if (!thisValue.inherits(&DateInstance::info))
return throwError(exec, TypeError);
DateInstance* thisDateObj = asDateInstance(thisValue);
@@ -553,7 +553,7 @@ JSValue JSC_HOST_CALL dateProtoFuncGetTime(ExecState* exec, JSObject*, JSValue t
JSValue JSC_HOST_CALL dateProtoFuncGetFullYear(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- if (!thisValue.isObject(&DateInstance::info))
+ if (!thisValue.inherits(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = false;
@@ -570,7 +570,7 @@ JSValue JSC_HOST_CALL dateProtoFuncGetFullYear(ExecState* exec, JSObject*, JSVal
JSValue JSC_HOST_CALL dateProtoFuncGetUTCFullYear(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- if (!thisValue.isObject(&DateInstance::info))
+ if (!thisValue.inherits(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = true;
@@ -587,7 +587,7 @@ JSValue JSC_HOST_CALL dateProtoFuncGetUTCFullYear(ExecState* exec, JSObject*, JS
JSValue JSC_HOST_CALL dateProtoFuncToGMTString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- if (!thisValue.isObject(&DateInstance::info))
+ if (!thisValue.inherits(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = true;
@@ -604,7 +604,7 @@ JSValue JSC_HOST_CALL dateProtoFuncToGMTString(ExecState* exec, JSObject*, JSVal
JSValue JSC_HOST_CALL dateProtoFuncGetMonth(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- if (!thisValue.isObject(&DateInstance::info))
+ if (!thisValue.inherits(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = false;
@@ -621,7 +621,7 @@ JSValue JSC_HOST_CALL dateProtoFuncGetMonth(ExecState* exec, JSObject*, JSValue
JSValue JSC_HOST_CALL dateProtoFuncGetUTCMonth(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- if (!thisValue.isObject(&DateInstance::info))
+ if (!thisValue.inherits(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = true;
@@ -638,7 +638,7 @@ JSValue JSC_HOST_CALL dateProtoFuncGetUTCMonth(ExecState* exec, JSObject*, JSVal
JSValue JSC_HOST_CALL dateProtoFuncGetDate(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- if (!thisValue.isObject(&DateInstance::info))
+ if (!thisValue.inherits(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = false;
@@ -655,7 +655,7 @@ JSValue JSC_HOST_CALL dateProtoFuncGetDate(ExecState* exec, JSObject*, JSValue t
JSValue JSC_HOST_CALL dateProtoFuncGetUTCDate(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- if (!thisValue.isObject(&DateInstance::info))
+ if (!thisValue.inherits(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = true;
@@ -672,7 +672,7 @@ JSValue JSC_HOST_CALL dateProtoFuncGetUTCDate(ExecState* exec, JSObject*, JSValu
JSValue JSC_HOST_CALL dateProtoFuncGetDay(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- if (!thisValue.isObject(&DateInstance::info))
+ if (!thisValue.inherits(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = false;
@@ -689,7 +689,7 @@ JSValue JSC_HOST_CALL dateProtoFuncGetDay(ExecState* exec, JSObject*, JSValue th
JSValue JSC_HOST_CALL dateProtoFuncGetUTCDay(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- if (!thisValue.isObject(&DateInstance::info))
+ if (!thisValue.inherits(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = true;
@@ -706,7 +706,7 @@ JSValue JSC_HOST_CALL dateProtoFuncGetUTCDay(ExecState* exec, JSObject*, JSValue
JSValue JSC_HOST_CALL dateProtoFuncGetHours(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- if (!thisValue.isObject(&DateInstance::info))
+ if (!thisValue.inherits(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = false;
@@ -723,7 +723,7 @@ JSValue JSC_HOST_CALL dateProtoFuncGetHours(ExecState* exec, JSObject*, JSValue
JSValue JSC_HOST_CALL dateProtoFuncGetUTCHours(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- if (!thisValue.isObject(&DateInstance::info))
+ if (!thisValue.inherits(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = true;
@@ -740,7 +740,7 @@ JSValue JSC_HOST_CALL dateProtoFuncGetUTCHours(ExecState* exec, JSObject*, JSVal
JSValue JSC_HOST_CALL dateProtoFuncGetMinutes(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- if (!thisValue.isObject(&DateInstance::info))
+ if (!thisValue.inherits(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = false;
@@ -757,7 +757,7 @@ JSValue JSC_HOST_CALL dateProtoFuncGetMinutes(ExecState* exec, JSObject*, JSValu
JSValue JSC_HOST_CALL dateProtoFuncGetUTCMinutes(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- if (!thisValue.isObject(&DateInstance::info))
+ if (!thisValue.inherits(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = true;
@@ -774,7 +774,7 @@ JSValue JSC_HOST_CALL dateProtoFuncGetUTCMinutes(ExecState* exec, JSObject*, JSV
JSValue JSC_HOST_CALL dateProtoFuncGetSeconds(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- if (!thisValue.isObject(&DateInstance::info))
+ if (!thisValue.inherits(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = false;
@@ -791,7 +791,7 @@ JSValue JSC_HOST_CALL dateProtoFuncGetSeconds(ExecState* exec, JSObject*, JSValu
JSValue JSC_HOST_CALL dateProtoFuncGetUTCSeconds(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- if (!thisValue.isObject(&DateInstance::info))
+ if (!thisValue.inherits(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = true;
@@ -808,7 +808,7 @@ JSValue JSC_HOST_CALL dateProtoFuncGetUTCSeconds(ExecState* exec, JSObject*, JSV
JSValue JSC_HOST_CALL dateProtoFuncGetMilliSeconds(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- if (!thisValue.isObject(&DateInstance::info))
+ if (!thisValue.inherits(&DateInstance::info))
return throwError(exec, TypeError);
DateInstance* thisDateObj = asDateInstance(thisValue);
@@ -823,7 +823,7 @@ JSValue JSC_HOST_CALL dateProtoFuncGetMilliSeconds(ExecState* exec, JSObject*, J
JSValue JSC_HOST_CALL dateProtoFuncGetUTCMilliseconds(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- if (!thisValue.isObject(&DateInstance::info))
+ if (!thisValue.inherits(&DateInstance::info))
return throwError(exec, TypeError);
DateInstance* thisDateObj = asDateInstance(thisValue);
@@ -838,7 +838,7 @@ JSValue JSC_HOST_CALL dateProtoFuncGetUTCMilliseconds(ExecState* exec, JSObject*
JSValue JSC_HOST_CALL dateProtoFuncGetTimezoneOffset(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- if (!thisValue.isObject(&DateInstance::info))
+ if (!thisValue.inherits(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = false;
@@ -855,7 +855,7 @@ JSValue JSC_HOST_CALL dateProtoFuncGetTimezoneOffset(ExecState* exec, JSObject*,
JSValue JSC_HOST_CALL dateProtoFuncSetTime(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
- if (!thisValue.isObject(&DateInstance::info))
+ if (!thisValue.inherits(&DateInstance::info))
return throwError(exec, TypeError);
DateInstance* thisDateObj = asDateInstance(thisValue);
@@ -868,7 +868,7 @@ JSValue JSC_HOST_CALL dateProtoFuncSetTime(ExecState* exec, JSObject*, JSValue t
static JSValue setNewValueFromTimeArgs(ExecState* exec, JSValue thisValue, const ArgList& args, int numArgsToUse, bool inputIsUTC)
{
- if (!thisValue.isObject(&DateInstance::info))
+ if (!thisValue.inherits(&DateInstance::info))
return throwError(exec, TypeError);
DateInstance* thisDateObj = asDateInstance(thisValue);
@@ -899,7 +899,7 @@ static JSValue setNewValueFromTimeArgs(ExecState* exec, JSValue thisValue, const
static JSValue setNewValueFromDateArgs(ExecState* exec, JSValue thisValue, const ArgList& args, int numArgsToUse, bool inputIsUTC)
{
- if (!thisValue.isObject(&DateInstance::info))
+ if (!thisValue.inherits(&DateInstance::info))
return throwError(exec, TypeError);
DateInstance* thisDateObj = asDateInstance(thisValue);
@@ -1020,7 +1020,7 @@ JSValue JSC_HOST_CALL dateProtoFuncSetUTCFullYear(ExecState* exec, JSObject*, JS
JSValue JSC_HOST_CALL dateProtoFuncSetYear(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
- if (!thisValue.isObject(&DateInstance::info))
+ if (!thisValue.inherits(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = false;
@@ -1062,7 +1062,7 @@ JSValue JSC_HOST_CALL dateProtoFuncSetYear(ExecState* exec, JSObject*, JSValue t
JSValue JSC_HOST_CALL dateProtoFuncGetYear(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- if (!thisValue.isObject(&DateInstance::info))
+ if (!thisValue.inherits(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = false;
diff --git a/JavaScriptCore/runtime/Error.cpp b/JavaScriptCore/runtime/Error.cpp
index db1d8cc..ddd4bc4 100644
--- a/JavaScriptCore/runtime/Error.cpp
+++ b/JavaScriptCore/runtime/Error.cpp
@@ -97,6 +97,12 @@ JSObject* Error::create(ExecState* exec, ErrorType type, const char* message)
return create(exec, type, message, -1, -1, NULL);
}
+JSObject* throwError(ExecState* exec, JSObject* error)
+{
+ exec->setException(error);
+ return error;
+}
+
JSObject* throwError(ExecState* exec, ErrorType type)
{
JSObject* error = Error::create(exec, type, UString(), -1, -1, NULL);
diff --git a/JavaScriptCore/runtime/Error.h b/JavaScriptCore/runtime/Error.h
index adf7fdf..e959cff 100644
--- a/JavaScriptCore/runtime/Error.h
+++ b/JavaScriptCore/runtime/Error.h
@@ -59,6 +59,7 @@ namespace JSC {
JSObject* throwError(ExecState*, ErrorType, const UString& message);
JSObject* throwError(ExecState*, ErrorType, const char* message);
JSObject* throwError(ExecState*, ErrorType);
+ JSObject* throwError(ExecState*, JSObject*);
} // namespace JSC
diff --git a/JavaScriptCore/runtime/ExceptionHelpers.cpp b/JavaScriptCore/runtime/ExceptionHelpers.cpp
index e63594c..cc18b95 100644
--- a/JavaScriptCore/runtime/ExceptionHelpers.cpp
+++ b/JavaScriptCore/runtime/ExceptionHelpers.cpp
@@ -74,7 +74,7 @@ JSValue createUndefinedVariableError(ExecState* exec, const Identifier& ident, u
int line = codeBlock->expressionRangeForBytecodeOffset(exec, bytecodeOffset, divotPoint, startOffset, endOffset);
UString message = "Can't find variable: ";
message.append(ident.ustring());
- JSObject* exception = Error::create(exec, ReferenceError, message, line, codeBlock->ownerNode()->sourceID(), codeBlock->ownerNode()->sourceURL());
+ JSObject* exception = Error::create(exec, ReferenceError, message, line, codeBlock->ownerExecutable()->sourceID(), codeBlock->ownerExecutable()->sourceURL());
exception->putWithAttributes(exec, Identifier(exec, expressionBeginOffsetPropertyName), jsNumber(exec, divotPoint - startOffset), ReadOnly | DontDelete);
exception->putWithAttributes(exec, Identifier(exec, expressionCaretOffsetPropertyName), jsNumber(exec, divotPoint), ReadOnly | DontDelete);
exception->putWithAttributes(exec, Identifier(exec, expressionEndOffsetPropertyName), jsNumber(exec, divotPoint + endOffset), ReadOnly | DontDelete);
@@ -136,7 +136,7 @@ JSObject* createInvalidParamError(ExecState* exec, const char* op, JSValue value
int divotPoint = 0;
int line = codeBlock->expressionRangeForBytecodeOffset(exec, bytecodeOffset, divotPoint, startOffset, endOffset);
UString errorMessage = createErrorMessage(exec, codeBlock, line, divotPoint, divotPoint + endOffset, value, message);
- JSObject* exception = Error::create(exec, TypeError, errorMessage, line, codeBlock->ownerNode()->sourceID(), codeBlock->ownerNode()->sourceURL());
+ JSObject* exception = Error::create(exec, TypeError, errorMessage, line, codeBlock->ownerExecutable()->sourceID(), codeBlock->ownerExecutable()->sourceURL());
exception->putWithAttributes(exec, Identifier(exec, expressionBeginOffsetPropertyName), jsNumber(exec, divotPoint - startOffset), ReadOnly | DontDelete);
exception->putWithAttributes(exec, Identifier(exec, expressionCaretOffsetPropertyName), jsNumber(exec, divotPoint), ReadOnly | DontDelete);
exception->putWithAttributes(exec, Identifier(exec, expressionEndOffsetPropertyName), jsNumber(exec, divotPoint + endOffset), ReadOnly | DontDelete);
@@ -157,7 +157,7 @@ JSObject* createNotAConstructorError(ExecState* exec, JSValue value, unsigned by
startPoint++;
UString errorMessage = createErrorMessage(exec, codeBlock, line, startPoint, divotPoint, value, "not a constructor");
- JSObject* exception = Error::create(exec, TypeError, errorMessage, line, codeBlock->ownerNode()->sourceID(), codeBlock->ownerNode()->sourceURL());
+ JSObject* exception = Error::create(exec, TypeError, errorMessage, line, codeBlock->ownerExecutable()->sourceID(), codeBlock->ownerExecutable()->sourceURL());
exception->putWithAttributes(exec, Identifier(exec, expressionBeginOffsetPropertyName), jsNumber(exec, divotPoint - startOffset), ReadOnly | DontDelete);
exception->putWithAttributes(exec, Identifier(exec, expressionCaretOffsetPropertyName), jsNumber(exec, divotPoint), ReadOnly | DontDelete);
exception->putWithAttributes(exec, Identifier(exec, expressionEndOffsetPropertyName), jsNumber(exec, divotPoint + endOffset), ReadOnly | DontDelete);
@@ -171,7 +171,7 @@ JSValue createNotAFunctionError(ExecState* exec, JSValue value, unsigned bytecod
int divotPoint = 0;
int line = codeBlock->expressionRangeForBytecodeOffset(exec, bytecodeOffset, divotPoint, startOffset, endOffset);
UString errorMessage = createErrorMessage(exec, codeBlock, line, divotPoint - startOffset, divotPoint, value, "not a function");
- JSObject* exception = Error::create(exec, TypeError, errorMessage, line, codeBlock->ownerNode()->sourceID(), codeBlock->ownerNode()->sourceURL());
+ JSObject* exception = Error::create(exec, TypeError, errorMessage, line, codeBlock->ownerExecutable()->sourceID(), codeBlock->ownerExecutable()->sourceURL());
exception->putWithAttributes(exec, Identifier(exec, expressionBeginOffsetPropertyName), jsNumber(exec, divotPoint - startOffset), ReadOnly | DontDelete);
exception->putWithAttributes(exec, Identifier(exec, expressionCaretOffsetPropertyName), jsNumber(exec, divotPoint), ReadOnly | DontDelete);
exception->putWithAttributes(exec, Identifier(exec, expressionEndOffsetPropertyName), jsNumber(exec, divotPoint + endOffset), ReadOnly | DontDelete);
@@ -201,7 +201,7 @@ JSObject* createNotAnObjectError(ExecState* exec, JSNotAnObjectErrorStub* error,
int divotPoint = 0;
int line = codeBlock->expressionRangeForBytecodeOffset(exec, bytecodeOffset, divotPoint, startOffset, endOffset);
UString errorMessage = createErrorMessage(exec, codeBlock, line, divotPoint - startOffset, divotPoint, error->isNull() ? jsNull() : jsUndefined(), "not an object");
- JSObject* exception = Error::create(exec, TypeError, errorMessage, line, codeBlock->ownerNode()->sourceID(), codeBlock->ownerNode()->sourceURL());
+ JSObject* exception = Error::create(exec, TypeError, errorMessage, line, codeBlock->ownerExecutable()->sourceID(), codeBlock->ownerExecutable()->sourceURL());
exception->putWithAttributes(exec, Identifier(exec, expressionBeginOffsetPropertyName), jsNumber(exec, divotPoint - startOffset), ReadOnly | DontDelete);
exception->putWithAttributes(exec, Identifier(exec, expressionCaretOffsetPropertyName), jsNumber(exec, divotPoint), ReadOnly | DontDelete);
exception->putWithAttributes(exec, Identifier(exec, expressionEndOffsetPropertyName), jsNumber(exec, divotPoint + endOffset), ReadOnly | DontDelete);
diff --git a/JavaScriptCore/runtime/Executable.cpp b/JavaScriptCore/runtime/Executable.cpp
new file mode 100644
index 0000000..053dbfb
--- /dev/null
+++ b/JavaScriptCore/runtime/Executable.cpp
@@ -0,0 +1,216 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "Executable.h"
+
+#include "BytecodeGenerator.h"
+#include "CodeBlock.h"
+#include "JIT.h"
+#include "Parser.h"
+
+namespace JSC {
+
+EvalExecutable::~EvalExecutable()
+{
+ delete m_evalCodeBlock;
+}
+
+ProgramExecutable::~ProgramExecutable()
+{
+ delete m_programCodeBlock;
+}
+
+FunctionExecutable::~FunctionExecutable()
+{
+ delete m_codeBlock;
+}
+
+void EvalExecutable::generateBytecode(ScopeChainNode* scopeChainNode)
+{
+ ScopeChain scopeChain(scopeChainNode);
+ JSGlobalObject* globalObject = scopeChain.globalObject();
+
+ ASSERT(!m_evalCodeBlock);
+ m_evalCodeBlock = new EvalCodeBlock(this, globalObject, source().provider(), scopeChain.localDepth());
+ OwnPtr<BytecodeGenerator> generator(new BytecodeGenerator(evalNode(), globalObject->debugger(), scopeChain, &m_evalCodeBlock->symbolTable(), m_evalCodeBlock));
+ generator->generate();
+
+ evalNode()->partialDestroyData();
+}
+
+void ProgramExecutable::generateBytecode(ScopeChainNode* scopeChainNode)
+{
+ ScopeChain scopeChain(scopeChainNode);
+ JSGlobalObject* globalObject = scopeChain.globalObject();
+
+ ASSERT(!m_programCodeBlock);
+ m_programCodeBlock = new ProgramCodeBlock(this, GlobalCode, globalObject, source().provider());
+ OwnPtr<BytecodeGenerator> generator(new BytecodeGenerator(programNode(), globalObject->debugger(), scopeChain, &globalObject->symbolTable(), m_programCodeBlock));
+ generator->generate();
+
+ programNode()->destroyData();
+}
+
+void FunctionExecutable::generateBytecode(ScopeChainNode* scopeChainNode)
+{
+ body()->reparseDataIfNecessary(scopeChainNode);
+
+ ScopeChain scopeChain(scopeChainNode);
+ JSGlobalObject* globalObject = scopeChain.globalObject();
+
+ ASSERT(!m_codeBlock);
+ m_codeBlock = new FunctionCodeBlock(this, FunctionCode, source().provider(), source().startOffset());
+ OwnPtr<BytecodeGenerator> generator(new BytecodeGenerator(body(), globalObject->debugger(), scopeChain, &m_codeBlock->symbolTable(), m_codeBlock));
+ generator->generate();
+
+ body()->destroyData();
+}
+
+#if ENABLE(JIT)
+
+void EvalExecutable::generateJITCode(ScopeChainNode* scopeChainNode)
+{
+ CodeBlock* codeBlock = &bytecode(scopeChainNode);
+ m_jitCode = JIT::compile(scopeChainNode->globalData, codeBlock);
+
+#if !ENABLE(OPCODE_SAMPLING)
+ if (!BytecodeGenerator::dumpsGeneratedCode())
+ codeBlock->discardBytecode();
+#endif
+}
+
+void ProgramExecutable::generateJITCode(ScopeChainNode* scopeChainNode)
+{
+ CodeBlock* codeBlock = &bytecode(scopeChainNode);
+ m_jitCode = JIT::compile(scopeChainNode->globalData, codeBlock);
+
+#if !ENABLE(OPCODE_SAMPLING)
+ if (!BytecodeGenerator::dumpsGeneratedCode())
+ codeBlock->discardBytecode();
+#endif
+}
+
+void FunctionExecutable::generateJITCode(ScopeChainNode* scopeChainNode)
+{
+ CodeBlock* codeBlock = &bytecode(scopeChainNode);
+ m_jitCode = JIT::compile(scopeChainNode->globalData, codeBlock);
+
+#if !ENABLE(OPCODE_SAMPLING)
+ if (!BytecodeGenerator::dumpsGeneratedCode())
+ codeBlock->discardBytecode();
+#endif
+}
+
+#endif
+
+bool FunctionExecutable::isHostFunction() const
+{
+ return m_codeBlock && m_codeBlock->codeType() == NativeCode;
+}
+
+void FunctionExecutable::markAggregate(MarkStack& markStack)
+{
+ if (m_codeBlock)
+ m_codeBlock->markAggregate(markStack);
+}
+
+ExceptionInfo* FunctionExecutable::reparseExceptionInfo(JSGlobalData* globalData, ScopeChainNode* scopeChainNode, CodeBlock* codeBlock)
+{
+ RefPtr<FunctionBodyNode> newFunctionBody = globalData->parser->reparse<FunctionBodyNode>(globalData, body());
+ ASSERT(newFunctionBody);
+ newFunctionBody->finishParsing(body()->copyParameters(), body()->parameterCount(), body()->ident());
+
+ ScopeChain scopeChain(scopeChainNode);
+ JSGlobalObject* globalObject = scopeChain.globalObject();
+
+ OwnPtr<CodeBlock> newCodeBlock(new FunctionCodeBlock(this, FunctionCode, source().provider(), source().startOffset()));
+ globalData->functionCodeBlockBeingReparsed = newCodeBlock.get();
+
+ OwnPtr<BytecodeGenerator> generator(new BytecodeGenerator(newFunctionBody.get(), globalObject->debugger(), scopeChain, &newCodeBlock->symbolTable(), newCodeBlock.get()));
+ generator->setRegeneratingForExceptionInfo(static_cast<FunctionCodeBlock*>(codeBlock));
+ generator->generate();
+
+ ASSERT(newCodeBlock->instructionCount() == codeBlock->instructionCount());
+
+#if ENABLE(JIT)
+ JITCode newJITCode = JIT::compile(globalData, newCodeBlock.get());
+ ASSERT(newJITCode.size() == generatedJITCode().size());
+#endif
+
+ globalData->functionCodeBlockBeingReparsed = 0;
+
+ return newCodeBlock->extractExceptionInfo();
+}
+
+ExceptionInfo* EvalExecutable::reparseExceptionInfo(JSGlobalData* globalData, ScopeChainNode* scopeChainNode, CodeBlock* codeBlock)
+{
+ RefPtr<EvalNode> newEvalBody = globalData->parser->reparse<EvalNode>(globalData, evalNode());
+
+ ScopeChain scopeChain(scopeChainNode);
+ JSGlobalObject* globalObject = scopeChain.globalObject();
+
+ OwnPtr<EvalCodeBlock> newCodeBlock(new EvalCodeBlock(this, globalObject, source().provider(), scopeChain.localDepth()));
+
+ OwnPtr<BytecodeGenerator> generator(new BytecodeGenerator(newEvalBody.get(), globalObject->debugger(), scopeChain, &newCodeBlock->symbolTable(), newCodeBlock.get()));
+ generator->setRegeneratingForExceptionInfo(static_cast<EvalCodeBlock*>(codeBlock));
+ generator->generate();
+
+ ASSERT(newCodeBlock->instructionCount() == codeBlock->instructionCount());
+
+#if ENABLE(JIT)
+ JITCode newJITCode = JIT::compile(globalData, newCodeBlock.get());
+ ASSERT(newJITCode.size() == generatedJITCode().size());
+#endif
+
+ return newCodeBlock->extractExceptionInfo();
+}
+
+void FunctionExecutable::recompile(ExecState* exec)
+{
+ FunctionBodyNode* oldBody = body();
+ RefPtr<FunctionBodyNode> newBody = exec->globalData().parser->parse<FunctionBodyNode>(exec, 0, m_source);
+ ASSERT(newBody);
+ newBody->finishParsing(oldBody->copyParameters(), oldBody->parameterCount(), oldBody->ident());
+ m_node = newBody;
+ delete m_codeBlock;
+ m_codeBlock = 0;
+#if ENABLE(JIT)
+ m_jitCode = JITCode();
+#endif
+}
+
+#if ENABLE(JIT)
+FunctionExecutable::FunctionExecutable(ExecState* exec)
+ : m_codeBlock(new NativeCodeBlock(this))
+ , m_name(Identifier(exec, "<native thunk>"))
+{
+ m_jitCode = JITCode(JITCode::HostFunction(exec->globalData().jitStubs.ctiNativeCallThunk()));
+}
+#endif
+
+};
+
+
diff --git a/JavaScriptCore/runtime/Executable.h b/JavaScriptCore/runtime/Executable.h
new file mode 100644
index 0000000..29288df
--- /dev/null
+++ b/JavaScriptCore/runtime/Executable.h
@@ -0,0 +1,268 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef Executable_h
+#define Executable_h
+
+#include "Nodes.h"
+
+namespace JSC {
+
+ class CodeBlock;
+ class EvalCodeBlock;
+ class ProgramCodeBlock;
+ class ScopeChainNode;
+
+ struct ExceptionInfo;
+
+ class ExecutableBase {
+ friend class JIT;
+ public:
+ virtual ~ExecutableBase() {}
+
+ ExecutableBase(const SourceCode& source)
+ : m_source(source)
+ {
+ }
+
+ const SourceCode& source() { return m_source; }
+ intptr_t sourceID() const { return m_node->sourceID(); }
+ const UString& sourceURL() const { return m_node->sourceURL(); }
+ int lineNo() const { return m_node->lineNo(); }
+ int lastLine() const { return m_node->lastLine(); }
+
+ bool usesEval() const { return m_node->usesEval(); }
+ bool usesArguments() const { return m_node->usesArguments(); }
+ bool needsActivation() const { return m_node->needsActivation(); }
+
+ virtual ExceptionInfo* reparseExceptionInfo(JSGlobalData*, ScopeChainNode*, CodeBlock*) = 0;
+
+ ScopeNode* astNode() { return m_node.get(); }
+
+ protected:
+ RefPtr<ScopeNode> m_node;
+ SourceCode m_source;
+
+ private:
+ // For use making native thunk.
+ friend class FunctionExecutable;
+ ExecutableBase()
+ {
+ }
+
+#if ENABLE(JIT)
+ public:
+ JITCode& generatedJITCode()
+ {
+ ASSERT(m_jitCode);
+ return m_jitCode;
+ }
+
+ ExecutablePool* getExecutablePool()
+ {
+ return m_jitCode.getExecutablePool();
+ }
+
+ protected:
+ JITCode m_jitCode;
+#endif
+ };
+
+ class EvalExecutable : public ExecutableBase {
+ public:
+ EvalExecutable(const SourceCode& source)
+ : ExecutableBase(source)
+ , m_evalCodeBlock(0)
+ {
+ }
+
+ ~EvalExecutable();
+
+ JSObject* parse(ExecState* exec, bool allowDebug = true);
+
+ EvalCodeBlock& bytecode(ScopeChainNode* scopeChainNode)
+ {
+ if (!m_evalCodeBlock)
+ generateBytecode(scopeChainNode);
+ return *m_evalCodeBlock;
+ }
+
+ DeclarationStacks::VarStack& varStack() { return m_node->varStack(); }
+
+ ExceptionInfo* reparseExceptionInfo(JSGlobalData*, ScopeChainNode*, CodeBlock*);
+
+ private:
+ EvalNode* evalNode() { return static_cast<EvalNode*>(m_node.get()); }
+
+ void generateBytecode(ScopeChainNode*);
+
+ EvalCodeBlock* m_evalCodeBlock;
+
+#if ENABLE(JIT)
+ public:
+ JITCode& jitCode(ScopeChainNode* scopeChainNode)
+ {
+ if (!m_jitCode)
+ generateJITCode(scopeChainNode);
+ return m_jitCode;
+ }
+
+ private:
+ void generateJITCode(ScopeChainNode*);
+#endif
+ };
+
+ class CacheableEvalExecutable : public EvalExecutable, public RefCounted<CacheableEvalExecutable> {
+ public:
+ static PassRefPtr<CacheableEvalExecutable> create(const SourceCode& source) { return adoptRef(new CacheableEvalExecutable(source)); }
+
+ private:
+ CacheableEvalExecutable(const SourceCode& source)
+ : EvalExecutable(source)
+ {
+ }
+ };
+
+ class ProgramExecutable : public ExecutableBase {
+ public:
+ ProgramExecutable(const SourceCode& source)
+ : ExecutableBase(source)
+ , m_programCodeBlock(0)
+ {
+ }
+
+ ~ProgramExecutable();
+
+ JSObject* parse(ExecState* exec, bool allowDebug = true);
+
+ // CodeBlocks for program code are transient and therefore to not gain from from throwing out there exception information.
+ ExceptionInfo* reparseExceptionInfo(JSGlobalData*, ScopeChainNode*, CodeBlock*) { ASSERT_NOT_REACHED(); return 0; }
+
+ ProgramCodeBlock& bytecode(ScopeChainNode* scopeChainNode)
+ {
+ if (!m_programCodeBlock)
+ generateBytecode(scopeChainNode);
+ return *m_programCodeBlock;
+ }
+
+ private:
+ ProgramNode* programNode() { return static_cast<ProgramNode*>(m_node.get()); }
+
+ void generateBytecode(ScopeChainNode*);
+
+ ProgramCodeBlock* m_programCodeBlock;
+
+#if ENABLE(JIT)
+ public:
+ JITCode& jitCode(ScopeChainNode* scopeChainNode)
+ {
+ if (!m_jitCode)
+ generateJITCode(scopeChainNode);
+ return m_jitCode;
+ }
+
+ private:
+ void generateJITCode(ScopeChainNode*);
+#endif
+ };
+
+ class FunctionExecutable : public ExecutableBase, public RefCounted<FunctionExecutable> {
+ friend class JIT;
+ public:
+ FunctionExecutable(const Identifier& name, FunctionBodyNode* body)
+ : ExecutableBase(body->source())
+ , m_codeBlock(0)
+ , m_name(name)
+ {
+ m_node = body;
+ }
+
+ ~FunctionExecutable();
+
+ const Identifier& name() { return m_name; }
+
+ JSFunction* make(ExecState* exec, ScopeChainNode* scopeChain);
+
+ CodeBlock& bytecode(ScopeChainNode* scopeChainNode)
+ {
+ ASSERT(scopeChainNode);
+ if (!m_codeBlock)
+ generateBytecode(scopeChainNode);
+ return *m_codeBlock;
+ }
+ CodeBlock& generatedBytecode()
+ {
+ ASSERT(m_codeBlock);
+ return *m_codeBlock;
+ }
+
+ bool usesEval() const { return body()->usesEval(); }
+ bool usesArguments() const { return body()->usesArguments(); }
+ size_t parameterCount() const { return body()->parameterCount(); }
+ UString paramString() const { return body()->paramString(); }
+
+ bool isHostFunction() const;
+ bool isGenerated() const
+ {
+ return m_codeBlock;
+ }
+
+ void recompile(ExecState* exec);
+
+ ExceptionInfo* reparseExceptionInfo(JSGlobalData*, ScopeChainNode*, CodeBlock*);
+
+ void markAggregate(MarkStack& markStack);
+
+ private:
+ FunctionBodyNode* body() const { return static_cast<FunctionBodyNode*>(m_node.get()); }
+
+ void generateBytecode(ScopeChainNode*);
+
+ CodeBlock* m_codeBlock;
+ const Identifier& m_name;
+
+#if ENABLE(JIT)
+ public:
+ JITCode& jitCode(ScopeChainNode* scopeChainNode)
+ {
+ if (!m_jitCode)
+ generateJITCode(scopeChainNode);
+ return m_jitCode;
+ }
+
+ static PassRefPtr<FunctionExecutable> createNativeThunk(ExecState* exec)
+ {
+ return adoptRef(new FunctionExecutable(exec));
+ }
+
+ private:
+ FunctionExecutable(ExecState* exec);
+ void generateJITCode(ScopeChainNode*);
+#endif
+ };
+
+};
+
+#endif
diff --git a/JavaScriptCore/runtime/FunctionConstructor.cpp b/JavaScriptCore/runtime/FunctionConstructor.cpp
index f4f5cc8..2783b35 100644
--- a/JavaScriptCore/runtime/FunctionConstructor.cpp
+++ b/JavaScriptCore/runtime/FunctionConstructor.cpp
@@ -66,32 +66,6 @@ CallType FunctionConstructor::getCallData(CallData& callData)
return CallTypeHost;
}
-FunctionBodyNode* extractFunctionBody(ProgramNode* program)
-{
- if (!program)
- return 0;
-
- StatementVector& children = program->children();
- if (children.size() != 1)
- return 0;
-
- StatementNode* exprStatement = children[0];
- ASSERT(exprStatement);
- ASSERT(exprStatement->isExprStatement());
- if (!exprStatement || !exprStatement->isExprStatement())
- return 0;
-
- ExpressionNode* funcExpr = static_cast<ExprStatementNode*>(exprStatement)->expr();
- ASSERT(funcExpr);
- ASSERT(funcExpr->isFuncExprNode());
- if (!funcExpr || !funcExpr->isFuncExprNode())
- return 0;
-
- FunctionBodyNode* body = static_cast<FuncExprNode*>(funcExpr)->body();
- ASSERT(body);
- return body;
-}
-
// ECMA 15.3.2 The Function Constructor
JSObject* constructFunction(ExecState* exec, const ArgList& args, const Identifier& functionName, const UString& sourceURL, int lineNumber)
{
@@ -113,15 +87,13 @@ JSObject* constructFunction(ExecState* exec, const ArgList& args, const Identifi
int errLine;
UString errMsg;
SourceCode source = makeSource(program, sourceURL, lineNumber);
- RefPtr<ProgramNode> programNode = exec->globalData().parser->parse<ProgramNode>(exec, exec->dynamicGlobalObject()->debugger(), source, &errLine, &errMsg);
-
- FunctionBodyNode* body = extractFunctionBody(programNode.get());
+ RefPtr<FunctionBodyNode> body = exec->globalData().parser->parseFunctionFromGlobalCode(exec, exec->dynamicGlobalObject()->debugger(), source, &errLine, &errMsg);
if (!body)
return throwError(exec, SyntaxError, errMsg, errLine, source.provider()->asID(), source.provider()->url());
JSGlobalObject* globalObject = exec->lexicalGlobalObject();
ScopeChain scopeChain(globalObject, globalObject->globalData(), exec->globalThisValue());
- return new (exec) JSFunction(exec, functionName, body, scopeChain.node());
+ return new (exec) JSFunction(exec, adoptRef(new FunctionExecutable(functionName, body.get())), scopeChain.node());
}
// ECMA 15.3.2 The Function Constructor
diff --git a/JavaScriptCore/runtime/FunctionConstructor.h b/JavaScriptCore/runtime/FunctionConstructor.h
index 124b354..e8486dc 100644
--- a/JavaScriptCore/runtime/FunctionConstructor.h
+++ b/JavaScriptCore/runtime/FunctionConstructor.h
@@ -26,8 +26,6 @@
namespace JSC {
class FunctionPrototype;
- class ProgramNode;
- class FunctionBodyNode;
class FunctionConstructor : public InternalFunction {
public:
@@ -41,8 +39,6 @@ namespace JSC {
JSObject* constructFunction(ExecState*, const ArgList&, const Identifier& functionName, const UString& sourceURL, int lineNumber);
JSObject* constructFunction(ExecState*, const ArgList&);
- FunctionBodyNode* extractFunctionBody(ProgramNode*);
-
} // namespace JSC
#endif // FunctionConstructor_h
diff --git a/JavaScriptCore/runtime/FunctionPrototype.cpp b/JavaScriptCore/runtime/FunctionPrototype.cpp
index 9ba2144..d911f2f 100644
--- a/JavaScriptCore/runtime/FunctionPrototype.cpp
+++ b/JavaScriptCore/runtime/FunctionPrototype.cpp
@@ -1,6 +1,6 @@
/*
* Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
- * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -84,16 +84,17 @@ static inline void insertSemicolonIfNeeded(UString& functionBody)
JSValue JSC_HOST_CALL functionProtoFuncToString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- if (thisValue.isObject(&JSFunction::info)) {
+ if (thisValue.inherits(&JSFunction::info)) {
JSFunction* function = asFunction(thisValue);
- if (!function->isHostFunction()) {
- UString functionBody = function->body()->toSourceString();
- insertSemicolonIfNeeded(functionBody);
- return jsString(exec, "function " + function->name(&exec->globalData()) + "(" + function->body()->paramString() + ") " + functionBody);
+ FunctionExecutable* executable = function->executable();
+ if (!executable->isHostFunction()) {
+ UString sourceString = executable->source().toString();
+ insertSemicolonIfNeeded(sourceString);
+ return jsString(exec, "function " + function->name(&exec->globalData()) + "(" + executable->paramString() + ") " + sourceString);
}
}
- if (thisValue.isObject(&InternalFunction::info)) {
+ if (thisValue.inherits(&InternalFunction::info)) {
InternalFunction* function = asInternalFunction(thisValue);
return jsString(exec, "function " + function->name(&exec->globalData()) + "() {\n [native code]\n}");
}
diff --git a/JavaScriptCore/runtime/FunctionPrototype.h b/JavaScriptCore/runtime/FunctionPrototype.h
index 607ddab..4f674f5 100644
--- a/JavaScriptCore/runtime/FunctionPrototype.h
+++ b/JavaScriptCore/runtime/FunctionPrototype.h
@@ -34,7 +34,7 @@ namespace JSC {
static PassRefPtr<Structure> createStructure(JSValue proto)
{
- return Structure::create(proto, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot));
+ return Structure::create(proto, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot | HasDefaultMark));
}
private:
diff --git a/JavaScriptCore/runtime/InternalFunction.h b/JavaScriptCore/runtime/InternalFunction.h
index 310644c..37077f6 100644
--- a/JavaScriptCore/runtime/InternalFunction.h
+++ b/JavaScriptCore/runtime/InternalFunction.h
@@ -42,7 +42,7 @@ namespace JSC {
static PassRefPtr<Structure> createStructure(JSValue proto)
{
- return Structure::create(proto, TypeInfo(ObjectType, ImplementsHasInstance | HasStandardGetOwnPropertySlot));
+ return Structure::create(proto, TypeInfo(ObjectType, ImplementsHasInstance | HasStandardGetOwnPropertySlot | HasDefaultMark));
}
protected:
diff --git a/JavaScriptCore/runtime/JSAPIValueWrapper.h b/JavaScriptCore/runtime/JSAPIValueWrapper.h
index 21a9710..5cd4bdd 100644
--- a/JavaScriptCore/runtime/JSAPIValueWrapper.h
+++ b/JavaScriptCore/runtime/JSAPIValueWrapper.h
@@ -54,6 +54,7 @@ namespace JSC {
: JSCell(exec->globalData().apiWrapperStructure.get())
, m_value(value)
{
+ ASSERT(!value.isCell());
}
JSValue m_value;
diff --git a/JavaScriptCore/runtime/JSActivation.cpp b/JavaScriptCore/runtime/JSActivation.cpp
index 87adbcd..d025abb 100644
--- a/JavaScriptCore/runtime/JSActivation.cpp
+++ b/JavaScriptCore/runtime/JSActivation.cpp
@@ -39,8 +39,8 @@ ASSERT_CLASS_FITS_IN_CELL(JSActivation);
const ClassInfo JSActivation::info = { "JSActivation", 0, 0, 0 };
-JSActivation::JSActivation(CallFrame* callFrame, PassRefPtr<FunctionBodyNode> functionBody)
- : Base(callFrame->globalData().activationStructure, new JSActivationData(functionBody, callFrame->registers()))
+JSActivation::JSActivation(CallFrame* callFrame, PassRefPtr<FunctionExecutable> functionExecutable)
+ : Base(callFrame->globalData().activationStructure, new JSActivationData(functionExecutable, callFrame->registers()))
{
}
@@ -57,12 +57,12 @@ void JSActivation::markChildren(MarkStack& markStack)
if (!registerArray)
return;
- size_t numParametersMinusThis = d()->functionBody->generatedBytecode().m_numParameters - 1;
+ size_t numParametersMinusThis = d()->functionExecutable->generatedBytecode().m_numParameters - 1;
size_t count = numParametersMinusThis;
markStack.appendValues(registerArray, count);
- size_t numVars = d()->functionBody->generatedBytecode().m_numVars;
+ size_t numVars = d()->functionExecutable->generatedBytecode().m_numVars;
// Skip the call frame, which sits between the parameters and vars.
markStack.appendValues(registerArray + count + RegisterFile::CallFrameHeaderSize, numVars, MayContainNullValues);
@@ -136,14 +136,14 @@ JSObject* JSActivation::toThisObject(ExecState* exec) const
bool JSActivation::isDynamicScope() const
{
- return d()->functionBody->usesEval();
+ return d()->functionExecutable->usesEval();
}
JSValue JSActivation::argumentsGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
{
JSActivation* activation = asActivation(slot.slotBase());
- if (activation->d()->functionBody->usesArguments()) {
+ if (activation->d()->functionExecutable->usesArguments()) {
PropertySlot slot;
activation->symbolTableGet(exec->propertyNames().arguments, slot);
return slot.getValue(exec, exec->propertyNames().arguments);
@@ -156,7 +156,7 @@ JSValue JSActivation::argumentsGetter(ExecState* exec, const Identifier&, const
arguments->copyRegisters();
callFrame->setCalleeArguments(arguments);
}
- ASSERT(arguments->isObject(&Arguments::info));
+ ASSERT(arguments->inherits(&Arguments::info));
return arguments;
}
diff --git a/JavaScriptCore/runtime/JSActivation.h b/JavaScriptCore/runtime/JSActivation.h
index 6a08439..285ae67 100644
--- a/JavaScriptCore/runtime/JSActivation.h
+++ b/JavaScriptCore/runtime/JSActivation.h
@@ -43,7 +43,7 @@ namespace JSC {
class JSActivation : public JSVariableObject {
typedef JSVariableObject Base;
public:
- JSActivation(CallFrame*, PassRefPtr<FunctionBodyNode>);
+ JSActivation(CallFrame*, PassRefPtr<FunctionExecutable>);
virtual ~JSActivation();
virtual void markChildren(MarkStack&);
@@ -70,13 +70,13 @@ namespace JSC {
private:
struct JSActivationData : public JSVariableObjectData {
- JSActivationData(PassRefPtr<FunctionBodyNode> functionBody, Register* registers)
- : JSVariableObjectData(&functionBody->generatedBytecode().symbolTable(), registers)
- , functionBody(functionBody)
+ JSActivationData(PassRefPtr<FunctionExecutable> functionExecutable, Register* registers)
+ : JSVariableObjectData(&functionExecutable->generatedBytecode().symbolTable(), registers)
+ , functionExecutable(functionExecutable)
{
}
- RefPtr<FunctionBodyNode> functionBody;
+ RefPtr<FunctionExecutable> functionExecutable;
};
static JSValue argumentsGetter(ExecState*, const Identifier&, const PropertySlot&);
diff --git a/JavaScriptCore/runtime/JSArray.cpp b/JavaScriptCore/runtime/JSArray.cpp
index 7d7d4c4..90e0434 100644
--- a/JavaScriptCore/runtime/JSArray.cpp
+++ b/JavaScriptCore/runtime/JSArray.cpp
@@ -25,6 +25,7 @@
#include "ArrayPrototype.h"
#include "CachedCall.h"
+#include "Error.h"
#include "PropertyNameArray.h"
#include <wtf/AVLTree.h>
#include <wtf/Assertions.h>
@@ -348,8 +349,7 @@ NEVER_INLINE void JSArray::putSlowCase(ExecState* exec, unsigned i, JSValue valu
}
}
- storage = static_cast<ArrayStorage*>(tryFastRealloc(storage, storageSize(newVectorLength)));
- if (!storage) {
+ if (!tryFastRealloc(storage, storageSize(newVectorLength)).getValue(storage)) {
throwOutOfMemoryError(exec);
return;
}
@@ -467,8 +467,7 @@ bool JSArray::increaseVectorLength(unsigned newLength)
ASSERT(newLength <= MAX_STORAGE_VECTOR_INDEX);
unsigned newVectorLength = increasedVectorLength(newLength);
- storage = static_cast<ArrayStorage*>(tryFastRealloc(storage, storageSize(newVectorLength)));
- if (!storage)
+ if (!tryFastRealloc(storage, storageSize(newVectorLength)).getValue(storage))
return false;
Heap::heap(this)->reportExtraMemoryCost(storageSize(newVectorLength) - storageSize(vectorLength));
@@ -603,18 +602,7 @@ void JSArray::push(ExecState* exec, JSValue value)
void JSArray::markChildren(MarkStack& markStack)
{
- JSObject::markChildren(markStack);
-
- ArrayStorage* storage = m_storage;
-
- unsigned usedVectorLength = min(storage->m_length, storage->m_vectorLength);
- markStack.appendValues(storage->m_vector, usedVectorLength, MayContainNullValues);
-
- if (SparseArrayValueMap* map = storage->m_sparseValueMap) {
- SparseArrayValueMap::iterator end = map->end();
- for (SparseArrayValueMap::iterator it = map->begin(); it != end; ++it)
- markStack.append(it->second);
- }
+ markChildrenDirect(markStack);
}
static int compareNumbersForQSort(const void* a, const void* b)
diff --git a/JavaScriptCore/runtime/JSArray.h b/JavaScriptCore/runtime/JSArray.h
index 49df6c4..88d8ee4 100644
--- a/JavaScriptCore/runtime/JSArray.h
+++ b/JavaScriptCore/runtime/JSArray.h
@@ -82,6 +82,8 @@ namespace JSC {
{
return Structure::create(prototype, TypeInfo(ObjectType));
}
+
+ inline void markChildrenDirect(MarkStack& markStack);
protected:
virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
@@ -125,6 +127,77 @@ namespace JSC {
inline bool isJSArray(JSGlobalData* globalData, JSValue v) { return v.isCell() && v.asCell()->vptr() == globalData->jsArrayVPtr; }
+ void JSArray::markChildrenDirect(MarkStack& markStack) {
+ JSObject::markChildrenDirect(markStack);
+
+ ArrayStorage* storage = m_storage;
+
+ unsigned usedVectorLength = std::min(storage->m_length, storage->m_vectorLength);
+ markStack.appendValues(storage->m_vector, usedVectorLength, MayContainNullValues);
+
+ if (SparseArrayValueMap* map = storage->m_sparseValueMap) {
+ SparseArrayValueMap::iterator end = map->end();
+ for (SparseArrayValueMap::iterator it = map->begin(); it != end; ++it)
+ markStack.append(it->second);
+ }
+ }
+
+ inline void MarkStack::drain()
+ {
+ while (!m_markSets.isEmpty() || !m_values.isEmpty()) {
+ while (!m_markSets.isEmpty() && m_values.size() < 50) {
+ ASSERT(!m_markSets.isEmpty());
+ MarkSet& current = m_markSets.last();
+ ASSERT(current.m_values);
+ JSValue* end = current.m_end;
+ ASSERT(current.m_values);
+ ASSERT(current.m_values != end);
+ findNextUnmarkedNullValue:
+ ASSERT(current.m_values != end);
+ JSValue v = *current.m_values;
+ current.m_values++;
+
+ if (!v || v.marked()) {
+ if (current.m_values == end) {
+ m_markSets.removeLast();
+ continue;
+ }
+ goto findNextUnmarkedNullValue;
+ }
+
+ JSCell* currentCell = v.asCell();
+ currentCell->markCellDirect();
+ if (currentCell->structure()->typeInfo().type() < CompoundType) {
+ if (current.m_values == end) {
+ m_markSets.removeLast();
+ continue;
+ }
+ goto findNextUnmarkedNullValue;
+ }
+
+ if (current.m_values == end)
+ m_markSets.removeLast();
+
+ if (currentCell->structure()->typeInfo().hasDefaultMark())
+ static_cast<JSObject*>(currentCell)->markChildrenDirect(*this);
+ else if (currentCell->vptr() == m_jsArrayVPtr)
+ static_cast<JSArray*>(currentCell)->markChildrenDirect(*this);
+ else
+ currentCell->markChildren(*this);
+ }
+ while (!m_values.isEmpty()) {
+ JSCell* current = m_values.removeLast();
+ ASSERT(current->marked());
+ if (current->structure()->typeInfo().hasDefaultMark())
+ static_cast<JSObject*>(current)->markChildrenDirect(*this);
+ else if (current->vptr() == m_jsArrayVPtr)
+ static_cast<JSArray*>(current)->markChildrenDirect(*this);
+ else
+ current->markChildren(*this);
+ }
+ }
+ }
+
} // namespace JSC
#endif // JSArray_h
diff --git a/JavaScriptCore/runtime/JSByteArray.cpp b/JavaScriptCore/runtime/JSByteArray.cpp
index 2a5e72f..f832578 100644
--- a/JavaScriptCore/runtime/JSByteArray.cpp
+++ b/JavaScriptCore/runtime/JSByteArray.cpp
@@ -45,7 +45,7 @@ JSByteArray::JSByteArray(ExecState* exec, PassRefPtr<Structure> structure, ByteA
PassRefPtr<Structure> JSByteArray::createStructure(JSValue prototype)
{
- PassRefPtr<Structure> result = Structure::create(prototype, TypeInfo(ObjectType));
+ PassRefPtr<Structure> result = Structure::create(prototype, TypeInfo(ObjectType, HasDefaultMark));
return result;
}
diff --git a/JavaScriptCore/runtime/JSCell.h b/JavaScriptCore/runtime/JSCell.h
index 75ccf7f..485ad2e 100644
--- a/JavaScriptCore/runtime/JSCell.h
+++ b/JavaScriptCore/runtime/JSCell.h
@@ -55,7 +55,7 @@ namespace JSC {
bool isString() const;
bool isObject() const;
virtual bool isGetterSetter() const;
- virtual bool isObject(const ClassInfo*) const;
+ bool inherits(const ClassInfo*) const;
virtual bool isAPIValueWrapper() const { return false; }
Structure* structure() const;
@@ -379,30 +379,6 @@ namespace JSC {
if (cell->structure()->typeInfo().type() >= CompoundType)
m_values.append(cell);
}
-
- inline void MarkStack::drain() {
- while (!m_markSets.isEmpty() || !m_values.isEmpty()) {
- while ((!m_markSets.isEmpty()) && m_values.size() < 50) {
- const MarkSet& current = m_markSets.removeLast();
- JSValue* ptr = current.m_values;
- JSValue* end = current.m_end;
- if (current.m_properties == NoNullValues) {
- while (ptr != end)
- append(*ptr++);
- } else {
- while (ptr != end) {
- if (JSValue value = *ptr++)
- append(value);
- }
- }
- }
- while (!m_values.isEmpty()) {
- JSCell* current = m_values.removeLast();
- ASSERT(current->marked());
- current->markChildren(*this);
- }
- }
- }
} // namespace JSC
#endif // JSCell_h
diff --git a/JavaScriptCore/runtime/JSFunction.cpp b/JavaScriptCore/runtime/JSFunction.cpp
index 84c6263..f8e3d82 100644
--- a/JavaScriptCore/runtime/JSFunction.cpp
+++ b/JavaScriptCore/runtime/JSFunction.cpp
@@ -45,12 +45,26 @@ ASSERT_CLASS_FITS_IN_CELL(JSFunction);
const ClassInfo JSFunction::info = { "Function", &InternalFunction::info, 0, 0 };
+inline bool JSFunction::isHostFunction() const
+{
+ return m_executable && m_executable->isHostFunction();
+}
+
+bool JSFunction::isHostFunctionNonInline() const
+{
+ return isHostFunction();
+}
+
+JSFunction::JSFunction(PassRefPtr<Structure> structure)
+ : Base(structure)
+{
+ clearScopeChain();
+}
+
JSFunction::JSFunction(ExecState* exec, PassRefPtr<Structure> structure, int length, const Identifier& name, NativeFunction func)
: Base(&exec->globalData(), structure, name)
#if ENABLE(JIT)
- , m_body(FunctionBodyNode::createNativeThunk(&exec->globalData()))
-#else
- , m_body(0)
+ , m_executable(FunctionExecutable::createNativeThunk(exec))
#endif
{
#if ENABLE(JIT)
@@ -63,9 +77,9 @@ JSFunction::JSFunction(ExecState* exec, PassRefPtr<Structure> structure, int len
#endif
}
-JSFunction::JSFunction(ExecState* exec, const Identifier& name, FunctionBodyNode* body, ScopeChainNode* scopeChainNode)
- : Base(&exec->globalData(), exec->lexicalGlobalObject()->functionStructure(), name)
- , m_body(body)
+JSFunction::JSFunction(ExecState* exec, PassRefPtr<FunctionExecutable> executable, ScopeChainNode* scopeChainNode)
+ : Base(&exec->globalData(), exec->lexicalGlobalObject()->functionStructure(), executable->name())
+ , m_executable(executable)
{
setScopeChain(scopeChainNode);
}
@@ -76,8 +90,8 @@ JSFunction::~JSFunction()
// are based on a check for the this pointer value for this JSFunction - which will no longer be valid once
// this memory is freed and may be reused (potentially for another, different JSFunction).
#if ENABLE(JIT_OPTIMIZE_CALL)
- if (m_body && m_body->isGenerated())
- m_body->generatedBytecode().unlinkCallers();
+ if (m_executable && m_executable->isGenerated())
+ m_executable->generatedBytecode().unlinkCallers();
#endif
if (!isHostFunction())
scopeChain().~ScopeChain(); // FIXME: Don't we need to do this in the interpreter too?
@@ -86,7 +100,7 @@ JSFunction::~JSFunction()
void JSFunction::markChildren(MarkStack& markStack)
{
Base::markChildren(markStack);
- m_body->markAggregate(markStack);
+ m_executable->markAggregate(markStack);
if (!isHostFunction())
scopeChain().markAggregate(markStack);
}
@@ -97,7 +111,7 @@ CallType JSFunction::getCallData(CallData& callData)
callData.native.function = nativeFunction();
return CallTypeHost;
}
- callData.js.functionBody = m_body.get();
+ callData.js.functionExecutable = m_executable.get();
callData.js.scopeChain = scopeChain().node();
return CallTypeJS;
}
@@ -105,7 +119,7 @@ CallType JSFunction::getCallData(CallData& callData)
JSValue JSFunction::call(ExecState* exec, JSValue thisValue, const ArgList& args)
{
ASSERT(!isHostFunction());
- return exec->interpreter()->execute(m_body.get(), exec, this, thisValue.toThisObject(exec), args, scopeChain().node(), exec->exceptionSlot());
+ return exec->interpreter()->execute(m_executable.get(), exec, this, thisValue.toThisObject(exec), args, scopeChain().node(), exec->exceptionSlot());
}
JSValue JSFunction::argumentsGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
@@ -126,7 +140,7 @@ JSValue JSFunction::lengthGetter(ExecState* exec, const Identifier&, const Prope
{
JSFunction* thisObj = asFunction(slot.slotBase());
ASSERT(!thisObj->isHostFunction());
- return jsNumber(exec, thisObj->m_body->parameterCount());
+ return jsNumber(exec, thisObj->m_executable->parameterCount());
}
bool JSFunction::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
@@ -190,7 +204,7 @@ ConstructType JSFunction::getConstructData(ConstructData& constructData)
{
if (isHostFunction())
return ConstructTypeNone;
- constructData.js.functionBody = m_body.get();
+ constructData.js.functionExecutable = m_executable.get();
constructData.js.scopeChain = scopeChain().node();
return ConstructTypeJS;
}
@@ -206,7 +220,7 @@ JSObject* JSFunction::construct(ExecState* exec, const ArgList& args)
structure = exec->lexicalGlobalObject()->emptyObjectStructure();
JSObject* thisObj = new (exec) JSObject(structure);
- JSValue result = exec->interpreter()->execute(m_body.get(), exec, this, thisObj, args, scopeChain().node(), exec->exceptionSlot());
+ JSValue result = exec->interpreter()->execute(m_executable.get(), exec, this, thisObj, args, scopeChain().node(), exec->exceptionSlot());
if (exec->hadException() || !result.isObject())
return thisObj;
return asObject(result);
diff --git a/JavaScriptCore/runtime/JSFunction.h b/JavaScriptCore/runtime/JSFunction.h
index cab1e5b..71998dc 100644
--- a/JavaScriptCore/runtime/JSFunction.h
+++ b/JavaScriptCore/runtime/JSFunction.h
@@ -24,15 +24,11 @@
#ifndef JSFunction_h
#define JSFunction_h
+#include "Executable.h"
#include "InternalFunction.h"
-#include "JSVariableObject.h"
-#include "SymbolTable.h"
-#include "Nodes.h"
-#include "JSObject.h"
namespace JSC {
- class FunctionBodyNode;
class FunctionPrototype;
class JSActivation;
class JSGlobalObject;
@@ -43,20 +39,10 @@ namespace JSC {
typedef InternalFunction Base;
- JSFunction(PassRefPtr<Structure> structure)
- : InternalFunction(structure)
- {
- clearScopeChain();
- }
-
public:
JSFunction(ExecState*, PassRefPtr<Structure>, int length, const Identifier&, NativeFunction);
- JSFunction(ExecState*, const Identifier&, FunctionBodyNode*, ScopeChainNode*);
- ~JSFunction();
-
- virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
- virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
- virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
+ JSFunction(ExecState*, PassRefPtr<FunctionExecutable>, ScopeChainNode*);
+ virtual ~JSFunction();
JSObject* construct(ExecState*, const ArgList&);
JSValue call(ExecState*, JSValue thisValue, const ArgList&);
@@ -64,11 +50,7 @@ namespace JSC {
void setScope(const ScopeChain& scopeChain) { setScopeChain(scopeChain); }
ScopeChain& scope() { return scopeChain(); }
- void setBody(FunctionBodyNode* body) { m_body = body; }
- void setBody(PassRefPtr<FunctionBodyNode> body) { m_body = body; }
- FunctionBodyNode* body() const { return m_body.get(); }
-
- virtual void markChildren(MarkStack&);
+ FunctionExecutable* executable() const { return m_executable.get(); }
static JS_EXPORTDATA const ClassInfo info;
@@ -77,11 +59,6 @@ namespace JSC {
return Structure::create(prototype, TypeInfo(ObjectType, ImplementsHasInstance));
}
-#if ENABLE(JIT)
- bool isHostFunction() const { return m_body && m_body->isHostFunction(); }
-#else
- bool isHostFunction() const { return false; }
-#endif
NativeFunction nativeFunction()
{
return *reinterpret_cast<NativeFunction*>(m_data);
@@ -91,31 +68,42 @@ namespace JSC {
virtual CallType getCallData(CallData&);
private:
+ JSFunction(PassRefPtr<Structure>);
+
+ bool isHostFunction() const;
+ bool isHostFunctionNonInline() const;
+
+ virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
+ virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
+ virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
+
+ virtual void markChildren(MarkStack&);
+
virtual const ClassInfo* classInfo() const { return &info; }
static JSValue argumentsGetter(ExecState*, const Identifier&, const PropertySlot&);
static JSValue callerGetter(ExecState*, const Identifier&, const PropertySlot&);
static JSValue lengthGetter(ExecState*, const Identifier&, const PropertySlot&);
- RefPtr<FunctionBodyNode> m_body;
+ RefPtr<FunctionExecutable> m_executable;
ScopeChain& scopeChain()
{
- ASSERT(!isHostFunction());
+ ASSERT(!isHostFunctionNonInline());
return *reinterpret_cast<ScopeChain*>(m_data);
}
void clearScopeChain()
{
- ASSERT(!isHostFunction());
+ ASSERT(!isHostFunctionNonInline());
new (m_data) ScopeChain(NoScopeChain());
}
void setScopeChain(ScopeChainNode* sc)
{
- ASSERT(!isHostFunction());
+ ASSERT(!isHostFunctionNonInline());
new (m_data) ScopeChain(sc);
}
void setScopeChain(const ScopeChain& sc)
{
- ASSERT(!isHostFunction());
+ ASSERT(!isHostFunctionNonInline());
*reinterpret_cast<ScopeChain*>(m_data) = sc;
}
void setNativeFunction(NativeFunction func)
@@ -133,6 +121,11 @@ namespace JSC {
return static_cast<JSFunction*>(asObject(value));
}
+ inline JSFunction* FunctionExecutable::make(ExecState* exec, ScopeChainNode* scopeChain)
+ {
+ return new (exec) JSFunction(exec, this, scopeChain);
+ }
+
} // namespace JSC
#endif // JSFunction_h
diff --git a/JavaScriptCore/runtime/JSGlobalData.cpp b/JavaScriptCore/runtime/JSGlobalData.cpp
index 03df41d..38ee1d0 100644
--- a/JavaScriptCore/runtime/JSGlobalData.cpp
+++ b/JavaScriptCore/runtime/JSGlobalData.cpp
@@ -144,8 +144,9 @@ JSGlobalData::JSGlobalData(bool isShared, const VPtrSet& vptrSet)
, initializingLazyNumericCompareFunction(false)
, head(0)
, dynamicGlobalObject(0)
- , scopeNodeBeingReparsed(0)
+ , functionCodeBlockBeingReparsed(0)
, firstStringifierToMark(0)
+ , markStack(vptrSet.jsArrayVPtr)
{
#if PLATFORM(MAC)
startProfilerServerIfNeeded();
@@ -235,9 +236,9 @@ const Vector<Instruction>& JSGlobalData::numericCompareFunction(ExecState* exec)
{
if (!lazyNumericCompareFunction.size() && !initializingLazyNumericCompareFunction) {
initializingLazyNumericCompareFunction = true;
- RefPtr<ProgramNode> programNode = parser->parse<ProgramNode>(exec, 0, makeSource(UString("(function (v1, v2) { return v1 - v2; })")), 0, 0);
- RefPtr<FunctionBodyNode> functionBody = extractFunctionBody(programNode.get());
- lazyNumericCompareFunction = functionBody->bytecode(exec->scopeChain()).instructions();
+ RefPtr<FunctionBodyNode> functionBody = parser->parseFunctionFromGlobalCode(exec, 0, makeSource(UString("(function (v1, v2) { return v1 - v2; })")), 0, 0);
+ FunctionExecutable function(functionBody->ident(), functionBody.get());
+ lazyNumericCompareFunction = function.bytecode(exec->scopeChain()).instructions();
initializingLazyNumericCompareFunction = false;
}
diff --git a/JavaScriptCore/runtime/JSGlobalData.h b/JavaScriptCore/runtime/JSGlobalData.h
index 88cb516..77556b7 100644
--- a/JavaScriptCore/runtime/JSGlobalData.h
+++ b/JavaScriptCore/runtime/JSGlobalData.h
@@ -45,15 +45,14 @@ struct OpaqueJSClassContextData;
namespace JSC {
+ class CodeBlock;
class CommonIdentifiers;
- class FunctionBodyNode;
class IdentifierTable;
class Interpreter;
class JSGlobalObject;
class JSObject;
class Lexer;
class Parser;
- class ScopeNode;
class Stringifier;
class Structure;
class UString;
@@ -145,7 +144,7 @@ namespace JSC {
HashSet<JSObject*> arrayVisitedElements;
- ScopeNode* scopeNodeBeingReparsed;
+ CodeBlock* functionCodeBlockBeingReparsed;
Stringifier* firstStringifierToMark;
MarkStack markStack;
diff --git a/JavaScriptCore/runtime/JSGlobalObject.cpp b/JavaScriptCore/runtime/JSGlobalObject.cpp
index a90f18f..3a1909d 100644
--- a/JavaScriptCore/runtime/JSGlobalObject.cpp
+++ b/JavaScriptCore/runtime/JSGlobalObject.cpp
@@ -112,8 +112,8 @@ JSGlobalObject::~JSGlobalObject()
if (headObject == this)
headObject = 0;
- HashSet<ProgramCodeBlock*>::const_iterator end = codeBlocks().end();
- for (HashSet<ProgramCodeBlock*>::const_iterator it = codeBlocks().begin(); it != end; ++it)
+ HashSet<GlobalCodeBlock*>::const_iterator end = codeBlocks().end();
+ for (HashSet<GlobalCodeBlock*>::const_iterator it = codeBlocks().begin(); it != end; ++it)
(*it)->clearGlobalObject();
RegisterFile& registerFile = globalData()->interpreter->registerFile();
@@ -258,7 +258,7 @@ void JSGlobalObject::reset(JSValue prototype)
JSCell* objectConstructor = new (exec) ObjectConstructor(exec, ObjectConstructor::createStructure(d()->functionPrototype), d()->objectPrototype, d()->prototypeFunctionStructure.get());
JSCell* functionConstructor = new (exec) FunctionConstructor(exec, FunctionConstructor::createStructure(d()->functionPrototype), d()->functionPrototype);
- JSCell* arrayConstructor = new (exec) ArrayConstructor(exec, ArrayConstructor::createStructure(d()->functionPrototype), d()->arrayPrototype);
+ JSCell* arrayConstructor = new (exec) ArrayConstructor(exec, ArrayConstructor::createStructure(d()->functionPrototype), d()->arrayPrototype, d()->prototypeFunctionStructure.get());
JSCell* stringConstructor = new (exec) StringConstructor(exec, StringConstructor::createStructure(d()->functionPrototype), d()->prototypeFunctionStructure.get(), d()->stringPrototype);
JSCell* booleanConstructor = new (exec) BooleanConstructor(exec, BooleanConstructor::createStructure(d()->functionPrototype), d()->booleanPrototype);
JSCell* numberConstructor = new (exec) NumberConstructor(exec, NumberConstructor::createStructure(d()->functionPrototype), d()->numberPrototype);
@@ -361,8 +361,8 @@ void JSGlobalObject::markChildren(MarkStack& markStack)
{
JSVariableObject::markChildren(markStack);
- HashSet<ProgramCodeBlock*>::const_iterator end = codeBlocks().end();
- for (HashSet<ProgramCodeBlock*>::const_iterator it = codeBlocks().begin(); it != end; ++it)
+ HashSet<GlobalCodeBlock*>::const_iterator end = codeBlocks().end();
+ for (HashSet<GlobalCodeBlock*>::const_iterator it = codeBlocks().begin(); it != end; ++it)
(*it)->markAggregate(markStack);
RegisterFile& registerFile = globalData()->interpreter->registerFile();
diff --git a/JavaScriptCore/runtime/JSGlobalObject.h b/JavaScriptCore/runtime/JSGlobalObject.h
index cda49bd..cc36ada 100644
--- a/JavaScriptCore/runtime/JSGlobalObject.h
+++ b/JavaScriptCore/runtime/JSGlobalObject.h
@@ -38,6 +38,7 @@ namespace JSC {
class Debugger;
class ErrorConstructor;
class FunctionPrototype;
+ class GlobalCodeBlock;
class GlobalEvalFunction;
class NativeErrorConstructor;
class ProgramCodeBlock;
@@ -144,7 +145,7 @@ namespace JSC {
RefPtr<JSGlobalData> globalData;
- HashSet<ProgramCodeBlock*> codeBlocks;
+ HashSet<GlobalCodeBlock*> codeBlocks;
};
public:
@@ -246,7 +247,7 @@ namespace JSC {
virtual bool isDynamicScope() const;
- HashSet<ProgramCodeBlock*>& codeBlocks() { return d()->codeBlocks; }
+ HashSet<GlobalCodeBlock*>& codeBlocks() { return d()->codeBlocks; }
void copyGlobalsFrom(RegisterFile&);
void copyGlobalsTo(RegisterFile&);
diff --git a/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp b/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
index affb99c..50ea27f 100644
--- a/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
+++ b/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
@@ -286,16 +286,12 @@ JSValue JSC_HOST_CALL globalFuncEval(ExecState* exec, JSObject* function, JSValu
if (JSValue parsedObject = preparser.tryLiteralParse())
return parsedObject;
- int errLine;
- UString errMsg;
+ EvalExecutable eval(makeSource(s));
+ JSObject* error = eval.parse(exec);
+ if (error)
+ return throwError(exec, error);
- SourceCode source = makeSource(s);
- RefPtr<EvalNode> evalNode = exec->globalData().parser->parse<EvalNode>(exec, exec->dynamicGlobalObject()->debugger(), source, &errLine, &errMsg);
-
- if (!evalNode)
- return throwError(exec, SyntaxError, errMsg, errLine, source.provider()->asID(), NULL);
-
- return exec->interpreter()->execute(evalNode.get(), exec, thisObject, static_cast<JSGlobalObject*>(unwrappedObject)->globalScopeChain().node(), exec->exceptionSlot());
+ return exec->interpreter()->execute(&eval, exec, thisObject, static_cast<JSGlobalObject*>(unwrappedObject)->globalScopeChain().node(), exec->exceptionSlot());
}
JSValue JSC_HOST_CALL globalFuncParseInt(ExecState* exec, JSObject*, JSValue, const ArgList& args)
diff --git a/JavaScriptCore/runtime/JSNumberCell.h b/JavaScriptCore/runtime/JSNumberCell.h
index 04cccef..6a48081 100644
--- a/JavaScriptCore/runtime/JSNumberCell.h
+++ b/JavaScriptCore/runtime/JSNumberCell.h
@@ -84,7 +84,7 @@ namespace JSC {
#endif
}
- static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(NumberType, NeedsThisConversion)); }
+ static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(NumberType, NeedsThisConversion | HasDefaultMark)); }
private:
JSNumberCell(JSGlobalData* globalData, double value)
diff --git a/JavaScriptCore/runtime/JSONObject.cpp b/JavaScriptCore/runtime/JSONObject.cpp
index d643808..fed9fc3 100644
--- a/JavaScriptCore/runtime/JSONObject.cpp
+++ b/JavaScriptCore/runtime/JSONObject.cpp
@@ -381,6 +381,15 @@ Stringifier::StringifyResult Stringifier::appendStringifiedValue(StringBuilder&
JSObject* object = asObject(value);
+ CallData callData;
+ if (object->getCallData(callData) != CallTypeNone) {
+ if (holder->inherits(&JSArray::info)) {
+ builder.append("null");
+ return StringifySucceeded;
+ }
+ return StringifyFailedDueToUndefinedValue;
+ }
+
// Handle cycle detection, and put the holder on the stack.
if (!m_holderCycleDetector.add(object).second) {
throwError(m_exec, TypeError, "JSON.stringify cannot serialize cyclic structures.");
diff --git a/JavaScriptCore/runtime/JSONObject.h b/JavaScriptCore/runtime/JSONObject.h
index faca7c7..c61b0dd 100644
--- a/JavaScriptCore/runtime/JSONObject.h
+++ b/JavaScriptCore/runtime/JSONObject.h
@@ -41,7 +41,7 @@ namespace JSC {
static PassRefPtr<Structure> createStructure(JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType));
+ return Structure::create(prototype, TypeInfo(ObjectType, HasDefaultMark));
}
static void markStringifiers(MarkStack&, Stringifier*);
diff --git a/JavaScriptCore/runtime/JSObject.cpp b/JavaScriptCore/runtime/JSObject.cpp
index 419dfe9..57624fb 100644
--- a/JavaScriptCore/runtime/JSObject.cpp
+++ b/JavaScriptCore/runtime/JSObject.cpp
@@ -37,26 +37,6 @@
#include <math.h>
#include <wtf/Assertions.h>
-#define JSOBJECT_MARK_TRACING 0
-
-#if JSOBJECT_MARK_TRACING
-
-#define JSOBJECT_MARK_BEGIN() \
- static int markStackDepth = 0; \
- for (int i = 0; i < markStackDepth; i++) \
- putchar('-'); \
- printf("%s (%p)\n", className().UTF8String().c_str(), this); \
- markStackDepth++; \
-
-#define JSOBJECT_MARK_END() \
- markStackDepth--;
-
-#else // JSOBJECT_MARK_TRACING
-
-#define JSOBJECT_MARK_BEGIN()
-#define JSOBJECT_MARK_END()
-
-#endif // JSOBJECT_MARK_TRACING
namespace JSC {
@@ -64,16 +44,7 @@ ASSERT_CLASS_FITS_IN_CELL(JSObject);
void JSObject::markChildren(MarkStack& markStack)
{
- JSOBJECT_MARK_BEGIN();
-
- JSCell::markChildren(markStack);
- m_structure->markAggregate(markStack);
-
- PropertyStorage storage = propertyStorage();
- size_t storageSize = m_structure->propertyStorageSize();
- markStack.appendValues(reinterpret_cast<JSValue*>(storage), storageSize);
-
- JSOBJECT_MARK_END();
+ markChildrenDirect(markStack);
}
UString JSObject::className() const
diff --git a/JavaScriptCore/runtime/JSObject.h b/JavaScriptCore/runtime/JSObject.h
index decd5e9..856c5a1 100644
--- a/JavaScriptCore/runtime/JSObject.h
+++ b/JavaScriptCore/runtime/JSObject.h
@@ -27,7 +27,9 @@
#include "ClassInfo.h"
#include "CommonIdentifiers.h"
#include "CallFrame.h"
+#include "JSCell.h"
#include "JSNumberCell.h"
+#include "MarkStack.h"
#include "PropertySlot.h"
#include "PutPropertySlot.h"
#include "ScopeChain.h"
@@ -74,13 +76,12 @@ namespace JSC {
explicit JSObject(PassRefPtr<Structure>);
virtual void markChildren(MarkStack&);
+ ALWAYS_INLINE void markChildrenDirect(MarkStack& markStack);
// The inline virtual destructor cannot be the first virtual function declared
// in the class as it results in the vtable being generated as a weak symbol
virtual ~JSObject();
- bool inherits(const ClassInfo* classInfo) const { return JSCell::isObject(classInfo); }
-
JSValue prototype() const;
void setPrototype(JSValue prototype);
@@ -201,10 +202,22 @@ namespace JSC {
static PassRefPtr<Structure> createStructure(JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot));
+ return Structure::create(prototype, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot | HasDefaultMark));
}
private:
+ // Nobody should ever ask any of these questions on something already known to be a JSObject.
+ using JSCell::isAPIValueWrapper;
+ using JSCell::isGetterSetter;
+ using JSCell::toObject;
+ void getObject();
+ void getString();
+ void isObject();
+ void isString();
+#if USE(JSVALUE32)
+ void isNumber();
+#endif
+
ConstPropertyStorage propertyStorage() const { return (isUsingInlineStorage() ? m_inlineStorage : m_externalStorage); }
PropertyStorage propertyStorage() { return (isUsingInlineStorage() ? m_inlineStorage : m_externalStorage); }
@@ -293,7 +306,7 @@ inline bool Structure::isUsingInlineStorage() const
return (propertyStorageCapacity() == JSObject::inlineStorageCapacity);
}
-inline bool JSCell::isObject(const ClassInfo* info) const
+inline bool JSCell::inherits(const ClassInfo* info) const
{
for (const ClassInfo* ci = classInfo(); ci; ci = ci->parentClass) {
if (ci == info)
@@ -302,10 +315,10 @@ inline bool JSCell::isObject(const ClassInfo* info) const
return false;
}
-// this method is here to be after the inline declaration of JSCell::isObject
-inline bool JSValue::isObject(const ClassInfo* classInfo) const
+// this method is here to be after the inline declaration of JSCell::inherits
+inline bool JSValue::inherits(const ClassInfo* classInfo) const
{
- return isCell() && asCell()->isObject(classInfo);
+ return isCell() && asCell()->inherits(classInfo);
}
ALWAYS_INLINE bool JSObject::inlineGetOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
@@ -627,6 +640,16 @@ ALWAYS_INLINE void JSObject::allocatePropertyStorageInline(size_t oldSize, size_
m_externalStorage = newPropertyStorage;
}
+ALWAYS_INLINE void JSObject::markChildrenDirect(MarkStack& markStack)
+{
+ JSCell::markChildren(markStack);
+ m_structure->markAggregate(markStack);
+
+ PropertyStorage storage = propertyStorage();
+ size_t storageSize = m_structure->propertyStorageSize();
+ markStack.appendValues(reinterpret_cast<JSValue*>(storage), storageSize);
+}
+
} // namespace JSC
#endif // JSObject_h
diff --git a/JavaScriptCore/runtime/JSString.h b/JavaScriptCore/runtime/JSString.h
index 3daf58a..f9b0a8f 100644
--- a/JavaScriptCore/runtime/JSString.h
+++ b/JavaScriptCore/runtime/JSString.h
@@ -90,7 +90,7 @@ namespace JSC {
bool canGetIndex(unsigned i) { return i < static_cast<unsigned>(m_value.size()); }
JSString* getIndex(JSGlobalData*, unsigned);
- static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(StringType, NeedsThisConversion)); }
+ static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(StringType, NeedsThisConversion | HasDefaultMark)); }
private:
enum VPtrStealingHackType { VPtrStealingHack };
diff --git a/JavaScriptCore/runtime/JSType.h b/JavaScriptCore/runtime/JSType.h
index a118b87..882b218 100644
--- a/JavaScriptCore/runtime/JSType.h
+++ b/JavaScriptCore/runtime/JSType.h
@@ -33,7 +33,6 @@ namespace JSC {
NumberType = 3,
NullType = 4,
StringType = 5,
-
// The CompoundType value must come before any JSType that may have children
CompoundType = 6,
ObjectType = 7,
diff --git a/JavaScriptCore/runtime/JSValue.h b/JavaScriptCore/runtime/JSValue.h
index 408c187..b72cc6e 100644
--- a/JavaScriptCore/runtime/JSValue.h
+++ b/JavaScriptCore/runtime/JSValue.h
@@ -130,7 +130,7 @@ namespace JSC {
bool isString() const;
bool isGetterSetter() const;
bool isObject() const;
- bool isObject(const ClassInfo*) const;
+ bool inherits(const ClassInfo*) const;
// Extracting the value.
bool getBoolean(bool&) const;
diff --git a/JavaScriptCore/runtime/MarkStack.h b/JavaScriptCore/runtime/MarkStack.h
index 7a7b3af..a97aa7e 100644
--- a/JavaScriptCore/runtime/MarkStack.h
+++ b/JavaScriptCore/runtime/MarkStack.h
@@ -31,15 +31,15 @@
#include <wtf/Noncopyable.h>
namespace JSC {
+ class JSGlobalData;
class Register;
enum MarkSetProperties { MayContainNullValues, NoNullValues };
class MarkStack : Noncopyable {
public:
- MarkStack()
- : m_markSets()
- , m_values()
+ MarkStack(void* jsArrayVPtr)
+ : m_jsArrayVPtr(jsArrayVPtr)
{
}
@@ -82,6 +82,7 @@ namespace JSC {
, m_end(end)
, m_properties(properties)
{
+ ASSERT(values);
}
JSValue* m_values;
JSValue* m_end;
@@ -136,6 +137,12 @@ namespace JSC {
ASSERT(m_top);
return m_data[--m_top];
}
+
+ inline T& last()
+ {
+ ASSERT(m_top);
+ return m_data[m_top - 1];
+ }
inline bool isEmpty()
{
@@ -150,7 +157,14 @@ namespace JSC {
ASSERT(0 == (size % MarkStack::pageSize()));
if (size == m_allocated)
return;
+#if PLATFORM(WIN)
+ // We cannot release a part of a region with VirtualFree. To get around this,
+ // we'll release the entire region and reallocate the size that we want.
+ releaseStack(m_data, m_allocated);
+ m_data = reinterpret_cast<T*>(allocateStack(size));
+#else
releaseStack(reinterpret_cast<char*>(m_data) + size, m_allocated - size);
+#endif
m_allocated = size;
m_capacity = m_allocated / sizeof(T);
}
@@ -162,6 +176,7 @@ namespace JSC {
T* m_data;
};
+ void* m_jsArrayVPtr;
MarkStackArray<MarkSet> m_markSets;
MarkStackArray<JSCell*> m_values;
static size_t s_pageSize;
diff --git a/JavaScriptCore/runtime/MarkStackWin.cpp b/JavaScriptCore/runtime/MarkStackWin.cpp
index dbc3306..1fdd06a 100644
--- a/JavaScriptCore/runtime/MarkStackWin.cpp
+++ b/JavaScriptCore/runtime/MarkStackWin.cpp
@@ -43,9 +43,11 @@ void* MarkStack::allocateStack(size_t size)
{
return VirtualAlloc(0, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
}
-void MarkStack::releaseStack(void* addr, size_t size)
+void MarkStack::releaseStack(void* addr, size_t)
{
- VirtualFree(addr, size, MEM_RELEASE);
+ // According to http://msdn.microsoft.com/en-us/library/aa366892(VS.85).aspx,
+ // dwSize must be 0 if dwFreeType is MEM_RELEASE.
+ VirtualFree(addr, 0, MEM_RELEASE);
}
}
diff --git a/JavaScriptCore/runtime/MathObject.h b/JavaScriptCore/runtime/MathObject.h
index 3557d1e..06aa54b 100644
--- a/JavaScriptCore/runtime/MathObject.h
+++ b/JavaScriptCore/runtime/MathObject.h
@@ -36,7 +36,7 @@ namespace JSC {
static PassRefPtr<Structure> createStructure(JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType));
+ return Structure::create(prototype, TypeInfo(ObjectType, HasDefaultMark));
}
};
diff --git a/JavaScriptCore/runtime/NumberConstructor.h b/JavaScriptCore/runtime/NumberConstructor.h
index b1224ec..6e67840 100644
--- a/JavaScriptCore/runtime/NumberConstructor.h
+++ b/JavaScriptCore/runtime/NumberConstructor.h
@@ -38,7 +38,7 @@ namespace JSC {
static PassRefPtr<Structure> createStructure(JSValue proto)
{
- return Structure::create(proto, TypeInfo(ObjectType, ImplementsHasInstance));
+ return Structure::create(proto, TypeInfo(ObjectType, ImplementsHasInstance | HasDefaultMark));
}
enum { NaNValue, NegInfinity, PosInfinity, MaxValue, MinValue };
diff --git a/JavaScriptCore/runtime/NumberObject.h b/JavaScriptCore/runtime/NumberObject.h
index d354b9b..07a013f 100644
--- a/JavaScriptCore/runtime/NumberObject.h
+++ b/JavaScriptCore/runtime/NumberObject.h
@@ -30,6 +30,11 @@ namespace JSC {
explicit NumberObject(PassRefPtr<Structure>);
static const ClassInfo info;
+
+ static PassRefPtr<Structure> createStructure(JSValue prototype)
+ {
+ return Structure::create(prototype, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot | HasDefaultMark));
+ }
private:
virtual const ClassInfo* classInfo() const { return &info; }
diff --git a/JavaScriptCore/runtime/ObjectConstructor.cpp b/JavaScriptCore/runtime/ObjectConstructor.cpp
index 70c7cd1..b05b910 100644
--- a/JavaScriptCore/runtime/ObjectConstructor.cpp
+++ b/JavaScriptCore/runtime/ObjectConstructor.cpp
@@ -21,6 +21,7 @@
#include "config.h"
#include "ObjectConstructor.h"
+#include "Error.h"
#include "JSFunction.h"
#include "JSGlobalObject.h"
#include "ObjectPrototype.h"
diff --git a/JavaScriptCore/runtime/PropertySlot.cpp b/JavaScriptCore/runtime/PropertySlot.cpp
index 36fa5d8..a0a2f48 100644
--- a/JavaScriptCore/runtime/PropertySlot.cpp
+++ b/JavaScriptCore/runtime/PropertySlot.cpp
@@ -23,7 +23,6 @@
#include "JSFunction.h"
#include "JSGlobalObject.h"
-#include "JSObject.h"
namespace JSC {
@@ -39,7 +38,7 @@ JSValue PropertySlot::functionGetter(ExecState* exec, const Identifier&, const P
return callData.native.function(exec, slot.m_data.getterFunc, slot.slotBase(), exec->emptyList());
ASSERT(callType == CallTypeJS);
// FIXME: Can this be done more efficiently using the callData?
- return static_cast<JSFunction*>(slot.m_data.getterFunc)->call(exec, slot.slotBase(), exec->emptyList());
+ return asFunction(slot.m_data.getterFunc)->call(exec, slot.slotBase(), exec->emptyList());
}
} // namespace JSC
diff --git a/JavaScriptCore/runtime/RegExpConstructor.cpp b/JavaScriptCore/runtime/RegExpConstructor.cpp
index 6a8089d..62d56e9 100644
--- a/JavaScriptCore/runtime/RegExpConstructor.cpp
+++ b/JavaScriptCore/runtime/RegExpConstructor.cpp
@@ -23,6 +23,7 @@
#include "RegExpConstructor.h"
#include "ArrayPrototype.h"
+#include "Error.h"
#include "JSArray.h"
#include "JSFunction.h"
#include "JSString.h"
@@ -329,7 +330,7 @@ JSObject* constructRegExp(ExecState* exec, const ArgList& args)
JSValue arg0 = args.at(0);
JSValue arg1 = args.at(1);
- if (arg0.isObject(&RegExpObject::info)) {
+ if (arg0.inherits(&RegExpObject::info)) {
if (!arg1.isUndefined())
return throwError(exec, TypeError, "Cannot supply flags when constructing one RegExp from another.");
return asObject(arg0);
diff --git a/JavaScriptCore/runtime/RegExpConstructor.h b/JavaScriptCore/runtime/RegExpConstructor.h
index 6823f3f..30b9750 100644
--- a/JavaScriptCore/runtime/RegExpConstructor.h
+++ b/JavaScriptCore/runtime/RegExpConstructor.h
@@ -36,7 +36,7 @@ namespace JSC {
static PassRefPtr<Structure> createStructure(JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, ImplementsHasInstance));
+ return Structure::create(prototype, TypeInfo(ObjectType, ImplementsHasInstance | HasDefaultMark));
}
virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
diff --git a/JavaScriptCore/runtime/RegExpObject.h b/JavaScriptCore/runtime/RegExpObject.h
index e83e0ac..5ca3b3f 100644
--- a/JavaScriptCore/runtime/RegExpObject.h
+++ b/JavaScriptCore/runtime/RegExpObject.h
@@ -48,7 +48,7 @@ namespace JSC {
static PassRefPtr<Structure> createStructure(JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType));
+ return Structure::create(prototype, TypeInfo(ObjectType, HasDefaultMark));
}
private:
diff --git a/JavaScriptCore/runtime/RegExpPrototype.cpp b/JavaScriptCore/runtime/RegExpPrototype.cpp
index b1ab889..30420e9 100644
--- a/JavaScriptCore/runtime/RegExpPrototype.cpp
+++ b/JavaScriptCore/runtime/RegExpPrototype.cpp
@@ -22,6 +22,7 @@
#include "RegExpPrototype.h"
#include "ArrayPrototype.h"
+#include "Error.h"
#include "JSArray.h"
#include "JSFunction.h"
#include "JSObject.h"
@@ -58,28 +59,28 @@ RegExpPrototype::RegExpPrototype(ExecState* exec, PassRefPtr<Structure> structur
JSValue JSC_HOST_CALL regExpProtoFuncTest(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
- if (!thisValue.isObject(&RegExpObject::info))
+ if (!thisValue.inherits(&RegExpObject::info))
return throwError(exec, TypeError);
return asRegExpObject(thisValue)->test(exec, args);
}
JSValue JSC_HOST_CALL regExpProtoFuncExec(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
- if (!thisValue.isObject(&RegExpObject::info))
+ if (!thisValue.inherits(&RegExpObject::info))
return throwError(exec, TypeError);
return asRegExpObject(thisValue)->exec(exec, args);
}
JSValue JSC_HOST_CALL regExpProtoFuncCompile(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
- if (!thisValue.isObject(&RegExpObject::info))
+ if (!thisValue.inherits(&RegExpObject::info))
return throwError(exec, TypeError);
RefPtr<RegExp> regExp;
JSValue arg0 = args.at(0);
JSValue arg1 = args.at(1);
- if (arg0.isObject(&RegExpObject::info)) {
+ if (arg0.inherits(&RegExpObject::info)) {
if (!arg1.isUndefined())
return throwError(exec, TypeError, "Cannot supply flags when constructing one RegExp from another.");
regExp = asRegExpObject(arg0)->regExp();
@@ -99,8 +100,8 @@ JSValue JSC_HOST_CALL regExpProtoFuncCompile(ExecState* exec, JSObject*, JSValue
JSValue JSC_HOST_CALL regExpProtoFuncToString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- if (!thisValue.isObject(&RegExpObject::info)) {
- if (thisValue.isObject(&RegExpPrototype::info))
+ if (!thisValue.inherits(&RegExpObject::info)) {
+ if (thisValue.inherits(&RegExpPrototype::info))
return jsNontrivialString(exec, "//");
return throwError(exec, TypeError);
}
diff --git a/JavaScriptCore/runtime/ScopeChain.cpp b/JavaScriptCore/runtime/ScopeChain.cpp
index 5c2edab..960c525 100644
--- a/JavaScriptCore/runtime/ScopeChain.cpp
+++ b/JavaScriptCore/runtime/ScopeChain.cpp
@@ -56,7 +56,7 @@ int ScopeChain::localDepth() const
int scopeDepth = 0;
ScopeChainIterator iter = this->begin();
ScopeChainIterator end = this->end();
- while (!(*iter)->isObject(&JSActivation::info)) {
+ while (!(*iter)->inherits(&JSActivation::info)) {
++iter;
if (iter == end)
break;
diff --git a/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h b/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h
index bc5c0a5..1d2e03f 100644
--- a/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h
+++ b/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h
@@ -44,7 +44,7 @@ namespace JSC {
static PassRefPtr<Structure> createStructure(JSValue proto)
{
- return Structure::create(proto, TypeInfo(ObjectType, MasqueradesAsUndefined));
+ return Structure::create(proto, TypeInfo(ObjectType, MasqueradesAsUndefined | HasDefaultMark));
}
virtual bool toBoolean(ExecState*) const { return false; }
diff --git a/JavaScriptCore/runtime/StringPrototype.cpp b/JavaScriptCore/runtime/StringPrototype.cpp
index 531a302..b4f7634 100644
--- a/JavaScriptCore/runtime/StringPrototype.cpp
+++ b/JavaScriptCore/runtime/StringPrototype.cpp
@@ -23,6 +23,7 @@
#include "StringPrototype.h"
#include "CachedCall.h"
+#include "Error.h"
#include "JSArray.h"
#include "JSFunction.h"
#include "ObjectPrototype.h"
@@ -220,7 +221,7 @@ JSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec, JSObject*, JSValue
if (callType == CallTypeNone)
replacementString = replacement.toString(exec);
- if (pattern.isObject(&RegExpObject::info)) {
+ if (pattern.inherits(&RegExpObject::info)) {
RegExp* reg = asRegExpObject(pattern)->regExp();
bool global = reg->global();
@@ -365,7 +366,7 @@ JSValue JSC_HOST_CALL stringProtoFuncToString(ExecState* exec, JSObject*, JSValu
if (thisValue.isString())
return thisValue;
- if (thisValue.isObject(&StringObject::info))
+ if (thisValue.inherits(&StringObject::info))
return asStringObject(thisValue)->internalValue();
return throwError(exec, TypeError);
@@ -466,7 +467,7 @@ JSValue JSC_HOST_CALL stringProtoFuncMatch(ExecState* exec, JSObject*, JSValue t
UString u = s;
RefPtr<RegExp> reg;
RegExpObject* imp = 0;
- if (a0.isObject(&RegExpObject::info))
+ if (a0.inherits(&RegExpObject::info))
reg = asRegExpObject(a0)->regExp();
else {
/*
@@ -516,7 +517,7 @@ JSValue JSC_HOST_CALL stringProtoFuncSearch(ExecState* exec, JSObject*, JSValue
UString u = s;
RefPtr<RegExp> reg;
- if (a0.isObject(&RegExpObject::info))
+ if (a0.inherits(&RegExpObject::info))
reg = asRegExpObject(a0)->regExp();
else {
/*
@@ -568,7 +569,7 @@ JSValue JSC_HOST_CALL stringProtoFuncSplit(ExecState* exec, JSObject*, JSValue t
unsigned i = 0;
int p0 = 0;
unsigned limit = a1.isUndefined() ? 0xFFFFFFFFU : a1.toUInt32(exec);
- if (a0.isObject(&RegExpObject::info)) {
+ if (a0.inherits(&RegExpObject::info)) {
RegExp* reg = asRegExpObject(a0)->regExp();
if (s.isEmpty() && reg->match(s, 0) >= 0) {
// empty string matched by regexp -> empty array
@@ -821,8 +822,8 @@ JSValue JSC_HOST_CALL stringProtoFuncFontsize(ExecState* exec, JSObject*, JSValu
if (a0.getUInt32(smallInteger) && smallInteger <= 9) {
unsigned stringSize = s.size();
unsigned bufferSize = 22 + stringSize;
- UChar* buffer = static_cast<UChar*>(tryFastMalloc(bufferSize * sizeof(UChar)));
- if (!buffer)
+ UChar* buffer;
+ if (!tryFastMalloc(bufferSize * sizeof(UChar)).getValue(buffer))
return jsUndefined();
buffer[0] = '<';
buffer[1] = 'f';
@@ -869,8 +870,8 @@ JSValue JSC_HOST_CALL stringProtoFuncLink(ExecState* exec, JSObject*, JSValue th
unsigned linkTextSize = linkText.size();
unsigned stringSize = s.size();
unsigned bufferSize = 15 + linkTextSize + stringSize;
- UChar* buffer = static_cast<UChar*>(tryFastMalloc(bufferSize * sizeof(UChar)));
- if (!buffer)
+ UChar* buffer;
+ if (!tryFastMalloc(bufferSize * sizeof(UChar)).getValue(buffer))
return jsUndefined();
buffer[0] = '<';
buffer[1] = 'a';
diff --git a/JavaScriptCore/runtime/TypeInfo.h b/JavaScriptCore/runtime/TypeInfo.h
index 70aeed3..20c13ea 100644
--- a/JavaScriptCore/runtime/TypeInfo.h
+++ b/JavaScriptCore/runtime/TypeInfo.h
@@ -38,6 +38,7 @@ namespace JSC {
static const unsigned ImplementsDefaultHasInstance = 1 << 3;
static const unsigned NeedsThisConversion = 1 << 4;
static const unsigned HasStandardGetOwnPropertySlot = 1 << 5;
+ static const unsigned HasDefaultMark = 1 << 6;
class TypeInfo {
friend class JIT;
@@ -59,7 +60,7 @@ namespace JSC {
bool overridesHasInstance() const { return m_flags & OverridesHasInstance; }
bool needsThisConversion() const { return m_flags & NeedsThisConversion; }
bool hasStandardGetOwnPropertySlot() const { return m_flags & HasStandardGetOwnPropertySlot; }
-
+ bool hasDefaultMark() const { return m_flags & HasDefaultMark; }
unsigned flags() const { return m_flags; }
private:
diff --git a/JavaScriptCore/runtime/UString.cpp b/JavaScriptCore/runtime/UString.cpp
index 118751e..9977f12 100644
--- a/JavaScriptCore/runtime/UString.cpp
+++ b/JavaScriptCore/runtime/UString.cpp
@@ -32,12 +32,14 @@
#include <ctype.h>
#include <float.h>
#include <limits.h>
+#include <limits>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <wtf/ASCIICType.h>
#include <wtf/Assertions.h>
#include <wtf/MathExtras.h>
+#include <wtf/StringExtras.h>
#include <wtf/Vector.h>
#include <wtf/unicode/UTF8.h>
@@ -68,20 +70,20 @@ static const int minLengthToShare = 10;
static inline size_t overflowIndicator() { return std::numeric_limits<size_t>::max(); }
static inline size_t maxUChars() { return std::numeric_limits<size_t>::max() / sizeof(UChar); }
-static inline UChar* allocChars(size_t length)
+static inline PossiblyNull<UChar*> allocChars(size_t length)
{
ASSERT(length);
if (length > maxUChars())
return 0;
- return static_cast<UChar*>(tryFastMalloc(sizeof(UChar) * length));
+ return tryFastMalloc(sizeof(UChar) * length);
}
-static inline UChar* reallocChars(UChar* buffer, size_t length)
+static inline PossiblyNull<UChar*> reallocChars(UChar* buffer, size_t length)
{
ASSERT(length);
if (length > maxUChars())
return 0;
- return static_cast<UChar*>(tryFastRealloc(buffer, sizeof(UChar) * length));
+ return tryFastRealloc(buffer, sizeof(UChar) * length);
}
static inline void copyChars(UChar* destination, const UChar* source, unsigned numCharacters)
@@ -480,8 +482,7 @@ static inline bool expandCapacity(UString::Rep* rep, int requiredLength)
if (requiredLength > base->capacity) {
size_t newCapacity = expandedSize(requiredLength, base->preCapacity);
UChar* oldBuf = base->buf;
- base->buf = reallocChars(base->buf, newCapacity);
- if (!base->buf) {
+ if (!reallocChars(base->buf, newCapacity).getValue(base->buf)) {
base->buf = oldBuf;
return false;
}
@@ -512,8 +513,7 @@ bool UString::Rep::reserveCapacity(int capacity)
size_t newCapacity = expandedSize(capacity, base->preCapacity);
UChar* oldBuf = base->buf;
- base->buf = reallocChars(base->buf, newCapacity);
- if (!base->buf) {
+ if (!reallocChars(base->buf, newCapacity).getValue(base->buf)) {
base->buf = oldBuf;
return false;
}
@@ -540,8 +540,8 @@ void UString::expandPreCapacity(int requiredPreCap)
size_t newCapacity = expandedSize(requiredPreCap, base->capacity);
int delta = newCapacity - base->capacity - base->preCapacity;
- UChar* newBuf = allocChars(newCapacity);
- if (!newBuf) {
+ UChar* newBuf;
+ if (!allocChars(newCapacity).getValue(newBuf)) {
makeNull();
return;
}
@@ -566,8 +566,8 @@ static PassRefPtr<UString::Rep> createRep(const char* c)
return &UString::Rep::empty();
size_t length = strlen(c);
- UChar* d = allocChars(length);
- if (!d)
+ UChar* d;
+ if (!allocChars(length).getValue(d))
return &UString::Rep::null();
else {
for (size_t i = 0; i < length; i++)
@@ -656,8 +656,8 @@ static ALWAYS_INLINE PassRefPtr<UString::Rep> concatenate(PassRefPtr<UString::Re
} else {
// This is shared in some way that prevents us from modifying base, so we must make a whole new string.
size_t newCapacity = expandedSize(length, 0);
- UChar* d = allocChars(newCapacity);
- if (!d)
+ UChar* d;
+ if (!allocChars(newCapacity).getValue(d))
rep = &UString::Rep::null();
else {
copyChars(d, rep->data(), thisSize);
@@ -712,8 +712,8 @@ static ALWAYS_INLINE PassRefPtr<UString::Rep> concatenate(PassRefPtr<UString::Re
} else {
// This is shared in some way that prevents us from modifying base, so we must make a whole new string.
size_t newCapacity = expandedSize(length, 0);
- UChar* d = allocChars(newCapacity);
- if (!d)
+ UChar* d;
+ if (!allocChars(newCapacity).getValue(d))
rep = &UString::Rep::null();
else {
copyChars(d, rep->data(), thisSize);
@@ -800,8 +800,8 @@ PassRefPtr<UString::Rep> concatenate(UString::Rep* a, UString::Rep* b)
// a does not qualify for append, and b does not qualify for prepend, gotta make a whole new string
size_t newCapacity = expandedSize(length, 0);
- UChar* d = allocChars(newCapacity);
- if (!d)
+ UChar* d;
+ if (!allocChars(newCapacity).getValue(d))
return 0;
copyChars(d, a->data(), aSize);
copyChars(d + aSize, b->data(), bSize);
@@ -942,6 +942,39 @@ UString UString::from(int i)
return UString(p, static_cast<int>(end - p));
}
+UString UString::from(long long i)
+{
+ UChar buf[1 + sizeof(i) * 3];
+ UChar* end = buf + sizeof(buf) / sizeof(UChar);
+ UChar* p = end;
+
+ if (i == 0)
+ *--p = '0';
+ else if (i == std::numeric_limits<long long>::min()) {
+ char minBuf[1 + sizeof(i) * 3];
+#if PLATFORM(WIN_OS)
+ snprintf(minBuf, sizeof(minBuf) - 1, "%I64d", std::numeric_limits<long long>::min());
+#else
+ snprintf(minBuf, sizeof(minBuf) - 1, "%lld", std::numeric_limits<long long>::min());
+#endif
+ return UString(minBuf);
+ } else {
+ bool negative = false;
+ if (i < 0) {
+ negative = true;
+ i = -i;
+ }
+ while (i) {
+ *--p = static_cast<unsigned short>((i % 10) + '0');
+ i /= 10;
+ }
+ if (negative)
+ *--p = '-';
+ }
+
+ return UString(p, static_cast<int>(end - p));
+}
+
UString UString::from(unsigned int u)
{
UChar buf[sizeof(u) * 3];
@@ -1076,8 +1109,8 @@ UString UString::spliceSubstringsWithSeparators(const Range* substringRanges, in
if (totalLength == 0)
return "";
- UChar* buffer = allocChars(totalLength);
- if (!buffer)
+ UChar* buffer;
+ if (!allocChars(totalLength).getValue(buffer))
return null();
int maxCount = max(rangeCount, separatorCount);
@@ -1105,8 +1138,8 @@ UString UString::replaceRange(int rangeStart, int rangeLength, const UString& re
if (totalLength == 0)
return "";
- UChar* buffer = allocChars(totalLength);
- if (!buffer)
+ UChar* buffer;
+ if (!allocChars(totalLength).getValue(buffer))
return null();
copyChars(buffer, data(), rangeStart);
@@ -1153,8 +1186,8 @@ UString& UString::append(const UString &t)
} else {
// This is shared in some way that prevents us from modifying base, so we must make a whole new string.
size_t newCapacity = expandedSize(length, 0);
- UChar* d = allocChars(newCapacity);
- if (!d)
+ UChar* d;
+ if (!allocChars(newCapacity).getValue(d))
makeNull();
else {
copyChars(d, data(), thisSize);
@@ -1206,8 +1239,8 @@ UString& UString::append(UChar c)
if (length == 0) {
// this is empty - must make a new m_rep because we don't want to pollute the shared empty one
size_t newCapacity = expandedSize(1, 0);
- UChar* d = allocChars(newCapacity);
- if (!d)
+ UChar* d;
+ if (!allocChars(newCapacity).getValue(d))
makeNull();
else {
d[0] = c;
@@ -1234,8 +1267,8 @@ UString& UString::append(UChar c)
} else {
// This is shared in some way that prevents us from modifying base, so we must make a whole new string.
size_t newCapacity = expandedSize(length + 1, 0);
- UChar* d = allocChars(newCapacity);
- if (!d)
+ UChar* d;
+ if (!allocChars(newCapacity).getValue(d))
makeNull();
else {
copyChars(d, data(), length);
@@ -1313,8 +1346,7 @@ UString& UString::operator=(const char* c)
m_rep->_hash = 0;
m_rep->len = l;
} else {
- d = allocChars(l);
- if (!d) {
+ if (!allocChars(l).getValue(d)) {
makeNull();
return *this;
}
diff --git a/JavaScriptCore/runtime/UString.h b/JavaScriptCore/runtime/UString.h
index d01b75d..2dbca1f 100644
--- a/JavaScriptCore/runtime/UString.h
+++ b/JavaScriptCore/runtime/UString.h
@@ -91,7 +91,8 @@ namespace JSC {
{
// Guard against integer overflow
if (size < (std::numeric_limits<size_t>::max() / sizeof(UChar))) {
- if (void * buf = tryFastMalloc(size * sizeof(UChar)))
+ void* buf = 0;
+ if (tryFastMalloc(size * sizeof(UChar)).getValue(buf))
return adoptRef(new BaseString(static_cast<UChar*>(buf), 0, size));
}
return adoptRef(new BaseString(0, 0, 0));
@@ -256,6 +257,7 @@ namespace JSC {
}
static UString from(int);
+ static UString from(long long);
static UString from(unsigned int);
static UString from(long);
static UString from(double);