<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[160947] branches/jsCStack/Source/JavaScriptCore</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/160947">160947</a></dd>
<dt>Author</dt> <dd>mark.lam@apple.com</dd>
<dt>Date</dt> <dd>2013-12-20 16:56:24 -0800 (Fri, 20 Dec 2013)</dd>
</dl>

<h3>Log Message</h3>
<pre>CStack: callToJavaScript should do stack check for incoming args.
https://bugs.webkit.org/show_bug.cgi?id=126088.

Not yet reviewed.

1. Change callToJavaScript()'s prototype to:
       EncodedJSValue callToJavaScript(void*, VM*, ProtoCallFrame*);

   We now pass VM* instead of &amp;vm.topCallFrame for the second argument.
   This gives us greater utility out of that arg.
   We also now save the VM* in the VMEntrySentinelFrame instead of
   &amp;vm.topCallFrame.

2. Change callToJavaScript() to do a stack check to ensure that we have
   adequate stack space to copy all the args from the protoCallFrame.
   If not, it'll throw a StackOverflowError.

3. Removed JSStack::entryCheck() and calls to it.

   callToJavaScript now takes care of the stack check that ensures
   adequate stack space for incoming args.
   callToJavaScript does assume that we have adequate stack space for
   the VMEntrySentinelFrame, but that is ensured by our stack host zone.

Changes to callToJavaScript are done in the doCallToJavaScript macro.
Hence, all the changes apply to callToNativeFunction as well.

