LLInt offsets extractor should be able to handle C++ constexprs
authorkeith_miller@apple.com <keith_miller@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 30 Jul 2017 03:01:12 +0000 (03:01 +0000)
committerkeith_miller@apple.com <keith_miller@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 30 Jul 2017 03:01:12 +0000 (03:01 +0000)
https://bugs.webkit.org/show_bug.cgi?id=174964

Reviewed by Saam Barati.

This patch adds new syntax to the offline asm language. The new keyword,
constexpr, takes the subsequent identifier and maps it to a C++ constexpr
expression. Additionally, if the value is not an identifier you can wrap it in
parentheses. e.g. constexpr (myConstexprFunction() + OBJECT_OFFSET(Foo, bar)),
which will get converted into:
static_cast<int64_t>(myConstexprFunction() + OBJECT_OFFSET(Foo, bar));

This patch also changes the data format the LLIntOffsetsExtractor
binary produces.  Previously, it would produce unsigned values,
after this patch every value is an int64_t.  Using an int64_t is
useful because it means that we can represent any constant needed.
int32_t masks are sign extended then passed then converted to a
negative literal sting in the assembler so it will be the constant
expected.

* llint/LLIntOffsetsExtractor.cpp:
(JSC::LLIntOffsetsExtractor::dummy):
* llint/LowLevelInterpreter.asm:
* llint/LowLevelInterpreter64.asm:
* offlineasm/asm.rb:
* offlineasm/ast.rb:
* offlineasm/generate_offset_extractor.rb:
* offlineasm/offsets.rb:
* offlineasm/parser.rb:
* offlineasm/transform.rb:

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

Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/llint/LLIntOffsetsExtractor.cpp
Source/JavaScriptCore/llint/LowLevelInterpreter.asm
Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
Source/JavaScriptCore/offlineasm/asm.rb
Source/JavaScriptCore/offlineasm/ast.rb
Source/JavaScriptCore/offlineasm/generate_offset_extractor.rb
Source/JavaScriptCore/offlineasm/offsets.rb
Source/JavaScriptCore/offlineasm/parser.rb
Source/JavaScriptCore/offlineasm/transform.rb

index f58d1ae..51e4c55 100644 (file)
@@ -1,3 +1,36 @@
+2017-07-29  Keith Miller  <keith_miller@apple.com>
+
+        LLInt offsets extractor should be able to handle C++ constexprs
+        https://bugs.webkit.org/show_bug.cgi?id=174964
+
+        Reviewed by Saam Barati.
+
+        This patch adds new syntax to the offline asm language. The new keyword,
+        constexpr, takes the subsequent identifier and maps it to a C++ constexpr
+        expression. Additionally, if the value is not an identifier you can wrap it in
+        parentheses. e.g. constexpr (myConstexprFunction() + OBJECT_OFFSET(Foo, bar)),
+        which will get converted into:
+        static_cast<int64_t>(myConstexprFunction() + OBJECT_OFFSET(Foo, bar));
+
+        This patch also changes the data format the LLIntOffsetsExtractor
+        binary produces.  Previously, it would produce unsigned values,
+        after this patch every value is an int64_t.  Using an int64_t is
+        useful because it means that we can represent any constant needed.
+        int32_t masks are sign extended then passed then converted to a
+        negative literal sting in the assembler so it will be the constant
+        expected.
+
+        * llint/LLIntOffsetsExtractor.cpp:
+        (JSC::LLIntOffsetsExtractor::dummy):
+        * llint/LowLevelInterpreter.asm:
+        * llint/LowLevelInterpreter64.asm:
+        * offlineasm/asm.rb:
+        * offlineasm/ast.rb:
+        * offlineasm/generate_offset_extractor.rb:
+        * offlineasm/offsets.rb:
+        * offlineasm/parser.rb:
+        * offlineasm/transform.rb:
+
 2017-07-28  Matt Baker  <mattbaker@apple.com>
 
         Web Inspector: capture an async stack trace when web content calls addEventListener
