summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/llint/LowLevelInterpreter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/JavaScriptCore/llint/LowLevelInterpreter.cpp')
-rw-r--r--Source/JavaScriptCore/llint/LowLevelInterpreter.cpp118
1 files changed, 97 insertions, 21 deletions
diff --git a/Source/JavaScriptCore/llint/LowLevelInterpreter.cpp b/Source/JavaScriptCore/llint/LowLevelInterpreter.cpp
index ebfdadfdb..a9cb393b0 100644
--- a/Source/JavaScriptCore/llint/LowLevelInterpreter.cpp
+++ b/Source/JavaScriptCore/llint/LowLevelInterpreter.cpp
@@ -122,6 +122,98 @@ static double Ints2Double(uint32_t lo, uint32_t hi)
//============================================================================
+// CLoopRegister is the storage for an emulated CPU register.
+// It defines the policy of how ints smaller than intptr_t are packed into the
+// pseudo register, as well as hides endianness differences.
+
+struct CLoopRegister {
+ union {
+ intptr_t i;
+ uintptr_t u;
+#if USE(JSVALUE64)
+#if CPU(BIG_ENDIAN)
+ struct {
+ int32_t i32padding;
+ int32_t i32;
+ };
+ struct {
+ uint32_t u32padding;
+ uint32_t u32;
+ };
+ struct {
+ int8_t i8padding[7];
+ int8_t i8;
+ };
+ struct {
+ uint8_t u8padding[7];
+ uint8_t u8;
+ };
+#else // !CPU(BIG_ENDIAN)
+ struct {
+ int32_t i32;
+ int32_t i32padding;
+ };
+ struct {
+ uint32_t u32;
+ uint32_t u32padding;
+ };
+ struct {
+ int8_t i8;
+ int8_t i8padding[7];
+ };
+ struct {
+ uint8_t u8;
+ uint8_t u8padding[7];
+ };
+#endif // !CPU(BIG_ENDIAN)
+#else // !USE(JSVALUE64)
+ int32_t i32;
+ uint32_t u32;
+
+#if CPU(BIG_ENDIAN)
+ struct {
+ int8_t i8padding[3];
+ int8_t i8;
+ };
+ struct {
+ uint8_t u8padding[3];
+ uint8_t u8;
+ };
+
+#else // !CPU(BIG_ENDIAN)
+ struct {
+ int8_t i8;
+ int8_t i8padding[3];
+ };
+ struct {
+ uint8_t u8;
+ uint8_t u8padding[3];
+ };
+#endif // !CPU(BIG_ENDIAN)
+#endif // !USE(JSVALUE64)
+
+ int8_t* i8p;
+ void* vp;
+ ExecState* execState;
+ void* instruction;
+ NativeFunction nativeFunc;
+#if USE(JSVALUE64)
+ int64_t i64;
+ uint64_t u64;
+ EncodedJSValue encodedJSValue;
+ double castToDouble;
+#endif
+ Opcode opcode;
+ };
+
+#if USE(JSVALUE64)
+ inline void clearHighWord() { i32padding = 0; }
+#else
+ inline void clearHighWord() { }
+#endif
+};
+
+//============================================================================
// The llint C++ interpreter loop:
//
@@ -164,29 +256,12 @@ JSValue CLoop::execute(CallFrame* callFrame, OpcodeID bootstrapOpcodeId,
ASSERT(callFrame->globalData().topCallFrame == callFrame);
// Define the pseudo registers used by the LLINT C Loop backend:
- union CLoopRegister {
- intptr_t i;
- uintptr_t u;
- int32_t i32;
- uint32_t u32;
- int8_t i8;
- uint8_t u8;
- int8_t* i8p;
- void* vp;
- ExecState* execState;
- void* instruction;
- NativeFunction nativeFunc;
-#if USE(JSVALUE64)
- int64_t i64;
- EncodedJSValue encodedJSValue;
- double castToDouble;
-#endif
- Opcode opcode;
- };
+ ASSERT(sizeof(CLoopRegister) == sizeof(intptr_t));
+
union CLoopDoubleRegister {
double d;
#if USE(JSVALUE64)
- void* castToVoidPtr;
+ int64_t castToInt64;
#endif
};
@@ -311,6 +386,7 @@ JSValue CLoop::execute(CallFrame* callFrame, OpcodeID bootstrapOpcodeId,
#define DEFINE_OPCODE(__opcode) \
case __opcode: \
+ __opcode: \
RECORD_OPCODE_STATS(__opcode);
// Dispatch to the current PC's bytecode:
@@ -417,7 +493,7 @@ JSValue CLoop::execute(CallFrame* callFrame, OpcodeID bootstrapOpcodeId,
// compiler on all such labels:
#define LLINT_OPCODE_ENTRY(__opcode, length) \
UNUSED_LABEL(__opcode);
- FOR_EACH_LLINT_NATIVE_HELPER(LLINT_OPCODE_ENTRY)
+ FOR_EACH_OPCODE_ID(LLINT_OPCODE_ENTRY);
#undef LLINT_OPCODE_ENTRY