WSL doesn't need to wrap primitives like ints and floats in specialized classes like...
authorfpizlo@apple.com <fpizlo@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 31 Aug 2017 21:50:57 +0000 (21:50 +0000)
committerfpizlo@apple.com <fpizlo@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 31 Aug 2017 21:50:57 +0000 (21:50 +0000)
https://bugs.webkit.org/show_bug.cgi?id=176184

Reviewed by Saam Barati.

The only use for EInt and EFloat was that users of the interpreter want to be able to reason
about values that know their type. But for the actual interpreter, it makes most sense for
EBuffer to hold values directly - for example, ints in the case of values of type int. Then,
all of the logic of doing math on those things can be implemented in Intrinsics.js.

So, this removes EInt and EFloat but introduces a new TypedValue class that is used only on the
boundary of the interpreter. You can either use the interpreter by speaking its internal
language (EPtr to an EBuffer that has the values) or by using the simple API (which uses
TypedValue as a trade-off between power and convenience).

* WebGPUShadingLanguageRI/All.js:
* WebGPUShadingLanguageRI/CallFunction.js:
(callFunction):
* WebGPUShadingLanguageRI/EFloat.js: Removed.
* WebGPUShadingLanguageRI/EInt.js: Removed.
* WebGPUShadingLanguageRI/EPtr.js:
(EPtr.box):
* WebGPUShadingLanguageRI/Evaluator.js:
(Evaluator.prototype.visitIntLiteral):
* WebGPUShadingLanguageRI/Intrinsics.js:
(Intrinsics):
* WebGPUShadingLanguageRI/Test.js:
(makeInt):
(checkInt):
(TEST_add1):
(TEST_simpleGeneric):
(TEST_simpleAssignment):
(TEST_simpleDefault):
* WebGPUShadingLanguageRI/TypedValue.js: Added.
(TypedValue):
(TypedValue.prototype.toString):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@221446 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Tools/ChangeLog
Tools/WebGPUShadingLanguageRI/All.js
Tools/WebGPUShadingLanguageRI/CallFunction.js
Tools/WebGPUShadingLanguageRI/EInt.js [deleted file]
Tools/WebGPUShadingLanguageRI/EPtr.js
Tools/WebGPUShadingLanguageRI/Evaluator.js
Tools/WebGPUShadingLanguageRI/Intrinsics.js
Tools/WebGPUShadingLanguageRI/Test.js
Tools/WebGPUShadingLanguageRI/TypedValue.js [moved from Tools/WebGPUShadingLanguageRI/EFloat.js with 84% similarity]

index fbf1452..1dce998 100644 (file)
@@ -1,3 +1,42 @@
+2017-08-31  Filip Pizlo  <fpizlo@apple.com>
+
+        WSL doesn't need to wrap primitives like ints and floats in specialized classes like EInt and EFloat
+        https://bugs.webkit.org/show_bug.cgi?id=176184
+
+        Reviewed by Saam Barati.
+        
+        The only use for EInt and EFloat was that users of the interpreter want to be able to reason
+        about values that know their type. But for the actual interpreter, it makes most sense for
+        EBuffer to hold values directly - for example, ints in the case of values of type int. Then,
+        all of the logic of doing math on those things can be implemented in Intrinsics.js.
+        
+        So, this removes EInt and EFloat but introduces a new TypedValue class that is used only on the
+        boundary of the interpreter. You can either use the interpreter by speaking its internal
+        language (EPtr to an EBuffer that has the values) or by using the simple API (which uses
+        TypedValue as a trade-off between power and convenience).
+
+        * WebGPUShadingLanguageRI/All.js:
+        * WebGPUShadingLanguageRI/CallFunction.js:
+        (callFunction):
+        * WebGPUShadingLanguageRI/EFloat.js: Removed.
+        * WebGPUShadingLanguageRI/EInt.js: Removed.
+        * WebGPUShadingLanguageRI/EPtr.js:
+        (EPtr.box):
+        * WebGPUShadingLanguageRI/Evaluator.js:
+        (Evaluator.prototype.visitIntLiteral):
+        * WebGPUShadingLanguageRI/Intrinsics.js:
+        (Intrinsics):
+        * WebGPUShadingLanguageRI/Test.js:
+        (makeInt):
+        (checkInt):
+        (TEST_add1):
+        (TEST_simpleGeneric):
+        (TEST_simpleAssignment):
+        (TEST_simpleDefault):
+        * WebGPUShadingLanguageRI/TypedValue.js: Added.
+        (TypedValue):
+        (TypedValue.prototype.toString):
+
 2017-08-31  David Quesada  <david_quesada@apple.com>
 
         WKNavigationDelegatePrivate client redirect SPI needs to be able to detect redirects scheduled before the document finishes loading
