1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef V8_FAST_ACCESSOR_ASSEMBLER_H_
6 #define V8_FAST_ACCESSOR_ASSEMBLER_H_
7 
8 #include <stdint.h>
9 #include <memory>
10 #include <vector>
11 
12 #include "include/v8-experimental.h"
13 #include "src/base/macros.h"
14 #include "src/handles.h"
15 
16 // For CodeStubAssembler::Label. (We cannot forward-declare inner classes.)
17 #include "src/code-stub-assembler.h"
18 
19 namespace v8 {
20 namespace internal {
21 
22 class Code;
23 class Isolate;
24 class Zone;
25 
26 namespace compiler {
27 class Node;
28 }
29 
30 // This interface "exports" an aggregated subset of RawMachineAssembler, for
31 // use by the API to implement Fast Dom Accessors.
32 //
33 // This interface is made for this single purpose only and does not attempt
34 // to implement a general purpose solution. If you need one, please look at
35 // RawMachineAssembler instead.
36 //
37 // The life cycle of a FastAccessorAssembler has two phases:
38 // - After creating the instance, you can call an arbitrary sequence of
39 //   builder functions to build the desired function.
40 // - When done, you can Build() the accessor and query for the build results.
41 //
42 // You cannot call any result getters before Build() was called & successful;
43 // and you cannot call any builder functions after Build() was called.
44 class FastAccessorAssembler {
45  public:
46   typedef v8::experimental::FastAccessorBuilder::ValueId ValueId;
47   typedef v8::experimental::FastAccessorBuilder::LabelId LabelId;
48   typedef v8::FunctionCallback FunctionCallback;
49 
50   explicit FastAccessorAssembler(Isolate* isolate);
51   ~FastAccessorAssembler();
52 
53   // Builder / assembler functions:
54   ValueId IntegerConstant(int int_constant);
55   ValueId GetReceiver();
56   ValueId LoadInternalField(ValueId value_id, int field_no);
57 
58   // Loads internal field and assumes the object is indeed a valid API object
59   // with the proper internal fields present.
60   // The intended use is to call this on an object whose structure has already
61   // been checked previously, e.g. the accessor's receiver, which is map-checked
62   // before the fast accessor is called on it. Using this on an arbitrary object
63   // will result in unsafe memory accesses.
64   ValueId LoadInternalFieldUnchecked(ValueId value_id, int field_no);
65 
66   ValueId LoadValue(ValueId value_id, int offset);
67   ValueId LoadObject(ValueId value_id, int offset);
68 
69   // Converts a machine integer to a SMI.
70   ValueId ToSmi(ValueId value_id);
71 
72   // Builder / assembler functions for control flow.
73   void ReturnValue(ValueId value_id);
74   void CheckFlagSetOrReturnNull(ValueId value_id, int mask);
75   void CheckNotZeroOrReturnNull(ValueId value_id);
76   LabelId MakeLabel();
77   void SetLabel(LabelId label_id);
78   void Goto(LabelId label_id);
79   void CheckNotZeroOrJump(ValueId value_id, LabelId label_id);
80 
81   // C++ callback.
82   ValueId Call(FunctionCallback callback, ValueId arg);
83 
84   // Assemble the code.
85   MaybeHandle<Code> Build();
86 
87  private:
88   ValueId FromRaw(compiler::Node* node);
89   LabelId FromRaw(CodeStubAssembler::Label* label);
90   compiler::Node* FromId(ValueId value) const;
91   CodeStubAssembler::Label* FromId(LabelId value) const;
92 
93   void CheckIsJSObjectOrJump(ValueId value, LabelId label_id);
94 
95   void Clear();
zone()96   Zone* zone() { return &zone_; }
isolate()97   Isolate* isolate() const { return isolate_; }
98 
99   Zone zone_;
100   Isolate* isolate_;
101   std::unique_ptr<CodeStubAssembler> assembler_;
102 
103   // To prevent exposing the RMA internals to the outside world, we'll map
104   // Node + Label pointers integers wrapped in ValueId and LabelId instances.
105   // These vectors maintain this mapping.
106   std::vector<compiler::Node*> nodes_;
107   std::vector<CodeStubAssembler::Label*> labels_;
108 
109   // Remember the current state for easy error checking. (We prefer to be
110   // strict as this class will be exposed at the API.)
111   enum { kBuilding, kBuilt, kError } state_;
112 
113   DISALLOW_COPY_AND_ASSIGN(FastAccessorAssembler);
114 };
115 
116 }  // namespace internal
117 }  // namespace v8
118 
119 #endif  // V8_FAST_ACCESSOR_ASSEMBLER_H_
120