index 90e48b4..12073ad 100644 (file)
@@ -67,10 +67,10 @@ namespace JSC {
 
 class LLIntOffsetsExtractor {
 public:
-    static const unsigned* dummy();
+    static const int64_t* dummy();
 };
 
-const unsigned* LLIntOffsetsExtractor::dummy()
+const int64_t* LLIntOffsetsExtractor::dummy()
 {
 // This is a file generated by offlineasm/generate_offsets_extractor.rb, and contains code
 // to create a table of offsets, sizes, and a header identifying what combination of
index cbd81c0..9167f85 100644 (file)
@@ -153,11 +153,11 @@ end
 
 # These declarations must match interpreter/JSStack.h.
 
+const PtrSize = constexpr (sizeof(void*))
+
 if JSVALUE64
-    const PtrSize = 8
     const CallFrameHeaderSlots = 5
 else
-    const PtrSize = 4
     const CallFrameHeaderSlots = 4
     const CallFrameAlignSlots = 1
 end
@@ -205,21 +205,21 @@ else
 end
 
 # NOTE: The values below must be in sync with what is in PutByIdFlags.h.
-const PutByIdPrimaryTypeMask = 0x6
-const PutByIdPrimaryTypeSecondary = 0x0
-const PutByIdPrimaryTypeObjectWithStructure = 0x2
-const PutByIdPrimaryTypeObjectWithStructureOrOther = 0x4
-const PutByIdSecondaryTypeMask = -0x8
-const PutByIdSecondaryTypeBottom = 0x0
-const PutByIdSecondaryTypeBoolean = 0x8
-const PutByIdSecondaryTypeOther = 0x10
-const PutByIdSecondaryTypeInt32 = 0x18
-const PutByIdSecondaryTypeNumber = 0x20
-const PutByIdSecondaryTypeString = 0x28
-const PutByIdSecondaryTypeSymbol = 0x30
-const PutByIdSecondaryTypeObject = 0x38
-const PutByIdSecondaryTypeObjectOrOther = 0x40
-const PutByIdSecondaryTypeTop = 0x48
+const PutByIdPrimaryTypeMask = constexpr PutByIdPrimaryTypeMask
+const PutByIdPrimaryTypeSecondary = constexpr PutByIdPrimaryTypeSecondary
+const PutByIdPrimaryTypeObjectWithStructure = constexpr PutByIdPrimaryTypeObjectWithStructure
+const PutByIdPrimaryTypeObjectWithStructureOrOther = constexpr PutByIdPrimaryTypeObjectWithStructureOrOther
+const PutByIdSecondaryTypeMask = constexpr PutByIdSecondaryTypeMask
+const PutByIdSecondaryTypeBottom = constexpr PutByIdSecondaryTypeBottom
+const PutByIdSecondaryTypeBoolean = constexpr PutByIdSecondaryTypeBoolean
+const PutByIdSecondaryTypeOther = constexpr PutByIdSecondaryTypeOther
+const PutByIdSecondaryTypeInt32 = constexpr PutByIdSecondaryTypeInt32
+const PutByIdSecondaryTypeNumber = constexpr PutByIdSecondaryTypeNumber
+const PutByIdSecondaryTypeString = constexpr PutByIdSecondaryTypeString
+const PutByIdSecondaryTypeSymbol = constexpr PutByIdSecondaryTypeSymbol
+const PutByIdSecondaryTypeObject = constexpr PutByIdSecondaryTypeObject
+const PutByIdSecondaryTypeObjectOrOther = constexpr PutByIdSecondaryTypeObjectOrOther
+const PutByIdSecondaryTypeTop = constexpr PutByIdSecondaryTypeTop
 
 const CallOpCodeSize = 9
 
@@ -245,9 +245,9 @@ const CalleeSaveSpaceStackAligned = (CalleeSaveSpaceAsVirtualRegisters * SlotSiz
 
 
 # Watchpoint states
-const ClearWatchpoint = 0
-const IsWatched = 1
-const IsInvalidated = 2
+const ClearWatchpoint = constexpr ClearWatchpoint
+const IsWatched = constexpr IsWatched
+const IsInvalidated = constexpr IsInvalidated
 
 # ShadowChicken data
 const ShadowChickenTailMarker = 0x7a11
@@ -333,52 +333,52 @@ else
 end
 
 # Constant for reasoning about butterflies.
-const IsArray                  = 0x01
-const IndexingShapeMask        = 0x0E
-const NoIndexingShape          = 0x00
-const Int32Shape               = 0x04
-const DoubleShape              = 0x06
-const ContiguousShape          = 0x08
-const ArrayStorageShape        = 0x0A
-const SlowPutArrayStorageShape = 0x0C
+const IsArray                  = constexpr IsArray
+const IndexingShapeMask        = constexpr IndexingShapeMask
+const NoIndexingShape          = constexpr NoIndexingShape
+const Int32Shape               = constexpr Int32Shape
+const DoubleShape              = constexpr DoubleShape
+const ContiguousShape          = constexpr ContiguousShape
+const ArrayStorageShape        = constexpr ArrayStorageShape
+const SlowPutArrayStorageShape = constexpr SlowPutArrayStorageShape
 
 # Type constants.
-const StringType = 6
-const SymbolType = 7
-const ObjectType = 23
-const FinalObjectType = 24
-const JSFunctionType = 26
-const ArrayType = 34
-const DerivedArrayType = 35
-const ProxyObjectType = 53
+const StringType = constexpr StringType
+const SymbolType = constexpr SymbolType
+const ObjectType = constexpr ObjectType
+const FinalObjectType = constexpr FinalObjectType
+const JSFunctionType = constexpr JSFunctionType
+const ArrayType = constexpr ArrayType
+const DerivedArrayType = constexpr DerivedArrayType
+const ProxyObjectType = constexpr ProxyObjectType
 
 # The typed array types need to be numbered in a particular order because of the manually written
 # switch statement in get_by_val and put_by_val.
-const Int8ArrayType = 36
-const Int16ArrayType = 37
-const Int32ArrayType = 38
-const Uint8ArrayType = 39
-const Uint8ClampedArrayType = 40
-const Uint16ArrayType = 41
-const Uint32ArrayType = 42
-const Float32ArrayType = 43
-const Float64ArrayType = 44
+const Int8ArrayType = constexpr Int8ArrayType
+const Int16ArrayType = constexpr Int16ArrayType
+const Int32ArrayType = constexpr Int32ArrayType
+const Uint8ArrayType = constexpr Uint8ArrayType
+const Uint8ClampedArrayType = constexpr Uint8ClampedArrayType
+const Uint16ArrayType = constexpr Uint16ArrayType
+const Uint32ArrayType = constexpr Uint32ArrayType
+const Float32ArrayType = constexpr Float32ArrayType
+const Float64ArrayType = constexpr Float64ArrayType
 
 const FirstArrayType = Int8ArrayType
 const LastArrayType = Float64ArrayType
 
 # Type flags constants.
-const MasqueradesAsUndefined = 1
-const ImplementsDefaultHasInstance = 2
+const MasqueradesAsUndefined = constexpr MasqueradesAsUndefined
+const ImplementsDefaultHasInstance = constexpr ImplementsDefaultHasInstance
 
 # Bytecode operand constants.
-const FirstConstantRegisterIndex = 0x40000000
+const FirstConstantRegisterIndex = constexpr FirstConstantRegisterIndex
 
 # Code type constants.
-const GlobalCode = 0
-const EvalCode = 1
-const FunctionCode = 2
-const ModuleCode = 3
+const GlobalCode = constexpr GlobalCode
+const EvalCode = constexpr EvalCode
+const FunctionCode = constexpr FunctionCode
+const ModuleCode = constexpr ModuleCode
 
 # The interpreter steals the tag word of the argument count.
 const LLIntReturnPC = ArgumentCount + TagOffset
@@ -390,16 +390,16 @@ const HashFlags8BitBuffer = 8
 const firstOutOfLineOffset = 100
 
 # ResolveType
-const GlobalProperty = 0
-const GlobalVar = 1
-const GlobalLexicalVar = 2
-const ClosureVar = 3
-const LocalClosureVar = 4
-const ModuleVar = 5
-const GlobalPropertyWithVarInjectionChecks = 6
-const GlobalVarWithVarInjectionChecks = 7
-const GlobalLexicalVarWithVarInjectionChecks = 8
-const ClosureVarWithVarInjectionChecks = 9
+const GlobalProperty = constexpr GlobalProperty
+const GlobalVar = constexpr GlobalVar
+const GlobalLexicalVar = constexpr GlobalLexicalVar
+const ClosureVar = constexpr ClosureVar
+const LocalClosureVar = constexpr LocalClosureVar
+const ModuleVar = constexpr ModuleVar
+const GlobalPropertyWithVarInjectionChecks = constexpr GlobalPropertyWithVarInjectionChecks
+const GlobalVarWithVarInjectionChecks = constexpr GlobalVarWithVarInjectionChecks
+const GlobalLexicalVarWithVarInjectionChecks = constexpr GlobalLexicalVarWithVarInjectionChecks
+const ClosureVarWithVarInjectionChecks = constexpr ClosureVarWithVarInjectionChecks
 
 const ResolveTypeMask = 0x3ff
 const InitializationModeMask = 0xffc00
@@ -1256,210 +1256,210 @@ end
 _llint_op_create_direct_arguments:
     traceExecution()
     callOpcodeSlowPath(_slow_path_create_direct_arguments)
-    dispatch(2)
+    dispatch(constexpr op_create_direct_arguments_length)
 
 
 _llint_op_create_scoped_arguments:
     traceExecution()
     callOpcodeSlowPath(_slow_path_create_scoped_arguments)
-    dispatch(3)
+    dispatch(constexpr op_create_scoped_arguments_length)
 
 
 _llint_op_create_cloned_arguments:
     traceExecution()
     callOpcodeSlowPath(_slow_path_create_cloned_arguments)
-    dispatch(2)
+    dispatch(constexpr op_create_cloned_arguments_length)
 
 
 _llint_op_create_this:
     traceExecution()
     callOpcodeSlowPath(_slow_path_create_this)
-    dispatch(5)
+    dispatch(constexpr op_create_this_length)
 
 
 _llint_op_new_object:
     traceExecution()
     callOpcodeSlowPath(_llint_slow_path_new_object)
-    dispatch(4)
+    dispatch(constexpr op_new_object_length)
 
 
 _llint_op_new_func:
     traceExecution()
     callOpcodeSlowPath(_llint_slow_path_new_func)
-    dispatch(4)
+    dispatch(constexpr op_new_func_length)
 
 
 _llint_op_new_generator_func:
     traceExecution()
     callOpcodeSlowPath(_llint_slow_path_new_generator_func)
-    dispatch(4)
+    dispatch(constexpr op_new_generator_func_length)
 
 
 _llint_op_new_async_func:
     traceExecution()
     callSlowPath(_llint_slow_path_new_async_func)
-    dispatch(4)
+    dispatch(constexpr op_new_async_func_length)
 
 
 _llint_op_new_array:
     traceExecution()
     callOpcodeSlowPath(_llint_slow_path_new_array)
-    dispatch(5)
+    dispatch(constexpr op_new_array_length)
 
 
 _llint_op_new_array_with_spread:
     traceExecution()
     callOpcodeSlowPath(_slow_path_new_array_with_spread)
-    dispatch(5)
+    dispatch(constexpr op_new_array_with_spread_length)
 
 
 _llint_op_spread:
     traceExecution()
     callOpcodeSlowPath(_slow_path_spread)
-    dispatch(3)
+    dispatch(constexpr op_spread_length)
 
 
 _llint_op_new_array_with_size:
     traceExecution()
     callOpcodeSlowPath(_llint_slow_path_new_array_with_size)
-    dispatch(4)
+    dispatch(constexpr op_new_array_with_size_length)
 
 
 _llint_op_new_array_buffer:
     traceExecution()
     callOpcodeSlowPath(_llint_slow_path_new_array_buffer)
-    dispatch(5)
+    dispatch(constexpr op_new_array_buffer_length)
 
 
 _llint_op_new_regexp:
     traceExecution()
     callOpcodeSlowPath(_llint_slow_path_new_regexp)
-    dispatch(3)
+    dispatch(constexpr op_new_regexp_length)
 
 
 _llint_op_less:
     traceExecution()
     callOpcodeSlowPath(_slow_path_less)
-    dispatch(4)
+    dispatch(constexpr op_less_length)
 
 
 _llint_op_lesseq:
     traceExecution()
     callOpcodeSlowPath(_slow_path_lesseq)
-    dispatch(4)
+    dispatch(constexpr op_lesseq_length)
 
 
 _llint_op_greater:
     traceExecution()
     callOpcodeSlowPath(_slow_path_greater)
-    dispatch(4)
+    dispatch(constexpr op_greater_length)
 
 
 _llint_op_greatereq:
     traceExecution()
     callOpcodeSlowPath(_slow_path_greatereq)
-    dispatch(4)
+    dispatch(constexpr op_greatereq_length)
 
 
 _llint_op_mod:
     traceExecution()
     callOpcodeSlowPath(_slow_path_mod)
-    dispatch(4)
+    dispatch(constexpr op_mod_length)
 
 
 _llint_op_pow:
     traceExecution()
     callOpcodeSlowPath(_slow_path_pow)
-    dispatch(4)
+    dispatch(constexpr op_pow_length)
 
 
 _llint_op_typeof:
     traceExecution()
     callOpcodeSlowPath(_slow_path_typeof)
-    dispatch(3)
+    dispatch(constexpr op_typeof_length)
 
 
 _llint_op_is_object_or_null:
     traceExecution()
     callOpcodeSlowPath(_slow_path_is_object_or_null)
-    dispatch(3)
+    dispatch(constexpr op_is_object_or_null_length)
 
 _llint_op_is_function:
     traceExecution()
     callOpcodeSlowPath(_slow_path_is_function)
-    dispatch(3)
+    dispatch(constexpr op_is_function_length)
 
 
 _llint_op_in:
     traceExecution()
     callOpcodeSlowPath(_slow_path_in)
-    dispatch(5)
+    dispatch(constexpr op_in_length)
 
 
 _llint_op_try_get_by_id:
     traceExecution()
     callOpcodeSlowPath(_llint_slow_path_try_get_by_id)
-    dispatch(5)
+    dispatch(constexpr op_try_get_by_id_length)
 
 
 _llint_op_del_by_id:
     traceExecution()
     callOpcodeSlowPath(_llint_slow_path_del_by_id)
-    dispatch(4)
+    dispatch(constexpr op_del_by_id_length)
 
 
 _llint_op_del_by_val:
     traceExecution()
     callOpcodeSlowPath(_llint_slow_path_del_by_val)
-    dispatch(4)
+    dispatch(constexpr op_del_by_val_length)
 
 
 _llint_op_put_by_index:
     traceExecution()
     callOpcodeSlowPath(_llint_slow_path_put_by_index)
-    dispatch(4)
+    dispatch(constexpr op_put_by_index_length)
 
 
 _llint_op_put_getter_by_id:
     traceExecution()
     callOpcodeSlowPath(_llint_slow_path_put_getter_by_id)
-    dispatch(5)
+    dispatch(constexpr op_put_getter_by_id_length)
 
 
 _llint_op_put_setter_by_id:
     traceExecution()
     callOpcodeSlowPath(_llint_slow_path_put_setter_by_id)
-    dispatch(5)
+    dispatch(constexpr op_put_setter_by_id_length)
 
 
 _llint_op_put_getter_setter_by_id:
     traceExecution()
     callOpcodeSlowPath(_llint_slow_path_put_getter_setter_by_id)
-    dispatch(6)
+    dispatch(constexpr op_put_getter_setter_by_id_length)
 
 
 _llint_op_put_getter_by_val:
     traceExecution()
     callOpcodeSlowPath(_llint_slow_path_put_getter_by_val)
-    dispatch(5)
+    dispatch(constexpr op_put_getter_by_val_length)
 
 
 _llint_op_put_setter_by_val:
     traceExecution()
     callOpcodeSlowPath(_llint_slow_path_put_setter_by_val)
-    dispatch(5)
+    dispatch(constexpr op_put_setter_by_val_length)
 
 
 _llint_op_define_data_property:
     traceExecution()
     callOpcodeSlowPath(_slow_path_define_data_property)
-    dispatch(5)
+    dispatch(constexpr op_define_data_property_length)
 
 
 _llint_op_define_accessor_property:
     traceExecution()
     callOpcodeSlowPath(_slow_path_define_accessor_property)
-    dispatch(6)
+    dispatch(constexpr op_define_accessor_property_length)
 
 
 _llint_op_jtrue:
@@ -1543,7 +1543,7 @@ _llint_op_jngreatereq:
 _llint_op_loop_hint:
     traceExecution()
     checkSwitchToJITForLoop()
-    dispatch(1)
+    dispatch(constexpr op_loop_hint_length)
 
 
 _llint_op_check_traps:
@@ -1553,7 +1553,7 @@ _llint_op_check_traps:
     loadb VM::m_traps+VMTraps::m_needTrapHandling[t1], t0
     btpnz t0, .handleTraps
 .afterHandlingTraps:
-    dispatch(1)
+    dispatch(constexpr op_check_traps_length)
 .handleTraps:
     callTrapHandler(.throwHandler)
     jmp .afterHandlingTraps
@@ -1574,7 +1574,7 @@ end
 
 
 _llint_op_nop:
-    dispatch(1)
+    dispatch(constexpr op_nop_length)
 
 
 _llint_op_switch_string:
@@ -1586,23 +1586,23 @@ _llint_op_switch_string:
 _llint_op_new_func_exp:
     traceExecution()
     callOpcodeSlowPath(_llint_slow_path_new_func_exp)
-    dispatch(4)
+    dispatch(constexpr op_new_func_exp_length)
 
 _llint_op_new_generator_func_exp:
     traceExecution()
     callOpcodeSlowPath(_llint_slow_path_new_generator_func_exp)
-    dispatch(4)
+    dispatch(constexpr op_new_generator_func_exp_length)
 
 _llint_op_new_async_func_exp:
     traceExecution()
     callSlowPath(_llint_slow_path_new_async_func_exp)
-    dispatch(4)
+    dispatch(constexpr op_new_async_func_exp_length)
 
 
 _llint_op_set_function_name:
     traceExecution()
     callOpcodeSlowPath(_llint_slow_path_set_function_name)
-    dispatch(3)
+    dispatch(constexpr op_set_function_name_length)
 
 _llint_op_call:
     traceExecution()
@@ -1708,25 +1708,25 @@ _llint_generic_return_point:
 _llint_op_strcat:
     traceExecution()
     callOpcodeSlowPath(_slow_path_strcat)
-    dispatch(4)
+    dispatch(constexpr op_strcat_length)
 
 
 _llint_op_push_with_scope:
     traceExecution()
     callOpcodeSlowPath(_slow_path_push_with_scope)
-    dispatch(4)
+    dispatch(constexpr op_push_with_scope_length)
 
 
 _llint_op_assert:
     traceExecution()
     callOpcodeSlowPath(_slow_path_assert)
-    dispatch(3)
+    dispatch(constexpr op_assert_length)
 
 
 _llint_op_unreachable:
     traceExecution()
     callOpcodeSlowPath(_slow_path_unreachable)
-    dispatch(1)
+    dispatch(constexpr op_unreachable_length)
 
 
 _llint_op_yield:
@@ -1736,19 +1736,19 @@ _llint_op_yield:
 _llint_op_create_lexical_environment:
     traceExecution()
     callOpcodeSlowPath(_slow_path_create_lexical_environment)
-    dispatch(5)
+    dispatch(constexpr op_create_lexical_environment_length)
 
 
 _llint_op_throw:
     traceExecution()
     callOpcodeSlowPath(_llint_slow_path_throw)
-    dispatch(2)
+    dispatch(constexpr op_throw_length)
 
 
 _llint_op_throw_static_error:
     traceExecution()
     callOpcodeSlowPath(_slow_path_throw_static_error)
-    dispatch(3)
+    dispatch(constexpr op_throw_static_error_length)
 
 
 _llint_op_debug:
@@ -1758,7 +1758,7 @@ _llint_op_debug:
     btiz t0, .opDebugDone
     callOpcodeSlowPath(_llint_slow_path_debug)
 .opDebugDone:                    
-    dispatch(3)
+    dispatch(constexpr op_debug_length)
 
 
 _llint_native_call_trampoline:
@@ -1771,82 +1771,82 @@ _llint_native_construct_trampoline:
 _llint_op_get_enumerable_length:
     traceExecution()
     callOpcodeSlowPath(_slow_path_get_enumerable_length)
-    dispatch(3)
+    dispatch(constexpr op_get_enumerable_length_length)
 
 _llint_op_has_indexed_property:
     traceExecution()
     callOpcodeSlowPath(_slow_path_has_indexed_property)
-    dispatch(5)
+    dispatch(constexpr op_has_indexed_property_length)
 
 _llint_op_has_structure_property:
     traceExecution()
     callOpcodeSlowPath(_slow_path_has_structure_property)
-    dispatch(5)
+    dispatch(constexpr op_has_structure_property_length)
 
 _llint_op_has_generic_property:
     traceExecution()
     callOpcodeSlowPath(_slow_path_has_generic_property)
-    dispatch(4)
+    dispatch(constexpr op_has_generic_property_length)
 
 _llint_op_get_direct_pname:
     traceExecution()
     callOpcodeSlowPath(_slow_path_get_direct_pname)
-    dispatch(7)
+    dispatch(constexpr op_get_direct_pname_length)
 
 _llint_op_get_property_enumerator:
     traceExecution()
     callOpcodeSlowPath(_slow_path_get_property_enumerator)
-    dispatch(3)
+    dispatch(constexpr op_get_property_enumerator_length)
 
 _llint_op_enumerator_structure_pname:
     traceExecution()
     callOpcodeSlowPath(_slow_path_next_structure_enumerator_pname)
-    dispatch(4)
+    dispatch(constexpr op_enumerator_structure_pname_length)
 
 _llint_op_enumerator_generic_pname:
     traceExecution()
     callOpcodeSlowPath(_slow_path_next_generic_enumerator_pname)
-    dispatch(4)
+    dispatch(constexpr op_enumerator_generic_pname_length)
 
 _llint_op_to_index_string:
     traceExecution()
     callOpcodeSlowPath(_slow_path_to_index_string)
-    dispatch(3)
+    dispatch(constexpr op_to_index_string_length)
 
 _llint_op_create_rest:
     traceExecution()
     callOpcodeSlowPath(_slow_path_create_rest)
-    dispatch(4)
+    dispatch(constexpr op_create_rest_length)
 
 _llint_op_instanceof:
     traceExecution()
     callOpcodeSlowPath(_llint_slow_path_instanceof)
-    dispatch(4)
+    dispatch(constexpr op_instanceof_length)
 
 _llint_op_get_by_id_with_this:
     traceExecution()
     callOpcodeSlowPath(_slow_path_get_by_id_with_this)
-    dispatch(6)
+    dispatch(constexpr op_get_by_id_with_this_length)
 
 _llint_op_get_by_val_with_this:
     traceExecution()
     callOpcodeSlowPath(_slow_path_get_by_val_with_this)
-    dispatch(6)
+    dispatch(constexpr op_get_by_val_with_this_length)
 
 _llint_op_put_by_id_with_this:
     traceExecution()
     callOpcodeSlowPath(_slow_path_put_by_id_with_this)
-    dispatch(5)
+    dispatch(constexpr op_put_by_id_with_this_length)
 
 _llint_op_put_by_val_with_this:
     traceExecution()
     callOpcodeSlowPath(_slow_path_put_by_val_with_this)
-    dispatch(5)
+    dispatch(constexpr op_put_by_val_with_this_length)
 
 _llint_op_resolve_scope_for_hoisting_func_decl_in_eval:
     traceExecution()
     callOpcodeSlowPath(_slow_path_resolve_scope_for_hoisting_func_decl_in_eval)
-    dispatch(4)
+    dispatch(constexpr op_resolve_scope_for_hoisting_func_decl_in_eval_length)
 
 # Lastly, make sure that we can link even though we don't support all opcodes.
 # These opcodes should never arise when using LLInt or either JIT. We assert
index 2450d40..a70e2b5 100644 (file)
@@ -672,7 +672,7 @@ _llint_op_enter:
     btinz t2, .opEnterLoop
 .opEnterDone:
     callOpcodeSlowPath(_slow_path_enter)
-    dispatch(1)
+    dispatch(constexpr op_enter_length)
 
 
 _llint_op_get_argument:
@@ -686,13 +686,13 @@ _llint_op_get_argument:
     storei t0, TagOffset[cfr, t1, 8]
     storei t3, PayloadOffset[cfr, t1, 8]
     valueProfile(t0, t3, 12, t1)
-    dispatch(4)
+    dispatch(constexpr op_get_argument_length)
 
 .opGetArgumentOutOfBounds:
     storei UndefinedTag, TagOffset[cfr, t1, 8]
     storei 0, PayloadOffset[cfr, t1, 8]
     valueProfile(UndefinedTag, 0, 12, t1)
-    dispatch(4)
+    dispatch(constexpr op_get_argument_length)
 
 
 _llint_op_argument_count:
@@ -703,7 +703,7 @@ _llint_op_argument_count:
     move Int32Tag, t1
     storei t1, TagOffset[cfr, t2, 8]
     storei t0, PayloadOffset[cfr, t2, 8]
-    dispatch(2)
+    dispatch(constexpr op_argument_count_length)
 
 
 _llint_op_get_scope:
@@ -713,7 +713,7 @@ _llint_op_get_scope:
     loadisFromInstruction(1, t1)
     storei CellTag, TagOffset[cfr, t1, 8]
     storei t0, PayloadOffset[cfr, t1, 8]
-    dispatch(2)
+    dispatch(constexpr op_get_scope_length)
 
 
 _llint_op_to_this:
@@ -724,11 +724,11 @@ _llint_op_to_this:
     bbneq JSCell::m_type[t0], FinalObjectType, .opToThisSlow
     loadpFromInstruction(2, t2)
     bpneq JSCell::m_structureID[t0], t2, .opToThisSlow
-    dispatch(4)
+    dispatch(constexpr op_to_this_length)
 
 .opToThisSlow:
     callOpcodeSlowPath(_slow_path_to_this)
-    dispatch(4)
+    dispatch(constexpr op_to_this_length)
 
 
 _llint_op_check_tdz:
@@ -739,7 +739,7 @@ _llint_op_check_tdz:
     callOpcodeSlowPath(_slow_path_throw_tdz_error)
 
 .opNotTDZ:
-    dispatch(2)
+    dispatch(constexpr op_check_tdz_length)
 
 
 _llint_op_mov:
@@ -749,7 +749,7 @@ _llint_op_mov:
     loadConstantOrVariable(t1, t2, t3)
     storei t2, TagOffset[cfr, t0, 8]
     storei t3, PayloadOffset[cfr, t0, 8]
-    dispatch(3)
+    dispatch(constexpr op_mov_length)
 
 
 _llint_op_not:
@@ -761,11 +761,11 @@ _llint_op_not:
     xori 1, t3
     storei t2, TagOffset[cfr, t1, 8]
     storei t3, PayloadOffset[cfr, t1, 8]
-    dispatch(3)
+    dispatch(constexpr op_not_length)
 
 .opNotSlow:
     callOpcodeSlowPath(_slow_path_not)
-    dispatch(3)
+    dispatch(constexpr op_not_length)
 
 
 _llint_op_eq:
@@ -781,11 +781,11 @@ _llint_op_eq:
     cieq t0, t1, t0
     storei BooleanTag, TagOffset[cfr, t2, 8]
     storei t0, PayloadOffset[cfr, t2, 8]
-    dispatch(4)
+    dispatch(constexpr op_eq_length)
 
 .opEqSlow:
     callOpcodeSlowPath(_slow_path_eq)
-    dispatch(4)
+    dispatch(constexpr op_eq_length)
 
 
 _llint_op_eq_null:
@@ -812,7 +812,7 @@ _llint_op_eq_null:
 .opEqNullNotImmediate:
     storei BooleanTag, TagOffset[cfr, t3, 8]
     storei t1, PayloadOffset[cfr, t3, 8]
-    dispatch(3)
+    dispatch(constexpr op_eq_null_length)
 
 
 _llint_op_neq:
@@ -828,11 +828,11 @@ _llint_op_neq:
     cineq t0, t1, t0
     storei BooleanTag, TagOffset[cfr, t2, 8]
     storei t0, PayloadOffset[cfr, t2, 8]
-    dispatch(4)
+    dispatch(constexpr op_neq_length)
 
 .opNeqSlow:
     callOpcodeSlowPath(_slow_path_neq)
-    dispatch(4)
+    dispatch(constexpr op_neq_length)
     
 
 _llint_op_neq_null:
@@ -859,7 +859,7 @@ _llint_op_neq_null:
 .opNeqNullNotImmediate:
     storei BooleanTag, TagOffset[cfr, t3, 8]
     storei t1, PayloadOffset[cfr, t3, 8]
-    dispatch(3)
+    dispatch(constexpr op_neq_null_length)
 
 
 macro strictEq(equalityOperation, slowPath)
@@ -901,11 +901,11 @@ _llint_op_inc:
     loadi PayloadOffset[cfr, t0, 8], t1
     baddio 1, t1, .opIncSlow
     storei t1, PayloadOffset[cfr, t0, 8]
-    dispatch(2)
+    dispatch(constexpr op_inc_length)
 
 .opIncSlow:
     callOpcodeSlowPath(_slow_path_inc)
-    dispatch(2)
+    dispatch(constexpr op_inc_length)
 
 
 _llint_op_dec:
@@ -915,11 +915,11 @@ _llint_op_dec:
     loadi PayloadOffset[cfr, t0, 8], t1
     bsubio 1, t1, .opDecSlow
     storei t1, PayloadOffset[cfr, t0, 8]
-    dispatch(2)
+    dispatch(constexpr op_dec_length)
 
 .opDecSlow:
     callOpcodeSlowPath(_slow_path_dec)
-    dispatch(2)
+    dispatch(constexpr op_dec_length)
 
 
 _llint_op_to_number:
@@ -933,11 +933,11 @@ _llint_op_to_number:
     storei t2, TagOffset[cfr, t1, 8]
     storei t3, PayloadOffset[cfr, t1, 8]
     valueProfile(t2, t3, 12, t1)
-    dispatch(4)
+    dispatch(constexpr op_to_number_length)
 
 .opToNumberSlow:
     callOpcodeSlowPath(_slow_path_to_number)
-    dispatch(4)
+    dispatch(constexpr op_to_number_length)
 
 
 _llint_op_to_string:
@@ -950,11 +950,11 @@ _llint_op_to_string:
 .opToStringIsString:
     storei t2, TagOffset[cfr, t1, 8]
     storei t3, PayloadOffset[cfr, t1, 8]
-    dispatch(3)
+    dispatch(constexpr op_to_string_length)
 
 .opToStringSlow:
     callOpcodeSlowPath(_slow_path_to_string)
-    dispatch(3)
+    dispatch(constexpr op_to_string_length)
 
 
 _llint_op_negate:
@@ -970,7 +970,7 @@ _llint_op_negate:
     storei Int32Tag, TagOffset[cfr, t3, 8]
     storeisToInstruction(t0, 3)
     storei t2, PayloadOffset[cfr, t3, 8]
-    dispatch(4)
+    dispatch(constexpr op_negate_length)
 .opNegateSrcNotInt:
     bia t1, LowestTag, .opNegateSlow
     xori 0x80000000, t1
@@ -978,11 +978,11 @@ _llint_op_negate:
     storei t2, PayloadOffset[cfr, t3, 8]
     storeisToInstruction(t0, 3)
     storei t1, TagOffset[cfr, t3, 8]
-    dispatch(4)
+    dispatch(constexpr op_negate_length)
 
 .opNegateSlow:
     callOpcodeSlowPath(_slow_path_negate)
-    dispatch(4)
+    dispatch(constexpr op_negate_length)
 
 
 macro binaryOpCustomStore(integerOperationAndStore, doubleOperation, slowPath)
@@ -1125,7 +1125,7 @@ _llint_op_lshift:
     bitOp(
         macro (left, right) lshifti left, right end,
         _slow_path_lshift,
-        4)
+        constexpr op_lshift_length)
 
 
 _llint_op_rshift:
@@ -1133,7 +1133,7 @@ _llint_op_rshift:
     bitOp(
         macro (left, right) rshifti left, right end,
         _slow_path_rshift,
-        4)
+        constexpr op_rshift_length)
 
 
 _llint_op_urshift:
@@ -1141,7 +1141,7 @@ _llint_op_urshift:
     bitOp(
         macro (left, right) urshifti left, right end,
         _slow_path_urshift,
-        4)
+        constexpr op_urshift_length)
 
 
 _llint_op_unsigned:
