<!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>[189946] trunk/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/189946">189946</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2015-09-17 17:03:49 -0700 (Thu, 17 Sep 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>Convert return values from JavaScript functions to the expected types in WebAssembly
https://bugs.webkit.org/show_bug.cgi?id=149200

Patch by Sukolsak Sakshuwong &lt;sukolsak@gmail.com&gt; on 2015-09-17
Reviewed by Mark Lam.

When a WebAssembly function calls a JavaScript function, there is no
guarantee that the JavaScript function will always return values of the
type we expect. This patch converts the return values to the expected
types.

(The reverse is also true: When a WebAssembly function is called from a
JavaScript function, there is no guarantee that the arguments to the
WebAssembly function will always be of the types we expect. We have
fixed this in Bug 149033.)

We don't need to type check the return values if the callee is a
WebAssembly function. We don't need to type check the arguments if the
caller is a WebAssembly function. This optimization will be
implemented in the future. See https://bugs.webkit.org/show_bug.cgi?id=149310

* tests/stress/wasm-type-conversion.js:
* tests/stress/wasm/type-conversion.wasm:
* wasm/WASMFunctionCompiler.h:
(JSC::WASMFunctionCompiler::startFunction):
(JSC::WASMFunctionCompiler::buildReturn):
(JSC::WASMFunctionCompiler::boxArgumentsAndAdjustStackPointer):
(JSC::WASMFunctionCompiler::callAndUnboxResult):
(JSC::WASMFunctionCompiler::convertValueToInt32):
(JSC::WASMFunctionCompiler::convertValueToDouble):
(JSC::WASMFunctionCompiler::convertDoubleToValue):
(JSC::WASMFunctionCompiler::loadValueAndConvertToInt32): Deleted.
(JSC::WASMFunctionCompiler::loadValueAndConvertToDouble): Deleted.
* wasm/WASMFunctionParser.cpp:
(JSC::WASMFunctionParser::parseExpressionI32):
(JSC::WASMFunctionParser::parseExpressionF32):
(JSC::WASMFunctionParser::parseExpressionF64):
(JSC::WASMFunctionParser::parseCallInternalExpressionI32): Deleted.
* wasm/WASMFunctionParser.h:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstresswasmtypeconversionwasm">trunk/Source/JavaScriptCore/tests/stress/wasm/type-conversion.wasm</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstresswasmtypeconversionjs">trunk/Source/JavaScriptCore/tests/stress/wasm-type-conversion.js</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmWASMFunctionCompilerh">trunk/Source/JavaScriptCore/wasm/WASMFunctionCompiler.h</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmWASMFunctionParsercpp">trunk/Source/JavaScriptCore/wasm/WASMFunctionParser.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmWASMFunctionParserh">trunk/Source/JavaScriptCore/wasm/WASMFunctionParser.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (189945 => 189946)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2015-09-17 23:53:58 UTC (rev 189945)
+++ trunk/Source/JavaScriptCore/ChangeLog        2015-09-18 00:03:49 UTC (rev 189946)
</span><span class="lines">@@ -1,3 +1,44 @@
</span><ins>+2015-09-17  Sukolsak Sakshuwong  &lt;sukolsak@gmail.com&gt;
+
+        Convert return values from JavaScript functions to the expected types in WebAssembly
+        https://bugs.webkit.org/show_bug.cgi?id=149200
+
+        Reviewed by Mark Lam.
+
+        When a WebAssembly function calls a JavaScript function, there is no
+        guarantee that the JavaScript function will always return values of the
+        type we expect. This patch converts the return values to the expected
+        types.
+
+        (The reverse is also true: When a WebAssembly function is called from a
+        JavaScript function, there is no guarantee that the arguments to the
+        WebAssembly function will always be of the types we expect. We have
+        fixed this in Bug 149033.)
+
+        We don't need to type check the return values if the callee is a
+        WebAssembly function. We don't need to type check the arguments if the
+        caller is a WebAssembly function. This optimization will be
+        implemented in the future. See https://bugs.webkit.org/show_bug.cgi?id=149310
+
+        * tests/stress/wasm-type-conversion.js:
+        * tests/stress/wasm/type-conversion.wasm:
+        * wasm/WASMFunctionCompiler.h:
+        (JSC::WASMFunctionCompiler::startFunction):
+        (JSC::WASMFunctionCompiler::buildReturn):
+        (JSC::WASMFunctionCompiler::boxArgumentsAndAdjustStackPointer):
+        (JSC::WASMFunctionCompiler::callAndUnboxResult):
+        (JSC::WASMFunctionCompiler::convertValueToInt32):
+        (JSC::WASMFunctionCompiler::convertValueToDouble):
+        (JSC::WASMFunctionCompiler::convertDoubleToValue):
+        (JSC::WASMFunctionCompiler::loadValueAndConvertToInt32): Deleted.
+        (JSC::WASMFunctionCompiler::loadValueAndConvertToDouble): Deleted.
+        * wasm/WASMFunctionParser.cpp:
+        (JSC::WASMFunctionParser::parseExpressionI32):
+        (JSC::WASMFunctionParser::parseExpressionF32):
+        (JSC::WASMFunctionParser::parseExpressionF64):
+        (JSC::WASMFunctionParser::parseCallInternalExpressionI32): Deleted.
+        * wasm/WASMFunctionParser.h:
+
</ins><span class="cx"> 2015-09-17  Yusuke Suzuki  &lt;utatane.tea@gmail.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [ES6] Add more fine-grained APIs and additional hooks to control module loader from WebCore
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstresswasmtypeconversionwasm"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/tests/stress/wasm/type-conversion.wasm (189945 => 189946)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/wasm/type-conversion.wasm        2015-09-17 23:53:58 UTC (rev 189945)
+++ trunk/Source/JavaScriptCore/tests/stress/wasm/type-conversion.wasm        2015-09-18 00:03:49 UTC (rev 189946)
</span><span class="lines">@@ -1 +1,4 @@
</span><del>-wasm{\x80\xC0\x80\xA0\x80\xA0takeAndReturnInt32takeAndReturnFloattakeAndReturnDouble
</del><span class="cx">\ No newline at end of file
</span><ins>+wasm\xEFgetInt32getDoublegetStringgetBoolean+\x80\xC0\x80\xA0\x80\xA0\x80\x80\x80\x80\x80 \x80 \x80 \x80 \x80\xA0\x80
+ \xA0 takeAndReturnInt32takeAndReturnFloattakeAndReturnDoublereturnInt32FromInt32returnInt32FromDoublereturnInt32FromStringreturnInt32FromBooleanreturnDoubleFromInt32returnDoubleFromDoublereturnDoubleFromString        returnDoubleFromBoolean
+add
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstresswasmtypeconversionjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/tests/stress/wasm-type-conversion.js (189945 => 189946)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/wasm-type-conversion.js        2015-09-17 23:53:58 UTC (rev 189945)
+++ trunk/Source/JavaScriptCore/tests/stress/wasm-type-conversion.js        2015-09-18 00:03:49 UTC (rev 189946)
</span><span class="lines">@@ -8,14 +8,18 @@
</span><span class="cx"> /*
</span><span class="cx"> wasm/type-conversion.wasm is generated by pack-asmjs &lt;https://github.com/WebAssembly/polyfill-prototype-1&gt; from the following script:
</span><span class="cx"> 
</span><del>-function asmModule(global, env, buffer) {
</del><ins>+function asmModule(global, imports, buffer) {
</ins><span class="cx">     &quot;use asm&quot;;
</span><span class="cx"> 
</span><span class="cx">     var fround = global.Math.fround;
</span><ins>+    var getInt32 = imports.getInt32;
+    var getDouble = imports.getDouble;
+    var getString = imports.getString;
+    var getBoolean = imports.getBoolean;
</ins><span class="cx"> 
</span><span class="cx">     function takeAndReturnInt32(x) {
</span><span class="cx">         x = x | 0;
</span><del>-        return x;
</del><ins>+        return x | 0;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     function takeAndReturnFloat(x) {
</span><span class="lines">@@ -28,14 +32,62 @@
</span><span class="cx">         return x;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    function returnInt32FromInt32() {
+        return getInt32() | 0;
+    }
+
+    function returnInt32FromDouble() {
+        return getDouble() | 0;
+    }
+
+    function returnInt32FromString() {
+        return getString() | 0;
+    }
+
+    function returnInt32FromBoolean() {
+        return getBoolean() | 0;
+    }
+
+    function returnDoubleFromInt32() {
+        return +getInt32();
+    }
+
+    function returnDoubleFromDouble() {
+        return +getDouble();
+    }
+
+    function returnDoubleFromString() {
+        return +getString();
+    }
+
+    function returnDoubleFromBoolean() {
+        return +getBoolean();
+    }
+
</ins><span class="cx">     return {
</span><span class="cx">         takeAndReturnInt32: takeAndReturnInt32,
</span><ins>+        takeAndReturnFloat: takeAndReturnFloat,
</ins><span class="cx">         takeAndReturnDouble: takeAndReturnDouble,
</span><ins>+
+        returnInt32FromInt32: returnInt32FromInt32,
+        returnInt32FromDouble: returnInt32FromDouble,
+        returnInt32FromString: returnInt32FromString,
+        returnInt32FromBoolean: returnInt32FromBoolean,
+        returnDoubleFromInt32: returnDoubleFromInt32,
+        returnDoubleFromDouble: returnDoubleFromDouble,
+        returnDoubleFromString: returnDoubleFromString,
+        returnDoubleFromBoolean: returnDoubleFromBoolean,
</ins><span class="cx">     };
</span><span class="cx"> }
</span><span class="cx"> */
</span><span class="cx"> 
</span><del>-var module = loadWebAssembly(&quot;wasm/type-conversion.wasm&quot;);
</del><ins>+var imports = {
+    getInt32: () =&gt; 42,
+    getDouble: () =&gt; 4.2,
+    getString: () =&gt; &quot;4.2&quot;,
+    getBoolean: () =&gt; true,
+};
+var module = loadWebAssembly(&quot;wasm/type-conversion.wasm&quot;, imports);
</ins><span class="cx"> 
</span><span class="cx"> var two = {
</span><span class="cx">     valueOf() { return 2; }
</span><span class="lines">@@ -70,3 +122,12 @@
</span><span class="cx"> shouldBe(isNaN(module.takeAndReturnDouble({ })), true);
</span><span class="cx"> shouldBe(module.takeAndReturnDouble([2.5]), 2.5);
</span><span class="cx"> shouldBe(module.takeAndReturnDouble(two), 2);
</span><ins>+
+shouldBe(module.returnInt32FromInt32(), 42);
+shouldBe(module.returnInt32FromDouble(), 4);
+shouldBe(module.returnInt32FromString(), 4);
+shouldBe(module.returnInt32FromBoolean(), 1);
+shouldBe(module.returnDoubleFromInt32(), 42);
+shouldBe(module.returnDoubleFromDouble(), 4.2);
+shouldBe(module.returnDoubleFromString(), 4.2);
+shouldBe(module.returnDoubleFromBoolean(), 1);
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWASMFunctionCompilerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WASMFunctionCompiler.h (189945 => 189946)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WASMFunctionCompiler.h        2015-09-17 23:53:58 UTC (rev 189945)
+++ trunk/Source/JavaScriptCore/wasm/WASMFunctionCompiler.h        2015-09-18 00:03:49 UTC (rev 189946)
</span><span class="lines">@@ -112,22 +112,26 @@
</span><span class="cx"> 
</span><span class="cx">         unsigned localIndex = 0;
</span><span class="cx">         for (size_t i = 0; i &lt; arguments.size(); ++i) {
</span><ins>+            // FIXME: No need to do type conversion if the caller is a WebAssembly function.
+            // https://bugs.webkit.org/show_bug.cgi?id=149310
</ins><span class="cx">             Address address(GPRInfo::callFrameRegister, CallFrame::argumentOffset(i) * sizeof(Register));
</span><del>-            switch (arguments[i]) {
-            case WASMType::I32:
</del><span class="cx"> #if USE(JSVALUE64)
</span><del>-                loadValueAndConvertToInt32(address, GPRInfo::regT0);
</del><ins>+            JSValueRegs valueRegs(GPRInfo::regT0);
</ins><span class="cx"> #else
</span><del>-                loadValueAndConvertToInt32(address, GPRInfo::regT0, GPRInfo::regT1);
</del><ins>+            JSValueRegs valueRegs(GPRInfo::regT1, GPRInfo::regT0);
</ins><span class="cx"> #endif
</span><ins>+            loadValue(address, valueRegs);
+            switch (arguments[i]) {
+            case WASMType::I32:
+                convertValueToInt32(valueRegs, GPRInfo::regT0);
</ins><span class="cx">                 store32(GPRInfo::regT0, localAddress(localIndex++));
</span><span class="cx">                 break;
</span><span class="cx">             case WASMType::F32:
</span><span class="cx">             case WASMType::F64:
</span><span class="cx"> #if USE(JSVALUE64)
</span><del>-                loadValueAndConvertToDouble(address, FPRInfo::fpRegT0, GPRInfo::regT0, GPRInfo::regT1);
</del><ins>+                convertValueToDouble(valueRegs, FPRInfo::fpRegT0, GPRInfo::regT1);
</ins><span class="cx"> #else
</span><del>-                loadValueAndConvertToDouble(address, FPRInfo::fpRegT0, GPRInfo::regT0, GPRInfo::regT1, GPRInfo::regT2, FPRInfo::fpRegT1);
</del><ins>+                convertValueToDouble(valueRegs, FPRInfo::fpRegT0, GPRInfo::regT2, FPRInfo::fpRegT1);
</ins><span class="cx"> #endif
</span><span class="cx">                 if (arguments[i] == WASMType::F32)
</span><span class="cx">                     convertDoubleToFloat(FPRInfo::fpRegT0, FPRInfo::fpRegT0);
</span><span class="lines">@@ -285,11 +289,7 @@
</span><span class="cx">             loadDouble(temporaryAddress(m_tempStackTop - 1), FPRInfo::fpRegT0);
</span><span class="cx">             if (returnType == WASMExpressionType::F32)
</span><span class="cx">                 convertFloatToDouble(FPRInfo::fpRegT0, FPRInfo::fpRegT0);
</span><del>-#if USE(JSVALUE64)
-            boxDouble(FPRInfo::fpRegT0, GPRInfo::returnValueGPR);
-#else
-            boxDouble(FPRInfo::fpRegT0, GPRInfo::returnValueGPR2, GPRInfo::returnValueGPR);
-#endif
</del><ins>+            convertDoubleToValue(FPRInfo::fpRegT0, returnValueRegs);
</ins><span class="cx">             m_tempStackTop--;
</span><span class="cx">             break;
</span><span class="cx">         case WASMExpressionType::Void:
</span><span class="lines">@@ -938,6 +938,11 @@
</span><span class="cx"> 
</span><span class="cx">         for (size_t i = 0; i &lt; argumentCount; ++i) {
</span><span class="cx">             Address address(GPRInfo::callFrameRegister, (stackOffset + CallFrame::argumentOffset(i)) * sizeof(Register));
</span><ins>+#if USE(JSVALUE64)
+            JSValueRegs valueRegs(GPRInfo::regT0);
+#else
+            JSValueRegs valueRegs(GPRInfo::regT1, GPRInfo::regT0);
+#endif
</ins><span class="cx">             switch (arguments[i]) {
</span><span class="cx">             case WASMType::I32:
</span><span class="cx">                 load32(temporaryAddress(m_tempStackTop - argumentCount + i), GPRInfo::regT0);
</span><span class="lines">@@ -949,6 +954,14 @@
</span><span class="cx">                 store32(TrustedImm32(JSValue::Int32Tag), address.withOffset(TagOffset));
</span><span class="cx"> #endif
</span><span class="cx">                 break;
</span><ins>+            case WASMType::F32:
+            case WASMType::F64:
+                loadDouble(temporaryAddress(m_tempStackTop - argumentCount + i), FPRInfo::fpRegT0);
+                if (arguments[i] == WASMType::F32)
+                    convertFloatToDouble(FPRInfo::fpRegT0, FPRInfo::fpRegT0);
+                convertDoubleToValue(FPRInfo::fpRegT0, valueRegs);
+                storeValue(valueRegs, address);
+                break;
</ins><span class="cx">             default:
</span><span class="cx">                 ASSERT_NOT_REACHED();
</span><span class="cx">             }
</span><span class="lines">@@ -988,10 +1001,29 @@
</span><span class="cx">         addPtr(TrustedImm32(-m_calleeSaveSpace - WTF::roundUpToMultipleOf(stackAlignmentRegisters(), m_stackHeight) * sizeof(StackSlot) - maxFrameExtentForSlowPathCall), GPRInfo::callFrameRegister, stackPointerRegister);
</span><span class="cx">         checkStackPointerAlignment();
</span><span class="cx"> 
</span><ins>+        // FIXME: No need to do type conversion if the callee is a WebAssembly function.
+        // https://bugs.webkit.org/show_bug.cgi?id=149310
+#if USE(JSVALUE64)
+        JSValueRegs valueRegs(GPRInfo::returnValueGPR);
+#else
+        JSValueRegs valueRegs(GPRInfo::returnValueGPR2, GPRInfo::returnValueGPR);
+#endif
</ins><span class="cx">         switch (returnType) {
</span><span class="cx">         case WASMExpressionType::I32:
</span><del>-            store32(GPRInfo::returnValueGPR, temporaryAddress(m_tempStackTop++));
</del><ins>+            convertValueToInt32(valueRegs, GPRInfo::regT0);
+            store32(GPRInfo::regT0, temporaryAddress(m_tempStackTop++));
</ins><span class="cx">             break;
</span><ins>+        case WASMExpressionType::F32:
+        case WASMExpressionType::F64:
+#if USE(JSVALUE64)
+            convertValueToDouble(valueRegs, FPRInfo::fpRegT0, GPRInfo::nonPreservedNonReturnGPR);
+#else
+            convertValueToDouble(valueRegs, FPRInfo::fpRegT0, GPRInfo::nonPreservedNonReturnGPR, FPRInfo::fpRegT1);
+#endif
+            if (returnType == WASMExpressionType::F32)
+                convertDoubleToFloat(FPRInfo::fpRegT0, FPRInfo::fpRegT0);
+            storeDouble(FPRInfo::fpRegT0, temporaryAddress(m_tempStackTop++));
+            break;
</ins><span class="cx">         case WASMExpressionType::Void:
</span><span class="cx">             break;
</span><span class="cx">         default:
</span><span class="lines">@@ -1000,69 +1032,72 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx"> #if USE(JSVALUE64)
</span><del>-    void loadValueAndConvertToInt32(Address address, GPRReg dst)
</del><ins>+    void convertValueToInt32(JSValueRegs valueRegs, GPRReg dst)
</ins><span class="cx">     {
</span><del>-        JSValueRegs tempRegs(dst);
-        loadValue(address, tempRegs);
-        Jump checkJSInt32 = branchIfInt32(tempRegs);
</del><ins>+        Jump checkJSInt32 = branchIfInt32(valueRegs);
</ins><span class="cx"> 
</span><del>-        callOperation(operationConvertJSValueToInt32, dst, dst);
</del><ins>+        callOperation(operationConvertJSValueToInt32, valueRegs.gpr(), valueRegs.gpr());
</ins><span class="cx"> 
</span><span class="cx">         checkJSInt32.link(this);
</span><ins>+        move(valueRegs.gpr(), dst);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    void loadValueAndConvertToDouble(Address address, FPRReg dst, GPRReg scratch1, GPRReg scratch2)
</del><ins>+    void convertValueToDouble(JSValueRegs valueRegs, FPRReg dst, GPRReg scratch)
</ins><span class="cx">     {
</span><del>-        JSValueRegs tempRegs(scratch1);
-        loadValue(address, tempRegs);
-        Jump checkJSInt32 = branchIfInt32(tempRegs);
-        Jump checkJSNumber = branchIfNumber(tempRegs, scratch2);
</del><ins>+        Jump checkJSInt32 = branchIfInt32(valueRegs);
+        Jump checkJSNumber = branchIfNumber(valueRegs, scratch);
</ins><span class="cx">         JumpList end;
</span><span class="cx"> 
</span><del>-        callOperation(operationConvertJSValueToDouble, tempRegs.gpr(), dst);
</del><ins>+        callOperation(operationConvertJSValueToDouble, valueRegs.gpr(), dst);
</ins><span class="cx">         end.append(jump());
</span><span class="cx"> 
</span><span class="cx">         checkJSInt32.link(this);
</span><del>-        convertInt32ToDouble(tempRegs.gpr(), dst);
</del><ins>+        convertInt32ToDouble(valueRegs.gpr(), dst);
</ins><span class="cx">         end.append(jump());
</span><span class="cx"> 
</span><span class="cx">         checkJSNumber.link(this);
</span><del>-        unboxDoubleWithoutAssertions(tempRegs.gpr(), dst);
</del><ins>+        unboxDoubleWithoutAssertions(valueRegs.gpr(), dst);
</ins><span class="cx">         end.link(this);
</span><span class="cx">     }
</span><span class="cx"> #else
</span><del>-    void loadValueAndConvertToInt32(Address address, GPRReg dst, GPRReg scratch)
</del><ins>+    void convertValueToInt32(JSValueRegs valueRegs, GPRReg dst)
</ins><span class="cx">     {
</span><del>-        JSValueRegs tempRegs(scratch, dst);
-        loadValue(address, tempRegs);
-        Jump checkJSInt32 = branchIfInt32(tempRegs);
</del><ins>+        Jump checkJSInt32 = branchIfInt32(valueRegs);
</ins><span class="cx"> 
</span><del>-        callOperation(operationConvertJSValueToInt32, tempRegs.tagGPR(), tempRegs.payloadGPR(), dst);
</del><ins>+        callOperation(operationConvertJSValueToInt32, valueRegs.tagGPR(), valueRegs.payloadGPR(), valueRegs.payloadGPR());
</ins><span class="cx"> 
</span><span class="cx">         checkJSInt32.link(this);
</span><ins>+        move(valueRegs.payloadGPR(), dst);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    void loadValueAndConvertToDouble(Address address, FPRReg dst, GPRReg scratch1, GPRReg scratch2, GPRReg scratch3, FPRReg fpScratch)
</del><ins>+    void convertValueToDouble(JSValueRegs valueRegs, FPRReg dst, GPRReg scratch, FPRReg fpScratch)
</ins><span class="cx">     {
</span><del>-        JSValueRegs tempRegs(scratch2, scratch1);
-        loadValue(address, tempRegs);
-        Jump checkJSInt32 = branchIfInt32(tempRegs);
-        Jump checkJSNumber = branchIfNumber(tempRegs, scratch3);
</del><ins>+        Jump checkJSInt32 = branchIfInt32(valueRegs);
+        Jump checkJSNumber = branchIfNumber(valueRegs, scratch);
</ins><span class="cx">         JumpList end;
</span><span class="cx"> 
</span><del>-        callOperation(operationConvertJSValueToDouble, tempRegs.tagGPR(), tempRegs.payloadGPR(), dst);
</del><ins>+        callOperation(operationConvertJSValueToDouble, valueRegs.tagGPR(), valueRegs.payloadGPR(), dst);
</ins><span class="cx">         end.append(jump());
</span><span class="cx"> 
</span><span class="cx">         checkJSInt32.link(this);
</span><del>-        convertInt32ToDouble(tempRegs.payloadGPR(), dst);
</del><ins>+        convertInt32ToDouble(valueRegs.payloadGPR(), dst);
</ins><span class="cx">         end.append(jump());
</span><span class="cx"> 
</span><span class="cx">         checkJSNumber.link(this);
</span><del>-        unboxDouble(tempRegs.tagGPR(), tempRegs.payloadGPR(), dst, fpScratch);
</del><ins>+        unboxDouble(valueRegs.tagGPR(), valueRegs.payloadGPR(), dst, fpScratch);
</ins><span class="cx">         end.link(this);
</span><span class="cx">     }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+    void convertDoubleToValue(FPRReg fpr, JSValueRegs valueRegs)
+    {
+#if USE(JSVALUE64)
+        boxDouble(fpr, valueRegs.gpr());
+#else
+        boxDouble(fpr, valueRegs.tagGPR(), valueRegs.payloadGPR());
+#endif
+    }
+
</ins><span class="cx">     JSWASMModule* m_module;
</span><span class="cx">     unsigned m_stackHeight;
</span><span class="cx">     unsigned m_numberOfLocals;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWASMFunctionParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WASMFunctionParser.cpp (189945 => 189946)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WASMFunctionParser.cpp        2015-09-17 23:53:58 UTC (rev 189945)
+++ trunk/Source/JavaScriptCore/wasm/WASMFunctionParser.cpp        2015-09-18 00:03:49 UTC (rev 189946)
</span><span class="lines">@@ -529,7 +529,7 @@
</span><span class="cx">         case WASMOpExpressionI32::GetGlobal:
</span><span class="cx">             return parseGetGlobalExpressionI32(context);
</span><span class="cx">         case WASMOpExpressionI32::CallInternal:
</span><del>-            return parseCallInternalExpressionI32(context);
</del><ins>+            return parseCallInternal(context, WASMExpressionType::I32);
</ins><span class="cx">         case WASMOpExpressionI32::CallIndirect:
</span><span class="cx">             return parseCallIndirect(context, WASMExpressionType::I32);
</span><span class="cx">         case WASMOpExpressionI32::CallImport:
</span><span class="lines">@@ -681,12 +681,6 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> template &lt;class Context&gt;
</span><del>-ContextExpression WASMFunctionParser::parseCallInternalExpressionI32(Context&amp; context)
-{
-    return parseCallInternal(context, WASMExpressionType::I32);
-}
-
-template &lt;class Context&gt;
</del><span class="cx"> ContextExpression WASMFunctionParser::parseUnaryExpressionI32(Context&amp; context, WASMOpExpressionI32 op)
</span><span class="cx"> {
</span><span class="cx">     ContextExpression expression = parseExpressionI32(context);
</span><span class="lines">@@ -752,6 +746,8 @@
</span><span class="cx">             return parseGetLocalExpressionF32(context);
</span><span class="cx">         case WASMOpExpressionF32::GetGlobal:
</span><span class="cx">             return parseGetGlobalExpressionF32(context);
</span><ins>+        case WASMOpExpressionF32::CallInternal:
+            return parseCallInternal(context, WASMExpressionType::F32);
</ins><span class="cx">         case WASMOpExpressionF32::CallIndirect:
</span><span class="cx">             return parseCallIndirect(context, WASMExpressionType::F32);
</span><span class="cx">         case WASMOpExpressionF32::Negate:
</span><span class="lines">@@ -771,7 +767,6 @@
</span><span class="cx">         case WASMOpExpressionF32::LoadWithOffset:
</span><span class="cx">         case WASMOpExpressionF32::Store:
</span><span class="cx">         case WASMOpExpressionF32::StoreWithOffset:
</span><del>-        case WASMOpExpressionF32::CallInternal:
</del><span class="cx">         case WASMOpExpressionF32::Conditional:
</span><span class="cx">         case WASMOpExpressionF32::Comma:
</span><span class="cx">         case WASMOpExpressionF32::FromS32:
</span><span class="lines">@@ -880,6 +875,8 @@
</span><span class="cx">             return parseGetLocalExpressionF64(context);
</span><span class="cx">         case WASMOpExpressionF64::GetGlobal:
</span><span class="cx">             return parseGetGlobalExpressionF64(context);
</span><ins>+        case WASMOpExpressionF64::CallInternal:
+            return parseCallInternal(context, WASMExpressionType::F64);
</ins><span class="cx">         case WASMOpExpressionF64::CallImport:
</span><span class="cx">             return parseCallImport(context, WASMExpressionType::F64);
</span><span class="cx">         case WASMOpExpressionF64::CallIndirect:
</span><span class="lines">@@ -890,7 +887,6 @@
</span><span class="cx">         case WASMOpExpressionF64::LoadWithOffset:
</span><span class="cx">         case WASMOpExpressionF64::Store:
</span><span class="cx">         case WASMOpExpressionF64::StoreWithOffset:
</span><del>-        case WASMOpExpressionF64::CallInternal:
</del><span class="cx">         case WASMOpExpressionF64::Conditional:
</span><span class="cx">         case WASMOpExpressionF64::Comma:
</span><span class="cx">         case WASMOpExpressionF64::FromS32:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWASMFunctionParserh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WASMFunctionParser.h (189945 => 189946)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WASMFunctionParser.h        2015-09-17 23:53:58 UTC (rev 189945)
+++ trunk/Source/JavaScriptCore/wasm/WASMFunctionParser.h        2015-09-18 00:03:49 UTC (rev 189946)
</span><span class="lines">@@ -89,7 +89,6 @@
</span><span class="cx">     template &lt;class Context&gt; ContextExpression parseGetLocalExpressionI32(Context&amp;, uint32_t localIndex);
</span><span class="cx">     template &lt;class Context&gt; ContextExpression parseGetLocalExpressionI32(Context&amp;);
</span><span class="cx">     template &lt;class Context&gt; ContextExpression parseGetGlobalExpressionI32(Context&amp;);
</span><del>-    template &lt;class Context&gt; ContextExpression parseCallInternalExpressionI32(Context&amp;);
</del><span class="cx">     template &lt;class Context&gt; ContextExpression parseUnaryExpressionI32(Context&amp;, WASMOpExpressionI32);
</span><span class="cx">     template &lt;class Context&gt; ContextExpression parseBinaryExpressionI32(Context&amp;, WASMOpExpressionI32);
</span><span class="cx">     template &lt;class Context&gt; ContextExpression parseRelationalI32ExpressionI32(Context&amp;, WASMOpExpressionI32);
</span></span></pre>
</div>
</div>

</body>
</html>