| Index: src/x64/codegen-x64.h
|
| ===================================================================
|
| --- src/x64/codegen-x64.h (revision 3716)
|
| +++ src/x64/codegen-x64.h (working copy)
|
| @@ -1,4 +1,4 @@
|
| -// Copyright 2009 the V8 project authors. All rights reserved.
|
| +// Copyright 2010 the V8 project authors. All rights reserved.
|
| // Redistribution and use in source and binary forms, with or without
|
| // modification, are permitted provided that the following conditions are
|
| // met:
|
| @@ -43,57 +43,70 @@
|
| // -------------------------------------------------------------------------
|
| // Reference support
|
|
|
| -// A reference is a C++ stack-allocated object that keeps an ECMA
|
| -// reference on the execution stack while in scope. For variables
|
| -// the reference is empty, indicating that it isn't necessary to
|
| -// store state on the stack for keeping track of references to those.
|
| -// For properties, we keep either one (named) or two (indexed) values
|
| -// on the execution stack to represent the reference.
|
| -
|
| +// A reference is a C++ stack-allocated object that puts a
|
| +// reference on the virtual frame. The reference may be consumed
|
| +// by GetValue, TakeValue, SetValue, and Codegen::UnloadReference.
|
| +// When the lifetime (scope) of a valid reference ends, it must have
|
| +// been consumed, and be in state UNLOADED.
|
| class Reference BASE_EMBEDDED {
|
| public:
|
| // The values of the types is important, see size().
|
| - enum Type { ILLEGAL = -1, SLOT = 0, NAMED = 1, KEYED = 2 };
|
| - Reference(CodeGenerator* cgen, Expression* expression);
|
| + enum Type { UNLOADED = -2, ILLEGAL = -1, SLOT = 0, NAMED = 1, KEYED = 2 };
|
| +
|
| + Reference(CodeGenerator* cgen,
|
| + Expression* expression,
|
| + bool persist_after_get = false);
|
| ~Reference();
|
|
|
| Expression* expression() const { return expression_; }
|
| Type type() const { return type_; }
|
| void set_type(Type value) {
|
| - ASSERT(type_ == ILLEGAL);
|
| + ASSERT_EQ(ILLEGAL, type_);
|
| type_ = value;
|
| }
|
|
|
| + void set_unloaded() {
|
| + ASSERT_NE(ILLEGAL, type_);
|
| + ASSERT_NE(UNLOADED, type_);
|
| + type_ = UNLOADED;
|
| + }
|
| // The size the reference takes up on the stack.
|
| - int size() const { return (type_ == ILLEGAL) ? 0 : type_; }
|
| + int size() const {
|
| + return (type_ < SLOT) ? 0 : type_;
|
| + }
|
|
|
| bool is_illegal() const { return type_ == ILLEGAL; }
|
| bool is_slot() const { return type_ == SLOT; }
|
| bool is_property() const { return type_ == NAMED || type_ == KEYED; }
|
| + bool is_unloaded() const { return type_ == UNLOADED; }
|
|
|
| // Return the name. Only valid for named property references.
|
| Handle<String> GetName();
|
|
|
| // Generate code to push the value of the reference on top of the
|
| // expression stack. The reference is expected to be already on top of
|
| - // the expression stack, and it is left in place with its value above it.
|
| + // the expression stack, and it is consumed by the call unless the
|
| + // reference is for a compound assignment.
|
| + // If the reference is not consumed, it is left in place under its value.
|
| void GetValue();
|
|
|
| // Like GetValue except that the slot is expected to be written to before
|
| - // being read from again. Thae value of the reference may be invalidated,
|
| + // being read from again. The value of the reference may be invalidated,
|
| // causing subsequent attempts to read it to fail.
|
| void TakeValue();
|
|
|
| // Generate code to store the value on top of the expression stack in the
|
| // reference. The reference is expected to be immediately below the value
|
| - // on the expression stack. The stored value is left in place (with the
|
| - // reference intact below it) to support chained assignments.
|
| + // on the expression stack. The value is stored in the location specified
|
| + // by the reference, and is left on top of the stack, after the reference
|
| + // is popped from beneath it (unloaded).
|
| void SetValue(InitState init_state);
|
|
|
| private:
|
| CodeGenerator* cgen_;
|
| Expression* expression_;
|
| Type type_;
|
| + bool persist_after_get_;
|
| };
|
|
|
|
|
| @@ -422,6 +435,11 @@
|
| // value in place.
|
| void StoreToSlot(Slot* slot, InitState init_state);
|
|
|
| + // Load a property of an object, returning it in a Result.
|
| + // The object and the property name are passed on the stack, and
|
| + // not changed.
|
| + Result EmitKeyedLoad(bool is_global);
|
| +
|
| // Special code for typeof expressions: Unfortunately, we must
|
| // be careful when loading the expression in 'typeof'
|
| // expressions. We are not allowed to throw reference errors for
|
| @@ -478,10 +496,10 @@
|
| CallFunctionFlags flags,
|
| int position);
|
|
|
| - // Use an optimized version of Function.prototype.apply that avoid
|
| - // allocating the arguments object and just copies the arguments
|
| - // from the stack.
|
| - void CallApplyLazy(Property* apply,
|
| + // An optimized implementation of expressions of the form
|
| + // x.apply(y, arguments). We call x the applicand and y the receiver.
|
| + // The optimization avoids allocating an arguments object if possible.
|
| + void CallApplyLazy(Expression* applicand,
|
| Expression* receiver,
|
| VariableProxy* arguments,
|
| int position);
|
|
|