* interpreter/Interpreter.cpp:
(JSC::Interpreter::execute):
(JSC::Interpreter::executeCall):
(JSC::Interpreter::executeConstruct):
(JSC::Interpreter::prepareForRepeatCall):
* interpreter/JSStack.h:
* interpreter/JSStackInlines.h:
* jit/JITCode.cpp:
(JSC::JITCode::execute):
* jit/JITStubs.h:
* jit/JITStubsMSVC64.asm: Added a FIXME.
* jit/JITStubsX86.h: Added a FIXME.
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::llint_throw_stack_overflow_error):
* llint/LLIntSlowPaths.h:
* llint/LLIntThunks.h:
* llint/LowLevelInterpreter64.asm:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#branchesjsCStackSourceJavaScriptCoreChangeLog">branches/jsCStack/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoreinterpreterInterpretercpp">branches/jsCStack/Source/JavaScriptCore/interpreter/Interpreter.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoreinterpreterJSStackh">branches/jsCStack/Source/JavaScriptCore/interpreter/JSStack.h</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoreinterpreterJSStackInlinesh">branches/jsCStack/Source/JavaScriptCore/interpreter/JSStackInlines.h</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCorejitJITCodecpp">branches/jsCStack/Source/JavaScriptCore/jit/JITCode.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCorejitJITStubsh">branches/jsCStack/Source/JavaScriptCore/jit/JITStubs.h</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCorejitJITStubsMSVC64asm">branches/jsCStack/Source/JavaScriptCore/jit/JITStubsMSVC64.asm</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCorejitJITStubsX86h">branches/jsCStack/Source/JavaScriptCore/jit/JITStubsX86.h</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCorellintLLIntSlowPathscpp">branches/jsCStack/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCorellintLLIntSlowPathsh">branches/jsCStack/Source/JavaScriptCore/llint/LLIntSlowPaths.h</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCorellintLLIntThunksh">branches/jsCStack/Source/JavaScriptCore/llint/LLIntThunks.h</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCorellintLowLevelInterpreter64asm">branches/jsCStack/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="branchesjsCStackSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/ChangeLog (160946 => 160947)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/ChangeLog        2013-12-21 00:44:36 UTC (rev 160946)
+++ branches/jsCStack/Source/JavaScriptCore/ChangeLog        2013-12-21 00:56:24 UTC (rev 160947)
</span><span class="lines">@@ -1,3 +1,50 @@
</span><ins>+2013-12-20  Mark Lam  &lt;mark.lam@apple.com&gt;
+
+        CStack: callToJavaScript should do stack check for incoming args.
+        https://bugs.webkit.org/show_bug.cgi?id=126088.
+
+        Not yet reviewed.
+
+        1. Change callToJavaScript()'s prototype to:
+               EncodedJSValue callToJavaScript(void*, VM*, ProtoCallFrame*);
+
+           We now pass VM* instead of &amp;vm.topCallFrame for the second argument.
+           This gives us greater utility out of that arg.
+           We also now save the VM* in the VMEntrySentinelFrame instead of
+           &amp;vm.topCallFrame.
+
+        2. Change callToJavaScript() to do a stack check to ensure that we have
+           adequate stack space to copy all the args from the protoCallFrame.
+           If not, it'll throw a StackOverflowError.
+
+        3. Removed JSStack::entryCheck() and calls to it.
+
+           callToJavaScript now takes care of the stack check that ensures
+           adequate stack space for incoming args.
+           callToJavaScript does assume that we have adequate stack space for
+           the VMEntrySentinelFrame, but that is ensured by our stack host zone.
+
+        Changes to callToJavaScript are done in the doCallToJavaScript macro.
+        Hence, all the changes apply to callToNativeFunction as well.
+
+        * interpreter/Interpreter.cpp:
+        (JSC::Interpreter::execute):
+        (JSC::Interpreter::executeCall):
+        (JSC::Interpreter::executeConstruct):
+        (JSC::Interpreter::prepareForRepeatCall):
+        * interpreter/JSStack.h:
+        * interpreter/JSStackInlines.h:
+        * jit/JITCode.cpp:
+        (JSC::JITCode::execute):
+        * jit/JITStubs.h:
+        * jit/JITStubsMSVC64.asm: Added a FIXME.
+        * jit/JITStubsX86.h: Added a FIXME.
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::llint_throw_stack_overflow_error):
+        * llint/LLIntSlowPaths.h:
+        * llint/LLIntThunks.h:
+        * llint/LowLevelInterpreter64.asm:
+
</ins><span class="cx"> 2013-12-20  Filip Pizlo  &lt;fpizlo@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Arity check slow path should ensure that when we return, we restore SP back to what the caller expects
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoreinterpreterInterpretercpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/interpreter/Interpreter.cpp (160946 => 160947)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/interpreter/Interpreter.cpp        2013-12-21 00:44:36 UTC (rev 160946)
+++ branches/jsCStack/Source/JavaScriptCore/interpreter/Interpreter.cpp        2013-12-21 00:56:24 UTC (rev 160947)
</span><span class="lines">@@ -892,9 +892,6 @@
</span><span class="cx"> 
</span><span class="cx">     ASSERT(codeBlock-&gt;numParameters() == 1); // 1 parameter for 'this'.
</span><span class="cx"> 
</span><del>-    if (UNLIKELY(!m_stack.entryCheck(codeBlock, 1)))
-        return checkedReturn(throwStackOverflowError(callFrame));
-
</del><span class="cx">     ProtoCallFrame protoCallFrame;
</span><span class="cx">     protoCallFrame.init(codeBlock, scope, 0, thisObj, 1);
</span><span class="cx"> 
</span><span class="lines">@@ -955,9 +952,6 @@
</span><span class="cx">     if (UNLIKELY(vm.watchdog.didFire(callFrame)))
</span><span class="cx">         return throwTerminatedExecutionException(callFrame);
</span><span class="cx"> 
</span><del>-    if (UNLIKELY(!m_stack.entryCheck(newCodeBlock, argsCount)))
-        return checkedReturn(throwStackOverflowError(callFrame));
-
</del><span class="cx">     ProtoCallFrame protoCallFrame;
</span><span class="cx">     protoCallFrame.init(newCodeBlock, scope, function, thisValue, argsCount, args.data());
</span><span class="cx"> 
</span><span class="lines">@@ -973,7 +967,7 @@
</span><span class="cx">         if (isJSCall)
</span><span class="cx">             result = callData.js.functionExecutable-&gt;generatedJITCodeForCall()-&gt;execute(&amp;vm, &amp;protoCallFrame);
</span><span class="cx">         else
</span><del>-            result = JSValue::decode(callToNativeFunction(reinterpret_cast&lt;void*&gt;(callData.native.function), &amp;vm.topCallFrame, &amp;protoCallFrame));
</del><ins>+            result = JSValue::decode(callToNativeFunction(reinterpret_cast&lt;void*&gt;(callData.native.function), &amp;vm, &amp;protoCallFrame));
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if (LegacyProfiler* profiler = vm.enabledProfiler())
</span><span class="lines">@@ -1023,9 +1017,6 @@
</span><span class="cx">     if (UNLIKELY(vm.watchdog.didFire(callFrame)))
</span><span class="cx">         return throwTerminatedExecutionException(callFrame);
</span><span class="cx"> 
</span><del>-    if (UNLIKELY(!m_stack.entryCheck(newCodeBlock, argsCount)))
-        return checkedReturn(throwStackOverflowError(callFrame));
-
</del><span class="cx">     ProtoCallFrame protoCallFrame;
</span><span class="cx">     protoCallFrame.init(newCodeBlock, scope, constructor, jsUndefined(), argsCount, args.data());
</span><span class="cx"> 
</span><span class="lines">@@ -1041,7 +1032,7 @@
</span><span class="cx">         if (isJSConstruct)
</span><span class="cx">             result = constructData.js.functionExecutable-&gt;generatedJITCodeForConstruct()-&gt;execute(&amp;vm, &amp;protoCallFrame);
</span><span class="cx">         else {
</span><del>-            result = JSValue::decode(callToNativeFunction(reinterpret_cast&lt;void*&gt;(constructData.native.function), &amp;vm.topCallFrame, &amp;protoCallFrame));
</del><ins>+            result = JSValue::decode(callToNativeFunction(reinterpret_cast&lt;void*&gt;(constructData.native.function), &amp;vm, &amp;protoCallFrame));
</ins><span class="cx"> 
</span><span class="cx">             if (!callFrame-&gt;hadException())
</span><span class="cx">                 RELEASE_ASSERT(result.isObject());
</span><span class="lines">@@ -1076,11 +1067,6 @@
</span><span class="cx"> 
</span><span class="cx">     size_t argsCount = argumentCountIncludingThis;
</span><span class="cx"> 
</span><del>-    if (UNLIKELY(!m_stack.entryCheck(newCodeBlock, argsCount))) {
-        throwStackOverflowError(callFrame);
-        return CallFrameClosure();
-    }
-
</del><span class="cx">     protoCallFrame-&gt;init(newCodeBlock, scope, function, jsUndefined(), argsCount, args);
</span><span class="cx">     // Return the successful closure:
</span><span class="cx">     CallFrameClosure result = { callFrame, protoCallFrame, function, functionExecutable, &amp;vm, scope, newCodeBlock-&gt;numParameters(), argumentCountIncludingThis };
</span><span class="lines">@@ -1182,9 +1168,6 @@
</span><span class="cx"> 
</span><span class="cx">     ASSERT(codeBlock-&gt;numParameters() == 1); // 1 parameter for 'this'.
</span><span class="cx"> 
</span><del>-    if (UNLIKELY(!m_stack.entryCheck(codeBlock, 1)))
-        return checkedReturn(throwStackOverflowError(callFrame));
-
</del><span class="cx">     ProtoCallFrame protoCallFrame;
</span><span class="cx">     protoCallFrame.init(codeBlock, scope, 0, thisValue, 1);
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoreinterpreterJSStackh"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/interpreter/JSStack.h (160946 => 160947)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/interpreter/JSStack.h        2013-12-21 00:44:36 UTC (rev 160946)
+++ branches/jsCStack/Source/JavaScriptCore/interpreter/JSStack.h        2013-12-21 00:56:24 UTC (rev 160947)
</span><span class="lines">@@ -101,8 +101,6 @@
</span><span class="cx">         Register* startOfFrameFor(CallFrame*);
</span><span class="cx">         Register* topOfStack();
</span><span class="cx"> 
</span><del>-        bool entryCheck(class CodeBlock*, int);
-
</del><span class="cx">         CallFrame* pushFrame(class CodeBlock*, JSScope*, int argsCount, JSObject* callee);
</span><span class="cx"> 
</span><span class="cx">         void popFrame(CallFrame*);
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoreinterpreterJSStackInlinesh"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/interpreter/JSStackInlines.h (160946 => 160947)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/interpreter/JSStackInlines.h        2013-12-21 00:44:36 UTC (rev 160946)
+++ branches/jsCStack/Source/JavaScriptCore/interpreter/JSStackInlines.h        2013-12-21 00:56:24 UTC (rev 160947)
</span><span class="lines">@@ -51,35 +51,6 @@
</span><span class="cx">     return topOfFrameFor(callerFrame);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-inline bool JSStack::entryCheck(class CodeBlock* codeBlock, int argsCount)
-{
-    Register* oldEnd = topOfStack();
-
-    // Ensure that we have enough space for the parameters:
-    size_t paddedArgsCount = argsCount;
-    if (codeBlock) {
-        size_t numParameters = codeBlock-&gt;numParameters();
-        if (paddedArgsCount &lt; numParameters)
-            paddedArgsCount = numParameters;
-    }
-
-    Register* newCallFrameSlot = oldEnd - paddedArgsCount - (2 * JSStack::CallFrameHeaderSize) + 1;
-
-#if ENABLE(DEBUG_JSSTACK)
-    newCallFrameSlot -= JSStack::FenceSize;
-#endif
-
-    Register* topOfStack = newCallFrameSlot;
-    if (!!codeBlock)
-        topOfStack += codeBlock-&gt;stackPointerOffset();
-
-    // Ensure that we have the needed stack capacity to push the new frame:
-    if (!grow(topOfStack))
-        return false;
-
-    return true;
-}
-
</del><span class="cx"> inline CallFrame* JSStack::pushFrame(class CodeBlock* codeBlock, JSScope* scope, int argsCount, JSObject* callee)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(!!scope);
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCorejitJITCodecpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/jit/JITCode.cpp (160946 => 160947)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/jit/JITCode.cpp        2013-12-21 00:44:36 UTC (rev 160946)
+++ branches/jsCStack/Source/JavaScriptCore/jit/JITCode.cpp        2013-12-21 00:56:24 UTC (rev 160947)
</span><span class="lines">@@ -44,7 +44,7 @@
</span><span class="cx"> 
</span><span class="cx"> JSValue JITCode::execute(VM* vm, ProtoCallFrame* protoCallFrame)
</span><span class="cx"> {
</span><del>-    JSValue result = JSValue::decode(callToJavaScript(executableAddress(), &amp;vm-&gt;topCallFrame, protoCallFrame));
</del><ins>+    JSValue result = JSValue::decode(callToJavaScript(executableAddress(), vm, protoCallFrame));
</ins><span class="cx">     return vm-&gt;exception() ? jsNull() : result;
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCorejitJITStubsh"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/jit/JITStubs.h (160946 => 160947)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/jit/JITStubs.h        2013-12-21 00:44:36 UTC (rev 160946)
+++ branches/jsCStack/Source/JavaScriptCore/jit/JITStubs.h        2013-12-21 00:56:24 UTC (rev 160947)
</span><span class="lines">@@ -37,14 +37,13 @@
</span><span class="cx"> #if ENABLE(JIT)
</span><span class="cx"> 
</span><span class="cx"> #if OS(WINDOWS)
</span><del>-class ExecState;
-class Register;
</del><span class="cx"> struct ProtoCallFrame;
</span><ins>+class VM;
</ins><span class="cx"> 
</span><span class="cx"> extern &quot;C&quot; {
</span><del>-    EncodedJSValue callToJavaScript(void*, ExecState**, ProtoCallFrame*);
</del><ins>+    EncodedJSValue callToJavaScript(void*, VM*, ProtoCallFrame*);
+    EncodedJSValue callToNativeFunction(void*, VM*, ProtoCallFrame*);
</ins><span class="cx">     void handleUncaughtException();
</span><del>-    EncodedJSValue callToNativeFunction(void*, ExecState**, ProtoCallFrame*);
</del><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCorejitJITStubsMSVC64asm"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/jit/JITStubsMSVC64.asm (160946 => 160947)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/jit/JITStubsMSVC64.asm        2013-12-21 00:44:36 UTC (rev 160946)
+++ branches/jsCStack/Source/JavaScriptCore/jit/JITStubsMSVC64.asm        2013-12-21 00:56:24 UTC (rev 160947)
</span><span class="lines">@@ -35,6 +35,16 @@
</span><span class="cx">     ;; FIXME: This function has not been tested as the Win 64 port doesn't currently use the JIT.
</span><span class="cx">     ;; It is believed to be an accurate adaptation of the assembly created by the llint stub of the
</span><span class="cx">     ;; same name with changes for agrument register differences.
</span><ins>+
+    ;; FIXME: This code is stale and need to be updated for the following:
+    ;; 1. The prototype is now:
+    ;;        EncodedJSValue callToJavaScript(void* code, VM*, ProtoCallFrame*)
+    ;;    The code below was implemented for a prototype of:
+    ;;        EncodedJSValue callToJavaScript(void* code, ExecState**, ProtoCallFrame*, Register*)
+    ;;
+    ;; 2. Need to add code for a stack check to ensure that we have enough stack space
+    ;;    for incoming args.
+
</ins><span class="cx">     int 3
</span><span class="cx">     mov r10, qword ptr[rsp]
</span><span class="cx">     push rbp
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCorejitJITStubsX86h"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/jit/JITStubsX86.h (160946 => 160947)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/jit/JITStubsX86.h        2013-12-21 00:44:36 UTC (rev 160946)
+++ branches/jsCStack/Source/JavaScriptCore/jit/JITStubsX86.h        2013-12-21 00:56:24 UTC (rev 160947)
</span><span class="lines">@@ -206,6 +206,16 @@
</span><span class="cx"> 
</span><span class="cx">     // FIXME: Since Windows doesn't use the LLInt, we have inline stubs here.
</span><span class="cx">     // Until the LLInt is changed to support Windows, these stub needs to be updated.
</span><ins>+
+    // FIXME: This code is stale and need to be updated for the following:
+    // 1. The prototype is now:
+    //        EncodedJSValue callToJavaScript(void* code, VM*, ProtoCallFrame*)
+    //    I've left the old prototype in place to give context for what the implementation
+    //    below is doing.
+    //
+    // 2. Need to add code for a stack check to ensure that we have enough stack space
+    //    for incoming args.
+    
</ins><span class="cx">     __declspec(naked) EncodedJSValue callToJavaScript(void* code, ExecState**, ProtoCallFrame*, Register*)
</span><span class="cx">     {
</span><span class="cx">         __asm {
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCorellintLLIntSlowPathscpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp (160946 => 160947)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp        2013-12-21 00:44:36 UTC (rev 160946)
+++ branches/jsCStack/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp        2013-12-21 00:56:24 UTC (rev 160947)
</span><span class="lines">@@ -51,6 +51,7 @@
</span><span class="cx"> #include &quot;LowLevelInterpreter.h&quot;
</span><span class="cx"> #include &quot;ObjectConstructor.h&quot;
</span><span class="cx"> #include &quot;Operations.h&quot;
</span><ins>+#include &quot;ProtoCallFrame.h&quot;
</ins><span class="cx"> #include &quot;StructureRareDataInlines.h&quot;
</span><span class="cx"> #include &lt;wtf/StringPrintStream.h&gt;
</span><span class="cx"> 
</span><span class="lines">@@ -1392,6 +1393,14 @@
</span><span class="cx">     LLINT_END();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void llint_throw_stack_overflow_error(VM* vm, ProtoCallFrame* protoFrame)
+{
+    ExecState* exec = vm-&gt;topCallFrame;
+    if (!exec)
+        exec = protoFrame-&gt;scope()-&gt;globalObject()-&gt;globalExec();
+    throwStackOverflowError(exec);
+}
+
</ins><span class="cx"> } } // namespace JSC::LLInt
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(LLINT)
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCorellintLLIntSlowPathsh"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/llint/LLIntSlowPaths.h (160946 => 160947)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/llint/LLIntSlowPaths.h        2013-12-21 00:44:36 UTC (rev 160946)
+++ branches/jsCStack/Source/JavaScriptCore/llint/LLIntSlowPaths.h        2013-12-21 00:56:24 UTC (rev 160947)
</span><span class="lines">@@ -36,6 +36,7 @@
</span><span class="cx"> 
</span><span class="cx"> class ExecState;
</span><span class="cx"> struct Instruction;
</span><ins>+struct ProtoCallFrame;
</ins><span class="cx"> 
</span><span class="cx"> namespace LLInt {
</span><span class="cx"> 
</span><span class="lines">@@ -122,6 +123,7 @@
</span><span class="cx"> LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_resolve_scope);
</span><span class="cx"> LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_get_from_scope);
</span><span class="cx"> LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_put_to_scope);
</span><ins>+extern &quot;C&quot; void llint_throw_stack_overflow_error(VM*, ProtoCallFrame*);
</ins><span class="cx"> 
</span><span class="cx"> } } // namespace JSC::LLInt
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCorellintLLIntThunksh"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/llint/LLIntThunks.h (160946 => 160947)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/llint/LLIntThunks.h        2013-12-21 00:44:36 UTC (rev 160946)
+++ branches/jsCStack/Source/JavaScriptCore/llint/LLIntThunks.h        2013-12-21 00:56:24 UTC (rev 160947)
</span><span class="lines">@@ -34,14 +34,12 @@
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><del>-class ExecState;
-class Register;
</del><span class="cx"> class VM;
</span><span class="cx"> struct ProtoCallFrame;
</span><span class="cx"> 
</span><span class="cx"> extern &quot;C&quot; {
</span><del>-    EncodedJSValue callToJavaScript(void*, ExecState**, ProtoCallFrame*);
-    EncodedJSValue callToNativeFunction(void*, ExecState**, ProtoCallFrame*);
</del><ins>+    EncodedJSValue callToJavaScript(void*, VM*, ProtoCallFrame*);
+    EncodedJSValue callToNativeFunction(void*, VM*, ProtoCallFrame*);
</ins><span class="cx"> #if ENABLE(JIT)
</span><span class="cx">     void handleUncaughtException();
</span><span class="cx"> #endif
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCorellintLowLevelInterpreter64asm"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm (160946 => 160947)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm        2013-12-21 00:44:36 UTC (rev 160946)
+++ branches/jsCStack/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm        2013-12-21 00:56:24 UTC (rev 160947)
</span><span class="lines">@@ -151,9 +151,8 @@
</span><span class="cx"> macro doCallToJavaScript(makeCall)
</span><span class="cx">     if X86_64
</span><span class="cx">         const entry = t4
</span><del>-        const vmTopCallFrame = t5
</del><ins>+        const vm = t5
</ins><span class="cx">         const protoCallFrame = t1
</span><del>-        const topOfStack = t2
</del><span class="cx"> 
</span><span class="cx">         const previousCFR = t0
</span><span class="cx">         const previousPC = t6
</span><span class="lines">@@ -162,9 +161,8 @@
</span><span class="cx">         const temp3 = t6
</span><span class="cx">     elsif ARM64
</span><span class="cx">         const entry = a0
</span><del>-        const vmTopCallFrame = a1
</del><ins>+        const vm = a1
</ins><span class="cx">         const protoCallFrame = a2
</span><del>-        const topOfStack = a3
</del><span class="cx"> 
</span><span class="cx">         const previousCFR = t5
</span><span class="cx">         const previousPC = lr
</span><span class="lines">@@ -181,12 +179,14 @@
</span><span class="cx"> 
</span><span class="cx">     checkStackPointerAlignment(temp2, 0xbad0dc01)
</span><span class="cx"> 
</span><del>-    # Allocate and initialize the sentinel frame.
</del><ins>+    # The stack host zone ensures that we have adequate space for the
+    # VMEntrySentinelFrame. Proceed with allocating and initializing the
+    # sentinel frame.
</ins><span class="cx">     move sp, cfr
</span><span class="cx">     subp CallFrameHeaderSlots*8, cfr
</span><span class="cx">     storep 0, ArgumentCount[cfr]
</span><del>-    storep vmTopCallFrame, Callee[cfr]
-    loadp [vmTopCallFrame], temp2
</del><ins>+    storep vm, Callee[cfr]
+    loadp VM::topCallFrame[vm], temp2
</ins><span class="cx">     storep temp2, ScopeChain[cfr]
</span><span class="cx">     storep 1, CodeBlock[cfr]
</span><span class="cx">     storep previousPC, ReturnPC[cfr]
</span><span class="lines">@@ -195,8 +195,27 @@
</span><span class="cx">     loadi ProtoCallFrame::paddedArgCount[protoCallFrame], temp2
</span><span class="cx">     addp CallFrameHeaderSlots, temp2, temp2
</span><span class="cx">     lshiftp 3, temp2
</span><del>-    subp cfr, temp2, sp
</del><ins>+    subp cfr, temp2, temp1
</ins><span class="cx"> 
</span><ins>+    # Ensure that we have enough additional stack capacity for the incoming args,
+    # and the frame for the JS code we're executing. We need to do this check
+    # before we start copying the args from the protoCallFrame below.
+    bpaeq temp1, VM::m_jsStackLimit[vm], .stackHeightOK
+
+    move cfr, sp
+
+    if C_LOOP
+    # FIXME: Need to call stack check here to see if we can grow the stack.
+    # Will need to preserve registers so that we can recover if we do not end
+    # up throwing a StackOverflowError.
+    end
+
+    cCall2(_llint_throw_stack_overflow_error, vm, protoCallFrame)
+    callToJavaScriptEpilogue()
+    ret
+
+.stackHeightOK:
+    move temp1, sp
</ins><span class="cx">     move 5, temp1
</span><span class="cx"> 
</span><span class="cx"> .copyHeaderLoop:
</span><span class="lines">@@ -228,7 +247,7 @@
</span><span class="cx">     jmp .copyArgsLoop
</span><span class="cx"> 
</span><span class="cx"> .copyArgsDone:
</span><del>-    storep sp, [vmTopCallFrame]
</del><ins>+    storep sp, VM::topCallFrame[vm]
</ins><span class="cx"> 
</span><span class="cx">     move 0xffff000000000000, csr1
</span><span class="cx">     addp 2, csr1, csr2
</span><span class="lines">@@ -243,9 +262,9 @@
</span><span class="cx">     loadp CallerFrame[cfr], cfr
</span><span class="cx"> 
</span><span class="cx"> .calleeFramePopped:
</span><del>-    loadp Callee[cfr], temp2 # VM.topCallFrame
-    loadp ScopeChain[cfr], temp3
-    storep temp3, [temp2]
</del><ins>+    loadp Callee[cfr], temp2 # VM
+    loadp ScopeChain[cfr], temp3 # previous topCallFrame
+    storep temp3, VM::topCallFrame[temp2]
</ins><span class="cx"> 
</span><span class="cx">     checkStackPointerAlignment(temp3, 0xbad0dc04)
</span><span class="cx"> 
</span><span class="lines">@@ -285,9 +304,9 @@
</span><span class="cx">     # returning to the caller C frame.
</span><span class="cx">     loadp CallerFrame[cfr], cfr
</span><span class="cx"> 
</span><del>-    loadp Callee[cfr], t3 # VM.topCallFrame
-    loadp ScopeChain[cfr], t6
-    storep t6, [t3]
</del><ins>+    loadp Callee[cfr], t3 # VM
+    loadp ScopeChain[cfr], t6 # previous topCallFrame
+    storep t6, VM::topCallFrame[t3]
</ins><span class="cx"> 
</span><span class="cx">     callToJavaScriptEpilogue()
</span><span class="cx">     ret
</span></span></pre>
</div>
</div>

</body>
</html>