index b71c212..b107caf 100644 (file)
@@ -47,8 +47,6 @@ load("CommaExpression.js");
 load("ConstexprTypeParameter.js");
 load("EBuffer.js");
 load("EBufferBuilder.js");
-load("EFloat.js");
-load("EInt.js");
 load("EPtr.js");
 load("EvaluationCommon.js");
 load("Evaluator.js");
@@ -92,6 +90,7 @@ load("TypeDefResolver.js");
 load("TypeOrVariableRef.js");
 load("TypeRef.js");
 load("TypeVariable.js");
+load("TypedValue.js");
 load("UnificationContext.js");
 load("VariableDecl.js");
 load("VariableRef.js");
index a5bb5b0..6cd06e2 100644 (file)
@@ -41,9 +41,11 @@ function callFunctionByRef(program, name, typeArguments, argumentList)
     return new Evaluator(program).visitFunctionBody(func.body);
 }
 
+// This uses the simplified TypedValue object for wrapping values like integers and doubles.
 function callFunction(program, name, typeArguments, argumentList)
 {
-    return callFunctionByRef(
+    let result = callFunctionByRef(
         program, name, typeArguments,
-        argumentList.map(argument => EPtr.box(argument))).loadValue();
+        argumentList.map(argument => EPtr.box(argument.type, argument.value)));
+    return new TypedValue(result.type.elementType, result.loadValue());
 }
