X-Git-Url: https://git.saurik.com/apple/javascriptcore.git/blobdiff_plain/9dae56ea45a0f5f8136a5c93d6f3a7f99399ca73..2d39b0e377c0896910ee49ae70082ba665faf986:/interpreter/Register.h diff --git a/interpreter/Register.h b/interpreter/Register.h index ff36bbc..054b570 100644 --- a/interpreter/Register.h +++ b/interpreter/Register.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Apple Inc. All rights reserved. + * Copyright (C) 2008, 2009 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -10,7 +10,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * 3. Neither the name of Apple Inc. ("Apple") nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * @@ -29,265 +29,183 @@ #ifndef Register_h #define Register_h -#include "JSValue.h" +#include "JSCJSValue.h" +#include #include namespace JSC { - class Arguments; class CodeBlock; class ExecState; class JSActivation; - class JSFunction; + class JSObject; class JSPropertyNameIterator; - class ScopeChainNode; - - struct Instruction; + class JSScope; typedef ExecState CallFrame; class Register { + WTF_MAKE_FAST_ALLOCATED; public: Register(); - Register(JSValuePtr); - - JSValuePtr jsValue(CallFrame*) const; - JSValuePtr getJSValue() const; - bool marked() const; - void mark(); + Register(const JSValue&); + Register& operator=(const JSValue&); + JSValue jsValue() const; + EncodedJSValue encodedJSValue() const; - private: - friend class ExecState; - friend class Interpreter; - - // Only CallFrame and Interpreter should use these functions. - - Register(intptr_t); - - Register(JSActivation*); - Register(Arguments*); - Register(CallFrame*); - Register(CodeBlock*); - Register(JSFunction*); - Register(JSPropertyNameIterator*); - Register(ScopeChainNode*); - Register(Instruction*); - - intptr_t i() const; - void* v() const; + Register& operator=(CallFrame*); + Register& operator=(CodeBlock*); + Register& operator=(JSScope*); + int32_t i() const; JSActivation* activation() const; - Arguments* arguments() const; CallFrame* callFrame() const; CodeBlock* codeBlock() const; - JSFunction* function() const; + JSObject* function() const; JSPropertyNameIterator* propertyNameIterator() const; - ScopeChainNode* scopeChain() const; - Instruction* vPC() const; + JSScope* scope() const; + int32_t unboxedInt32() const; + int64_t unboxedInt52() const; + int64_t unboxedStrictInt52() const; + bool unboxedBoolean() const; + double unboxedDouble() const; + JSCell* unboxedCell() const; + int32_t payload() const; + int32_t tag() const; + int32_t& payload(); + int32_t& tag(); + + static Register withInt(int32_t i) + { + Register r = jsNumber(i); + return r; + } + + static Register withCallee(JSObject* callee); + private: union { - intptr_t i; - void* v; - JSValueEncodedAsPointer* value; - - JSActivation* activation; - Arguments* arguments; + EncodedJSValue value; CallFrame* callFrame; CodeBlock* codeBlock; - JSFunction* function; - JSPropertyNameIterator* propertyNameIterator; - ScopeChainNode* scopeChain; - Instruction* vPC; + EncodedValueDescriptor encodedValue; + double number; + int64_t integer; } u; - -#ifndef NDEBUG - enum { - EmptyType, - - IntType, - ValueType, - - ActivationType, - ArgumentsType, - CallFrameType, - CodeBlockType, - FunctionType, - InstructionType, - PropertyNameIteratorType, - RegisterType, - ScopeChainNodeType - } m_type; -#endif }; -#ifndef NDEBUG - #define SET_TYPE(type) m_type = (type) - // FIXME: The CTI code to put value into registers doesn't set m_type. - // Once it does, we can turn this assertion back on. - #define ASSERT_TYPE(type) -#else - #define SET_TYPE(type) - #define ASSERT_TYPE(type) -#endif - ALWAYS_INLINE Register::Register() { #ifndef NDEBUG - SET_TYPE(EmptyType); - u.value = JSValuePtr::encode(noValue()); + *this = JSValue(); #endif } - ALWAYS_INLINE Register::Register(JSValuePtr v) + ALWAYS_INLINE Register::Register(const JSValue& v) { - SET_TYPE(ValueType); - u.value = JSValuePtr::encode(v); + u.value = JSValue::encode(v); } - // This function is scaffolding for legacy clients. It will eventually go away. - ALWAYS_INLINE JSValuePtr Register::jsValue(CallFrame*) const - { - // Once registers hold doubles, this function will allocate a JSValue* - // if the register doesn't hold one already. - ASSERT_TYPE(ValueType); - return JSValuePtr::decode(u.value); - } - - ALWAYS_INLINE JSValuePtr Register::getJSValue() const - { - ASSERT_TYPE(JSValueType); - return JSValuePtr::decode(u.value); - } - - ALWAYS_INLINE bool Register::marked() const + ALWAYS_INLINE Register& Register::operator=(const JSValue& v) { - return getJSValue().marked(); + u.value = JSValue::encode(v); + return *this; } - ALWAYS_INLINE void Register::mark() + ALWAYS_INLINE JSValue Register::jsValue() const { - getJSValue().mark(); + return JSValue::decode(u.value); } - - // Interpreter functions - ALWAYS_INLINE Register::Register(Arguments* arguments) + ALWAYS_INLINE EncodedJSValue Register::encodedJSValue() const { - SET_TYPE(ArgumentsType); - u.arguments = arguments; + return u.value; } - ALWAYS_INLINE Register::Register(JSActivation* activation) - { - SET_TYPE(ActivationType); - u.activation = activation; - } + // Interpreter functions - ALWAYS_INLINE Register::Register(CallFrame* callFrame) + ALWAYS_INLINE Register& Register::operator=(CallFrame* callFrame) { - SET_TYPE(CallFrameType); u.callFrame = callFrame; + return *this; } - ALWAYS_INLINE Register::Register(CodeBlock* codeBlock) + ALWAYS_INLINE Register& Register::operator=(CodeBlock* codeBlock) { - SET_TYPE(CodeBlockType); u.codeBlock = codeBlock; + return *this; } - ALWAYS_INLINE Register::Register(JSFunction* function) + ALWAYS_INLINE int32_t Register::i() const { - SET_TYPE(FunctionType); - u.function = function; + return jsValue().asInt32(); } - ALWAYS_INLINE Register::Register(Instruction* vPC) + ALWAYS_INLINE CallFrame* Register::callFrame() const { - SET_TYPE(InstructionType); - u.vPC = vPC; + return u.callFrame; } - - ALWAYS_INLINE Register::Register(ScopeChainNode* scopeChain) + + ALWAYS_INLINE CodeBlock* Register::codeBlock() const { - SET_TYPE(ScopeChainNodeType); - u.scopeChain = scopeChain; + return u.codeBlock; } - ALWAYS_INLINE Register::Register(JSPropertyNameIterator* propertyNameIterator) + ALWAYS_INLINE int32_t Register::unboxedInt32() const { - SET_TYPE(PropertyNameIteratorType); - u.propertyNameIterator = propertyNameIterator; + return payload(); } - ALWAYS_INLINE Register::Register(intptr_t i) + ALWAYS_INLINE int64_t Register::unboxedInt52() const { - SET_TYPE(IntType); - u.i = i; + return u.integer >> JSValue::int52ShiftAmount; } - ALWAYS_INLINE intptr_t Register::i() const + ALWAYS_INLINE int64_t Register::unboxedStrictInt52() const { - ASSERT_TYPE(IntType); - return u.i; - } - - ALWAYS_INLINE void* Register::v() const - { - return u.v; + return u.integer; } - ALWAYS_INLINE JSActivation* Register::activation() const + ALWAYS_INLINE bool Register::unboxedBoolean() const { - ASSERT_TYPE(ActivationType); - return u.activation; + return !!payload(); } - - ALWAYS_INLINE Arguments* Register::arguments() const - { - ASSERT_TYPE(ArgumentsType); - return u.arguments; - } - - ALWAYS_INLINE CallFrame* Register::callFrame() const + + ALWAYS_INLINE double Register::unboxedDouble() const { - ASSERT_TYPE(CallFrameType); - return u.callFrame; + return u.number; } - - ALWAYS_INLINE CodeBlock* Register::codeBlock() const + + ALWAYS_INLINE JSCell* Register::unboxedCell() const { - ASSERT_TYPE(CodeBlockType); - return u.codeBlock; +#if USE(JSVALUE64) + return u.encodedValue.ptr; +#else + return bitwise_cast(payload()); +#endif } - - ALWAYS_INLINE JSFunction* Register::function() const + + ALWAYS_INLINE int32_t Register::payload() const { - ASSERT_TYPE(FunctionType); - return u.function; + return u.encodedValue.asBits.payload; } - - ALWAYS_INLINE JSPropertyNameIterator* Register::propertyNameIterator() const + + ALWAYS_INLINE int32_t Register::tag() const { - ASSERT_TYPE(PropertyNameIteratorType); - return u.propertyNameIterator; + return u.encodedValue.asBits.tag; } - - ALWAYS_INLINE ScopeChainNode* Register::scopeChain() const + + ALWAYS_INLINE int32_t& Register::payload() { - ASSERT_TYPE(ScopeChainNodeType); - return u.scopeChain; + return u.encodedValue.asBits.payload; } - - ALWAYS_INLINE Instruction* Register::vPC() const + + ALWAYS_INLINE int32_t& Register::tag() { - ASSERT_TYPE(InstructionType); - return u.vPC; + return u.encodedValue.asBits.tag; } - #undef SET_TYPE - #undef ASSERT_TYPE - } // namespace JSC namespace WTF {