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
19namespace v8 {
20namespace internal {
21
22class Code;
23class Isolate;
24class Zone;
25
26namespace compiler {
27class 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.
44class 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();
96  Zone* zone() { return &zone_; }
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