@@ -1152,10 +1152,10 @@ _llint_op_unsigned:
     bilt t2, 0, .opUnsignedSlow
     storei t2, PayloadOffset[cfr, t0, 8]
     storei Int32Tag, TagOffset[cfr, t0, 8]
-    dispatch(3)
+    dispatch(constexpr op_unsigned_length)
 .opUnsignedSlow:
     callOpcodeSlowPath(_slow_path_unsigned)
-    dispatch(3)
+    dispatch(constexpr op_unsigned_length)
 
 
 _llint_op_bitand:
@@ -1163,7 +1163,7 @@ _llint_op_bitand:
     bitOp(
         macro (left, right) andi left, right end,
         _slow_path_bitand,
-        5)
+        constexpr op_bitand_length)
 
 
 _llint_op_bitxor:
@@ -1171,7 +1171,7 @@ _llint_op_bitxor:
     bitOp(
         macro (left, right) xori left, right end,
         _slow_path_bitxor,
-        5)
+        constexpr op_bitxor_length)
 
 
 _llint_op_bitor:
@@ -1179,7 +1179,7 @@ _llint_op_bitor:
     bitOp(
         macro (left, right) ori left, right end,
         _slow_path_bitor,
-        5)
+        constexpr op_bitor_length)
 
 
 _llint_op_overrides_has_instance:
