Merge branch 'gerben-fast-table' into fast-table
diff --git a/CMakeLists.txt b/CMakeLists.txt
index f7d6128..5e48701 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -64,7 +64,9 @@
   upb/port.c)
 add_library(upb
   upb/decode.c
+  upb/decode.int.h
   upb/decode_fast.c
+  upb/decode_fast.h
   upb/encode.c
   upb/msg.c
   upb/msg.h
diff --git a/generated_for_cmake/google/protobuf/descriptor.upb.c b/generated_for_cmake/google/protobuf/descriptor.upb.c
index 09642cc..4b5c92c 100644
--- a/generated_for_cmake/google/protobuf/descriptor.upb.c
+++ b/generated_for_cmake/google/protobuf/descriptor.upb.c
@@ -155,8 +155,8 @@
   },
   {
     UPB_SIZE(0, 0),
-    UPB_SIZE(1125908496777226, 2251808403619850),
-    UPB_SIZE(3377716900397074, 6755416620924946),
+    UPB_SIZE(1125899906973706, 2251799813816330),
+    UPB_SIZE(3377699720790034, 6755399441317906),
     UPB_SIZE(0, 0),
     UPB_SIZE(11258999068426274, 22517998136852514),
     UPB_SIZE(12384898975334442, 24769797950603306),
@@ -166,7 +166,7 @@
     UPB_SIZE(9007289449381962, 18014488704122954),
     UPB_SIZE(0, 0),
     UPB_SIZE(0, 0),
-    UPB_SIZE(5629533893951586, 11259033428164706),
+    UPB_SIZE(5629499534737506, 11258999068950626),
     UPB_SIZE(0, 0),
     UPB_SIZE(0, 0),
     UPB_SIZE(0, 0),
@@ -252,7 +252,7 @@
   },
   {
     UPB_SIZE(0, 0),
-    UPB_SIZE(1125908496777226, 2251808403619850),
+    UPB_SIZE(1125899906973706, 2251799813816330),
     UPB_SIZE(4503599627632658, 9007199255003154),
     UPB_SIZE(5629499534213146, 11258999068426266),
     UPB_SIZE(6755399441252386, 13510798882308130),
@@ -336,8 +336,8 @@
   },
   {
     UPB_SIZE(0, 0),
-    UPB_SIZE(1125908496777224, 1125908496777224),
-    UPB_SIZE(2251816993554448, 2251816993554448),
+    UPB_SIZE(1125899906973704, 1125899906973704),
+    UPB_SIZE(2251799813947408, 2251799813947408),
     UPB_SIZE(3377781324906522, 4503681231749146),
     UPB_SIZE(0, 0),
     UPB_SIZE(0, 0),
@@ -415,8 +415,8 @@
   },
   {
     UPB_SIZE(0, 0),
-    UPB_SIZE(1125908496777224, 1125908496777224),
-    UPB_SIZE(2251816993554448, 2251816993554448),
+    UPB_SIZE(1125899906973704, 1125899906973704),
+    UPB_SIZE(2251799813947408, 2251799813947408),
     UPB_SIZE(0, 0),
     UPB_SIZE(0, 0),
     UPB_SIZE(0, 0),
@@ -589,23 +589,23 @@
   },
   {
     UPB_SIZE(0, 0),
-    UPB_SIZE(10133374039490570, 11259273946333194),
-    UPB_SIZE(12385448731082770, 15763148451610642),
-    UPB_SIZE(6755433800794136, 6755433800794136),
-    UPB_SIZE(2251808403619872, 2251808403619872),
-    UPB_SIZE(4503616807239720, 4503616807239720),
-    UPB_SIZE(14637798300581938, 20267297834795058),
-    UPB_SIZE(16890697625894970, 24771996973793338),
+    UPB_SIZE(10133099165777930, 11258999072620554),
+    UPB_SIZE(12384898983657490, 15762598704185362),
+    UPB_SIZE(6755399441580056, 6755399441580056),
+    UPB_SIZE(2251799813816352, 2251799813816352),
+    UPB_SIZE(4503599627632680, 4503599627632680),
+    UPB_SIZE(14636698805731378, 20266198339944498),
+    UPB_SIZE(16888498636193850, 24769797984092218),
     UPB_SIZE(21392214194126914, 33777113169395778),
-    UPB_SIZE(7881368067375176, 7881368067375176),
-    UPB_SIZE(19144696462835794, 29277795624419410),
+    UPB_SIZE(7881299348947016, 7881299348947016),
+    UPB_SIZE(19140298483433554, 29273397645017170),
     UPB_SIZE(0, 0),
     UPB_SIZE(0, 0),
     UPB_SIZE(0, 0),
     UPB_SIZE(0, 0),
     UPB_SIZE(0, 0),
     UPB_SIZE(0, 0),
-    UPB_SIZE(9007336693694856, 9007336693694856),
+    UPB_SIZE(9007199256838536, 9007199256838536),
     UPB_SIZE(0, 0),
     UPB_SIZE(0, 0),
     UPB_SIZE(0, 0),
@@ -672,7 +672,7 @@
   },
   {
     UPB_SIZE(0, 0),
-    UPB_SIZE(1125908496777226, 2251808403619850),
+    UPB_SIZE(1125899906973706, 2251799813816330),
     UPB_SIZE(3377777029939218, 6755476750467090),
     UPB_SIZE(0, 0),
     UPB_SIZE(0, 0),
@@ -760,7 +760,7 @@
   },
   {
     UPB_SIZE(0, 0),
-    UPB_SIZE(1125908496777226, 2251808403619850),
+    UPB_SIZE(1125899906973706, 2251799813816330),
     UPB_SIZE(4503599627501586, 9007199254872082),
     UPB_SIZE(3377777030004762, 6755476750532634),
     UPB_SIZE(5629499534213154, 11258999068426274),
@@ -839,8 +839,8 @@
   },
   {
     UPB_SIZE(0, 0),
-    UPB_SIZE(1125908496777224, 1125908496777224),
-    UPB_SIZE(2251816993554448, 2251816993554448),
+    UPB_SIZE(1125899906973704, 1125899906973704),
+    UPB_SIZE(2251799813947408, 2251799813947408),
     UPB_SIZE(0, 0),
     UPB_SIZE(0, 0),
     UPB_SIZE(0, 0),
@@ -923,8 +923,8 @@
   },
   {
     UPB_SIZE(0, 0),
-    UPB_SIZE(2251816993554442, 2251816993554442),
-    UPB_SIZE(1125908496777232, 1125908496777232),
+    UPB_SIZE(2251799813947402, 2251799813947402),
+    UPB_SIZE(1125899906973712, 1125899906973712),
     UPB_SIZE(4503681231749146, 6755481045434394),
     UPB_SIZE(0, 0),
     UPB_SIZE(0, 0),
@@ -1008,7 +1008,7 @@
   },
   {
     UPB_SIZE(0, 0),
-    UPB_SIZE(1125908496777226, 2251808403619850),
+    UPB_SIZE(1125899906973706, 2251799813816330),
     UPB_SIZE(4503599627370514, 9007199254741010),
     UPB_SIZE(3377777030004762, 6755476750532634),
     UPB_SIZE(0, 0),
@@ -1095,12 +1095,12 @@
   },
   {
     UPB_SIZE(0, 0),
-    UPB_SIZE(1125934266581002, 2251834173423626),
-    UPB_SIZE(3377768440004626, 6755468160532498),
-    UPB_SIZE(5629636973166618, 11259136507379738),
+    UPB_SIZE(1125899907366922, 2251799814209546),
+    UPB_SIZE(3377699721576466, 6755399442104338),
+    UPB_SIZE(5629499536310298, 11258999070523418),
     UPB_SIZE(7881393837178914, 15762693185077282),
-    UPB_SIZE(281483566645288, 281483566645288),
-    UPB_SIZE(562967133290544, 562967133290544),
+    UPB_SIZE(281474976841768, 281474976841768),
+    UPB_SIZE(562949953683504, 562949953683504),
     UPB_SIZE(0, 0),
     UPB_SIZE(0, 0),
     UPB_SIZE(0, 0),
@@ -1197,37 +1197,37 @@
   },
   {
     UPB_SIZE(0, 0),
-    UPB_SIZE(7890095440920586, 9015995347763210),
+    UPB_SIZE(7881299482116106, 9007199388958730),
     UPB_SIZE(0, 0),
     UPB_SIZE(0, 0),
     UPB_SIZE(0, 0),
     UPB_SIZE(0, 0),
     UPB_SIZE(0, 0),
     UPB_SIZE(0, 0),
-    UPB_SIZE(10150691347628098, 13528391068155970),
-    UPB_SIZE(2251808403619912, 2251808403619912),
-    UPB_SIZE(4503616807239760, 4503616807239760),
-    UPB_SIZE(12420083347357786, 18049582881570906),
+    UPB_SIZE(10133099430019138, 13510799150547010),
+    UPB_SIZE(2251799813816392, 2251799813816392),
+    UPB_SIZE(4503599627632720, 4503599627632720),
+    UPB_SIZE(12384899512139866, 18014399046352986),
     UPB_SIZE(0, 0),
     UPB_SIZE(0, 0),
     UPB_SIZE(0, 0),
     UPB_SIZE(0, 0),
-    UPB_SIZE(4785108963819904, 4785108963819904),
-    UPB_SIZE(5066618300268936, 5066618300268936),
-    UPB_SIZE(5348161996456336, 5348161996456336),
+    UPB_SIZE(4785074604605824, 4785074604605824),
+    UPB_SIZE(5066549581840776, 5066549581840776),
+    UPB_SIZE(5348024559600016, 5348024559600016),
     UPB_SIZE(0, 0),
-    UPB_SIZE(5629774412120480, 5629774412120480),
+    UPB_SIZE(5629499538407840, 5629499538407840),
     UPB_SIZE(0, 0),
     UPB_SIZE(0, 0),
-    UPB_SIZE(5911524266738104, 5911524266738104),
+    UPB_SIZE(5910974519312824, 5910974519312824),
     UPB_SIZE(0, 0),
     UPB_SIZE(0, 0),
     UPB_SIZE(0, 0),
-    UPB_SIZE(6193548999262680, 6193548999262680),
+    UPB_SIZE(6192449504412120, 6192449504412120),
     UPB_SIZE(0, 0),
     UPB_SIZE(0, 0),
     UPB_SIZE(0, 0),
-    UPB_SIZE(6476123487601144, 6476123487601144),
+    UPB_SIZE(6473924497900024, 6473924497900024),
   },
   &google_protobuf_FileOptions_submsgs[0],
   &google_protobuf_FileOptions__fields[0],
