Bug 146064

Summary: JSC should natively support WebAssembly
Product: WebKit Reporter: Filip Pizlo <fpizlo>
Component: JavaScriptCoreAssignee: Keith Miller <keith_miller>
Status: NEW ---    
Severity: Normal CC: annulen, barraclough, basile_clement, benjamin, bfulgham, changseok, chi187, chris, clopez, commit-queue, cshankland, dbates, ehsan, ggaren, gyuyoung.kim, igor.oliveira, jfbastien, luke, mark.lam, mhahnenb, mike, mitz, mjs, mmirman, msaboff, nrotem, oliver, ossy, sam, sbarati, sukolsak, teppeis, utatane.tea, webkit-bug-importer, youennf
Priority: P2 Keywords: InRadar
Version: 528+ (Nightly build)   
Hardware: All   
OS: All   
Bug Depends on: 159775, 162706, 165164, 147212, 147222, 147293, 147393, 147738, 148333, 148373, 148734, 148737, 148772, 148791, 148793, 148838, 148882, 148913, 148934, 148945, 148998, 148999, 149031, 149033, 149051, 149062, 149065, 149080, 149093, 149100, 149102, 149200, 149203, 149206, 149240, 149247, 149254, 149326, 149340, 149383, 149395, 149411, 149425, 149451, 149454, 149486, 149919, 161569, 162884    
Bug Blocks:    
Attachments:
Description Flags
work in progress
none
work in progress, based on https://github.com/WebAssembly/polyfill-prototype-1
none
work in progress, based on https://github.com/WebAssembly/polyfill-prototype-1
none
Work in progress. Add support for some 64-bit floating-point operations.
none
Work in progress. Add initial support for calling internal functions.
none
Work in progress. Add support for calling JavaScript functions from WebAssembly functions and vice versa. Add initial support for importing and exporting functions.
none
Work in progress. Fix GC-related bugs.
none
Work in progress. Implement linear memory.
none
Work in progress. Implement all the linear memory operations and many mathematical operations.
none
Work in progress. First attempt at templatizing the parser. Add a stack height calculator.
none
Work in progress. Make a structural change.
none
Work in progress. Refactor the function parser. Remove WebAssemblyExecutable.
none
Work in progress. Change a lot of things.
none
Work in progress. Clean up the code.
none
Work in progress. Implement almost every instruction. Should be able to run any WASM files generated by Emscripten and pack-asmjs. none