@@ -1205,17 +1205,17 @@ _llint_op_overrides_has_instance:
     loadConstantOrVariablePayloadUnchecked(t0, t1)
     tbz JSCell::m_flags[t1], ImplementsDefaultHasInstance, t0
     storei t0, PayloadOffset[cfr, t3, 8]
-    dispatch(4)
+    dispatch(constexpr op_overrides_has_instance_length)
 
 .opOverrideshasInstanceValueNotCell:
 .opOverrideshasInstanceValueNotDefault:
     storei 1, PayloadOffset[cfr, t3, 8]
-    dispatch(4)
+    dispatch(constexpr op_overrides_has_instance_length)
 
 _llint_op_instanceof_custom:
     traceExecution()
     callOpcodeSlowPath(_llint_slow_path_instanceof_custom)
-    dispatch(5)
+    dispatch(constexpr op_instanceof_custom_length)
 
 
 _llint_op_is_empty:
@@ -1226,7 +1226,7 @@ _llint_op_is_empty:
     cieq t2, EmptyValueTag, t3
     storei BooleanTag, TagOffset[cfr, t0, 8]
     storei t3, PayloadOffset[cfr, t0, 8]
-    dispatch(3)
+    dispatch(constexpr op_is_empty_length)
 
 
 _llint_op_is_undefined:
@@ -1238,19 +1238,19 @@ _llint_op_is_undefined:
     bieq t2, CellTag, .opIsUndefinedCell
     cieq t2, UndefinedTag, t3
     storei t3, PayloadOffset[cfr, t0, 8]
-    dispatch(3)
+    dispatch(constexpr op_is_undefined_length)
 .opIsUndefinedCell:
     btbnz JSCell::m_flags[t3], MasqueradesAsUndefined, .opIsUndefinedMasqueradesAsUndefined
     move 0, t1
     storei t1, PayloadOffset[cfr, t0, 8]
-    dispatch(3)
+    dispatch(constexpr op_is_undefined_length)
 .opIsUndefinedMasqueradesAsUndefined:
     loadp JSCell::m_structureID[t3], t1
     loadp CodeBlock[cfr], t3
     loadp CodeBlock::m_globalObject[t3], t3
     cpeq Structure::m_globalObject[t1], t3, t1
     storei t1, PayloadOffset[cfr, t0, 8]
-    dispatch(3)
+    dispatch(constexpr op_is_undefined_length)
 
 
 _llint_op_is_boolean:
@@ -1261,7 +1261,7 @@ _llint_op_is_boolean:
     cieq t0, BooleanTag, t0
     storei BooleanTag, TagOffset[cfr, t2, 8]
     storei t0, PayloadOffset[cfr, t2, 8]
-    dispatch(3)
+    dispatch(constexpr op_is_boolean_length)
 
 
 _llint_op_is_number:
@@ -1273,7 +1273,7 @@ _llint_op_is_number:
     addi 1, t0
     cib t0, LowestTag + 1, t1
     storei t1, PayloadOffset[cfr, t2, 8]
-    dispatch(3)
+    dispatch(constexpr op_is_number_length)
 
 
 _llint_op_is_cell_with_type:
@@ -1286,10 +1286,10 @@ _llint_op_is_cell_with_type:
     loadi 12[PC], t0
     cbeq JSCell::m_type[t3], t0, t1
     storei t1, PayloadOffset[cfr, t2, 8]
-    dispatch(4)
+    dispatch(constexpr op_is_cell_with_type_length)
 .notCellCase:
     storep 0, PayloadOffset[cfr, t2, 8]
-    dispatch(4)
+    dispatch(constexpr op_is_cell_with_type_length)
 
 
 _llint_op_is_object:
@@ -1301,10 +1301,10 @@ _llint_op_is_object:
     bineq t0, CellTag, .opIsObjectNotCell
     cbaeq JSCell::m_type[t3], ObjectType, t1
     storei t1, PayloadOffset[cfr, t2, 8]
-    dispatch(3)
+    dispatch(constexpr op_is_object_length)
 .opIsObjectNotCell:
     storep 0, PayloadOffset[cfr, t2, 8]
-    dispatch(3)
+    dispatch(constexpr op_is_object_length)
 
 
 macro loadPropertyAtVariableOffsetKnownNotInline(propertyOffset, objectAndStorage, tag, payload)
@@ -1360,11 +1360,11 @@ _llint_op_get_by_id:
     storei t0, TagOffset[cfr, t2, 8]
     storei t1, PayloadOffset[cfr, t2, 8]
     valueProfile(t0, t1, 32, t2)
-    dispatch(9)
+    dispatch(constexpr op_get_by_id_length)
 
 .opGetByIdSlow:
     callOpcodeSlowPath(_llint_slow_path_get_by_id)
-    dispatch(9)
+    dispatch(constexpr op_get_by_id_length)
 
 
 _llint_op_get_by_id_proto_load:
@@ -1380,11 +1380,11 @@ _llint_op_get_by_id_proto_load:
     storei t0, TagOffset[cfr, t2, 8]
     storei t1, PayloadOffset[cfr, t2, 8]
     valueProfile(t0, t1, 32, t2)
-    dispatch(9)
+    dispatch(constexpr op_get_by_id_proto_load_length)
 
 .opGetByIdProtoSlow:
     callOpcodeSlowPath(_llint_slow_path_get_by_id)
-    dispatch(9)
+    dispatch(constexpr op_get_by_id_proto_load_length)
 
 
 _llint_op_get_by_id_unset:
@@ -1397,11 +1397,11 @@ _llint_op_get_by_id_unset:
     storei UndefinedTag, TagOffset[cfr, t2, 8]
     storei 0, PayloadOffset[cfr, t2, 8]
     valueProfile(UndefinedTag, 0, 32, t2)
-    dispatch(9)
+    dispatch(constexpr op_get_by_id_unset_length)
 
 .opGetByIdUnsetSlow:
     callOpcodeSlowPath(_llint_slow_path_get_by_id)
-    dispatch(9)
+    dispatch(constexpr op_get_by_id_unset_length)
 
 
 _llint_op_get_array_length:
@@ -1420,11 +1420,11 @@ _llint_op_get_array_length:
     valueProfile(Int32Tag, t0, 32, t2)
     storep t0, PayloadOffset[cfr, t1, 8]
     storep Int32Tag, TagOffset[cfr, t1, 8]
-    dispatch(9)
+    dispatch(constexpr op_get_array_length_length)
 
 .opGetArrayLengthSlow:
     callOpcodeSlowPath(_llint_slow_path_get_by_id)
-    dispatch(9)
+    dispatch(constexpr op_get_array_length_length)
 
 
 _llint_op_put_by_id:
