summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2012-08-24 08:29:43 +0200
committerSimon Hausmann <simon.hausmann@nokia.com>2012-08-24 08:29:43 +0200
commit2e2ba8ff45915f40ed3e014101269c175f2a89a0 (patch)
tree3b94a9a9fa83efa384b8dac611cf8c6495532a62 /Source/JavaScriptCore
parentf53e6f8e798362ed712d4a51633b0d0b03dbc213 (diff)
downloadqtwebkit-2e2ba8ff45915f40ed3e014101269c175f2a89a0.tar.gz
Imported WebKit commit bf0b0213bbf3886c96610020602012ca7d11b084 (http://svn.webkit.org/repository/webkit/trunk@126545)
New snapshot with clang and python build fixes
Diffstat (limited to 'Source/JavaScriptCore')
-rw-r--r--Source/JavaScriptCore/API/JSValueRef.cpp2
-rw-r--r--Source/JavaScriptCore/ChangeLog201
-rw-r--r--Source/JavaScriptCore/Configurations/Version.xcconfig2
-rwxr-xr-xSource/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def5
-rw-r--r--Source/JavaScriptCore/bytecode/Watchpoint.h2
-rw-r--r--Source/JavaScriptCore/debugger/DebuggerCallFrame.h1
-rw-r--r--Source/JavaScriptCore/dfg/DFGAbstractState.cpp25
-rw-r--r--Source/JavaScriptCore/dfg/DFGCFGSimplificationPhase.cpp2
-rw-r--r--Source/JavaScriptCore/dfg/DFGOperations.cpp6
-rw-r--r--Source/JavaScriptCore/dfg/DFGOperations.h2
-rw-r--r--Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp73
-rw-r--r--Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp75
-rw-r--r--Source/JavaScriptCore/heap/MachineStackMarker.cpp7
-rw-r--r--Source/JavaScriptCore/heap/MachineStackMarker.h4
-rw-r--r--Source/JavaScriptCore/interpreter/Interpreter.cpp22
-rw-r--r--Source/JavaScriptCore/jit/JITOpcodes.cpp45
-rw-r--r--Source/JavaScriptCore/jit/JITOpcodes32_64.cpp46
-rw-r--r--Source/JavaScriptCore/jit/JITStubCall.h14
-rw-r--r--Source/JavaScriptCore/jit/JITStubs.cpp14
-rw-r--r--Source/JavaScriptCore/llint/LLIntSlowPaths.cpp8
-rw-r--r--Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm42
-rw-r--r--Source/JavaScriptCore/llint/LowLevelInterpreter64.asm36
-rw-r--r--Source/JavaScriptCore/runtime/ArrayPrototype.cpp12
-rw-r--r--Source/JavaScriptCore/runtime/BooleanConstructor.cpp4
-rw-r--r--Source/JavaScriptCore/runtime/BooleanObject.h6
-rw-r--r--Source/JavaScriptCore/runtime/JSCell.h2
-rw-r--r--Source/JavaScriptCore/runtime/JSGlobalObject.cpp1
-rw-r--r--Source/JavaScriptCore/runtime/JSGlobalObject.h5
-rw-r--r--Source/JavaScriptCore/runtime/JSString.h8
-rw-r--r--Source/JavaScriptCore/runtime/JSValue.h2
-rw-r--r--Source/JavaScriptCore/runtime/NumberObject.h4
-rw-r--r--Source/JavaScriptCore/runtime/ObjectConstructor.cpp6
-rw-r--r--Source/JavaScriptCore/runtime/Operations.cpp6
-rw-r--r--Source/JavaScriptCore/runtime/Operations.h6
-rw-r--r--Source/JavaScriptCore/runtime/RegExpConstructor.cpp4
-rw-r--r--Source/JavaScriptCore/runtime/RegExpPrototype.cpp6
-rw-r--r--Source/JavaScriptCore/runtime/StringObject.cpp8
-rw-r--r--Source/JavaScriptCore/runtime/StringObject.h2
-rw-r--r--Source/JavaScriptCore/runtime/Structure.h12
39 files changed, 600 insertions, 128 deletions
diff --git a/Source/JavaScriptCore/API/JSValueRef.cpp b/Source/JavaScriptCore/API/JSValueRef.cpp
index 04d7f661d..9b7268a2d 100644
--- a/Source/JavaScriptCore/API/JSValueRef.cpp
+++ b/Source/JavaScriptCore/API/JSValueRef.cpp
@@ -266,7 +266,7 @@ bool JSValueToBoolean(JSContextRef ctx, JSValueRef value)
APIEntryShim entryShim(exec);
JSValue jsValue = toJS(exec, value);
- return jsValue.toBoolean();
+ return jsValue.toBoolean(exec);
}
double JSValueToNumber(JSContextRef ctx, JSValueRef value, JSValueRef* exception)
diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog
index 987ca8ecf..a8434ccc7 100644
--- a/Source/JavaScriptCore/ChangeLog
+++ b/Source/JavaScriptCore/ChangeLog
@@ -1,3 +1,204 @@
+2011-08-23 Geoffrey Garen <ggaren@apple.com>
+
+ Unreviewed, rolling out r126505.
+ http://trac.webkit.org/changeset/126505
+ https://bugs.webkit.org/show_bug.cgi?id=94840
+
+ Caused testapi to crash on launch
+
+ * DerivedSources.make:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * bytecode/Opcode.h:
+ (JSC):
+ (JSC::padOpcodeName):
+ * bytecode/OpcodeDefinitions.h: Removed.
+ * bytecode/opcodes: Removed.
+ * opcode_definition_generator.py: Removed.
+ * opcode_generator.py: Removed.
+ * opcode_parser.py: Removed.
+
+2012-08-23 Oliver Hunt <oliver@apple.com>
+
+ Autogenerate Opcode definitions
+ https://bugs.webkit.org/show_bug.cgi?id=94840
+
+ Reviewed by Gavin Barraclough.
+
+ Start the process of autogenerating the code emission for the bytecode.
+ We'll just start with automatic generation of the list of Opcodes as that
+ requires the actual definition of the opcodes, and the logic for parsing
+ them.
+
+ Due to some rather annoying dependency cycles, this initial version has
+ the OpcodeDefinitions.h file checked into the tree, although with some
+ work I hope to be able to fix that.
+
+ * DerivedSources.make:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * bytecode/Opcode.h:
+ Include OpcodeDefinitions.h as our definitive source of info
+ about the opcodes.
+ * bytecode/OpcodeDefinitions.h: Added.
+ Autogenerated file
+ * bytecode/opcodes: Added.
+ The new opcode definition file
+ * opcode_definition_generator.py: Added.
+ (generateOpcodeDefinition):
+ (generate):
+ Module that generates the content for OpcodeDefinitions.h
+ * opcode_generator.py: Added.
+ (printUsage):
+ (main):
+ Driver script
+ * opcode_parser.py: Added.
+ Simple parser for the opcode definitions.
+
+2012-08-23 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Change behavior of MasqueradesAsUndefined to better accommodate DFG changes
+ https://bugs.webkit.org/show_bug.cgi?id=93884
+
+ Reviewed by Filip Pizlo.
+
+ With some upcoming changes to the DFG to remove uses of ClassInfo, we will be changing the behavior of
+ MasqueradesAsUndefined. In order to make this change consistent across all of our execution engines,
+ we will make this change to MasqueradesAsUndefined as a separate patch. After this patch, MasqueradesAsUndefined
+ objects will only masquerade as undefined in their original context (i.e. their original JSGlobalObject).
+ For example, if an object that masquerades as undefined in frame A is passed to frame B, it will not
+ masquerade as undefined within frame B, but it will continue to masquerade in frame A.
+
+ There are two primary changes that are taking place here. One is to thread the ExecState* through
+ JSValue::toBoolean and JSCell::toBoolean so that JSCell::toBoolean can check the object's
+ JSGlobalObject to compare it to the lexical JSGlobalObject of the currently running code. If the two
+ are distinct, then the object cannot MasqueradeAsUndefined.
+
+ The other change is to perform this comparison of JSGlobalObjects everywhere where the MasqueradesAsUndefined
+ flag in the Structure is checked. For C++ code, this check has been factored into its own function in
+ Structure::masqueradesAsUndefined. We only perform this check in the DFG if the current JSGlobalObject has
+ had a MasqueradesAsUndefined object allocated within its context. This conditional compilation is managed
+ through the use of a WatchpointSet in each JSGlobalObject and alternate create() functions for JS DOM wrappers
+ that are MasqueradesAsUndefined.
+
+ * API/JSValueRef.cpp:
+ (JSValueToBoolean):
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+ * bytecode/Watchpoint.h:
+ (WatchpointSet):
+ * debugger/DebuggerCallFrame.h:
+ (JSC::DebuggerCallFrame::callFrame):
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::execute):
+ * dfg/DFGCFGSimplificationPhase.cpp:
+ (JSC::DFG::CFGSimplificationPhase::run):
+ * dfg/DFGOperations.cpp:
+ * dfg/DFGOperations.h:
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull):
+ (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranchNull):
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull):
+ (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranchNull):
+ (JSC::DFG::SpeculativeJIT::compile):
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::privateExecute):
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::emit_op_is_undefined):
+ (JSC::JIT::emit_op_jeq_null):
+ (JSC::JIT::emit_op_jneq_null):
+ (JSC::JIT::emit_op_eq_null):
+ (JSC::JIT::emit_op_neq_null):
+ * jit/JITOpcodes32_64.cpp:
+ (JSC::JIT::emit_op_is_undefined):
+ (JSC::JIT::emit_op_jeq_null):
+ (JSC::JIT::emit_op_jneq_null):
+ (JSC::JIT::emit_op_eq_null):
+ (JSC::JIT::emit_op_neq_null):
+ * jit/JITStubs.cpp:
+ (JSC::DEFINE_STUB_FUNCTION):
+ * llint/LLIntSlowPaths.cpp:
+ (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+ * llint/LowLevelInterpreter32_64.asm:
+ * llint/LowLevelInterpreter64.asm:
+ * runtime/ArrayPrototype.cpp:
+ (JSC::arrayProtoFuncFilter):
+ (JSC::arrayProtoFuncEvery):
+ (JSC::arrayProtoFuncSome):
+ * runtime/BooleanConstructor.cpp:
+ (JSC::constructBoolean):
+ (JSC::callBooleanConstructor):
+ * runtime/JSCell.h:
+ (JSCell):
+ * runtime/JSGlobalObject.cpp:
+ (JSC::JSGlobalObject::JSGlobalObject):
+ * runtime/JSGlobalObject.h:
+ (JSGlobalObject):
+ (JSC::JSGlobalObject::masqueradesAsUndefinedWatchpoint):
+ * runtime/JSString.h:
+ (JSC::JSCell::toBoolean):
+ (JSC::JSValue::toBoolean):
+ * runtime/JSValue.h:
+ * runtime/ObjectConstructor.cpp:
+ (JSC::toPropertyDescriptor):
+ * runtime/Operations.cpp:
+ (JSC::jsTypeStringForValue):
+ (JSC::jsIsObjectType):
+ * runtime/Operations.h:
+ (JSC):
+ (JSC::JSValue::equalSlowCaseInline):
+ * runtime/RegExpConstructor.cpp:
+ (JSC::setRegExpConstructorMultiline):
+ * runtime/RegExpPrototype.cpp:
+ (JSC::regExpProtoFuncToString):
+ * runtime/Structure.h:
+ (Structure):
+ (JSC::Structure::globalObjectOffset):
+ (JSC::Structure::masqueradesAsUndefined):
+ (JSC):
+
+2012-08-23 Mark Rowe <mrowe@apple.com>
+
+ Make JavaScriptCore build with the latest version of clang.
+
+ Reviewed by Dan Bernstein.
+
+ * heap/MachineStackMarker.cpp:
+ (JSC::MachineThreads::MachineThreads): The m_heap member is only used within
+ assertions, so guard its initialization with !ASSERT_DISABLED.
+ * heap/MachineStackMarker.h:
+ (MachineThreads): Ditto for its declaration.
+ * jit/JITStubCall.h:
+ (JSC::JITStubCall::JITStubCall): The m_returnType member is only used within
+ assertions or if we're using JSVALUE32_64, so guard its uses with the appropriate
+ #if.
+ (JITStubCall): Ditto.
+
+2012-08-23 Christophe Dumez <christophe.dumez@intel.com>
+
+ Serialization of JavaScript values does not appear to respect new HTML5 Structured Clone semantics
+ https://bugs.webkit.org/show_bug.cgi?id=65292
+
+ Reviewed by Oliver Hunt.
+
+ Add function to construct a StringObject from a JSValue.
+ Similar functions already exist for NumberObject and
+ BooleanObject for example.
+
+ Export several symbols so address linking errors in
+ WebCore.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+ * runtime/BooleanObject.h:
+ (BooleanObject):
+ * runtime/NumberObject.h:
+ (NumberObject):
+ (JSC):
+ * runtime/StringObject.cpp:
+ (JSC::constructString):
+ (JSC):
+ * runtime/StringObject.h:
+ (JSC):
+
2012-08-22 Filip Pizlo <fpizlo@apple.com>
Array accesses should remember what kind of array they are predicted to access
diff --git a/Source/JavaScriptCore/Configurations/Version.xcconfig b/Source/JavaScriptCore/Configurations/Version.xcconfig
index b619d3602..cff1fe049 100644
--- a/Source/JavaScriptCore/Configurations/Version.xcconfig
+++ b/Source/JavaScriptCore/Configurations/Version.xcconfig
@@ -22,7 +22,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
MAJOR_VERSION = 537;
-MINOR_VERSION = 6;
+MINOR_VERSION = 8;
TINY_VERSION = 0;
FULL_VERSION = $(MAJOR_VERSION).$(MINOR_VERSION);
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def
index 8032ed178..e3453201b 100755
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def
@@ -1,6 +1,7 @@
EXPORTS
??0ArrayBufferView@WTF@@IAE@V?$PassRefPtr@VArrayBuffer@WTF@@@1@I@Z
+ ??0BooleanObject@JSC@@IAE@AAVJSGlobalData@1@PAVStructure@1@@Z
??0CString@WTF@@QAE@PBD@Z
??0CString@WTF@@QAE@PBDI@Z
??0Collator@WTF@@QAE@PBD@Z
@@ -107,6 +108,8 @@ EXPORTS
?constructArray@JSC@@YAPAVJSArray@1@PAVExecState@1@ABVArgList@1@@Z
?constructEmptyObject@JSC@@YAPAVJSObject@1@PAVExecState@1@@Z
?constructFunctionSkippingEvalEnabledCheck@JSC@@YAPAVJSObject@1@PAVExecState@1@PAVJSGlobalObject@1@ABVArgList@1@ABVIdentifier@1@ABVUString@1@ABVTextPosition@WTF@@@Z
+ ?constructNumber@JSC@@YAPAVNumberObject@1@PAVExecState@1@PAVJSGlobalObject@1@VJSValue@1@@Z
+ ?constructString@JSC@@YAPAVStringObject@1@PAVExecState@1@PAVJSGlobalObject@1@VJSValue@1@@Z
?convertLatin1ToUTF8@Unicode@WTF@@YA?AW4ConversionResult@12@PAPBEPBEPAPADPAD@Z
?convertUTF16ToUTF8@Unicode@WTF@@YA?AW4ConversionResult@12@PAPB_WPB_WPAPADPAD_N@Z
?convertUTF8ToUTF16@Unicode@WTF@@YA?AW4ConversionResult@12@PAPBDPBDPAPA_WPA_W_N@Z
@@ -186,6 +189,7 @@ EXPORTS
?fillGetterPropertySlot@JSObject@JSC@@AAEXAAVPropertySlot@2@PAV?$WriteBarrierBase@W4Unknown@JSC@@@2@@Z
?finalize@WeakHandleOwner@JSC@@UAEXV?$Handle@W4Unknown@JSC@@@2@PAX@Z
?findAllocator@WeakSet@JSC@@AAEPAUFreeCell@WeakBlock@2@XZ
+ ?finishCreation@BooleanObject@JSC@@IAEXAAVJSGlobalData@2@@Z
?finishCreation@DateInstance@JSC@@IAEXAAVJSGlobalData@2@N@Z
?finishCreation@InternalFunction@JSC@@IAEXAAVJSGlobalData@2@ABVUString@2@@Z
?finishCreation@JSArray@JSC@@IAEXAAVJSGlobalData@2@I@Z
@@ -258,6 +262,7 @@ EXPORTS
?neuter@ArrayBufferView@WTF@@MAEXXZ
?newUninitialized@CString@WTF@@SA?AV12@IAAPAD@Z
?notifyWriteSlow@SymbolTableEntry@JSC@@AAEXXZ
+ ?notifyWriteSlow@WatchpointSet@JSC@@QAEXXZ
?nullptr@@3Vnullptr_t@std@@A
?number@String@WTF@@SA?AV12@NII@Z
?number@UString@JSC@@SA?AV12@H@Z
diff --git a/Source/JavaScriptCore/bytecode/Watchpoint.h b/Source/JavaScriptCore/bytecode/Watchpoint.h
index 8e0526c0f..e6fba93a9 100644
--- a/Source/JavaScriptCore/bytecode/Watchpoint.h
+++ b/Source/JavaScriptCore/bytecode/Watchpoint.h
@@ -78,7 +78,7 @@ public:
bool* addressOfIsWatched() { return &m_isWatched; }
- void notifyWriteSlow(); // Call only if you've checked isWatched.
+ JS_EXPORT_PRIVATE void notifyWriteSlow(); // Call only if you've checked isWatched.
private:
void fireAllWatchpoints();
diff --git a/Source/JavaScriptCore/debugger/DebuggerCallFrame.h b/Source/JavaScriptCore/debugger/DebuggerCallFrame.h
index 8605af54d..dca7487c0 100644
--- a/Source/JavaScriptCore/debugger/DebuggerCallFrame.h
+++ b/Source/JavaScriptCore/debugger/DebuggerCallFrame.h
@@ -48,6 +48,7 @@ namespace JSC {
{
}
+ CallFrame* callFrame() const { return m_callFrame; }
JSGlobalObject* dynamicGlobalObject() const { return m_callFrame->dynamicGlobalObject(); }
ScopeChainNode* scopeChain() const { return m_callFrame->scopeChain(); }
JS_EXPORT_PRIVATE const UString* functionName() const;
diff --git a/Source/JavaScriptCore/dfg/DFGAbstractState.cpp b/Source/JavaScriptCore/dfg/DFGAbstractState.cpp
index cfe915947..43b5a03f3 100644
--- a/Source/JavaScriptCore/dfg/DFGAbstractState.cpp
+++ b/Source/JavaScriptCore/dfg/DFGAbstractState.cpp
@@ -618,7 +618,7 @@ bool AbstractState::execute(unsigned indexInBlock)
case LogicalNot: {
JSValue childConst = forNode(node.child1()).value();
- if (childConst && trySetConstant(nodeIndex, jsBoolean(!childConst.toBoolean()))) {
+ if (childConst && trySetConstant(nodeIndex, jsBoolean(!childConst.toBoolean(m_codeBlock->globalObjectFor(node.codeOrigin)->globalExec())))) {
m_foundConstants = true;
node.setCanExit(false);
break;
@@ -650,16 +650,23 @@ bool AbstractState::execute(unsigned indexInBlock)
case IsString:
case IsObject:
case IsFunction: {
- node.setCanExit(false);
+ node.setCanExit(node.op() == IsUndefined && m_codeBlock->globalObjectFor(node.codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid());
JSValue child = forNode(node.child1()).value();
if (child) {
bool constantWasSet;
switch (node.op()) {
case IsUndefined:
- constantWasSet = trySetConstant(nodeIndex, jsBoolean(
- child.isCell()
- ? child.asCell()->structure()->typeInfo().masqueradesAsUndefined()
- : child.isUndefined()));
+ if (m_codeBlock->globalObjectFor(node.codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid()) {
+ constantWasSet = trySetConstant(nodeIndex, jsBoolean(
+ child.isCell()
+ ? false
+ : child.isUndefined()));
+ } else {
+ constantWasSet = trySetConstant(nodeIndex, jsBoolean(
+ child.isCell()
+ ? child.asCell()->structure()->masqueradesAsUndefined(m_codeBlock->globalObjectFor(node.codeOrigin))
+ : child.isUndefined()));
+ }
break;
case IsBoolean:
constantWasSet = trySetConstant(nodeIndex, jsBoolean(child.isBoolean()));
@@ -739,8 +746,8 @@ bool AbstractState::execute(unsigned indexInBlock)
&& m_graph.valueOfJSConstant(node.child1().index()).isNull())
|| (m_graph.isConstant(node.child2().index())
&& m_graph.valueOfJSConstant(node.child2().index()).isNull())) {
- // We know that this won't clobber the world. But that's all we know.
- node.setCanExit(false);
+ // We can exit if we haven't fired the MasqueradesAsUndefind watchpoint yet.
+ node.setCanExit(m_codeBlock->globalObjectFor(node.codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid());
break;
}
@@ -1077,7 +1084,7 @@ bool AbstractState::execute(unsigned indexInBlock)
case Branch: {
JSValue value = forNode(node.child1()).value();
if (value) {
- bool booleanValue = value.toBoolean();
+ bool booleanValue = value.toBoolean(m_codeBlock->globalObjectFor(node.codeOrigin)->globalExec());
if (booleanValue)
m_branchDirection = TakeTrue;
else
diff --git a/Source/JavaScriptCore/dfg/DFGCFGSimplificationPhase.cpp b/Source/JavaScriptCore/dfg/DFGCFGSimplificationPhase.cpp
index f054707e2..aecce83ed 100644
--- a/Source/JavaScriptCore/dfg/DFGCFGSimplificationPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGCFGSimplificationPhase.cpp
@@ -101,7 +101,7 @@ public:
// Branch on constant -> jettison the not-taken block and merge.
if (m_graph[m_graph[block->last()].child1()].hasConstant()) {
bool condition =
- m_graph.valueOfJSConstant(m_graph[block->last()].child1().index()).toBoolean();
+ m_graph.valueOfJSConstant(m_graph[block->last()].child1().index()).toBoolean(m_graph.globalObjectFor(m_graph[block->last()].codeOrigin)->globalExec());
BasicBlock* targetBlock = m_graph.m_blocks[
m_graph.successorForCondition(block, condition)].get();
if (targetBlock->m_predecessors.size() == 1) {
diff --git a/Source/JavaScriptCore/dfg/DFGOperations.cpp b/Source/JavaScriptCore/dfg/DFGOperations.cpp
index 882e1cd02..b5c3b961b 100644
--- a/Source/JavaScriptCore/dfg/DFGOperations.cpp
+++ b/Source/JavaScriptCore/dfg/DFGOperations.cpp
@@ -1273,9 +1273,9 @@ JSCell* DFG_OPERATION operationNewFunctionExpression(ExecState* exec, JSCell* fu
return function;
}
-size_t DFG_OPERATION operationIsObject(EncodedJSValue value)
+size_t DFG_OPERATION operationIsObject(ExecState* exec, EncodedJSValue value)
{
- return jsIsObjectType(JSValue::decode(value));
+ return jsIsObjectType(exec, JSValue::decode(value));
}
size_t DFG_OPERATION operationIsFunction(EncodedJSValue value)
@@ -1368,7 +1368,7 @@ size_t DFG_OPERATION dfgConvertJSValueToBoolean(ExecState* exec, EncodedJSValue
JSGlobalData* globalData = &exec->globalData();
NativeCallFrameTracer tracer(globalData, exec);
- return JSValue::decode(encodedOp).toBoolean();
+ return JSValue::decode(encodedOp).toBoolean(exec);
}
#if DFG_ENABLE(VERBOSE_SPECULATION_FAILURE)
diff --git a/Source/JavaScriptCore/dfg/DFGOperations.h b/Source/JavaScriptCore/dfg/DFGOperations.h
index 0ff721216..455c2bcc3 100644
--- a/Source/JavaScriptCore/dfg/DFGOperations.h
+++ b/Source/JavaScriptCore/dfg/DFGOperations.h
@@ -180,7 +180,7 @@ EncodedJSValue DFG_OPERATION operationGetArgumentByVal(ExecState*, int32_t, int3
JSCell* DFG_OPERATION operationNewFunction(ExecState*, JSCell*) WTF_INTERNAL;
JSCell* DFG_OPERATION operationNewFunctionExpression(ExecState*, JSCell*) WTF_INTERNAL;
double DFG_OPERATION operationFModOnInts(int32_t, int32_t) WTF_INTERNAL;
-size_t DFG_OPERATION operationIsObject(EncodedJSValue) WTF_INTERNAL;
+size_t DFG_OPERATION operationIsObject(ExecState*, EncodedJSValue) WTF_INTERNAL;
size_t DFG_OPERATION operationIsFunction(EncodedJSValue) WTF_INTERNAL;
void DFG_OPERATION operationReallocateStorageAndFinishPut(ExecState*, JSObject*, Structure*, PropertyOffset, EncodedJSValue) WTF_INTERNAL;
char* DFG_OPERATION operationAllocatePropertyStorageWithInitialCapacity(ExecState*) WTF_INTERNAL;
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
index 26a48dcec..846d078ba 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
@@ -623,10 +623,29 @@ void SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull(Edge operand, bool inv
JITCompiler::Jump notCell;
if (!isKnownCell(operand.index()))
notCell = m_jit.branch32(MacroAssembler::NotEqual, argTagGPR, TrustedImm32(JSValue::CellTag));
-
- m_jit.loadPtr(JITCompiler::Address(argPayloadGPR, JSCell::structureOffset()), resultPayloadGPR);
- m_jit.test8(invert ? JITCompiler::Zero : JITCompiler::NonZero, JITCompiler::Address(resultPayloadGPR, Structure::typeInfoFlagsOffset()), JITCompiler::TrustedImm32(MasqueradesAsUndefined), resultPayloadGPR);
-
+
+ JITCompiler::Jump notMasqueradesAsUndefined;
+ if (m_jit.graph().globalObjectFor(m_jit.graph()[operand].codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid()) {
+ m_jit.graph().globalObjectFor(m_jit.graph()[operand].codeOrigin)->masqueradesAsUndefinedWatchpoint()->add(speculationWatchpoint());
+ m_jit.move(invert ? TrustedImm32(1) : TrustedImm32(0), resultPayloadGPR);
+ notMasqueradesAsUndefined = m_jit.jump();
+ } else {
+ m_jit.loadPtr(JITCompiler::Address(argPayloadGPR, JSCell::structureOffset()), resultPayloadGPR);
+ JITCompiler::Jump isMasqueradesAsUndefined = m_jit.branchTest8(JITCompiler::NonZero, JITCompiler::Address(resultPayloadGPR, Structure::typeInfoFlagsOffset()), JITCompiler::TrustedImm32(MasqueradesAsUndefined));
+
+ m_jit.move(invert ? TrustedImm32(1) : TrustedImm32(0), resultPayloadGPR);
+ notMasqueradesAsUndefined = m_jit.jump();
+
+ isMasqueradesAsUndefined.link(&m_jit);
+ GPRTemporary localGlobalObject(this);
+ GPRTemporary remoteGlobalObject(this);
+ GPRReg localGlobalObjectGPR = localGlobalObject.gpr();
+ GPRReg remoteGlobalObjectGPR = remoteGlobalObject.gpr();
+ m_jit.move(JITCompiler::TrustedImmPtr(m_jit.graph().globalObjectFor(m_jit.graph()[operand].codeOrigin)), localGlobalObjectGPR);
+ m_jit.loadPtr(JITCompiler::Address(resultPayloadGPR, Structure::globalObjectOffset()), remoteGlobalObjectGPR);
+ m_jit.compare32(invert ? JITCompiler::NotEqual : JITCompiler::Equal, localGlobalObjectGPR, remoteGlobalObjectGPR, resultPayloadGPR);
+ }
+
if (!isKnownCell(operand.index())) {
JITCompiler::Jump done = m_jit.jump();
@@ -640,6 +659,8 @@ void SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull(Edge operand, bool inv
done.link(&m_jit);
}
+ notMasqueradesAsUndefined.link(&m_jit);
+
booleanResult(resultPayloadGPR, m_compileIndex);
}
@@ -668,9 +689,22 @@ void SpeculativeJIT::nonSpeculativePeepholeBranchNull(Edge operand, NodeIndex br
if (!isKnownCell(operand.index()))
notCell = m_jit.branch32(MacroAssembler::NotEqual, argTagGPR, TrustedImm32(JSValue::CellTag));
- m_jit.loadPtr(JITCompiler::Address(argPayloadGPR, JSCell::structureOffset()), resultGPR);
- branchTest8(invert ? JITCompiler::Zero : JITCompiler::NonZero, JITCompiler::Address(resultGPR, Structure::typeInfoFlagsOffset()), JITCompiler::TrustedImm32(MasqueradesAsUndefined), taken);
-
+ if (m_jit.graph().globalObjectFor(m_jit.graph()[operand].codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid()) {
+ m_jit.graph().globalObjectFor(m_jit.graph()[operand].codeOrigin)->masqueradesAsUndefinedWatchpoint()->add(speculationWatchpoint());
+ jump(invert ? taken : notTaken, ForceJump);
+ } else {
+ m_jit.loadPtr(JITCompiler::Address(argPayloadGPR, JSCell::structureOffset()), resultGPR);
+ branchTest8(JITCompiler::Zero, JITCompiler::Address(resultGPR, Structure::typeInfoFlagsOffset()), JITCompiler::TrustedImm32(MasqueradesAsUndefined), invert ? taken : notTaken);
+
+ GPRTemporary localGlobalObject(this);
+ GPRTemporary remoteGlobalObject(this);
+ GPRReg localGlobalObjectGPR = localGlobalObject.gpr();
+ GPRReg remoteGlobalObjectGPR = remoteGlobalObject.gpr();
+ m_jit.move(TrustedImmPtr(m_jit.graph().globalObjectFor(m_jit.graph()[operand].codeOrigin)), localGlobalObjectGPR);
+ m_jit.loadPtr(JITCompiler::Address(resultGPR, Structure::globalObjectOffset()), remoteGlobalObjectGPR);
+ branchPtr(JITCompiler::Equal, localGlobalObjectGPR, remoteGlobalObjectGPR, invert ? notTaken : taken);
+ }
+
if (!isKnownCell(operand.index())) {
jump(notTaken, ForceJump);
@@ -3580,9 +3614,28 @@ void SpeculativeJIT::compile(Node& node)
JITCompiler::Jump done = m_jit.jump();
isCell.link(&m_jit);
- m_jit.loadPtr(JITCompiler::Address(value.payloadGPR(), JSCell::structureOffset()), result.gpr());
- m_jit.test8(JITCompiler::NonZero, JITCompiler::Address(result.gpr(), Structure::typeInfoFlagsOffset()), TrustedImm32(MasqueradesAsUndefined), result.gpr());
-
+ JITCompiler::Jump notMasqueradesAsUndefined;
+ if (m_jit.graph().globalObjectFor(node.codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid()) {
+ m_jit.graph().globalObjectFor(node.codeOrigin)->masqueradesAsUndefinedWatchpoint()->add(speculationWatchpoint());
+ m_jit.move(TrustedImm32(0), result.gpr());
+ notMasqueradesAsUndefined = m_jit.jump();
+ } else {
+ m_jit.loadPtr(JITCompiler::Address(value.payloadGPR(), JSCell::structureOffset()), result.gpr());
+ JITCompiler::Jump isMasqueradesAsUndefined = m_jit.branchTest8(JITCompiler::NonZero, JITCompiler::Address(result.gpr(), Structure::typeInfoFlagsOffset()), TrustedImm32(MasqueradesAsUndefined));
+ m_jit.move(TrustedImm32(0), result.gpr());
+ notMasqueradesAsUndefined = m_jit.jump();
+
+ isMasqueradesAsUndefined.link(&m_jit);
+ GPRTemporary localGlobalObject(this);
+ GPRTemporary remoteGlobalObject(this);
+ GPRReg localGlobalObjectGPR = localGlobalObject.gpr();
+ GPRReg remoteGlobalObjectGPR = remoteGlobalObject.gpr();
+ m_jit.move(TrustedImmPtr(m_jit.globalObjectFor(node.codeOrigin)), localGlobalObjectGPR);
+ m_jit.loadPtr(JITCompiler::Address(result.gpr(), Structure::globalObjectOffset()), remoteGlobalObjectGPR);
+ m_jit.compare32(JITCompiler::Equal, localGlobalObjectGPR, remoteGlobalObjectGPR, result.gpr());
+ }
+
+ notMasqueradesAsUndefined.link(&m_jit);
done.link(&m_jit);
booleanResult(result.gpr(), m_compileIndex);
break;
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
index c2e207264..b69d53600 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
@@ -588,10 +588,29 @@ void SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull(Edge operand, bool inv
if (!isKnownCell(operand.index()))
notCell = m_jit.branchTestPtr(MacroAssembler::NonZero, argGPR, GPRInfo::tagMaskRegister);
-
- m_jit.loadPtr(JITCompiler::Address(argGPR, JSCell::structureOffset()), resultGPR);
- m_jit.test8(invert ? JITCompiler::Zero : JITCompiler::NonZero, JITCompiler::Address(resultGPR, Structure::typeInfoFlagsOffset()), JITCompiler::TrustedImm32(MasqueradesAsUndefined), resultGPR);
-
+
+ JITCompiler::Jump notMasqueradesAsUndefined;
+ if (m_jit.graph().globalObjectFor(m_jit.graph()[operand].codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid()) {
+ m_jit.graph().globalObjectFor(m_jit.graph()[operand].codeOrigin)->masqueradesAsUndefinedWatchpoint()->add(speculationWatchpoint());
+ m_jit.move(invert ? TrustedImm32(1) : TrustedImm32(0), resultGPR);
+ notMasqueradesAsUndefined = m_jit.jump();
+ } else {
+ m_jit.loadPtr(JITCompiler::Address(argGPR, JSCell::structureOffset()), resultGPR);
+ JITCompiler::Jump isMasqueradesAsUndefined = m_jit.branchTest8(JITCompiler::NonZero, JITCompiler::Address(resultGPR, Structure::typeInfoFlagsOffset()), JITCompiler::TrustedImm32(MasqueradesAsUndefined));
+
+ m_jit.move(invert ? TrustedImm32(1) : TrustedImm32(0), resultGPR);
+ notMasqueradesAsUndefined = m_jit.jump();
+
+ isMasqueradesAsUndefined.link(&m_jit);
+ GPRTemporary localGlobalObject(this);
+ GPRTemporary remoteGlobalObject(this);
+ GPRReg localGlobalObjectGPR = localGlobalObject.gpr();
+ GPRReg remoteGlobalObjectGPR = remoteGlobalObject.gpr();
+ m_jit.move(JITCompiler::TrustedImmPtr(m_jit.graph().globalObjectFor(m_jit.graph()[operand].codeOrigin)), localGlobalObjectGPR);
+ m_jit.loadPtr(JITCompiler::Address(resultGPR, Structure::globalObjectOffset()), remoteGlobalObjectGPR);
+ m_jit.comparePtr(invert ? JITCompiler::NotEqual : JITCompiler::Equal, localGlobalObjectGPR, remoteGlobalObjectGPR, resultGPR);
+ }
+
if (!isKnownCell(operand.index())) {
JITCompiler::Jump done = m_jit.jump();
@@ -603,7 +622,9 @@ void SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull(Edge operand, bool inv
done.link(&m_jit);
}
-
+
+ notMasqueradesAsUndefined.link(&m_jit);
+
m_jit.or32(TrustedImm32(ValueFalse), resultGPR);
jsValueResult(resultGPR, m_compileIndex, DataFormatJSBoolean);
}
@@ -632,9 +653,22 @@ void SpeculativeJIT::nonSpeculativePeepholeBranchNull(Edge operand, NodeIndex br
if (!isKnownCell(operand.index()))
notCell = m_jit.branchTestPtr(MacroAssembler::NonZero, argGPR, GPRInfo::tagMaskRegister);
- m_jit.loadPtr(JITCompiler::Address(argGPR, JSCell::structureOffset()), resultGPR);
- branchTest8(invert ? JITCompiler::Zero : JITCompiler::NonZero, JITCompiler::Address(resultGPR, Structure::typeInfoFlagsOffset()), JITCompiler::TrustedImm32(MasqueradesAsUndefined), taken);
-
+ if (m_jit.graph().globalObjectFor(m_jit.graph()[operand].codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid()) {
+ m_jit.graph().globalObjectFor(m_jit.graph()[operand].codeOrigin)->masqueradesAsUndefinedWatchpoint()->add(speculationWatchpoint());
+ jump(invert ? taken : notTaken, ForceJump);
+ } else {
+ m_jit.loadPtr(JITCompiler::Address(argGPR, JSCell::structureOffset()), resultGPR);
+ branchTest8(JITCompiler::Zero, JITCompiler::Address(resultGPR, Structure::typeInfoFlagsOffset()), JITCompiler::TrustedImm32(MasqueradesAsUndefined), invert ? taken : notTaken);
+
+ GPRTemporary localGlobalObject(this);
+ GPRTemporary remoteGlobalObject(this);
+ GPRReg localGlobalObjectGPR = localGlobalObject.gpr();
+ GPRReg remoteGlobalObjectGPR = remoteGlobalObject.gpr();
+ m_jit.move(TrustedImmPtr(m_jit.graph().globalObjectFor(m_jit.graph()[operand].codeOrigin)), localGlobalObjectGPR);
+ m_jit.loadPtr(JITCompiler::Address(resultGPR, Structure::globalObjectOffset()), remoteGlobalObjectGPR);
+ branchPtr(JITCompiler::Equal, localGlobalObjectGPR, remoteGlobalObjectGPR, invert ? notTaken : taken);
+ }
+
if (!isKnownCell(operand.index())) {
jump(notTaken, ForceJump);
@@ -3553,9 +3587,28 @@ void SpeculativeJIT::compile(Node& node)
JITCompiler::Jump done = m_jit.jump();
isCell.link(&m_jit);
- m_jit.loadPtr(JITCompiler::Address(value.gpr(), JSCell::structureOffset()), result.gpr());
- m_jit.test8(JITCompiler::NonZero, JITCompiler::Address(result.gpr(), Structure::typeInfoFlagsOffset()), TrustedImm32(MasqueradesAsUndefined), result.gpr());
-
+ JITCompiler::Jump notMasqueradesAsUndefined;
+ if (m_jit.graph().globalObjectFor(node.codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid()) {
+ m_jit.graph().globalObjectFor(node.codeOrigin)->masqueradesAsUndefinedWatchpoint()->add(speculationWatchpoint());
+ m_jit.move(TrustedImm32(0), result.gpr());
+ notMasqueradesAsUndefined = m_jit.jump();
+ } else {
+ m_jit.loadPtr(JITCompiler::Address(value.gpr(), JSCell::structureOffset()), result.gpr());
+ JITCompiler::Jump isMasqueradesAsUndefined = m_jit.branchTest8(JITCompiler::NonZero, JITCompiler::Address(result.gpr(), Structure::typeInfoFlagsOffset()), TrustedImm32(MasqueradesAsUndefined));
+ m_jit.move(TrustedImm32(0), result.gpr());
+ notMasqueradesAsUndefined = m_jit.jump();
+
+ isMasqueradesAsUndefined.link(&m_jit);
+ GPRTemporary localGlobalObject(this);
+ GPRTemporary remoteGlobalObject(this);
+ GPRReg localGlobalObjectGPR = localGlobalObject.gpr();
+ GPRReg remoteGlobalObjectGPR = remoteGlobalObject.gpr();
+ m_jit.move(TrustedImmPtr(m_jit.globalObjectFor(node.codeOrigin)), localGlobalObjectGPR);
+ m_jit.loadPtr(JITCompiler::Address(result.gpr(), Structure::globalObjectOffset()), remoteGlobalObjectGPR);
+ m_jit.comparePtr(JITCompiler::Equal, localGlobalObjectGPR, remoteGlobalObjectGPR, result.gpr());
+ }
+
+ notMasqueradesAsUndefined.link(&m_jit);
done.link(&m_jit);
m_jit.or32(TrustedImm32(ValueFalse), result.gpr());
jsValueResult(result.gpr(), m_compileIndex, DataFormatJSBoolean);
diff --git a/Source/JavaScriptCore/heap/MachineStackMarker.cpp b/Source/JavaScriptCore/heap/MachineStackMarker.cpp
index 537a34e48..3c7ff9c3e 100644
--- a/Source/JavaScriptCore/heap/MachineStackMarker.cpp
+++ b/Source/JavaScriptCore/heap/MachineStackMarker.cpp
@@ -133,10 +133,13 @@ public:
};
MachineThreads::MachineThreads(Heap* heap)
- : m_heap(heap)
- , m_registeredThreads(0)
+ : m_registeredThreads(0)
, m_threadSpecific(0)
+#if !ASSERT_DISABLED
+ , m_heap(heap)
+#endif
{
+ UNUSED_PARAM(heap);
}
MachineThreads::~MachineThreads()
diff --git a/Source/JavaScriptCore/heap/MachineStackMarker.h b/Source/JavaScriptCore/heap/MachineStackMarker.h
index 3d4aa22d4..cece29cd3 100644
--- a/Source/JavaScriptCore/heap/MachineStackMarker.h
+++ b/Source/JavaScriptCore/heap/MachineStackMarker.h
@@ -52,10 +52,12 @@ namespace JSC {
void gatherFromOtherThread(ConservativeRoots&, Thread*);
- Heap* m_heap;
Mutex m_registeredThreadsMutex;
Thread* m_registeredThreads;
WTF::ThreadSpecificKey m_threadSpecific;
+#if !ASSERT_DISABLED
+ Heap* m_heap;
+#endif
};
} // namespace JSC
diff --git a/Source/JavaScriptCore/interpreter/Interpreter.cpp b/Source/JavaScriptCore/interpreter/Interpreter.cpp
index a9118f43b..f6a197ef0 100644
--- a/Source/JavaScriptCore/interpreter/Interpreter.cpp
+++ b/Source/JavaScriptCore/interpreter/Interpreter.cpp
@@ -2118,7 +2118,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
NEXT_INSTRUCTION();
}
- callFrame->uncheckedR(dst) = jsBoolean(src.isCell() && src.asCell()->structure()->typeInfo().masqueradesAsUndefined());
+ callFrame->uncheckedR(dst) = jsBoolean(src.isCell() && src.asCell()->structure()->masqueradesAsUndefined(callFrame->lexicalGlobalObject()));
vPC += OPCODE_LENGTH(op_eq_null);
NEXT_INSTRUCTION();
}
@@ -2158,7 +2158,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
NEXT_INSTRUCTION();
}
- callFrame->uncheckedR(dst) = jsBoolean(!src.isCell() || !src.asCell()->structure()->typeInfo().masqueradesAsUndefined());
+ callFrame->uncheckedR(dst) = jsBoolean(!src.isCell() || !src.asCell()->structure()->masqueradesAsUndefined(callFrame->lexicalGlobalObject()));
vPC += OPCODE_LENGTH(op_neq_null);
NEXT_INSTRUCTION();
}
@@ -2632,7 +2632,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
*/
int dst = vPC[1].u.operand;
int src = vPC[2].u.operand;
- JSValue result = jsBoolean(!callFrame->r(src).jsValue().toBoolean());
+ JSValue result = jsBoolean(!callFrame->r(src).jsValue().toBoolean(callFrame));
CHECK_FOR_EXCEPTION();
callFrame->uncheckedR(dst) = result;
@@ -2708,7 +2708,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
int dst = vPC[1].u.operand;
int src = vPC[2].u.operand;
JSValue v = callFrame->r(src).jsValue();
- callFrame->uncheckedR(dst) = jsBoolean(v.isCell() ? v.asCell()->structure()->typeInfo().masqueradesAsUndefined() : v.isUndefined());
+ callFrame->uncheckedR(dst) = jsBoolean(v.isCell() ? v.asCell()->structure()->masqueradesAsUndefined(callFrame->lexicalGlobalObject()) : v.isUndefined());
vPC += OPCODE_LENGTH(op_is_undefined);
NEXT_INSTRUCTION();
@@ -2764,7 +2764,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
*/
int dst = vPC[1].u.operand;
int src = vPC[2].u.operand;
- callFrame->uncheckedR(dst) = jsBoolean(jsIsObjectType(callFrame->r(src).jsValue()));
+ callFrame->uncheckedR(dst) = jsBoolean(jsIsObjectType(callFrame, callFrame->r(src).jsValue()));
vPC += OPCODE_LENGTH(op_is_object);
NEXT_INSTRUCTION();
@@ -3980,7 +3980,7 @@ skip_id_custom_self:
*/
int cond = vPC[1].u.operand;
int target = vPC[2].u.operand;
- if (callFrame->r(cond).jsValue().toBoolean()) {
+ if (callFrame->r(cond).jsValue().toBoolean(callFrame)) {
vPC += target;
CHECK_FOR_TIMEOUT();
NEXT_INSTRUCTION();
@@ -4000,7 +4000,7 @@ skip_id_custom_self:
*/
int cond = vPC[1].u.operand;
int target = vPC[2].u.operand;
- if (!callFrame->r(cond).jsValue().toBoolean()) {
+ if (!callFrame->r(cond).jsValue().toBoolean(callFrame)) {
vPC += target;
CHECK_FOR_TIMEOUT();
NEXT_INSTRUCTION();
@@ -4017,7 +4017,7 @@ skip_id_custom_self:
*/
int cond = vPC[1].u.operand;
int target = vPC[2].u.operand;
- if (callFrame->r(cond).jsValue().toBoolean()) {
+ if (callFrame->r(cond).jsValue().toBoolean(callFrame)) {
vPC += target;
NEXT_INSTRUCTION();
}
@@ -4033,7 +4033,7 @@ skip_id_custom_self:
*/
int cond = vPC[1].u.operand;
int target = vPC[2].u.operand;
- if (!callFrame->r(cond).jsValue().toBoolean()) {
+ if (!callFrame->r(cond).jsValue().toBoolean(callFrame)) {
vPC += target;
NEXT_INSTRUCTION();
}
@@ -4051,7 +4051,7 @@ skip_id_custom_self:
int target = vPC[2].u.operand;
JSValue srcValue = callFrame->r(src).jsValue();
- if (srcValue.isUndefinedOrNull() || (srcValue.isCell() && srcValue.asCell()->structure()->typeInfo().masqueradesAsUndefined())) {
+ if (srcValue.isUndefinedOrNull() || (srcValue.isCell() && srcValue.asCell()->structure()->masqueradesAsUndefined(callFrame->lexicalGlobalObject()))) {
vPC += target;
NEXT_INSTRUCTION();
}
@@ -4069,7 +4069,7 @@ skip_id_custom_self:
int target = vPC[2].u.operand;
JSValue srcValue = callFrame->r(src).jsValue();
- if (!srcValue.isUndefinedOrNull() && (!srcValue.isCell() || !srcValue.asCell()->structure()->typeInfo().masqueradesAsUndefined())) {
+ if (!srcValue.isUndefinedOrNull() && (!srcValue.isCell() || !(srcValue.asCell()->structure()->masqueradesAsUndefined(callFrame->lexicalGlobalObject())))) {
vPC += target;
NEXT_INSTRUCTION();
}
diff --git a/Source/JavaScriptCore/jit/JITOpcodes.cpp b/Source/JavaScriptCore/jit/JITOpcodes.cpp
index 0d24961b8..8ebad61ff 100644
--- a/Source/JavaScriptCore/jit/JITOpcodes.cpp
+++ b/Source/JavaScriptCore/jit/JITOpcodes.cpp
@@ -479,8 +479,16 @@ void JIT::emit_op_is_undefined(Instruction* currentInstruction)
isCell.link(this);
loadPtr(Address(regT0, JSCell::structureOffset()), regT1);
- test8(NonZero, Address(regT1, Structure::typeInfoFlagsOffset()), TrustedImm32(MasqueradesAsUndefined), regT0);
-
+ Jump isMasqueradesAsUndefined = branchTest8(NonZero, Address(regT1, Structure::typeInfoFlagsOffset()), TrustedImm32(MasqueradesAsUndefined));
+ move(TrustedImm32(0), regT0);
+ Jump notMasqueradesAsUndefined = jump();
+
+ isMasqueradesAsUndefined.link(this);
+ move(TrustedImmPtr(m_codeBlock->globalObject()), regT0);
+ loadPtr(Address(regT1, Structure::globalObjectOffset()), regT1);
+ comparePtr(Equal, regT0, regT1, regT0);
+
+ notMasqueradesAsUndefined.link(this);
done.link(this);
emitTagAsBoolImmediate(regT0);
emitPutVirtualRegister(dst);
@@ -760,15 +768,18 @@ void JIT::emit_op_jeq_null(Instruction* currentInstruction)
// First, handle JSCell cases - check MasqueradesAsUndefined bit on the structure.
loadPtr(Address(regT0, JSCell::structureOffset()), regT2);
- addJump(branchTest8(NonZero, Address(regT2, Structure::typeInfoFlagsOffset()), TrustedImm32(MasqueradesAsUndefined)), target);
- Jump wasNotImmediate = jump();
+ Jump isNotMasqueradesAsUndefined = branchTest8(Zero, Address(regT2, Structure::typeInfoFlagsOffset()), TrustedImm32(MasqueradesAsUndefined));
+ move(TrustedImmPtr(m_codeBlock->globalObject()), regT0);
+ addJump(branchPtr(Equal, Address(regT2, Structure::globalObjectOffset()), regT0), target);
+ Jump masqueradesGlobalObjectIsForeign = jump();
// Now handle the immediate cases - undefined & null
isImmediate.link(this);
andPtr(TrustedImm32(~TagBitUndefined), regT0);
addJump(branchPtr(Equal, regT0, TrustedImmPtr(JSValue::encode(jsNull()))), target);
- wasNotImmediate.link(this);
+ isNotMasqueradesAsUndefined.link(this);
+ masqueradesGlobalObjectIsForeign.link(this);
};
void JIT::emit_op_jneq_null(Instruction* currentInstruction)
{
@@ -781,6 +792,8 @@ void JIT::emit_op_jneq_null(Instruction* currentInstruction)
// First, handle JSCell cases - check MasqueradesAsUndefined bit on the structure.
loadPtr(Address(regT0, JSCell::structureOffset()), regT2);
addJump(branchTest8(Zero, Address(regT2, Structure::typeInfoFlagsOffset()), TrustedImm32(MasqueradesAsUndefined)), target);
+ move(TrustedImmPtr(m_codeBlock->globalObject()), regT0);
+ addJump(branchPtr(NotEqual, Address(regT2, Structure::globalObjectOffset()), regT0), target);
Jump wasNotImmediate = jump();
// Now handle the immediate cases - undefined & null
@@ -1172,8 +1185,14 @@ void JIT::emit_op_eq_null(Instruction* currentInstruction)
Jump isImmediate = emitJumpIfNotJSCell(regT0);
loadPtr(Address(regT0, JSCell::structureOffset()), regT2);
- test8(NonZero, Address(regT2, Structure::typeInfoFlagsOffset()), TrustedImm32(MasqueradesAsUndefined), regT0);
-
+ Jump isMasqueradesAsUndefined = branchTest8(NonZero, Address(regT2, Structure::typeInfoFlagsOffset()), TrustedImm32(MasqueradesAsUndefined));
+ move(TrustedImm32(0), regT0);
+ Jump wasNotMasqueradesAsUndefined = jump();
+
+ isMasqueradesAsUndefined.link(this);
+ move(TrustedImmPtr(m_codeBlock->globalObject()), regT0);
+ loadPtr(Address(regT2, Structure::globalObjectOffset()), regT2);
+ comparePtr(Equal, regT0, regT2, regT0);
Jump wasNotImmediate = jump();
isImmediate.link(this);
@@ -1182,6 +1201,7 @@ void JIT::emit_op_eq_null(Instruction* currentInstruction)
comparePtr(Equal, regT0, TrustedImm32(ValueNull), regT0);
wasNotImmediate.link(this);
+ wasNotMasqueradesAsUndefined.link(this);
emitTagAsBoolImmediate(regT0);
emitPutVirtualRegister(dst);
@@ -1197,8 +1217,14 @@ void JIT::emit_op_neq_null(Instruction* currentInstruction)
Jump isImmediate = emitJumpIfNotJSCell(regT0);
loadPtr(Address(regT0, JSCell::structureOffset()), regT2);
- test8(Zero, Address(regT2, Structure::typeInfoFlagsOffset()), TrustedImm32(MasqueradesAsUndefined), regT0);
-
+ Jump isMasqueradesAsUndefined = branchTest8(NonZero, Address(regT2, Structure::typeInfoFlagsOffset()), TrustedImm32(MasqueradesAsUndefined));
+ move(TrustedImm32(1), regT0);
+ Jump wasNotMasqueradesAsUndefined = jump();
+
+ isMasqueradesAsUndefined.link(this);
+ move(TrustedImmPtr(m_codeBlock->globalObject()), regT0);
+ loadPtr(Address(regT2, Structure::globalObjectOffset()), regT2);
+ comparePtr(NotEqual, regT0, regT2, regT0);
Jump wasNotImmediate = jump();
isImmediate.link(this);
@@ -1207,6 +1233,7 @@ void JIT::emit_op_neq_null(Instruction* currentInstruction)
comparePtr(NotEqual, regT0, TrustedImm32(ValueNull), regT0);
wasNotImmediate.link(this);
+ wasNotMasqueradesAsUndefined.link(this);
emitTagAsBoolImmediate(regT0);
emitPutVirtualRegister(dst);
diff --git a/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp b/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
index eec9df36f..00c886eb7 100644
--- a/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
+++ b/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
@@ -646,8 +646,16 @@ void JIT::emit_op_is_undefined(Instruction* currentInstruction)
isCell.link(this);
loadPtr(Address(regT0, JSCell::structureOffset()), regT1);
- test8(NonZero, Address(regT1, Structure::typeInfoFlagsOffset()), TrustedImm32(MasqueradesAsUndefined), regT0);
+ Jump isMasqueradesAsUndefined = branchTest8(NonZero, Address(regT1, Structure::typeInfoFlagsOffset()), TrustedImm32(MasqueradesAsUndefined));
+ move(TrustedImm32(0), regT0);
+ Jump notMasqueradesAsUndefined = jump();
+ isMasqueradesAsUndefined.link(this);
+ move(TrustedImmPtr(m_codeBlock->globalObject()), regT0);
+ loadPtr(Address(regT1, Structure::globalObjectOffset()), regT1);
+ compare32(Equal, regT0, regT1, regT0);
+
+ notMasqueradesAsUndefined.link(this);
done.link(this);
emitStoreBool(dst, regT0);
}
@@ -930,18 +938,19 @@ void JIT::emit_op_jeq_null(Instruction* currentInstruction)
// First, handle JSCell cases - check MasqueradesAsUndefined bit on the structure.
loadPtr(Address(regT0, JSCell::structureOffset()), regT2);
- addJump(branchTest8(NonZero, Address(regT2, Structure::typeInfoFlagsOffset()), TrustedImm32(MasqueradesAsUndefined)), target);
-
- Jump wasNotImmediate = jump();
+ Jump isNotMasqueradesAsUndefined = branchTest8(Zero, Address(regT2, Structure::typeInfoFlagsOffset()), TrustedImm32(MasqueradesAsUndefined));
+ move(TrustedImmPtr(m_codeBlock->globalObject()), regT0);
+ addJump(branchPtr(Equal, Address(regT2, Structure::globalObjectOffset()), regT0), target);
+ Jump masqueradesGlobalObjectIsForeign = jump();
// Now handle the immediate cases - undefined & null
isImmediate.link(this);
-
ASSERT((JSValue::UndefinedTag + 1 == JSValue::NullTag) && (JSValue::NullTag & 0x1));
or32(TrustedImm32(1), regT1);
addJump(branch32(Equal, regT1, TrustedImm32(JSValue::NullTag)), target);
- wasNotImmediate.link(this);
+ isNotMasqueradesAsUndefined.link(this);
+ masqueradesGlobalObjectIsForeign.link(this);
}
void JIT::emit_op_jneq_null(Instruction* currentInstruction)
@@ -956,7 +965,8 @@ void JIT::emit_op_jneq_null(Instruction* currentInstruction)
// First, handle JSCell cases - check MasqueradesAsUndefined bit on the structure.
loadPtr(Address(regT0, JSCell::structureOffset()), regT2);
addJump(branchTest8(Zero, Address(regT2, Structure::typeInfoFlagsOffset()), TrustedImm32(MasqueradesAsUndefined)), target);
-
+ move(TrustedImmPtr(m_codeBlock->globalObject()), regT0);
+ addJump(branchPtr(NotEqual, Address(regT2, Structure::globalObjectOffset()), regT0), target);
Jump wasNotImmediate = jump();
// Now handle the immediate cases - undefined & null
@@ -1158,8 +1168,14 @@ void JIT::emit_op_eq_null(Instruction* currentInstruction)
Jump isImmediate = branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag));
loadPtr(Address(regT0, JSCell::structureOffset()), regT1);
- test8(NonZero, Address(regT1, Structure::typeInfoFlagsOffset()), TrustedImm32(MasqueradesAsUndefined), regT1);
-
+ Jump isMasqueradesAsUndefined = branchTest8(NonZero, Address(regT1, Structure::typeInfoFlagsOffset()), TrustedImm32(MasqueradesAsUndefined));
+ move(TrustedImm32(0), regT1);
+ Jump wasNotMasqueradesAsUndefined = jump();
+
+ isMasqueradesAsUndefined.link(this);
+ move(TrustedImmPtr(m_codeBlock->globalObject()), regT0);
+ loadPtr(Address(regT2, Structure::globalObjectOffset()), regT2);
+ compare32(Equal, regT0, regT2, regT1);
Jump wasNotImmediate = jump();
isImmediate.link(this);
@@ -1169,6 +1185,7 @@ void JIT::emit_op_eq_null(Instruction* currentInstruction)
or32(regT2, regT1);
wasNotImmediate.link(this);
+ wasNotMasqueradesAsUndefined.link(this);
emitStoreBool(dst, regT1);
}
@@ -1182,8 +1199,14 @@ void JIT::emit_op_neq_null(Instruction* currentInstruction)
Jump isImmediate = branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag));
loadPtr(Address(regT0, JSCell::structureOffset()), regT1);
- test8(Zero, Address(regT1, Structure::typeInfoFlagsOffset()), TrustedImm32(MasqueradesAsUndefined), regT1);
-
+ Jump isMasqueradesAsUndefined = branchTest8(NonZero, Address(regT1, Structure::typeInfoFlagsOffset()), TrustedImm32(MasqueradesAsUndefined));
+ move(TrustedImm32(1), regT1);
+ Jump wasNotMasqueradesAsUndefined = jump();
+
+ isMasqueradesAsUndefined.link(this);
+ move(TrustedImmPtr(m_codeBlock->globalObject()), regT0);
+ loadPtr(Address(regT2, Structure::globalObjectOffset()), regT2);
+ compare32(NotEqual, regT0, regT2, regT1);
Jump wasNotImmediate = jump();
isImmediate.link(this);
@@ -1193,6 +1216,7 @@ void JIT::emit_op_neq_null(Instruction* currentInstruction)
and32(regT2, regT1);
wasNotImmediate.link(this);
+ wasNotMasqueradesAsUndefined.link(this);
emitStoreBool(dst, regT1);
}
diff --git a/Source/JavaScriptCore/jit/JITStubCall.h b/Source/JavaScriptCore/jit/JITStubCall.h
index a525ff227..352956559 100644
--- a/Source/JavaScriptCore/jit/JITStubCall.h
+++ b/Source/JavaScriptCore/jit/JITStubCall.h
@@ -37,7 +37,9 @@ namespace JSC {
JITStubCall(JIT* jit, JSObject* (JIT_STUB *stub)(STUB_ARGS_DECLARATION))
: m_jit(jit)
, m_stub(stub)
+#if USE(JSVALUE32_64) || !ASSERT_DISABLED
, m_returnType(Cell)
+#endif
, m_stackIndex(JITSTACKFRAME_ARGS_INDEX)
{
}
@@ -45,7 +47,9 @@ namespace JSC {
JITStubCall(JIT* jit, JSPropertyNameIterator* (JIT_STUB *stub)(STUB_ARGS_DECLARATION))
: m_jit(jit)
, m_stub(stub)
+#if USE(JSVALUE32_64) || !ASSERT_DISABLED
, m_returnType(Cell)
+#endif
, m_stackIndex(JITSTACKFRAME_ARGS_INDEX)
{
}
@@ -53,7 +57,9 @@ namespace JSC {
JITStubCall(JIT* jit, void* (JIT_STUB *stub)(STUB_ARGS_DECLARATION))
: m_jit(jit)
, m_stub(stub)
+#if USE(JSVALUE32_64) || !ASSERT_DISABLED
, m_returnType(VoidPtr)
+#endif
, m_stackIndex(JITSTACKFRAME_ARGS_INDEX)
{
}
@@ -61,7 +67,9 @@ namespace JSC {
JITStubCall(JIT* jit, int (JIT_STUB *stub)(STUB_ARGS_DECLARATION))
: m_jit(jit)
, m_stub(stub)
+#if USE(JSVALUE32_64) || !ASSERT_DISABLED
, m_returnType(Int)
+#endif
, m_stackIndex(JITSTACKFRAME_ARGS_INDEX)
{
}
@@ -69,7 +77,9 @@ namespace JSC {
JITStubCall(JIT* jit, bool (JIT_STUB *stub)(STUB_ARGS_DECLARATION))
: m_jit(jit)
, m_stub(stub)
+#if USE(JSVALUE32_64) || !ASSERT_DISABLED
, m_returnType(Int)
+#endif
, m_stackIndex(JITSTACKFRAME_ARGS_INDEX)
{
}
@@ -77,7 +87,9 @@ namespace JSC {
JITStubCall(JIT* jit, void (JIT_STUB *stub)(STUB_ARGS_DECLARATION))
: m_jit(jit)
, m_stub(stub)
+#if USE(JSVALUE32_64) || !ASSERT_DISABLED
, m_returnType(Void)
+#endif
, m_stackIndex(JITSTACKFRAME_ARGS_INDEX)
{
}
@@ -265,7 +277,9 @@ namespace JSC {
JIT* m_jit;
FunctionPtr m_stub;
+#if USE(JSVALUE32_64) || !ASSERT_DISABLED
enum { Void, VoidPtr, Int, Value, Cell } m_returnType;
+#endif
size_t m_stackIndex;
};
}
diff --git a/Source/JavaScriptCore/jit/JITStubs.cpp b/Source/JavaScriptCore/jit/JITStubs.cpp
index cb5adc2fa..cc899587f 100644
--- a/Source/JavaScriptCore/jit/JITStubs.cpp
+++ b/Source/JavaScriptCore/jit/JITStubs.cpp
@@ -2777,7 +2777,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_not)
JSValue src = stackFrame.args[0].jsValue();
- JSValue result = jsBoolean(!src.toBoolean());
+ JSValue result = jsBoolean(!src.toBoolean(stackFrame.callFrame));
CHECK_FOR_EXCEPTION_AT_END();
return JSValue::encode(result);
}
@@ -2788,7 +2788,7 @@ DEFINE_STUB_FUNCTION(int, op_jtrue)
JSValue src1 = stackFrame.args[0].jsValue();
- bool result = src1.toBoolean();
+ bool result = src1.toBoolean(stackFrame.callFrame);
CHECK_FOR_EXCEPTION_AT_END();
return result;
}
@@ -2819,13 +2819,13 @@ DEFINE_STUB_FUNCTION(int, op_eq)
start:
if (src2.isUndefined()) {
return src1.isNull() ||
- (src1.isCell() && src1.asCell()->structure()->typeInfo().masqueradesAsUndefined())
+ (src1.isCell() && src1.asCell()->structure()->masqueradesAsUndefined(stackFrame.callFrame->lexicalGlobalObject()))
|| src1.isUndefined();
}
if (src2.isNull()) {
return src1.isUndefined() ||
- (src1.isCell() && src1.asCell()->structure()->typeInfo().masqueradesAsUndefined())
+ (src1.isCell() && src1.asCell()->structure()->masqueradesAsUndefined(stackFrame.callFrame->lexicalGlobalObject()))
|| src1.isNull();
}
@@ -2862,10 +2862,10 @@ DEFINE_STUB_FUNCTION(int, op_eq)
}
if (src1.isUndefined())
- return src2.isCell() && src2.asCell()->structure()->typeInfo().masqueradesAsUndefined();
+ return src2.isCell() && src2.asCell()->structure()->masqueradesAsUndefined(stackFrame.callFrame->lexicalGlobalObject());
if (src1.isNull())
- return src2.isCell() && src2.asCell()->structure()->typeInfo().masqueradesAsUndefined();
+ return src2.isCell() && src2.asCell()->structure()->masqueradesAsUndefined(stackFrame.callFrame->lexicalGlobalObject());
JSCell* cell1 = src1.asCell();
@@ -3178,7 +3178,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_is_object)
{
STUB_INIT_STACK_FRAME(stackFrame);
- return JSValue::encode(jsBoolean(jsIsObjectType(stackFrame.args[0].jsValue())));
+ return JSValue::encode(jsBoolean(jsIsObjectType(stackFrame.callFrame, stackFrame.args[0].jsValue())));
}
DEFINE_STUB_FUNCTION(EncodedJSValue, op_is_function)
diff --git a/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp b/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
index 58bf1bdeb..eef54ac7b 100644
--- a/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
+++ b/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
@@ -517,7 +517,7 @@ LLINT_SLOW_PATH_DECL(slow_path_new_regexp)
LLINT_SLOW_PATH_DECL(slow_path_not)
{
LLINT_BEGIN();
- LLINT_RETURN(jsBoolean(!LLINT_OP_C(2).jsValue().toBoolean()));
+ LLINT_RETURN(jsBoolean(!LLINT_OP_C(2).jsValue().toBoolean(exec)));
}
LLINT_SLOW_PATH_DECL(slow_path_eq)
@@ -739,7 +739,7 @@ LLINT_SLOW_PATH_DECL(slow_path_typeof)
LLINT_SLOW_PATH_DECL(slow_path_is_object)
{
LLINT_BEGIN();
- LLINT_RETURN(jsBoolean(jsIsObjectType(LLINT_OP_C(2).jsValue())));
+ LLINT_RETURN(jsBoolean(jsIsObjectType(exec, LLINT_OP_C(2).jsValue())));
}
LLINT_SLOW_PATH_DECL(slow_path_is_function)
@@ -1173,13 +1173,13 @@ LLINT_SLOW_PATH_DECL(slow_path_jmp_scopes)
LLINT_SLOW_PATH_DECL(slow_path_jtrue)
{
LLINT_BEGIN();
- LLINT_BRANCH(op_jtrue, LLINT_OP_C(1).jsValue().toBoolean());
+ LLINT_BRANCH(op_jtrue, LLINT_OP_C(1).jsValue().toBoolean(exec));
}
LLINT_SLOW_PATH_DECL(slow_path_jfalse)
{
LLINT_BEGIN();
- LLINT_BRANCH(op_jfalse, !LLINT_OP_C(1).jsValue().toBoolean());
+ LLINT_BRANCH(op_jfalse, !LLINT_OP_C(1).jsValue().toBoolean(exec));
}
LLINT_SLOW_PATH_DECL(slow_path_jless)
diff --git a/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm b/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
index 5f280ce1b..c0f136889 100644
--- a/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
+++ b/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
@@ -444,7 +444,13 @@ _llint_op_eq_null:
loadi PayloadOffset[cfr, t0, 8], t0
bineq t1, CellTag, .opEqNullImmediate
loadp JSCell::m_structure[t0], t1
- tbnz Structure::m_typeInfo + TypeInfo::m_flags[t1], MasqueradesAsUndefined, t1
+ btbnz Structure::m_typeInfo + TypeInfo::m_flags[t1], MasqueradesAsUndefined, .opEqNullMasqueradesAsUndefined
+ move 0, t1
+ jmp .opEqNullNotImmediate
+.opEqNullMasqueradesAsUndefined:
+ loadp CodeBlock[cfr], t0
+ loadp CodeBlock::m_globalObject[t0], t0
+ cpeq Structure::m_globalObject[t1], t0, t1
jmp .opEqNullNotImmediate
.opEqNullImmediate:
cieq t1, NullTag, t2
@@ -485,7 +491,13 @@ _llint_op_neq_null:
loadi PayloadOffset[cfr, t0, 8], t0
bineq t1, CellTag, .opNeqNullImmediate
loadp JSCell::m_structure[t0], t1
- tbz Structure::m_typeInfo + TypeInfo::m_flags[t1], MasqueradesAsUndefined, t1
+ btbnz Structure::m_typeInfo + TypeInfo::m_flags[t1], MasqueradesAsUndefined, .opNeqNullMasqueradesAsUndefined
+ move 1, t1
+ jmp .opNeqNullNotImmediate
+.opNeqNullMasqueradesAsUndefined:
+ loadp CodeBlock[cfr], t0
+ loadp CodeBlock::m_globalObject[t0], t0
+ cpneq Structure::m_globalObject[t1], t0, t1
jmp .opNeqNullNotImmediate
.opNeqNullImmediate:
cineq t1, NullTag, t2
@@ -875,7 +887,14 @@ _llint_op_is_undefined:
dispatch(3)
.opIsUndefinedCell:
loadp JSCell::m_structure[t3], t1
- tbnz Structure::m_typeInfo + TypeInfo::m_flags[t1], MasqueradesAsUndefined, t1
+ btbnz Structure::m_typeInfo + TypeInfo::m_flags[t1], MasqueradesAsUndefined, .opIsUndefinedMasqueradesAsUndefined
+ move 0, t1
+ storei t1, PayloadOffset[cfr, t0, 8]
+ dispatch(3)
+.opIsUndefinedMasqueradesAsUndefined:
+ loadp CodeBlock[cfr], t3
+ loadp CodeBlock::m_globalObject[t3], t3
+ cpeq Structure::m_globalObject[t1], t3, t1
storei t1, PayloadOffset[cfr, t0, 8]
dispatch(3)
@@ -1406,7 +1425,7 @@ macro equalNull(cellHandler, immediateHandler)
loadi PayloadOffset[cfr, t0, 8], t0
bineq t1, CellTag, .immediate
loadp JSCell::m_structure[t0], t2
- cellHandler(Structure::m_typeInfo + TypeInfo::m_flags[t2], .target)
+ cellHandler(t2, Structure::m_typeInfo + TypeInfo::m_flags[t2], .target)
dispatch(3)
.target:
@@ -1421,14 +1440,25 @@ end
_llint_op_jeq_null:
traceExecution()
equalNull(
- macro (value, target) btbnz value, MasqueradesAsUndefined, target end,
+ macro (structure, value, target)
+ btbz value, MasqueradesAsUndefined, .opJeqNullNotMasqueradesAsUndefined
+ loadp CodeBlock[cfr], t0
+ loadp CodeBlock::m_globalObject[t0], t0
+ bpeq Structure::m_globalObject[structure], t0, target
+.opJeqNullNotMasqueradesAsUndefined:
+ end,
macro (value, target) bieq value, NullTag, target end)
_llint_op_jneq_null:
traceExecution()
equalNull(
- macro (value, target) btbz value, MasqueradesAsUndefined, target end,
+ macro (structure, value, target)
+ btbz value, MasqueradesAsUndefined, target
+ loadp CodeBlock[cfr], t0
+ loadp CodeBlock::m_globalObject[t0], t0
+ bpneq Structure::m_globalObject[structure], t0, target
+ end,
macro (value, target) bineq value, NullTag, target end)
diff --git a/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm b/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
index f1a7e2998..73e8613de 100644
--- a/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
+++ b/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
@@ -324,7 +324,13 @@ macro equalNullComparison()
loadp [cfr, t0, 8], t0
btpnz t0, tagMask, .immediate
loadp JSCell::m_structure[t0], t2
- tbnz Structure::m_typeInfo + TypeInfo::m_flags[t2], MasqueradesAsUndefined, t0
+ btbnz Structure::m_typeInfo + TypeInfo::m_flags[t2], MasqueradesAsUndefined, .masqueradesAsUndefined
+ move 0, t0
+ jmp .done
+.masqueradesAsUndefined:
+ loadp CodeBlock[cfr], t0
+ loadp CodeBlock::m_globalObject[t0], t0
+ cpeq Structure::m_globalObject[t2], t0, t0
jmp .done
.immediate:
andp ~TagBitUndefined, t0
@@ -733,10 +739,17 @@ _llint_op_is_undefined:
dispatch(3)
.opIsUndefinedCell:
loadp JSCell::m_structure[t0], t0
- tbnz Structure::m_typeInfo + TypeInfo::m_flags[t0], MasqueradesAsUndefined, t1
- orp ValueFalse, t1
+ btbnz Structure::m_typeInfo + TypeInfo::m_flags[t0], MasqueradesAsUndefined, .masqueradesAsUndefined
+ move ValueFalse, t1
storep t1, [cfr, t2, 8]
dispatch(3)
+.masqueradesAsUndefined:
+ loadp CodeBlock[cfr], t1
+ loadp CodeBlock::m_globalObject[t1], t1
+ cpeq Structure::m_globalObject[t0], t1, t3
+ orp ValueFalse, t3
+ storep t3, [cfr, t2, 8]
+ dispatch(3)
_llint_op_is_boolean:
@@ -1250,7 +1263,7 @@ macro equalNull(cellHandler, immediateHandler)
loadp [cfr, t0, 8], t0
btpnz t0, tagMask, .immediate
loadp JSCell::m_structure[t0], t2
- cellHandler(Structure::m_typeInfo + TypeInfo::m_flags[t2], .target)
+ cellHandler(t2, Structure::m_typeInfo + TypeInfo::m_flags[t2], .target)
dispatch(3)
.target:
@@ -1265,14 +1278,25 @@ end
_llint_op_jeq_null:
traceExecution()
equalNull(
- macro (value, target) btbnz value, MasqueradesAsUndefined, target end,
+ macro (structure, value, target)
+ btbz value, MasqueradesAsUndefined, .notMasqueradesAsUndefined
+ loadp CodeBlock[cfr], t0
+ loadp CodeBlock::m_globalObject[t0], t0
+ bpeq Structure::m_globalObject[structure], t0, target
+.notMasqueradesAsUndefined:
+ end,
macro (value, target) bpeq value, ValueNull, target end)
_llint_op_jneq_null:
traceExecution()
equalNull(
- macro (value, target) btbz value, MasqueradesAsUndefined, target end,
+ macro (structure, value, target)
+ btbz value, MasqueradesAsUndefined, target
+ loadp CodeBlock[cfr], t0
+ loadp CodeBlock::m_globalObject[t0], t0
+ bpneq Structure::m_globalObject[structure], t0, target
+ end,
macro (value, target) bpneq value, ValueNull, target end)
diff --git a/Source/JavaScriptCore/runtime/ArrayPrototype.cpp b/Source/JavaScriptCore/runtime/ArrayPrototype.cpp
index b0adb7f0f..a97cf82de 100644
--- a/Source/JavaScriptCore/runtime/ArrayPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/ArrayPrototype.cpp
@@ -797,7 +797,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncFilter(ExecState* exec)
cachedCall.setArgument(2, thisObj);
JSValue result = cachedCall.call();
- if (result.toBoolean())
+ if (result.toBoolean(exec))
resultArray->putDirectIndex(exec, filterIndex++, v);
}
if (k == length)
@@ -818,7 +818,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncFilter(ExecState* exec)
eachArguments.append(thisObj);
JSValue result = call(exec, function, callType, callData, applyThis, eachArguments);
- if (result.toBoolean())
+ if (result.toBoolean(exec))
resultArray->putDirectIndex(exec, filterIndex++, v);
}
return JSValue::encode(resultArray);
@@ -917,7 +917,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncEvery(ExecState* exec)
cachedCall.setArgument(1, jsNumber(k));
cachedCall.setArgument(2, thisObj);
JSValue result = cachedCall.call();
- if (!result.toBoolean())
+ if (!result.toBoolean(exec))
return JSValue::encode(jsBoolean(false));
}
}
@@ -934,7 +934,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncEvery(ExecState* exec)
if (exec->hadException())
return JSValue::encode(jsUndefined());
- bool predicateResult = call(exec, function, callType, callData, applyThis, eachArguments).toBoolean();
+ bool predicateResult = call(exec, function, callType, callData, applyThis, eachArguments).toBoolean(exec);
if (!predicateResult) {
result = jsBoolean(false);
break;
@@ -1025,7 +1025,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSome(ExecState* exec)
cachedCall.setArgument(1, jsNumber(k));
cachedCall.setArgument(2, thisObj);
JSValue result = cachedCall.call();
- if (result.toBoolean())
+ if (result.toBoolean(exec))
return JSValue::encode(jsBoolean(true));
}
}
@@ -1042,7 +1042,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSome(ExecState* exec)
if (exec->hadException())
return JSValue::encode(jsUndefined());
- bool predicateResult = call(exec, function, callType, callData, applyThis, eachArguments).toBoolean();
+ bool predicateResult = call(exec, function, callType, callData, applyThis, eachArguments).toBoolean(exec);
if (predicateResult) {
result = jsBoolean(true);
break;
diff --git a/Source/JavaScriptCore/runtime/BooleanConstructor.cpp b/Source/JavaScriptCore/runtime/BooleanConstructor.cpp
index 090be0aaa..9b666292c 100644
--- a/Source/JavaScriptCore/runtime/BooleanConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/BooleanConstructor.cpp
@@ -49,7 +49,7 @@ void BooleanConstructor::finishCreation(ExecState* exec, BooleanPrototype* boole
JSObject* constructBoolean(ExecState* exec, const ArgList& args)
{
BooleanObject* obj = BooleanObject::create(exec->globalData(), asInternalFunction(exec->callee())->globalObject()->booleanObjectStructure());
- obj->setInternalValue(exec->globalData(), jsBoolean(args.at(0).toBoolean()));
+ obj->setInternalValue(exec->globalData(), jsBoolean(args.at(0).toBoolean(exec)));
return obj;
}
@@ -68,7 +68,7 @@ ConstructType BooleanConstructor::getConstructData(JSCell*, ConstructData& const
// ECMA 15.6.1
static EncodedJSValue JSC_HOST_CALL callBooleanConstructor(ExecState* exec)
{
- return JSValue::encode(jsBoolean(exec->argument(0).toBoolean()));
+ return JSValue::encode(jsBoolean(exec->argument(0).toBoolean(exec)));
}
CallType BooleanConstructor::getCallData(JSCell*, CallData& callData)
diff --git a/Source/JavaScriptCore/runtime/BooleanObject.h b/Source/JavaScriptCore/runtime/BooleanObject.h
index 2704ff3cd..bd0f66944 100644
--- a/Source/JavaScriptCore/runtime/BooleanObject.h
+++ b/Source/JavaScriptCore/runtime/BooleanObject.h
@@ -27,8 +27,8 @@ namespace JSC {
class BooleanObject : public JSWrapperObject {
protected:
- BooleanObject(JSGlobalData&, Structure*);
- void finishCreation(JSGlobalData&);
+ JS_EXPORT_PRIVATE BooleanObject(JSGlobalData&, Structure*);
+ JS_EXPORT_PRIVATE void finishCreation(JSGlobalData&);
public:
typedef JSWrapperObject Base;
@@ -40,7 +40,7 @@ namespace JSC {
return boolean;
}
- static const ClassInfo s_info;
+ static JS_EXPORTDATA const ClassInfo s_info;
static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
{
diff --git a/Source/JavaScriptCore/runtime/JSCell.h b/Source/JavaScriptCore/runtime/JSCell.h
index 90e531cec..39f98356f 100644
--- a/Source/JavaScriptCore/runtime/JSCell.h
+++ b/Source/JavaScriptCore/runtime/JSCell.h
@@ -98,7 +98,7 @@ namespace JSC {
// Basic conversions.
JS_EXPORT_PRIVATE JSValue toPrimitive(ExecState*, PreferredPrimitiveType) const;
bool getPrimitiveNumber(ExecState*, double& number, JSValue&) const;
- bool toBoolean() const;
+ bool toBoolean(ExecState*) const;
JS_EXPORT_PRIVATE double toNumber(ExecState*) const;
JS_EXPORT_PRIVATE JSObject* toObject(ExecState*, JSGlobalObject*) const;
diff --git a/Source/JavaScriptCore/runtime/JSGlobalObject.cpp b/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
index 0edc0a8a9..ff7b1486f 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
@@ -115,6 +115,7 @@ template <typename T> static inline void visitIfNeeded(SlotVisitor& visitor, Wri
JSGlobalObject::JSGlobalObject(JSGlobalData& globalData, Structure* structure, const GlobalObjectMethodTable* globalObjectMethodTable)
: JSSegmentedVariableObject(globalData, structure, &m_symbolTable)
, m_globalScopeChain()
+ , m_masqueradesAsUndefinedWatchpoint(adoptRef(new WatchpointSet(InitializedWatching)))
, m_weakRandom(Options::forceWeakRandomSeed() ? Options::forcedWeakRandomSeed() : static_cast<unsigned>(randomNumber() * (std::numeric_limits<unsigned>::max() + 1.0)))
, m_evalEnabled(true)
, m_globalObjectMethodTable(globalObjectMethodTable ? globalObjectMethodTable : &s_globalObjectMethodTable)
diff --git a/Source/JavaScriptCore/runtime/JSGlobalObject.h b/Source/JavaScriptCore/runtime/JSGlobalObject.h
index af03f32e6..248004bd5 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalObject.h
+++ b/Source/JavaScriptCore/runtime/JSGlobalObject.h
@@ -30,6 +30,7 @@
#include "NumberPrototype.h"
#include "StringPrototype.h"
#include "StructureChain.h"
+#include "Watchpoint.h"
#include <wtf/HashSet.h>
#include <wtf/OwnPtr.h>
#include <wtf/RandomNumber.h>
@@ -142,6 +143,8 @@ namespace JSC {
Debugger* m_debugger;
+ RefPtr<WatchpointSet> m_masqueradesAsUndefinedWatchpoint;
+
OwnPtr<JSGlobalObjectRareData> m_rareData;
WeakRandom m_weakRandom;
@@ -270,6 +273,8 @@ namespace JSC {
Structure* regExpStructure() const { return m_regExpStructure.get(); }
Structure* stringObjectStructure() const { return m_stringObjectStructure.get(); }
+ WatchpointSet* masqueradesAsUndefinedWatchpoint() { return m_masqueradesAsUndefinedWatchpoint.get(); }
+
void setProfileGroup(unsigned value) { createRareDataIfNeeded(); m_rareData->profileGroup = value; }
unsigned profileGroup() const
{
diff --git a/Source/JavaScriptCore/runtime/JSString.h b/Source/JavaScriptCore/runtime/JSString.h
index d6fc4c2a1..e91553aeb 100644
--- a/Source/JavaScriptCore/runtime/JSString.h
+++ b/Source/JavaScriptCore/runtime/JSString.h
@@ -500,23 +500,23 @@ namespace JSC {
inline bool isJSString(JSValue v) { return v.isCell() && v.asCell()->classInfo() == &JSString::s_info; }
- inline bool JSCell::toBoolean() const
+ inline bool JSCell::toBoolean(ExecState* exec) const
{
if (isString())
return static_cast<const JSString*>(this)->toBoolean();
- return !structure()->typeInfo().masqueradesAsUndefined();
+ return !structure()->masqueradesAsUndefined(exec->lexicalGlobalObject());
}
// --- JSValue inlines ----------------------------
- inline bool JSValue::toBoolean() const
+ inline bool JSValue::toBoolean(ExecState* exec) const
{
if (isInt32())
return asInt32();
if (isDouble())
return asDouble() > 0.0 || asDouble() < 0.0; // false for NaN
if (isCell())
- return asCell()->toBoolean();
+ return asCell()->toBoolean(exec);
return isTrue(); // false, null, and undefined all convert to false.
}
diff --git a/Source/JavaScriptCore/runtime/JSValue.h b/Source/JavaScriptCore/runtime/JSValue.h
index 19a8c4759..7aa5453e4 100644
--- a/Source/JavaScriptCore/runtime/JSValue.h
+++ b/Source/JavaScriptCore/runtime/JSValue.h
@@ -209,7 +209,7 @@ namespace JSC {
JSValue toPrimitive(ExecState*, PreferredPrimitiveType = NoPreference) const;
bool getPrimitiveNumber(ExecState*, double& number, JSValue&);
- bool toBoolean() const;
+ bool toBoolean(ExecState*) const;
// toNumber conversion is expected to be side effect free if an exception has
// been set in the ExecState already.
diff --git a/Source/JavaScriptCore/runtime/NumberObject.h b/Source/JavaScriptCore/runtime/NumberObject.h
index 07334722b..ed84207d9 100644
--- a/Source/JavaScriptCore/runtime/NumberObject.h
+++ b/Source/JavaScriptCore/runtime/NumberObject.h
@@ -40,7 +40,7 @@ namespace JSC {
return number;
}
- static const ClassInfo s_info;
+ static JS_EXPORTDATA const ClassInfo s_info;
static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
{
@@ -48,7 +48,7 @@ namespace JSC {
}
};
- NumberObject* constructNumber(ExecState*, JSGlobalObject*, JSValue);
+ JS_EXPORT_PRIVATE NumberObject* constructNumber(ExecState*, JSGlobalObject*, JSValue);
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/ObjectConstructor.cpp b/Source/JavaScriptCore/runtime/ObjectConstructor.cpp
index 7b6a5f669..5a6fcddf0 100644
--- a/Source/JavaScriptCore/runtime/ObjectConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/ObjectConstructor.cpp
@@ -214,14 +214,14 @@ static bool toPropertyDescriptor(ExecState* exec, JSValue in, PropertyDescriptor
PropertySlot enumerableSlot(description);
if (description->getPropertySlot(exec, exec->propertyNames().enumerable, enumerableSlot)) {
- desc.setEnumerable(enumerableSlot.getValue(exec, exec->propertyNames().enumerable).toBoolean());
+ desc.setEnumerable(enumerableSlot.getValue(exec, exec->propertyNames().enumerable).toBoolean(exec));
if (exec->hadException())
return false;
}
PropertySlot configurableSlot(description);
if (description->getPropertySlot(exec, exec->propertyNames().configurable, configurableSlot)) {
- desc.setConfigurable(configurableSlot.getValue(exec, exec->propertyNames().configurable).toBoolean());
+ desc.setConfigurable(configurableSlot.getValue(exec, exec->propertyNames().configurable).toBoolean(exec));
if (exec->hadException())
return false;
}
@@ -236,7 +236,7 @@ static bool toPropertyDescriptor(ExecState* exec, JSValue in, PropertyDescriptor
PropertySlot writableSlot(description);
if (description->getPropertySlot(exec, exec->propertyNames().writable, writableSlot)) {
- desc.setWritable(writableSlot.getValue(exec, exec->propertyNames().writable).toBoolean());
+ desc.setWritable(writableSlot.getValue(exec, exec->propertyNames().writable).toBoolean(exec));
if (exec->hadException())
return false;
}
diff --git a/Source/JavaScriptCore/runtime/Operations.cpp b/Source/JavaScriptCore/runtime/Operations.cpp
index 4cb9de505..d96bae575 100644
--- a/Source/JavaScriptCore/runtime/Operations.cpp
+++ b/Source/JavaScriptCore/runtime/Operations.cpp
@@ -70,7 +70,7 @@ JSValue jsTypeStringForValue(CallFrame* callFrame, JSValue v)
if (v.isObject()) {
// Return "undefined" for objects that should be treated
// as null when doing comparisons.
- if (asObject(v)->structure()->typeInfo().masqueradesAsUndefined())
+ if (asObject(v)->structure()->masqueradesAsUndefined(callFrame->lexicalGlobalObject()))
return globalData.smallStrings.undefinedString(&globalData);
CallData callData;
JSObject* object = asObject(v);
@@ -80,7 +80,7 @@ JSValue jsTypeStringForValue(CallFrame* callFrame, JSValue v)
return globalData.smallStrings.objectString(&globalData);
}
-bool jsIsObjectType(JSValue v)
+bool jsIsObjectType(CallFrame* callFrame, JSValue v)
{
if (!v.isCell())
return v.isNull();
@@ -89,7 +89,7 @@ bool jsIsObjectType(JSValue v)
if (type == NumberType || type == StringType)
return false;
if (type >= ObjectType) {
- if (asObject(v)->structure()->typeInfo().masqueradesAsUndefined())
+ if (asObject(v)->structure()->masqueradesAsUndefined(callFrame->lexicalGlobalObject()))
return false;
CallData callData;
JSObject* object = asObject(v);
diff --git a/Source/JavaScriptCore/runtime/Operations.h b/Source/JavaScriptCore/runtime/Operations.h
index 497b19d82..88fffdac4 100644
--- a/Source/JavaScriptCore/runtime/Operations.h
+++ b/Source/JavaScriptCore/runtime/Operations.h
@@ -31,7 +31,7 @@ namespace JSC {
NEVER_INLINE JSValue jsAddSlowCase(CallFrame*, JSValue, JSValue);
JSValue jsTypeStringForValue(CallFrame*, JSValue);
- bool jsIsObjectType(JSValue);
+ bool jsIsObjectType(CallFrame*, JSValue);
bool jsIsFunctionType(JSValue);
ALWAYS_INLINE JSValue jsString(ExecState* exec, JSString* s1, JSString* s2)
@@ -134,13 +134,13 @@ namespace JSC {
return true;
if (!v2.isCell())
return false;
- return v2.asCell()->structure()->typeInfo().masqueradesAsUndefined();
+ return v2.asCell()->structure()->masqueradesAsUndefined(exec->lexicalGlobalObject());
}
if (v2.isUndefinedOrNull()) {
if (!v1.isCell())
return false;
- return v1.asCell()->structure()->typeInfo().masqueradesAsUndefined();
+ return v1.asCell()->structure()->masqueradesAsUndefined(exec->lexicalGlobalObject());
}
if (v1.isObject()) {
diff --git a/Source/JavaScriptCore/runtime/RegExpConstructor.cpp b/Source/JavaScriptCore/runtime/RegExpConstructor.cpp
index 0f2091c27..0b463474f 100644
--- a/Source/JavaScriptCore/runtime/RegExpConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/RegExpConstructor.cpp
@@ -249,9 +249,9 @@ void setRegExpConstructorInput(ExecState* exec, JSObject* baseObject, JSValue va
asRegExpConstructor(baseObject)->setInput(exec, value.toString(exec));
}
-void setRegExpConstructorMultiline(ExecState*, JSObject* baseObject, JSValue value)
+void setRegExpConstructorMultiline(ExecState* exec, JSObject* baseObject, JSValue value)
{
- asRegExpConstructor(baseObject)->setMultiline(value.toBoolean());
+ asRegExpConstructor(baseObject)->setMultiline(value.toBoolean(exec));
}
// ECMA 15.10.4
diff --git a/Source/JavaScriptCore/runtime/RegExpPrototype.cpp b/Source/JavaScriptCore/runtime/RegExpPrototype.cpp
index 6080a1c99..24c7c8027 100644
--- a/Source/JavaScriptCore/runtime/RegExpPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/RegExpPrototype.cpp
@@ -147,11 +147,11 @@ EncodedJSValue JSC_HOST_CALL regExpProtoFuncToString(ExecState* exec)
char postfix[5] = { '/', 0, 0, 0, 0 };
int index = 1;
- if (thisObject->get(exec, exec->propertyNames().global).toBoolean())
+ if (thisObject->get(exec, exec->propertyNames().global).toBoolean(exec))
postfix[index++] = 'g';
- if (thisObject->get(exec, exec->propertyNames().ignoreCase).toBoolean())
+ if (thisObject->get(exec, exec->propertyNames().ignoreCase).toBoolean(exec))
postfix[index++] = 'i';
- if (thisObject->get(exec, exec->propertyNames().multiline).toBoolean())
+ if (thisObject->get(exec, exec->propertyNames().multiline).toBoolean(exec))
postfix[index] = 'm';
UString source = thisObject->get(exec, exec->propertyNames().source).toString(exec)->value(exec);
// If source is empty, use "/(?:)/" to avoid colliding with comment syntax
diff --git a/Source/JavaScriptCore/runtime/StringObject.cpp b/Source/JavaScriptCore/runtime/StringObject.cpp
index 1dac06b46..3c037bcd1 100644
--- a/Source/JavaScriptCore/runtime/StringObject.cpp
+++ b/Source/JavaScriptCore/runtime/StringObject.cpp
@@ -22,6 +22,7 @@
#include "StringObject.h"
#include "Error.h"
+#include "JSGlobalObject.h"
#include "PropertyNameArray.h"
namespace JSC {
@@ -143,4 +144,11 @@ void StringObject::getOwnPropertyNames(JSObject* object, ExecState* exec, Proper
return JSObject::getOwnPropertyNames(thisObject, exec, propertyNames, mode);
}
+StringObject* constructString(ExecState* exec, JSGlobalObject* globalObject, JSValue string)
+{
+ StringObject* object = StringObject::create(exec, globalObject->stringObjectStructure());
+ object->setInternalValue(exec->globalData(), string);
+ return object;
+}
+
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/StringObject.h b/Source/JavaScriptCore/runtime/StringObject.h
index 7089e8983..f0c445e91 100644
--- a/Source/JavaScriptCore/runtime/StringObject.h
+++ b/Source/JavaScriptCore/runtime/StringObject.h
@@ -78,6 +78,8 @@ namespace JSC {
return static_cast<StringObject*>(asObject(value));
}
+ JS_EXPORT_PRIVATE StringObject* constructString(ExecState*, JSGlobalObject*, JSValue);
+
} // namespace JSC
#endif // StringObject_h
diff --git a/Source/JavaScriptCore/runtime/Structure.h b/Source/JavaScriptCore/runtime/Structure.h
index 0b9c92210..2bb0107b7 100644
--- a/Source/JavaScriptCore/runtime/Structure.h
+++ b/Source/JavaScriptCore/runtime/Structure.h
@@ -256,6 +256,8 @@ namespace JSC {
&& offset <= lastValidOffset();
}
+ bool masqueradesAsUndefined(JSGlobalObject* lexicalGlobalObject);
+
PropertyOffset get(JSGlobalData&, PropertyName);
PropertyOffset get(JSGlobalData&, const UString& name);
JS_EXPORT_PRIVATE PropertyOffset get(JSGlobalData&, PropertyName, unsigned& attributes, JSCell*& specificValue);
@@ -313,6 +315,11 @@ namespace JSC {
return OBJECT_OFFSETOF(Structure, m_prototype);
}
+ static ptrdiff_t globalObjectOffset()
+ {
+ return OBJECT_OFFSETOF(Structure, m_globalObject);
+ }
+
static ptrdiff_t typeInfoFlagsOffset()
{
return OBJECT_OFFSETOF(Structure, m_typeInfo) + TypeInfo::flagsOffset();
@@ -505,6 +512,11 @@ namespace JSC {
return entry ? entry->offset : invalidOffset;
}
+ inline bool Structure::masqueradesAsUndefined(JSGlobalObject* lexicalGlobalObject)
+ {
+ return typeInfo().masqueradesAsUndefined() && globalObject() == lexicalGlobalObject;
+ }
+
inline JSValue JSValue::structureOrUndefined() const
{
if (isCell())