diff --git a/Tools/WebGPUShadingLanguageRI/EInt.js b/Tools/WebGPUShadingLanguageRI/EInt.js
deleted file mode 100644 (file)
index 16cd6e1..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-"use strict";
-
-class EInt extends EValue {
-    constructor(type, value)
-    {
-        super(type);
-        this._value = value;
-    }
-    
-    get value() { return this._value; }
-    
-    add(other)
-    {
-        return new EInt(this.type, (this.value + other.value) | 0);
-    }
-    
-    toString()
-    {
-        return "" + this.value;
-    }
-}
-
index a173ec7..42574b1 100644 (file)
@@ -39,13 +39,13 @@ class EPtr extends EValue {
     // function is here to help.
     //
     // In a real execution environment, uses of this manifest as SSA temporaries.
-    static box(value)
+    static box(type, value)
     {
-        if (!value.type)
-            throw new Error("Value has no type: " + value);
+        if (!type || !value)
+            throw new Error("Need both type and value");
         let buffer = new EBuffer(1);
         buffer.set(0, value);
-        return new EPtr(new PtrType(null, "thread", value.type), buffer, 0);
+        return new EPtr(new PtrType(null, "thread", type), buffer, 0);
     }
     
     get buffer() { return this._buffer; }
index ba22c7b..be990f6 100644 (file)
@@ -89,7 +89,7 @@ class Evaluator extends Visitor {
     
     visitIntLiteral(node)
     {
-        return EPtr.box(new EInt(this._program.intrinsics.int32, node.value));
+        return EPtr.box(this._program.intrinsics.int32, node.value);
     }
     
     visitCallExpression(node)
index 27e68a9..36eed63 100644 (file)
@@ -47,7 +47,7 @@ class Intrinsics {
             (type) => {
                 this.int32 = type;
                 type.size = 1;
-                type.populateDefaultValue = (buffer, offset) => buffer.set(offset, new EInt(type, 0));
+                type.populateDefaultValue = (buffer, offset) => buffer.set(offset, 0);
             });
 
         this._map.set(
@@ -55,15 +55,14 @@ class Intrinsics {
             (type) => {
                 this.double = type;
                 type.size = 1;
-                type.populateDefaultValue =
-                    (buffer, offset) => buffer.set(offset, new EFloat(type, 0));
+                type.populateDefaultValue = (buffer, offset) => buffer.set(offset, 0);
             });
         
         this._map.set(
             "native int operator+<>(int,int)",
             (func) => {
                 func.implementation =
-                    ([left, right]) => EPtr.box(left.loadValue().add(right.loadValue()));
+                    ([left, right]) => EPtr.box(this.int32, (left.loadValue() + right.loadValue()) | 0);
             });
     }
     
index 6aa44f2..eddeaaa 100644 (file)
@@ -33,12 +33,12 @@ function doPrep(code)
 
 function makeInt(program, value)
 {
-    return new EInt(program.intrinsics.int32, value);
+    return new TypedValue(program.intrinsics.int32, value);
 }
 
-function checkInt(result, expected)
+function checkInt(program, result, expected)
 {
-    if (!(result instanceof EInt))
+    if (result.type != program.intrinsics.int32)
         throw new Error("Wrong result type; result: " + result);
     if (result.value != expected)
         throw new Error("Wrong result: " + result + " (expected " + expected + ")");
@@ -60,14 +60,14 @@ function checkFail(callback, predicate)
 
 function TEST_add1() {
     let program = doPrep("int foo(int x) { return x + 1; }");
-    checkInt(callFunction(program, "foo", [], [makeInt(program, 42)]), 43);
+    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 42)]), 43);
 }
 
 function TEST_simpleGeneric() {
     let program = doPrep(`
         T id<T>(T x) { return x; }
         int foo(int x) { return id(x) + 1; }`);
-    checkInt(callFunction(program, "foo", [], [makeInt(program, 42)]), 43);
+    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 42)]), 43);
 }
 
 function TEST_nameResolutionFailure()
@@ -85,7 +85,7 @@ function TEST_simpleVariable()
             int result = p;
             return result;
         }`);
-    checkInt(callFunction(program, "foo", [], [makeInt(program, 42)]), 42);
+    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 42)]), 42);
 }
 
 function TEST_simpleAssignment()
@@ -97,7 +97,7 @@ function TEST_simpleAssignment()
             result = p;
             return result;
         }`);
-    checkInt(callFunction(program, "foo", [], [makeInt(program, 42)]), 42);
+    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 42)]), 42);
 }
 
 function TEST_simpleDefault()
@@ -108,7 +108,7 @@ function TEST_simpleDefault()
             int result;
             return result;
         }`);
-    checkInt(callFunction(program, "foo", [], []), 0);
+    checkInt(program, callFunction(program, "foo", [], []), 0);
 }
 
 let before = preciseTime();
similarity index 84%
rename from Tools/WebGPUShadingLanguageRI/EFloat.js
rename to Tools/WebGPUShadingLanguageRI/TypedValue.js
index 4d13a5f..c1a6ffc 100644 (file)
  */
 "use strict";
 
-class EFloat extends EValue {
+class TypedValue {
     constructor(type, value)
     {
-        super(type);
-        this._value = value;
-    }
-    
-    get value() { return this._value; }
-    
-    add(other)
-    {
-        return new EFloat(this.type, this.value + other.value);
+        this.type = type;
+        this.value = value;
     }
     
     toString()
     {
-        return "" + this.value;
+        return this.type + "(" + this.value + ")";
     }
 }
-