@@ -1549,7 +1549,7 @@ _llint_op_put_by_id:
     loadi 20[PC], t1
     storePropertyAtVariableOffset(t1, t0, t2, t3)
     writeBarrierOnOperand(1)
-    dispatch(9)
+    dispatch(constexpr op_put_by_id_length)
 
 .opPutByIdNotTransition:
     # The only thing live right now is t0, which holds the base.
@@ -1557,11 +1557,11 @@ _llint_op_put_by_id:
     loadConstantOrVariable(t1, t2, t3)
     loadi 20[PC], t1
     storePropertyAtVariableOffset(t1, t0, t2, t3)
-    dispatch(9)
+    dispatch(constexpr op_put_by_id_length)
 
 .opPutByIdSlow:
     callOpcodeSlowPath(_llint_slow_path_put_by_id)
-    dispatch(9)
+    dispatch(constexpr op_put_by_id_length)
 
 
 _llint_op_get_by_val:
@@ -1608,14 +1608,14 @@ _llint_op_get_by_val:
     storei t2, TagOffset[cfr, t0, 8]
     storei t1, PayloadOffset[cfr, t0, 8]
     valueProfile(t2, t1, 20, t0)
-    dispatch(6)
+    dispatch(constexpr op_get_by_val_length)
 
 .opGetByValOutOfBounds:
     loadpFromInstruction(4, t0)
     storeb 1, ArrayProfile::m_outOfBounds[t0]
 .opGetByValSlow:
     callOpcodeSlowPath(_llint_slow_path_get_by_val)
-    dispatch(6)
+    dispatch(constexpr op_get_by_val_length)
 
 
 macro contiguousPutByVal(storeCallback)
@@ -1793,7 +1793,7 @@ _llint_op_jneq_ptr:
     storei 1, 16[PC]
     dispatchBranch(12[PC])
 .opJneqPtrFallThrough:
-    dispatch(5)
+    dispatch(constexpr op_jneq_ptr_length)
 
 
 macro compare(integerCompare, doubleCompare, slowPath)
@@ -1952,11 +1952,11 @@ _llint_op_to_primitive:
 .opToPrimitiveIsImm:
     storei t1, TagOffset[cfr, t3, 8]
     storei t0, PayloadOffset[cfr, t3, 8]
-    dispatch(3)
+    dispatch(constexpr op_to_primitive_length)
 
 .opToPrimitiveSlowCase:
     callOpcodeSlowPath(_slow_path_to_primitive)
-    dispatch(3)
+    dispatch(constexpr op_to_primitive_length)
 
 
 _llint_op_catch:
index c849109..2a8103e 100644 (file)
@@ -582,7 +582,7 @@ _llint_op_enter:
     btqnz t2, .opEnterLoop
 .opEnterDone:
     callOpcodeSlowPath(_slow_path_enter)
-    dispatch(1)
+    dispatch(constexpr op_enter_length)
 
 
 _llint_op_get_argument:
@@ -594,12 +594,12 @@ _llint_op_get_argument:
     loadq ThisArgumentOffset[cfr, t2, 8], t0
     storeq t0, [cfr, t1, 8]
     valueProfile(t0, 3, t2)
-    dispatch(4)
+    dispatch(constexpr op_get_argument_length)
 
 .opGetArgumentOutOfBounds:
     storeq ValueUndefined, [cfr, t1, 8]
     valueProfile(ValueUndefined, 3, t2)
-    dispatch(4)
+    dispatch(constexpr op_get_argument_length)
 
 
 _llint_op_argument_count:
@@ -609,7 +609,7 @@ _llint_op_argument_count:
     subi 1, t0
     orq TagTypeNumber, t0
     storeq t0, [cfr, t1, 8]
-    dispatch(2)
+    dispatch(constexpr op_argument_count_length)
 
 
 _llint_op_get_scope:
@@ -618,7 +618,7 @@ _llint_op_get_scope:
     loadp JSCallee::m_scope[t0], t0
     loadisFromInstruction(1, t1)
     storeq t0, [cfr, t1, 8]
-    dispatch(2)
+    dispatch(constexpr op_get_scope_length)
 
 
 _llint_op_to_this:
@@ -630,11 +630,11 @@ _llint_op_to_this:
     loadStructureWithScratch(t0, t1, t2)
     loadpFromInstruction(2, t2)
     bpneq t1, t2, .opToThisSlow
-    dispatch(4)
+    dispatch(constexpr op_to_this_length)
 
 .opToThisSlow:
     callOpcodeSlowPath(_slow_path_to_this)
-    dispatch(4)
+    dispatch(constexpr op_to_this_length)
 
 
 _llint_op_check_tdz:
@@ -645,7 +645,7 @@ _llint_op_check_tdz:
     callOpcodeSlowPath(_slow_path_throw_tdz_error)
 
 .opNotTDZ:
-    dispatch(2)
+    dispatch(constexpr op_check_tdz_length)
 
 
 _llint_op_mov:
@@ -654,7 +654,7 @@ _llint_op_mov:
     loadisFromInstruction(1, t0)
     loadConstantOrVariable(t1, t2)
     storeq t2, [cfr, t0, 8]
-    dispatch(3)
+    dispatch(constexpr op_mov_length)
 
 
 _llint_op_not:
@@ -666,11 +666,11 @@ _llint_op_not:
     btqnz t2, ~1, .opNotSlow
     xorq ValueTrue, t2
     storeq t2, [cfr, t1, 8]
-    dispatch(3)
+    dispatch(constexpr op_not_length)
 
 .opNotSlow:
     callOpcodeSlowPath(_slow_path_not)
-    dispatch(3)
+    dispatch(constexpr op_not_length)
 
 
 macro equalityComparison(integerComparison, slowPath)
@@ -727,7 +727,7 @@ _llint_op_eq_null:
     loadisFromInstruction(1, t1)
     orq ValueFalse, t0
     storeq t0, [cfr, t1, 8]
-    dispatch(3)
+    dispatch(constexpr op_eq_null_length)
 
 
 _llint_op_neq_null:
@@ -736,7 +736,7 @@ _llint_op_neq_null:
     loadisFromInstruction(1, t1)
     xorq ValueTrue, t0
     storeq t0, [cfr, t1, 8]
-    dispatch(3)
+    dispatch(constexpr op_neq_null_length)
 
 
 macro strictEq(equalityOperation, slowPath)
@@ -814,11 +814,11 @@ _llint_op_to_number:
 .opToNumberIsImmediate:
     storeq t2, [cfr, t1, 8]
     valueProfile(t2, 3, t0)
-    dispatch(4)
+    dispatch(constexpr op_to_number_length)
 
 .opToNumberSlow:
     callOpcodeSlowPath(_slow_path_to_number)
-    dispatch(4)
+    dispatch(constexpr op_to_number_length)
 
 
 _llint_op_to_string:
@@ -830,11 +830,11 @@ _llint_op_to_string:
     bbneq JSCell::m_type[t0], StringType, .opToStringSlow
 .opToStringIsString:
     storeq t0, [cfr, t2, 8]
-    dispatch(3)
+    dispatch(constexpr op_to_string_length)
 
 .opToStringSlow:
     callOpcodeSlowPath(_slow_path_to_string)
-    dispatch(3)
+    dispatch(constexpr op_to_string_length)
 
 
 _llint_op_negate:
@@ -850,18 +850,18 @@ _llint_op_negate:
     orq tagTypeNumber, t3
     storeisToInstruction(t2, 3)
     storeq t3, [cfr, t1, 8]
-    dispatch(4)
+    dispatch(constexpr op_negate_length)
 .opNegateNotInt:
     btqz t3, tagTypeNumber, .opNegateSlow
     xorq 0x8000000000000000, t3
     ori ArithProfileNumber, t2
     storeq t3, [cfr, t1, 8]
     storeisToInstruction(t2, 3)
-    dispatch(4)
+    dispatch(constexpr op_negate_length)
 
 .opNegateSlow:
     callOpcodeSlowPath(_slow_path_negate)
-    dispatch(4)
+    dispatch(constexpr op_negate_length)
 
 
 macro binaryOpCustomStore(integerOperationAndStore, doubleOperation, slowPath)
@@ -994,7 +994,7 @@ _llint_op_div:
             _slow_path_div)
     else
         callOpcodeSlowPath(_slow_path_div)
-        dispatch(5)
+        dispatch(constexpr op_div_length)
     end
 
 
@@ -1021,7 +1021,7 @@ _llint_op_lshift:
     bitOp(
         macro (left, right) lshifti left, right end,
         _slow_path_lshift,
-        4)
+        constexpr op_lshift_length)
 
 
 _llint_op_rshift:
@@ -1029,7 +1029,7 @@ _llint_op_rshift:
     bitOp(
         macro (left, right) rshifti left, right end,
         _slow_path_rshift,
-        4)
+        constexpr op_rshift_length)
 
 
 _llint_op_urshift:
@@ -1037,7 +1037,7 @@ _llint_op_urshift:
     bitOp(
         macro (left, right) urshifti left, right end,
         _slow_path_urshift,
-        4)
+        constexpr op_urshift_length)
 
 
 _llint_op_unsigned:
@@ -1047,10 +1047,10 @@ _llint_op_unsigned:
     loadConstantOrVariable(t1, t2)
     bilt t2, 0, .opUnsignedSlow
     storeq t2, [cfr, t0, 8]
-    dispatch(3)
+    dispatch(constexpr op_unsigned_length)
 .opUnsignedSlow:
     callOpcodeSlowPath(_slow_path_unsigned)
-    dispatch(3)
+    dispatch(constexpr op_unsigned_length)
 
 
 _llint_op_bitand:
@@ -1058,7 +1058,7 @@ _llint_op_bitand:
     bitOp(
         macro (left, right) andi left, right end,
         _slow_path_bitand,
-        5)
+        constexpr op_bitand_length)
 
 
 _llint_op_bitxor:
@@ -1066,7 +1066,7 @@ _llint_op_bitxor:
     bitOp(
         macro (left, right) xori left, right end,
         _slow_path_bitxor,
-        5)
+        constexpr op_bitxor_length)
 
 
 _llint_op_bitor:
@@ -1074,7 +1074,7 @@ _llint_op_bitor:
     bitOp(
         macro (left, right) ori left, right end,
         _slow_path_bitor,
-        5)
+        constexpr op_bitor_length)
 
 
 _llint_op_overrides_has_instance:
@@ -1093,17 +1093,17 @@ _llint_op_overrides_has_instance:
     tbz JSCell::m_flags[t0], ImplementsDefaultHasInstance, t1
     orq ValueFalse, t1
     storeq t1, [cfr, t3, 8]
-    dispatch(4)
+    dispatch(constexpr op_overrides_has_instance_length)
 
 .opOverridesHasInstanceNotDefaultSymbol:
     storeq ValueTrue, [cfr, t3, 8]
-    dispatch(4)
+    dispatch(constexpr op_overrides_has_instance_length)
 
 
 _llint_op_instanceof_custom:
     traceExecution()
     callOpcodeSlowPath(_llint_slow_path_instanceof_custom)
-    dispatch(5)
+    dispatch(constexpr op_instanceof_custom_length)
 
 
 _llint_op_is_empty:
@@ -1114,7 +1114,7 @@ _llint_op_is_empty:
     cqeq t0, ValueEmpty, t3
     orq ValueFalse, t3
     storeq t3, [cfr, t2, 8]
