Commit e699f4cc authored by Alberto Garcia's avatar Alberto Garcia
Browse files

New upstream version 2.16.1

parent f83a282d
......@@ -14,7 +14,7 @@
<div class="titlepage">
<div>
<div><table class="navigation" id="top" width="100%" cellpadding="2" cellspacing="0"><tr><th valign="middle"><p class="title">WebKit2GTK+ Reference Manual</p></th></tr></table></div>
<div><p class="releaseinfo">for WebKit2GTK+ 2.16.0</p></div>
<div><p class="releaseinfo">for WebKit2GTK+ 2.16.1</p></div>
</div>
<hr>
</div>
......
/home/cgarcia/src/git/gnome/WebKit-2.16/WebKitBuild/Release/Documentation/webkit2gtk-4.0/xml/WebKitWebView.xml:3294: parser error : Opening and ending tag mismatch: para line 3283 and itemizedlist
</itemizedlist>
^
/home/cgarcia/src/git/gnome/WebKit-2.16/WebKitBuild/Release/Documentation/webkit2gtk-4.0/xml/WebKitWebView.xml:3330: parser error : Opening and ending tag mismatch: listitem line 3283 and refsect2
</refsect2><refsect2 id="WebKitWebView-context-menu-dismissed" role="signal"><ti
^
/home/cgarcia/src/git/gnome/WebKit-2.16/WebKitBuild/Release/Documentation/webkit2gtk-4.0/xml/WebKitWebView.xml:4200: parser error : Opening and ending tag mismatch: itemizedlist line 3282 and refsect1
</refsect1>
^
/home/cgarcia/src/git/gnome/WebKit-2.16/WebKitBuild/Release/Documentation/webkit2gtk-4.0/xml/WebKitWebView.xml:4202: parser error : Opening and ending tag mismatch: refsect2 line 3245 and refentry
</refentry>
^
/home/cgarcia/src/git/gnome/WebKit-2.16/WebKitBuild/Release/Documentation/webkit2gtk-4.0/xml/WebKitWebView.xml:4203: parser error : Premature end of data in tag refsect1 line 3175
^
/home/cgarcia/src/git/gnome/WebKit-2.16/WebKitBuild/Release/Documentation/webkit2gtk-4.0/xml/WebKitWebView.xml:4203: parser error : Premature end of data in tag refentry line 6
^
/home/cgarcia/src/git/gnome/WebKit-2.16/WebKitBuild/Release/Documentation/webkit2gtk-4.0/webkit2gtk-docs.sgml:15: element include: XInclude error : could not load /home/cgarcia/src/git/gnome/WebKit-2.16/WebKitBuild/Release/Documentation/webkit2gtk-4.0/xml/WebKitWebView.xml, and no fallback was found
......@@ -177,7 +177,7 @@ against at application run time.</p>
<hr>
<div class="refsect2">
<a name="WEBKIT-MICRO-VERSION:CAPS"></a><h3>WEBKIT_MICRO_VERSION</h3>
<pre class="programlisting">#define WEBKIT_MICRO_VERSION (0)
<pre class="programlisting">#define WEBKIT_MICRO_VERSION (1)
</pre>
<p>Like <a class="link" href="webkit2gtk-4.0-WebKitVersion.html#webkit-get-micro-version" title="webkit_get_micro_version ()"><code class="function">webkit_get_micro_version()</code></a>, but from the headers used at
application compile time, rather than from the library linked
......
......@@ -14,7 +14,7 @@
<div class="titlepage">
<div>
<div><table class="navigation" id="top" width="100%" cellpadding="2" cellspacing="0"><tr><th valign="middle"><p class="title">WebKitDOMGTK+ Reference Manual</p></th></tr></table></div>
<div><p class="releaseinfo">for WebKitDOMGTK+ 2.16.0</p></div>
<div><p class="releaseinfo">for WebKitDOMGTK+ 2.16.1</p></div>
</div>
<hr>
</div>
......
This diff is collapsed.
==================
WebKitGTK+ 2.16.1
==================
- Fix no-third-party cookies policy in case of redirections.
- Keep URL fragments after server redirections.
- Honor GTK+ font settings.
- Ensure depth and stencil renderbuffers are created on GLESv2.
- Prevent new navigations from onbeforeunload handler and document unload.
- Disallow beforeunload alerts from web pages users have never interacted with.
- Fix several crashes and rendering issues.
==================
WebKitGTK+ 2.16.0
==================
......
......@@ -1840,6 +1840,7 @@ CodeBlock::CodeBlock(VM* vm, Structure* structure, CopyParsedBlockTag, CodeBlock
, m_isStrictMode(other.m_isStrictMode)
, m_codeType(other.m_codeType)
, m_unlinkedCode(*other.m_vm, this, other.m_unlinkedCode.get())
, m_numberOfArgumentsToSkip(other.m_numberOfArgumentsToSkip)
, m_hasDebuggerStatement(false)
, m_steppingMode(SteppingModeDisabled)
, m_numBreakpoints(0)
......@@ -2327,7 +2328,8 @@ void CodeBlock::finishCreation(VM& vm, ScriptExecutable* ownerExecutable, Unlink
case op_create_rest: {
int numberOfArgumentsToSkip = instructions[i + 3].u.operand;
ASSERT_UNUSED(numberOfArgumentsToSkip, numberOfArgumentsToSkip >= 0);
ASSERT_WITH_MESSAGE(numberOfArgumentsToSkip == numParameters() - 1, "We assume that this is true when rematerializing the rest parameter during OSR exit in the FTL JIT.");
// This is used when rematerializing the rest parameter during OSR exit in the FTL JIT.");
m_numberOfArgumentsToSkip = numberOfArgumentsToSkip;
break;
}
......
......@@ -143,6 +143,8 @@ public:
int numParameters() const { return m_numParameters; }
void setNumParameters(int newValue);
int numberOfArgumentsToSkip() const { return m_numberOfArgumentsToSkip; }
int numCalleeLocals() const { return m_numCalleeLocals; }
int* addressOfNumParameters() { return &m_numParameters; }
......@@ -968,6 +970,7 @@ private:
WriteBarrier<UnlinkedCodeBlock> m_unlinkedCode;
int m_numParameters;
int m_numberOfArgumentsToSkip { 0 };
union {
unsigned m_debuggerRequests;
struct {
......
......@@ -88,7 +88,6 @@ UnlinkedFunctionExecutable::UnlinkedFunctionExecutable(VM* vm, Structure* struct
, m_typeProfilingStartOffset(node->functionKeywordStart())
, m_typeProfilingEndOffset(node->startStartOffset() + node->source().length() - 1)
, m_parameterCount(node->parameterCount())
, m_functionLength(node->functionLength())
, m_features(0)
, m_sourceParseMode(node->parseMode())
, m_isInStrictContext(node->isInStrictContext())
......
......@@ -77,7 +77,6 @@ public:
void setEcmaName(const Identifier& name) { m_ecmaName = name; }
const Identifier& inferredName() const { return m_inferredName; }
unsigned parameterCount() const { return m_parameterCount; }; // Excluding 'this'!
unsigned functionLength() const { return m_functionLength; }
SourceParseMode parseMode() const { return static_cast<SourceParseMode>(m_sourceParseMode); };
const SourceCode& classSource() const { return m_classSource; };
......@@ -159,7 +158,6 @@ private:
unsigned m_typeProfilingStartOffset;
unsigned m_typeProfilingEndOffset;
unsigned m_parameterCount;
unsigned m_functionLength;
CodeFeatures m_features;
SourceParseMode m_sourceParseMode;
unsigned m_isInStrictContext : 1;
......
......@@ -254,15 +254,8 @@ BytecodeGenerator::BytecodeGenerator(VM& vm, FunctionNode* functionNode, Unlinke
// If IsSimpleParameterList is false, we will create a strict-mode like arguments object.
// IsSimpleParameterList is false if the argument list contains any default parameter values,
// a rest parameter, or any destructuring patterns.
bool isSimpleParameterList = true;
// If we do have default parameters, destructuring parameters, or a rest parameter, our parameters will be allocated in a different scope.
for (size_t i = 0; i < parameters.size(); i++) {
std::pair<DestructuringPatternNode*, ExpressionNode*> parameter = parameters.at(i);
bool hasDefaultParameterValue = !!parameter.second;
auto pattern = parameter.first;
bool isSimpleParameter = !hasDefaultParameterValue && pattern->isBindingNode();
isSimpleParameterList &= isSimpleParameter;
}
bool isSimpleParameterList = parameters.isSimpleParameterList();
SourceParseMode parseMode = codeBlock->parseMode();
......@@ -983,10 +976,12 @@ void BytecodeGenerator::initializeDefaultParameterValuesAndSetupFunctionScopeSta
std::pair<DestructuringPatternNode*, ExpressionNode*> parameter = parameters.at(i);
if (parameter.first->isRestParameter())
continue;
RefPtr<RegisterID> parameterValue = &registerFor(virtualRegisterForArgument(1 + i));
emitMove(temp.get(), parameterValue.get());
if ((i + 1) < m_parameters.size())
emitMove(temp.get(), &m_parameters[i + 1]);
else
emitGetArgument(temp.get(), i);
if (parameter.second) {
RefPtr<RegisterID> condition = emitIsUndefined(newTemporary(), parameterValue.get());
RefPtr<RegisterID> condition = emitIsUndefined(newTemporary(), temp.get());
Ref<Label> skipDefaultParameterBecauseNotUndefined = newLabel();
emitJumpIfFalse(condition.get(), skipDefaultParameterBecauseNotUndefined.get());
emitNode(temp.get(), parameter.second);
......@@ -1031,6 +1026,15 @@ void BytecodeGenerator::initializeDefaultParameterValuesAndSetupFunctionScopeSta
}
}
bool BytecodeGenerator::needsDerivedConstructorInArrowFunctionLexicalEnvironment()
{
if ((isConstructor() && constructorKind() == ConstructorKind::Extends) || m_codeBlock->isClassContext()) {
if (isSuperUsedInInnerArrowFunction())
return true;
}
return false;
}
void BytecodeGenerator::initializeArrowFunctionContextScopeIfNeeded(SymbolTable* functionSymbolTable, bool canReuseLexicalEnvironment)
{
ASSERT(!m_arrowFunctionContextLexicalEnvironmentRegister);
......@@ -1053,7 +1057,7 @@ void BytecodeGenerator::initializeArrowFunctionContextScopeIfNeeded(SymbolTable*
functionSymbolTable->set(NoLockingNecessary, propertyNames().builtinNames().newTargetLocalPrivateName().impl(), SymbolTableEntry(VarOffset(offset)));
}
if (isConstructor() && constructorKind() == ConstructorKind::Extends && isSuperUsedInInnerArrowFunction()) {
if (needsDerivedConstructorInArrowFunctionLexicalEnvironment()) {
offset = functionSymbolTable->takeNextScopeOffset(NoLockingNecessary);
functionSymbolTable->set(NoLockingNecessary, propertyNames().builtinNames().derivedConstructorPrivateName().impl(), SymbolTableEntry(VarOffset(offset)));
}
......@@ -1075,7 +1079,7 @@ void BytecodeGenerator::initializeArrowFunctionContextScopeIfNeeded(SymbolTable*
addTarget.iterator->value.setIsLet();
}
if (isConstructor() && constructorKind() == ConstructorKind::Extends && isSuperUsedInInnerArrowFunction()) {
if (needsDerivedConstructorInArrowFunctionLexicalEnvironment()) {
auto derivedConstructor = environment.add(propertyNames().builtinNames().derivedConstructorPrivateName());
derivedConstructor.iterator->value.setIsCaptured();
derivedConstructor.iterator->value.setIsLet();
......@@ -1094,7 +1098,8 @@ void BytecodeGenerator::initializeArrowFunctionContextScopeIfNeeded(SymbolTable*
RegisterID* BytecodeGenerator::initializeNextParameter()
{
VirtualRegister reg = virtualRegisterForArgument(m_codeBlock->numParameters());
RegisterID& parameter = registerFor(reg);
m_parameters.grow(m_parameters.size() + 1);
auto& parameter = registerFor(reg);
parameter.setIndex(reg.offset());
m_codeBlock->addParameter();
return &parameter;
......@@ -1104,14 +1109,23 @@ void BytecodeGenerator::initializeParameters(FunctionParameters& parameters)
{
// Make sure the code block knows about all of our parameters, and make sure that parameters
// needing destructuring are noted.
m_parameters.grow(parameters.size() + 1); // reserve space for "this"
m_thisRegister.setIndex(initializeNextParameter()->index()); // this
bool nonSimpleArguments = false;
for (unsigned i = 0; i < parameters.size(); ++i) {
auto pattern = parameters.at(i).first;
auto parameter = parameters.at(i);
auto pattern = parameter.first;
if (pattern->isRestParameter()) {
RELEASE_ASSERT(!m_restParameter);
m_restParameter = static_cast<RestParameterNode*>(pattern);
} else
nonSimpleArguments = true;
continue;
}
if (parameter.second) {
nonSimpleArguments = true;
continue;
}
if (!nonSimpleArguments)
initializeNextParameter();
}
}
......@@ -4550,13 +4564,11 @@ void BytecodeGenerator::emitPutNewTargetToArrowFunctionContextScope()
void BytecodeGenerator::emitPutDerivedConstructorToArrowFunctionContextScope()
{
if ((isConstructor() && constructorKind() == ConstructorKind::Extends) || m_codeBlock->isClassContext()) {
if (isSuperUsedInInnerArrowFunction()) {
ASSERT(m_arrowFunctionContextLexicalEnvironmentRegister);
Variable protoScope = variable(propertyNames().builtinNames().derivedConstructorPrivateName());
emitPutToScope(m_arrowFunctionContextLexicalEnvironmentRegister, protoScope, &m_calleeRegister, DoNotThrowIfNotFound, InitializationMode::Initialization);
}
if (needsDerivedConstructorInArrowFunctionLexicalEnvironment()) {
ASSERT(m_arrowFunctionContextLexicalEnvironmentRegister);
Variable protoScope = variable(propertyNames().builtinNames().derivedConstructorPrivateName());
emitPutToScope(m_arrowFunctionContextLexicalEnvironmentRegister, protoScope, &m_calleeRegister, DoNotThrowIfNotFound, InitializationMode::Initialization);
}
}
......
......@@ -639,7 +639,6 @@ namespace JSC {
RegisterID* emitDeleteById(RegisterID* dst, RegisterID* base, const Identifier&);
RegisterID* emitGetByVal(RegisterID* dst, RegisterID* base, RegisterID* property);
RegisterID* emitGetByVal(RegisterID* dst, RegisterID* base, RegisterID* thisValue, RegisterID* property);
RegisterID* emitGetArgumentByVal(RegisterID* dst, RegisterID* base, RegisterID* property);
RegisterID* emitPutByVal(RegisterID* base, RegisterID* property, RegisterID* value);
RegisterID* emitPutByVal(RegisterID* base, RegisterID* thisValue, RegisterID* property, RegisterID* value);
RegisterID* emitDirectPutByVal(RegisterID* base, RegisterID* property, RegisterID* value);
......@@ -1024,6 +1023,7 @@ namespace JSC {
void initializeVarLexicalEnvironment(int symbolTableConstantIndex, SymbolTable* functionSymbolTable, bool hasCapturedVariables);
void initializeDefaultParameterValuesAndSetupFunctionScopeStack(FunctionParameters&, bool isSimpleParameterList, FunctionNode*, SymbolTable*, int symbolTableConstantIndex, const std::function<bool (UniquedStringImpl*)>& captures, bool shouldCreateArgumentsVariableInParameterScope);
void initializeArrowFunctionContextScopeIfNeeded(SymbolTable* functionSymbolTable = nullptr, bool canReuseLexicalEnvironment = false);
bool needsDerivedConstructorInArrowFunctionLexicalEnvironment();
public:
JSString* addStringConstant(const Identifier&);
......
......@@ -3463,13 +3463,13 @@ void EvalNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
void FunctionNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
{
if (generator.vm()->typeProfiler()) {
for (size_t i = 0; i < m_parameters->size(); i++) {
// Destructuring parameters are handled in destructuring nodes.
if (!m_parameters->at(i).first->isBindingNode())
continue;
BindingNode* parameter = static_cast<BindingNode*>(m_parameters->at(i).first);
RegisterID reg(CallFrame::argumentOffset(i));
generator.emitProfileType(&reg, ProfileTypeBytecodeFunctionArgument, parameter->divotStart(), parameter->divotEnd());
// If the parameter list is non simple one, it is handled in bindValue's code.
if (m_parameters->isSimpleParameterList()) {
for (size_t i = 0; i < m_parameters->size(); i++) {
BindingNode* bindingNode = static_cast<BindingNode*>(m_parameters->at(i).first);
RegisterID reg(CallFrame::argumentOffset(i));
generator.emitProfileType(&reg, ProfileTypeBytecodeFunctionArgument, bindingNode->divotStart(), bindingNode->divotEnd());
}
}
}
......
......@@ -475,7 +475,7 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
break;
}
forNode(node).setType(SpecInt32Only);
forNode(node).setType(SpecAnyInt);
break;
}
......@@ -1858,6 +1858,10 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
m_graph.registerStructure(m_graph.globalObjectFor(node->origin.semantic)->stringObjectStructure()));
break;
case StringOrStringObjectUse:
case Int32Use:
case Int52RepUse:
case DoubleRepUse:
case NotCellUse:
break;
case CellUse:
case UntypedUse:
......@@ -1870,6 +1874,11 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
forNode(node).set(m_graph, m_vm.stringStructure.get());
break;
}
case NumberToStringWithRadix:
clobberWorld(node->origin.semantic, clobberLimit);
forNode(node).set(m_graph, m_graph.m_vm.stringStructure.get());
break;
case NewStringObject: {
ASSERT(node->structure()->classInfo() == StringObject::info());
......@@ -2928,6 +2937,29 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
case CheckTypeInfoFlags:
break;
case ParseInt: {
AbstractValue value = forNode(node->child1());
if (value.m_type && !(value.m_type & ~SpecInt32Only)) {
JSValue radix;
if (!node->child2())
radix = jsNumber(0);
else
radix = forNode(node->child2()).m_value;
if (radix.isNumber()
&& (radix.asNumber() == 0 || radix.asNumber() == 10)) {
m_state.setFoundConstants(true);
forNode(node).setType(SpecInt32Only);
break;
}
}
if (node->child1().useKind() == UntypedUse)
clobberWorld(node->origin.semantic, clobberLimit);
forNode(node).setType(m_graph, SpecBytecodeNumber);
break;
}
case CreateRest:
if (!m_graph.isWatchingHavingABadTimeWatchpoint(node)) {
// This means we're already having a bad time.
......
......@@ -1424,15 +1424,6 @@ unsigned ByteCodeParser::inliningCost(CallVariant callee, int argumentCountInclu
return UINT_MAX;
}
// Does the number of arguments we're passing match the arity of the target? We currently
// inline only if the number of arguments passed is greater than or equal to the number
// arguments expected.
if (static_cast<int>(executable->parameterCount()) + 1 > argumentCountIncludingThis) {
if (verbose)
dataLog(" Failing because of arity mismatch.\n");
return UINT_MAX;
}
// Do we have a code block, and does the code block's size match the heuristics/requirements for
// being an inline candidate? We might not have a code block (1) if code was thrown away,
// (2) if we simply hadn't actually made this call yet or (3) code is a builtin function and
......@@ -1446,6 +1437,16 @@ unsigned ByteCodeParser::inliningCost(CallVariant callee, int argumentCountInclu
dataLog(" Failing because no code block available.\n");
return UINT_MAX;
}
// Does the number of arguments we're passing match the arity of the target? We currently
// inline only if the number of arguments passed is greater than or equal to the number
// arguments expected.
if (codeBlock->numParameters() > argumentCountIncludingThis) {
if (verbose)
dataLog(" Failing because of arity mismatch.\n");
return UINT_MAX;
}
CapabilityLevel capabilityLevel = inlineFunctionForCapabilityLevel(
codeBlock, kind, callee.isClosureCall());
if (verbose) {
......@@ -2360,6 +2361,27 @@ bool ByteCodeParser::handleIntrinsicCall(Node* callee, int resultOperand, Intrin
}
}
case ParseIntIntrinsic: {
if (argumentCountIncludingThis < 2)
return false;
if (m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCell) || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadType))
return false;
insertChecks();
VirtualRegister valueOperand = virtualRegisterForArgument(1, registerOffset);
Node* parseInt;
if (argumentCountIncludingThis == 2)
parseInt = addToGraph(ParseInt, OpInfo(), OpInfo(prediction), get(valueOperand));
else {
ASSERT(argumentCountIncludingThis > 2);
VirtualRegister radixOperand = virtualRegisterForArgument(2, registerOffset);
parseInt = addToGraph(ParseInt, OpInfo(), OpInfo(prediction), get(valueOperand), get(radixOperand));
}
set(VirtualRegister(resultOperand), parseInt);
return true;
}
case CharCodeAtIntrinsic: {
if (argumentCountIncludingThis != 2)
return false;
......@@ -2689,7 +2711,7 @@ bool ByteCodeParser::handleIntrinsicCall(Node* callee, int resultOperand, Intrin
return true;
}
case ToLowerCaseIntrinsic: {
case StringPrototypeToLowerCaseIntrinsic: {
if (argumentCountIncludingThis != 1)
return false;
......@@ -2703,6 +2725,26 @@ bool ByteCodeParser::handleIntrinsicCall(Node* callee, int resultOperand, Intrin
return true;
}
case NumberPrototypeToStringIntrinsic: {
if (argumentCountIncludingThis != 1 && argumentCountIncludingThis != 2)
return false;
if (m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadType))
return false;
insertChecks();
Node* thisNumber = get(virtualRegisterForArgument(0, registerOffset));
if (argumentCountIncludingThis == 1) {
Node* result = addToGraph(ToString, thisNumber);
set(VirtualRegister(resultOperand), result);
} else {
Node* radix = get(virtualRegisterForArgument(1, registerOffset));
Node* result = addToGraph(NumberToStringWithRadix, thisNumber, radix);
set(VirtualRegister(resultOperand), result);
}
return true;
}
default:
return false;
}
......
......@@ -888,6 +888,17 @@ void clobberize(Graph& graph, Node* node, const ReadFunctor& read, const WriteFu
def(HeapLocation(CheckTypeInfoFlagsLoc, JSCell_typeInfoFlags, node->child1()), LazyNode(node));
return;
case ParseInt:
// Note: We would have eliminated a ParseInt that has just a single child as an Int32Use inside fixup.
if (node->child1().useKind() == StringUse && (!node->child2() || node->child2().useKind() == Int32Use)) {
def(PureValue(node));
return;
}
read(World);
write(Heap);
return;
case OverridesHasInstance:
read(JSCell_typeInfoFlags);
def(HeapLocation(OverridesHasInstanceLoc, JSCell_typeInfoFlags, node->child1()), LazyNode(node));
......@@ -1389,6 +1400,13 @@ void clobberize(Graph& graph, Node* node, const ReadFunctor& read, const WriteFu
read(World);
write(Heap);
return;
case Int32Use:
case Int52RepUse:
case DoubleRepUse:
case NotCellUse:
def(PureValue(node));
return;
default:
RELEASE_ASSERT_NOT_REACHED();
......@@ -1434,6 +1452,11 @@ void clobberize(Graph& graph, Node* node, const ReadFunctor& read, const WriteFu
case ToLowerCase:
def(PureValue(node));
return;
case NumberToStringWithRadix:
read(World);
write(Heap);
return;
case LastNodeType:
RELEASE_ASSERT_NOT_REACHED();
......
......@@ -602,6 +602,29 @@ private:
break;
}
case ParseInt: {
AbstractValue& value = m_state.forNode(node->child1());
if (!value.m_type || (value.m_type & ~SpecInt32Only))
break;
JSValue radix;
if (!node->child2())
radix = jsNumber(0);
else
radix = m_state.forNode(node->child2()).m_value;
if (!radix.isNumber())
break;
if (radix.asNumber() == 0 || radix.asNumber() == 10) {
node->child2() = Edge();
node->convertToIdentity();
changed = true;
}
break;
}
case Check: {
alreadyHandled = true;
m_interpreter.execute(indexInBlock);
......
......@@ -178,6 +178,7 @@ bool doesGC(Graph& graph, Node* node)
case ToNumber:
case ToString:
case CallStringConstructor:
case NumberToStringWithRadix:
case In:
case HasOwnProperty:
case Jump:
......@@ -310,6 +311,7 @@ bool doesGC(Graph& graph, Node* node)
case CallDOMGetter:
case CallDOM:
case ArraySlice:
case ParseInt: // We might resolve a rope even though we don't clobber anything.
return true;
case MultiPutByOffset:
......
......@@ -1753,6 +1753,17 @@ private:
break;
}
case NumberToStringWithRadix: {
if (node->child1()->shouldSpeculateInt32())
fixEdge<Int32Use>(node->child1());
else if (enableInt52() && node->child1()->shouldSpeculateAnyInt())
fixEdge<Int52RepUse>(node->child1());
else
fixEdge<DoubleRepUse>(node->child1());
fixEdge<Int32Use>(node->child2());
break;
}
case DefineAccessorProperty: {
fixEdge<CellUse>(m_graph.varArgChild(node, 0));
Edge& propertyEdge = m_graph.varArgChild(node, 1);
......@@ -1793,6 +1804,24 @@ private:
break;
}
case ParseInt: {
if (node->child1()->shouldSpeculateInt32() && !node->child2()) {
fixEdge<Int32Use>(node->child1());
node->convertToIdentity();
break;
}
if (node->child1()->shouldSpeculateString()) {
fixEdge<StringUse>(node->child1());
node->clearFlags(NodeMustGenerate);
}
if (node->child2())
fixEdge<Int32Use>(node->child2());
break;
}
#if !ASSERT_DISABLED
// Have these no-op cases here to ensure that nobody forgets to add handlers for new opcodes.
case SetArgument:
......@@ -2210,6 +2239,34 @@ private:
fixEdge<CellUse>(node->child1());