Description Filip Pizlo 2015-06-17 09:07:29 PDT
WebAssembly (https://github.com/WebAssembly/design) is a new format for native programs on the web. It aims to support everything that asm.js supports, but allows the VM to sidestep the JS parsing and profiling pipeline entirely. This is a good thing for the VM - less work to support native code.

Although WebAssembly will have polyfill to asm.js, we should support it natively by:

- Having a WebAssembly baseline JIT that's used for fast start-up and some basic execution count profiling.
- An LLVM backend that uses the FTL's LLVM glue and compiler plan scheduling for hot code.

This standard has broad support, and we should continue to participate in discussions about how to make it great.

https://blog.mozilla.org/luke/2015/06/17/webassembly/
https://brendaneich.com/2015/06/from-asm-js-to-webassembly/
http://blogs.msdn.com/b/mikeholman/archive/2015/06/17/working-on-the-future-of-compile-to-web-applications.aspx
https://twitter.com/jfbastien/status/611201861245399041
Comment 1 Saam Barati 2015-06-17 18:06:52 PDT
I'm up for helping this this. This sounds great.
Comment 2 Filip Pizlo 2015-06-17 20:52:16 PDT
Here's a proposed implementation sketch:

We should start out by decoupling our work from ES6 modules. From our standpoint, a wasm blob produces a JSGlobalObject that has things hanging off of it. Those things are:

- The ArrayBuffer that is the wasm heap. Eventually this will be a special kind of ArrayBuffer, but initially it can just be an ArrayBuffer.
- Some JSFunction's that point to FunctionExecutables for all of the wasm functions.
- The CodeBlocks for those FunctionExecutables should contain something other than JSC bytecode. It should be either wasm directly, or our own 3AC (https://en.wikipedia.org/wiki/Three_address_code) bytecode that "unpacks" the wasm AST. I strongly recommend the former - wasm *should* be able to serve the same purposes as our bytecode would ordinarily serve for the purposes of establishing things like CodeOrigin and enabling OSR.
- Preparing a wasm CodeBlock for execution should mean executing a baseline JIT compile of the wasm. I recommend putting a wasm baseline JIT in a directory like JavaScriptCore/wasm. This baseline JIT should be the first thing we implement. It should be possible to implement it using a single unified codebase for all of the target architectures we will ever care about, by just carefully using the existing ABI logic in CCallHelpers and AssemblyHelpers.
- Wasm code should end up having a JITCode instance like any other CodeBlock that has been JITed. That JITCode instance should respond to all of the methods that JITCode should respond to, and this should be sufficient to allow calls from JS to wasm with zero overhead.
- To bootstrap and allow testing, jsc.cpp should allow for feeding in a wasm blob using a global function like loadWASM(data) or loadWASM(filename) or something. The result of the call should be the wasm JSGlobalObject. We should add a new test mode to run-jsc-stress-tests where a directory of .wasm files is turned into tests such that each .wasm file is automagically wrapped by a script that compiles it to binary form and then wraps it in a .js file that loads it and runs it.

This will get us to a point where we can execute wasm, have zero-cost wasm<->JS calls, and have a testing story.

Once we know that this works and we have a decent test suite, we should proceed to the LLVM optimizing JIT implementation. This would involve:

- Add ExecutionCounter profiling to the wasm baseline JIT code.
- Implement a second JIT that converts wasm to LLVM IR by reusing as much of the DFG::Plan, FTL::Output, FTL::compile, and FTL::link infrastructure as possible.
- Add OSR entry support, probably using the same style as we use for normal FTL OSR entry.

Note that initially we should probably implement the wasm top tier as a direct translation from wasm to LLVM IR. But, eventually, we'll need our own IR as an intermediate step, to aid support of things like heap bounds check removal and hoisting. LLVM will not be able to do these things, so we should do them ourselves. When we do these things, we should add OSR exit support as well. But I recommend first implementing a direct wasm->LLVM translation, even if we eventually have to toss this out the window. This translation layer *should* be very small anyway.

In the very near term, we should track the wasm spec and decide when it's a good time to start implementing a wasm parser. I strongly recommend implementing a SAX-style event-driven parser. Everything we'll want to do over wasm should involve a full pass over the wasm that is driven by the SAX-style parser. This should be functorized/templatized like crazy to enable super fast analyses in the baseline JIT. The baseline JIT will basically want to run one analysis to establish stack heights and then another analysis to dump code. The optimizing JIT will do a pass to generate IR. I'm not sure if the wasm binary spec is ready for the implementation of such a thing, but as soon as it is, we could start doing this. We should check what the V8 people are doing - I know that they have some public wasm code already; it would be totally cool to reuse their parser if it's BSD licensed.
Comment 3 Radar WebKit Bug Importer 2015-06-18 19:03:10 PDT
<rdar://problem/21454421>
Comment 4 Sukolsak Sakshuwong 2015-07-02 16:57:10 PDT
Created attachment 256051 [details]
work in progress
Comment 5 WebKit Commit Bot 2015-07-02 16:59:02 PDT
Attachment 256051 [details] did not pass style-queue:

ERROR: Source/JavaScriptCore/wasm/WasmOpcodes.h:286:  Missing spaces around |  [whitespace/operators] [3]
ERROR: Source/JavaScriptCore/wasm/WasmOpcodes.h:305:  Missing space before {  [whitespace/braces] [5]
ERROR: Source/JavaScriptCore/wasm/WasmOpcodes.h:305:  Missing space inside { }.  [whitespace/braces] [5]
ERROR: Source/JavaScriptCore/wasm/WasmOpcodes.h:305:  Should be indented on a separate line, with the colon or comma first on that line.  [whitespace/indent] [4]
ERROR: Source/JavaScriptCore/wasm/WasmOpcodes.h:312:  is_bad is incorrectly named. Don't use underscores in your identifier names.  [readability/naming/underscores] [4]
ERROR: Source/JavaScriptCore/wasm/WasmOpcodes.h:347:  The parameter name "ImmBits" adds no information, so it should be removed.  [readability/parameter_name] [5]
ERROR: Source/JavaScriptCore/wasm/WasmOpcodes.h:366:  Missing space inside { }.  [whitespace/braces] [5]
ERROR: Source/JavaScriptCore/wasm/WasmOpcodes.h:366:  Should be indented on a separate line, with the colon or comma first on that line.  [whitespace/indent] [4]
ERROR: Source/JavaScriptCore/wasm/WasmOpcodes.h:371:  is_bad is incorrectly named. Don't use underscores in your identifier names.  [readability/naming/underscores] [4]
ERROR: Source/JavaScriptCore/wasm/WasmOpcodes.h:400:  Missing space inside { }.  [whitespace/braces] [5]
ERROR: Source/JavaScriptCore/wasm/WasmOpcodes.h:401:  Missing space inside { }.  [whitespace/braces] [5]
ERROR: Source/JavaScriptCore/wasm/WasmOpcodes.h:401:  Should be indented on a separate line, with the colon or comma first on that line.  [whitespace/indent] [4]
ERROR: Source/JavaScriptCore/wasm/WasmOpcodes.h:402:  Missing space inside { }.  [whitespace/braces] [5]
ERROR: Source/JavaScriptCore/wasm/WasmOpcodes.h:402:  Should be indented on a separate line, with the colon or comma first on that line.  [whitespace/indent] [4]
ERROR: Source/JavaScriptCore/wasm/WasmOpcodes.h:403:  Missing space inside { }.  [whitespace/braces] [5]
ERROR: Source/JavaScriptCore/wasm/WasmOpcodes.h:403:  Should be indented on a separate line, with the colon or comma first on that line.  [whitespace/indent] [4]
ERROR: Source/JavaScriptCore/wasm/WasmOpcodes.h:409:  Place brace on its own line for function definitions.  [whitespace/braces] [4]
ERROR: Source/JavaScriptCore/wasm/WasmOpcodes.h:422:  Should be indented on a separate line, with the colon or comma first on that line.  [whitespace/indent] [4]
ERROR: Source/JavaScriptCore/wasm/WasmOpcodes.h:436:  The parameter name "u32" adds no information, so it should be removed.  [readability/parameter_name] [5]
ERROR: Source/JavaScriptCore/wasm/WasmOpcodes.h:515:  sign_extend is incorrectly named. Don't use underscores in your identifier names.  [readability/naming/underscores] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.h:44:  Should be indented on a separate line, with the colon or comma first on that line.  [whitespace/indent] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.h:74:  get_local is incorrectly named. Don't use underscores in your identifier names.  [readability/naming/underscores] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.h:75:  set_local is incorrectly named. Don't use underscores in your identifier names.  [readability/naming/underscores] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.h:76:  set_local is incorrectly named. Don't use underscores in your identifier names.  [readability/naming/underscores] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.h:77:  return_stmt is incorrectly named. Don't use underscores in your identifier names.  [readability/naming/underscores] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.h:78:  block_stmt is incorrectly named. Don't use underscores in your identifier names.  [readability/naming/underscores] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.h:79:  stmt_list is incorrectly named. Don't use underscores in your identifier names.  [readability/naming/underscores] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.h:80:  if_stmt is incorrectly named. Don't use underscores in your identifier names.  [readability/naming/underscores] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.h:81:  if_else_stmt is incorrectly named. Don't use underscores in your identifier names.  [readability/naming/underscores] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.h:82:  while_stmt is incorrectly named. Don't use underscores in your identifier names.  [readability/naming/underscores] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.h:83:  do_stmt is incorrectly named. Don't use underscores in your identifier names.  [readability/naming/underscores] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.h:84:  label_stmt is incorrectly named. Don't use underscores in your identifier names.  [readability/naming/underscores] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.h:85:  break_label_stmt is incorrectly named. Don't use underscores in your identifier names.  [readability/naming/underscores] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.h:86:  continue_label_stmt is incorrectly named. Don't use underscores in your identifier names.  [readability/naming/underscores] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.h:87:  switch_stmt is incorrectly named. Don't use underscores in your identifier names.  [readability/naming/underscores] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.h:89:  The parameter name "rType" adds no information, so it should be removed.  [readability/parameter_name] [5]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.h:90:  signed_expr is incorrectly named. Don't use underscores in your identifier names.  [readability/naming/underscores] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.h:91:  add_sub is incorrectly named. Don't use underscores in your identifier names.  [readability/naming/underscores] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.h:92:  mul_i32 is incorrectly named. Don't use underscores in your identifier names.  [readability/naming/underscores] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.h:93:  rel_i32 is incorrectly named. Don't use underscores in your identifier names.  [readability/naming/underscores] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.h:97:  Place brace on its own line for function definitions.  [whitespace/braces] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.h:101:  Place brace on its own line for function definitions.  [whitespace/braces] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.cpp:41:  Wrong number of spaces before statement. (expected: 8)  [whitespace/indent] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.cpp:42:  Wrong number of spaces before statement. (expected: 8)  [whitespace/indent] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.cpp:47:  Wrong number of spaces before statement. (expected: 8)  [whitespace/indent] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.cpp:48:  Wrong number of spaces before statement. (expected: 8)  [whitespace/indent] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.cpp:49:  Wrong number of spaces before statement. (expected: 8)  [whitespace/indent] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.cpp:144:  func_imp_i is incorrectly named. Don't use underscores in your identifier names.  [readability/naming/underscores] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.cpp:161:  num_i32_zero is incorrectly named. Don't use underscores in your identifier names.  [readability/naming/underscores] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.cpp:162:  num_f32_zero is incorrectly named. Don't use underscores in your identifier names.  [readability/naming/underscores] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.cpp:163:  num_f64_zero is incorrectly named. Don't use underscores in your identifier names.  [readability/naming/underscores] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.cpp:164:  num_i32_import is incorrectly named. Don't use underscores in your identifier names.  [readability/naming/underscores] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.cpp:165:  num_f32_import is incorrectly named. Don't use underscores in your identifier names.  [readability/naming/underscores] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.cpp:166:  num_f64_import is incorrectly named. Don't use underscores in your identifier names.  [readability/naming/underscores] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.cpp:174:  One line control clauses should not use braces.  [whitespace/braces] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.cpp:177:  One line control clauses should not use braces.  [whitespace/braces] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.cpp:180:  One line control clauses should not use braces.  [whitespace/braces] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.cpp:235:  num_elements is incorrectly named. Don't use underscores in your identifier names.  [readability/naming/underscores] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.cpp:254:  A case label should not be indented, but line up with its switch statement.  [whitespace/indent] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.cpp:258:  num_exports is incorrectly named. Don't use underscores in your identifier names.  [readability/naming/underscores] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.cpp:259:  export_index is incorrectly named. Don't use underscores in your identifier names.  [readability/naming/underscores] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.cpp:289:  A case label should not be indented, but line up with its switch statement.  [whitespace/indent] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.cpp:317:  One line control clauses should not use braces.  [whitespace/braces] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.cpp:321:  num_vars is incorrectly named. Don't use underscores in your identifier names.  [readability/naming/underscores] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.cpp:368:  More than one command on the same line  [whitespace/newline] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.cpp:414:  JITCompiler::get_local is incorrectly named. Don't use underscores in your identifier names.  [readability/naming/underscores] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.cpp:422:  JITCompiler::set_local is incorrectly named. Don't use underscores in your identifier names.  [readability/naming/underscores] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.cpp:429:  A case label should not be indented, but line up with its switch statement.  [whitespace/indent] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.cpp:441:  JITCompiler::set_local is incorrectly named. Don't use underscores in your identifier names.  [readability/naming/underscores] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.cpp:446:  JITCompiler::return_stmt is incorrectly named. Don't use underscores in your identifier names.  [readability/naming/underscores] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.cpp:450:  A case label should not be indented, but line up with its switch statement.  [whitespace/indent] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.cpp:467:  JITCompiler::stmt_list is incorrectly named. Don't use underscores in your identifier names.  [readability/naming/underscores] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.cpp:469:  num_stmts is incorrectly named. Don't use underscores in your identifier names.  [readability/naming/underscores] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.cpp:474:  JITCompiler::block_stmt is incorrectly named. Don't use underscores in your identifier names.  [readability/naming/underscores] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.cpp:479:  JITCompiler::if_stmt is incorrectly named. Don't use underscores in your identifier names.  [readability/naming/underscores] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.cpp:488:  JITCompiler::if_else_stmt is incorrectly named. Don't use underscores in your identifier names.  [readability/naming/underscores] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.cpp:500:  JITCompiler::while_stmt is incorrectly named. Don't use underscores in your identifier names.  [readability/naming/underscores] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.cpp:521:  JITCompiler::do_stmt is incorrectly named. Don't use underscores in your identifier names.  [readability/naming/underscores] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.cpp:543:  JITCompiler::label_stmt is incorrectly named. Don't use underscores in your identifier names.  [readability/naming/underscores] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.cpp:555:  JITCompiler::break_label_stmt is incorrectly named. Don't use underscores in your identifier names.  [readability/naming/underscores] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.cpp:561:  JITCompiler::continue_label_stmt is incorrectly named. Don't use underscores in your identifier names.  [readability/naming/underscores] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.cpp:567:  JITCompiler::switch_stmt is incorrectly named. Don't use underscores in your identifier names.  [readability/naming/underscores] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.cpp:585:  A case label should not be indented, but line up with its switch statement.  [whitespace/indent] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.cpp:627:  One line control clauses should not use braces.  [whitespace/braces] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.cpp:638:  i32_with_imm is incorrectly named. Don't use underscores in your identifier names.  [readability/naming/underscores] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.cpp:643:  One line control clauses should not use braces.  [whitespace/braces] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.cpp:647:  A case label should not be indented, but line up with its switch statement.  [whitespace/indent] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.cpp:770:  A case label should not be indented, but line up with its switch statement.  [whitespace/indent] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.cpp:786:  JITCompiler::signed_expr is incorrectly named. Don't use underscores in your identifier names.  [readability/naming/underscores] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.cpp:792:  One line control clauses should not use braces.  [whitespace/braces] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.cpp:794:  Should have a space between // and comment  [whitespace/comments] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.cpp:797:  Should have a space between // and comment  [whitespace/comments] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.cpp:798:  Should have a space between // and comment  [whitespace/comments] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.cpp:801:  Should have a space between // and comment  [whitespace/comments] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.cpp:802:  Should have a space between // and comment  [whitespace/comments] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.cpp:807:  JITCompiler::add_sub is incorrectly named. Don't use underscores in your identifier names.  [readability/naming/underscores] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.cpp:824:  JITCompiler::mul_i32 is incorrectly named. Don't use underscores in your identifier names.  [readability/naming/underscores] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.cpp:834:  JITCompiler::rel_i32 is incorrectly named. Don't use underscores in your identifier names.  [readability/naming/underscores] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.cpp:841:  Tests for true/false, null/non-null, and zero/non-zero should all be done without equality comparisons.  [readability/comparison_to_zero] [5]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.cpp:843:  Tests for true/false, null/non-null, and zero/non-zero should all be done without equality comparisons.  [readability/comparison_to_zero] [5]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.cpp:845:  Tests for true/false, null/non-null, a
nd zero/non-zero should all be done without equality comparisons.  [readability/comparison_to_zero] [5]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.cpp:847:  Tests for true/false, null/non-null, and zero/non-zero should all be done without equality comparisons.  [readability/comparison_to_zero] [5]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.cpp:849:  Tests for true/false, null/non-null, and zero/non-zero should all be done without equality comparisons.  [readability/comparison_to_zero] [5]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.cpp:851:  Tests for true/false, null/non-null, and zero/non-zero should all be done without equality comparisons.  [readability/comparison_to_zero] [5]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.cpp:853:  One line control clauses should not use braces.  [whitespace/braces] [4]
ERROR: Source/JavaScriptCore/wasm/WasmJITCompiler.cpp:855:  One line control clauses should not use braces.  [whitespace/braces] [4]
Total errors found: 106 in 6 files


If any of these errors are false positives, please file a bug against check-webkit-style.
Comment 6 Sukolsak Sakshuwong 2015-07-02 17:41:05 PDT
Created attachment 256055 [details]
work in progress, based on https://github.com/WebAssembly/polyfill-prototype-1
Comment 7 Sukolsak Sakshuwong 2015-07-02 22:47:20 PDT
Created attachment 256074 [details]
work in progress, based on https://github.com/WebAssembly/polyfill-prototype-1
Comment 8 Sukolsak Sakshuwong 2015-07-04 10:31:50 PDT
Created attachment 256153 [details]
Work in progress. Add support for some 64-bit floating-point operations.
Comment 9 Sukolsak Sakshuwong 2015-07-09 00:22:50 PDT
Created attachment 256466 [details]
Work in progress. Add initial support for calling internal functions.
Comment 10 Sukolsak Sakshuwong 2015-07-10 20:17:22 PDT
Created attachment 256641 [details]
Work in progress. Add support for calling JavaScript functions from WebAssembly functions and vice versa. Add initial support for importing and exporting functions.
Comment 11 Filip Pizlo 2015-07-10 21:52:45 PDT
I wonder if the reason why visitChildren on Wasm::Module isn't called is that the macro magic to build the method table doesn't like things that aren't directly in the JSC namespace.  Perhaps try to remove the Module from the Wasm namespace and see what happens?

Before you do that, you could just take a look at what the Wasm::Module::s_info looks like in the debugger.  Check if the visitChilren points at your visitChildren.
Comment 12 Sukolsak Sakshuwong 2015-07-11 11:23:46 PDT
Created attachment 256659 [details]
Work in progress. Fix GC-related bugs.
Comment 13 Sukolsak Sakshuwong 2015-07-13 03:24:27 PDT
Created attachment 256693 [details]
Work in progress. Implement linear memory.
Comment 14 Sukolsak Sakshuwong 2015-07-14 04:16:09 PDT
Created attachment 256765 [details]
Work in progress. Implement all the linear memory operations and many mathematical operations.
Comment 15 Sukolsak Sakshuwong 2015-07-15 12:43:17 PDT
Created attachment 256851 [details]
Work in progress. First attempt at templatizing the parser. Add a stack height calculator.
Comment 16 Sukolsak Sakshuwong 2015-07-16 03:28:47 PDT
Created attachment 256898 [details]
Work in progress. Make a structural change.
Comment 17 Sukolsak Sakshuwong 2015-07-20 05:35:53 PDT
Created attachment 257089 [details]
Work in progress. Refactor the function parser. Remove WebAssemblyExecutable.
Comment 18 Sukolsak Sakshuwong 2015-07-22 15:50:13 PDT
Created attachment 257303 [details]
Work in progress. Change a lot of things.
Comment 19 Sukolsak Sakshuwong 2015-07-23 04:22:19 PDT
Created attachment 257347 [details]
Work in progress. Clean up the code.
Comment 20 Sukolsak Sakshuwong 2015-08-05 04:45:10 PDT
Created attachment 258273 [details]
Work in progress. Implement almost every instruction. Should be able to run any WASM files generated by Emscripten and pack-asmjs.
Comment 21 Oliver Hunt 2015-09-09 12:27:12 PDT
Comment on attachment 258273 [details]
Work in progress. Implement almost every instruction. Should be able to run any WASM files generated by Emscripten and pack-asmjs.

View in context: https://bugs.webkit.org/attachment.cgi?id=258273&action=review

You need to turn the assertions into parse errors.

> Source/JavaScriptCore/runtime/Executable.cpp:267
> +        codeBlock->capabilityLevel();

Why this line?

> Source/JavaScriptCore/wasm/WASMCodeGenerator.h:278
> +            ASSERT_NOT_REACHED();

You can't trust input here, this should be an error return, not an assertion (neither debug, nor release)

> Source/JavaScriptCore/wasm/WASMCodeGenerator.h:328
> +            ASSERT_NOT_REACHED();

Ditto, you have to handle this error case

> Source/JavaScriptCore/wasm/WASMCodeGenerator.h:411
> +            ASSERT_NOT_REACHED();

ditto

> Source/JavaScriptCore/wasm/WASMCodeGenerator.h:442
> +            ASSERT_NOT_REACHED();

ditto

> Source/JavaScriptCore/wasm/WASMCodeGenerator.h:486
> +            ASSERT_NOT_REACHED();

ditto

> Source/JavaScriptCore/wasm/WASMCodeGenerator.h:519
> +            ASSERT_NOT_REACHED();

ditto

> Source/JavaScriptCore/wasm/WASMCodeGenerator.h:611
> +            ASSERT_NOT_REACHED();

ditto

> Source/JavaScriptCore/wasm/WASMCodeGenerator.h:678
> +            ASSERT_NOT_REACHED();

ditto

> Source/JavaScriptCore/wasm/WASMCodeGenerator.h:710
> +                ASSERT_NOT_REACHED();

ditto

> Source/JavaScriptCore/wasm/WASMCodeGenerator.h:768
> +            ASSERT_NOT_REACHED();

ditto

> Source/JavaScriptCore/wasm/WASMCodeGenerator.h:892
> +                ASSERT_NOT_REACHED();

ditto

> Source/JavaScriptCore/wasm/WASMCodeGenerator.h:955
> +            ASSERT_NOT_REACHED();

ditto

> Source/JavaScriptCore/wasm/WASMCodeGenerator.h:972
> +                ASSERT_NOT_REACHED();

ditto

> Source/JavaScriptCore/wasm/WASMCodeGenerator.h:1001
> +            ASSERT_NOT_REACHED();

ditto

> Source/JavaScriptCore/wasm/WASMFunctionParser.cpp:207
> +            RELEASE_ASSERT_NOT_REACHED();

This is a parse error, not a crash.
Comment 22 Sukolsak Sakshuwong 2015-09-21 16:07:45 PDT
(In reply to comment #21)
> Comment on attachment 258273 [details]
> Work in progress. Implement almost every instruction. Should be able to run
> any WASM files generated by Emscripten and pack-asmjs.
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=258273&action=review
> 
> You need to turn the assertions into parse errors.
> 
> > Source/JavaScriptCore/runtime/Executable.cpp:267
> > +        codeBlock->capabilityLevel();
> 
> Why this line?
> 
> > Source/JavaScriptCore/wasm/WASMCodeGenerator.h:278
> > +            ASSERT_NOT_REACHED();
> 
> You can't trust input here, this should be an error return, not an assertion
> (neither debug, nor release)

Thanks for the comments. This patch is obsolete. I rewrote it almost from beginning. In the current implementation, which has been checked in, the WASMReader class makes sure that the values that it reads are valid. We always use the READ_..._OR_FAIL(value, ...) pattern when we read a value from the user input.
Comment 23 Sukolsak Sakshuwong 2015-09-22 15:58:48 PDT
The baseline JIT for WebAssembly (polyfill-prototype-1 format[1]) is now complete. We should be able to run any WebAssembly file generated by pack-asmjs.[2]

Below are some very rough, unscientific benchmark results. All these JavaScript files are from PerformanceTests/JetStream/simple/. For each file, I extract the asm.js part, convert it into WebAssembly (polyfill-prototype-1 format) using pack-asmjs, and use loadWebAssembly() to load it. I disable the DFG JIT and the FTL JIT. (If I enable them, the results could be as much as 20x slower.) The reason that float-mm.c-wasm.js is slower than float-mm.c.js is likely that we use very inefficient float calculation in WASM. (We convert the operands to double and convert the result back to float.[3])

[1]: https://github.com/WebAssembly/polyfill-prototype-1
[2]: https://github.com/WebAssembly/polyfill-prototype-1/blob/master/src/pack-asmjs.cpp
[3]: https://bugs.webkit.org/show_bug.cgi?id=149102

--------------------

$ time ./jsc -f ~/benchmark/bigfib.cpp.js 

real	0m4.576s
user	0m4.497s
sys	0m0.067s

$ time ./jsc -f ~/benchmark/bigfib.cpp-wasm.js 

real	0m2.411s
user	0m2.349s
sys	0m0.056s

--------------------

$ time ./jsc -f ~/benchmark/container.cpp.js 

real	0m18.102s
user	0m18.003s
sys	0m0.064s

$ time ./jsc -f ~/benchmark/container.cpp-wasm.js 

real	0m12.808s
user	0m12.737s
sys	0m0.045s

--------------------

$ time ./jsc -f ~/benchmark/float-mm.c.js 

real	0m9.199s
user	0m9.149s
sys	0m0.032s

$ time ./jsc -f ~/benchmark/float-mm.c-wasm.js 

real	0m10.279s
user	0m10.225s
sys	0m0.031s

--------------------

$ time ./jsc -f ~/benchmark/n-body.c.js 
-0.169075164
-0.169083134

real	0m13.374s
user	0m13.312s
sys	0m0.038s

$ time ./jsc -f ~/benchmark/n-body.c-wasm.js 
-0.169075164
-0.169083134

real	0m6.556s
user	0m6.516s
sys	0m0.025s

--------------------

$ time ./jsc -f ~/benchmark/quicksort.c.js 

real	0m2.415s
user	0m2.391s
sys	0m0.016s

$ time ./jsc -f ~/benchmark/quicksort.c-wasm.js 

real	0m2.285s
user	0m2.259s
sys	0m0.019s

--------------------

$ time ./jsc -f ~/benchmark/towers.c.js 

real	0m2.484s
user	0m2.459s
sys	0m0.017s

$ time ./jsc -f ~/benchmark/towers.c-wasm.js 

real	0m1.443s
user	0m1.421s
sys	0m0.016s