-    dispatch(3)
+    dispatch(constexpr op_is_empty_length)
 
 
 _llint_op_is_undefined:
@@ -1126,12 +1126,12 @@ _llint_op_is_undefined:
     cqeq t0, ValueUndefined, t3
     orq ValueFalse, t3
     storeq t3, [cfr, t2, 8]
-    dispatch(3)
+    dispatch(constexpr op_is_undefined_length)
 .opIsUndefinedCell:
     btbnz JSCell::m_flags[t0], MasqueradesAsUndefined, .masqueradesAsUndefined
     move ValueFalse, t1
     storeq t1, [cfr, t2, 8]
-    dispatch(3)
+    dispatch(constexpr op_is_undefined_length)
 .masqueradesAsUndefined:
     loadStructureWithScratch(t0, t3, t1)
     loadp CodeBlock[cfr], t1
@@ -1139,7 +1139,7 @@ _llint_op_is_undefined:
     cpeq Structure::m_globalObject[t3], t1, t0
     orq ValueFalse, t0
     storeq t0, [cfr, t2, 8]
-    dispatch(3)
+    dispatch(constexpr op_is_undefined_length)
 
 
 _llint_op_is_boolean:
@@ -1151,7 +1151,7 @@ _llint_op_is_boolean:
     tqz t0, ~1, t0
     orq ValueFalse, t0
     storeq t0, [cfr, t2, 8]
-    dispatch(3)
+    dispatch(constexpr op_is_boolean_length)
 
 
 _llint_op_is_number:
@@ -1162,7 +1162,7 @@ _llint_op_is_number:
     tqnz t0, tagTypeNumber, t1
     orq ValueFalse, t1
     storeq t1, [cfr, t2, 8]
-    dispatch(3)
+    dispatch(constexpr op_is_number_length)
 
 
 _llint_op_is_cell_with_type:
@@ -1175,10 +1175,10 @@ _llint_op_is_cell_with_type:
     cbeq JSCell::m_type[t3], t0, t1
     orq ValueFalse, t1
     storeq t1, [cfr, t2, 8]
-    dispatch(4)
+    dispatch(constexpr op_is_cell_with_type_length)
 .notCellCase:
     storeq ValueFalse, [cfr, t2, 8]
-    dispatch(4)
+    dispatch(constexpr op_is_cell_with_type_length)
 
 
 _llint_op_is_object:
@@ -1190,10 +1190,10 @@ _llint_op_is_object:
     cbaeq JSCell::m_type[t0], ObjectType, t1
     orq ValueFalse, t1
     storeq t1, [cfr, t2, 8]
-    dispatch(3)
+    dispatch(constexpr op_is_object_length)
 .opIsObjectNotCell:
     storeq ValueFalse, [cfr, t2, 8]
-    dispatch(3)
+    dispatch(constexpr op_is_object_length)
 
 
 macro loadPropertyAtVariableOffset(propertyOffsetAsInt, objectAndStorage, value)
@@ -1233,11 +1233,11 @@ _llint_op_get_by_id:
     loadPropertyAtVariableOffset(t1, t3, t0)
     storeq t0, [cfr, t2, 8]
     valueProfile(t0, 8, t1)
-    dispatch(9)
+    dispatch(constexpr op_get_by_id_length)
 
 .opGetByIdSlow:
     callOpcodeSlowPath(_llint_slow_path_get_by_id)
-    dispatch(9)
+    dispatch(constexpr op_get_by_id_length)
 
 
 _llint_op_get_by_id_proto_load:
@@ -1253,11 +1253,11 @@ _llint_op_get_by_id_proto_load:
     loadPropertyAtVariableOffset(t1, t3, t0)
     storeq t0, [cfr, t2, 8]
     valueProfile(t0, 8, t1)
-    dispatch(9)
+    dispatch(constexpr op_get_by_id_proto_load_length)
 
 .opGetByIdProtoSlow:
     callOpcodeSlowPath(_llint_slow_path_get_by_id)
-    dispatch(9)
+    dispatch(constexpr op_get_by_id_proto_load_length)
 
 
 _llint_op_get_by_id_unset:
@@ -1270,11 +1270,11 @@ _llint_op_get_by_id_unset:
     loadisFromInstruction(1, t2)
     storeq ValueUndefined, [cfr, t2, 8]
     valueProfile(ValueUndefined, 8, t1)
-    dispatch(9)
+    dispatch(constexpr op_get_by_id_unset_length)
 
 .opGetByIdUnsetSlow:
     callOpcodeSlowPath(_llint_slow_path_get_by_id)
-    dispatch(9)
+    dispatch(constexpr op_get_by_id_unset_length)
 
 
 _llint_op_get_array_length:
@@ -1293,11 +1293,11 @@ _llint_op_get_array_length:
     orq tagTypeNumber, t0
     valueProfile(t0, 8, t2)
     storeq t0, [cfr, t1, 8]
-    dispatch(9)
+    dispatch(constexpr op_get_array_length_length)
 
 .opGetArrayLengthSlow:
     callOpcodeSlowPath(_llint_slow_path_get_by_id)
-    dispatch(9)
+    dispatch(constexpr op_get_array_length_length)
 
 
 _llint_op_put_by_id:
@@ -1436,11 +1436,11 @@ _llint_op_put_by_id:
     loadisFromInstruction(5, t1)
     storePropertyAtVariableOffset(t1, t0, t2)
     writeBarrierOnOperands(1, 3)
-    dispatch(9)
+    dispatch(constexpr op_put_by_id_length)
 
 .opPutByIdSlow:
     callOpcodeSlowPath(_llint_slow_path_put_by_id)
-    dispatch(9)
+    dispatch(constexpr op_put_by_id_length)
 
 macro finishGetByVal(result, scratch)
     loadisFromInstruction(1, scratch)
@@ -1503,7 +1503,7 @@ _llint_op_get_by_val:
 .opGetByValDone:
     storeq t2, [cfr, t0, 8]
     valueProfile(t2, 5, t0)
-    dispatch(6)
+    dispatch(constexpr op_get_by_val_length)
 
 .opGetByValOutOfBounds:
     loadpFromInstruction(4, t0)
@@ -1579,7 +1579,7 @@ _llint_op_get_by_val:
 
 .opGetByValSlow:
     callOpcodeSlowPath(_llint_slow_path_get_by_val)
-    dispatch(6)
+    dispatch(constexpr op_get_by_val_length)
 
 
 macro contiguousPutByVal(storeCallback)
@@ -1917,11 +1917,11 @@ _llint_op_to_primitive:
     bbaeq JSCell::m_type[t0], ObjectType, .opToPrimitiveSlowCase
 .opToPrimitiveIsImm:
     storeq t0, [cfr, t3, 8]
-    dispatch(3)
+    dispatch(constexpr op_to_primitive_length)
 
 .opToPrimitiveSlowCase:
     callOpcodeSlowPath(_slow_path_to_primitive)
-    dispatch(3)
+    dispatch(constexpr op_to_primitive_length)
 
 
 _llint_op_catch:
@@ -1963,7 +1963,7 @@ _llint_op_catch:
     storeq t3, [cfr, t2, 8]
 
     traceExecution()
-    dispatch(3)
+    dispatch(constexpr op_catch_length)
 
 
 _llint_op_end:
@@ -2075,55 +2075,55 @@ _llint_op_resolve_scope:
 #rGlobalProperty:
     bineq t0, GlobalProperty, .rGlobalVar
     getConstantScope(1)
-    dispatch(7)
+    dispatch(constexpr op_resolve_scope_length)
 
 .rGlobalVar:
     bineq t0, GlobalVar, .rGlobalLexicalVar
     getConstantScope(1)
-    dispatch(7)
+    dispatch(constexpr op_resolve_scope_length)
 
 .rGlobalLexicalVar:
     bineq t0, GlobalLexicalVar, .rClosureVar
     getConstantScope(1)
-    dispatch(7)
+    dispatch(constexpr op_resolve_scope_length)
 
 .rClosureVar:
     bineq t0, ClosureVar, .rModuleVar
     resolveScope()
-    dispatch(7)
+    dispatch(constexpr op_resolve_scope_length)
 
 .rModuleVar:
     bineq t0, ModuleVar, .rGlobalPropertyWithVarInjectionChecks
     getConstantScope(1)
-    dispatch(7)
+    dispatch(constexpr op_resolve_scope_length)
 
 .rGlobalPropertyWithVarInjectionChecks:
     bineq t0, GlobalPropertyWithVarInjectionChecks, .rGlobalVarWithVarInjectionChecks
     varInjectionCheck(.rDynamic)
     getConstantScope(1)
-    dispatch(7)
+    dispatch(constexpr op_resolve_scope_length)
 
 .rGlobalVarWithVarInjectionChecks:
     bineq t0, GlobalVarWithVarInjectionChecks, .rGlobalLexicalVarWithVarInjectionChecks
     varInjectionCheck(.rDynamic)
     getConstantScope(1)
-    dispatch(7)
+    dispatch(constexpr op_resolve_scope_length)
 
 .rGlobalLexicalVarWithVarInjectionChecks:
     bineq t0, GlobalLexicalVarWithVarInjectionChecks, .rClosureVarWithVarInjectionChecks
     varInjectionCheck(.rDynamic)
     getConstantScope(1)
-    dispatch(7)
+    dispatch(constexpr op_resolve_scope_length)
 
 .rClosureVarWithVarInjectionChecks:
     bineq t0, ClosureVarWithVarInjectionChecks, .rDynamic
     varInjectionCheck(.rDynamic)
     resolveScope()
-    dispatch(7)
+    dispatch(constexpr op_resolve_scope_length)
 
 .rDynamic:
     callOpcodeSlowPath(_slow_path_resolve_scope)
-    dispatch(7)
+    dispatch(constexpr op_resolve_scope_length)
 
 
 macro loadWithStructureCheck(operand, slowPath)
@@ -2168,12 +2168,12 @@ _llint_op_get_from_scope:
     bineq t0, GlobalProperty, .gGlobalVar
     loadWithStructureCheck(2, .gDynamic)
     getProperty()
-    dispatch(8)
+    dispatch(constexpr op_get_from_scope_length)
 
 .gGlobalVar:
     bineq t0, GlobalVar, .gGlobalLexicalVar
     getGlobalVar(macro(v) end)
-    dispatch(8)
+    dispatch(constexpr op_get_from_scope_length)
 
 .gGlobalLexicalVar:
     bineq t0, GlobalLexicalVar, .gClosureVar
@@ -2181,25 +2181,25 @@ _llint_op_get_from_scope:
         macro (value)
             bqeq value, ValueEmpty, .gDynamic
         end)
-    dispatch(8)
+    dispatch(constexpr op_get_from_scope_length)
 
 .gClosureVar:
     bineq t0, ClosureVar, .gGlobalPropertyWithVarInjectionChecks
     loadVariable(2, t0)
     getClosureVar()
-    dispatch(8)
+    dispatch(constexpr op_get_from_scope_length)
 
 .gGlobalPropertyWithVarInjectionChecks:
     bineq t0, GlobalPropertyWithVarInjectionChecks, .gGlobalVarWithVarInjectionChecks
     loadWithStructureCheck(2, .gDynamic)
     getProperty()
