Skip to content

Commit

Permalink
Merge pull request #47 from blendin/webgpudomato
Browse files Browse the repository at this point in the history
Add WebGPU Support
  • Loading branch information
ifratric authored Nov 15, 2024
2 parents 053714b + 1630782 commit ed35bfe
Show file tree
Hide file tree
Showing 10 changed files with 1,219 additions and 432 deletions.
6 changes: 5 additions & 1 deletion grammar.py
Original file line number Diff line number Diff line change
Expand Up @@ -970,7 +970,7 @@ def parse_from_string(self, grammar_str):

return 0

def parse_from_file(self, filename):
def parse_from_file(self, filename, extra=None):
"""Parses grammar from file.
Opens a text file, parses it and loads the grammar rules within.
Expand All @@ -991,6 +991,10 @@ def parse_from_file(self, filename):
print('Error reading ' + filename)
return 1
self._definitions_dir = os.path.dirname(filename)

if extra:
content = extra + content

return self.parse_from_string(content)

def _compute_interesting_indices(self):
Expand Down
12 changes: 12 additions & 0 deletions webgpu/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Simple WebGPU fuzzer

## Setup

1. Populate the `wgsl/` directory with wgsl scripts. I would recomment copying wgsl test files from [tint's tests](https://source.chromium.org/chromium/chromium/src/+/main:third_party/dawn/test/tint/bug/).
2. From here, the usage is the same as [vanilla Domato's](https://github.com/googleprojectzero/domato).

## Bugs
Chrome: [40063883](https://issues.chromium.org/u/0/issues/40063883), [40063356](https://issues.chromium.org/u/0/issues/40063356)

## Building Grammars
This repo also contains a helper script that can be used to assist in generating Domato grammars using Chrome's [WebIDL compiler](https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/bindings/scripts/web_idl/README.md;l=1?q=f:md%20web_idl&sq=). It is far from complete but may help others generate grammars faster.
Empty file removed webgpu/__init__.py
Empty file.
150 changes: 150 additions & 0 deletions webgpu/build_grammar.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
# Domato - example generator script
# --------------------------------------
#
# Written by Brendon Tiszka <[email protected]>
#
# Copyright 2017 Google Inc. All Rights Reserved.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import web_idl

# Path to your chromium build directory
PATH_TO_CHROME_BUILD_DIR = ""
web_idl_database_path = '/gen/third_party/blink/renderer/bindings/web_idl_database.pickle'
web_idl_database = web_idl.Database.read_from_file(PATH_TO_CHROME_BUILD_DIR + web_idl_database_path)

def is_gpu(ident):
if "GPU" in ident:
return True
return False

def is_promise(ident):
if "Promise" in ident:
return True
return False

def remove_promise_info(s):
if "OrNullPromise" in s:
return s[:s.index("OrNullPromise")]

if "Promise" in s:
return s[:s.index("Promise")]

return s

def parse_enums():
builder = ""

for enum in web_idl_database.enumerations:
if not is_gpu(enum.identifier):
continue

for value in enum.values:
builder += "<{}> = \"{}\"\n".format(enum.identifier, value)

builder += "\n"

return builder

def parse_namespaces():
builder = ""

for ns in web_idl_database.namespaces:
if not is_gpu(ns.identifier):
continue

for const in ns.constants:
builder += "<{}> = {}.{}\n".format(ns.identifier, ns.identifier, const.identifier)

builder += "\n"

return builder

def parse_dictionaries():
builder = ""

for dictionary in web_idl_database.dictionaries:
if not is_gpu(dictionary.identifier):
continue

print(dictionary.identifier)

def parse_interfaces():
builder = ""

for interface in web_idl_database.interfaces:
if not is_gpu(interface.identifier):
continue


builder += "#" + ("~"*16) + interface.identifier + ("~"*16) + "#\n"
for attribute in interface.attributes:
if attribute.is_readonly:
continue

builder += "<{}>.{} = <{}>".format(interface.identifier, attribute.identifier, attribute.idl_type.type_name)
builder += "\n"

for operation in interface.operations:
required_args = operation.num_of_required_arguments
num_args = len(operation.arguments)

lifted_args = []
for argument in operation.arguments:
lifted_args.append("<{}>".format(argument.idl_type.type_name))

for i in range(required_args, num_args + 1):
if operation.return_type.type_name != "Void":
return_type = remove_promise_info(operation.return_type.type_name)
builder += "<new {}> = ".format(return_type)

if is_promise(operation.return_type.type_name):
builder += "await "

builder += "<{}>.{}(".format(interface.identifier, operation.identifier)
builder += "{}".format(",".join(lifted_args[:i]))
builder += ");\n"

builder += "\n"
return builder


def parse_dictionaries():
builder = ""

for dictionary in web_idl_database.dictionaries:
if not is_gpu(dictionary.identifier):
continue


lifted_members = []
for member in dictionary.members:
lifted_members.append("{}: <{}>".format(member.identifier, member.idl_type.type_name))

builder += "<{}> = ".format(dictionary.identifier)
builder += "{ "
builder += ", ".join(lifted_members)
builder += " };"
builder += "\n"

return builder

if __name__ == "__main__":
enums = parse_enums()
namespaces = parse_namespaces()
interfaces = parse_interfaces()
dictionaries = parse_dictionaries()
print(enums)
print(namespaces)
print(interfaces)
print(dictionaries)
Loading

0 comments on commit ed35bfe

Please sign in to comment.