@@ -1283,13 +1283,13 @@
   },
   {
     UPB_SIZE(0, 0),
-    UPB_SIZE(281483566645256, 281483566645256),
-    UPB_SIZE(562967133290512, 562967133290512),
-    UPB_SIZE(844459289870360, 844459289870360),
+    UPB_SIZE(281474976841736, 281474976841736),
+    UPB_SIZE(562949953683472, 562949953683472),
+    UPB_SIZE(844424930656280, 844424930656280),
     UPB_SIZE(0, 0),
     UPB_SIZE(0, 0),
     UPB_SIZE(0, 0),
-    UPB_SIZE(1125968626319416, 1125968626319416),
+    UPB_SIZE(1125899907891256, 1125899907891256),
     UPB_SIZE(0, 0),
     UPB_SIZE(0, 0),
     UPB_SIZE(0, 0),
@@ -1371,16 +1371,16 @@
   },
   {
     UPB_SIZE(0, 0),
-    UPB_SIZE(2251808403619848, 2251808403619848),
-    UPB_SIZE(6755433800794128, 6755433800794128),
-    UPB_SIZE(7036943137243160, 7036943137243160),
+    UPB_SIZE(2251799813816328, 2251799813816328),
+    UPB_SIZE(6755399441580048, 6755399441580048),
+    UPB_SIZE(7036874418815000, 7036874418815000),
     UPB_SIZE(0, 0),
-    UPB_SIZE(7318486833430568, 7318486833430568),
-    UPB_SIZE(4503616807239728, 4503616807239728),
+    UPB_SIZE(7318349396574248, 7318349396574248),
+    UPB_SIZE(4503599627632688, 4503599627632688),
     UPB_SIZE(0, 0),
     UPB_SIZE(0, 0),
     UPB_SIZE(0, 0),
-    UPB_SIZE(7600099249094736, 7600099249094736),
+    UPB_SIZE(7599824375382096, 7599824375382096),
     UPB_SIZE(0, 0),
     UPB_SIZE(0, 0),
     UPB_SIZE(0, 0),
@@ -1538,8 +1538,8 @@
   {
     UPB_SIZE(0, 0),
     UPB_SIZE(0, 0),
-    UPB_SIZE(281483566645264, 281483566645264),
-    UPB_SIZE(562967133290520, 562967133290520),
+    UPB_SIZE(281474976841744, 281474976841744),
+    UPB_SIZE(562949953683480, 562949953683480),
     UPB_SIZE(0, 0),
     UPB_SIZE(0, 0),
     UPB_SIZE(0, 0),
@@ -1620,7 +1620,7 @@
   },
   {
     UPB_SIZE(0, 0),
-    UPB_SIZE(281483566645256, 281483566645256),
+    UPB_SIZE(281474976841736, 281474976841736),
     UPB_SIZE(0, 0),
     UPB_SIZE(0, 0),
     UPB_SIZE(0, 0),
@@ -1877,12 +1877,12 @@
     UPB_SIZE(0, 0),
     UPB_SIZE(0, 0),
     UPB_SIZE(15762598695796754, 22517998136852498),
-    UPB_SIZE(9007267974217754, 9007267974217754),
-    UPB_SIZE(2251808403619872, 2251808403619872),
-    UPB_SIZE(4503616807239720, 4503616807239720),
+    UPB_SIZE(9007199255789594, 9007199255789594),
+    UPB_SIZE(2251799813816352, 2251799813816352),
+    UPB_SIZE(4503599627632680, 4503599627632680),
     UPB_SIZE(0, 0),
-    UPB_SIZE(11259136507379770, 13510936321065018),
-    UPB_SIZE(13511073760018498, 18014673387388994),
+    UPB_SIZE(11258999070523450, 13510798884208698),
+    UPB_SIZE(13510798886305858, 18014398513676354),
     UPB_SIZE(0, 0),
     UPB_SIZE(0, 0),
     UPB_SIZE(0, 0),
@@ -1954,8 +1954,8 @@
   },
   {
     UPB_SIZE(0, 0),
-    UPB_SIZE(1125917086711818, 2251816993554442),
-    UPB_SIZE(281483566645264, 281483566645264),
+    UPB_SIZE(1125899907104778, 2251799813947402),
+    UPB_SIZE(281474976841744, 281474976841744),
     UPB_SIZE(0, 0),
     UPB_SIZE(0, 0),
     UPB_SIZE(0, 0),
@@ -2120,8 +2120,8 @@
     UPB_SIZE(0, 0),
     UPB_SIZE(0, 0),
     UPB_SIZE(0, 0),
-    UPB_SIZE(1125908496777242, 2251808403619866),
-    UPB_SIZE(3377716900397090, 6755416620924962),
+    UPB_SIZE(1125899906973722, 2251799813816346),
+    UPB_SIZE(3377699720790050, 6755399441317922),
     UPB_SIZE(0, 0),
     UPB_SIZE(0, 0),
     UPB_SIZE(0, 0),
@@ -2282,9 +2282,9 @@
   {
     UPB_SIZE(0, 0),
     UPB_SIZE(0, 0),
-    UPB_SIZE(3377734080266258, 4503633987108882),
-    UPB_SIZE(1125908496777240, 1125908496777240),
-    UPB_SIZE(2251816993554464, 2251816993554464),
+    UPB_SIZE(3377699721052178, 4503599627894802),
+    UPB_SIZE(1125899906973720, 1125899906973720),
+    UPB_SIZE(2251799813947424, 2251799813947424),
     UPB_SIZE(0, 0),
     UPB_SIZE(0, 0),
     UPB_SIZE(0, 0),
diff --git a/upbc/generator.cc b/upbc/generator.cc
index 02a9da5..da0149c 100644
--- a/upbc/generator.cc
+++ b/upbc/generator.cc
@@ -791,13 +791,13 @@
   uint16_t expected_tag = (num << 3) | wire_type;
   if (num > 15) expected_tag |= 0x100;
   MessageLayout::Size offset = layout.GetFieldOffset(field);
-  uint64_t hasbit_index = 0;
+  uint64_t hasbit_index = 0;  // Zero means no hasbits.
 
   if (layout.HasHasbit(field)) {
     hasbit_index = layout.GetHasbitIndex(field);
     if (hasbit_index > 31) return;
     // thas hasbits mask in the parser occupies bits 16-48
-    // in the 64 bit register.
+    // in the 64 bit register. 
     hasbit_index += 16;  // account for the shifted hasbits
   }
 
@@ -812,9 +812,9 @@
     data.size32 |= idx << 16 | hasbit_index << 32;
     data.size64 |= idx << 16 | hasbit_index << 32;
   } else {
-    uint32_t hasbit_mask = 1U << hasbit_index;
-    data.size32 |= (uint64_t)hasbit_mask << 16;
-    data.size64 |= (uint64_t)hasbit_mask << 16;
+    uint64_t hasbit_mask = (1ull << hasbit_index) & -0x10000;
+    data.size32 |= (uint64_t)hasbit_mask;
+    data.size64 |= (uint64_t)hasbit_mask;
   }