-    dispatch(8)
+    dispatch(constexpr op_get_from_scope_length)
 
 .gGlobalVarWithVarInjectionChecks:
     bineq t0, GlobalVarWithVarInjectionChecks, .gGlobalLexicalVarWithVarInjectionChecks
     varInjectionCheck(.gDynamic)
     getGlobalVar(macro(v) end)
-    dispatch(8)
+    dispatch(constexpr op_get_from_scope_length)
 
 .gGlobalLexicalVarWithVarInjectionChecks:
     bineq t0, GlobalLexicalVarWithVarInjectionChecks, .gClosureVarWithVarInjectionChecks
@@ -2208,18 +2208,18 @@ _llint_op_get_from_scope:
         macro (value)
             bqeq value, ValueEmpty, .gDynamic
         end)
-    dispatch(8)
+    dispatch(constexpr op_get_from_scope_length)
 
 .gClosureVarWithVarInjectionChecks:
     bineq t0, ClosureVarWithVarInjectionChecks, .gDynamic
     varInjectionCheck(.gDynamic)
     loadVariable(2, t0)
     getClosureVar()
-    dispatch(8)
+    dispatch(constexpr op_get_from_scope_length)
 
 .gDynamic:
     callOpcodeSlowPath(_llint_slow_path_get_from_scope)
-    dispatch(8)
+    dispatch(constexpr op_get_from_scope_length)
 
 
 macro putProperty()
@@ -2278,48 +2278,48 @@ _llint_op_put_to_scope:
     loadVariable(1, t0)
     putLocalClosureVar()
     writeBarrierOnOperands(1, 3)
-    dispatch(7)
+    dispatch(constexpr op_put_to_scope_length)
 
 .pGlobalProperty:
     bineq t0, GlobalProperty, .pGlobalVar
     loadWithStructureCheck(1, .pDynamic)
     putProperty()
     writeBarrierOnOperands(1, 3)
-    dispatch(7)
+    dispatch(constexpr op_put_to_scope_length)
 
 .pGlobalVar:
     bineq t0, GlobalVar, .pGlobalLexicalVar
     writeBarrierOnGlobalObject(3)
     putGlobalVariable()
-    dispatch(7)
+    dispatch(constexpr op_put_to_scope_length)
 
 .pGlobalLexicalVar:
     bineq t0, GlobalLexicalVar, .pClosureVar
     writeBarrierOnGlobalLexicalEnvironment(3)
     checkTDZInGlobalPutToScopeIfNecessary()
     putGlobalVariable()
-    dispatch(7)
+    dispatch(constexpr op_put_to_scope_length)
 
 .pClosureVar:
     bineq t0, ClosureVar, .pGlobalPropertyWithVarInjectionChecks
     loadVariable(1, t0)
     putClosureVar()
     writeBarrierOnOperands(1, 3)
-    dispatch(7)
+    dispatch(constexpr op_put_to_scope_length)
 
 .pGlobalPropertyWithVarInjectionChecks:
     bineq t0, GlobalPropertyWithVarInjectionChecks, .pGlobalVarWithVarInjectionChecks
     loadWithStructureCheck(1, .pDynamic)
     putProperty()
     writeBarrierOnOperands(1, 3)
-    dispatch(7)
+    dispatch(constexpr op_put_to_scope_length)
 
 .pGlobalVarWithVarInjectionChecks:
     bineq t0, GlobalVarWithVarInjectionChecks, .pGlobalLexicalVarWithVarInjectionChecks
     writeBarrierOnGlobalObject(3)
     varInjectionCheck(.pDynamic)
     putGlobalVariable()
-    dispatch(7)
+    dispatch(constexpr op_put_to_scope_length)
 
 .pGlobalLexicalVarWithVarInjectionChecks:
     bineq t0, GlobalLexicalVarWithVarInjectionChecks, .pClosureVarWithVarInjectionChecks
@@ -2327,7 +2327,7 @@ _llint_op_put_to_scope:
     varInjectionCheck(.pDynamic)
     checkTDZInGlobalPutToScopeIfNecessary()
     putGlobalVariable()
-    dispatch(7)
+    dispatch(constexpr op_put_to_scope_length)
 
 .pClosureVarWithVarInjectionChecks:
     bineq t0, ClosureVarWithVarInjectionChecks, .pModuleVar
@@ -2335,16 +2335,16 @@ _llint_op_put_to_scope:
     loadVariable(1, t0)
     putClosureVar()
     writeBarrierOnOperands(1, 3)
-    dispatch(7)
+    dispatch(constexpr op_put_to_scope_length)
 
 .pModuleVar:
     bineq t0, ModuleVar, .pDynamic
     callOpcodeSlowPath(_slow_path_throw_strict_mode_readonly_property_write_error)
-    dispatch(7)
+    dispatch(constexpr op_put_to_scope_length)
 
 .pDynamic:
     callOpcodeSlowPath(_llint_slow_path_put_to_scope)
-    dispatch(7)
+    dispatch(constexpr op_put_to_scope_length)
 
 
 _llint_op_get_from_arguments:
@@ -2355,7 +2355,7 @@ _llint_op_get_from_arguments:
     valueProfile(t0, 4, t1)
     loadisFromInstruction(1, t1)
     storeq t0, [cfr, t1, 8]
-    dispatch(5)
+    dispatch(constexpr op_get_from_arguments_length)
 
 
 _llint_op_put_to_arguments:
@@ -2366,7 +2366,7 @@ _llint_op_put_to_arguments:
     loadConstantOrVariable(t3, t2)
     storeq t2, DirectArguments_storage[t0, t1, 8]
     writeBarrierOnOperands(1, 3)
-    dispatch(4)
+    dispatch(constexpr op_put_to_arguments_length)
 
 
 _llint_op_get_parent_scope:
@@ -2375,7 +2375,7 @@ _llint_op_get_parent_scope:
     loadp JSScope::m_next[t0], t0
     loadisFromInstruction(1, t1)
     storeq t0, [cfr, t1, 8]
-    dispatch(3)
+    dispatch(constexpr op_get_parent_scope_length)
 
 
 _llint_op_profile_type:
@@ -2416,13 +2416,13 @@ _llint_op_profile_type:
     callOpcodeSlowPath(_slow_path_profile_type_clear_log)
 
 .opProfileTypeDone:
-    dispatch(6)
+    dispatch(constexpr op_profile_type_length)
 
 _llint_op_profile_control_flow:
     traceExecution()
     loadpFromInstruction(1, t0)
     addq 1, BasicBlockLocation::m_executionCount[t0]
-    dispatch(2)
+    dispatch(constexpr op_profile_control_flow_length)
 
 
 _llint_op_get_rest_length:
@@ -2439,7 +2439,7 @@ _llint_op_get_rest_length:
     orq tagTypeNumber, t0
     loadisFromInstruction(1, t1)
     storeq t0, [cfr, t1, 8]
-    dispatch(3)
+    dispatch(constexpr op_get_rest_length_length)
 
 
 _llint_op_log_shadow_chicken_prologue:
@@ -2452,10 +2452,10 @@ _llint_op_log_shadow_chicken_prologue:
     storep t1, ShadowChicken::Packet::callee[t0]
     loadVariable(1, t1)
     storep t1, ShadowChicken::Packet::scope[t0]
-    dispatch(2)
+    dispatch(constexpr op_log_shadow_chicken_prologue_length)
 .opLogShadowChickenPrologueSlow:
     callOpcodeSlowPath(_llint_slow_path_log_shadow_chicken_prologue)
-    dispatch(2)
+    dispatch(constexpr op_log_shadow_chicken_prologue_length)
 
 
 _llint_op_log_shadow_chicken_tail:
@@ -2470,7 +2470,7 @@ _llint_op_log_shadow_chicken_tail:
     loadp CodeBlock[cfr], t1
     storep t1, ShadowChicken::Packet::codeBlock[t0]
     storei PC, ShadowChicken::Packet::callSiteIndex[t0]
-    dispatch(3)
+    dispatch(constexpr op_log_shadow_chicken_tail_length)
 .opLogShadowChickenTailSlow:
     callOpcodeSlowPath(_llint_slow_path_log_shadow_chicken_tail)
-    dispatch(3)
+    dispatch(constexpr op_log_shadow_chicken_tail_length)
index fa00402..8d76565 100644 (file)
@@ -315,7 +315,7 @@ begin
     configurationList = offsetsAndConfigurationIndex(offsetsFile)
 rescue MissingMagicValuesException
     $stderr.puts "offlineasm: No magic values found. Skipping assembly file generation."
-    exit 0
+    exit 1
 end
 
 # The MS compiler doesn't accept DWARF2 debug annotations.
@@ -366,7 +366,7 @@ File.open(outputFlnm, "w") {
                 $enableDebugAnnotations = false
             end
 
-            lowLevelAST = lowLevelAST.resolve(*buildOffsetsMap(lowLevelAST, offsetsList))
+            lowLevelAST = lowLevelAST.resolve(buildOffsetsMap(lowLevelAST, offsetsList))
             lowLevelAST.validate
             emitCodeInConfiguration(concreteSettings, lowLevelAST, backend) {
                 $asm.inAsm {
index 1241b7f..e2bc51d 100644 (file)
@@ -945,23 +945,53 @@ class Error < NoChildren
     end
 end
 
+class ConstExpr < NoChildren
+    attr_reader :variable, :value
+
+    def initialize(codeOrigin, value)
+        super(codeOrigin)
+        @value = value
+    end
+
+    @@mapping = {}
+
+    def self.forName(codeOrigin, text)
+        unless @@mapping[text]
+            @@mapping[text] = ConstExpr.new(codeOrigin, text)
+        end
+        @@mapping[text]
+    end
+
+    def dump
+        "constexpr (#{@value.dump})"
+    end
+
+    def <=>(other)
+        @value <=> other.value
+    end
+
+    def immediate?
+        true
+    end
+end
+
 class ConstDecl < Node
     attr_reader :variable, :value
-    
+
     def initialize(codeOrigin, variable, value)
         super(codeOrigin)
         @variable = variable
         @value = value
     end
-    
+
     def children
         [@variable, @value]
     end
-    
+
     def mapChildren
         ConstDecl.new(codeOrigin, (yield @variable), (yield @value))
     end
-    
+
     def dump
         "const #{@variable.dump} = #{@value.dump}"
     end
index aafa934..160b94c 100644 (file)
@@ -108,6 +108,12 @@ class Sizeof
     end
 end
 
+class ConstExpr
+    def offsetsPruneTo(sequence)
+        sequence.list << self
+    end
+end
+
 prunedAST = originalAST.offsetsPrune
 
 File.open(outputFlnm, "w") {
@@ -119,9 +125,10 @@ File.open(outputFlnm, "w") {
         | settings, ast, backend, index |
         offsetsList = ast.filter(StructOffset).uniq.sort
         sizesList = ast.filter(Sizeof).uniq.sort
-        length += OFFSET_HEADER_MAGIC_NUMBERS.size + (OFFSET_MAGIC_NUMBERS.size + 1) * (1 + offsetsList.size + sizesList.size)
+        constsList = ast.filter(ConstExpr).uniq.sort
+        length += OFFSET_HEADER_MAGIC_NUMBERS.size + (OFFSET_MAGIC_NUMBERS.size + 1) * (1 + offsetsList.size + sizesList.size + constsList.size)
     }
-    outp.puts "static const unsigned extractorTable[#{length}] = {"
+    outp.puts "static const int64_t extractorTable[#{length}] = {"
     emitCodeInAllConfigurations(prunedAST) {
         | settings, ast, backend, index |
         OFFSET_HEADER_MAGIC_NUMBERS.each {
@@ -131,7 +138,8 @@ File.open(outputFlnm, "w") {
 
         offsetsList = ast.filter(StructOffset).uniq.sort
         sizesList = ast.filter(Sizeof).uniq.sort
-        
+        constsList = ast.filter(ConstExpr).uniq.sort
+
         emitMagicNumber
         outp.puts "#{index},"
         offsetsList.each {
@@ -140,10 +148,28 @@ File.open(outputFlnm, "w") {
             outp.puts "OFFLINE_ASM_OFFSETOF(#{offset.struct}, #{offset.field}),"
         }
         sizesList.each {
-            | offset |
+            | sizeof |
+            emitMagicNumber
+            outp.puts "sizeof(#{sizeof.struct}),"
+        }
+        constsList.each {
+            | const |
             emitMagicNumber
-            outp.puts "sizeof(#{offset.struct}),"
+            outp.puts "static_cast<int64_t>(#{const.value}),"
         }
     }
     outp.puts "};"
+
+    emitCodeInAllConfigurations(prunedAST) {
+        | settings, ast, backend, index |
+        constsList = ast.filter(ConstExpr).uniq.sort
+
+        constsList.each_with_index {
+            | const, index |
+            outp.puts "constexpr int64_t isConst#{index} = static_cast<int64_t>(#{const.value});"
+            # Make a trivally true static assert that uses the last value...
+            outp.puts "static_assert(isConst#{index} || true, \"\");"
+        }
+    }
+
 }
index 50b963b..2c1c1b7 100644 (file)
 require "config"
 require "ast"
 
-def to32Bit(value)
-    if value > 0x7fffffff
-        value -= 1 << 32
-    end
-    value
-end
-
-OFFSET_HEADER_MAGIC_NUMBERS = [ to32Bit(0x9e43fd66), to32Bit(0x4379bfba) ]
-OFFSET_MAGIC_NUMBERS = [ to32Bit(0xec577ac7), to32Bit(0x0ff5e755) ]
+OFFSET_HEADER_MAGIC_NUMBERS = [ 0x2e43fd66, 0x4379bfba ]
+OFFSET_MAGIC_NUMBERS = [ 0x5c577ac7, 0x0ff5e755 ]
 
 #
 # MissingMagicValuesException
@@ -46,8 +39,9 @@ end
 #
 # offsetsList(ast)
 # sizesList(ast)
+# constsLists(ast)
 #
-# Returns a list of offsets and sizes used by the AST.
+# Returns a list of offsets, sizeofs, and consts used by the AST.
 #
 
 def offsetsList(ast)
@@ -58,6 +52,10 @@ def sizesList(ast)
     ast.filter(Sizeof).uniq.sort
 end
 
+def constsList(ast)
+    ast.filter(ConstExpr).uniq.sort
+end
+
 #
 # offsetsAndConfigurationIndex(ast, file) ->
 #     [[offsets, index], ...]
@@ -73,17 +71,29 @@ def offsetsAndConfigurationIndex(file)
     def readInt(endianness, bytes)
         if endianness == :little
             # Little endian
-            (bytes[0] << 0 |
-             bytes[1] << 8 |
-             bytes[2] << 16 |
-             bytes[3] << 24)
+            number = (bytes[0] << 0  |
+                      bytes[1] << 8  |
+                      bytes[2] << 16 |
+                      bytes[3] << 24 |
+                      bytes[4] << 32 |
+                      bytes[5] << 40 |
+                      bytes[6] << 48 |
+                      bytes[7] << 56)
         else
             # Big endian
-            (bytes[0] << 24 |
-             bytes[1] << 16 |
-             bytes[2] << 8 |
-             bytes[3] << 0)
+            number = (bytes[0] << 56 |
+                      bytes[1] << 48 |
+                      bytes[2] << 40 |
+                      bytes[3] << 32 |
+                      bytes[4] << 24 |
+                      bytes[5] << 16 |
+                      bytes[6] << 8  |
+                      bytes[7] << 0)
+        end
+        if number > 0x7fffffff_ffffffff
+            number -= 1 << 64
         end
+        number
     end
     
     def prepareMagic(endianness, numbers)
@@ -91,7 +101,7 @@ def offsetsAndConfigurationIndex(file)
         numbers.each {
             | number |
             currentBytes = []
-            4.times {
+            8.times {
                 currentBytes << (number & 0xff)
                 number >>= 8
             }
@@ -170,25 +180,30 @@ def offsetsAndConfigurationIndex(file)
 end
 
 #
-# buildOffsetsMap(ast, offsetsList) -> [offsets, sizes]
+# buildOffsetsMap(ast, extractedConstants) -> map
 #
-# Builds a mapping between StructOffset nodes and their values.
+# Builds a mapping between StructOffset, Sizeof, and ConstExpr nodes and their values.
 #
 
-def buildOffsetsMap(ast, offsetsList)
-    offsetsMap = {}
-    sizesMap = {}
+def buildOffsetsMap(ast, extractedConstants)
+    map = {}
     astOffsetsList = offsetsList(ast)
     astSizesList = sizesList(ast)
-    raise unless astOffsetsList.size + astSizesList.size == offsetsList.size
-    offsetsList(ast).each_with_index {
+    astConstsList = constsList(ast)
+
+    raise unless astOffsetsList.size + astSizesList.size + astConstsList.size == extractedConstants.size
+    astOffsetsList.each_with_index {
         | structOffset, index |
-        offsetsMap[structOffset] = offsetsList.shift
+        map[structOffset] = extractedConstants.shift
     }
-    sizesList(ast).each_with_index {
+    astSizesList.each_with_index {
         | sizeof, index |
-        sizesMap[sizeof] = offsetsList.shift
+        map[sizeof] = extractedConstants.shift
+    }
+    astConstsList.each_with_index {
+        | const, index |
+        map[const] = extractedConstants.shift
     }
-    [offsetsMap, sizesMap]
+    map
 end
 
index b445112..907021d 100644 (file)
@@ -3,7 +3,7 @@
 # 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
+# 1. Redistributions of source code must retain the above copyrighht
 #    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
@@ -222,7 +222,7 @@ def isInstruction(token)
 end
 
 def isKeyword(token)
-    token =~ /\A((true)|(false)|(if)|(then)|(else)|(elsif)|(end)|(and)|(or)|(not)|(global)|(macro)|(const)|(sizeof)|(error)|(include))\Z/ or
+    token =~ /\A((true)|(false)|(if)|(then)|(else)|(elsif)|(end)|(and)|(or)|(not)|(global)|(macro)|(const)|(constexpr)|(sizeof)|(error)|(include))\Z/ or
         token =~ REGISTER_PATTERN or
         isInstruction(token)
 end
@@ -417,6 +417,30 @@ class Parser
         raise if names.empty?
         [codeOrigin, names]
     end
+
+    def parseTextInParens
+        skipNewLine
+        codeOrigin = @tokens[@idx].codeOrigin
+        raise unless @tokens[@idx] == "("
+        @idx += 1
+        # need at least one item
+        raise if @tokens[@idx] == ")"
+        numEnclosedParens = 0
+        text = []
+        while @tokens[@idx] != ")" || numEnclosedParens > 0
+            if @tokens[@idx] == "("
+                numEnclosedParens += 1
+            elsif @tokens[@idx] == ")"
+                numEnclosedParens -= 1
+            end
+
+            text << @tokens[@idx].string
+            @idx += 1
+        end
+        @idx += 1
+        return [codeOrigin, text]
+    end
+
     
     def parseExpressionAtom
         skipNewLine
@@ -453,6 +477,17 @@ class Parser
             @idx += 1
             codeOrigin, names = parseColonColon
             Sizeof.forName(codeOrigin, names.join('::'))
+        elsif @tokens[@idx] == "constexpr"
+            @idx += 1
+            skipNewLine
+            if @tokens[@idx] == "("
+                codeOrigin, text = parseTextInParens
+                text = text.join
+            else
+                codeOrigin, text = parseColonColon
+                text = text.join("::")
+            end
+            ConstExpr.forName(codeOrigin, text)
         elsif isLabel @tokens[@idx]
             result = LabelReference.new(@tokens[@idx].codeOrigin, Label.forName(@tokens[@idx].codeOrigin, @tokens[@idx].string))
             @idx += 1
@@ -481,7 +516,7 @@ class Parser
     end
     
     def couldBeExpression
-        @tokens[@idx] == "-" or @tokens[@idx] == "~" or @tokens[@idx] == "sizeof" or isInteger(@tokens[@idx]) or isString(@tokens[@idx]) or isVariable(@tokens[@idx]) or @tokens[@idx] == "("
+        @tokens[@idx] == "-" or @tokens[@idx] == "~" or @tokens[@idx] == "sizeof" or @tokens[@idx] == "constexpr" or isInteger(@tokens[@idx]) or isString(@tokens[@idx]) or isVariable(@tokens[@idx]) or @tokens[@idx] == "("
     end
     
     def parseExpressionAdd
index 84dd041..e0c4a68 100644 (file)
@@ -249,32 +249,46 @@ end
 #
 
 class Node
-    def resolveOffsets(offsets, sizes)
+    def resolveOffsets(constantsMap)
         mapChildren {
             | child |
-            child.resolveOffsets(offsets, sizes)
+            child.resolveOffsets(constantsMap)
         }
     end
 end
 
 class StructOffset
-    def resolveOffsets(offsets, sizes)
-        if offsets[self]
-            Immediate.new(codeOrigin, offsets[self])
+    def resolveOffsets(constantsMap)
+        if constantsMap[self]
+            Immediate.new(codeOrigin, constantsMap[self])
         else
-            self
+            puts "Could not find #{self.inspect} in #{constantsMap.keys.inspect}"
+            puts "sizes = #{constantsMap.inspect}"
+            raise
         end
     end
 end
 
 class Sizeof
-    def resolveOffsets(offsets, sizes)
-        if sizes[self]
-            Immediate.new(codeOrigin, sizes[self])
+    def resolveOffsets(constantsMap)
+        if constantsMap[self]
+            Immediate.new(codeOrigin, constantsMap[self])
         else
-            puts "Could not find #{self.inspect} in #{sizes.keys.inspect}"
-            puts "sizes = #{sizes.inspect}"
-            self
+            puts "Could not find #{self.inspect} in #{constantsMap.keys.inspect}"
+            puts "sizes = #{constantsMap.inspect}"
+            raise
+        end
+    end
+end
+
+class ConstExpr
+    def resolveOffsets(constantsMap)
+        if constantsMap[self]
+            Immediate.new(codeOrigin, constantsMap[self])
+        else
+            puts "Could not find #{self.inspect} in #{constantsMap.keys.inspect}"
+            puts "sizes = #{constantsMap.inspect}"
+            raise
         end
     end
 end
@@ -377,8 +391,8 @@ end
 #
 
 class Node
-    def resolve(offsets, sizes)
-        demacroify({}).resolveOffsets(offsets, sizes).fold
+    def resolve(constantsMap)
+        demacroify({}).resolveOffsets(constantsMap).fold
     end
 end